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

dataInitializerFunctional3D.hh

Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00028 #ifndef 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