$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 DATA_INITIALIZER_FUNCTIONAL_3D_HH 00029 #define DATA_INITIALIZER_FUNCTIONAL_3D_HH 00030 00031 #include "dataProcessors/dataInitializerFunctional3D.h" 00032 #include "core/cell.h" 00033 #include "latticeBoltzmann/geometricOperationTemplates.h" 00034 #include "atomicBlock/blockLattice3D.h" 00035 #include "multiGrid/multiGridUtil.h" 00036 00037 namespace plb { 00038 00039 /* *************** PART I ******************************************** */ 00040 /* *************** Initialization of the block-lattice *************** */ 00041 /* ******************************************************************* */ 00042 00043 template<typename T, template<class U> class Descriptor> 00044 OneCellFunctional3D<T,Descriptor>::~OneCellFunctional3D() 00045 { } 00046 00047 template<typename T, template<class U> class Descriptor> 00048 BlockDomain::DomainT OneCellFunctional3D<T,Descriptor>::appliesTo() const { 00049 return BlockDomain::bulkAndEnvelope; 00050 } 00051 00052 template<typename T, template<class U> class Descriptor> 00053 void OneCellFunctional3D<T,Descriptor>::getTypeOfModification ( 00054 std::vector<modif::ModifT>& modified ) const 00055 { 00056 modified[0] = modif::staticVariables; 00057 } 00058 00059 00060 template<typename T, template<class U> class Descriptor> 00061 void OneCellFunctional3D<T,Descriptor>::setscale(int dxScale, int dtScale) 00062 { } 00063 00064 00065 template<typename T, template<class U> class Descriptor> 00066 OneCellIndexedFunctional3D<T,Descriptor>::~OneCellIndexedFunctional3D() 00067 { } 00068 00069 template<typename T, template<class U> class Descriptor> 00070 BlockDomain::DomainT OneCellIndexedFunctional3D<T,Descriptor>::appliesTo() const { 00071 return BlockDomain::bulkAndEnvelope; 00072 } 00073 00074 template<typename T, template<class U> class Descriptor> 00075 void OneCellIndexedFunctional3D<T,Descriptor>::getTypeOfModification(std::vector<modif::ModifT>& modified) const 00076 { 00077 modified[0] = modif::staticVariables; 00078 } 00079 00080 template<typename T, template<class U> class Descriptor> 00081 void OneCellIndexedFunctional3D<T,Descriptor>::setscale(int dxScale, int dtScale) 00082 { } 00083 00084 00085 template<typename T, template<class U> class Descriptor> 00086 GenericLatticeFunctional3D<T,Descriptor>::GenericLatticeFunctional3D ( 00087 OneCellFunctional3D<T,Descriptor>* f_ ) 00088 : f(f_) 00089 { } 00090 00091 template<typename T, template<class U> class Descriptor> 00092 GenericLatticeFunctional3D<T,Descriptor>::GenericLatticeFunctional3D ( 00093 GenericLatticeFunctional3D<T,Descriptor> const& rhs ) 00094 : f(rhs.f->clone()) 00095 { } 00096 00097 template<typename T, template<class U> class Descriptor> 00098 GenericLatticeFunctional3D<T,Descriptor>::~GenericLatticeFunctional3D() { 00099 delete f; 00100 } 00101 00102 template<typename T, template<class U> class Descriptor> 00103 GenericLatticeFunctional3D<T,Descriptor>& GenericLatticeFunctional3D<T,Descriptor>::operator= ( 00104 GenericLatticeFunctional3D<T,Descriptor> const& rhs ) 00105 { 00106 delete f; 00107 f = rhs.f->clone(); 00108 return *this; 00109 } 00110 00111 template<typename T, template<class U> class Descriptor> 00112 void GenericLatticeFunctional3D<T,Descriptor>::process ( 00113 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00114 { 00115 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00116 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00117 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00118 f->execute(lattice.get(iX,iY,iZ)); 00119 } 00120 } 00121 } 00122 } 00123 00124 template<typename T, template<class U> class Descriptor> 00125 GenericLatticeFunctional3D<T,Descriptor>* 00126 GenericLatticeFunctional3D<T,Descriptor>::clone() const 00127 { 00128 return new GenericLatticeFunctional3D<T,Descriptor>(*this); 00129 } 00130 00131 template<typename T, template<class U> class Descriptor> 00132 void GenericLatticeFunctional3D<T,Descriptor>::getTypeOfModification ( 00133 std::vector<modif::ModifT>& modified ) const 00134 { 00135 f->getTypeOfModification(modified); 00136 } 00137 00138 template<typename T, template<class U> class Descriptor> 00139 BlockDomain::DomainT GenericLatticeFunctional3D<T,Descriptor>::appliesTo() const { 00140 return f->appliesTo(); 00141 } 00142 00143 template<typename T, template<class U> class Descriptor> 00144 void GenericLatticeFunctional3D<T,Descriptor>::setscale(int dxScale, int dtScale) { 00145 f->setscale(dxScale, dtScale); 00146 } 00147 00148 00149 00150 template<typename T, template<class U> class Descriptor> 00151 GenericIndexedLatticeFunctional3D<T,Descriptor>::GenericIndexedLatticeFunctional3D ( 00152 OneCellIndexedFunctional3D<T,Descriptor>* f_ ) 00153 : f(f_) 00154 { } 00155 00156 template<typename T, template<class U> class Descriptor> 00157 GenericIndexedLatticeFunctional3D<T,Descriptor>::GenericIndexedLatticeFunctional3D ( 00158 GenericIndexedLatticeFunctional3D<T,Descriptor> const& rhs ) 00159 : f(rhs.f->clone()) 00160 { } 00161 00162 template<typename T, template<class U> class Descriptor> 00163 GenericIndexedLatticeFunctional3D<T,Descriptor>::~GenericIndexedLatticeFunctional3D() { 00164 delete f; 00165 } 00166 00167 template<typename T, template<class U> class Descriptor> 00168 GenericIndexedLatticeFunctional3D<T,Descriptor>& 00169 GenericIndexedLatticeFunctional3D<T,Descriptor>::operator= ( 00170 GenericIndexedLatticeFunctional3D<T,Descriptor> const& rhs ) 00171 { 00172 delete f; 00173 f = rhs.f->clone(); 00174 return *this; 00175 } 00176 00177 template<typename T, template<class U> class Descriptor> 00178 void GenericIndexedLatticeFunctional3D<T,Descriptor>::process ( 00179 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00180 { 00181 Dot3D relativeOffset = lattice.getLocation(); 00182 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00183 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00184 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00185 f->execute ( iX+relativeOffset.x, 00186 iY+relativeOffset.y, 00187 iZ+relativeOffset.z, 00188 lattice.get(iX,iY,iZ) ); 00189 } 00190 } 00191 } 00192 } 00193 00194 template<typename T, template<class U> class Descriptor> 00195 GenericIndexedLatticeFunctional3D<T,Descriptor>* 00196 GenericIndexedLatticeFunctional3D<T,Descriptor>::clone() const 00197 { 00198 return new GenericIndexedLatticeFunctional3D<T,Descriptor>(*this); 00199 } 00200 00201 template<typename T, template<class U> class Descriptor> 00202 void GenericIndexedLatticeFunctional3D<T,Descriptor>::getTypeOfModification ( 00203 std::vector<modif::ModifT>& modified ) const 00204 { 00205 f->getTypeOfModification(modified); 00206 } 00207 00208 template<typename T, template<class U> class Descriptor> 00209 BlockDomain::DomainT GenericIndexedLatticeFunctional3D<T,Descriptor>::appliesTo() const 00210 { 00211 return f->appliesTo(); 00212 } 00213 00214 template<typename T, template<class U> class Descriptor> 00215 void GenericIndexedLatticeFunctional3D<T,Descriptor>::setscale(int dxScale, int dtScale) 00216 { 00217 f->setscale(dxScale, dtScale); 00218 } 00219 00220 00221 /* *************** Class InstantiateDynamicsFunctional3D ************* */ 00222 00223 template<typename T, template<typename U> class Descriptor> 00224 InstantiateDynamicsFunctional3D<T,Descriptor>::InstantiateDynamicsFunctional3D ( 00225 Dynamics<T,Descriptor>* dynamics_ ) 00226 : dynamics(dynamics_) 00227 { } 00228 00229 template<typename T, template<typename U> class Descriptor> 00230 InstantiateDynamicsFunctional3D<T,Descriptor>::InstantiateDynamicsFunctional3D ( 00231 InstantiateDynamicsFunctional3D<T,Descriptor> const& rhs ) 00232 : dynamics(rhs.dynamics->clone()) 00233 { } 00234 00235 template<typename T, template<typename U> class Descriptor> 00236 InstantiateDynamicsFunctional3D<T,Descriptor>& 00237 InstantiateDynamicsFunctional3D<T,Descriptor>::operator= ( 00238 InstantiateDynamicsFunctional3D<T,Descriptor> const& rhs ) 00239 { 00240 delete dynamics; dynamics = rhs.dynamics->clone(); 00241 return *this; 00242 } 00243 00244 00245 template<typename T, template<typename U> class Descriptor> 00246 InstantiateDynamicsFunctional3D<T,Descriptor>::~InstantiateDynamicsFunctional3D() { 00247 delete dynamics; 00248 } 00249 00250 template<typename T, template<typename U> class Descriptor> 00251 void InstantiateDynamicsFunctional3D<T,Descriptor>::process ( 00252 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00253 { 00254 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00255 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00256 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00257 lattice.attributeDynamics(iX,iY,iZ, dynamics->clone()); 00258 } 00259 } 00260 } 00261 } 00262 00263 template<typename T, template<typename U> class Descriptor> 00264 BlockDomain::DomainT InstantiateDynamicsFunctional3D<T,Descriptor>::appliesTo() const { 00265 // Dynamics needs to be instantiated everywhere, including envelope. 00266 return BlockDomain::bulkAndEnvelope; 00267 } 00268 00269 template<typename T, template<typename U> class Descriptor> 00270 void InstantiateDynamicsFunctional3D<T,Descriptor>::getTypeOfModification ( 00271 std::vector<modif::ModifT>& modified ) const 00272 { 00273 modified[0] = modif::staticVariables; 00274 } 00275 00276 template<typename T, template<typename U> class Descriptor> 00277 InstantiateDynamicsFunctional3D<T,Descriptor>* 00278 InstantiateDynamicsFunctional3D<T,Descriptor>::clone() const 00279 { 00280 return new InstantiateDynamicsFunctional3D<T,Descriptor>(*this); 00281 } 00282 00283 00284 /* ************* Class InstantiateComplexDomainDynamicsFunctional3D ** */ 00285 00286 template<typename T, template<typename U> class Descriptor> 00287 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::InstantiateComplexDomainDynamicsFunctional3D ( 00288 Dynamics<T,Descriptor>* dynamics_, DomainFunctional3D* domain_ ) 00289 : dynamics(dynamics_), 00290 domain(domain_) 00291 { } 00292 00293 template<typename T, template<typename U> class Descriptor> 00294 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::InstantiateComplexDomainDynamicsFunctional3D ( 00295 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor> const& rhs ) 00296 : dynamics(rhs.dynamics->clone()), 00297 domain(rhs.domain->clone()) 00298 { } 00299 00300 template<typename T, template<typename U> class Descriptor> 00301 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>& 00302 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::operator= ( 00303 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor> const& rhs ) 00304 { 00305 delete dynamics; dynamics = rhs.dynamics->clone(); 00306 delete domain; domain = rhs.domain->clone(); 00307 return *this; 00308 } 00309 00310 template<typename T, template<typename U> class Descriptor> 00311 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::~InstantiateComplexDomainDynamicsFunctional3D() 00312 { 00313 delete dynamics; 00314 delete domain; 00315 } 00316 00317 template<typename T, template<typename U> class Descriptor> 00318 void InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::process ( 00319 Box3D boundingBox, BlockLattice3D<T,Descriptor>& lattice ) 00320 { 00321 Dot3D relativeOffset = lattice.getLocation(); 00322 for (plint iX=boundingBox.x0; iX<=boundingBox.x1; ++iX) { 00323 for (plint iY=boundingBox.y0; iY<=boundingBox.y1; ++iY) { 00324 for (plint iZ=boundingBox.z0; iZ<=boundingBox.z1; ++iZ) { 00325 if ((*domain)(iX+relativeOffset.x,iY+relativeOffset.y,iZ+relativeOffset.z)) { 00326 lattice.attributeDynamics(iX,iY,iZ, dynamics->clone()); 00327 } 00328 } 00329 } 00330 } 00331 } 00332 00333 template<typename T, template<typename U> class Descriptor> 00334 BlockDomain::DomainT InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::appliesTo() const 00335 { 00336 // Dynamics needs to be instantiated everywhere, including envelope. 00337 return BlockDomain::bulkAndEnvelope; 00338 } 00339 00340 template<typename T, template<typename U> class Descriptor> 00341 void InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::getTypeOfModification ( 00342 std::vector<modif::ModifT>& modified) const 00343 { 00344 modified[0] = modif::staticVariables; 00345 } 00346 00347 template<typename T, template<typename U> class Descriptor> 00348 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>* 00349 InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>::clone() const 00350 { 00351 return new InstantiateComplexDomainDynamicsFunctional3D<T,Descriptor>(*this); 00352 } 00353 00354 00355 /* ************* Class InstantiateDotDynamicsFunctional3D ******************* */ 00356 00357 template<typename T, template<typename U> class Descriptor> 00358 InstantiateDotDynamicsFunctional3D<T,Descriptor>::InstantiateDotDynamicsFunctional3D ( 00359 Dynamics<T,Descriptor>* dynamics_ ) 00360 : dynamics(dynamics_) 00361 { } 00362 00363 template<typename T, template<typename U> class Descriptor> 00364 InstantiateDotDynamicsFunctional3D<T,Descriptor>::InstantiateDotDynamicsFunctional3D ( 00365 InstantiateDotDynamicsFunctional3D<T,Descriptor> const& rhs ) 00366 : dynamics(rhs.dynamics->clone()) 00367 { } 00368 00369 template<typename T, template<typename U> class Descriptor> 00370 InstantiateDotDynamicsFunctional3D<T,Descriptor>& 00371 InstantiateDotDynamicsFunctional3D<T,Descriptor>::operator= ( 00372 InstantiateDotDynamicsFunctional3D<T,Descriptor> const& rhs ) 00373 { 00374 delete dynamics; dynamics = rhs.dynamics->clone(); 00375 return *this; 00376 } 00377 00378 template<typename T, template<typename U> class Descriptor> 00379 InstantiateDotDynamicsFunctional3D<T,Descriptor>::~InstantiateDotDynamicsFunctional3D() 00380 { 00381 delete dynamics; 00382 } 00383 00384 template<typename T, template<typename U> class Descriptor> 00385 void InstantiateDotDynamicsFunctional3D<T,Descriptor>::process ( 00386 DotList3D const& dotList, BlockLattice3D<T,Descriptor>& lattice ) 00387 { 00388 for (plint iDot=0; iDot<dotList.getN(); ++iDot) { 00389 Dot3D const& dot = dotList.getDot(iDot); 00390 lattice.attributeDynamics(dot.x, dot.y, dot.z, dynamics->clone()); 00391 } 00392 } 00393 00394 template<typename T, template<typename U> class Descriptor> 00395 BlockDomain::DomainT InstantiateDotDynamicsFunctional3D<T,Descriptor>::appliesTo() const 00396 { 00397 // Dynamics needs to be instantiated everywhere, including envelope. 00398 return BlockDomain::bulkAndEnvelope; 00399 } 00400 00401 template<typename T, template<typename U> class Descriptor> 00402 void InstantiateDotDynamicsFunctional3D<T,Descriptor>::getTypeOfModification ( 00403 std::vector<modif::ModifT>& modified ) const 00404 { 00405 modified[0] = modif::staticVariables; 00406 } 00407 00408 template<typename T, template<typename U> class Descriptor> 00409 InstantiateDotDynamicsFunctional3D<T,Descriptor>* 00410 InstantiateDotDynamicsFunctional3D<T,Descriptor>::clone() const 00411 { 00412 return new InstantiateDotDynamicsFunctional3D<T,Descriptor>(*this); 00413 } 00414 00415 00416 /* ************* Class DynamicsFromMaskFunctional3D ************************ */ 00417 00418 template<typename T, template<typename U> class Descriptor> 00419 DynamicsFromMaskFunctional3D<T,Descriptor>::DynamicsFromMaskFunctional3D ( 00420 Dynamics<T,Descriptor>* dynamics_, bool whichFlag_ ) 00421 : dynamics(dynamics_), whichFlag(whichFlag_) 00422 { } 00423 00424 template<typename T, template<typename U> class Descriptor> 00425 DynamicsFromMaskFunctional3D<T,Descriptor>::DynamicsFromMaskFunctional3D ( 00426 DynamicsFromMaskFunctional3D<T,Descriptor> const& rhs ) 00427 : dynamics(rhs.dynamics->clone()), 00428 whichFlag(rhs.whichFlag) 00429 { } 00430 00431 template<typename T, template<typename U> class Descriptor> 00432 DynamicsFromMaskFunctional3D<T,Descriptor>& 00433 DynamicsFromMaskFunctional3D<T,Descriptor>::operator= ( 00434 DynamicsFromMaskFunctional3D<T,Descriptor> const& rhs ) 00435 { 00436 delete dynamics; dynamics = rhs.dynamics->clone(); 00437 whichFlag = rhs.whichFlag; 00438 return *this; 00439 } 00440 00441 template<typename T, template<typename U> class Descriptor> 00442 DynamicsFromMaskFunctional3D<T,Descriptor>::~DynamicsFromMaskFunctional3D() { 00443 delete dynamics; 00444 } 00445 00446 template<typename T, template<typename U> class Descriptor> 00447 void DynamicsFromMaskFunctional3D<T,Descriptor>::process ( 00448 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, 00449 ScalarField3D<bool>& mask ) 00450 { 00451 Dot3D offset = computeRelativeDisplacement(lattice, mask); 00452 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00453 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00454 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00455 bool flag = mask.get(iX+offset.x, iY+offset.y, iZ+offset.z); 00456 if ( util::boolIsEqual(flag, whichFlag) ) { 00457 lattice.attributeDynamics(iX,iY,iZ, dynamics->clone()); 00458 } 00459 } 00460 } 00461 } 00462 } 00463 00464 template<typename T, template<typename U> class Descriptor> 00465 BlockDomain::DomainT DynamicsFromMaskFunctional3D<T,Descriptor>::appliesTo() const { 00466 // Dynamics needs to be instantiated everywhere, including envelope. 00467 return BlockDomain::bulkAndEnvelope; 00468 } 00469 00470 template<typename T, template<typename U> class Descriptor> 00471 void DynamicsFromMaskFunctional3D<T,Descriptor>::getTypeOfModification ( 00472 std::vector<modif::ModifT>& modified ) const 00473 { 00474 modified[0] = modif::staticVariables; 00475 modified[1] = modif::nothing; 00476 } 00477 00478 template<typename T, template<typename U> class Descriptor> 00479 DynamicsFromMaskFunctional3D<T,Descriptor>* 00480 DynamicsFromMaskFunctional3D<T,Descriptor>::clone() const 00481 { 00482 return new DynamicsFromMaskFunctional3D<T,Descriptor>(*this); 00483 } 00484 00485 00486 /* ************* Class DynamicsFromIntMaskFunctional3D ************************ */ 00487 00488 template<typename T, template<typename U> class Descriptor> 00489 DynamicsFromIntMaskFunctional3D<T,Descriptor>::DynamicsFromIntMaskFunctional3D ( 00490 Dynamics<T,Descriptor>* dynamics_, int whichFlag_ ) 00491 : dynamics(dynamics_), whichFlag(whichFlag_) 00492 { } 00493 00494 template<typename T, template<typename U> class Descriptor> 00495 DynamicsFromIntMaskFunctional3D<T,Descriptor>::DynamicsFromIntMaskFunctional3D ( 00496 DynamicsFromIntMaskFunctional3D<T,Descriptor> const& rhs ) 00497 : dynamics(rhs.dynamics->clone()), 00498 whichFlag(rhs.whichFlag) 00499 { } 00500 00501 template<typename T, template<typename U> class Descriptor> 00502 DynamicsFromIntMaskFunctional3D<T,Descriptor>& 00503 DynamicsFromIntMaskFunctional3D<T,Descriptor>::operator= ( 00504 DynamicsFromIntMaskFunctional3D<T,Descriptor> const& rhs ) 00505 { 00506 delete dynamics; dynamics = rhs.dynamics->clone(); 00507 whichFlag = rhs.whichFlag; 00508 return *this; 00509 } 00510 00511 template<typename T, template<typename U> class Descriptor> 00512 DynamicsFromIntMaskFunctional3D<T,Descriptor>::~DynamicsFromIntMaskFunctional3D() { 00513 delete dynamics; 00514 } 00515 00516 template<typename T, template<typename U> class Descriptor> 00517 void DynamicsFromIntMaskFunctional3D<T,Descriptor>::process ( 00518 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, 00519 ScalarField3D<int>& mask ) 00520 { 00521 Dot3D offset = computeRelativeDisplacement(lattice, mask); 00522 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00523 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00524 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00525 int flag = mask.get(iX+offset.x, iY+offset.y, iZ+offset.z); 00526 if ( flag == whichFlag ) { 00527 lattice.attributeDynamics(iX,iY,iZ, dynamics->clone()); 00528 } 00529 } 00530 } 00531 } 00532 } 00533 00534 template<typename T, template<typename U> class Descriptor> 00535 BlockDomain::DomainT DynamicsFromIntMaskFunctional3D<T,Descriptor>::appliesTo() const { 00536 // Dynamics needs to be instantiated everywhere, including envelope. 00537 return BlockDomain::bulkAndEnvelope; 00538 } 00539 00540 template<typename T, template<typename U> class Descriptor> 00541 void DynamicsFromIntMaskFunctional3D<T,Descriptor>::getTypeOfModification ( 00542 std::vector<modif::ModifT>& modified ) const 00543 { 00544 modified[0] = modif::staticVariables; 00545 modified[1] = modif::nothing; 00546 } 00547 00548 template<typename T, template<typename U> class Descriptor> 00549 DynamicsFromIntMaskFunctional3D<T,Descriptor>* 00550 DynamicsFromIntMaskFunctional3D<T,Descriptor>::clone() const 00551 { 00552 return new DynamicsFromIntMaskFunctional3D<T,Descriptor>(*this); 00553 } 00554 00555 /* ************* Class RecomposeFromFlowVariablesFunctional3D ******************* */ 00556 00557 template<typename T, template<typename U> class Descriptor> 00558 void RecomposeFromFlowVariablesFunctional3D<T,Descriptor>::processGenericBlocks ( 00559 Box3D domain, std::vector<AtomicBlock3D*> atomicBlocks ) 00560 { 00561 BlockLattice3D<T,Descriptor>& lattice = 00562 dynamic_cast<BlockLattice3D<T,Descriptor>&>(*atomicBlocks[0]); 00563 ScalarField3D<T> const& rhoField = 00564 dynamic_cast<ScalarField3D<T> const&>(*atomicBlocks[1]); 00565 TensorField3D<T,3> const& uField = 00566 dynamic_cast<TensorField3D<T,3> const&>(*atomicBlocks[2]); 00567 TensorField3D<T,6> const& SField = 00568 dynamic_cast<TensorField3D<T,6> const&>(*atomicBlocks[3]); 00569 00570 Dot3D offset1 = computeRelativeDisplacement(lattice, rhoField); 00571 Dot3D offset2 = computeRelativeDisplacement(lattice, uField); 00572 Dot3D offset3 = computeRelativeDisplacement(lattice, SField); 00573 00574 std::vector<T> rawData(10); 00575 00576 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00577 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00578 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00579 Cell<T,Descriptor>& cell = lattice.get(iX,iY,iZ); 00580 T rho = rhoField.get(iX+offset1.x, iY+offset1.y, iZ+offset1.z); 00581 Array<T,3> const& u = uField.get(iX+offset2.x, iY+offset2.y, iZ+offset2.z); 00582 Array<T,6> const& S = SField.get(iX+offset3.x, iY+offset3.y, iZ+offset3.z); 00583 00584 // Convert rho --> rhoBar. 00585 rawData[0] = Descriptor<T>::rhoBar(rho); 00586 00587 // Convert u --> j 00588 rawData[1] = rho*u[0]; 00589 rawData[2] = rho*u[1]; 00590 rawData[3] = rho*u[2]; 00591 00592 // Convert S --> PiNeq. 00593 T omega = cell.getDynamics().getOmega(); 00594 T prefactor = - Descriptor<T>::cs2 * rho * (T)2 / omega; 00595 rawData[4] = S[0] * prefactor; 00596 rawData[5] = S[1] * prefactor; 00597 rawData[6] = S[2] * prefactor; 00598 rawData[7] = S[3] * prefactor; 00599 rawData[8] = S[4] * prefactor; 00600 rawData[9] = S[5] * prefactor; 00601 00602 // Recompose the cell. 00603 plint recomposeOrder = 1; 00604 cell.getDynamics().recompose(cell, rawData, recomposeOrder); 00605 } 00606 } 00607 } 00608 } 00609 00610 template<typename T, template<typename U> class Descriptor> 00611 RecomposeFromFlowVariablesFunctional3D<T,Descriptor>* 00612 RecomposeFromFlowVariablesFunctional3D<T,Descriptor>::clone() const 00613 { 00614 return new RecomposeFromFlowVariablesFunctional3D<T,Descriptor>(*this); 00615 } 00616 00617 template<typename T, template<typename U> class Descriptor> 00618 BlockDomain::DomainT RecomposeFromFlowVariablesFunctional3D<T,Descriptor>::appliesTo() const 00619 { 00620 // We could directly apply to the envelope too, but let's keep it 00621 // bulk-only for future compatibility. 00622 return BlockDomain::bulk; 00623 } 00624 00625 template<typename T, template<typename U> class Descriptor> 00626 void RecomposeFromFlowVariablesFunctional3D<T,Descriptor>::getTypeOfModification ( 00627 std::vector<modif::ModifT>& modified) const 00628 { 00629 modified[0] = modif::staticVariables; 00630 modified[1] = modif::nothing; 00631 modified[2] = modif::nothing; 00632 modified[3] = modif::nothing; 00633 } 00634 00635 00636 /* ************* Class AssignOmegaFunctional3D ******************* */ 00637 00638 template<typename T, template<typename U> class Descriptor> 00639 AssignOmegaFunctional3D<T,Descriptor>::AssignOmegaFunctional3D(T omega_) 00640 : omega(omega_) 00641 { } 00642 00643 template<typename T, template<typename U> class Descriptor> 00644 void AssignOmegaFunctional3D<T,Descriptor>::process ( 00645 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00646 { 00647 // Define dimensions of a viscosity. 00648 int dimDx = 2; 00649 int dimDt = -1; 00650 T scaleFactor = scaleFromReference(this->getDxScale(), dimDx, 00651 this->getDtScale(), dimDt); 00652 T nu_cs2 = (T)1/omega - (T)1/(T)2; 00653 T scaledOmega = (T)1/(scaleFactor*nu_cs2 + (T)1/(T)2); 00654 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00655 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00656 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00657 lattice.get(iX,iY,iZ).getDynamics().setOmega(scaledOmega); 00658 } 00659 } 00660 } 00661 } 00662 00663 template<typename T, template<typename U> class Descriptor> 00664 AssignOmegaFunctional3D<T,Descriptor>* 00665 AssignOmegaFunctional3D<T,Descriptor>::clone() const 00666 { 00667 return new AssignOmegaFunctional3D<T,Descriptor>(*this); 00668 } 00669 00670 template<typename T, template<typename U> class Descriptor> 00671 BlockDomain::DomainT AssignOmegaFunctional3D<T,Descriptor>::appliesTo() const 00672 { 00673 // Omega needs to be set on envelope nodes as well, because the dynamics object 00674 // is being modified. 00675 return BlockDomain::bulkAndEnvelope; 00676 } 00677 00678 template<typename T, template<typename U> class Descriptor> 00679 void AssignOmegaFunctional3D<T,Descriptor>::getTypeOfModification ( 00680 std::vector<modif::ModifT>& modified) const 00681 { 00682 modified[0] = modif::staticVariables; 00683 } 00684 00685 00686 /* ************* Class SetConstBoundaryVelocityFunctional3D ******************* */ 00687 00688 template<typename T, template<typename U> class Descriptor> 00689 SetConstBoundaryVelocityFunctional3D<T,Descriptor>::SetConstBoundaryVelocityFunctional3D ( 00690 Array<T,Descriptor<T>::d> velocity ) 00691 : u(velocity) 00692 { } 00693 00694 template<typename T, template<typename U> class Descriptor> 00695 void SetConstBoundaryVelocityFunctional3D<T,Descriptor>::process ( 00696 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00697 { 00698 int dimDx = 1; 00699 int dimDt = -1; 00700 T scaleFactor = scaleFromReference(this->getDxScale(), dimDx, 00701 this->getDtScale(), dimDt); 00702 Array<T,3> scaledU = u*scaleFactor; 00703 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00704 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00705 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00706 lattice.get(iX,iY,iZ).defineVelocity(scaledU); 00707 } 00708 } 00709 } 00710 } 00711 00712 template<typename T, template<typename U> class Descriptor> 00713 SetConstBoundaryVelocityFunctional3D<T,Descriptor>* 00714 SetConstBoundaryVelocityFunctional3D<T,Descriptor>::clone() const 00715 { 00716 return new SetConstBoundaryVelocityFunctional3D<T,Descriptor>(*this); 00717 } 00718 00719 template<typename T, template<typename U> class Descriptor> 00720 BlockDomain::DomainT SetConstBoundaryVelocityFunctional3D<T,Descriptor>::appliesTo() const 00721 { 00722 // Boundary condition needs to be set on envelope nodes as well to ensure 00723 // proper behavior. 00724 return BlockDomain::bulkAndEnvelope; 00725 } 00726 00727 template<typename T, template<typename U> class Descriptor> 00728 void SetConstBoundaryVelocityFunctional3D<T,Descriptor>::getTypeOfModification ( 00729 std::vector<modif::ModifT>& modified) const 00730 { 00731 modified[0] = modif::staticVariables; 00732 } 00733 00734 00735 /* ************* Class SetConstBoundaryDensityFunctional3D ******************* */ 00736 00737 template<typename T, template<typename U> class Descriptor> 00738 SetConstBoundaryDensityFunctional3D<T,Descriptor>::SetConstBoundaryDensityFunctional3D(T rho_) 00739 : rho(rho_) 00740 { } 00741 00742 template<typename T, template<typename U> class Descriptor> 00743 void SetConstBoundaryDensityFunctional3D<T,Descriptor>::process ( 00744 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00745 { 00746 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00747 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00748 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00749 lattice.get(iX,iY,iZ).defineDensity(rho); 00750 } 00751 } 00752 } 00753 } 00754 00755 template<typename T, template<typename U> class Descriptor> 00756 SetConstBoundaryDensityFunctional3D<T,Descriptor>* 00757 SetConstBoundaryDensityFunctional3D<T,Descriptor>::clone() const 00758 { 00759 return new SetConstBoundaryDensityFunctional3D<T,Descriptor>(*this); 00760 } 00761 00762 template<typename T, template<typename U> class Descriptor> 00763 BlockDomain::DomainT SetConstBoundaryDensityFunctional3D<T,Descriptor>::appliesTo() const 00764 { 00765 // Boundary condition needs to be set on envelope nodes as well to ensure 00766 // proper behavior. 00767 return BlockDomain::bulkAndEnvelope; 00768 } 00769 00770 template<typename T, template<typename U> class Descriptor> 00771 void SetConstBoundaryDensityFunctional3D<T,Descriptor>::getTypeOfModification ( 00772 std::vector<modif::ModifT>& modified ) const 00773 { 00774 modified[0] = modif::staticVariables; 00775 } 00776 00777 00778 /* ************* Class IniConstEquilibriumFunctional3D ******************* */ 00779 00780 template<typename T, template<typename U> class Descriptor> 00781 IniConstEquilibriumFunctional3D<T,Descriptor>::IniConstEquilibriumFunctional3D ( 00782 T density_, Array<T,Descriptor<T>::d> velocity, T temperature ) 00783 : rhoBar(Descriptor<T>::rhoBar(density_)), 00784 j (density_*velocity[0], density_*velocity[1], density_*velocity[2]), 00785 jSqr (VectorTemplate<T,Descriptor>::normSqr(j)), 00786 thetaBar(temperature-(T)1) 00787 { } 00788 00789 template<typename T, template<typename U> class Descriptor> 00790 void IniConstEquilibriumFunctional3D<T,Descriptor>::process ( 00791 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00792 { 00793 int dimDx = 1; 00794 int dimDt = -1; 00795 T scaleFactor = scaleFromReference(this->getDxScale(), dimDx, 00796 this->getDtScale(), dimDt); 00797 Array<T,3> scaledJ = j*scaleFactor; 00798 T scaledJsqr = jSqr*scaleFactor*scaleFactor; 00799 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00800 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00801 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00802 for (plint iPop=0; iPop<Descriptor<T>::q; ++iPop) { 00803 lattice.get(iX,iY,iZ)[iPop] = 00804 lattice.get(iX,iY,iZ).computeEquilibrium(iPop, rhoBar, scaledJ, scaledJsqr, thetaBar); 00805 } 00806 } 00807 } 00808 } 00809 } 00810 00811 template<typename T, template<typename U> class Descriptor> 00812 IniConstEquilibriumFunctional3D<T,Descriptor>* 00813 IniConstEquilibriumFunctional3D<T,Descriptor>::clone() const 00814 { 00815 return new IniConstEquilibriumFunctional3D<T,Descriptor>(*this); 00816 } 00817 00818 template<typename T, template<typename U> class Descriptor> 00819 BlockDomain::DomainT IniConstEquilibriumFunctional3D<T,Descriptor>::appliesTo() const 00820 { 00821 // Include boundary right away, to avoid need for envelope update. 00822 return BlockDomain::bulkAndEnvelope; 00823 } 00824 00825 template<typename T, template<typename U> class Descriptor> 00826 void IniConstEquilibriumFunctional3D<T,Descriptor>::getTypeOfModification ( 00827 std::vector<modif::ModifT>& modified ) const 00828 { 00829 modified[0] = modif::staticVariables; 00830 } 00831 00832 00833 /* ************* Class StripeOffDensityOffsetFunctional3D ******************* */ 00834 00835 template<typename T, template<typename U> class Descriptor> 00836 StripeOffDensityOffsetFunctional3D<T,Descriptor>::StripeOffDensityOffsetFunctional3D(T deltaRho_) 00837 : deltaRho(deltaRho_) 00838 { } 00839 00840 template<typename T, template<typename U> class Descriptor> 00841 void StripeOffDensityOffsetFunctional3D<T,Descriptor>::process ( 00842 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00843 { 00844 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00845 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00846 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00847 Cell<T,Descriptor>& cell = lattice.get(iX,iY,iZ); 00848 Dynamics<T,Descriptor>& dynamics = cell.getDynamics(); 00849 plint orderOfDecomposition = 0; 00850 std::vector<T> rawData; 00851 dynamics.decompose(cell, rawData, orderOfDecomposition); 00852 T& rhoBar = rawData[0]; 00853 rhoBar -= deltaRho; 00854 dynamics.recompose(cell, rawData, orderOfDecomposition); 00855 } 00856 } 00857 } 00858 } 00859 00860 template<typename T, template<typename U> class Descriptor> 00861 StripeOffDensityOffsetFunctional3D<T,Descriptor>* 00862 StripeOffDensityOffsetFunctional3D<T,Descriptor>::clone() const 00863 { 00864 return new StripeOffDensityOffsetFunctional3D<T,Descriptor>(*this); 00865 } 00866 00867 template<typename T, template<typename U> class Descriptor> 00868 BlockDomain::DomainT StripeOffDensityOffsetFunctional3D<T,Descriptor>::appliesTo() const 00869 { 00870 // Include boundary right away, to avoid need for envelope update. 00871 return BlockDomain::bulkAndEnvelope; 00872 } 00873 00874 template<typename T, template<typename U> class Descriptor> 00875 void StripeOffDensityOffsetFunctional3D<T,Descriptor>::getTypeOfModification ( 00876 std::vector<modif::ModifT>& modified) const 00877 { 00878 modified[0] = modif::staticVariables; 00879 } 00880 00881 /* ************* Class InstantiateCompositeDynamicsFunctional3D ******************* */ 00882 00883 template<typename T, template<typename U> class Descriptor> 00884 InstantiateCompositeDynamicsFunctional3D<T,Descriptor>::InstantiateCompositeDynamicsFunctional3D ( 00885 CompositeDynamics<T,Descriptor>* compositeDynamics_ ) 00886 : compositeDynamics(compositeDynamics_) 00887 { } 00888 00889 template<typename T, template<typename U> class Descriptor> 00890 InstantiateCompositeDynamicsFunctional3D<T,Descriptor>::InstantiateCompositeDynamicsFunctional3D ( 00891 InstantiateCompositeDynamicsFunctional3D<T,Descriptor> const& rhs ) 00892 : compositeDynamics(rhs.compositeDynamics->clone()) 00893 { } 00894 00895 template<typename T, template<typename U> class Descriptor> 00896 InstantiateCompositeDynamicsFunctional3D<T,Descriptor>& 00897 InstantiateCompositeDynamicsFunctional3D<T,Descriptor>::operator= ( 00898 InstantiateCompositeDynamicsFunctional3D<T,Descriptor> const& rhs ) 00899 { 00900 delete compositeDynamics; compositeDynamics = rhs.compositeDynamics->clone(); 00901 return *this; 00902 } 00903 00904 00905 template<typename T, template<typename U> class Descriptor> 00906 InstantiateCompositeDynamicsFunctional3D<T,Descriptor>::~InstantiateCompositeDynamicsFunctional3D() 00907 { 00908 delete compositeDynamics; 00909 } 00910 00911 template<typename T, template<typename U> class Descriptor> 00912 void InstantiateCompositeDynamicsFunctional3D<T,Descriptor>::process ( 00913 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00914 { 00915 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00916 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00917 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00918 lattice.attributeDynamics(iX,iY,iZ, 00919 cloneAndInsertAtTopDynamics ( 00920 lattice.get(iX,iY,iZ).getDynamics(), 00921 compositeDynamics->clone() ) ); 00922 } 00923 } 00924 } 00925 } 00926 00927 template<typename T, template<typename U> class Descriptor> 00928 void InstantiateCompositeDynamicsFunctional3D<T,Descriptor>::getTypeOfModification ( 00929 std::vector<modif::ModifT>& modified ) const 00930 { 00931 modified[0] = modif::dataStructure; 00932 } 00933 00934 template<typename T, template<typename U> class Descriptor> 00935 InstantiateCompositeDynamicsFunctional3D<T,Descriptor>* 00936 InstantiateCompositeDynamicsFunctional3D<T,Descriptor>::clone() const 00937 { 00938 return new InstantiateCompositeDynamicsFunctional3D<T,Descriptor>(*this); 00939 } 00940 00941 00942 00943 /* ************* Class SetExternalScalarFunctional3D ******************* */ 00944 00945 template<typename T, template<typename U> class Descriptor> 00946 SetExternalScalarFunctional3D<T,Descriptor>::SetExternalScalarFunctional3D ( 00947 int whichScalar_, T externalScalar_) 00948 : whichScalar(whichScalar_), 00949 externalScalar(externalScalar_) 00950 { 00951 PLB_ASSERT(whichScalar < Descriptor<T>::ExternalField::numScalars); 00952 } 00953 00954 template<typename T, template<typename U> class Descriptor> 00955 void SetExternalScalarFunctional3D<T,Descriptor>::process ( 00956 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00957 { 00958 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00959 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00960 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00961 *lattice.get(iX,iY,iZ).getExternal(whichScalar) = externalScalar; 00962 } 00963 } 00964 } 00965 } 00966 00967 template<typename T, template<typename U> class Descriptor> 00968 BlockDomain::DomainT SetExternalScalarFunctional3D<T,Descriptor>::appliesTo() const 00969 { 00970 return BlockDomain::bulkAndEnvelope; 00971 } 00972 00973 template<typename T, template<typename U> class Descriptor> 00974 void SetExternalScalarFunctional3D<T,Descriptor>::getTypeOfModification ( 00975 std::vector<modif::ModifT>& modified ) const 00976 { 00977 modified[0] = modif::staticVariables; 00978 } 00979 00980 template<typename T, template<typename U> class Descriptor> 00981 SetExternalScalarFunctional3D<T,Descriptor>* 00982 SetExternalScalarFunctional3D<T,Descriptor>::clone() const 00983 { 00984 return new SetExternalScalarFunctional3D<T,Descriptor>(*this); 00985 } 00986 00987 00988 /* ************* Class SetExternalVectorFunctional3D ******************* */ 00989 00990 template<typename T, template<typename U> class Descriptor> 00991 SetExternalVectorFunctional3D<T,Descriptor>::SetExternalVectorFunctional3D ( 00992 int vectorStartsAt_, Array<T,Descriptor<T>::d> const& externalVector_) 00993 : vectorStartsAt(vectorStartsAt_), 00994 externalVector(externalVector_) 00995 { 00996 PLB_ASSERT( vectorStartsAt+Descriptor<T>::d <= 00997 Descriptor<T>::ExternalField::numScalars ); 00998 } 00999 01000 template<typename T, template<typename U> class Descriptor> 01001 void SetExternalVectorFunctional3D<T,Descriptor>::process ( 01002 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 01003 { 01004 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01005 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01006 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01007 Cell<T,Descriptor>& cell = lattice.get(iX,iY,iZ); 01008 for (plint iD=0; iD<Descriptor<T>::d; ++iD) { 01009 *cell.getExternal(vectorStartsAt+iD) = externalVector[iD]; 01010 } 01011 } 01012 } 01013 } 01014 } 01015 01016 template<typename T, template<typename U> class Descriptor> 01017 BlockDomain::DomainT SetExternalVectorFunctional3D<T,Descriptor>::appliesTo() const 01018 { 01019 return BlockDomain::bulkAndEnvelope; 01020 } 01021 01022 template<typename T, template<typename U> class Descriptor> 01023 void SetExternalVectorFunctional3D<T,Descriptor>::getTypeOfModification ( 01024 std::vector<modif::ModifT>& modified ) const 01025 { 01026 modified[0] = modif::staticVariables; 01027 } 01028 01029 template<typename T, template<typename U> class Descriptor> 01030 SetExternalVectorFunctional3D<T,Descriptor>* 01031 SetExternalVectorFunctional3D<T,Descriptor>::clone() const 01032 { 01033 return new SetExternalVectorFunctional3D<T,Descriptor>(*this); 01034 } 01035 01036 01037 /* ************* Class SetExternalVectorFromTensorFieldFunctional3D ******************* */ 01038 01039 template<typename T, template<typename U> class Descriptor, int nDim> 01040 SetExternalVectorFromTensorFieldFunctional3D<T,Descriptor,nDim>::SetExternalVectorFromTensorFieldFunctional3D ( 01041 int vectorStartsAt_) 01042 : vectorStartsAt(vectorStartsAt_) 01043 { 01044 PLB_ASSERT( vectorStartsAt+nDim <= 01045 Descriptor<T>::ExternalField::numScalars ); 01046 } 01047 01048 template<typename T, template<typename U> class Descriptor, int nDim> 01049 void SetExternalVectorFromTensorFieldFunctional3D<T,Descriptor,nDim>::process ( 01050 Box3D domain, BlockLattice3D<T,Descriptor>& lattice, TensorField3D<T,nDim>& tensor ) 01051 { 01052 Dot3D offset = computeRelativeDisplacement(lattice, tensor); 01053 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01054 plint oX = iX + offset.x; 01055 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01056 plint oY = iY + offset.y; 01057 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01058 plint oZ = iZ + offset.z; 01059 Cell<T,Descriptor>& cell = lattice.get(iX,iY,iZ); 01060 Array<T,nDim> externalVector = tensor.get(oX,oY,oZ); 01061 01062 for (plint iD=0; iD<nDim; ++iD) { 01063 *cell.getExternal(vectorStartsAt+iD) = externalVector[iD]; 01064 } 01065 } 01066 } 01067 } 01068 } 01069 01070 template<typename T, template<typename U> class Descriptor, int nDim> 01071 BlockDomain::DomainT SetExternalVectorFromTensorFieldFunctional3D<T,Descriptor,nDim>::appliesTo() const 01072 { 01073 return BlockDomain::bulkAndEnvelope; 01074 } 01075 01076 template<typename T, template<typename U> class Descriptor, int nDim> 01077 void SetExternalVectorFromTensorFieldFunctional3D<T,Descriptor,nDim>::getTypeOfModification ( 01078 std::vector<modif::ModifT>& modified ) const 01079 { 01080 modified[0] = modif::staticVariables; 01081 modified[1] = modif::nothing; 01082 } 01083 01084 template<typename T, template<typename U> class Descriptor, int nDim> 01085 SetExternalVectorFromTensorFieldFunctional3D<T,Descriptor,nDim>* 01086 SetExternalVectorFromTensorFieldFunctional3D<T,Descriptor,nDim>::clone() const 01087 { 01088 return new SetExternalVectorFromTensorFieldFunctional3D<T,Descriptor,nDim>(*this); 01089 } 01090 01091 01092 01093 /* ************* Class InterpolatePopulationsFunctional3D ******************* */ 01094 01095 template<typename T, template<typename U> class Descriptor> 01096 InterpolatePopulationsFunctional3D<T,Descriptor>::InterpolatePopulationsFunctional3D ( 01097 plint minIter_, plint maxIter_ ) 01098 : minIter(minIter_), 01099 maxIter(maxIter_) 01100 { } 01101 01102 template<typename T, template<typename U> class Descriptor> 01103 void InterpolatePopulationsFunctional3D<T,Descriptor>::process ( 01104 Box3D domain, BlockLattice3D<T,Descriptor>& lattice1, 01105 BlockLattice3D<T,Descriptor>& lattice2 ) 01106 { 01107 plint currentIter = (plint)lattice1.getTimeCounter().getTime(); 01108 T lambda = 0.5 + 0.5*(T)(currentIter-minIter)/(T)(maxIter-minIter); 01109 if (lambda<0.5) lambda = 0.5; 01110 if (lambda>T(1.)) lambda = T(1.); 01111 Dot3D offset = computeRelativeDisplacement(lattice1, lattice2); 01112 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01113 plint oX = iX + offset.x; 01114 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01115 plint oY = iY + offset.y; 01116 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01117 plint oZ = iZ + offset.z; 01118 Cell<T,Descriptor>& cell1 = lattice1.get(iX,iY,iZ); 01119 Cell<T,Descriptor>& cell2 = lattice2.get(oX,oY,oZ); 01120 for (plint iPop=0; iPop<Descriptor<T>::q; ++iPop) { 01121 cell1[iPop] = lambda*cell1[iPop] + (1.-lambda)*cell2[iPop]; 01122 } 01123 } 01124 } 01125 } 01126 } 01127 01128 template<typename T, template<typename U> class Descriptor> 01129 BlockDomain::DomainT InterpolatePopulationsFunctional3D<T,Descriptor>::appliesTo() const 01130 { 01131 return BlockDomain::bulk; 01132 } 01133 01134 template<typename T, template<typename U> class Descriptor> 01135 void InterpolatePopulationsFunctional3D<T,Descriptor>::getTypeOfModification ( 01136 std::vector<modif::ModifT>& modified ) const 01137 { 01138 modified[0] = modif::staticVariables; 01139 modified[1] = modif::nothing; 01140 } 01141 01142 template<typename T, template<typename U> class Descriptor> 01143 InterpolatePopulationsFunctional3D<T,Descriptor>* 01144 InterpolatePopulationsFunctional3D<T,Descriptor>::clone() const 01145 { 01146 return new InterpolatePopulationsFunctional3D<T,Descriptor>(*this); 01147 } 01148 01149 01150 /* *************** PART II ******************************************* */ 01151 /* *************** Initialization of scalar- and tensor-fields ******* */ 01152 /* ******************************************************************* */ 01153 01154 01155 /* ************** Class IniConstScalarFunctional3D ******************* */ 01156 01157 template<typename T> 01158 IniConstScalarFunctional3D<T>::IniConstScalarFunctional3D(T value_) 01159 : value(value_) 01160 { } 01161 01162 template<typename T> 01163 void IniConstScalarFunctional3D<T>::process(Box3D domain, ScalarField3D<T>& field) { 01164 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01165 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01166 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01167 field.get(iX,iY,iZ) = value; 01168 } 01169 } 01170 } 01171 } 01172 01173 template<typename T> 01174 IniConstScalarFunctional3D<T>* IniConstScalarFunctional3D<T>::clone() const { 01175 return new IniConstScalarFunctional3D<T>(*this); 01176 } 01177 01178 template<typename T> 01179 BlockDomain::DomainT IniConstScalarFunctional3D<T>::appliesTo() const { 01180 // Include boundary right away, to avoid need for envelope update. 01181 return BlockDomain::bulkAndEnvelope; 01182 } 01183 01184 template<typename T> 01185 void IniConstScalarFunctional3D<T>::getTypeOfModification ( 01186 std::vector<modif::ModifT>& modified ) const 01187 { 01188 modified[0] = modif::staticVariables; 01189 } 01190 01191 01192 /* ************** Class MaskedIniConstScalarFunctional3D ******************* */ 01193 01194 template<typename T> 01195 MaskedIniConstScalarFunctional3D<T>::MaskedIniConstScalarFunctional3D ( 01196 int flag_, T value_ ) 01197 : flag(flag_), 01198 value(value_) 01199 { } 01200 01201 template<typename T> 01202 void MaskedIniConstScalarFunctional3D<T>::process ( 01203 Box3D domain, ScalarField3D<T>& field, ScalarField3D<int>& mask) 01204 { 01205 Dot3D offset = computeRelativeDisplacement(field, mask); 01206 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01207 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01208 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01209 if (mask.get(iX+offset.x,iY+offset.y,iZ+offset.z)==flag) { 01210 field.get(iX,iY,iZ) = value; 01211 } 01212 } 01213 } 01214 } 01215 } 01216 01217 template<typename T> 01218 MaskedIniConstScalarFunctional3D<T>* MaskedIniConstScalarFunctional3D<T>::clone() const { 01219 return new MaskedIniConstScalarFunctional3D<T>(*this); 01220 } 01221 01222 template<typename T> 01223 BlockDomain::DomainT MaskedIniConstScalarFunctional3D<T>::appliesTo() const { 01224 // Include boundary right away, to avoid need for envelope update. 01225 return BlockDomain::bulkAndEnvelope; 01226 } 01227 01228 template<typename T> 01229 void MaskedIniConstScalarFunctional3D<T>::getTypeOfModification ( 01230 std::vector<modif::ModifT>& modified ) const 01231 { 01232 modified[0] = modif::staticVariables; // Scalar-Field. 01233 modified[1] = modif::nothing; // Mask. 01234 } 01235 01236 01237 /* ************** Class IniConstTensorFunctional3D ******************* */ 01238 01239 template<typename T, int nDim> 01240 IniConstTensorFunctional3D<T,nDim>::IniConstTensorFunctional3D ( 01241 Array<T,nDim> const& value_ ) 01242 : value(value_) 01243 { } 01244 01245 template<typename T, int nDim> 01246 void IniConstTensorFunctional3D<T,nDim>::process ( 01247 Box3D domain, TensorField3D<T,nDim>& field ) 01248 { 01249 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01250 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01251 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01252 field.get(iX,iY,iZ) = value; 01253 } 01254 } 01255 } 01256 } 01257 01258 template<typename T, int nDim> 01259 IniConstTensorFunctional3D<T,nDim>* IniConstTensorFunctional3D<T,nDim>::clone() const { 01260 return new IniConstTensorFunctional3D<T,nDim>(*this); 01261 } 01262 01263 template<typename T, int nDim> 01264 BlockDomain::DomainT IniConstTensorFunctional3D<T,nDim>::appliesTo() const { 01265 // Include boundary right away, to avoid need for envelope update. 01266 return BlockDomain::bulkAndEnvelope; 01267 } 01268 01269 template<typename T, int nDim> 01270 void IniConstTensorFunctional3D<T,nDim>::getTypeOfModification ( 01271 std::vector<modif::ModifT>& modified ) const 01272 { 01273 modified[0] = modif::staticVariables; 01274 } 01275 01276 01277 /* ************** Class MaskedIniConstTensorFunctional3D ******************* */ 01278 01279 template<typename T, int nDim> 01280 MaskedIniConstTensorFunctional3D<T,nDim>::MaskedIniConstTensorFunctional3D ( 01281 int flag_, Array<T,nDim> const& value_ ) 01282 : flag(flag_), 01283 value(value_) 01284 { } 01285 01286 template<typename T, int nDim> 01287 void MaskedIniConstTensorFunctional3D<T,nDim>::process ( 01288 Box3D domain, 01289 ScalarField3D<int>& mask, TensorField3D<T,nDim>& field ) 01290 { 01291 Dot3D offset = computeRelativeDisplacement(mask, field); 01292 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01293 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01294 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01295 if (mask.get(iX,iY,iZ)==flag) { 01296 field.get(iX+offset.x,iY+offset.y,iZ+offset.z) = value; 01297 } 01298 } 01299 } 01300 } 01301 } 01302 01303 template<typename T, int nDim> 01304 MaskedIniConstTensorFunctional3D<T,nDim>* MaskedIniConstTensorFunctional3D<T,nDim>::clone() const { 01305 return new MaskedIniConstTensorFunctional3D<T,nDim>(*this); 01306 } 01307 01308 template<typename T, int nDim> 01309 BlockDomain::DomainT MaskedIniConstTensorFunctional3D<T,nDim>::appliesTo() const { 01310 // Include boundary right away, to avoid need for envelope update. 01311 return BlockDomain::bulkAndEnvelope; 01312 } 01313 01314 template<typename T, int nDim> 01315 void MaskedIniConstTensorFunctional3D<T,nDim>::getTypeOfModification ( 01316 std::vector<modif::ModifT>& modified ) const 01317 { 01318 modified[0] = modif::nothing; // Mask. 01319 modified[1] = modif::staticVariables; // Tensor-Field. 01320 } 01321 01322 01323 /* ************** Class SetToCoordinateFunctional3D ****************** */ 01324 01325 template<typename T> 01326 SetToCoordinateFunctional3D<T>::SetToCoordinateFunctional3D(plint index_) 01327 : index(index_) 01328 { 01329 PLB_ASSERT( index >= 0 && index <=2 ); 01330 } 01331 01332 template<typename T> 01333 void SetToCoordinateFunctional3D<T>::process(Box3D domain, ScalarField3D<T>& field) { 01334 Dot3D relativeOffset = field.getLocation(); 01335 Array<plint,3> ofs(relativeOffset.x, relativeOffset.y, relativeOffset.z); 01336 Array<plint,3> pos; 01337 for ( pos[0]=domain.x0; pos[0]<=domain.x1; ++pos[0] ) { 01338 for ( pos[1]=domain.y0; pos[1]<=domain.y1; ++pos[1] ) { 01339 for ( pos[2]=domain.z0; pos[2]<=domain.z1; ++pos[2] ) { 01340 field.get(pos[0],pos[1],pos[2]) = (T) (pos[index]+ofs[index]); 01341 } 01342 } 01343 } 01344 } 01345 01346 template<typename T> 01347 SetToCoordinateFunctional3D<T>* SetToCoordinateFunctional3D<T>::clone() const { 01348 return new SetToCoordinateFunctional3D<T>(*this); 01349 } 01350 01351 template<typename T> 01352 BlockDomain::DomainT SetToCoordinateFunctional3D<T>::appliesTo() const { 01353 // Boundary cannot be included, because periodic boundaries 01354 // would get the wrong value. 01355 return BlockDomain::bulk; 01356 } 01357 01358 template<typename T> 01359 void SetToCoordinateFunctional3D<T>::getTypeOfModification ( 01360 std::vector<modif::ModifT>& modified ) const 01361 { 01362 modified[0] = modif::staticVariables; 01363 } 01364 01365 01366 /* ************** Class SetToCoordinatesFunctional3D ***************** */ 01367 01368 template<typename T> 01369 SetToCoordinatesFunctional3D<T>::SetToCoordinatesFunctional3D() 01370 { } 01371 01372 template<typename T> 01373 void SetToCoordinatesFunctional3D<T>::process(Box3D domain, TensorField3D<T,3>& field) { 01374 Dot3D relativeOffset = field.getLocation(); 01375 Array<plint,3> ofs(relativeOffset.x, relativeOffset.y, relativeOffset.z); 01376 Array<plint,3> pos; 01377 for ( pos[0]=domain.x0; pos[0]<=domain.x1; ++pos[0] ) { 01378 for ( pos[1]=domain.y0; pos[1]<=domain.y1; ++pos[1] ) { 01379 for ( pos[2]=domain.z0; pos[2]<=domain.z1; ++pos[2] ) { 01380 Array<T,3>& cell = field.get(pos[0], pos[1], pos[2]); 01381 cell[0] = (T) (pos[0]+ofs[0]); 01382 cell[1] = (T) (pos[1]+ofs[1]); 01383 cell[2] = (T) (pos[2]+ofs[2]); 01384 } 01385 } 01386 } 01387 } 01388 01389 template<typename T> 01390 SetToCoordinatesFunctional3D<T>* SetToCoordinatesFunctional3D<T>::clone() const { 01391 return new SetToCoordinatesFunctional3D<T>(*this); 01392 } 01393 01394 template<typename T> 01395 BlockDomain::DomainT SetToCoordinatesFunctional3D<T>::appliesTo() const { 01396 // Boundary cannot be included, because periodic boundaries 01397 // would get the wrong value. 01398 return BlockDomain::bulk; 01399 } 01400 01401 template<typename T> 01402 void SetToCoordinatesFunctional3D<T>::getTypeOfModification ( 01403 std::vector<modif::ModifT>& modified ) const 01404 { 01405 modified[0] = modif::staticVariables; 01406 } 01407 01408 /* ************** Class SetTensorComponentFunctional3D ***************** */ 01409 01410 template<typename T, int nDim> 01411 SetTensorComponentFunctional3D<T,nDim>::SetTensorComponentFunctional3D(int whichDim_) 01412 : whichDim(whichDim_) 01413 { } 01414 01415 template<typename T, int nDim> 01416 void SetTensorComponentFunctional3D<T,nDim>::process ( 01417 Box3D domain, ScalarField3D<T>& scalarField, 01418 TensorField3D<T,nDim>& tensorField ) 01419 { 01420 Dot3D offset = computeRelativeDisplacement(scalarField, tensorField); 01421 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 01422 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 01423 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 01424 tensorField.get(iX+offset.x, iY+offset.y, iZ+offset.z)[whichDim] = 01425 scalarField.get(iX,iY,iZ); 01426 } 01427 } 01428 } 01429 } 01430 01431 template<typename T, int nDim> 01432 SetTensorComponentFunctional3D<T,nDim>* SetTensorComponentFunctional3D<T,nDim>::clone() const { 01433 return new SetTensorComponentFunctional3D<T,nDim>(*this); 01434 } 01435 01436 template<typename T, int nDim> 01437 BlockDomain::DomainT SetTensorComponentFunctional3D<T,nDim>::appliesTo() const { 01438 // Boundary cannot be included, because periodic boundaries 01439 // would get the wrong value. 01440 return BlockDomain::bulk; 01441 } 01442 01443 template<typename T, int nDim> 01444 void SetTensorComponentFunctional3D<T,nDim>::getTypeOfModification ( 01445 std::vector<modif::ModifT>& modified ) const 01446 { 01447 modified[0] = modif::nothing; 01448 modified[1] = modif::staticVariables; 01449 } 01450 } // namespace plb 01451 01452 #endif // DATA_INITIALIZER_FUNCTIONAL_3D_HH 01453
1.6.3
1.6.3