initial commit of the fluid simulator.
[blender.git] / intern / elbeem / intern / parametrizer.cpp
1 /******************************************************************************
2  *
3  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
4  * Copyright 2003,2004 Nils Thuerey
5  *
6  * Parameter calculator for the LBM Solver class
7  *
8  *****************************************************************************/
9
10 #include <sstream>
11 #include "parametrizer.h"
12
13 /*! param seen debug string array */
14 char *ParamStrings[] = {
15         "RelaxTime",
16         "Reynolds",
17         "Viscosity",
18         "SoundSpeed",
19         "DomainSize",
20         "GravityForce",
21         "TimeLength",
22         "StepTime",
23         "Size",
24         "TimeFactor",
25         "AniFrames",
26         "AniFrameTime",
27         "AniStart",
28         "SurfaceTension",
29         "Density",
30         "CellSize",
31         "GStar",
32         "MaxSpeed",
33         "SimMaxSpeed",
34         "FluidVolHeight",
35         "NormalizedGStar",
36         "PSERR", "PSERR", "PSERR", "PSERR"
37 };
38
39
40
41 /******************************************************************************
42  * Default constructor
43  *****************************************************************************/
44 Parametrizer::Parametrizer( void ) :
45         mSetupType("caro"),
46   mRelaxTime( 1.0 ), mReynolds( 0.0 ),
47         mViscosity( 8.94e-7 ), mSoundSpeed( 1500 ),
48         mDomainSize( 0.1 ), mCellSize( 0.01 ),
49         mGravity(0.0, 0.0, 0.0), mLatticeGravity(0.0, 0.0, 0.0),
50         mStepTime(0.01), mDesiredStepTime(-1.0),
51         mSizex(50), mSizey(50), mSizez(50),
52         mTimeFactor( 1.0 ),
53         mAniFrames(0), mAniFrameTime(0.0), mAniStart(0.0),
54         mExtent(1.0, 1.0, 1.0), mSurfaceTension( 0.0 ),
55         mDensity(1000.0), mGStar(0.0001), mFluidVolumeHeight(0.0),
56         mMaxSpeed(0.0), mSimulationMaxSpeed(0.0),
57         mTadapMaxOmega(1.95), mTadapMaxSpeed(0.1), mTadapLevels(1),
58         mSeenValues( 0 ), mCalculatedValues( 0 )
59         //mActive( false )
60 {
61 }
62
63
64 /******************************************************************************
65  * Destructor
66  *****************************************************************************/
67 Parametrizer::~Parametrizer() 
68 {
69         /* not much to do... */
70 }
71
72 /******************************************************************************
73  * Init from attr list
74  *****************************************************************************/
75 void Parametrizer::parseAttrList() 
76 {
77         if(!mpAttrs) {
78                 errMsg("Parametrizer::parseAttrList", "mpAttrs pointer not initialized!");
79                 exit(1);
80         }
81
82         //mActive = mpAttrs->readBool("p_active",mActive, "Parametrizer","mActive", false);
83         mSetupType = mpAttrs->readString("p_setup",mSetupType, "Parametrizer","mSetupType", false); 
84         mRelaxTime = mpAttrs->readFloat("p_relaxtime",mRelaxTime, "Parametrizer","mRelaxTime", false); 
85         if(getAttributeList()->exists("p_relaxtime")) seenThis( PARAM_RELAXTIME );
86
87         mReynolds = mpAttrs->readFloat("p_reynolds",mReynolds, "Parametrizer","mReynolds", false); 
88         if(getAttributeList()->exists("p_reynolds")) seenThis( PARAM_REYNOLDS );
89
90         mViscosity = mpAttrs->readFloat("p_viscosity",mViscosity, "Parametrizer","mViscosity", false); 
91         if(getAttributeList()->exists("p_viscosity")) seenThis( PARAM_VISCOSITY );
92
93         mSoundSpeed = mpAttrs->readFloat("p_soundspeed",mSoundSpeed, "Parametrizer","mSoundSpeed", false); 
94         if(getAttributeList()->exists("p_soundspeed")) seenThis( PARAM_SOUNDSPEED );
95
96         mDomainSize = mpAttrs->readFloat("p_domainsize",mDomainSize, "Parametrizer","mDomainSize", false); 
97         if(getAttributeList()->exists("p_domainsize")) seenThis( PARAM_DOMAINSIZE );
98
99         mGravity = mpAttrs->readVec3d("p_gravity",mGravity, "Parametrizer","mGravity", false); 
100         if(getAttributeList()->exists("p_gravity")) seenThis( PARAM_GRAVITY );
101
102         //mTimeLength = mpAttrs->readFloat("p_timelength",mTimeLength, "Parametrizer","mTimeLength", false); 
103         //if(getAttributeList()->exists("p_timelength")) seenThis( PARAM_TIMELENGTH );
104
105         mStepTime = mpAttrs->readFloat("p_steptime",mStepTime, "Parametrizer","mStepTime", false); 
106         if(getAttributeList()->exists("p_steptime")) seenThis( PARAM_STEPTIME );
107
108         mTimeFactor = mpAttrs->readFloat("p_timefactor",mTimeFactor, "Parametrizer","mTimeFactor", false); 
109         if(getAttributeList()->exists("p_timefactor")) seenThis( PARAM_TIMEFACTOR );
110
111         mAniFrames = mpAttrs->readInt("p_aniframes",mAniFrames, "Parametrizer","mAniFrames", false); 
112         if(getAttributeList()->exists("p_aniframes")) seenThis( PARAM_ANIFRAMES );
113
114         mAniFrameTime = mpAttrs->readFloat("p_aniframetime",mAniFrameTime, "Parametrizer","mAniFrameTime", false); 
115         if(getAttributeList()->exists("p_aniframetime")) seenThis( PARAM_ANIFRAMETIME );
116         if(mAniFrameTime<=0.0) {
117                 errMsg("Parametrizer::parseAttrList","Invalid frame time:"<<mAniFrameTime<<", resetting to 0.0001");
118                 mAniFrameTime = 0.0001;
119         }
120
121         mAniStart = mpAttrs->readFloat("p_anistart",mAniStart, "Parametrizer","mAniStart", false); 
122         if(getAttributeList()->exists("p_anistart")) seenThis( PARAM_ANISTART );
123         if(mAniStart<0.0) {
124                 errMsg("Parametrizer::parseAttrList","Invalid start time:"<<mAniStart<<", resetting to 0.0");
125                 mAniStart = 0.0;
126         }
127
128         mSurfaceTension = mpAttrs->readFloat("p_surfacetension",mSurfaceTension, "Parametrizer","mSurfaceTension", false); 
129         if(getAttributeList()->exists("p_surfacetension")) seenThis( PARAM_SURFACETENSION );
130
131         mDensity = mpAttrs->readFloat("p_density",mDensity, "Parametrizer","mDensity", false); 
132         if(getAttributeList()->exists("p_density")) seenThis( PARAM_DENSITY );
133
134         mCellSize = mpAttrs->readFloat("p_cellsize",mCellSize, "Parametrizer","mCellSize", false); 
135         if(getAttributeList()->exists("p_cellsize")) seenThis( PARAM_CELLSIZE );
136
137         mGStar = mpAttrs->readFloat("p_gstar",mGStar, "Parametrizer","mGStar", false); 
138         if(getAttributeList()->exists("p_gstar")) seenThis( PARAM_GSTAR );
139
140         mNormalizedGStar = mpAttrs->readFloat("p_normgstar",mNormalizedGStar, "Parametrizer","mNormalizedGStar", false); 
141         if(getAttributeList()->exists("p_normgstar")) seenThis( PARAM_NORMALIZEDGSTAR );
142
143         mMaxSpeed = mpAttrs->readFloat("p_maxspeed",mMaxSpeed, "Parametrizer","mMaxSpeed", false); 
144         if(getAttributeList()->exists("p_maxspeed")) seenThis( PARAM_MAXSPEED );
145
146         mTadapMaxOmega = mpAttrs->readFloat("p_tadapmaxomega",mTadapMaxOmega, "Parametrizer","mTadapMaxOmega", false); 
147         mTadapMaxSpeed = mpAttrs->readFloat("p_tadapmaxspeed",mTadapMaxSpeed, "Parametrizer","mTadapMaxSpeed", false); 
148 }
149
150 /******************************************************************************
151  * scale a given speed vector in m/s to lattice values 
152  *****************************************************************************/
153 ParamVec Parametrizer::calculateAddForce(ParamVec vec, string usage)
154 {
155         ParamVec ret = vec * (mStepTime*mStepTime) /mCellSize;
156         debMsgStd("Parametrizer::calculateVector", DM_MSG, "scaled vector = "<<ret<<" for '"<<usage<<"', org = "<<vec<<" dt="<<mStepTime ,10);
157         return ret;
158 }
159
160
161 /******************************************************************************
162  * calculate size of a single cell
163  *****************************************************************************/
164 ParamFloat Parametrizer::calculateCellSize(void)
165 {
166         int maxsize = mSizex; // get max size
167         if(mSizey>maxsize) maxsize = mSizey;
168         if(mSizez>maxsize) maxsize = mSizez;
169         ParamFloat cellSize = 1.0 / (ParamFloat)maxsize;
170         return cellSize;
171 }
172
173
174 /*****************************************************************************/
175 /* simple calulation functions */
176 /*****************************************************************************/
177
178 /*! get omega for LBM */
179 ParamFloat Parametrizer::calculateOmega( void ) { 
180         //return (mTimeFactor/mRelaxTime); 
181         return (1.0/mRelaxTime); 
182 }
183
184 /*! get no. of timesteps for LBM */
185 //int calculateNoOfSteps( void ) { 
186 int Parametrizer::calculateNoOfSteps( ParamFloat timelen ) { 
187         return (int)(timelen/mStepTime); 
188 }
189
190 /*! get external force x component */
191 ParamVec Parametrizer::calculateGravity( void ) { 
192         return mLatticeGravity; 
193 }
194
195 /*! get no of steps for the given length in seconds */
196 int Parametrizer::calculateStepsForSecs( ParamFloat s ) { 
197         return (int)(s/mStepTime); 
198 }
199
200 /*! get start time of animation */
201 int Parametrizer::calculateAniStart( void )   { 
202         return (int)(mAniStart/mStepTime); 
203 }
204
205 /*! get no of steps for a singel animation frame */
206 int Parametrizer::calculateAniStepsPerFrame( void )   { 
207         if(!checkSeenValues(PARAM_ANIFRAMETIME)) {
208                 errMsg("Parametrizer::calculateAniStepsPerFrame", " Missing ani frame time argument!");
209                 exit(1);
210         }
211         return (int)(mAniFrameTime/mStepTime); 
212 }
213
214 /*! get extent of the domain = (1,1,1) if parametrizer not used, (x,y,z) [m] otherwise */
215 ParamVec Parametrizer::calculateExtent( void ) { 
216         return mExtent; 
217 }
218
219 /*! get (scaled) surface tension */
220 ParamFloat Parametrizer::calculateSurfaceTension( void ) { 
221         return mSurfaceTension; 
222 }
223
224 /*! calculate lattice velocity from real world value [m/s] */
225 ParamVec Parametrizer::calculateLattVelocityFromRw( ParamVec ivel ) { 
226         ParamVec velvec = ivel;
227         velvec /= mCellSize;
228         velvec *= mStepTime;
229         return velvec; 
230 }
231 /*! calculate real world [m/s] velocity from lattice value */
232 ParamVec Parametrizer::calculateRwVelocityFromLatt( ParamVec ivel ) { 
233         ParamVec velvec = ivel;
234         velvec *= mCellSize;
235         velvec /= mStepTime;
236         return velvec; 
237 }
238
239
240 /*! get the length of a single time step */
241 // explicity scaled by time factor for refinement 
242 // testing purposes (e.g. fsgr solver)
243 // not working... done manually in solver
244 ParamFloat Parametrizer::getStepTime( void ) { 
245         //return mTimeFactor * mStepTime; 
246         return mStepTime; 
247 }
248
249 /*! calculate the lattice viscosity */
250 ParamFloat Parametrizer::calculateLatticeViscosity( void ) { 
251         // check seen values
252         int reqValues = PARAM_VISCOSITY | PARAM_STEPTIME; // |PARAM_CELLSIZE |  PARAM_GRAVITY;
253         if(!checkSeenValues( reqValues ) ){
254                 errMsg("Parametrizer::calculateLatticeViscosity"," Missing arguments!");
255         }
256         ParamFloat viscStar = mViscosity * mStepTime / (mCellSize*mCellSize);
257         return viscStar; 
258 }
259
260 /*! get g star value with fhvol calculations */
261 ParamFloat Parametrizer::getCurrentGStar( void ) {
262         ParamFloat gStar = mGStar; // check? TODO get from mNormalizedGStar?
263         if(mFluidVolumeHeight>0.0) {
264                 gStar = mGStar/mFluidVolumeHeight;
265         }
266         return gStar;
267 }
268
269 /******************************************************************************
270  * function that tries to calculate all the missing values from the given ones
271  * prints errors and returns false if thats not possible 
272  *****************************************************************************/
273 bool Parametrizer::calculateAllMissingValues( bool silent )
274 {
275         bool init = false;  // did we init correctly?
276         int  valuesChecked = 0;
277         int reqValues;
278
279         // are we active anyway?
280         //if(!mActive) {
281                 // not active - so there's nothing to calculate
282                 //return true;
283         //}
284
285         // we always need the sizes
286         reqValues = PARAM_SIZE;
287         valuesChecked |= reqValues;
288         if(!checkSeenValues(reqValues)) {
289                 errMsg("Parametrizer::calculateAllMissingValues"," Missing size argument!");
290                 return false;
291         }
292
293         if(checkSeenValues(PARAM_CELLSIZE)) {
294                 errMsg("Parametrizer::calculateAllMissingValues"," Dont explicitly set cell size (use domain size instead)");
295                 return false;
296         }
297         if(!checkSeenValues(PARAM_DOMAINSIZE)) {
298                 errMsg("Parametrizer::calculateAllMissingValues"," Missing domain size argument!");
299                 return false;
300         }
301         int maxsize = mSizex; // get max size
302         if(mSizey>maxsize) maxsize = mSizey;
303         if(mSizez>maxsize) maxsize = mSizez;
304         mCellSize = ( mDomainSize * calculateCellSize() ); // sets mCellSize
305         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," max domain resolution="<<(maxsize)<<" cells , cellsize="<<mCellSize ,10);
306
307                         
308         /* Carolin init , see DA for details */
309         //ParamFloat viscMax = 0.7600;    // max lattice viscosity
310         //ParamFloat viscMin = 0.0033;  // min lattice viscosity
311         ParamFloat maxDeltaT = 0.0;
312         ParamFloat maxSpeed = 0.1; // for reynolds approx
313
314         /* normalized gstar init */
315         reqValues = PARAM_NORMALIZEDGSTAR;
316         valuesChecked |= reqValues;
317         if(checkSeenValues( reqValues ) ){
318                 //if(checkSeenValues( PARAM_GSTAR ) ){ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_WARNING," g star value override by normalizedGStar!",1); }
319                 mGStar = mNormalizedGStar/maxsize;
320                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star set to "<<mGStar<<" from normalizedGStar="<<mNormalizedGStar ,1);
321                 seenThis(PARAM_GSTAR);
322         }
323
324         reqValues = PARAM_GSTAR | PARAM_VISCOSITY;
325         if((checkSeenValues(PARAM_SURFACETENSION))) reqValues |= PARAM_DENSITY; // surface tension optional now...
326         valuesChecked |= reqValues;
327         if(checkSeenValues( reqValues ) ){
328                 const ParamFloat gstarReset = 0.0005;
329                 if(getCurrentGStar()<=0.0) {
330                         errMsg("Parametrizer::calculateAllMissingValues","Invalid Gstar: "<<getCurrentGStar()<<" (set to "<<mGStar<<") ... resetting to "<<gstarReset);
331                         mGStar = gstarReset;
332                 }
333
334                 ParamFloat gStar = getCurrentGStar();
335                 if(mFluidVolumeHeight>0.0) {
336                         debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," height"<<mFluidVolumeHeight<<" resGStar = "<<gStar, 10);
337                 }
338                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star = "<<gStar, 10);
339
340                 if(mSetupType=="caro") {
341                         if(!checkSeenValues(PARAM_GRAVITY)) {
342                                 errMsg("Parametrizer::calculateAllMissingValues","Setup type '"<<mSetupType<<"' requires gravity force!");
343                                 goto failure;
344                         }
345                         ParamFloat forceStrength = norm(mGravity);
346                         if(forceStrength<=0) {
347                                 errMsg("Parametrizer::calculateAllMissingValues"," Init failed - forceStrength = "<<forceStrength);
348                                 goto failure;
349                         }
350
351                         // determine max. delta density per timestep trough gravity force
352                         maxDeltaT = sqrt( gStar*mCellSize/forceStrength );
353                 } else if(mSetupType=="maxspeed") {
354                         // determine max. delta t from maximum speed (explicity set)
355                         if((!checkSeenValues(PARAM_MAXSPEED))||(mMaxSpeed<=0.0)) {
356                                 errMsg("Parametrizer::calculateAllMissingValues","Setup type '"<<mSetupType<<"' requires maximum speed ("<<mMaxSpeed<<") !");
357                                 goto failure;
358                         }
359                         ParamFloat maxLatticeSpeed = 0.0333333; //?
360                         maxDeltaT = ( maxLatticeSpeed * mCellSize) / mMaxSpeed;
361                         maxSpeed = mMaxSpeed;
362                 } else if(mSetupType=="falling") {
363                         // determine max. delta t from maximum speed that can be caused by falling through the domain
364                         errMsg("Parametrizer::calculateAllMissingValues"," NYI setup falling");
365                 } else {
366                         errMsg("Parametrizer::calculateAllMissingValues","Setup type '"<<mSetupType<<"' unknown!");
367                         goto failure;
368                 }
369
370                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," targeted step time = "<<maxDeltaT, 10);
371
372                 ParamFloat viscStarFac = mViscosity/(mCellSize*mCellSize);
373                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," viscStarFac = "<<viscStarFac, 10);
374
375                 // FIXME remove for LES?
376                 //if( (viscStarFac*maxDeltaT>=viscMin) && (viscStarFac*maxDeltaT<=viscMax) ) {
377                         //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," delta t: "<<viscMin<<" <? "<<maxDeltaT*viscStarFac<<" <? "<<viscMax, 1);
378                 //} else {
379                         //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_WARNING," delta t not in valid range: "<<viscMin<<" <? "<<maxDeltaT*viscStarFac<<" <? "<<viscMax, 1);
380                 //}
381
382                 // time step adaptivty, only for caro with max sim speed
383                 ParamFloat setDeltaT = maxDeltaT;
384                 if(mDesiredStepTime>0.0) {
385                         setDeltaT = mDesiredStepTime;
386                         mDesiredStepTime = -1.0;
387                         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," desired step time = "<<setDeltaT, 10);
388                 } else if((mSetupType=="caro") && (checkSeenValues( PARAM_SIMMAXSPEED )) ) {
389                         // determine minimal delta t by omega max.
390                         ParamFloat minDeltaT; 
391                         ParamFloat maxOmega = mTadapMaxOmega;
392                         ParamFloat minRelaxTime = 1.0/maxOmega;
393                         for(int lev=1; lev<mTadapLevels; lev++) {
394                                 // make minRelaxTime larger for each level that exists...
395                                 minRelaxTime = 2.0 * (minRelaxTime-0.5) + 0.5;
396                         }
397                         maxOmega = 1.0/minRelaxTime;
398                         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," maxOmega="<<maxOmega<<" minRelaxTime="<<minRelaxTime<<" levels="<<mTadapLevels, 1);
399                         // visc-star for min relax time to calculate min delta ta
400                         if(mViscosity>0.0) {
401                                 minDeltaT = ((2.0*minRelaxTime-1.0)/6.0) * mCellSize * mCellSize / mViscosity;
402                         } else {
403                                 // visc=0, this is not physical, but might happen
404                                 minDeltaT = 0.0;
405                         }
406                         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," min delta t = "<<minDeltaT<<" , range = " << (maxDeltaT/minDeltaT) ,1);
407
408                         // sim speed + accel shouldnt exceed 0.1?
409                         //if(mSimulationMaxSpeed + norm(mGravity*)) { ParamFloat nextmax = 0.1-mSimulationMaxSpeed }
410                         mMaxStepTime = maxDeltaT;
411                         mMinStepTime = minDeltaT;
412                         // only use once...
413                 } else {
414                         debMsgStd("Parametrizer::calculateAllMissingValues",DM_WARNING,"Warning - setup type set to '"<<mSetupType<<"' ",1);
415                         mMaxStepTime = mMinStepTime = setDeltaT;
416                 }
417
418                 setStepTime( setDeltaT ); // set mStepTime to new value
419
420                 //ParamFloat viscStar = mViscosity * mStepTime / (mCellSize*mCellSize);
421                 ParamFloat viscStar = calculateLatticeViscosity();
422                 mRelaxTime = (6.0 * viscStar + 1) * 0.5;
423                 init = true;    
424
425         }
426
427         // finish init
428         if(init) {
429                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," omega = "<<calculateOmega()<<", relax time = "<<mRelaxTime<<", delt="<<mStepTime,1);
430                 //debMsgStd("Parametrizer::calculateAllMissingValues: lbm steps = "<<calculateNoOfSteps()<<" ",1);
431
432                 if(checkSeenValues(PARAM_GRAVITY)) {
433                         ParamFloat forceFactor = (mStepTime *mStepTime)/mCellSize;
434                         //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," given force = "<<PRINT_NTLVEC(mGravity),1);
435                         mLatticeGravity = mGravity * forceFactor;
436                         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," gravity force = "<<PRINT_NTLVEC(mGravity)<<", scaled with "<<forceFactor<<" to "<<mLatticeGravity,1);
437                 }
438
439                 if((checkSeenValues(PARAM_SURFACETENSION))&&(mSurfaceTension>0.0)) {
440                         ParamFloat massDelta = 1.0;
441                         ParamFloat densityStar = 1.0;
442                         massDelta = mDensity / densityStar *mCellSize*mCellSize*mCellSize;
443                         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," massDelta = "<<massDelta, 10);
444
445                         mSurfaceTension = mSurfaceTension*mStepTime*mStepTime/massDelta;
446                         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," surface tension = "<<mSurfaceTension<<" ",1);
447                 }
448                 
449                 mExtent = ParamVec( mCellSize*mSizex, mCellSize*mSizey, mCellSize*mSizez );
450                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," domain extent = "<<PRINT_NTLVEC(mExtent)<<"m ",1);
451                 
452                 if(checkSeenValues(PARAM_ANIFRAMETIME)) {
453                         if(checkSeenValues(PARAM_ANIFRAMES)) {
454                                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," Warning - ani frame time and ani frames given!", 1);
455                                 exit(1);
456                         }
457                 } else {
458                         mAniFrameTime = mAniFrames * mStepTime;
459                 }
460                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani frame steps = "<<calculateAniStepsPerFrame()<<" ", 1);
461
462                 if((checkSeenValues(PARAM_ANISTART))&&(calculateAniStart()>0)) {
463                         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani start steps = "<<calculateAniStart()<<" ",1); 
464                 }
465
466                 // calculate reynolds number
467                 ParamFloat reynoldsApprox = -1.0;
468                 ParamFloat gridSpeed = (maxSpeed*mCellSize/mStepTime);
469                 reynoldsApprox = (mDomainSize*gridSpeed) / mViscosity;
470                 if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," reynolds number (D="<<mDomainSize<<", assuming V="<<gridSpeed<<")= "<<reynoldsApprox<<" ", 1);
471
472                 // everything ok
473                 return true;
474         }
475
476 failure:
477         errMsg("Parametrizer::calculateAllMissingValues "," invalid configuration!");
478         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues ",DM_WARNING, " values seen:", 1);
479         for(int i=0;i<PARAM_NUMIDS;i++) {
480                 if(checkSeenValues( 1<<i )) {
481                         if(!silent) debMsgStd("  ",DM_NOTIFY, ParamStrings[i], 1);
482                 }
483         }
484         if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues ",DM_WARNING, "values checked but missing:", 1);
485         for(int i=0;i<PARAM_NUMIDS;i++) {
486                 if((!checkSeenValues( 1<<i ))&&
487                          ( (valuesChecked&(1<<i))==(1<<i)) ) {
488                         debMsgStd("  ",DM_IMPORTANT, ParamStrings[i], 1);
489                 }
490         }
491
492         // print values?
493         return false;
494 }
495
496
497
498
499
500
501