$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 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
1.6.3
1.6.3