$treeview $search $mathjax
|
Palabos
Version 1.1
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /* This file is part of the Palabos library. 00002 * 00003 * Copyright (C) 2011 FlowKit Sarl 00004 * Avenue de Chailly 23 00005 * 1012 Lausanne, Switzerland 00006 * E-mail contact: contact@flowkit.com 00007 * 00008 * The most recent release of Palabos can be downloaded at 00009 * <http://www.palabos.org/> 00010 * 00011 * The library Palabos is free software: you can redistribute it and/or 00012 * modify it under the terms of the GNU Affero General Public License as 00013 * published by the Free Software Foundation, either version 3 of the 00014 * License, or (at your option) any later version. 00015 * 00016 * The library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Affero General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Affero General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 00025 /* Main author: Daniel Lagrava 00026 **/ 00027 00028 #ifndef MULTI_GRID_LATTICE_2D_HH 00029 #define MULTI_GRID_LATTICE_2D_HH 00030 00031 #include "multiGrid/multiGridLattice2D.h" 00032 #include "multiGrid/multiGridParameterManager.h" 00033 00034 #include "io/parallelIO.h" 00035 #include "core/util.h" 00036 00037 namespace plb { 00038 00039 /* ****** MultiGridLattice2D ****** */ 00040 00041 template <typename T, template <typename U> class Descriptor> 00042 MultiGridLattice2D<T,Descriptor>::MultiGridLattice2D( MultiGridManagement2D management, 00043 Dynamics<T,Descriptor>* backgroundDynamics, 00044 plint behaviorLevel, 00045 FineGridInterfaceInstantiator<T,Descriptor> *fineGridInstantiator_, 00046 CoarseGridInterfaceInstantiator<T,Descriptor> *coarseGridInstantiator_ ) 00047 : MultiGrid2D ( 00048 management, 00049 behaviorLevel ), fineGridInstantiator(fineGridInstantiator_), 00050 coarseGridInstantiator(coarseGridInstantiator_) 00051 { 00052 std::vector<Dynamics<T,Descriptor>*> dynamicsVector(this->getNumLevels()); 00053 for (plint iLevel=0; iLevel<this->getNumLevels(); ++iLevel){ 00054 Dynamics<T,Descriptor>* cloned = backgroundDynamics->clone(); 00055 cloned->rescale(behaviorLevel-iLevel,behaviorLevel-iLevel); 00056 dynamicsVector[iLevel] = cloned; 00057 } 00058 delete backgroundDynamics; 00059 // generate the lattices that correspond to the blocks contained inside the management object 00060 lattices = generateLattices( this->getMultiGridManagement(), dynamicsVector, 00061 defaultMultiGridPolicy2D().getBlockCommunicator<T>(management.getNumLevels()), 00062 defaultMultiGridPolicy2D().getCombinedStatistics(management.getNumLevels()), 00063 fineGridInstantiator->getEnvelopeWidth()); 00064 00065 // initialize the internalStatSubscription (multiGrid) once all the lattices have been created 00066 this->internalStatSubscription().initialize(); 00067 } 00068 00069 template <typename T, template <typename U> class Descriptor> 00070 MultiGridLattice2D<T,Descriptor>::MultiGridLattice2D ( 00071 MultiGridManagement2D management, 00072 std::vector<BlockCommunicator2D*> communicators_, 00073 std::vector<CombinedStatistics*> combinedStatistics_, 00074 Dynamics<T,Descriptor>* backgroundDynamics, 00075 plint behaviorLevel, 00076 FineGridInterfaceInstantiator<T,Descriptor> *fineGridInstantiator_, 00077 CoarseGridInterfaceInstantiator<T,Descriptor> *coarseGridInstantiator_ ) 00078 : MultiGrid2D( management, 00079 behaviorLevel ), fineGridInstantiator(fineGridInstantiator_), 00080 coarseGridInstantiator(coarseGridInstantiator_) 00081 { 00082 std::vector<Dynamics<T,Descriptor>*> dynamicsVector(this->getNumLevels()); 00083 for (plint iLevel=0; iLevel<this->getNumLevels(); ++iLevel){ 00084 Dynamics<T,Descriptor>* cloned = backgroundDynamics->clone(); 00085 cloned->rescale(behaviorLevel-iLevel,behaviorLevel-iLevel); 00086 dynamicsVector[iLevel] = cloned; 00087 } 00088 delete backgroundDynamics; 00089 // generate the lattices that correspond to the blocks contained inside the management object 00090 lattices = generateLattices( this->getMultiGridManagement(), dynamicsVector, 00091 communicators_, combinedStatistics_, 00092 fineGridInstantiator->getEnvelopeWidth() ); 00093 // initialize the internalStatSubscription (multiGrid) once all the lattices have been created 00094 this->internalStatSubscription().initialize(); 00095 } 00096 00097 00099 template <typename T, template <typename U> class Descriptor> 00100 MultiGridLattice2D<T,Descriptor>::~MultiGridLattice2D(){ 00101 for (plint i = 0; i < this->getNumLevels(); ++i){ 00102 delete lattices[i]; 00103 // the dynamics are taken care by each lattice 00104 } 00105 00106 delete fineGridInstantiator; 00107 delete coarseGridInstantiator; 00108 } 00109 00110 //BUG: there is a problem with the copy constructor 00111 template <typename T, template <typename U> class Descriptor> 00112 MultiGridLattice2D<T,Descriptor>::MultiGridLattice2D(MultiGridLattice2D<T,Descriptor> const& rhs) 00113 : MultiGrid2D(rhs), fineGridInstantiator(rhs.fineGridInstantiator->clone()), 00114 coarseGridInstantiator(rhs.coarseGridInstantiator->clone()) 00115 { 00116 std::vector<Dynamics<T,Descriptor>*> dynamicsVector(this->getNumLevels()); 00117 00118 for (plint iLevel=0; iLevel<this->getNumLevels(); ++iLevel){ 00119 Dynamics<T,Descriptor>* cloned = rhs.lattices[iLevel]->getBackgroundDynamics().clone(); 00120 dynamicsVector[iLevel] = cloned; 00121 } 00122 MultiGridManagement2D const& management = this->getMultiGridManagement(); 00123 // generate the lattices that correspond to the blocks contained inside the management object 00124 lattices = generateLattices( management, dynamicsVector, 00125 defaultMultiGridPolicy2D().getBlockCommunicator<T>(management.getNumLevels()), 00126 defaultMultiGridPolicy2D().getCombinedStatistics(management.getNumLevels()), 00127 fineGridInstantiator->getEnvelopeWidth() ); 00128 00129 // initialize the internalStatSubscription (multiGrid) once all the lattices have been created 00130 this->internalStatSubscription().initialize(); 00131 } 00132 00133 00134 template <typename T, template <typename U> class Descriptor> 00135 MultiGridLattice2D<T,Descriptor>::MultiGridLattice2D( MultiGridLattice2D<T,Descriptor> const& rhs, 00136 Box2D subDomain, bool crop ) 00137 : MultiGrid2D(rhs, subDomain, crop), fineGridInstantiator(rhs.fineGridInstantiator), 00138 coarseGridInstantiator(rhs.coarseGridInstantiator) 00139 { 00140 std::vector<Dynamics<T,Descriptor>*> backgroundDynamics; 00141 for (plint iDyn=0; iDyn<this->getNumLevels(); ++iDyn) { 00142 backgroundDynamics[iDyn] = new NoDynamics<T,Descriptor>(); 00143 } 00144 // generate the lattices that correspond to the blocks contained inside the management object 00145 lattices = generateLattices( this->getMultiGridManagement(), backgroundDynamics, 00146 this->getCommunicators(), this->getCombinedStatistics(), 00147 fineGridInstantiator->getEnvelopeWidth() ); 00148 00149 // initialize the internalStatSubscription (multiGrid) once all the lattices have been created 00150 this->internalStatSubscription().initialize(); 00151 } 00152 00153 00154 template <typename T, template <typename U> class Descriptor> 00155 MultiGridLattice2D<T,Descriptor>::MultiGridLattice2D(MultiGrid2D const& rhs) 00156 : MultiGrid2D(rhs) 00157 { 00158 std::vector<Dynamics<T,Descriptor>*> backgroundDynamics; 00159 for (plint iDyn=0; iDyn<this->getNumLevels(); ++iDyn) { 00160 backgroundDynamics[iDyn] = new NoDynamics<T,Descriptor>(); 00161 } 00162 // generate the lattices that correspond to the blocks contained inside the management object 00163 lattices = generateLattices( this->getMultiGridManagement(), backgroundDynamics, 00164 this->getCommunicators(), this->getCombinedStatistics() ); 00165 00166 // initialize the internalStatSubscription (multiGrid) once all the lattices have been created 00167 this->internalStatSubscription().initialize(); 00168 00169 } 00170 00171 template <typename T, template <typename U> class Descriptor> 00172 MultiGridLattice2D<T,Descriptor>::MultiGridLattice2D( MultiGrid2D const& rhs, 00173 Box2D subDomain, bool crop ) 00174 : MultiGrid2D(rhs, subDomain, crop) 00175 { 00176 std::vector<Dynamics<T,Descriptor>*> backgroundDynamics; 00177 for (plint iDyn=0; iDyn<this->getNumLevels(); ++iDyn) { 00178 backgroundDynamics[iDyn] = new NoDynamics<T,Descriptor>(); 00179 } 00180 // generate the lattices that correspond to the blocks contained inside the management object 00181 lattices = generateLattices( this->getMultiGridManagement(), backgroundDynamics, 00182 this->getCommunicators(), this->getCombinedStatistics() ); 00183 00184 // initialize the internalStatSubscription (multiGrid) once all the lattices have been created 00185 this->internalStatSubscription().initialize(); 00186 00187 } 00188 00189 template<typename T, template<typename U> class Descriptor> 00190 MultiGridLattice2D<T,Descriptor>& MultiGridLattice2D<T,Descriptor>::operator= ( 00191 MultiGridLattice2D<T,Descriptor> const& rhs ) 00192 { 00193 MultiGridLattice2D<T,Descriptor> tmp(rhs); 00194 swap(tmp); 00195 return *this; 00196 } 00197 00198 00202 template <typename T, template <typename U> class Descriptor> 00203 void MultiGridLattice2D<T,Descriptor>::initialize() 00204 { 00205 this->createInterfaces(); 00206 00207 // eliminate the statistics in the refinement overlap 00208 this->eliminateStatisticsInOverlap(); 00209 00210 // Execute this data processor once, because this allocates memory on the fine grid dynamcis 00211 // for time t0 (after we have values for t1) 00212 lattices[0]->initialize(); 00213 std::vector<std::vector<Box2D> > fineGridInterfaces = this->getMultiGridManagement().getFineInterface(); 00214 plint timeForImmediateExecution = 0; 00215 plint numTimeSteps=2; 00216 // fineGrid interfaces start at level 1 00217 for (pluint iLevel=1; iLevel<fineGridInterfaces.size(); ++iLevel){ 00218 std::vector<Box2D> levelInterfaces=fineGridInterfaces[iLevel]; 00219 for (pluint iInterf=0; iInterf<levelInterfaces.size(); ++iInterf){ 00220 applyProcessingFunctional ( 00221 new Copy_t1_to_t0_2D<T, Descriptor>(numTimeSteps, timeForImmediateExecution), 00222 levelInterfaces[iInterf].multiply(2), 00223 *lattices[iLevel] ); 00224 } 00225 lattices[iLevel]->initialize(); 00226 } 00227 00228 // toggle all stats on 00229 for (int iLevel = 0; iLevel < (plint)lattices.size(); ++iLevel){ 00230 lattices[iLevel]->toggleInternalStatistics(true); 00231 } 00232 00233 } 00234 00235 template <typename T, template <typename U> class Descriptor> 00236 void MultiGridLattice2D<T,Descriptor>::createInterfaces(){ 00237 MultiGridManagement2D management = this->getMultiGridManagement(); 00238 00239 std::vector<std::vector<Box2D> > fineGridInterfaces = management.getFineInterface(); 00240 std::vector<std::vector<Box2D> > coarseGridInterfaces = management.getCoarseInterface(); 00241 std::vector<std::vector<Array<plint,2> > > coarseOrientations = management.getCoarseOrientation(); 00242 std::vector<std::vector<Array<plint,2> > > fineOrientations = management.getFineOrientation(); 00243 00244 // Create the part of the coupling in which a lattice acts as a coarse lattice. 00245 for (pluint iCoarse=0; iCoarse<lattices.size()-1; ++iCoarse) { 00246 for (pluint iInterface=0; iInterface<coarseGridInterfaces[iCoarse].size(); ++iInterface) { 00247 plint direction = (coarseOrientations[iCoarse][iInterface])[0]; // w.r.t. the coarse grid 00248 plint orientation = (coarseOrientations[iCoarse][iInterface])[1]; // w.r.t. the coarse grid 00249 coarseGridInstantiator->instantiateDataProcessors(coarseGridInterfaces[iCoarse][iInterface], 00250 *lattices[iCoarse],*lattices[iCoarse+1], 00251 direction, orientation); 00252 } 00253 } 00254 // Create the part of the coupling in which a lattice acts as a fine lattice. 00255 for (pluint iFine=1; iFine<lattices.size(); ++iFine) { 00256 for (pluint iInterface=0; iInterface<fineGridInterfaces[iFine].size(); ++iInterface) { 00257 plint direction = (fineOrientations[iFine][iInterface])[0]; // w.r.t. the fine grid 00258 plint orientation = (fineOrientations[iFine][iInterface])[1]; // w.r.t. the fine grid 00259 fineGridInstantiator->instantiateDataProcessors(fineGridInterfaces[iFine][iInterface], 00260 *lattices[iFine-1],*lattices[iFine], 00261 direction, orientation); 00262 } 00263 } 00264 } 00265 00266 /* *** MultiGrid2D methods *** */ 00268 template <typename T, template <typename U> class Descriptor> 00269 MultiBlockLattice2D<T,Descriptor>& MultiGridLattice2D<T,Descriptor>::getComponent(plint iBlock) 00270 { 00271 PLB_PRECONDITION( iBlock >= 0 && iBlock < (plint) lattices.size() ); 00272 return *lattices[iBlock]; 00273 } 00274 00275 template <typename T, template <typename U> class Descriptor> 00276 const MultiBlockLattice2D<T,Descriptor>& MultiGridLattice2D<T,Descriptor>::getComponent(plint iBlock) const 00277 { 00278 PLB_PRECONDITION( iBlock >= 0 && iBlock < (plint) lattices.size() ); 00279 return *lattices[iBlock]; 00280 } 00281 00282 /* **** BlockLatticeBase2D methods **** */ 00283 00284 template <typename T, template <typename U> class Descriptor> 00285 Cell<T,Descriptor>& MultiGridLattice2D<T,Descriptor>::get(plint iX, plint iY){ 00286 return lattices[this->getBehaviorLevel()]->get(iX,iY); 00287 } 00288 00289 template <typename T, template <typename U> class Descriptor> 00290 Cell<T,Descriptor> const& MultiGridLattice2D<T,Descriptor>::get(plint iX, plint iY) const{ 00291 return lattices[this->getBehaviorLevel()]->get(iX,iY); 00292 } 00293 00294 template <typename T, template <typename U> class Descriptor> 00295 void MultiGridLattice2D<T,Descriptor>::specifyStatisticsStatus(Box2D domain, bool status){ 00296 for (plint iLevel = 0; iLevel < (plint)lattices.size(); ++iLevel){ 00297 Box2D rescaledDomain = this->getScaleManager().scaleBox(domain,iLevel); 00298 lattices[iLevel]->specifyStatisticsStatus(rescaledDomain,status); 00299 } 00300 } 00301 00302 00303 template <typename T, template <typename U> class Descriptor> 00304 void MultiGridLattice2D<T,Descriptor>::collide(Box2D domain){ 00305 plint levelNumber = (plint)lattices.size(); 00306 PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() ); 00307 for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){ 00308 // each level will iterate 2 times the iterations of level - 1 00309 plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel)); 00310 for (plint iterations = 0; iterations < fineGridIt; ++iterations){ 00311 lattices[iLevel]->collide(domain); 00312 } 00313 } 00314 } 00315 00316 template <typename T, template <typename U> class Descriptor> 00317 void MultiGridLattice2D<T,Descriptor>::collide() { 00318 plint levelNumber = (plint)lattices.size(); 00319 PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() ); 00320 for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){ 00321 // each level will iterate 2 times the iterations of level - 1 00322 plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel)); 00323 for (plint iterations = 0; iterations < fineGridIt; ++iterations){ 00324 lattices[iLevel]->collide(); 00325 } 00326 } 00327 } 00328 00329 template <typename T, template <typename U> class Descriptor> 00330 void MultiGridLattice2D<T,Descriptor>::stream(Box2D domain) { 00331 plint levelNumber = (plint)lattices.size(); 00332 PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() ); 00333 for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){ 00334 // each level will iterate 2 times the iterations of level - 1 00335 plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel)); 00336 for (plint iterations = 0; iterations < fineGridIt; ++iterations){ 00337 lattices[iLevel]->stream(domain); 00338 } 00339 } 00340 } 00341 00342 template <typename T, template <typename U> class Descriptor> 00343 void MultiGridLattice2D<T,Descriptor>::stream() { 00344 plint levelNumber = (plint)lattices.size(); 00345 PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() ); 00346 for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){ 00347 // each level will iterate 2 times the iterations of level - 1 00348 plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel)); 00349 for (plint iterations = 0; iterations < fineGridIt; ++iterations){ 00350 lattices[iLevel]->stream(); 00351 } 00352 // update the values for parallelism 00353 lattices[iLevel]->getBlockCommunicator().duplicateOverlaps(*lattices[iLevel], modif::staticVariables); 00354 } 00355 00356 this->evaluateStatistics(); 00357 } 00358 00360 template <typename T, template <typename U> class Descriptor> 00361 void MultiGridLattice2D<T,Descriptor>::collideAndStream(Box2D domain){ 00362 plint levelNumber = (plint)lattices.size(); 00363 PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() ); 00364 for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){ 00365 // each level will iterate 2 times the iterations of level - 1 00366 plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel)); 00367 for (plint iterations = 0; iterations < fineGridIt; ++iterations){ 00368 lattices[iLevel]->collideAndStream(domain); 00369 } 00370 } 00371 } 00372 00373 00374 template <typename T, template <typename U> class Descriptor> 00375 void MultiGridLattice2D<T,Descriptor>::iterateMultiGrid(plint level){ 00376 PLB_PRECONDITION( level>=0 && level<(plint)lattices.size() ); 00377 lattices[level]->collideAndStream(); 00378 if ((pluint)level<lattices.size()-1) { 00379 iterateMultiGrid(level+1); 00380 iterateMultiGrid(level+1); 00381 // Overlaps must be duplicated on the coarse lattice, because the 00382 // fine->coarse copy acts on bulk nodes only. 00383 lattices[level]->getBlockCommunicator().duplicateOverlaps(*lattices[level], modif::staticVariables); 00384 } 00385 } 00386 00388 template <typename T, template <typename U> class Descriptor> 00389 void MultiGridLattice2D<T,Descriptor>::collideAndStream(){ 00390 iterateMultiGrid(0); 00391 this->evaluateStatistics(); 00392 } 00393 00397 template <typename T, template <typename U> class Descriptor> 00398 void MultiGridLattice2D<T,Descriptor>::incrementTime() 00399 {} 00400 00401 template <typename T, template <typename U> class Descriptor> 00402 TimeCounter& MultiGridLattice2D<T,Descriptor>::getTimeCounter(){ 00403 return lattices[this->getBehaviorLevel()]->getTimeCounter(); 00404 } 00405 00406 template <typename T, template <typename U> class Descriptor> 00407 TimeCounter const& MultiGridLattice2D<T,Descriptor>::getTimeCounter() const{ 00408 return lattices[this->getBehaviorLevel()]->getTimeCounter(); 00409 } 00410 00411 template <typename T, template <typename U> class Descriptor> 00412 int MultiGridLattice2D<T,Descriptor>::getBlockId () const{ 00413 return lattices[this->getReferenceLevel()]->getStaticId(); 00414 } 00415 00420 template <typename T, template <typename U> class Descriptor> 00421 void MultiGridLattice2D<T,Descriptor>::eliminateStatisticsInOverlap(){ 00422 // the fine interface is the region inside the fine grid that overlaps with the coarse 00423 // grid. It is therefore there that we need to turn off the statistics in the 00424 // coarse grid. 00425 std::vector<std::vector<Box2D> > fineOverlaps = this->getMultiGridManagement().getFineInterface(); 00426 for (plint iLevel = 0; iLevel < (plint)lattices.size()-1; ++iLevel){ 00427 for (plint iOv = 0; iOv < (plint)fineOverlaps[iLevel].size(); ++iOv){ 00428 Box2D currentOverlap = (fineOverlaps[iLevel])[iOv]; 00429 lattices[iLevel]->specifyStatisticsStatus(currentOverlap, false); 00430 } 00431 } 00432 // it is also necessary to avoid computation in the coarse interface, as the refinement 00433 // overlap is two coarse sites 00434 std::vector<std::vector<Box2D> > coarseOverlaps = this->getMultiGridManagement().getCoarseInterface(); 00435 for (plint iLevel = 0; iLevel < (plint)lattices.size()-1; ++iLevel){ 00436 for (plint iOv = 0; iOv < (plint)coarseOverlaps[iLevel].size(); ++iOv){ 00437 Box2D currentOverlap = (coarseOverlaps[iLevel])[iOv]; 00438 lattices[iLevel]->specifyStatisticsStatus(currentOverlap, false); 00439 } 00440 } 00441 00442 } 00443 00444 00449 template <typename T, template <typename U> class Descriptor> 00450 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > MultiGridLattice2D<T,Descriptor>::convertToLevel(plint level) const 00451 { 00452 // create the resulting multiBlock 00453 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > result = 00454 generateMultiBlockLattice<T,Descriptor>( 00455 lattices[level]->getBoundingBox(), 00456 lattices[level]->getBackgroundDynamics().clone(), 00457 lattices[level]->getMultiBlockManagement().getEnvelopeWidth() ); 00458 00459 // create the first lattice to start looping 00460 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > refined = 00461 generateMultiBlockLattice<T,Descriptor>( 00462 lattices[0]->getBoundingBox(), 00463 lattices[0]->getBackgroundDynamics().clone(), 00464 lattices[0]->getMultiBlockManagement().getEnvelopeWidth() ); 00465 00466 copyNonLocal<T,Descriptor>(*lattices[0],*refined, 00467 refined->getBoundingBox(), modif::staticVariables); 00468 00469 // loop to interpolate the blocks until level-1 00470 for (plint iLevel=0; iLevel<(plint)level; ++iLevel){ 00471 plint envelopeWidth = lattices[iLevel+1]->getMultiBlockManagement().getEnvelopeWidth(); 00472 // interpolate lattice at iLevel 00473 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > tmp = 00474 refine(*refined,-1,-1,refined->getBackgroundDynamics().clone()); 00475 00476 refined = generateMultiBlockLattice<T,Descriptor>(lattices[iLevel+1]->getBoundingBox(), 00477 lattices[iLevel+1]->getBackgroundDynamics().clone(), 00478 envelopeWidth ); 00479 00480 // copy from reshaped iLevel to result 00481 copyNonLocal<T,Descriptor>(*tmp, *refined, refined->getBoundingBox(),modif::staticVariables); 00482 // copy from iLevel+1 to result 00483 copyNonLocal<T,Descriptor>(*lattices[iLevel+1], *refined, refined->getBoundingBox(),modif::staticVariables); 00484 } 00485 00486 // create the last lattice to start looping in the other orientation 00487 plint lastLevel = getNumLevels()-1; 00488 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > coarsened = 00489 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > ( 00490 new MultiBlockLattice2D<T,Descriptor>(*lattices[lastLevel])); 00491 00492 defineDynamics<T,Descriptor>( *coarsened, coarsened->getBoundingBox(), 00493 lattices[lastLevel]->getBackgroundDynamics().clone() ); 00494 00495 copyNonLocal<T,Descriptor>(*lattices[lastLevel],*coarsened, 00496 coarsened->getBoundingBox(), modif::staticVariables); 00497 00498 // loop to decimate the blocks until level+1 00499 for (plint iLevel=getNumLevels()-1; iLevel>=(plint)level+1; --iLevel){ 00500 // interpolate lattice at iLevel 00501 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > tmp = 00502 coarsen(*coarsened,1,1, lattices[iLevel]->getBackgroundDynamics().clone() ); 00503 00504 coarsened = generateJoinMultiBlockLattice<T,Descriptor>(*tmp, *lattices[iLevel-1]); 00505 // make all the dynamics from refinement disappear 00506 defineDynamics<T,Descriptor>(*coarsened, coarsened->getBoundingBox(), 00507 lattices[iLevel-1]->getBackgroundDynamics().clone() ); 00508 00509 // copy from reshaped iLevel to result 00510 copyNonLocal<T,Descriptor>(*tmp, *coarsened, coarsened->getBoundingBox(),modif::staticVariables); 00511 // copy from iLevel-1 to result 00512 copyNonLocal<T,Descriptor>(*lattices[iLevel-1], *coarsened, coarsened->getBoundingBox(),modif::staticVariables); 00513 } 00514 00515 // final copies 00516 copyNonLocal<T,Descriptor>(*refined, *result, result->getBoundingBox(),modif::staticVariables); 00517 copyNonLocal<T,Descriptor>(*lattices[level], *result, result->getBoundingBox(),modif::staticVariables); 00518 copyNonLocal<T,Descriptor>(*coarsened, *result, result->getBoundingBox(),modif::staticVariables); 00519 00520 return result; 00521 } 00522 00524 00525 template<typename T, template<typename U> class Descriptor> 00526 double getStoredAverageDensity(MultiGridLattice2D<T,Descriptor> const& multiGrid){ 00527 return Descriptor<T>::fullRho ( 00528 multiGrid.getInternalStatistics().getAverage( 00529 LatticeStatistics::avRhoBar ) ); 00530 } 00531 00532 template<typename T, template<typename U> class Descriptor> 00533 double getStoredAverageEnergy(MultiGridLattice2D<T,Descriptor> const& multiGrid){ 00534 return 0.5 * multiGrid.getInternalStatistics().getAverage( 00535 LatticeStatistics::avUSqr ); 00536 } 00537 00538 template<typename T, template<typename U> class Descriptor> 00539 double getStoredMaxVelocity(MultiGridLattice2D<T,Descriptor> const& multiGrid){ 00540 return std::sqrt( multiGrid.getInternalStatistics().getMax ( 00541 LatticeStatistics::maxUSqr ) ); 00542 } 00543 00544 00545 }// namespace plb 00546 00547 #endif // MULTI_GRID_LATTICE_2D_HH
1.6.3
1.6.3