Blender  V2.59
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