Blender V2.61 - r43446

solver_class.h

Go to the documentation of this file.
00001 
00004 /******************************************************************************
00005  *
00006  * El'Beem - the visual lattice boltzmann freesurface simulator
00007  * All code distributed as part of El'Beem is covered by the version 2 of the 
00008  * GNU General Public License. See the file COPYING for details.
00009  * Copyright 2003-2006 Nils Thuerey
00010  *
00011  * Combined 2D/3D Lattice Boltzmann standard solver classes
00012  *
00013  *****************************************************************************/
00014 
00015 
00016 #ifndef LBM_SOLVERCLASS_H
00017 #define LBM_SOLVERCLASS_H
00018 
00019 #include "utilities.h"
00020 #include "solver_interface.h"
00021 #include "ntl_ray.h"
00022 #include <stdio.h>
00023 
00024 #if PARALLEL==1
00025 #include <omp.h>
00026 #endif // PARALLEL=1
00027 #ifndef PARALLEL
00028 #define PARALLEL 0
00029 #endif // PARALLEL
00030 
00031 
00032 // general solver setting defines
00033 
00035 //  might be enabled by compilation
00036 #ifndef FSGR_STRICT_DEBUG
00037 #define FSGR_STRICT_DEBUG 0
00038 #endif // FSGR_STRICT_DEBUG
00039 
00041 #define FSGR_OMEGA_DEBUG 0
00042 
00044 #define USE_LES 1
00045 
00047 //#define TIMEINTORDER 0
00048 // TODO remove interpol t param, also interTime
00049 
00050 // use optimized 3D code?
00051 #if LBMDIM==2
00052 #define OPT3D 0
00053 #else
00054 // determine with debugging...
00055 #   if FSGR_STRICT_DEBUG==1
00056 #       define OPT3D 0
00057 #   else // FSGR_STRICT_DEBUG==1
00058 // usually switch optimizations for 3d on, when not debugging
00059 #       define OPT3D 1
00060 // COMPRT
00061 //#     define OPT3D 0
00062 #   endif // FSGR_STRICT_DEBUG==1
00063 #endif
00064 
00066 #define MASS_INVALID -1000.0
00067 
00068 // empty/fill cells without fluid/empty NB's by inserting them into the full/empty lists?
00069 #define FSGR_LISTTRICK          1
00070 #define FSGR_LISTTTHRESHEMPTY   0.10
00071 #define FSGR_LISTTTHRESHFULL    0.90
00072 #define FSGR_MAGICNR            0.025
00073 //0.04
00074 
00076 #define FSGR_MAXNOOFLEVELS 5
00077 
00078 // enable/disable fine grid compression for finest level
00079 // make sure this is same as useGridComp in calculateMemreqEstimate
00080 #if LBMDIM==3
00081 #define COMPRESSGRIDS 1
00082 #else 
00083 #define COMPRESSGRIDS 0
00084 #endif 
00085 
00086 // helper for comparing floats with epsilon
00087 #define GFX_FLOATNEQ(x,y) ( ABS((x)-(y)) > (VECTOR_EPSILON) )
00088 #define LBM_FLOATNEQ(x,y) ( ABS((x)-(y)) > (10.0*LBM_EPSILON) )
00089 
00090 
00091 // macros for loops over all DFs
00092 #define FORDF0 for(int l= 0; l< LBM_DFNUM; ++l)
00093 #define FORDF1 for(int l= 1; l< LBM_DFNUM; ++l)
00094 // and with different loop var to prevent shadowing
00095 #define FORDF0M for(int m= 0; m< LBM_DFNUM; ++m)
00096 #define FORDF1M for(int m= 1; m< LBM_DFNUM; ++m)
00097 
00098 // iso value defines
00099 // border for marching cubes
00100 #define ISOCORR 3
00101 
00102 #define LBM_INLINED  inline
00103 
00104 // sirdude fix for solaris
00105 #if !defined(linux) && defined(sun)
00106 #include "ieeefp.h"
00107 #ifndef expf
00108 #define expf(x) exp((double)(x))
00109 #endif
00110 #endif
00111 
00112 #include "solver_control.h"
00113 
00114 #if LBM_INCLUDE_TESTSOLVERS==1
00115 #include "solver_test.h"
00116 #endif // LBM_INCLUDE_TESTSOLVERS==1
00117 
00118 /*****************************************************************************/
00120 class UniformFsgrCellIdentifier : 
00121     public CellIdentifierInterface , public LbmCellContents
00122 {
00123     public:
00125         int level;
00127         int x,y,z;
00128 
00130         UniformFsgrCellIdentifier() :
00131             x(0), y(0), z(0) { };
00132 
00133         // implement CellIdentifierInterface
00134         virtual string getAsString() {
00135             std::ostringstream ret;
00136             ret <<"{ i"<<x<<",j"<<y;
00137             if(LBMDIM>2) ret<<",k"<<z;
00138             ret <<" }";
00139             return ret.str();
00140         }
00141 
00142         virtual bool equal(CellIdentifierInterface* other) {
00143             UniformFsgrCellIdentifier *cid = (UniformFsgrCellIdentifier *)( other );
00144             if(!cid) return false;
00145             if( x==cid->x && y==cid->y && z==cid->z && level==cid->level ) return true;
00146             return false;
00147         }
00148 };
00149 
00151 class FsgrLevelData {
00152 public:
00153     int id; // level number
00154 
00156     LbmFloat nodeSize;
00158     LbmFloat simCellSize;
00160     LbmFloat omega;
00162     LbmFloat time;
00164     LbmFloat timestep;
00166     int lsteps;
00168     LbmVec gravity;
00170     LbmFloat *mprsCells[2];
00171     CellFlagType *mprsFlags[2];
00172 
00174     LbmFloat lcsmago;
00175     LbmFloat lcsmago_sqr;
00176     LbmFloat lcnu;
00177 
00178     // LES statistics per level
00179     double avgOmega;
00180     double avgOmegaCnt;
00181 
00183     int setCurr;
00185     int setOther;
00186 
00188     LbmFloat lmass;
00189     LbmFloat lvolume;
00190     LbmFloat lcellfactor;
00191 
00193     int lSizex, lSizey, lSizez;
00194     int lOffsx, lOffsy, lOffsz;
00195 
00196 };
00197 
00198 
00199 
00200 /*****************************************************************************/
00202 class LbmFsgrSolver : 
00203     public LbmSolverInterface // this means, the solver is a lbmData object and implements the lbmInterface
00204 {
00205 
00206     public:
00208         LbmFsgrSolver();
00210         virtual ~LbmFsgrSolver();
00211 
00213         virtual void parseAttrList();
00215         void initLevelOmegas();
00216 
00217         // multi step solver init
00219         virtual bool initializeSolverMemory();
00221         virtual bool initializeSolverGrids();
00223         virtual bool initializeSolverPostinit();
00224 
00226         virtual void notifySolverOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename);
00227 
00228 #       if LBM_USE_GUI==1
00229 
00230         virtual void debugDisplay(int set);
00231 #       endif
00232         
00233         // implement CellIterator<UniformFsgrCellIdentifier> interface
00234         typedef UniformFsgrCellIdentifier stdCellId;
00235         virtual CellIdentifierInterface* getFirstCell( );
00236         virtual void advanceCell( CellIdentifierInterface* );
00237         virtual bool noEndCell( CellIdentifierInterface* );
00238         virtual void deleteCellIterator( CellIdentifierInterface** );
00239         virtual CellIdentifierInterface* getCellAt( ntlVec3Gfx pos );
00240         virtual int        getCellSet      ( CellIdentifierInterface* );
00241         virtual ntlVec3Gfx getCellOrigin   ( CellIdentifierInterface* );
00242         virtual ntlVec3Gfx getCellSize     ( CellIdentifierInterface* );
00243         virtual int        getCellLevel    ( CellIdentifierInterface* );
00244         virtual LbmFloat   getCellDensity  ( CellIdentifierInterface* ,int set);
00245         virtual LbmVec     getCellVelocity ( CellIdentifierInterface* ,int set);
00246         virtual LbmFloat   getCellDf       ( CellIdentifierInterface* ,int set, int dir);
00247         virtual LbmFloat   getCellMass     ( CellIdentifierInterface* ,int set);
00248         virtual LbmFloat   getCellFill     ( CellIdentifierInterface* ,int set);
00249         virtual CellFlagType getCellFlag   ( CellIdentifierInterface* ,int set);
00250         virtual LbmFloat   getEquilDf      ( int );
00251         virtual ntlVec3Gfx getVelocityAt   (float x, float y, float z);
00252         // convert pointers
00253         stdCellId* convertBaseCidToStdCid( CellIdentifierInterface* basecid);
00254 
00256         bool initGeometryFlags();
00258         void initFreeSurfaces();
00260         void initStandingFluidGradient();
00261 
00263         LBM_INLINED void initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass);
00264         LBM_INLINED void initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel);
00265         LBM_INLINED void changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag);
00266         LBM_INLINED void forceChangeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag);
00267         LBM_INLINED void initInterfaceVars(int level, int i,int j,int k,int workSet, bool initMass);
00269         void interpolateCellValues(int level,int ei,int ej,int ek,int workSet, LbmFloat &retrho, LbmFloat &retux, LbmFloat &retuy, LbmFloat &retuz);
00270 
00272         void stepMain();
00274         void fineAdvance();
00276         void coarseAdvance(int lev);
00278         void coarseCalculateFluxareas(int lev);
00279         // adaptively coarsen grid
00280         bool adaptGrid(int lev);
00281         // restrict fine grid DFs to coarse grid
00282         void coarseRestrictFromFine(int lev);
00283 
00284         /* simulation object interface, just calls stepMain */
00285         virtual void step();
00287         virtual int initParticles();
00289         virtual void advanceParticles();
00291         void handleObstacleParticle(ParticleObject *p);
00298         virtual vector<ntlGeometryObject*> getDebugObjects();
00299     
00300         // gui/output debugging functions
00301 #       if LBM_USE_GUI==1
00302         virtual void debugDisplayNode(int dispset, CellIdentifierInterface* cell );
00303         virtual void lbmDebugDisplay(int dispset);
00304         virtual void lbmMarkedCellDisplay();
00305 #       endif // LBM_USE_GUI==1
00306         virtual void debugPrintNodeInfo(CellIdentifierInterface* cell, int forceSet=-1);
00307 
00309         void prepareVisualization( void );
00310 
00311         /* surface generation settings */
00312         virtual void setSurfGenSettings(short value);
00313 
00314     protected:
00315 
00317         void printLbmCell(int level, int i, int j, int k,int set);
00318         // debugging use CellIterator interface to mark cell
00319         void debugMarkCellCall(int level, int vi,int vj,int vk);
00320         
00321         // loop over grid, stream&collide update
00322         void mainLoop(int lev);
00323         // change time step size
00324         void adaptTimestep();
00326         void recalculateObjectSpeeds();
00328         void initMovingObstacles(bool staticInit);
00330         void reinitFlags( int workSet );
00332         LbmFloat getMassdWeight(bool dirForw, int i,int j,int k,int workSet, int l);
00334         void computeFluidSurfaceNormal(LbmFloat *cell, CellFlagType *cellflag,    LbmFloat *snret);
00335         void computeFluidSurfaceNormalAcc(LbmFloat *cell, CellFlagType *cellflag, LbmFloat *snret);
00336         void computeObstacleSurfaceNormal(LbmFloat *cell, CellFlagType *cellflag, LbmFloat *snret);
00337         void computeObstacleSurfaceNormalAcc(int i,int j,int k, LbmFloat *snret);
00339         LBM_INLINED void addToNewInterList( int ni, int nj, int nk );   
00341         void interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet,bool markNbs);
00342         void coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int dstSet);
00343 
00345         LBM_INLINED int getForZMinBnd();
00346         LBM_INLINED int getForZMin1();
00347         LBM_INLINED int getForZMaxBnd(int lev);
00348         LBM_INLINED int getForZMax1(int lev);
00349         LBM_INLINED bool checkDomainBounds(int lev,int i,int j,int k);
00350         LBM_INLINED bool checkDomainBoundsPos(int lev,LbmVec pos);
00351 
00352         // touch grid and flags once
00353         void preinitGrids();
00354         // one relaxation step for standing fluid
00355         void standingFluidPreinit();
00356 
00357 
00358         // member vars
00359 
00361         LbmFloat mCurrentMass;
00362         LbmFloat mCurrentVolume;
00363         LbmFloat mInitialMass;
00364 
00366         int mNumProblems;
00367 
00368         // average mlsups, count how many so far...
00369         double mAvgMLSUPS;
00370         double mAvgMLSUPSCnt;
00371 
00373         IsoSurface *mpPreviewSurface;
00374         
00376         bool mTimeAdap;
00378         bool mForceTimeStepReduce;
00379 
00381         LbmFloat mFVHeight;
00382         LbmFloat mFVArea;
00383         bool mUpdateFVHeight;
00384 
00386         LbmFloat mGfxEndTime;
00388         int mInitSurfaceSmoothing;
00390         //  each flag switches side on off,  fssgNoObs is for obstacle sides
00391         //  -1 equals all on
00392         typedef enum {
00393              fssgNormal   =  0,
00394              fssgNoNorth  =  1,
00395              fssgNoSouth  =  2,
00396              fssgNoEast   =  4,
00397              fssgNoWest   =  8,
00398              fssgNoTop    = 16,
00399              fssgNoBottom = 32,
00400              fssgNoObs    = 64
00401         } fsSurfaceGen;
00402         int mFsSurfGenSetting;
00403 
00405         int mTimestepReduceLock;
00407         int mTimeSwitchCounts;
00408         // only switch of maxvel is higher for several steps...
00409         int mTimeMaxvelStepCnt;
00410 
00412         LbmFloat mSimulationTime, mLastSimTime;
00414         LbmFloat mMinTimestep, mMaxTimestep;
00416         LbmFloat mMxvx, mMxvy, mMxvz, mMaxVlen;
00417 
00419         vector<LbmPoint> mListEmpty;
00421         vector<LbmPoint> mListFull;
00423     vector<LbmPoint> mListNewInter;
00425         class lbmFloatSet {
00426             public:
00427                 LbmFloat val[dTotalNum];
00428                 LbmFloat numNbs;
00429         };
00431         LbmVec mDvecNrm[27];
00432         
00433         
00435         bool checkSymmetry(string idstring);
00437         int mMaxNoCells, mMinNoCells;
00438         LONGINT mAvgNumUsedCells;
00439 
00441         vector<LbmVec> mObjectSpeeds;
00443         vector<LbmFloat> mObjectPartslips;
00445         vector<LbmFloat> mObjectMassMovnd;
00446 
00448       vector<ntlVec3Gfx>  mMOIVertices;
00449     vector<ntlVec3Gfx>  mMOIVerticesOld;
00450       vector<ntlVec3Gfx>  mMOINormals;
00451 
00453         int mIsoWeightMethod;
00454         float mIsoWeight[27];
00455 
00456         // grid coarsening vars
00457         
00459         FsgrLevelData mLevel[FSGR_MAXNOOFLEVELS];
00460 
00462         int mMaxRefine;
00463 
00465         LbmFloat mDfScaleUp, mDfScaleDown;
00466 
00468         LbmFloat mFsgrCellArea[27];
00470         LbmFloat mGaussw[27];
00471 
00473         float mInitialCsmago;
00475         LbmFloat mDebugOmegaRet;
00477         LbmFloat mLastOmega;
00478         LbmVec   mLastGravity;
00479 
00481         int mNumInterdCells;
00482         int mNumInvIfCells;
00483         int mNumInvIfTotal;
00484         int mNumFsgrChanges;
00485 
00487         int mDisableStandingFluidInit;
00489         bool mInit2dYZ;
00491         int mForceTadapRefine;
00493         int mCutoff;
00494 
00495         // strict debug interface
00496 #       if FSGR_STRICT_DEBUG==1
00497         int debLBMGI(int level, int ii,int ij,int ik, int is);
00498         CellFlagType& debRFLAG(int level, int xx,int yy,int zz,int set);
00499         CellFlagType& debRFLAG_NB(int level, int xx,int yy,int zz,int set, int dir);
00500         CellFlagType& debRFLAG_NBINV(int level, int xx,int yy,int zz,int set, int dir);
00501         int debLBMQI(int level, int ii,int ij,int ik, int is, int l);
00502         LbmFloat& debQCELL(int level, int xx,int yy,int zz,int set,int l);
00503         LbmFloat& debQCELL_NB(int level, int xx,int yy,int zz,int set, int dir,int l);
00504         LbmFloat& debQCELL_NBINV(int level, int xx,int yy,int zz,int set, int dir,int l);
00505         LbmFloat* debRACPNT(int level,  int ii,int ij,int ik, int is );
00506         LbmFloat& debRAC(LbmFloat* s,int l);
00507 #       endif // FSGR_STRICT_DEBUG==1
00508 
00509         LbmControlData *mpControl;
00510 
00511         void initCpdata();
00512         void handleCpdata();
00513         void cpDebugDisplay(int dispset); 
00514 
00515         bool mUseTestdata;
00516 #       if LBM_INCLUDE_TESTSOLVERS==1
00517         // test functions
00518         LbmTestdata *mpTest;
00519         void initTestdata();
00520         void destroyTestdata();
00521         void handleTestdata();
00522         void set3dHeight(int ,int );
00523 
00524         int mMpNum,mMpIndex;
00525         int mOrgSizeX;
00526         LbmFloat mOrgStartX;
00527         LbmFloat mOrgEndX;
00528         void mrSetup();
00529         void mrExchange(); 
00530         void mrIsoExchange(); 
00531         LbmFloat mrInitTadap(LbmFloat max); 
00532         void gcFillBuffer(  LbmGridConnector *gc, int *retSizeCnt, const int *bdfs);
00533         void gcUnpackBuffer(LbmGridConnector *gc, int *retSizeCnt, const int *bdfs);
00534     public:
00535         // needed for testdata
00536         void find3dHeight(int i,int j, LbmFloat prev, LbmFloat &ret, LbmFloat *retux, LbmFloat *retuy, LbmFloat *retuz);
00537         // mptest
00538         int getMpIndex() { return mMpIndex; };
00539 #       endif // LBM_INCLUDE_TESTSOLVERS==1
00540 
00541         // former LbmModelLBGK  functions
00542         // relaxation funtions - implemented together with relax macros
00543         static inline LbmFloat getVelVecLen(int l, LbmFloat ux,LbmFloat uy,LbmFloat uz);
00544         static inline LbmFloat getCollideEq(int l, LbmFloat rho,  LbmFloat ux, LbmFloat uy, LbmFloat uz);
00545         inline LbmFloat getLesNoneqTensorCoeff( LbmFloat df[],              LbmFloat feq[] );
00546         inline LbmFloat getLesOmega(LbmFloat omega, LbmFloat csmago, LbmFloat Qo);
00547         inline void collideArrays( int lev, int i, int j, int k, // position - more for debugging
00548                 LbmFloat df[], LbmFloat &outrho, // out only!
00549                 // velocity modifiers (returns actual velocity!)
00550                 LbmFloat &mux, LbmFloat &muy, LbmFloat &muz, 
00551                 LbmFloat omega, LbmVec gravity, LbmFloat csmago, 
00552                 LbmFloat *newOmegaRet, LbmFloat *newQoRet);
00553 
00554 
00555         // former LBM models
00557 #       define STCON static const
00558 
00559 #       if LBMDIM==3
00560         
00562         virtual string getIdString() { return string("FreeSurfaceFsgrSolver[BGK_D3Q19]"); }
00563 
00565         STCON int cDimension;
00566 
00567         // Wi factors for collide step 
00568         STCON LbmFloat cCollenZero;
00569         STCON LbmFloat cCollenOne;
00570         STCON LbmFloat cCollenSqrtTwo;
00571 
00573         STCON LbmFloat cMagicNr2;
00574         STCON LbmFloat cMagicNr2Neg;
00575         STCON LbmFloat cMagicNr;
00576         STCON LbmFloat cMagicNrNeg;
00577 
00579         STCON int    cDfNum;
00581         STCON int    cDirNum;
00582 
00584         typedef enum {
00585              cDirInv=  -1,
00586              cDirC  =  0,
00587              cDirN  =  1,
00588              cDirS  =  2,
00589              cDirE  =  3,
00590              cDirW  =  4,
00591              cDirT  =  5,
00592              cDirB  =  6,
00593              cDirNE =  7,
00594              cDirNW =  8,
00595              cDirSE =  9,
00596              cDirSW = 10,
00597              cDirNT = 11,
00598              cDirNB = 12,
00599              cDirST = 13,
00600              cDirSB = 14,
00601              cDirET = 15,
00602              cDirEB = 16,
00603              cDirWT = 17,
00604              cDirWB = 18
00605         } dfDir;
00606 
00607         /* Vector Order 3D:
00608          *  0   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
00609          *  0,  0, 0,  1,-1,  0, 0,      1,-1, 1,-1,  0, 0, 0, 0,  1, 1,-1,-1,     1,-1, 1,-1,  1,-1, 1,-1
00610          *  0,  1,-1,  0, 0,  0, 0,      1, 1,-1,-1,  1, 1,-1,-1,  0, 0, 0, 0,     1, 1,-1,-1,  1, 1,-1,-1
00611          *  0,  0, 0,  0, 0,  1,-1,      0, 0, 0, 0,  1,-1, 1,-1,  1,-1, 1,-1,     1, 1, 1, 1, -1,-1,-1,-1
00612          */
00613 
00616         STCON char* dfString[ 19 ];
00617 
00619         STCON int dfNorm[ 19 ];
00620 
00622         STCON int dfInv[ 19 ];
00623 
00625         STCON int dfRefX[ 19 ];
00627         STCON int dfRefY[ 19 ];
00629         STCON int dfRefZ[ 19 ];
00630 
00632         STCON int dfVecX[ 27 ];
00633         STCON int dfVecY[ 27 ];
00634         STCON int dfVecZ[ 27 ];
00635 
00637         STCON LbmFloat dfDvecX[ 27 ];
00638         STCON LbmFloat dfDvecY[ 27 ];
00639         STCON LbmFloat dfDvecZ[ 27 ];
00640 
00642         STCON int princDirX[ 2*3 ];
00643         STCON int princDirY[ 2*3 ];
00644         STCON int princDirZ[ 2*3 ];
00645 
00647         STCON LbmFloat dfLength[ 19 ];
00648 
00650         static LbmFloat dfEquil[ dTotalNum ];
00651 
00653         static LbmFloat lesCoeffDiag[ (3-1)*(3-1) ][ 27 ];
00654         static LbmFloat lesCoeffOffdiag[ 3 ][ 27 ];
00655 
00656 #       else // end LBMDIM==3 , LBMDIM==2
00657         
00659         virtual string getIdString() { return string("FreeSurfaceFsgrSolver[BGK_D2Q9]"); }
00660 
00662         STCON int cDimension;
00663 
00665         STCON LbmFloat cCollenZero;
00666         STCON LbmFloat cCollenOne;
00667         STCON LbmFloat cCollenSqrtTwo;
00668 
00670         STCON LbmFloat cMagicNr2;
00671         STCON LbmFloat cMagicNr2Neg;
00672         STCON LbmFloat cMagicNr;
00673         STCON LbmFloat cMagicNrNeg;
00674 
00676         STCON int    cDfNum;
00677         STCON int    cDirNum;
00678 
00680         typedef enum {
00681              cDirInv=  -1,
00682              cDirC  =  0,
00683              cDirN  =  1,
00684              cDirS  =  2,
00685              cDirE  =  3,
00686              cDirW  =  4,
00687              cDirNE =  5,
00688              cDirNW =  6,
00689              cDirSE =  7,
00690              cDirSW =  8
00691         } dfDir;
00692 
00693         /* Vector Order 2D:
00694          * 0  1 2  3  4  5  6 7  8
00695          * 0, 0,0, 1,-1, 1,-1,1,-1 
00696          * 0, 1,-1, 0,0, 1,1,-1,-1  */
00697 
00698         /* name of the dist. function 
00699              only for nicer output */
00700         STCON char* dfString[ 9 ];
00701 
00702         /* index of normal dist func, not used so far?... */
00703         STCON int dfNorm[ 9 ];
00704 
00705         /* index of inverse dist func, not fast, but useful... */
00706         STCON int dfInv[ 9 ];
00707 
00708         /* index of x reflected dist func for free slip, not valid for all DFs... */
00709         STCON int dfRefX[ 9 ];
00710         /* index of x reflected dist func for free slip, not valid for all DFs... */
00711         STCON int dfRefY[ 9 ];
00712         /* index of x reflected dist func for free slip, not valid for all DFs... */
00713         STCON int dfRefZ[ 9 ];
00714 
00715         /* dist func vectors */
00716         STCON int dfVecX[ 9 ];
00717         STCON int dfVecY[ 9 ];
00718         /* Z, 2D values are all 0! */
00719         STCON int dfVecZ[ 9 ];
00720 
00721         /* arrays as before with doubles */
00722         STCON LbmFloat dfDvecX[ 9 ];
00723         STCON LbmFloat dfDvecY[ 9 ];
00724         /* Z, 2D values are all 0! */
00725         STCON LbmFloat dfDvecZ[ 9 ];
00726 
00728         STCON int princDirX[ 2*2 ];
00729         STCON int princDirY[ 2*2 ];
00730         STCON int princDirZ[ 2*2 ];
00731 
00732         /* vector lengths */
00733         STCON LbmFloat dfLength[ 9 ];
00734 
00735         /* equilibrium distribution functions, precalculated = getCollideEq(i, 0,0,0,0) */
00736         static LbmFloat dfEquil[ dTotalNum ];
00737 
00739         static LbmFloat lesCoeffDiag[ (2-1)*(2-1) ][ 9 ];
00740         static LbmFloat lesCoeffOffdiag[ 2 ][ 9 ];
00741 
00742 #       endif  // LBMDIM==2
00743 };
00744 
00745 #undef STCON
00746 
00747 
00748 /*****************************************************************************/
00749 // relaxation_macros
00750 
00751 
00752 
00753 // cell mark debugging
00754 #if FSGR_STRICT_DEBUG==10
00755 #define debugMarkCell(lev,x,y,z) \
00756     errMsg("debugMarkCell",this->mName<<" step: "<<this->mStepCnt<<" lev:"<<(lev)<<" marking "<<PRINT_VEC((x),(y),(z))<<" line "<< __LINE__ ); \
00757     debugMarkCellCall((lev),(x),(y),(z));
00758 #else // FSGR_STRICT_DEBUG==1
00759 #define debugMarkCell(lev,x,y,z) \
00760     debugMarkCellCall((lev),(x),(y),(z));
00761 #endif // FSGR_STRICT_DEBUG==1
00762 
00763 
00764 // flag array defines -----------------------------------------------------------------------------------------------
00765 
00766 // lbm testsolver get index define, note - ignores is (set) as flag
00767 // array is only a single entry
00768 #define _LBMGI(level, ii,ij,ik, is) ( (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
00769 
00771 #define _RFLAG(level,xx,yy,zz,set) mLevel[level].mprsFlags[set][ LBMGI((level),(xx),(yy),(zz),(set)) ]
00772 #define _RFLAG_NB(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+this->dfVecX[dir],(yy)+this->dfVecY[dir],(zz)+this->dfVecZ[dir],set) ]
00773 #define _RFLAG_NBINV(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+this->dfVecX[this->dfInv[dir]],(yy)+this->dfVecY[this->dfInv[dir]],(zz)+this->dfVecZ[this->dfInv[dir]],set) ]
00774 
00775 // array handling  -----------------------------------------------------------------------------------------------
00776 
00777 #define _LBMQI(level, ii,ij,ik, is, lunused) ( (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
00778 #define _QCELL(level,xx,yy,zz,set,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx),(yy),(zz),(set), l)*dTotalNum +(l)])
00779 #define _QCELL_NB(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+this->dfVecX[dir],(yy)+this->dfVecY[dir],(zz)+this->dfVecZ[dir],set, l)*dTotalNum +(l)])
00780 #define _QCELL_NBINV(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+this->dfVecX[this->dfInv[dir]],(yy)+this->dfVecY[this->dfInv[dir]],(zz)+this->dfVecZ[this->dfInv[dir]],set, l)*dTotalNum +(l)])
00781 
00782 #define QCELLSTEP dTotalNum
00783 #define _RACPNT(level, ii,ij,ik, is )  &QCELL(level,ii,ij,ik,is,0)
00784 #define _RAC(s,l) (s)[(l)]
00785 
00786 
00787 #if FSGR_STRICT_DEBUG==1
00788 
00789 #define LBMGI(level,ii,ij,ik, is)                 debLBMGI(level,ii,ij,ik, is)         
00790 #define RFLAG(level,xx,yy,zz,set)                 debRFLAG(level,xx,yy,zz,set)            
00791 #define RFLAG_NB(level,xx,yy,zz,set, dir)         debRFLAG_NB(level,xx,yy,zz,set, dir)    
00792 #define RFLAG_NBINV(level,xx,yy,zz,set, dir)      debRFLAG_NBINV(level,xx,yy,zz,set, dir) 
00793 
00794 #define LBMQI(level,ii,ij,ik, is, l)              debLBMQI(level,ii,ij,ik, is, l)         
00795 #define QCELL(level,xx,yy,zz,set,l)               debQCELL(level,xx,yy,zz,set,l)         
00796 #define QCELL_NB(level,xx,yy,zz,set, dir,l)       debQCELL_NB(level,xx,yy,zz,set, dir,l)
00797 #define QCELL_NBINV(level,xx,yy,zz,set, dir,l)    debQCELL_NBINV(level,xx,yy,zz,set, dir,l)
00798 #define RACPNT(level, ii,ij,ik, is )              debRACPNT(level, ii,ij,ik, is )          
00799 #define RAC(s,l)                                        debRAC(s,l)                  
00800 
00801 #else // FSGR_STRICT_DEBUG==1
00802 
00803 #define LBMGI(level,ii,ij,ik, is)                 _LBMGI(level,ii,ij,ik, is)         
00804 #define RFLAG(level,xx,yy,zz,set)                 _RFLAG(level,xx,yy,zz,set)            
00805 #define RFLAG_NB(level,xx,yy,zz,set, dir)         _RFLAG_NB(level,xx,yy,zz,set, dir)    
00806 #define RFLAG_NBINV(level,xx,yy,zz,set, dir)      _RFLAG_NBINV(level,xx,yy,zz,set, dir) 
00807 
00808 #define LBMQI(level,ii,ij,ik, is, l)              _LBMQI(level,ii,ij,ik, is, l)         
00809 #define QCELL(level,xx,yy,zz,set,l)               _QCELL(level,xx,yy,zz,set,l)         
00810 #define QCELL_NB(level,xx,yy,zz,set, dir,l)       _QCELL_NB(level,xx,yy,zz,set, dir, l)
00811 #define QCELL_NBINV(level,xx,yy,zz,set, dir,l)    _QCELL_NBINV(level,xx,yy,zz,set, dir,l)
00812 #define RACPNT(level, ii,ij,ik, is )              _RACPNT(level, ii,ij,ik, is )          
00813 #define RAC(s,l)                                  _RAC(s,l)                  
00814 
00815 #endif // FSGR_STRICT_DEBUG==1
00816 
00817 // general defines -----------------------------------------------------------------------------------------------
00818 
00819 // replace TESTFLAG
00820 #define FLAGISEXACT(flag, compflag)  ((flag & compflag)==compflag)
00821 
00822 #if LBMDIM==2
00823 #define dC 0
00824 #define dN 1
00825 #define dS 2
00826 #define dE 3
00827 #define dW 4
00828 #define dNE 5
00829 #define dNW 6
00830 #define dSE 7
00831 #define dSW 8
00832 #else
00833 // direction indices
00834 #define dC 0
00835 #define dN 1
00836 #define dS 2
00837 #define dE 3
00838 #define dW 4
00839 #define dT 5
00840 #define dB 6
00841 #define dNE 7
00842 #define dNW 8
00843 #define dSE 9
00844 #define dSW 10
00845 #define dNT 11
00846 #define dNB 12
00847 #define dST 13
00848 #define dSB 14
00849 #define dET 15
00850 #define dEB 16
00851 #define dWT 17
00852 #define dWB 18
00853 #endif
00854 //? #define dWB 18
00855 
00856 // default init for dFlux values
00857 #define FLUX_INIT 0.5f * (float)(this->cDfNum)
00858 
00859 // only for non DF dir handling!
00860 #define dNET 19
00861 #define dNWT 20
00862 #define dSET 21
00863 #define dSWT 22
00864 #define dNEB 23
00865 #define dNWB 24
00866 #define dSEB 25
00867 #define dSWB 26
00868 
00870 #define BND_FILL 0.0
00871 
00872 #define DFL1 (1.0/ 3.0)
00873 #define DFL2 (1.0/18.0)
00874 #define DFL3 (1.0/36.0)
00875 
00876 // loops over _all_ cells (including boundary layer)
00877 #define FSGR_FORIJK_BOUNDS(leveli) \
00878     for(int k= getForZMinBnd(); k< getForZMaxBnd(leveli); ++k) \
00879    for(int j=0;j<mLevel[leveli].lSizey-0;++j) \
00880     for(int i=0;i<mLevel[leveli].lSizex-0;++i) \
00881     
00882 // loops over _only inner_ cells 
00883 #define FSGR_FORIJK1(leveli) \
00884     for(int k= getForZMin1(); k< getForZMax1(leveli); ++k) \
00885    for(int j=1;j<mLevel[leveli].lSizey-1;++j) \
00886     for(int i=1;i<mLevel[leveli].lSizex-1;++i) \
00887 
00888 // relaxation_macros end
00889 
00890 
00891 
00892 /******************************************************************************/
00894 /******************************************************************************/
00895 
00897 inline LbmFloat LbmFsgrSolver::getVelVecLen(int l, LbmFloat ux,LbmFloat uy,LbmFloat uz) {
00898     return ((ux)*dfDvecX[l]+(uy)*dfDvecY[l]+(uz)*dfDvecZ[l]);
00899 };
00900 
00902 inline LbmFloat LbmFsgrSolver::getCollideEq(int l, LbmFloat rho,  LbmFloat ux, LbmFloat uy, LbmFloat uz) {
00903 #if FSGR_STRICT_DEBUG==1
00904     if((l<0)||(l>LBM_DFNUM)) { errFatal("LbmFsgrSolver::getCollideEq","Invalid DFEQ call "<<l, SIMWORLD_PANIC ); /* no access to mPanic here */ }
00905 #endif // FSGR_STRICT_DEBUG==1
00906     LbmFloat tmp = getVelVecLen(l,ux,uy,uz); 
00907     return( dfLength[l] *( 
00908                 + rho - (3.0/2.0*(ux*ux + uy*uy + uz*uz)) 
00909                 + 3.0 *tmp 
00910                 + 9.0/2.0 *(tmp*tmp) )
00911             ); // */
00912 };
00913 
00914 /*****************************************************************************/
00915 /* init a given cell with flag, density, mass and equilibrium dist. funcs */
00916 
00917 void LbmFsgrSolver::forceChangeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag) {
00918     // also overwrite persisting flags
00919     // function is useful for tracking accesses...
00920     RFLAG(level,xx,yy,zz,set) = newflag;
00921 }
00922 void LbmFsgrSolver::changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag) {
00923     CellFlagType pers = RFLAG(level,xx,yy,zz,set) & CFPersistMask;
00924     RFLAG(level,xx,yy,zz,set) = newflag | pers;
00925 }
00926 
00927 void 
00928 LbmFsgrSolver::initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass) {
00929   /* init eq. dist funcs */
00930     LbmFloat *ecel;
00931     int workSet = mLevel[level].setCurr;
00932 
00933     ecel = RACPNT(level, i,j,k, workSet);
00934     FORDF0 { RAC(ecel, l) = this->dfEquil[l] * rho; }
00935     RAC(ecel, dMass) = mass;
00936     RAC(ecel, dFfrac) = mass/rho;
00937     RAC(ecel, dFlux) = FLUX_INIT;
00938     changeFlag(level, i,j,k, workSet, flag);
00939 
00940   workSet ^= 1;
00941     changeFlag(level, i,j,k, workSet, flag);
00942     return;
00943 }
00944 
00945 void 
00946 LbmFsgrSolver::initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel) {
00947     LbmFloat *ecel;
00948     int workSet = mLevel[level].setCurr;
00949 
00950     ecel = RACPNT(level, i,j,k, workSet);
00951     FORDF0 { RAC(ecel, l) = getCollideEq(l, rho,vel[0],vel[1],vel[2]); }
00952     RAC(ecel, dMass) = mass;
00953     RAC(ecel, dFfrac) = mass/rho;
00954     RAC(ecel, dFlux) = FLUX_INIT;
00955     changeFlag(level, i,j,k, workSet, flag);
00956 
00957   workSet ^= 1;
00958     changeFlag(level, i,j,k, workSet, flag);
00959     return;
00960 }
00961 
00962 int LbmFsgrSolver::getForZMinBnd() { 
00963     return 0; 
00964 }
00965 int LbmFsgrSolver::getForZMin1()   { 
00966     if(LBMDIM==2) return 0;
00967     return 1; 
00968 }
00969 
00970 int LbmFsgrSolver::getForZMaxBnd(int lev) { 
00971     if(LBMDIM==2) return 1;
00972     return mLevel[lev].lSizez -0;
00973 }
00974 int LbmFsgrSolver::getForZMax1(int lev)   { 
00975     if(LBMDIM==2) return 1;
00976     return mLevel[lev].lSizez -1;
00977 }
00978 
00979 bool LbmFsgrSolver::checkDomainBounds(int lev,int i,int j,int k) { 
00980     if(i<0) return false;
00981     if(j<0) return false;
00982     if(k<0) return false;
00983     if(i>mLevel[lev].lSizex-1) return false;
00984     if(j>mLevel[lev].lSizey-1) return false;
00985     if(k>mLevel[lev].lSizez-1) return false;
00986     return true;
00987 }
00988 bool LbmFsgrSolver::checkDomainBoundsPos(int lev,LbmVec pos) { 
00989     const int i= (int)pos[0]; 
00990     if(i<0) return false;
00991     if(i>mLevel[lev].lSizex-1) return false;
00992     const int j= (int)pos[1]; 
00993     if(j<0) return false;
00994     if(j>mLevel[lev].lSizey-1) return false;
00995     const int k= (int)pos[2];
00996     if(k<0) return false;
00997     if(k>mLevel[lev].lSizez-1) return false;
00998     return true;
00999 }
01000 
01001 void LbmFsgrSolver::initInterfaceVars(int level, int i,int j,int k,int workSet, bool initMass) {
01002     LbmFloat *ccel = &QCELL(level ,i,j,k, workSet,0);
01003     LbmFloat nrho = 0.0;
01004     FORDF0 { nrho += RAC(ccel,l); }
01005     if(initMass) {
01006         RAC(ccel,dMass) = nrho;
01007     RAC(ccel, dFfrac) = 1.;
01008     } else {
01009         // preinited, e.g. from reinitFlags
01010         RAC(ccel, dFfrac) = RAC(ccel, dMass)/nrho;
01011         RAC(ccel, dFlux) = FLUX_INIT;
01012     }
01013 }
01014 
01015 
01016 #endif
01017 
01018