$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

multiGridLattice3D.hh

Go to the documentation of this file.
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_3D_HH
00029 #define MULTI_GRID_LATTICE_3D_HH
00030 
00031 #include "multiGrid/multiGridLattice3D.h"
00032 #include "multiGrid/multiGridParameterManager.h"
00033 #include "io/parallelIO.h"
00034 #include "multiGrid/multiGridGenerator3D.h"
00035 
00036 
00037 namespace plb {
00038 
00039 /* ****** MultiGridLattice3D ****** */
00040 
00041 template <typename T, template <typename U> class Descriptor>
00042 MultiGridLattice3D<T,Descriptor>::MultiGridLattice3D( MultiGridManagement3D management,
00043                                                       Dynamics<T,Descriptor>* backgroundDynamics,
00044                                                       plint behaviorLevel )
00045        : MultiGrid3D (
00046              management,
00047              behaviorLevel )
00048 {
00049     std::vector<Dynamics<T,Descriptor>*> dynamicsVector(this->getNumLevels());
00050     for (plint iLevel=0; iLevel<this->getNumLevels(); ++iLevel){
00051         Dynamics<T,Descriptor>* cloned = backgroundDynamics->clone();
00052         cloned->rescale(behaviorLevel-iLevel,behaviorLevel-iLevel);
00053         dynamicsVector[iLevel] = cloned;
00054     }
00055     delete backgroundDynamics;
00056     // generate the lattices that correspond to the blocks contained inside the management object
00057     lattices = generateLattices( this->getMultiGridManagement(), dynamicsVector,
00058                                  defaultMultiGridPolicy3D().getBlockCommunicator(management.getNumLevels()),
00059                                  defaultMultiGridPolicy3D().getCombinedStatistics(management.getNumLevels()) );
00060                                  
00061     // initialize the internalStatSubscription (multiGrid) once all the lattices have been created
00062     this->internalStatSubscription().initialize();    
00063 }
00064 
00065 template <typename T, template <typename U> class Descriptor>
00066 MultiGridLattice3D<T,Descriptor>::MultiGridLattice3D (
00067         MultiGridManagement3D management,
00068         std::vector<BlockCommunicator3D*> communicators_,
00069         std::vector<CombinedStatistics*> combinedStatistics_, 
00070         Dynamics<T,Descriptor>* backgroundDynamics,
00071         plint behaviorLevel )
00072     : MultiGrid3D( management,
00073                    behaviorLevel )
00074 {
00075     
00076     std::vector<Dynamics<T,Descriptor>*> dynamicsVector(this->getNumLevels());
00077     for (plint iLevel=0; iLevel<this->getNumLevels(); ++iLevel){
00078         Dynamics<T,Descriptor>* cloned = backgroundDynamics->clone();
00079         cloned->rescale(behaviorLevel-iLevel,behaviorLevel-iLevel);
00080         dynamicsVector[iLevel] = cloned;
00081     }
00082     delete backgroundDynamics;
00083     // generate the lattices that correspond to the blocks contained inside the management object
00084     lattices = generateLattices( this->getMultiGridManagement(), dynamicsVector,
00085                                  communicators_, combinedStatistics_ );
00086                                  
00087     // initialize the internalStatSubscription (multiGrid) once all the lattices have been created
00088     this->internalStatSubscription().initialize();
00089 }
00090 
00091 
00093 template <typename T, template <typename U> class Descriptor>
00094 MultiGridLattice3D<T,Descriptor>::~MultiGridLattice3D(){
00095     for (plint i = 0; i < this->getNumLevels(); ++i){
00096         delete lattices[i];
00097     }
00098 }
00099 
00100 template <typename T, template <typename U> class Descriptor>
00101 MultiGridLattice3D<T,Descriptor>::MultiGridLattice3D(MultiGridLattice3D<T,Descriptor> const& rhs)
00102   : MultiGrid3D(rhs)
00103 {
00104     lattices.resize(this->getNumLevels());
00105     for (plint iLattice=0; iLattice<this->getNumLevels(); ++iLattice) {
00106         lattices[iLattice] = new MultiBlockLattice3D<T,Descriptor>(rhs.lattices[iLattice]);
00107     }
00108 }
00109 
00110 template <typename T, template <typename U> class Descriptor>
00111 MultiGridLattice3D<T,Descriptor>::MultiGridLattice3D( MultiGridLattice3D<T,Descriptor> const& rhs, 
00112                                                       Box3D subDomain, bool crop )
00113   : MultiGrid3D(rhs, subDomain, crop)
00114 {
00115     std::vector<Dynamics<T,Descriptor>*> backgroundDynamics;
00116     for (plint iDyn=0; iDyn<this->getNumLevels(); ++iDyn) {
00117       backgroundDynamics[iDyn] = new NoDynamics<T,Descriptor>();
00118     }
00119     // generate the lattices that correspond to the blocks contained inside the management object
00120     lattices = generateLattices( this->getMultiGridManagement(), backgroundDynamics,
00121                                  this->getCommunicators(), this->getCombinedStatistics() );
00122     // initialize the internalStatSubscription (multiGrid) once all the lattices have been created
00123     this->internalStatSubscription().initialize();
00124 }
00125 
00126 
00127 template <typename T, template <typename U> class Descriptor>
00128 MultiGridLattice3D<T,Descriptor>::MultiGridLattice3D(MultiGrid3D const& rhs)
00129   : MultiGrid3D(rhs)
00130 {
00131     std::vector<Dynamics<T,Descriptor>*> backgroundDynamics;
00132     for (plint iDyn=0; iDyn<this->getNumLevels(); ++iDyn) {
00133       backgroundDynamics[iDyn] = new NoDynamics<T,Descriptor>();
00134     }
00135     // generate the lattices that correspond to the blocks contained inside the management object
00136     lattices = generateLattices( this->getMultiGridManagement(), backgroundDynamics,
00137                                  this->getCommunicators(), this->getCombinedStatistics() );
00138     // initialize the internalStatSubscription (multiGrid) once all the lattices have been created
00139     this->internalStatSubscription().initialize();
00140 }
00141 
00142 template <typename T, template <typename U> class Descriptor>
00143 MultiGridLattice3D<T,Descriptor>::MultiGridLattice3D( MultiGrid3D const& rhs, 
00144                                                       Box3D subDomain, bool crop )
00145   : MultiGrid3D(rhs, subDomain, crop)
00146 {
00147     std::vector<Dynamics<T,Descriptor>*> backgroundDynamics;
00148     for (plint iDyn=0; iDyn<this->getNumLevels(); ++iDyn) {
00149       backgroundDynamics[iDyn] = new NoDynamics<T,Descriptor>();
00150     }
00151     // generate the lattices that correspond to the blocks contained inside the management object
00152     lattices = generateLattices( this->getMultiGridManagement(), backgroundDynamics,
00153                                  this->getCommunicators(), this->getCombinedStatistics() );
00154     // initialize the internalStatSubscription (multiGrid) once all the lattices have been created
00155     this->internalStatSubscription().initialize();
00156 }
00157 
00158 template<typename T, template<typename U> class Descriptor>
00159 MultiGridLattice3D<T,Descriptor>& MultiGridLattice3D<T,Descriptor>::operator= (
00160         MultiGridLattice3D<T,Descriptor> const& rhs )
00161 {
00162     MultiGridLattice3D<T,Descriptor> tmp(rhs);
00163     swap(tmp);
00164     return *this;
00165 }
00166 
00170 template <typename T, template <typename U> class Descriptor>
00171 void MultiGridLattice3D<T,Descriptor>::initialize()
00172 {
00173     this->createInterfaces();
00174     
00175     // Execute this data processor once, because this allocates memory on the fine grid dynamcis
00176     //   for time t0 (after we have values for t1)
00177     lattices[0]->executeInternalProcessors();
00178     std::vector<std::vector<Box3D> > fineGridInterfaces = this->getMultiGridManagement().getFineInterface();
00179     plint timeForImmediateExecution = 0;
00180     plint numTimeSteps=2;
00181     // fineGrid interfaces start at level 1
00182     for (pluint iLevel=1; iLevel<fineGridInterfaces.size(); ++iLevel){
00183         std::vector<Box3D> levelInterfaces=fineGridInterfaces[iLevel];
00184         for (pluint iInterf=0; iInterf<levelInterfaces.size(); ++iInterf){
00185             applyProcessingFunctional (
00186                 new Copy_t1_to_t0_3D<T, Descriptor>(numTimeSteps, timeForImmediateExecution),
00187                 levelInterfaces[iInterf].multiply(2),
00188                 *lattices[iLevel] );
00189                 
00190              Box3D box = levelInterfaces[iInterf].multiply(2);
00191         }
00192         
00193         lattices[iLevel]->executeInternalProcessors();
00194     }
00195     
00196     // toggle all stats on
00197     for (int iLevel = 0; iLevel < (plint)lattices.size(); ++iLevel){
00198         lattices[iLevel]->initialize();
00199         lattices[iLevel]->toggleInternalStatistics(true);
00200     }
00201     
00202 }
00203 
00204 template <typename T, template <typename U> class Descriptor>
00205 void MultiGridLattice3D<T,Descriptor>::createInterfaces(){
00206     plb::createInterfaces( lattices, this->getMultiGridManagement());
00207 };
00208 
00209 /* *** MultiGrid3D methods *** */
00211 template <typename T, template <typename U> class Descriptor>
00212 MultiBlockLattice3D<T,Descriptor>& MultiGridLattice3D<T,Descriptor>::getComponent(plint iBlock){
00213     PLB_PRECONDITION( iBlock >= 0 && iBlock < (plint) lattices.size() );
00214     return *lattices[iBlock];
00215 }
00216 
00217 template <typename T, template <typename U> class Descriptor>
00218 const MultiBlockLattice3D<T,Descriptor>& MultiGridLattice3D<T,Descriptor>::getComponent(plint iBlock) const
00219 {
00220     PLB_PRECONDITION( iBlock >= 0 && iBlock < (plint) lattices.size() );
00221     return *lattices[iBlock];
00222 }
00223 
00224 /* **** BlockLatticeBase3D methods **** */
00225 
00226 template <typename T, template <typename U> class Descriptor>
00227 Cell<T,Descriptor>& MultiGridLattice3D<T,Descriptor>::get(plint iX, plint iY, plint iZ){
00228     return lattices[this->getBehaviorLevel()]->get(iX,iY,iZ);
00229 }
00230 
00231 template <typename T, template <typename U> class Descriptor>
00232 Cell<T,Descriptor> const& MultiGridLattice3D<T,Descriptor>::get(plint iX, plint iY, plint iZ) const{
00233     return lattices[this->getBehaviorLevel()]->get(iX,iY,iZ);
00234 }
00235 
00236 template <typename T, template <typename U> class Descriptor>
00237 void MultiGridLattice3D<T,Descriptor>::specifyStatisticsStatus(Box3D domain, bool status){
00238     for (plint iLevel = 0; iLevel < (plint)lattices.size(); ++iLevel){
00239         Box3D rescaledDomain = this->getScaleManager().scaleBox(domain,iLevel);
00240         lattices[iLevel]->specifyStatisticsStatus(rescaledDomain,status);
00241     }
00242 }
00243 
00244 
00245 template <typename T, template <typename U> class Descriptor>
00246 void MultiGridLattice3D<T,Descriptor>::collide(Box3D domain){
00247     plint levelNumber = (plint)lattices.size();
00248     PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() );
00249     for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){
00250         // each level will iterate 2 times the iterations of level - 1
00251         plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel));
00252         for (plint iterations = 0; iterations < fineGridIt; ++iterations){
00253             lattices[iLevel]->collide(domain);
00254         }
00255     }
00256 }
00257 
00258 template <typename T, template <typename U> class Descriptor>
00259 void MultiGridLattice3D<T,Descriptor>::collide() {
00260     plint levelNumber = (plint)lattices.size();
00261     PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() );
00262     for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){
00263         // each level will iterate 2 times the iterations of level - 1
00264         plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel));
00265         for (plint iterations = 0; iterations < fineGridIt; ++iterations){
00266             lattices[iLevel]->collide();
00267         }
00268     }
00269 }
00270 
00271 template <typename T, template <typename U> class Descriptor>
00272 void MultiGridLattice3D<T,Descriptor>::stream(Box3D domain) {
00273     plint levelNumber = (plint)lattices.size();
00274     PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() );
00275     for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){
00276         // each level will iterate 2 times the iterations of level - 1
00277         plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel));
00278         for (plint iterations = 0; iterations < fineGridIt; ++iterations){
00279             lattices[iLevel]->stream(domain);
00280         }
00281     }
00282 }
00283 
00284 template <typename T, template <typename U> class Descriptor>
00285 void MultiGridLattice3D<T,Descriptor>::stream() {
00286     plint levelNumber = (plint)lattices.size();
00287     PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() );
00288     for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){
00289         // each level will iterate 2 times the iterations of level - 1
00290         plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel));
00291         for (plint iterations = 0; iterations < fineGridIt; ++iterations){
00292                 lattices[iLevel]->stream();
00293         }
00294         // update the values for parallelism
00295         lattices[iLevel]->getBlockCommunicator().duplicateOverlaps(*lattices[iLevel], modif::staticVariables);
00296     }
00297     
00298     this->evaluateStatistics();
00299 }
00300 
00302 template <typename T, template <typename U> class Descriptor>
00303 void MultiGridLattice3D<T,Descriptor>::collideAndStream(Box3D domain){
00304     plint levelNumber = (plint)lattices.size();
00305     PLB_PRECONDITION( levelNumber >= 0 && levelNumber <= (plint)lattices.size() );
00306     for (plint iLevel = 0; iLevel < levelNumber; ++iLevel){
00307         // each level will iterate 2 times the iterations of level - 1
00308         plint fineGridIt = util::roundToInt(util::twoToThePower(iLevel));
00309         for (plint iterations = 0; iterations < fineGridIt; ++iterations){
00310             lattices[iLevel]->collideAndStream(domain);
00311         }
00312     }
00313 }
00314 
00315 
00316 template <typename T, template <typename U> class Descriptor>
00317 void MultiGridLattice3D<T,Descriptor>::iterateMultiGrid(plint level){
00318     PLB_PRECONDITION( level>=0 && level<(plint)lattices.size() );
00319     lattices[level]->collideAndStream();
00320     if ((pluint)level<lattices.size()-1) {
00321         iterateMultiGrid(level+1);
00322         iterateMultiGrid(level+1);
00323         // Overlaps must be duplicated on the coarse lattice, because the
00324         //   fine->coarse copy acts on bulk nodes only.
00325         lattices[level]->getBlockCommunicator().duplicateOverlaps(*lattices[level],modif::staticVariables);
00326     }
00327 }
00328 
00330 template <typename T, template <typename U> class Descriptor>
00331 void MultiGridLattice3D<T,Descriptor>::collideAndStream(){
00332     iterateMultiGrid(0);
00333     this->evaluateStatistics();
00334 }
00335 
00339 template <typename T, template <typename U> class Descriptor>
00340 void MultiGridLattice3D<T,Descriptor>::incrementTime()
00341 {}
00342 
00343 template <typename T, template <typename U> class Descriptor>
00344 TimeCounter& MultiGridLattice3D<T,Descriptor>::getTimeCounter(){
00345     return lattices[this->getBehaviorLevel()]->getTimeCounter();
00346 }
00347 
00348 template <typename T, template <typename U> class Descriptor>
00349 TimeCounter const& MultiGridLattice3D<T,Descriptor>::getTimeCounter() const{
00350     return lattices[this->getBehaviorLevel()]->getTimeCounter();
00351 }
00352 
00353 template <typename T, template <typename U> class Descriptor>
00354 int  MultiGridLattice3D<T,Descriptor>::getBlockId () const{
00355     return lattices[this->getReferenceLevel()]->getStaticId();
00356 }
00357 
00358 
00360 
00361 template<typename T, template<typename U> class Descriptor>
00362 double getStoredAverageDensity(MultiGridLattice3D<T,Descriptor> const& multiGrid){
00363     return Descriptor<T>::fullRho (
00364                  multiGrid.getInternalStatistics().getAverage(
00365                     LatticeStatistics::avRhoBar ) );
00366 }
00367 
00368 template<typename T, template<typename U> class Descriptor>
00369 double getStoredAverageEnergy(MultiGridLattice3D<T,Descriptor> const& multiGrid){
00370     return 0.5 * multiGrid.getInternalStatistics().getAverage(
00371                                             LatticeStatistics::avUSqr );
00372 }
00373 
00374 template<typename T, template<typename U> class Descriptor>
00375 double getStoredMaxVelocity(MultiGridLattice3D<T,Descriptor> const& multiGrid){
00376     return std::sqrt( multiGrid.getInternalStatistics().getMax (
00377                                LatticeStatistics::maxUSqr ) );
00378 }
00379 
00380 
00381 }// namespace plb
00382 
00383 #endif  // MULTI_GRID_LATTICE_3D_HH