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