Elbeem: fix memory leak and add guarded allocator directives
[blender.git] / intern / elbeem / intern / controlparticles.h
1 /** \file elbeem/intern/controlparticles.h
2  *  \ingroup elbeem
3  */
4 // --------------------------------------------------------------------------
5 //
6 // El'Beem - the visual lattice boltzmann freesurface simulator
7 // All code distributed as part of El'Beem is covered by the version 2 of the 
8 // GNU General Public License. See the file COPYING for details.  
9 //
10 // Copyright 2008 Nils Thuerey , Richard Keiser, Mark Pauly, Ulrich Ruede
11 //
12 // control particle classes
13 //
14 // --------------------------------------------------------------------------
15
16 #ifndef CONTROLPARTICLES_H
17 #define CONTROLPARTICLES_H
18
19 #include "ntl_geometrymodel.h"
20
21 #ifdef WITH_CXX_GUARDEDALLOC
22 #  include "MEM_guardedalloc.h"
23 #endif
24
25 // indicator for LBM inclusion
26 //#ifndef LBMDIM
27
28 //#include <NxFoundation.h>
29 //#include <vector>
30 //class MultisphGUI;
31 //#define NORMALIZE(a) a.normalize()
32 //#define MAGNITUDE(a) a.magnitude()
33 //#define CROSS(a,b,c) a.cross(b,c)
34 //#define ABS(a) (a>0. ? (a) : -(a))
35 //#include "cpdefines.h"
36
37 //#else // LBMDIM
38
39 // use compatibility defines
40 //#define NORMALIZE(a) normalize(a)
41 //#define MAGNITUDE(a) norm(a)
42 //#define CROSS(a,b,c) a=cross(b,c)
43
44 //#endif // LBMDIM
45
46 #define MAGNITUDE(a) norm(a)
47
48 // math.h compatibility
49 #define CP_PI ((LbmFloat)3.14159265358979323846)
50
51 // project 2d test cases onto plane?
52 // if not, 3d distance is used for 2d sim as well
53 #define CP_PROJECT2D 1
54
55
56 // default init for mincpdist, ControlForces::maxDistance
57 #define CPF_MAXDINIT 10000.
58
59 // storage of influence for a fluid cell/particle in lbm/sph
60 class ControlForces
61 {
62 public:
63         ControlForces() { };
64         ~ControlForces() {};
65
66         // attraction force
67         LbmFloat weightAtt;
68         LbmVec forceAtt;
69         // velocity influence
70         LbmFloat weightVel;
71         LbmVec forceVel;
72         // maximal distance influence, 
73         // first is max. distance to first control particle
74         // second attraction strength
75         LbmFloat maxDistance;
76         LbmVec forceMaxd;
77
78         LbmFloat compAvWeight;
79         LbmVec compAv;
80
81         void resetForces() {
82                 weightAtt = weightVel = 0.;
83                 maxDistance = CPF_MAXDINIT;
84                 forceAtt = forceVel = forceMaxd = LbmVec(0.,0.,0.);
85                 compAvWeight=0.; compAv=LbmVec(0.);
86         };
87
88 private:
89 #ifdef WITH_CXX_GUARDEDALLOC
90         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlForces")
91 #endif
92 };
93
94
95 // single control particle
96 class ControlParticle
97 {
98 public:
99         ControlParticle() { reset(); };
100         ~ControlParticle() {};
101
102         // control parameters
103         
104         // position
105         LbmVec pos;
106         // size (influences influence radius)
107         LbmFloat size;
108         // overall strength of influence
109         LbmFloat influence;
110         // rotation axis
111         LbmVec rotaxis;
112
113         // computed values
114
115         // velocity
116         LbmVec vel;
117         // computed density
118         LbmFloat density;
119         LbmFloat densityWeight;
120
121         LbmVec avgVel;
122         LbmVec avgVelAcc;
123         LbmFloat avgVelWeight;
124
125         // init all zero / defaults
126         void reset();
127
128 private:
129 #ifdef WITH_CXX_GUARDEDALLOC
130         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticle")
131 #endif
132 };
133
134
135 // container for a particle configuration at time t
136 class ControlParticleSet
137 {
138 public:
139
140         // time of particle set
141         LbmFloat time;
142         // particle positions
143         std::vector<ControlParticle> particles;
144
145 private:
146 #ifdef WITH_CXX_GUARDEDALLOC
147         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticleSet")
148 #endif
149 };
150
151
152 // container & management of control particles
153 class ControlParticles
154 {
155 public:
156         ControlParticles();
157         ~ControlParticles();
158
159         // reset datastructures for next influence step
160         // if motion object is given, particle 1 of second system is used for overall 
161         // position and speed offset
162         void prepareControl(LbmFloat simtime, LbmFloat dt, ControlParticles *motion);
163         // post control operations
164         void finishControl(std::vector<ControlForces> &forces, LbmFloat iatt, LbmFloat ivel, LbmFloat imaxd);
165         // recalculate 
166         void calculateKernelWeight();
167
168         // calculate forces at given position, and modify velocity
169         // according to timestep (from initControl)
170         void calculateCpInfluenceOpt (ControlParticle *cp, LbmVec fluidpos, LbmVec fluidvel, ControlForces *force, LbmFloat fillFactor);
171         void calculateMaxdForce      (ControlParticle *cp, LbmVec fluidpos, ControlForces *force);
172
173         // no. of particles
174         inline int getSize() { return (int)_particles.size(); }
175         int getTotalSize();
176         // get particle [i]
177         inline ControlParticle* getParticle(int i){ return &_particles[i]; }
178
179         // set influence parameters
180         void setInfluenceTangential(LbmFloat set) { _influenceTangential=set; }
181         void setInfluenceAttraction(LbmFloat set) { _influenceAttraction=set; }
182         void setInfluenceMaxdist(LbmFloat set)    { _influenceMaxdist=set; }
183         // calculate for delta t
184         void setInfluenceVelocity(LbmFloat set, LbmFloat dt);
185         // get influence parameters
186         inline LbmFloat getInfluenceAttraction()    { return _influenceAttraction; }
187         inline LbmFloat getInfluenceTangential()    { return _influenceTangential; }
188         inline LbmFloat getInfluenceVelocity()      { return _influenceVelocity; }
189         inline LbmFloat getInfluenceMaxdist()       { return _influenceMaxdist; }
190         inline LbmFloat getCurrTimestep()           { return _currTimestep; }
191
192         void setRadiusAtt(LbmFloat set)       { _radiusAtt=set; }
193         inline LbmFloat getRadiusAtt()        { return _radiusAtt; }
194         void setRadiusVel(LbmFloat set)       { _radiusVel=set; }
195         inline LbmFloat getRadiusVel()        { return _radiusVel; }
196         void setRadiusMaxd(LbmFloat set)      { _radiusMaxd=set; }
197         inline LbmFloat getRadiusMaxd()       { return _radiusMaxd; }
198         void setRadiusMinMaxd(LbmFloat set)   { _radiusMinMaxd=set; }
199         inline LbmFloat getRadiusMinMaxd()    { return _radiusMinMaxd; }
200
201         LbmFloat getControlTimStart();
202         LbmFloat getControlTimEnd();
203
204         // set/get characteristic length (and inverse)
205         void setCharLength(LbmFloat set)      { _charLength=set; _charLengthInv=1./_charLength; }
206         inline LbmFloat getCharLength()       { return _charLength;}
207         inline LbmFloat getCharLengthInv()    { return _charLengthInv;}
208
209         // set init parameters
210         void setInitTimeScale(LbmFloat set)  { _initTimeScale = set; };
211         void setInitMirror(string set)  { _initMirror = set; };
212         string getInitMirror()          { return _initMirror; };
213
214         void setLastOffset(LbmVec set) { _initLastPartOffset = set; };
215         void setLastScale(LbmVec set)  { _initLastPartScale = set; };
216         void setOffset(LbmVec set) { _initPartOffset = set; };
217         void setScale(LbmVec set)  { _initPartScale = set; };
218
219         // set/get cps params
220         void setCPSWith(LbmFloat set)       { mCPSWidth = set; };
221         void setCPSTimestep(LbmFloat set)   { mCPSTimestep = set; };
222         void setCPSTimeStart(LbmFloat set)  { mCPSTimeStart = set; };
223         void setCPSTimeEnd(LbmFloat set)    { mCPSTimeEnd = set; };
224         void setCPSMvmWeightFac(LbmFloat set) { mCPSWeightFac = set; };
225
226         LbmFloat getCPSWith()       { return mCPSWidth; };
227         LbmFloat getCPSTimestep()   { return mCPSTimestep; };
228         LbmFloat getCPSTimeStart()  { return mCPSTimeStart; };
229         LbmFloat getCPSTimeEnd()    { return mCPSTimeEnd; };
230         LbmFloat getCPSMvmWeightFac() { return mCPSWeightFac; };
231
232         void setDebugInit(int set)       { mDebugInit = set; };
233
234         // set init parameters
235         void setFluidSpacing(LbmFloat set)  { _fluidSpacing = set; };
236
237         // load positions & timing from text file
238         int initFromTextFile(string filename);
239         int initFromTextFileOld(string filename);
240         // load positions & timing from gzipped binary file
241         int initFromBinaryFile(string filename);
242         int initFromMVCMesh(string filename);
243         // init an example test case
244         int initExampleSet();
245
246         // init for a given time
247         void initTime(LbmFloat t, LbmFloat dt);
248
249         // blender test init
250         void initBlenderTest();
251         
252         int initFromObject(ntlGeometryObjModel *model);
253
254 protected:
255         // sets influence params
256         friend class MultisphGUI;
257
258         // tangential and attraction influence
259         LbmFloat _influenceTangential, _influenceAttraction;
260         // direct velocity influence
261         LbmFloat _influenceVelocity;
262         // maximal distance influence
263         LbmFloat _influenceMaxdist;
264
265         // influence radii
266         LbmFloat _radiusAtt, _radiusVel, _radiusMinMaxd, _radiusMaxd;
267
268         // currently valid time & timestep
269         LbmFloat _currTime, _currTimestep;
270         // all particles
271         std::vector<ControlParticle> _particles;
272
273         // particle sets
274         std::vector<ControlParticleSet> mPartSets;
275
276         // additional parameters for initing particles
277         LbmFloat _initTimeScale;
278         LbmVec _initPartOffset;
279         LbmVec _initPartScale;
280         LbmVec _initLastPartOffset;
281         LbmVec _initLastPartScale;
282         // mirror particles for loading?
283         string _initMirror;
284
285         // row spacing paramter, e.g. use for approximation of kernel area/volume
286         LbmFloat _fluidSpacing;
287         // save current kernel weight
288         LbmFloat _kernelWeight;
289         // charateristic length in world coordinates for normalizatioon of forces
290         LbmFloat _charLength, _charLengthInv;
291
292
293         /*! do ani mesh CPS */
294         void calculateCPS(string filename);
295         //! ani mesh cps params 
296         ntlVec3Gfx mvCPSStart, mvCPSEnd;
297         gfxReal mCPSWidth, mCPSTimestep;
298         gfxReal mCPSTimeStart, mCPSTimeEnd;
299         gfxReal mCPSWeightFac;
300
301         int mDebugInit;
302
303         
304 protected:
305         // apply init transformations
306         void applyTrafos();
307
308         // helper function for init -> swap components everywhere
309         void swapCoords(int a,int b);
310         // helper function for init -> mirror time
311         void mirrorTime();
312
313         // helper, init given array
314         void initTimeArray(LbmFloat t, std::vector<ControlParticle> &parts);
315
316         bool checkPointInside(ntlTree *tree, ntlVec3Gfx org, gfxReal &distance);
317
318 private:
319 #ifdef WITH_CXX_GUARDEDALLOC
320         MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticles")
321 #endif
322 };
323
324
325
326 #endif
327