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