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

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