Blender V2.61 - r43446
|
00001 00004 /****************************************************************************** 00005 * 00006 * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method 00007 * Copyright 2003-2006 Nils Thuerey 00008 * 00009 * Adaptivity functions 00010 * 00011 *****************************************************************************/ 00012 00013 #include "solver_class.h" 00014 #include "solver_relax.h" 00015 #include "particletracer.h" 00016 00017 00018 00019 /*****************************************************************************/ 00021 /*****************************************************************************/ 00022 00023 00024 00025 void LbmFsgrSolver::coarseCalculateFluxareas(int lev) 00026 { 00027 FSGR_FORIJK_BOUNDS(lev) { 00028 if( RFLAG(lev, i,j,k,mLevel[lev].setCurr) & CFFluid) { 00029 if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & CFGrFromCoarse) { 00030 LbmFloat totArea = mFsgrCellArea[0]; // for l=0 00031 for(int l=1; l<this->cDirNum; l++) { 00032 int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l]; 00033 if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)& 00034 (CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) 00035 ) { 00036 totArea += mFsgrCellArea[l]; 00037 } 00038 } // l 00039 QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = totArea; 00040 //continue; 00041 } else 00042 if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & (CFEmpty|CFUnused)) { 00043 QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 1.0; 00044 //continue; 00045 } else { 00046 QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 0.0; 00047 } 00048 //errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) ); 00049 } 00050 } // } TEST DEBUG 00051 if(!this->mSilent){ debMsgStd("coarseCalculateFluxareas",DM_MSG,"level "<<lev<<" calculated", 7); } 00052 } 00053 00054 void LbmFsgrSolver::coarseAdvance(int lev) 00055 { 00056 LbmFloat calcCurrentMass = 0.0; 00057 LbmFloat calcCurrentVolume = 0.0; 00058 00059 LbmFloat *ccel = NULL; 00060 LbmFloat *tcel = NULL; 00061 LbmFloat m[LBM_DFNUM]; 00062 LbmFloat rho, ux, uy, uz, tmp, usqr, lcsmqo; 00063 #if OPT3D==1 00064 LbmFloat lcsmqadd, lcsmeq[LBM_DFNUM], lcsmomega; 00065 #endif // OPT3D==true 00066 m[0] = tmp = usqr = 0.0; 00067 00068 coarseCalculateFluxareas(lev); 00069 // copied from fineAdv. 00070 CellFlagType *pFlagSrc = &RFLAG(lev, 1,1,getForZMin1(),SRCS(lev)); 00071 CellFlagType *pFlagDst = &RFLAG(lev, 1,1,getForZMin1(),TSET(lev)); 00072 pFlagSrc -= 1; 00073 pFlagDst -= 1; 00074 ccel = RACPNT(lev, 1,1,getForZMin1() ,SRCS(lev)); // QTEST 00075 ccel -= QCELLSTEP; 00076 tcel = RACPNT(lev, 1,1,getForZMin1() ,TSET(lev)); // QTEST 00077 tcel -= QCELLSTEP; 00078 //if(strstr(this->getName().c_str(),"Debug")){ errMsg("DEBUG","DEBUG!!!!!!!!!!!!!!!!!!!!!!!"); } 00079 00080 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { 00081 for(int j=1;j<mLevel[lev].lSizey-1;++j) { 00082 for(int i=1;i<mLevel[lev].lSizex-1;++i) { 00083 #if FSGR_STRICT_DEBUG==1 00084 rho = ux = uy = uz = tmp = usqr = -100.0; // DEBUG 00085 #endif 00086 pFlagSrc++; 00087 pFlagDst++; 00088 ccel += QCELLSTEP; 00089 tcel += QCELLSTEP; 00090 00091 // from coarse cells without unused nbs are not necessary...! -> remove 00092 if( ((*pFlagSrc) & (CFGrFromCoarse)) ) { 00093 bool invNb = false; 00094 FORDF1 { if(RFLAG_NB(lev, i, j, k, SRCS(lev), l) & CFUnused) { invNb = true; } } 00095 if(!invNb) { 00096 // WARNING - this modifies source flag array... 00097 *pFlagSrc = CFFluid|CFGrNorm; 00098 #if ELBEEM_PLUGIN!=1 00099 errMsg("coarseAdvance","FC2NRM_CHECK Converted CFGrFromCoarse to Norm at "<<lev<<" "<<PRINT_IJK); 00100 #endif // ELBEEM_PLUGIN!=1 00101 // move to perform coarsening? 00102 } 00103 } // */ 00104 00105 #if FSGR_STRICT_DEBUG==1 00106 *pFlagDst = *pFlagSrc; // always set other set... 00107 #else 00108 *pFlagDst = (*pFlagSrc & (~CFGrCoarseInited)); // always set other set... , remove coarse inited flag 00109 #endif 00110 00111 // old INTCFCOARSETEST==1 00112 if((*pFlagSrc) & CFGrFromCoarse) { // interpolateFineFromCoarse test! 00113 if(( this->mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) { 00114 FORDF0 { RAC(tcel,l) = RAC(ccel,l); } 00115 } else { 00116 interpolateCellFromCoarse( lev, i,j,k, TSET(lev), 0.0, CFFluid|CFGrFromCoarse, false); 00117 this->mNumUsedCells++; 00118 } 00119 continue; // interpolateFineFromCoarse test! 00120 } // interpolateFineFromCoarse test! old INTCFCOARSETEST==1 00121 00122 if( ((*pFlagSrc) & (CFFluid)) ) { 00123 ccel = RACPNT(lev, i,j,k ,SRCS(lev)); 00124 tcel = RACPNT(lev, i,j,k ,TSET(lev)); 00125 00126 if( ((*pFlagSrc) & (CFGrFromFine)) ) { 00127 FORDF0 { RAC(tcel,l) = RAC(ccel,l); } // always copy...? 00128 continue; // comes from fine grid 00129 } 00130 // also ignore CFGrFromCoarse 00131 else if( ((*pFlagSrc) & (CFGrFromCoarse)) ) { 00132 FORDF0 { RAC(tcel,l) = RAC(ccel,l); } // always copy...? 00133 continue; 00134 } 00135 00136 OPTIMIZED_STREAMCOLLIDE; 00137 *pFlagDst |= CFNoBndFluid; // test? 00138 calcCurrentVolume += RAC(ccel,dFlux); 00139 calcCurrentMass += RAC(ccel,dFlux)*rho; 00140 //ebugMarkCell(lev+1, 2*i+1,2*j+1,2*k ); 00141 #if FSGR_STRICT_DEBUG==1 00142 if(rho<-1.0){ debugMarkCell(lev, i,j,k ); 00143 errMsg("INVRHOCELL_CHECK"," l"<<lev<<" "<< PRINT_IJK<<" rho:"<<rho ); 00144 CAUSE_PANIC; 00145 } 00146 #endif // FSGR_STRICT_DEBUG==1 00147 this->mNumUsedCells++; 00148 00149 } 00150 } 00151 pFlagSrc+=2; // after x 00152 pFlagDst+=2; // after x 00153 ccel += (QCELLSTEP*2); 00154 tcel += (QCELLSTEP*2); 00155 } 00156 pFlagSrc+= mLevel[lev].lSizex*2; // after y 00157 pFlagDst+= mLevel[lev].lSizex*2; // after y 00158 ccel += (QCELLSTEP*mLevel[lev].lSizex*2); 00159 tcel += (QCELLSTEP*mLevel[lev].lSizex*2); 00160 } // all cell loop k,j,i 00161 00162 00163 //errMsg("coarseAdvance","level "<<lev<<" stepped from "<<mLevel[lev].setCurr<<" to "<<mLevel[lev].setOther); 00164 if(!this->mSilent){ errMsg("coarseAdvance","level "<<lev<<" stepped from "<<SRCS(lev)<<" to "<<TSET(lev)); } 00165 // */ 00166 00167 // update other set 00168 mLevel[lev].setOther = mLevel[lev].setCurr; 00169 mLevel[lev].setCurr ^= 1; 00170 mLevel[lev].lsteps++; 00171 mLevel[lev].lmass = calcCurrentMass * mLevel[lev].lcellfactor; 00172 mLevel[lev].lvolume = calcCurrentVolume * mLevel[lev].lcellfactor; 00173 #if ELBEEM_PLUGIN!=1 00174 debMsgStd("LbmFsgrSolver::coarseAdvance",DM_NOTIFY, "mass: lev="<<lev<<" m="<<mLevel[lev].lmass<<" c="<<calcCurrentMass<<" lcf="<< mLevel[lev].lcellfactor, 8 ); 00175 debMsgStd("LbmFsgrSolver::coarseAdvance",DM_NOTIFY, "volume: lev="<<lev<<" v="<<mLevel[lev].lvolume<<" c="<<calcCurrentVolume<<" lcf="<< mLevel[lev].lcellfactor, 8 ); 00176 #endif // ELBEEM_PLUGIN 00177 } 00178 00179 /*****************************************************************************/ 00181 /*****************************************************************************/ 00182 00183 00184 // get dfs from level (lev+1) to (lev) coarse border nodes 00185 void LbmFsgrSolver::coarseRestrictFromFine(int lev) 00186 { 00187 if((lev<0) || ((lev+1)>mMaxRefine)) return; 00188 #if FSGR_STRICT_DEBUG==1 00189 // reset all unused cell values to invalid 00190 int unuCnt = 0; 00191 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { 00192 for(int j=1;j<mLevel[lev].lSizey-1;++j) { 00193 for(int i=1;i<mLevel[lev].lSizex-1;++i) { 00194 CellFlagType *pFlagSrc = &RFLAG(lev, i,j,k,mLevel[lev].setCurr); 00195 if( ((*pFlagSrc) & (CFFluid|CFGrFromFine)) == (CFFluid|CFGrFromFine) ) { 00196 FORDF0{ QCELL(lev, i,j,k,mLevel[lev].setCurr, l) = -10000.0; } 00197 unuCnt++; 00198 // set here 00199 } else if( ((*pFlagSrc) & (CFFluid|CFGrNorm)) == (CFFluid|CFGrNorm) ) { 00200 // simulated... 00201 } else { 00202 // reset in interpolation 00203 //errMsg("coarseRestrictFromFine"," reset l"<<lev<<" "<<PRINT_IJK); 00204 } 00205 if( ((*pFlagSrc) & (CFEmpty|CFUnused)) ) { // test, also reset? 00206 FORDF0{ QCELL(lev, i,j,k,mLevel[lev].setCurr, l) = -10000.0; } 00207 } // test 00208 } } } 00209 errMsg("coarseRestrictFromFine"," reset l"<<lev<<" fluid|coarseBorder cells: "<<unuCnt); 00210 #endif // FSGR_STRICT_DEBUG==1 00211 const int srcSet = mLevel[lev+1].setCurr; 00212 const int dstSet = mLevel[lev].setCurr; 00213 00214 //restrict 00215 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { 00216 for(int j=1;j<mLevel[lev].lSizey-1;++j) { 00217 for(int i=1;i<mLevel[lev].lSizex-1;++i) { 00218 CellFlagType *pFlagSrc = &RFLAG(lev, i,j,k,dstSet); 00219 if((*pFlagSrc) & (CFFluid)) { 00220 if( ((*pFlagSrc) & (CFFluid|CFGrFromFine)) == (CFFluid|CFGrFromFine) ) { 00221 // do resctriction 00222 mNumInterdCells++; 00223 coarseRestrictCell(lev, i,j,k,srcSet,dstSet); 00224 00225 this->mNumUsedCells++; 00226 } // from fine & fluid 00227 else { 00228 if(RFLAG(lev+1, 2*i,2*j,2*k,srcSet) & CFGrFromCoarse) { 00229 RFLAG(lev, i,j,k,dstSet) |= CFGrToFine; 00230 } else { 00231 RFLAG(lev, i,j,k,dstSet) &= (~CFGrToFine); 00232 } 00233 } 00234 } // & fluid 00235 }}} 00236 if(!this->mSilent){ errMsg("coarseRestrictFromFine"," from l"<<(lev+1)<<",s"<<mLevel[lev+1].setCurr<<" to l"<<lev<<",s"<<mLevel[lev].setCurr); } 00237 } 00238 00239 bool LbmFsgrSolver::adaptGrid(int lev) { 00240 if((lev<0) || ((lev+1)>mMaxRefine)) return false; 00241 bool change = false; 00242 { // refinement, PASS 1-3 00243 00244 //bool nbsok; 00245 // FIXME remove TIMEINTORDER ? 00246 LbmFloat interTime = 0.0; 00247 // update curr from other, as streaming afterwards works on curr 00248 // thus read only from srcSet, modify other 00249 const int srcSet = mLevel[lev].setOther; 00250 const int dstSet = mLevel[lev].setCurr; 00251 const int srcFineSet = mLevel[lev+1].setCurr; 00252 const bool debugRefinement = false; 00253 00254 // use //template functions for 2D/3D 00255 /*if(strstr(this->getName().c_str(),"Debug")) 00256 if(lev+1==mMaxRefine) { // mixborder 00257 for(int l=0;((l<this->cDirNum) && (!removeFromFine)); l++) { // FARBORD 00258 int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l]; 00259 if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&CFBnd) { // NEWREFT 00260 removeFromFine=true; 00261 } 00262 } 00263 } // FARBORD */ 00264 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { 00265 for(int j=1;j<mLevel[lev].lSizey-1;++j) { 00266 for(int i=1;i<mLevel[lev].lSizex-1;++i) { 00267 00268 if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) { 00269 bool removeFromFine = false; 00270 const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); 00271 CellFlagType reqType = CFGrNorm; 00272 if(lev+1==mMaxRefine) reqType = CFNoBndFluid; 00273 00274 if( (RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet) & reqType) && 00275 (!(RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet) & (notAllowed)) ) ){ // ok 00276 } else { 00277 removeFromFine=true; 00278 } 00279 00280 if(removeFromFine) { 00281 // dont turn CFGrFromFine above interface cells into CFGrNorm 00282 //errMsg("performRefinement","Removing CFGrFromFine on lev"<<lev<<" " <<PRINT_IJK<<" srcflag:"<<convertCellFlagType2String(RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet)) <<" set:"<<dstSet ); 00283 RFLAG(lev, i,j,k, dstSet) = CFEmpty; 00284 #if FSGR_STRICT_DEBUG==1 00285 // for interpolation later on during fine grid fixing 00286 // these cells are still correctly inited 00287 RFLAG(lev, i,j,k, dstSet) |= CFGrCoarseInited; // remove later on? FIXME? 00288 #endif // FSGR_STRICT_DEBUG==1 00289 //RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFEmpty; // FLAGTEST 00290 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,i,j,k); 00291 change=true; 00292 mNumFsgrChanges++; 00293 for(int l=1; l<this->cDirNum; l++) { 00294 int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; 00295 //errMsg("performRefinement","On lev:"<<lev<<" check: "<<PRINT_VEC(ni,nj,nk)<<" set:"<<dstSet<<" = "<<convertCellFlagType2String(RFLAG(lev, ni,nj,nk, srcSet)) ); 00296 if( ( RFLAG(lev, ni,nj,nk, srcSet)&CFFluid ) && 00297 (!(RFLAG(lev, ni,nj,nk, srcSet)&CFGrFromFine)) ) { // dont change status of nb. from fine cells 00298 // tag as inited for debugging, cell contains fluid DFs anyway 00299 RFLAG(lev, ni,nj,nk, dstSet) = CFFluid|CFGrFromFine|CFGrCoarseInited; 00300 //errMsg("performRefinement","On lev:"<<lev<<" set to from fine: "<<PRINT_VEC(ni,nj,nk)<<" set:"<<dstSet); 00301 //if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk); 00302 } 00303 } // l 00304 00305 // FIXME fix fine level? 00306 } 00307 00308 // recheck from fine flag 00309 } 00310 }}} // TEST 00311 // PASS 1 */ 00312 00313 00314 /*if( ((*pFlagSrc) & (CFGrFromCoarse)) ) { 00315 bool invNb = false; 00316 FORDF1 { 00317 if(RFLAG_NB(lev, i, j, k, SRCS(lev), l) & CFUnused) { invNb = true; } 00318 } 00319 if(!invNb) { 00320 *pFlagSrc = CFFluid|CFGrNorm; 00321 errMsg("coarseAdvance","FC2NRM_CHECK Converted CFGrFromCoarse to Norm at "<<lev<<" "<<PRINT_IJK); 00322 } 00323 } // */ 00324 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { // TEST 00325 for(int j=1;j<mLevel[lev].lSizey-1;++j) { // TEST 00326 for(int i=1;i<mLevel[lev].lSizex-1;++i) { // TEST 00327 00328 // test from coarseAdvance 00329 // from coarse cells without unused nbs are not necessary...! -> remove 00330 00331 if(RFLAG(lev, i,j,k, srcSet) & CFGrFromCoarse) { 00332 00333 // from coarse cells without unused nbs are not necessary...! -> remove 00334 bool invNb = false; 00335 bool fluidNb = false; 00336 for(int l=1; l<this->cDirNum; l++) { 00337 if(RFLAG_NB(lev, i, j, k, srcSet, l) & CFUnused) { invNb = true; } 00338 if(RFLAG_NB(lev, i, j, k, srcSet, l) & (CFGrNorm)) { fluidNb = true; } 00339 } 00340 if(!invNb) { 00341 // no unused cells around -> calculate normally from now on 00342 RFLAG(lev, i,j,k, dstSet) = CFFluid|CFGrNorm; 00343 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k); 00344 change=true; 00345 mNumFsgrChanges++; 00346 } // from advance 00347 if(!fluidNb) { 00348 // no fluid cells near -> no transfer necessary 00349 RFLAG(lev, i,j,k, dstSet) = CFUnused; 00350 //RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFUnused; // FLAGTEST 00351 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k); 00352 change=true; 00353 mNumFsgrChanges++; 00354 } // from advance 00355 00356 00357 // dont allow double transfer 00358 // this might require fixing the neighborhood 00359 if(RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&(CFGrFromCoarse)) { 00360 // dont turn CFGrFromFine above interface cells into CFGrNorm 00361 //errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<lev<<" " <<PRINT_IJK<<" due to finer from coarse cell " ); 00362 RFLAG(lev, i,j,k, dstSet) = CFFluid|CFGrNorm; 00363 if(lev>0) RFLAG(lev-1, i/2,j/2,k/2, mLevel[lev-1].setCurr) &= (~CFGrToFine); // TODO add more of these? 00364 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k); 00365 change=true; 00366 mNumFsgrChanges++; 00367 for(int l=1; l<this->cDirNum; l++) { 00368 int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; 00369 if(RFLAG(lev, ni,nj,nk, srcSet)&(CFGrNorm)) { //ok 00370 for(int m=1; m<this->cDirNum; m++) { 00371 int mi= ni +this->dfVecX[m], mj= nj +this->dfVecY[m], mk= nk +this->dfVecZ[m]; 00372 if(RFLAG(lev, mi, mj, mk, srcSet)&CFUnused) { 00373 // norm cells in neighborhood with unused nbs have to be new border... 00374 RFLAG(lev, ni,nj,nk, dstSet) = CFFluid|CFGrFromCoarse; 00375 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk); 00376 } 00377 } 00378 // these alreay have valid values... 00379 } 00380 else if(RFLAG(lev, ni,nj,nk, srcSet)&(CFUnused)) { //ok 00381 // this should work because we have a valid neighborhood here for now 00382 interpolateCellFromCoarse(lev, ni, nj, nk, dstSet, interTime, CFFluid|CFGrFromCoarse, false); 00383 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk); 00384 mNumFsgrChanges++; 00385 } 00386 } // l 00387 } // double transer 00388 00389 } // from coarse 00390 00391 } } } 00392 // PASS 2 */ 00393 00394 00395 // fix dstSet from fine cells here 00396 // warning - checks CFGrFromFine on dstset changed before! 00397 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { // TEST 00398 for(int j=1;j<mLevel[lev].lSizey-1;++j) { // TEST 00399 for(int i=1;i<mLevel[lev].lSizex-1;++i) { // TEST 00400 00401 //if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) { 00402 if(RFLAG(lev, i,j,k, dstSet) & CFGrFromFine) { 00403 // modify finer level border 00404 if((RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&(CFGrFromCoarse))) { 00405 //errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<(lev+1)<<" from l"<<lev<<" " <<PRINT_IJK ); 00406 CellFlagType setf = CFFluid; 00407 if(lev+1 < mMaxRefine) setf = CFFluid|CFGrNorm; 00408 RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)=setf; 00409 change=true; 00410 mNumFsgrChanges++; 00411 for(int l=1; l<this->cDirNum; l++) { 00412 int bi=(2*i)+this->dfVecX[l], bj=(2*j)+this->dfVecY[l], bk=(2*k)+this->dfVecZ[l]; 00413 if(RFLAG(lev+1, bi, bj, bk, srcFineSet)&(CFGrFromCoarse)) { 00414 //errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) ); 00415 RFLAG(lev+1, bi, bj, bk, srcFineSet) = setf; 00416 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk); 00417 } 00418 else if(RFLAG(lev+1, bi, bj, bk, srcFineSet)&(CFUnused )) { 00419 //errMsg("performRefinement","Removing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) ); 00420 interpolateCellFromCoarse(lev+1, bi, bj, bk, srcFineSet, interTime, setf, false); 00421 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk); 00422 mNumFsgrChanges++; 00423 } 00424 } 00425 for(int l=1; l<this->cDirNum; l++) { 00426 int bi=(2*i)+this->dfVecX[l], bj=(2*j)+this->dfVecY[l], bk=(2*k)+this->dfVecZ[l]; 00427 if( (RFLAG(lev+1, bi, bj, bk, srcFineSet)&CFFluid ) && 00428 (!(RFLAG(lev+1, bi, bj, bk, srcFineSet)&CFGrFromCoarse)) ) { 00429 // all unused nbs now of coarse have to be from coarse 00430 for(int m=1; m<this->cDirNum; m++) { 00431 int mi= bi +this->dfVecX[m], mj= bj +this->dfVecY[m], mk= bk +this->dfVecZ[m]; 00432 if(RFLAG(lev+1, mi, mj, mk, srcFineSet)&CFUnused) { 00433 //errMsg("performRefinement","Changing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(mi,mj,mk) ); 00434 interpolateCellFromCoarse(lev+1, mi, mj, mk, srcFineSet, interTime, CFFluid|CFGrFromCoarse, false); 00435 if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,mi,mj,mk); 00436 mNumFsgrChanges++; 00437 } 00438 } 00439 // nbs prepared... 00440 } 00441 } 00442 } 00443 00444 } // convert regions of from fine 00445 }}} // TEST 00446 // PASS 3 */ 00447 00448 if(!this->mSilent){ errMsg("performRefinement"," for l"<<lev<<" done ("<<change<<") " ); } 00449 } // PASS 1-3 00450 // refinement done 00451 00452 //LbmFsgrSolver::performCoarsening(int lev) { 00453 { // PASS 4,5 00454 bool nbsok; 00455 // WARNING 00456 // now work on modified curr set 00457 const int srcSet = mLevel[lev].setCurr; 00458 const int dstlev = lev+1; 00459 const int dstFineSet = mLevel[dstlev].setCurr; 00460 const bool debugCoarsening = false; 00461 00462 // PASS 5 test DEBUG 00463 /*if(this->mInitDone) { 00464 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { 00465 for(int j=1;j<mLevel[lev].lSizey-1;++j) { 00466 for(int i=1;i<mLevel[lev].lSizex-1;++i) { 00467 if(RFLAG(lev, i,j,k, srcSet) & CFEmpty) { 00468 // check empty -> from fine conversion 00469 bool changeToFromFine = false; 00470 const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); 00471 CellFlagType reqType = CFGrNorm; 00472 if(lev+1==mMaxRefine) reqType = CFNoBndFluid; 00473 if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & reqType) && 00474 (!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){ 00475 changeToFromFine=true; } 00476 if(changeToFromFine) { 00477 change = true; 00478 mNumFsgrChanges++; 00479 RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrFromFine; 00480 if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k); 00481 // same as restr from fine func! not necessary ?! 00482 // coarseRestrictFromFine part 00483 coarseRestrictCell(lev, i,j,k,srcSet, dstFineSet); 00484 } 00485 } // only check empty cells 00486 }}} // TEST! 00487 } // PASS 5 */ 00488 00489 // use //template functions for 2D/3D 00490 /*if(strstr(this->getName().c_str(),"Debug")) 00491 if((nbsok)&&(lev+1==mMaxRefine)) { // mixborder 00492 for(int l=0;((l<this->cDirNum) && (nbsok)); l++) { // FARBORD 00493 int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l]; 00494 if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT 00495 nbsok=false; 00496 } 00497 } 00498 } // FARBORD */ 00499 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { 00500 for(int j=1;j<mLevel[lev].lSizey-1;++j) { 00501 for(int i=1;i<mLevel[lev].lSizex-1;++i) { 00502 00503 // from coarse cells without unused nbs are not necessary...! -> remove 00504 // perform check from coarseAdvance here? 00505 if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) { 00506 // remove from fine cells now that are completely in fluid 00507 // FIXME? check that new from fine in performRefinement never get deleted here afterwards? 00508 // or more general, one cell never changed more than once? 00509 const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); 00510 //const CellFlagType notNbAllowed = (CFInter|CFBnd|CFGrFromFine); unused 00511 CellFlagType reqType = CFGrNorm; 00512 if(lev+1==mMaxRefine) reqType = CFNoBndFluid; 00513 00514 nbsok = true; 00515 for(int l=0; l<this->cDirNum && nbsok; l++) { 00516 int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l]; 00517 if( (RFLAG(lev+1, ni,nj,nk, dstFineSet) & reqType) && 00518 (!(RFLAG(lev+1, ni,nj,nk, dstFineSet) & (notAllowed)) ) ){ 00519 // ok 00520 } else { 00521 nbsok=false; 00522 } 00523 // FARBORD 00524 } 00525 // dont turn CFGrFromFine above interface cells into CFGrNorm 00526 // now check nbs on same level 00527 for(int l=1; l<this->cDirNum && nbsok; l++) { 00528 int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; 00529 if(RFLAG(lev, ni,nj,nk, srcSet)&(CFFluid)) { //ok 00530 } else { 00531 nbsok = false; 00532 } 00533 } // l 00534 00535 if(nbsok) { 00536 // conversion to coarse fluid cell 00537 change = true; 00538 mNumFsgrChanges++; 00539 RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrNorm; 00540 // dfs are already ok... 00541 //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine changed to CFGrNorm at lev"<<lev<<" " <<PRINT_IJK ); 00542 if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k); 00543 00544 // only check complete cubes 00545 for(int dx=-1;dx<=1;dx+=2) { 00546 for(int dy=-1;dy<=1;dy+=2) { 00547 for(int dz=-1*(LBMDIM&1);dz<=1*(LBMDIM&1);dz+=2) { // 2d/3d 00548 // check for norm and from coarse, as the coarse level might just have been refined... 00549 if( 00550 // we now the flag of the current cell! ( RFLAG(lev, i , j , k , srcSet)&(CFGrNorm)) && 00551 ( RFLAG(lev, i+dx, j , k , srcSet)&(CFGrNorm|CFGrFromCoarse)) && 00552 ( RFLAG(lev, i , j+dy, k , srcSet)&(CFGrNorm|CFGrFromCoarse)) && 00553 ( RFLAG(lev, i , j , k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) && 00554 00555 ( RFLAG(lev, i+dx, j+dy, k , srcSet)&(CFGrNorm|CFGrFromCoarse)) && 00556 ( RFLAG(lev, i+dx, j , k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) && 00557 ( RFLAG(lev, i , j+dy, k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) && 00558 ( RFLAG(lev, i+dx, j+dy, k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) 00559 ) { 00560 // middle source node on higher level 00561 int dstx = (2*i)+dx; 00562 int dsty = (2*j)+dy; 00563 int dstz = (2*k)+dz; 00564 00565 mNumFsgrChanges++; 00566 RFLAG(dstlev, dstx,dsty,dstz, dstFineSet) = CFUnused; 00567 RFLAG(dstlev, dstx,dsty,dstz, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST 00568 //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init center unused set l"<<dstlev<<" at "<<PRINT_VEC(dstx,dsty,dstz) ); 00569 00570 for(int l=1; l<this->cDirNum; l++) { 00571 int dstni=dstx+this->dfVecX[l], dstnj=dsty+this->dfVecY[l], dstnk=dstz+this->dfVecZ[l]; 00572 if(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFFluid)) { 00573 RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse; 00574 } 00575 if(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFInter)) { 00576 //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init CHECK Warning - deleting interface cell..."); 00577 this->mFixMass += QCELL( dstlev, dstni,dstnj,dstnk, dstFineSet, dMass); 00578 RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse; 00579 } 00580 } // l 00581 00582 // again check nb flags of all surrounding cells to see if any from coarse 00583 // can be convted to unused 00584 for(int l=1; l<this->cDirNum; l++) { 00585 int dstni=dstx+this->dfVecX[l], dstnj=dsty+this->dfVecY[l], dstnk=dstz+this->dfVecZ[l]; 00586 // have to be at least from coarse here... 00587 //errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" "<< convertCellFlagType2String(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)) ); 00588 if(!(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFUnused) )) { 00589 bool delok = true; 00590 // careful long range here... check domain bounds? 00591 for(int m=1; m<this->cDirNum; m++) { 00592 int chkni=dstni+this->dfVecX[m], chknj=dstnj+this->dfVecY[m], chknk=dstnk+this->dfVecZ[m]; 00593 if(RFLAG(dstlev, chkni,chknj,chknk, dstFineSet)&(CFUnused|CFGrFromCoarse)) { 00594 // this nb cell is ok for deletion 00595 } else { 00596 delok=false; // keep it! 00597 } 00598 //errMsg("performCoarsening"," CHECK "<<PRINT_VEC(dstni,dstnj,dstnk)<<" to "<<PRINT_VEC( chkni,chknj,chknk )<<" f:"<< convertCellFlagType2String( RFLAG(dstlev, chkni,chknj,chknk, dstFineSet))<<" nbsok"<<delok ); 00599 } 00600 //errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" ok"<<delok ); 00601 if(delok) { 00602 mNumFsgrChanges++; 00603 RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFUnused; 00604 RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST 00605 if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(dstlev,dstni,dstnj,dstnk); 00606 } 00607 } 00608 } // l 00609 // treat subcube 00610 //ebugMarkCell(lev,i+dx,j+dy,k+dz); 00611 //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init, dir:"<<PRINT_VEC(dx,dy,dz) ); 00612 } 00613 } } } 00614 00615 } // ? 00616 } // convert regions of from fine 00617 }}} // TEST! 00618 // PASS 4 */ 00619 00620 // reinit cell area value 00621 /*if( RFLAG(lev, i,j,k,srcSet) & CFFluid) { 00622 if( RFLAG(lev+1, i*2,j*2,k*2,dstFineSet) & CFGrFromCoarse) { 00623 LbmFloat totArea = mFsgrCellArea[0]; // for l=0 00624 for(int l=1; l<this->cDirNum; l++) { 00625 int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l]; 00626 if(RFLAG(lev+1, ni,nj,nk, dstFineSet)& 00627 (CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) 00628 //(CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) 00629 ) { 00630 //LbmFloat area = 0.25; if(this->dfVecX[l]!=0) area *= 0.5; if(this->dfVecY[l]!=0) area *= 0.5; if(this->dfVecZ[l]!=0) area *= 0.5; 00631 totArea += mFsgrCellArea[l]; 00632 } 00633 } // l 00634 QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) = 00635 QCELL(lev, i,j,k,srcSet, dFlux) = totArea; 00636 } else { 00637 QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) = 00638 QCELL(lev, i,j,k,srcSet, dFlux) = 1.0; 00639 } 00640 //errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,srcSet, dFlux) ); 00641 } 00642 // */ 00643 00644 00645 // PASS 5 org 00646 /*if(strstr(this->getName().c_str(),"Debug")) 00647 if((changeToFromFine)&&(lev+1==mMaxRefine)) { // mixborder 00648 for(int l=0;((l<this->cDirNum) && (changeToFromFine)); l++) { // FARBORD 00649 int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l]; 00650 if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT 00651 changeToFromFine=false; } 00652 } 00653 }// FARBORD */ 00654 //if(!this->mInitDone) { 00655 for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { 00656 for(int j=1;j<mLevel[lev].lSizey-1;++j) { 00657 for(int i=1;i<mLevel[lev].lSizex-1;++i) { 00658 00659 00660 if(RFLAG(lev, i,j,k, srcSet) & CFEmpty) { 00661 // check empty -> from fine conversion 00662 bool changeToFromFine = false; 00663 const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); 00664 CellFlagType reqType = CFGrNorm; 00665 if(lev+1==mMaxRefine) reqType = CFNoBndFluid; 00666 00667 if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & reqType) && 00668 (!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){ 00669 // DEBUG 00670 changeToFromFine=true; 00671 } 00672 00673 // FARBORD 00674 00675 if(changeToFromFine) { 00676 change = true; 00677 mNumFsgrChanges++; 00678 RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrFromFine; 00679 if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k); 00680 // same as restr from fine func! not necessary ?! 00681 // coarseRestrictFromFine part 00682 } 00683 } // only check empty cells 00684 00685 }}} // TEST! 00686 //} // init done 00687 // PASS 5 */ 00688 } // coarsening, PASS 4,5 00689 00690 if(!this->mSilent){ errMsg("adaptGrid"," for l"<<lev<<" done " ); } 00691 return change; 00692 } 00693 00694 /*****************************************************************************/ 00696 /*****************************************************************************/ 00697 00698 void LbmFsgrSolver::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int dstSet) 00699 { 00700 LbmFloat *ccel = RACPNT(lev+1, 2*i,2*j,2*k,srcSet); 00701 LbmFloat *tcel = RACPNT(lev , i,j,k ,dstSet); 00702 00703 LbmFloat rho=0.0, ux=0.0, uy=0.0, uz=0.0; 00704 //LbmFloat *ccel = NULL; 00705 //LbmFloat *tcel = NULL; 00706 #if OPT3D==1 00707 LbmFloat m[LBM_DFNUM]; 00708 // for macro add 00709 LbmFloat usqr; 00710 //LbmFloat *addfcel, *dstcell; 00711 LbmFloat lcsmqadd, lcsmqo, lcsmeq[LBM_DFNUM]; 00712 LbmFloat lcsmDstOmega, lcsmSrcOmega, lcsmdfscale; 00713 #else // OPT3D==true 00714 LbmFloat df[LBM_DFNUM]; 00715 LbmFloat omegaDst, omegaSrc; 00716 LbmFloat feq[LBM_DFNUM]; 00717 LbmFloat dfScale = mDfScaleUp; 00718 #endif // OPT3D==true 00719 00720 # if OPT3D==0 00721 // add up weighted dfs 00722 FORDF0{ df[l] = 0.0;} 00723 for(int n=0;(n<this->cDirNum); n++) { 00724 int ni=2*i+1*this->dfVecX[n], nj=2*j+1*this->dfVecY[n], nk=2*k+1*this->dfVecZ[n]; 00725 ccel = RACPNT(lev+1, ni,nj,nk,srcSet);// CFINTTEST 00726 const LbmFloat weight = mGaussw[n]; 00727 FORDF0{ 00728 LbmFloat cdf = weight * RAC(ccel,l); 00729 # if FSGR_STRICT_DEBUG==1 00730 if( cdf<-1.0 ){ errMsg("INVDFCREST_DFCHECK", PRINT_IJK<<" s"<<dstSet<<" from "<<PRINT_VEC(2*i,2*j,2*k)<<" s"<<srcSet<<" df"<<l<<":"<< df[l]); } 00731 # endif 00732 //errMsg("INVDFCREST_DFCHECK", PRINT_IJK<<" s"<<dstSet<<" from "<<PRINT_VEC(2*i,2*j,2*k)<<" s"<<srcSet<<" df"<<l<<":"<< df[l]<<" = "<<cdf<<" , w"<<weight); 00733 df[l] += cdf; 00734 } 00735 } 00736 00737 // calc rho etc. from weighted dfs 00738 rho = ux = uy = uz = 0.0; 00739 FORDF0{ 00740 LbmFloat cdf = df[l]; 00741 rho += cdf; 00742 ux += (this->dfDvecX[l]*cdf); 00743 uy += (this->dfDvecY[l]*cdf); 00744 uz += (this->dfDvecZ[l]*cdf); 00745 } 00746 00747 FORDF0{ feq[l] = this->getCollideEq(l, rho,ux,uy,uz); } 00748 if(mLevel[lev ].lcsmago>0.0) { 00749 const LbmFloat Qo = this->getLesNoneqTensorCoeff(df,feq); 00750 omegaDst = this->getLesOmega(mLevel[lev ].omega,mLevel[lev ].lcsmago,Qo); 00751 omegaSrc = this->getLesOmega(mLevel[lev+1].omega,mLevel[lev+1].lcsmago,Qo); 00752 } else { 00753 omegaDst = mLevel[lev+0].omega; /* NEWSMAGOT*/ 00754 omegaSrc = mLevel[lev+1].omega; 00755 } 00756 dfScale = (mLevel[lev ].timestep/mLevel[lev+1].timestep)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); // yu 00757 FORDF0{ 00758 RAC(tcel, l) = feq[l]+ (df[l]-feq[l])*dfScale; 00759 } 00760 # else // OPT3D 00761 // similar to OPTIMIZED_STREAMCOLLIDE_UNUSED 00762 00763 //rho = ux = uy = uz = 0.0; 00764 MSRC_C = CCELG_C(0) ; 00765 MSRC_N = CCELG_N(0) ; 00766 MSRC_S = CCELG_S(0) ; 00767 MSRC_E = CCELG_E(0) ; 00768 MSRC_W = CCELG_W(0) ; 00769 MSRC_T = CCELG_T(0) ; 00770 MSRC_B = CCELG_B(0) ; 00771 MSRC_NE = CCELG_NE(0); 00772 MSRC_NW = CCELG_NW(0); 00773 MSRC_SE = CCELG_SE(0); 00774 MSRC_SW = CCELG_SW(0); 00775 MSRC_NT = CCELG_NT(0); 00776 MSRC_NB = CCELG_NB(0); 00777 MSRC_ST = CCELG_ST(0); 00778 MSRC_SB = CCELG_SB(0); 00779 MSRC_ET = CCELG_ET(0); 00780 MSRC_EB = CCELG_EB(0); 00781 MSRC_WT = CCELG_WT(0); 00782 MSRC_WB = CCELG_WB(0); 00783 for(int n=1;(n<this->cDirNum); n++) { 00784 ccel = RACPNT(lev+1, 2*i+1*this->dfVecX[n], 2*j+1*this->dfVecY[n], 2*k+1*this->dfVecZ[n] ,srcSet); 00785 MSRC_C += CCELG_C(n) ; 00786 MSRC_N += CCELG_N(n) ; 00787 MSRC_S += CCELG_S(n) ; 00788 MSRC_E += CCELG_E(n) ; 00789 MSRC_W += CCELG_W(n) ; 00790 MSRC_T += CCELG_T(n) ; 00791 MSRC_B += CCELG_B(n) ; 00792 MSRC_NE += CCELG_NE(n); 00793 MSRC_NW += CCELG_NW(n); 00794 MSRC_SE += CCELG_SE(n); 00795 MSRC_SW += CCELG_SW(n); 00796 MSRC_NT += CCELG_NT(n); 00797 MSRC_NB += CCELG_NB(n); 00798 MSRC_ST += CCELG_ST(n); 00799 MSRC_SB += CCELG_SB(n); 00800 MSRC_ET += CCELG_ET(n); 00801 MSRC_EB += CCELG_EB(n); 00802 MSRC_WT += CCELG_WT(n); 00803 MSRC_WB += CCELG_WB(n); 00804 } 00805 rho = MSRC_C + MSRC_N + MSRC_S + MSRC_E + MSRC_W + MSRC_T 00806 + MSRC_B + MSRC_NE + MSRC_NW + MSRC_SE + MSRC_SW + MSRC_NT 00807 + MSRC_NB + MSRC_ST + MSRC_SB + MSRC_ET + MSRC_EB + MSRC_WT + MSRC_WB; 00808 ux = MSRC_E - MSRC_W + MSRC_NE - MSRC_NW + MSRC_SE - MSRC_SW 00809 + MSRC_ET + MSRC_EB - MSRC_WT - MSRC_WB; 00810 uy = MSRC_N - MSRC_S + MSRC_NE + MSRC_NW - MSRC_SE - MSRC_SW 00811 + MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB; 00812 uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB 00813 + MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB; 00814 usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ 00815 \ 00816 lcsmeq[dC] = EQC ; \ 00817 COLL_CALCULATE_DFEQ(lcsmeq); \ 00818 COLL_CALCULATE_NONEQTENSOR(lev+0, MSRC_ )\ 00819 COLL_CALCULATE_CSMOMEGAVAL(lev+0, lcsmDstOmega); \ 00820 COLL_CALCULATE_CSMOMEGAVAL(lev+1, lcsmSrcOmega); \ 00821 \ 00822 lcsmdfscale = (mLevel[lev+0].timestep/mLevel[lev+1].timestep)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0); \ 00823 RAC(tcel, dC ) = (lcsmeq[dC ] + (MSRC_C -lcsmeq[dC ] )*lcsmdfscale); 00824 RAC(tcel, dN ) = (lcsmeq[dN ] + (MSRC_N -lcsmeq[dN ] )*lcsmdfscale); 00825 RAC(tcel, dS ) = (lcsmeq[dS ] + (MSRC_S -lcsmeq[dS ] )*lcsmdfscale); 00826 RAC(tcel, dE ) = (lcsmeq[dE ] + (MSRC_E -lcsmeq[dE ] )*lcsmdfscale); 00827 RAC(tcel, dW ) = (lcsmeq[dW ] + (MSRC_W -lcsmeq[dW ] )*lcsmdfscale); 00828 RAC(tcel, dT ) = (lcsmeq[dT ] + (MSRC_T -lcsmeq[dT ] )*lcsmdfscale); 00829 RAC(tcel, dB ) = (lcsmeq[dB ] + (MSRC_B -lcsmeq[dB ] )*lcsmdfscale); 00830 RAC(tcel, dNE) = (lcsmeq[dNE] + (MSRC_NE-lcsmeq[dNE] )*lcsmdfscale); 00831 RAC(tcel, dNW) = (lcsmeq[dNW] + (MSRC_NW-lcsmeq[dNW] )*lcsmdfscale); 00832 RAC(tcel, dSE) = (lcsmeq[dSE] + (MSRC_SE-lcsmeq[dSE] )*lcsmdfscale); 00833 RAC(tcel, dSW) = (lcsmeq[dSW] + (MSRC_SW-lcsmeq[dSW] )*lcsmdfscale); 00834 RAC(tcel, dNT) = (lcsmeq[dNT] + (MSRC_NT-lcsmeq[dNT] )*lcsmdfscale); 00835 RAC(tcel, dNB) = (lcsmeq[dNB] + (MSRC_NB-lcsmeq[dNB] )*lcsmdfscale); 00836 RAC(tcel, dST) = (lcsmeq[dST] + (MSRC_ST-lcsmeq[dST] )*lcsmdfscale); 00837 RAC(tcel, dSB) = (lcsmeq[dSB] + (MSRC_SB-lcsmeq[dSB] )*lcsmdfscale); 00838 RAC(tcel, dET) = (lcsmeq[dET] + (MSRC_ET-lcsmeq[dET] )*lcsmdfscale); 00839 RAC(tcel, dEB) = (lcsmeq[dEB] + (MSRC_EB-lcsmeq[dEB] )*lcsmdfscale); 00840 RAC(tcel, dWT) = (lcsmeq[dWT] + (MSRC_WT-lcsmeq[dWT] )*lcsmdfscale); 00841 RAC(tcel, dWB) = (lcsmeq[dWB] + (MSRC_WB-lcsmeq[dWB] )*lcsmdfscale); 00842 # endif // OPT3D==0 00843 } 00844 00845 void LbmFsgrSolver::interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet, bool markNbs) { 00846 LbmFloat rho=0.0, ux=0.0, uy=0.0, uz=0.0; 00847 LbmFloat intDf[19] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; 00848 00849 #if OPT3D==1 00850 // for macro add 00851 LbmFloat addDfFacT, addVal, usqr; 00852 LbmFloat *addfcel, *dstcell; 00853 LbmFloat lcsmqadd, lcsmqo, lcsmeq[LBM_DFNUM]; 00854 LbmFloat lcsmDstOmega, lcsmSrcOmega, lcsmdfscale; 00855 #endif // OPT3D==true 00856 00857 // SET required nbs to from coarse (this might overwrite flag several times) 00858 // this is not necessary for interpolateFineFromCoarse 00859 if(markNbs) { 00860 FORDF1{ 00861 int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; 00862 if(RFLAG(lev,ni,nj,nk,dstSet)&CFUnused) { 00863 // parents have to be inited! 00864 interpolateCellFromCoarse(lev, ni, nj, nk, dstSet, t, CFFluid|CFGrFromCoarse, false); 00865 } 00866 } } 00867 00868 // change flag of cell to be interpolated 00869 RFLAG(lev,i,j,k, dstSet) = flagSet; 00870 mNumInterdCells++; 00871 00872 // interpolation lines... 00873 int betx = i&1; 00874 int bety = j&1; 00875 int betz = k&1; 00876 00877 if((!betx) && (!bety) && (!betz)) { 00878 ADD_INT_DFS(lev-1, i/2 ,j/2 ,k/2 , 0.0, 1.0); 00879 } 00880 else if(( betx) && (!bety) && (!betz)) { 00881 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D1); 00882 ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D1); 00883 } 00884 else if((!betx) && ( bety) && (!betz)) { 00885 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D1); 00886 ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D1); 00887 } 00888 else if((!betx) && (!bety) && ( betz)) { 00889 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D1); 00890 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D1); 00891 } 00892 else if(( betx) && ( bety) && (!betz)) { 00893 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D2); 00894 ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D2); 00895 ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D2); 00896 ADD_INT_DFS(lev-1, (i/2)+1,(j/2)+1,(k/2) , t, WO1D2); 00897 } 00898 else if((!betx) && ( bety) && ( betz)) { 00899 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D2); 00900 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D2); 00901 ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D2); 00902 ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2)+1, t, WO1D2); 00903 } 00904 else if(( betx) && (!bety) && ( betz)) { 00905 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D2); 00906 ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D2); 00907 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D2); 00908 ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2)+1, t, WO1D2); 00909 } 00910 else if(( betx) && ( bety) && ( betz)) { 00911 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D3); 00912 ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D3); 00913 ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D3); 00914 ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2)+1, t, WO1D3); 00915 ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D3); 00916 ADD_INT_DFS(lev-1, (i/2)+1,(j/2)+1,(k/2) , t, WO1D3); 00917 ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2)+1, t, WO1D3); 00918 ADD_INT_DFS(lev-1, (i/2)+1,(j/2)+1,(k/2)+1, t, WO1D3); 00919 } 00920 else { 00921 CAUSE_PANIC; 00922 errFatal("interpolateCellFromCoarse","Invalid!?", SIMWORLD_GENERICERROR); 00923 } 00924 00925 IDF_WRITEBACK; 00926 return; 00927 } 00928 00929 00930 00931 // required globals 00932 extern bool glob_mpactive; 00933 extern int glob_mpnum, glob_mpindex; 00934 #define MPTADAP_INTERV 4 00935 00936 /*****************************************************************************/ 00938 /*****************************************************************************/ 00939 void LbmFsgrSolver::adaptTimestep() { 00940 LbmFloat massTOld=0.0, massTNew=0.0; 00941 LbmFloat volTOld=0.0, volTNew=0.0; 00942 00943 bool rescale = false; // do any rescale at all? 00944 LbmFloat scaleFac = -1.0; // timestep scaling 00945 if(mPanic) return; 00946 00947 LbmFloat levOldOmega[FSGR_MAXNOOFLEVELS]; 00948 LbmFloat levOldStepsize[FSGR_MAXNOOFLEVELS]; 00949 for(int lev=mMaxRefine; lev>=0 ; lev--) { 00950 levOldOmega[lev] = mLevel[lev].omega; 00951 levOldStepsize[lev] = mLevel[lev].timestep; 00952 } 00953 00954 const LbmFloat reduceFac = 0.8; // modify time step by 20%, TODO? do multiple times for large changes? 00955 LbmFloat diffPercent = 0.05; // dont scale if less than 5% 00956 LbmFloat allowMax = mpParam->getTadapMaxSpeed(); // maximum allowed velocity 00957 LbmFloat nextmax = mpParam->getSimulationMaxSpeed() + norm(mLevel[mMaxRefine].gravity); 00958 00959 // sync nextmax 00960 #if LBM_INCLUDE_TESTSOLVERS==1 00961 if(glob_mpactive) { 00962 if(mLevel[mMaxRefine].lsteps % MPTADAP_INTERV != MPTADAP_INTERV-1) { 00963 debMsgStd("LbmFsgrSolver::TAdp",DM_MSG, "mpact:"<<glob_mpactive<<","<<glob_mpindex<<"/"<<glob_mpnum<<" step:"<<mLevel[mMaxRefine].lsteps<<" skipping tadap...",8); 00964 return; 00965 } 00966 nextmax = mrInitTadap(nextmax); 00967 } 00968 #endif // LBM_INCLUDE_TESTSOLVERS==1 00969 00970 LbmFloat newdt = mpParam->getTimestep(); // newtr 00971 if(nextmax > allowMax/reduceFac) { 00972 mTimeMaxvelStepCnt++; } 00973 else { mTimeMaxvelStepCnt=0; } 00974 00975 // emergency, or 10 steps with high vel 00976 if((mTimeMaxvelStepCnt>5) || (nextmax> (1.0/3.0)) || (mForceTimeStepReduce) ) { 00977 newdt = mpParam->getTimestep() * reduceFac; 00978 } else { 00979 if(nextmax<allowMax*reduceFac) { 00980 newdt = mpParam->getTimestep() / reduceFac; 00981 } 00982 } // newtr 00983 //errMsg("LbmFsgrSolver::adaptTimestep","nextmax="<<nextmax<<" allowMax="<<allowMax<<" fac="<<reduceFac<<" simmaxv="<< mpParam->getSimulationMaxSpeed() ); 00984 00985 bool minCutoff = false; 00986 LbmFloat desireddt = newdt; 00987 if(newdt>mpParam->getMaxTimestep()){ newdt = mpParam->getMaxTimestep(); } 00988 if(newdt<mpParam->getMinTimestep()){ 00989 newdt = mpParam->getMinTimestep(); 00990 if(nextmax>allowMax/reduceFac){ minCutoff=true; } // only if really large vels... 00991 } 00992 00993 LbmFloat dtdiff = fabs(newdt - mpParam->getTimestep()); 00994 if(!mSilent) { 00995 debMsgStd("LbmFsgrSolver::TAdp",DM_MSG, "new"<<newdt 00996 <<" max"<<mpParam->getMaxTimestep()<<" min"<<mpParam->getMinTimestep()<<" diff"<<dtdiff 00997 <<" simt:"<<mSimulationTime<<" minsteps:"<<(mSimulationTime/mMaxTimestep)<<" maxsteps:"<<(mSimulationTime/mMinTimestep)<< 00998 " olddt"<<levOldStepsize[mMaxRefine]<<" redlock"<<mTimestepReduceLock 00999 , 10); } 01000 01001 // in range, and more than X% change? 01002 //if( newdt < mpParam->getTimestep() ) // DEBUG 01003 LbmFloat rhoAvg = mCurrentMass/mCurrentVolume; 01004 if( (newdt<=mpParam->getMaxTimestep()) && (newdt>=mpParam->getMinTimestep()) 01005 && (dtdiff>(mpParam->getTimestep()*diffPercent)) ) { 01006 if((newdt>levOldStepsize[mMaxRefine])&&(mTimestepReduceLock)) { 01007 // wait some more... 01008 //debMsgNnl("LbmFsgrSolver::TAdp",DM_NOTIFY," Delayed... "<<mTimestepReduceLock<<" ",10); 01009 debMsgDirect("D"); 01010 } else { 01011 mpParam->setDesiredTimestep( newdt ); 01012 rescale = true; 01013 if(!mSilent) { 01014 debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"\n\n\n\n",10); 01015 debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Timestep changing: new="<<newdt<<" old="<<mpParam->getTimestep() 01016 <<" maxSpeed:"<<mpParam->getSimulationMaxSpeed()<<" next:"<<nextmax<<" step:"<<mStepCnt, 10 ); 01017 //debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Timestep changing: "<< "rhoAvg="<<rhoAvg<<" cMass="<<mCurrentMass<<" cVol="<<mCurrentVolume,10); 01018 } 01019 } // really change dt 01020 } 01021 01022 if(mTimestepReduceLock>0) mTimestepReduceLock--; 01023 01024 01025 // forced back and forth switchting (for testing) 01026 /*const int tadtogInter = 100; 01027 const double tadtogSwitch = 0.66; 01028 errMsg("TIMESWITCHTOGGLETEST","warning enabled "<< tadtogSwitch<<","<<tadtogSwitch<<" !!!!!!!!!!!!!!!!!!!"); 01029 if( ((mStepCnt% tadtogInter)== (tadtogInter/4*1)-1) || 01030 ((mStepCnt% tadtogInter)== (tadtogInter/4*2)-1) ){ 01031 rescale = true; minCutoff = false; 01032 newdt = tadtogSwitch * mpParam->getTimestep(); 01033 mpParam->setDesiredTimestep( newdt ); 01034 } else 01035 if( ((mStepCnt% tadtogInter)== (tadtogInter/4*3)-1) || 01036 ((mStepCnt% tadtogInter)== (tadtogInter/4*4)-1) ){ 01037 rescale = true; minCutoff = false; 01038 newdt = mpParam->getTimestep()/tadtogSwitch ; 01039 mpParam->setDesiredTimestep( newdt ); 01040 } else { 01041 rescale = false; minCutoff = false; 01042 } 01043 // */ 01044 01045 // test mass rescale 01046 01047 scaleFac = newdt/mpParam->getTimestep(); 01048 if(rescale) { 01049 // perform acutal rescaling... 01050 mTimeMaxvelStepCnt=0; 01051 mForceTimeStepReduce = false; 01052 01053 // FIXME - approximate by averaging, take gravity direction here? 01054 //mTimestepReduceLock = 4*(mLevel[mMaxRefine].lSizey+mLevel[mMaxRefine].lSizez+mLevel[mMaxRefine].lSizex)/3; 01055 // use z as gravity direction 01056 mTimestepReduceLock = 4*mLevel[mMaxRefine].lSizez; 01057 01058 mTimeSwitchCounts++; 01059 mpParam->calculateAllMissingValues( mSimulationTime, mSilent ); 01060 recalculateObjectSpeeds(); 01061 // calc omega, force for all levels 01062 mLastOmega=1e10; mLastGravity=1e10; 01063 initLevelOmegas(); 01064 if(mpParam->getTimestep()<mMinTimestep) mMinTimestep = mpParam->getTimestep(); 01065 if(mpParam->getTimestep()>mMaxTimestep) mMaxTimestep = mpParam->getTimestep(); 01066 01067 // this might be called during init, before we have any particles 01068 if(mpParticles) { mpParticles->adaptPartTimestep(scaleFac); } 01069 #if LBM_INCLUDE_TESTSOLVERS==1 01070 if((mUseTestdata)&&(mpTest)) { 01071 mpTest->adaptTimestep(scaleFac, mLevel[mMaxRefine].omega, mLevel[mMaxRefine].timestep, vec2L( mpParam->calculateGravity(mSimulationTime)) ); 01072 mpTest->mGrav3d = mLevel[mMaxRefine].gravity; 01073 } 01074 #endif // LBM_INCLUDE_TESTSOLVERS!=1 01075 01076 for(int lev=mMaxRefine; lev>=0 ; lev--) { 01077 LbmFloat newSteptime = mLevel[lev].timestep; 01078 LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]); 01079 01080 if(!mSilent) { 01081 debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Level: "<<lev<<" Timestep chlevel: "<< 01082 " scaleFac="<<dfScaleFac<<" newDt="<<newSteptime<<" newOmega="<<mLevel[lev].omega,10); 01083 } 01084 if(lev!=mMaxRefine) coarseCalculateFluxareas(lev); 01085 01086 int wss = 0, wse = 1; 01087 // only change currset (necessary for compressed grids, better for non-compr.gr.) 01088 wss = wse = mLevel[lev].setCurr; 01089 for(int workSet = wss; workSet<=wse; workSet++) { // COMPRT 01090 // warning - check sets for higher levels...? 01091 FSGR_FORIJK1(lev) { 01092 if( (RFLAG(lev,i,j,k, workSet) & CFBndMoving) ) { 01093 /* 01094 // paranoid check - shouldnt be necessary! 01095 if(QCELL(lev, i, j, k, workSet, dFlux)!=mSimulationTime) { 01096 errMsg("TTTT","found invalid bnd cell.... removing at "<<PRINT_IJK); 01097 RFLAG(lev,i,j,k, workSet) = CFInter; 01098 // init empty zero vel interface cell... 01099 initVelocityCell(lev, i,j,k, CFInter, 1.0, 0.01, LbmVec(0.) ); 01100 } else {// */ 01101 for(int l=0; l<cDfNum; l++) { 01102 QCELL(lev, i, j, k, workSet, l) = QCELL(lev, i, j, k, workSet, l)* scaleFac; 01103 } 01104 //} // ok 01105 continue; 01106 } 01107 if( 01108 (RFLAG(lev,i,j,k, workSet) & CFFluid) || 01109 (RFLAG(lev,i,j,k, workSet) & CFInter) || 01110 (RFLAG(lev,i,j,k, workSet) & CFGrFromCoarse) || 01111 (RFLAG(lev,i,j,k, workSet) & CFGrFromFine) || 01112 (RFLAG(lev,i,j,k, workSet) & CFGrNorm) 01113 ) { 01114 // these cells have to be scaled... 01115 } else { 01116 continue; 01117 } 01118 01119 // collide on current set 01120 LbmFloat rhoOld; 01121 LbmVec velOld; 01122 LbmFloat rho, ux,uy,uz; 01123 rho=0.0; ux = uy = uz = 0.0; 01124 for(int l=0; l<cDfNum; l++) { 01125 LbmFloat m = QCELL(lev, i, j, k, workSet, l); 01126 rho += m; 01127 ux += (dfDvecX[l]*m); 01128 uy += (dfDvecY[l]*m); 01129 uz += (dfDvecZ[l]*m); 01130 } 01131 rhoOld = rho; 01132 velOld = LbmVec(ux,uy,uz); 01133 01134 LbmFloat rhoNew = (rhoOld-rhoAvg)*scaleFac +rhoAvg; 01135 LbmVec velNew = velOld * scaleFac; 01136 01137 LbmFloat df[LBM_DFNUM]; 01138 LbmFloat feqOld[LBM_DFNUM]; 01139 LbmFloat feqNew[LBM_DFNUM]; 01140 for(int l=0; l<cDfNum; l++) { 01141 feqOld[l] = getCollideEq(l,rhoOld, velOld[0],velOld[1],velOld[2] ); 01142 feqNew[l] = getCollideEq(l,rhoNew, velNew[0],velNew[1],velNew[2] ); 01143 df[l] = QCELL(lev, i,j,k,workSet, l); 01144 } 01145 const LbmFloat Qo = getLesNoneqTensorCoeff(df,feqOld); 01146 const LbmFloat oldOmega = getLesOmega(levOldOmega[lev], mLevel[lev].lcsmago,Qo); 01147 const LbmFloat newOmega = getLesOmega(mLevel[lev].omega,mLevel[lev].lcsmago,Qo); 01148 //newOmega = mLevel[lev].omega; // FIXME debug test 01149 01150 //LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]); 01151 const LbmFloat dfScale = (newSteptime/newOmega)/(levOldStepsize[lev]/oldOmega); 01152 //dfScale = dfScaleFac/newOmega; 01153 01154 for(int l=0; l<cDfNum; l++) { 01155 // org scaling 01156 //df = eqOld + (df-eqOld)*dfScale; df *= (eqNew/eqOld); // non-eq. scaling, important 01157 // new scaling 01158 LbmFloat dfn = feqNew[l] + (df[l]-feqOld[l])*dfScale*feqNew[l]/feqOld[l]; // non-eq. scaling, important 01159 //df = eqNew + (df-eqOld)*dfScale; // modified ig scaling, no real difference? 01160 QCELL(lev, i,j,k,workSet, l) = dfn; 01161 } 01162 01163 if(RFLAG(lev,i,j,k, workSet) & CFInter) { 01164 //if(workSet==mLevel[lev].setCurr) 01165 LbmFloat area = 1.0; 01166 if(lev!=mMaxRefine) area = QCELL(lev, i,j,k,workSet, dFlux); 01167 massTOld += QCELL(lev, i,j,k,workSet, dMass) * area; 01168 volTOld += QCELL(lev, i,j,k,workSet, dFfrac); 01169 01170 // wrong... QCELL(i,j,k,workSet, dMass] = (QCELL(i,j,k,workSet, dFfrac]*rhoNew); 01171 QCELL(lev, i,j,k,workSet, dMass) = (QCELL(lev, i,j,k,workSet, dMass)/rhoOld*rhoNew); 01172 QCELL(lev, i,j,k,workSet, dFfrac) = (QCELL(lev, i,j,k,workSet, dMass)/rhoNew); 01173 01174 //if(workSet==mLevel[lev].setCurr) 01175 massTNew += QCELL(lev, i,j,k,workSet, dMass); 01176 volTNew += QCELL(lev, i,j,k,workSet, dFfrac); 01177 } 01178 if(RFLAG(lev,i,j,k, workSet) & CFFluid) { // DEBUG 01179 if(RFLAG(lev,i,j,k, workSet) & (CFGrFromFine|CFGrFromCoarse)) { // DEBUG 01180 // dont include 01181 } else { 01182 LbmFloat area = 1.0; 01183 if(lev!=mMaxRefine) area = QCELL(lev, i,j,k,workSet, dFlux) * mLevel[lev].lcellfactor; 01184 //if(workSet==mLevel[lev].setCurr) 01185 massTOld += rhoOld*area; 01186 //if(workSet==mLevel[lev].setCurr) 01187 massTNew += rhoNew*area; 01188 volTOld += area; 01189 volTNew += area; 01190 } 01191 } 01192 01193 } // IJK 01194 } // workSet 01195 01196 } // lev 01197 01198 if(!mSilent) { 01199 debMsgStd("LbmFsgrSolver::step",DM_MSG,"REINIT DONE "<<mStepCnt<< 01200 " no"<<mTimeSwitchCounts<<" maxdt"<<mMaxTimestep<< 01201 " mindt"<<mMinTimestep<<" currdt"<<mLevel[mMaxRefine].timestep, 10); 01202 debMsgStd("LbmFsgrSolver::step",DM_MSG,"REINIT DONE masst:"<<massTNew<<","<<massTOld<<" org:"<<mCurrentMass<<"; "<< 01203 " volt:"<<volTNew<<","<<volTOld<<" org:"<<mCurrentVolume, 10); 01204 } else { 01205 debMsgStd("\nLbmOptSolver::step",DM_MSG,"Timestep changed by "<< (newdt/levOldStepsize[mMaxRefine]) <<" newDt:"<<newdt 01206 <<", oldDt:"<<levOldStepsize[mMaxRefine]<<" newOmega:"<<mOmega<<" gStar:"<<mpParam->getCurrentGStar()<<", step:"<<mStepCnt , 10); 01207 } 01208 } // rescale? 01209 //NEWDEBCHECK("tt2"); 01210 01211 //errMsg("adaptTimestep","Warning - brute force rescale off!"); minCutoff = false; // DEBUG 01212 if(minCutoff) { 01213 errMsg("adaptTimestep","Warning - performing Brute-Force rescale... (sim:"<<mName<<" step:"<<mStepCnt<<" newdt="<<desireddt<<" mindt="<<mpParam->getMinTimestep()<<") " ); 01214 //brute force resacle all the time? 01215 01216 for(int lev=mMaxRefine; lev>=0 ; lev--) { 01217 int rescs=0; 01218 int wss = 0, wse = 1; 01219 #if COMPRESSGRIDS==1 01220 if(lev== mMaxRefine) wss = wse = mLevel[lev].setCurr; 01221 #endif // COMPRESSGRIDS==1 01222 for(int workSet = wss; workSet<=wse; workSet++) { // COMPRT 01223 //for(int workSet = 0; workSet<=1; workSet++) { 01224 FSGR_FORIJK1(lev) { 01225 01226 //if( (RFLAG(lev, i,j,k, workSet) & CFFluid) || (RFLAG(lev, i,j,k, workSet) & CFInter) ) { 01227 if( 01228 (RFLAG(lev,i,j,k, workSet) & CFFluid) || 01229 (RFLAG(lev,i,j,k, workSet) & CFInter) || 01230 (RFLAG(lev,i,j,k, workSet) & CFGrFromCoarse) || 01231 (RFLAG(lev,i,j,k, workSet) & CFGrFromFine) || 01232 (RFLAG(lev,i,j,k, workSet) & CFGrNorm) 01233 ) { 01234 // these cells have to be scaled... 01235 } else { 01236 continue; 01237 } 01238 01239 // collide on current set 01240 LbmFloat rho, ux,uy,uz; 01241 rho=0.0; ux = uy = uz = 0.0; 01242 for(int l=0; l<cDfNum; l++) { 01243 LbmFloat m = QCELL(lev, i, j, k, workSet, l); 01244 rho += m; 01245 ux += (dfDvecX[l]*m); 01246 uy += (dfDvecY[l]*m); 01247 uz += (dfDvecZ[l]*m); 01248 } 01249 #ifndef WIN32 01250 if (!finite(rho)) { 01251 errMsg("adaptTimestep","Brute force non-finite rho at"<<PRINT_IJK); // DEBUG! 01252 rho = 1.0; 01253 ux = uy = uz = 0.0; 01254 QCELL(lev, i, j, k, workSet, dMass) = 1.0; 01255 QCELL(lev, i, j, k, workSet, dFfrac) = 1.0; 01256 } 01257 #endif // WIN32 01258 01259 if( (ux*ux+uy*uy+uz*uz)> (allowMax*allowMax) ) { 01260 LbmFloat cfac = allowMax/sqrt(ux*ux+uy*uy+uz*uz); 01261 ux *= cfac; 01262 uy *= cfac; 01263 uz *= cfac; 01264 for(int l=0; l<cDfNum; l++) { 01265 QCELL(lev, i, j, k, workSet, l) = getCollideEq(l, rho, ux,uy,uz); } 01266 rescs++; 01267 debMsgDirect("B"); 01268 } 01269 01270 } } 01271 //if(rescs>0) { errMsg("adaptTimestep","!!!!! Brute force rescaling was necessary !!!!!!!"); } 01272 debMsgStd("adaptTimestep",DM_MSG,"Brute force rescale done. level:"<<lev<<" rescs:"<<rescs, 1); 01273 //TTT mNumProblems += rescs; // add to problem display... 01274 } // lev,set,ijk 01275 01276 } // try brute force rescale? 01277 01278 // time adap done... 01279 } 01280 01281 01282