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

multiBlockLattice2D.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 
00028 #ifndef MULTI_BLOCK_LATTICE_2D_HH
00029 #define MULTI_BLOCK_LATTICE_2D_HH
00030 
00031 #include "multiBlock/multiBlockLattice2D.h"
00032 #include "atomicBlock/blockLattice2D.h"
00033 #include "multiBlock/defaultMultiBlockPolicy2D.h"
00034 #include "multiBlock/nonLocalTransfer2D.h"
00035 #include "multiBlock/multiBlockGenerator2D.h"
00036 #include "core/latticeStatistics.h"
00037 #include "core/plbTypenames.h"
00038 #include "core/multiBlockIdentifiers2D.h"
00039 #include "core/plbProfiler.h"
00040 #include "core/dynamicsIdentifiers.h"
00041 #include "dataProcessors/metaStuffWrapper2D.h"
00042 #include <algorithm>
00043 #include <limits>
00044 #include <cmath>
00045 
00046 
00047 namespace plb {
00048 
00050 
00051 template<typename T, template<typename U> class Descriptor>
00052 const int MultiBlockLattice2D<T,Descriptor>::staticId =
00053 meta::registerMultiBlock2D ( MultiBlockLattice2D<T,Descriptor>::basicType(),
00054                              MultiBlockLattice2D<T,Descriptor>::descriptorType(),
00055                              MultiBlockLattice2D<T,Descriptor>::blockName(),
00056                              defaultGenerateMultiBlockLattice2D<T,Descriptor> );
00057 
00058 template<typename T, template<typename U> class Descriptor>
00059 MultiBlockLattice2D<T,Descriptor>::MultiBlockLattice2D (
00060         MultiBlockManagement2D const& multiBlockManagement_,
00061         BlockCommunicator2D* blockCommunicator_,
00062         CombinedStatistics* combinedStatistics_,
00063         MultiCellAccess2D<T,Descriptor>* multiCellAccess_,
00064         Dynamics<T,Descriptor>* backgroundDynamics_ )
00065     : MultiBlock2D(multiBlockManagement_, blockCommunicator_, combinedStatistics_ ),
00066       backgroundDynamics(backgroundDynamics_),
00067       multiCellAccess(multiCellAccess_)
00068 {
00069     allocateAndInitialize();
00070     eliminateStatisticsInEnvelope();
00071     this->evaluateStatistics(); // Reset statistics to default.
00072 }
00073 
00074 template<typename T, template<typename U> class Descriptor>
00075 MultiBlockLattice2D<T,Descriptor>::MultiBlockLattice2D (
00076         plint nx, plint ny,
00077         Dynamics<T,Descriptor>* backgroundDynamics_ )
00078     : MultiBlock2D(nx,ny,Descriptor<T>::vicinity),
00079       backgroundDynamics(backgroundDynamics_),
00080       multiCellAccess(defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>())
00081 {
00082     allocateAndInitialize();
00083     eliminateStatisticsInEnvelope();
00084     this->evaluateStatistics(); // Reset statistics to default.
00085 }
00086 
00087 template<typename T, template<typename U> class Descriptor>
00088 MultiBlockLattice2D<T,Descriptor>::~MultiBlockLattice2D() {
00089     for ( typename BlockMap::iterator it = blockLattices.begin();
00090           it != blockLattices.end(); ++it)
00091     {
00092         delete it->second;
00093     }
00094     delete backgroundDynamics;
00095     delete multiCellAccess;
00096 }
00097 
00098 template<typename T, template<typename U> class Descriptor>
00099 MultiBlockLattice2D<T,Descriptor>::MultiBlockLattice2D(MultiBlockLattice2D<T,Descriptor> const& rhs)
00100     : BlockLatticeBase2D<T,Descriptor>(rhs),
00101       MultiBlock2D(rhs),
00102       backgroundDynamics(rhs.backgroundDynamics->clone()),
00103       multiCellAccess(rhs.multiCellAccess->clone())
00104 {
00105     for ( typename  BlockMap::const_iterator it = rhs.blockLattices.begin();
00106           it != rhs.blockLattices.end(); ++it )
00107     {
00108         blockLattices[it->first] = new BlockLattice2D<T,Descriptor>(*it->second);
00109     }
00110 }
00111 
00112 template<typename T, template<typename U> class Descriptor>
00113 MultiBlockLattice2D<T,Descriptor>::MultiBlockLattice2D(MultiBlock2D const& rhs)
00114       // Use MultiBlock's sub-domain constructor to avoid that the data-processors are copied
00115     : MultiBlock2D(rhs, rhs.getBoundingBox(), false),
00116       backgroundDynamics(new NoDynamics<T,Descriptor>),
00117       multiCellAccess(defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>())
00118 {
00119     allocateAndInitialize();
00120     eliminateStatisticsInEnvelope();
00121 }
00122 
00123 template<typename T, template<typename U> class Descriptor>
00124 MultiBlockLattice2D<T,Descriptor>::MultiBlockLattice2D(MultiBlock2D const& rhs, Box2D subDomain, bool crop)
00125     : MultiBlock2D(rhs, subDomain, crop),
00126       backgroundDynamics(new NoDynamics<T,Descriptor>),
00127       multiCellAccess(defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>())
00128 {
00129     allocateAndInitialize();
00130     eliminateStatisticsInEnvelope();
00131 }
00132 
00133 template<typename T, template<typename U> class Descriptor>
00134 void MultiBlockLattice2D<T,Descriptor>::swap(MultiBlockLattice2D<T,Descriptor>& rhs) {
00135     BlockLatticeBase2D<T,Descriptor>::swap(rhs);
00136     MultiBlock2D::swap(rhs);
00137     std::swap(backgroundDynamics, rhs.backgroundDynamics);
00138     std::swap(multiCellAccess, rhs.multiCellAccess);
00139     blockLattices.swap(rhs.blockLattices);
00140 }
00141 
00142 template<typename T, template<typename U> class Descriptor>
00143 MultiBlockLattice2D<T,Descriptor>& MultiBlockLattice2D<T,Descriptor>::operator= (
00144         MultiBlockLattice2D<T,Descriptor> const& rhs )
00145 {
00146     MultiBlockLattice2D<T,Descriptor> tmp(rhs);
00147     swap(tmp);
00148     return *this;
00149 }
00150 
00151 template<typename T, template<typename U> class Descriptor>
00152 MultiBlockLattice2D<T,Descriptor>*
00153     MultiBlockLattice2D<T,Descriptor>::clone() const
00154 {
00155     return new MultiBlockLattice2D<T,Descriptor>(*this);
00156 }
00157 
00158 template<typename T, template<typename U> class Descriptor>
00159 MultiBlockLattice2D<T,Descriptor>*
00160     MultiBlockLattice2D<T,Descriptor>::clone(MultiBlockManagement2D const& newManagement) const
00161 {
00162     MultiBlockLattice2D<T,Descriptor>* newLattice =
00163         new MultiBlockLattice2D<T,Descriptor> (
00164                 newManagement,
00165                 this->getBlockCommunicator().clone(),
00166                 this->getCombinedStatistics().clone(),
00167                 multiCellAccess->clone(),
00168                 getBackgroundDynamics().clone() );
00169     copy(*this, this->getBoundingBox(), *newLattice, newLattice->getBoundingBox(), modif::dataStructure);
00170     return newLattice;
00171 }
00172 
00173 template<typename T, template<typename U> class Descriptor>
00174 Dynamics<T,Descriptor> const& MultiBlockLattice2D<T,Descriptor>::getBackgroundDynamics() const {
00175     return *backgroundDynamics;
00176 }
00177 
00178 template<typename T, template<typename U> class Descriptor>
00179 Cell<T,Descriptor>& MultiBlockLattice2D<T,Descriptor>::get(plint iX, plint iY) {
00180     return multiCellAccess -> getDistributedCell(iX,iY, this->getMultiBlockManagement(), blockLattices);
00181 }
00182 
00183 template<typename T, template<typename U> class Descriptor>
00184 Cell<T,Descriptor> const& MultiBlockLattice2D<T,Descriptor>::get(plint iX, plint iY) const {
00185     return multiCellAccess -> getDistributedCell(iX,iY, this->getMultiBlockManagement(), blockLattices);
00186 }
00187 
00188 template<typename T, template<typename U> class Descriptor>
00189 void MultiBlockLattice2D<T,Descriptor>::specifyStatisticsStatus (Box2D domain, bool status) {
00190     Box2D inters;
00191     for ( typename BlockMap::iterator it = blockLattices.begin();
00192           it != blockLattices.end(); ++it)
00193     {
00194         SmartBulk2D bulk(this->getMultiBlockManagement(), it->first);
00195         if (intersect(domain, bulk.getBulk(), inters ) ) {
00196             inters = bulk.toLocal(inters);
00197             it->second -> specifyStatisticsStatus(inters, status);
00198         }
00199     }
00200 }
00201 
00202 template<typename T, template<typename U> class Descriptor>
00203 void MultiBlockLattice2D<T,Descriptor>::collide(Box2D domain) {
00204     Box2D inters;
00205     for ( typename BlockMap::iterator it = blockLattices.begin();
00206           it != blockLattices.end(); ++it)
00207     {
00208         SmartBulk2D bulk(this->getMultiBlockManagement(), it->first);
00209         if (intersect(domain, bulk.computeEnvelope(), inters ) ) {
00210             inters = bulk.toLocal(inters);
00211             it->second -> collide(inters);
00212         }
00213     }
00214 }
00215 
00216 template<typename T, template<typename U> class Descriptor>
00217 void MultiBlockLattice2D<T,Descriptor>::collide() {
00218     for ( typename BlockMap::iterator it = blockLattices.begin();
00219           it != blockLattices.end(); ++it)
00220     {
00221         it->second -> collide();
00222     }
00223 }
00224 
00225 template<typename T, template<typename U> class Descriptor>
00226 void MultiBlockLattice2D<T,Descriptor>::stream(Box2D domain) {
00227     Box2D inters;
00228     for ( typename BlockMap::iterator it = blockLattices.begin();
00229           it != blockLattices.end(); ++it)
00230     {
00231         SmartBulk2D bulk(this->getMultiBlockManagement(), it->first);
00232         if (intersect(domain, bulk.computeNonPeriodicEnvelope(), inters ) ) {
00233             inters = bulk.toLocal(inters);
00234             it->second -> stream(inters);
00235         }
00236     }
00237 }
00238 
00239 template<typename T, template<typename U> class Descriptor>
00240 Box2D MultiBlockLattice2D<T,Descriptor>::extendPeriodic(Box2D const& box, plint envelopeWidth) const
00241 {
00242     Box2D boundingBox(this->getBoundingBox());
00243     Box2D periodicBox(box);
00244     bool periodicX = this->periodicity().get(0);
00245     bool periodicY = this->periodicity().get(1);
00246     if (periodicX) {
00247         if (periodicBox.x0 == boundingBox.x0) {
00248             periodicBox.x0 -= envelopeWidth;
00249         }
00250         if (periodicBox.x1 == boundingBox.x1) {
00251             periodicBox.x1 += envelopeWidth;
00252         }
00253     }
00254     if (periodicY) {
00255         if (periodicBox.y0 == boundingBox.y0) {
00256             periodicBox.y0 -= envelopeWidth;
00257         }
00258         if (periodicBox.y1 == boundingBox.y1) {
00259             periodicBox.y1 += envelopeWidth;
00260         }
00261     }
00262     return periodicBox;
00263 }
00264 
00265 template<typename T, template<typename U> class Descriptor>
00266 void MultiBlockLattice2D<T,Descriptor>::stream() {
00267     for ( typename BlockMap::iterator it = blockLattices.begin();
00268           it != blockLattices.end(); ++it)
00269     {
00270         SmartBulk2D bulk(this->getMultiBlockManagement(), it->first);
00271         // Stream must be applied to full domain, including currently active envelopes.
00272         Box2D domain = extendPeriodic(bulk.computeNonPeriodicEnvelope(),
00273                                       this->getMultiBlockManagement().getEnvelopeWidth());
00274         it->second -> stream( bulk.toLocal(domain) );
00275     }
00276     this->executeInternalProcessors();
00277     this->evaluateStatistics();
00278     this->incrementTime();
00279 }
00280 
00281 template<typename T, template<typename U> class Descriptor>
00282 void MultiBlockLattice2D<T,Descriptor>::collideAndStream(Box2D domain) {
00283     Box2D inters;
00284     for ( typename BlockMap::iterator it = blockLattices.begin();
00285           it != blockLattices.end(); ++it)
00286     {
00287         SmartBulk2D bulk(this->getMultiBlockManagement(), it->first);
00288         if (intersect(domain, bulk.computeNonPeriodicEnvelope(), inters ) ) {
00289             inters = bulk.toLocal(inters);
00290             it->second -> collideAndStream(inters);
00291         }
00292     }
00293 }
00294 
00295 template<typename T, template<typename U> class Descriptor>
00296 void MultiBlockLattice2D<T,Descriptor>::collideAndStream() {
00297     global::profiler().start("cycle");
00298     for ( typename BlockMap::iterator it = blockLattices.begin();
00299           it != blockLattices.end(); ++it)
00300     {
00301         SmartBulk2D bulk(this->getMultiBlockManagement(), it->first);
00302         // CollideAndStream must be applied to full domain,
00303         //   including currently active envelopes.
00304         Box2D domain = extendPeriodic(bulk.computeNonPeriodicEnvelope(),
00305                                       this->getMultiBlockManagement().getEnvelopeWidth());
00306         it->second -> collideAndStream( bulk.toLocal(domain) );
00307     }
00308     this->executeInternalProcessors();
00309     this->evaluateStatistics();
00310     this->incrementTime();
00311     if (global::profiler().cyclingIsAutomatic()) {
00312         global::profiler().cycle();
00313     }
00314     global::profiler().stop("cycle");
00315 }
00316 
00317 template<typename T, template<typename U> class Descriptor>
00318 void MultiBlockLattice2D<T,Descriptor>::incrementTime() {
00319     for ( typename BlockMap::iterator it = blockLattices.begin();
00320           it != blockLattices.end(); ++it)
00321     {
00322         it->second -> incrementTime();
00323     }
00324     this->getTimeCounter().incrementTime();
00325 }
00326 
00327 template<typename T, template<typename U> class Descriptor>
00328 void MultiBlockLattice2D<T,Descriptor>::resetTime(pluint value)
00329 {
00330     for ( typename BlockMap::iterator it = blockLattices.begin();
00331           it != blockLattices.end(); ++it)
00332     {
00333         it->second -> getTimeCounter().resetTime(value);
00334     }
00335     this->getTimeCounter().resetTime(value);
00336 }
00337 
00338 template<typename T, template<typename U> class Descriptor>
00339 void MultiBlockLattice2D<T,Descriptor>::allocateAndInitialize()
00340 {
00341     this->getInternalStatistics().subscribeAverage(); // Subscribe average rho-bar
00342     this->getInternalStatistics().subscribeAverage(); // Subscribe average uSqr
00343     this->getInternalStatistics().subscribeMax();     // Subscribe max uSqr
00344 
00345     for (pluint iBlock=0; iBlock<this->getLocalInfo().getBlocks().size(); ++iBlock) {
00346         plint blockId = this->getLocalInfo().getBlocks()[iBlock];
00347         SmartBulk2D bulk(this->getMultiBlockManagement(), blockId);
00348         Box2D envelope = bulk.computeEnvelope();
00349         BlockLattice2D<T,Descriptor>* newLattice
00350             = new BlockLattice2D<T,Descriptor> (
00351                     envelope.getNx(), envelope.getNy(),
00352                     backgroundDynamics->clone() );
00353         newLattice -> setLocation(Dot2D(envelope.x0, envelope.y0));
00354         blockLattices[blockId] = newLattice;
00355     }
00356 }
00357 
00358 template<typename T, template<typename U> class Descriptor>
00359 void MultiBlockLattice2D<T,Descriptor>::eliminateStatisticsInEnvelope()
00360 {
00361     for ( typename BlockMap::iterator it = blockLattices.begin();
00362           it != blockLattices.end(); ++it )
00363     {
00364         plint envelopeWidth = this->getMultiBlockManagement().getEnvelopeWidth();
00365         BlockLattice2D<T,Descriptor>& block = *it->second;
00366         plint maxX = block.getNx()-1;
00367         plint maxY = block.getNy()-1;
00368 
00369         block.specifyStatisticsStatus(Box2D(0, maxX, 0, envelopeWidth-1), false);
00370         block.specifyStatisticsStatus(Box2D(0, maxX, maxY-envelopeWidth+1, maxY), false);
00371         block.specifyStatisticsStatus(Box2D(0, envelopeWidth-1,         0, maxY), false);
00372         block.specifyStatisticsStatus(Box2D(maxX-envelopeWidth+1, maxX, 0, maxY), false);
00373     }
00374 }
00375 
00376 template<typename T, template<typename U> class Descriptor>
00377 std::map<plint,BlockLattice2D<T,Descriptor>*>&
00378     MultiBlockLattice2D<T,Descriptor>::getBlockLattices()
00379 {
00380     return blockLattices;
00381 }
00382 
00383 template<typename T, template<typename U> class Descriptor>
00384 std::map<plint,BlockLattice2D<T,Descriptor>*> const&
00385     MultiBlockLattice2D<T,Descriptor>::getBlockLattices() const
00386 {
00387     return blockLattices;
00388 }
00389 
00390 template<typename T, template<typename U> class Descriptor>
00391 void MultiBlockLattice2D<T,Descriptor>::getDynamicsDict(Box2D domain, std::map<std::string,int>& dict)
00392 {
00393     std::vector<int> ids;
00394     uniqueDynamicsIds(*this, domain, ids);
00395     dict.clear();
00396     for (pluint i=0; i<ids.size(); ++i) {
00397         int id = ids[i];
00398         std::string name = meta::dynamicsRegistration<T,Descriptor>().getName(id);
00399         dict.insert(std::pair<std::string,int>(name,id));
00400     }
00401 }
00402 
00403 template<typename T, template<typename U> class Descriptor>
00404 std::string MultiBlockLattice2D<T,Descriptor>::getBlockName() const {
00405     return std::string("BlockLattice2D");
00406 }
00407 
00408 template<typename T, template<typename U> class Descriptor>
00409 std::vector<std::string> MultiBlockLattice2D<T,Descriptor>::getTypeInfo() const {
00410     std::vector<std::string> info;
00411     info.push_back(basicType());
00412     info.push_back(descriptorType());
00413     return info;
00414 }
00415 
00416 template<typename T, template<typename U> class Descriptor>
00417 std::string MultiBlockLattice2D<T,Descriptor>::blockName() {
00418     return std::string("BlockLattice2D");
00419 }
00420 
00421 template<typename T, template<typename U> class Descriptor>
00422 std::string MultiBlockLattice2D<T,Descriptor>::basicType() {
00423     return std::string(NativeType<T>::getName());
00424 }
00425 
00426 template<typename T, template<typename U> class Descriptor>
00427 std::string MultiBlockLattice2D<T,Descriptor>::descriptorType() {
00428     return std::string(Descriptor<T>::name);
00429 }
00430 
00431 template<typename T, template<typename U> class Descriptor>
00432 BlockLattice2D<T,Descriptor>& MultiBlockLattice2D<T,Descriptor>::getComponent(plint blockId) {
00433     typename BlockMap::iterator it = blockLattices.find(blockId);
00434     PLB_ASSERT (it != blockLattices.end());
00435     return *it->second;
00436 }
00437 
00438 template<typename T, template<typename U> class Descriptor>
00439 BlockLattice2D<T,Descriptor> const& MultiBlockLattice2D<T,Descriptor>::getComponent(plint blockId) const {
00440     typename BlockMap::const_iterator it = blockLattices.find(blockId);
00441     PLB_ASSERT (it != blockLattices.end());
00442     return *it->second;
00443 }
00444 
00445 template<typename T, template<typename U> class Descriptor>
00446 plint MultiBlockLattice2D<T,Descriptor>::sizeOfCell() const {
00447     return sizeof(T) * (
00448             Descriptor<T>::numPop + Descriptor<T>::ExternalField::numScalars );
00449 }
00450 
00451 template<typename T, template<typename U> class Descriptor>
00452 plint MultiBlockLattice2D<T,Descriptor>::getCellDim() const {
00453     return Descriptor<T>::numPop + Descriptor<T>::ExternalField::numScalars;
00454 }
00455 
00456 template<typename T, template<typename U> class Descriptor>
00457 int MultiBlockLattice2D<T,Descriptor>::getStaticId() const {
00458     return staticId;
00459 }
00460 
00461 template<typename T, template<typename U> class Descriptor>
00462 void MultiBlockLattice2D<T,Descriptor>::copyReceive (
00463                 MultiBlock2D const& fromBlock, Box2D const& fromDomain,
00464                 Box2D const& toDomain, modif::ModifT whichData )
00465 {
00466     MultiBlockLattice2D<T,Descriptor> const* fromLattice =
00467         dynamic_cast<MultiBlockLattice2D<T,Descriptor> const* >(&fromBlock);
00468     PLB_ASSERT( fromLattice );
00469     copy(*fromLattice, fromDomain, *this, toDomain, whichData);
00470 }
00471 
00473 
00474 template<typename T, template<typename U> class Descriptor>
00475 double getStoredAverageDensity(MultiBlockLattice2D<T,Descriptor> const& blockLattice) {
00476     return Descriptor<T>::fullRho (
00477                blockLattice.getInternalStatistics().getAverage (
00478                   LatticeStatistics::avRhoBar ) );
00479 }
00480 
00481 template<typename T, template<typename U> class Descriptor>
00482 double getStoredAverageEnergy(MultiBlockLattice2D<T,Descriptor> const& blockLattice) {
00483     return 0.5 * blockLattice.getInternalStatistics().getAverage (
00484                         LatticeStatistics::avUSqr );
00485 }
00486 
00487 template<typename T, template<typename U> class Descriptor>
00488 double getStoredMaxVelocity(MultiBlockLattice2D<T,Descriptor> const& blockLattice) {
00489     return std::sqrt( blockLattice.getInternalStatistics().getMax (
00490                              LatticeStatistics::maxUSqr ) );
00491 }
00492 
00493 }  // namespace plb
00494 
00495 #endif  // MULTI_BLOCK_LATTICE_2D_HH