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

multiDataField2D.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 
00029 #ifndef MULTI_DATA_FIELD_2D_HH
00030 #define MULTI_DATA_FIELD_2D_HH
00031 
00032 #include "multiBlock/multiDataField2D.h"
00033 #include "multiBlock/multiBlockManagement2D.h"
00034 #include "multiBlock/defaultMultiBlockPolicy2D.h"
00035 #include "multiBlock/nonLocalTransfer2D.h"
00036 #include "multiBlock/multiBlockGenerator2D.h"
00037 #include "core/plbTypenames.h"
00038 #include "core/multiBlockIdentifiers2D.h"
00039 #include <vector>
00040 #include <algorithm>
00041 #include <limits>
00042 #include <sstream>
00043 
00044 namespace plb {
00045 
00047 
00048 template<typename T>
00049 const int MultiScalarField2D<T>::staticId =
00050 meta::registerMultiBlock2D ( MultiScalarField2D<T>::basicType(),
00051                              "NA",
00052                              MultiScalarField2D<T>::blockName(),
00053                              defaultGenerateMultiScalarField2D<T> );
00054 
00055 template<typename T>
00056 MultiScalarField2D<T>::MultiScalarField2D (
00057         MultiBlockManagement2D const& multiBlockManagement_,
00058         BlockCommunicator2D* blockCommunicator_,
00059         CombinedStatistics* combinedStatistics_,
00060         MultiScalarAccess2D<T>* multiScalarAccess_,
00061         T iniVal )
00062     : MultiBlock2D(multiBlockManagement_, blockCommunicator_, combinedStatistics_ ),
00063       multiScalarAccess(multiScalarAccess_)
00064 {
00065     allocateFields(iniVal);
00066 }
00067 
00068 template<typename T>
00069 MultiScalarField2D<T>::MultiScalarField2D(plint nx, plint ny, T iniVal)
00070       // Envelope-width defaults to 1.
00071     : MultiBlock2D(nx,ny,1),
00072       multiScalarAccess(defaultMultiBlockPolicy2D().getMultiScalarAccess<T>())
00073 {
00074     allocateFields(iniVal);
00075 }
00076 
00077 template<typename T>
00078 MultiScalarField2D<T>::~MultiScalarField2D() {
00079     deAllocateFields();
00080     delete multiScalarAccess;
00081 }
00082 
00083 template<typename T>
00084 MultiScalarField2D<T>::MultiScalarField2D(MultiScalarField2D<T> const& rhs)
00085     : ScalarFieldBase2D<T>(rhs),
00086       MultiBlock2D(rhs),
00087       multiScalarAccess(rhs.multiScalarAccess->clone())
00088 {
00089     allocateFields();
00090     typename BlockMap::iterator it = fields.begin();
00091     typename BlockMap::const_iterator rhsIt = rhs.fields.begin();
00092 
00093     for (; it != fields.end(); ++it, ++rhsIt) {
00094         *(it->second) = *(rhsIt->second);
00095     }
00096 }
00097 
00098 template<typename T>
00099 MultiScalarField2D<T>::MultiScalarField2D(MultiBlock2D const& rhs)
00100       // Use MultiBlock's sub-domain constructor to avoid that the data-processors are copied
00101     : MultiBlock2D(rhs, rhs.getBoundingBox(), false),
00102       multiScalarAccess(defaultMultiBlockPolicy2D().getMultiScalarAccess<T>())
00103 {
00104     allocateFields();
00105 }
00106 
00107 template<typename T>
00108 MultiScalarField2D<T>::MultiScalarField2D(MultiBlock2D const& rhs, Box2D subDomain, bool crop)
00109     : MultiBlock2D(rhs, subDomain, crop),
00110       multiScalarAccess(defaultMultiBlockPolicy2D().getMultiScalarAccess<T>())
00111 {
00112     allocateFields();
00113 }
00114 
00115 template<typename T>
00116 MultiScalarField2D<T>& MultiScalarField2D<T>::operator=(MultiScalarField2D<T> const& rhs) {
00117     MultiScalarField2D<T> tmp(rhs);
00118     swap(tmp);
00119     return *this;
00120 }
00121 
00122 template<typename T>
00123 MultiScalarField2D<T>* MultiScalarField2D<T>::clone() const {
00124     return new MultiScalarField2D<T>(*this);
00125 }
00126 
00127 template<typename T>
00128 MultiScalarField2D<T>* MultiScalarField2D<T>::clone(MultiBlockManagement2D const& newManagement) const
00129 {
00130     MultiScalarField2D<T>* newField = new MultiScalarField2D<T> (
00131         newManagement,
00132         this->getBlockCommunicator().clone(),
00133         this->getCombinedStatistics().clone(),
00134         multiScalarAccess->clone(), T() );
00135     copy(*this, this->getBoundingBox(), *newField, newField->getBoundingBox());
00136     return newField;
00137 }
00138 
00139 template<typename T>
00140 void MultiScalarField2D<T>::swap(MultiScalarField2D<T>& rhs) {
00141     MultiBlock2D::swap(rhs);
00142     fields.swap(rhs.fields);
00143     std::swap(multiScalarAccess, rhs.multiScalarAccess);
00144 }
00145 
00146 template<typename T>
00147 void MultiScalarField2D<T>::reset() {
00148     for ( typename BlockMap::iterator it = fields.begin();
00149           it != fields.end(); ++it)
00150     {
00151         it->second->reset();
00152     }
00153 }
00154 
00155 template<typename T>
00156 void MultiScalarField2D<T>::allocateFields(T iniVal) 
00157 {
00158     for (pluint iBlock=0; iBlock<this->getLocalInfo().getBlocks().size(); ++iBlock) {
00159         plint blockId = this->getLocalInfo().getBlocks()[iBlock];
00160         SmartBulk2D bulk(this->getMultiBlockManagement(), blockId);
00161         Box2D envelope = bulk.computeEnvelope();
00162         ScalarField2D<T>* newField =
00163             new ScalarField2D<T> (
00164                     envelope.getNx(), envelope.getNy(), iniVal );
00165         newField -> setLocation(Dot2D(envelope.x0, envelope.y0));
00166         fields[blockId] = newField;
00167     }
00168 }
00169 
00170 template<typename T>
00171 void MultiScalarField2D<T>::deAllocateFields() 
00172 {
00173     for ( typename BlockMap::iterator it = fields.begin();
00174           it != fields.end(); ++it)
00175     {
00176         delete it->second;
00177     }
00178 }
00179 
00180 template<typename T>
00181 inline T& MultiScalarField2D<T>::get(plint iX, plint iY) {
00182     PLB_PRECONDITION(iX>=0 && iX<this->getNx());
00183     PLB_PRECONDITION(iY>=0 && iY<this->getNy());
00184     return multiScalarAccess->getDistributedScalar(iX,iY, this->getMultiBlockManagement(), fields);
00185 }
00186 
00187 template<typename T>
00188 inline T const& MultiScalarField2D<T>::get(plint iX, plint iY) const {
00189     PLB_PRECONDITION(iX>=0 && iX<this->getNx());
00190     PLB_PRECONDITION(iY>=0 && iY<this->getNy());
00191     return multiScalarAccess->getDistributedScalar(iX,iY, this->getMultiBlockManagement(), fields);
00192 }
00193 
00194 template<typename T>
00195 ScalarField2D<T>& MultiScalarField2D<T>::getComponent(plint blockId) {
00196     typename BlockMap::iterator it = fields.find(blockId);
00197     PLB_ASSERT (it != fields.end());
00198     return *it->second;
00199 }
00200 
00201 template<typename T>
00202 ScalarField2D<T> const& MultiScalarField2D<T>::getComponent(plint blockId) const {
00203     typename BlockMap::const_iterator it = fields.find(blockId);
00204     PLB_ASSERT (it != fields.end());
00205     return *it->second;
00206 }
00207 
00208 template<typename T>
00209 plint MultiScalarField2D<T>::sizeOfCell() const {
00210     return sizeof(T);
00211 }
00212 
00213 template<typename T>
00214 plint MultiScalarField2D<T>::getCellDim() const {
00215     return 1;
00216 }
00217 
00218 template<typename T>
00219 int MultiScalarField2D<T>::getStaticId() const {
00220     return staticId;
00221 }
00222 
00223 template<typename T>
00224 void MultiScalarField2D<T>::copyReceive (
00225                 MultiBlock2D const& fromBlock, Box2D const& fromDomain,
00226                 Box2D const& toDomain, modif::ModifT whichData )
00227 {
00228     MultiScalarField2D<T> const* fromField =
00229         dynamic_cast<MultiScalarField2D<T> const* >(&fromBlock);
00230     PLB_ASSERT( fromField );
00231     copy(*fromField, fromDomain, *this, toDomain);
00232 }
00233 
00234 template<typename T>
00235 std::string MultiScalarField2D<T>::getBlockName() const {
00236     return blockName();
00237 }
00238 
00239 template<typename T>
00240 std::vector<std::string> MultiScalarField2D<T>::getTypeInfo() const {
00241     std::vector<std::string> info;
00242     info.push_back(basicType());
00243     return info;
00244 }
00245 
00246 template<typename T>
00247 std::string MultiScalarField2D<T>::blockName() {
00248     return std::string("ScalarField2D");
00249 }
00250 
00251 template<typename T>
00252 std::string MultiScalarField2D<T>::basicType() {
00253     return NativeType<T>::getName();
00254 }
00255 
00256 
00258 
00259 template<typename T, int nDim>
00260 const int MultiTensorField2D<T,nDim>::staticId =
00261 meta::registerMultiBlock2D ( MultiTensorField2D<T,nDim>::basicType(),
00262                              "NA",
00263                              MultiTensorField2D<T,nDim>::blockName(),
00264                              defaultGenerateMultiTensorField2D<T,nDim> );
00265 
00266 template<typename T, int nDim>
00267 MultiTensorField2D<T,nDim>::MultiTensorField2D (
00268         MultiBlockManagement2D const& multiBlockManagement_,
00269         BlockCommunicator2D* blockCommunicator_,
00270         CombinedStatistics* combinedStatistics_,
00271         MultiTensorAccess2D<T,nDim>* multiTensorAccess_ )
00272     : MultiBlock2D(multiBlockManagement_, blockCommunicator_, combinedStatistics_ ),
00273       multiTensorAccess(multiTensorAccess_)
00274 {
00275     allocateFields();
00276 }
00277 
00278 template<typename T, int nDim>
00279 MultiTensorField2D<T,nDim>::MultiTensorField2D (
00280         MultiBlockManagement2D const& multiBlockManagement_,
00281         BlockCommunicator2D* blockCommunicator_,
00282         CombinedStatistics* combinedStatistics_,
00283         MultiTensorAccess2D<T,nDim>* multiTensorAccess_,
00284         Array<T,nDim> const& iniVal )
00285     : MultiBlock2D(multiBlockManagement_, blockCommunicator_, combinedStatistics_ ),
00286       multiTensorAccess(multiTensorAccess_)
00287 {
00288     allocateFields(iniVal);
00289 }
00290 
00291 template<typename T, int nDim>
00292 MultiTensorField2D<T,nDim>::MultiTensorField2D(plint nx, plint ny)
00293       // Envelope-width defaults to 1.
00294     : MultiBlock2D(nx,ny,1),
00295       multiTensorAccess(defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>())
00296 {
00297     allocateFields();
00298 }
00299 
00300 template<typename T, int nDim>
00301 MultiTensorField2D<T,nDim>::MultiTensorField2D( plint nx, plint ny,
00302                                                 Array<T,nDim> const& iniVal )
00303       // Envelope-width defaults to 1.
00304     : MultiBlock2D(nx,ny,1),
00305       multiTensorAccess(defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>())
00306 {
00307     allocateFields(iniVal);
00308 }
00309 
00310 template<typename T, int nDim>
00311 MultiTensorField2D<T,nDim>::~MultiTensorField2D() {
00312     deAllocateFields();
00313     delete multiTensorAccess;
00314 }
00315 
00316 template<typename T, int nDim>
00317 MultiTensorField2D<T,nDim>::MultiTensorField2D(MultiTensorField2D<T,nDim> const& rhs)
00318     : TensorFieldBase2D<T,nDim>(rhs),
00319       MultiBlock2D(rhs),
00320       multiTensorAccess(rhs.multiTensorAccess->clone())
00321 {
00322     allocateFields();
00323     typename BlockMap::iterator it = fields.begin();
00324     typename BlockMap::const_iterator rhsIt = rhs.fields.begin();
00325 
00326     for (; it != fields.end(); ++it, ++rhsIt) {
00327         *(it->second) = *(rhsIt->second);
00328     }
00329 }
00330 
00331 template<typename T, int nDim>
00332 MultiTensorField2D<T,nDim>::MultiTensorField2D(MultiBlock2D const& rhs)
00333       // Use MultiBlock's sub-domain constructor to avoid that the data-processors are copied
00334     : MultiBlock2D(rhs, rhs.getBoundingBox(), false),
00335       multiTensorAccess(defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>())
00336 {
00337     allocateFields();
00338 }
00339 
00340 template<typename T, int nDim>
00341 MultiTensorField2D<T,nDim>::MultiTensorField2D(MultiBlock2D const& rhs, Box2D subDomain, bool crop)
00342     : MultiBlock2D(rhs, subDomain, crop),
00343       multiTensorAccess(defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>())
00344 {
00345     allocateFields();
00346 }
00347 
00348 template<typename T, int nDim>
00349 MultiTensorField2D<T,nDim>& MultiTensorField2D<T,nDim>::operator=(MultiTensorField2D<T,nDim> const& rhs) {
00350     MultiTensorField2D<T,nDim> tmp(rhs);
00351     swap(tmp);
00352     return *this;
00353 }
00354 
00355 template<typename T, int nDim>
00356 MultiTensorField2D<T,nDim>* MultiTensorField2D<T,nDim>::clone() const {
00357     return new MultiTensorField2D<T,nDim>(*this);
00358 }
00359 
00360 template<typename T, int nDim>
00361 MultiTensorField2D<T,nDim>* MultiTensorField2D<T,nDim>::clone(MultiBlockManagement2D const& newManagement) const
00362 {
00363     Array<T,nDim> iniVal; iniVal.resetToZero();
00364     MultiTensorField2D<T,nDim>* newField = new MultiTensorField2D<T,nDim> (
00365         newManagement,
00366         this->getBlockCommunicator().clone(),
00367         this->getCombinedStatistics().clone(),
00368         multiTensorAccess->clone(), iniVal );
00369     copy(*this, this->getBoundingBox(), *newField, newField->getBoundingBox());
00370     return newField;
00371 }
00372 
00373 template<typename T, int nDim>
00374 void MultiTensorField2D<T,nDim>::swap(MultiTensorField2D<T,nDim>& rhs) {
00375     MultiBlock2D::swap(rhs);
00376     fields.swap(rhs.fields);
00377     std::swap(multiTensorAccess, rhs.multiTensorAccess);
00378 }
00379 
00380 template<typename T, int nDim>
00381 void MultiTensorField2D<T,nDim>::reset() {
00382     for ( typename BlockMap::iterator it = fields.begin();
00383           it != fields.end(); ++it)
00384     {
00385         it->second -> reset();
00386     }
00387 }
00388 
00389 template<typename T, int nDim>
00390 void MultiTensorField2D<T,nDim>::allocateFields() 
00391 {
00392     Array<T,nDim> iniVal;
00393     iniVal.resetToZero();
00394     allocateFields(iniVal);
00395 }
00396 
00397 template<typename T, int nDim>
00398 void MultiTensorField2D<T,nDim>::allocateFields(Array<T,nDim> const& iniVal) 
00399 {
00400     for (pluint iBlock=0; iBlock<this->getLocalInfo().getBlocks().size(); ++iBlock) {
00401         plint blockId = this->getLocalInfo().getBlocks()[iBlock];
00402         SmartBulk2D bulk(this->getMultiBlockManagement(), blockId);
00403         Box2D envelope = bulk.computeEnvelope();
00404         TensorField2D<T,nDim>* newField =
00405             new TensorField2D<T,nDim> (
00406                     envelope.getNx(), envelope.getNy(), iniVal );
00407         newField -> setLocation(Dot2D(envelope.x0, envelope.y0));
00408         fields[blockId] = newField;
00409     }
00410 }
00411 
00412 template<typename T, int nDim>
00413 void MultiTensorField2D<T,nDim>::deAllocateFields() 
00414 {
00415     for ( typename BlockMap::iterator it = fields.begin();
00416           it != fields.end(); ++it)
00417     {
00418         delete it->second;
00419     }
00420 }
00421 
00422 template<typename T, int nDim>
00423 inline Array<T,nDim>& 
00424 MultiTensorField2D<T,nDim>::get(plint iX, plint iY) {
00425     PLB_PRECONDITION(iX>=0 && iX<this->getNx());
00426     PLB_PRECONDITION(iY>=0 && iY<this->getNy());
00427     return multiTensorAccess->getDistributedTensor(iX,iY, this->getMultiBlockManagement(), fields);
00428 }
00429 
00430 template<typename T, int nDim>
00431 inline Array<T,nDim> const& 
00432 MultiTensorField2D<T,nDim>::get(plint iX, plint iY) const {
00433     PLB_PRECONDITION(iX>=0 && iX<this->getNx());
00434     PLB_PRECONDITION(iY>=0 && iY<this->getNy());
00435     return multiTensorAccess->getDistributedTensor(iX,iY, this->getMultiBlockManagement(), fields);
00436 }
00437 
00438 template<typename T, int nDim>
00439 TensorField2D<T,nDim>& MultiTensorField2D<T,nDim>::getComponent(plint blockId) {
00440     typename BlockMap::iterator it = fields.find(blockId);
00441     PLB_ASSERT (it != fields.end());
00442     return *it->second;
00443 }
00444 
00445 template<typename T, int nDim>
00446 TensorField2D<T,nDim> const& MultiTensorField2D<T,nDim>::getComponent(plint blockId) const {
00447     typename BlockMap::const_iterator it = fields.find(blockId);
00448     PLB_ASSERT (it != fields.end());
00449     return *it->second;
00450 }
00451 
00452 template<typename T, int nDim>
00453 plint MultiTensorField2D<T,nDim>::sizeOfCell() const {
00454     return nDim*sizeof(T);
00455 }
00456 
00457 template<typename T, int nDim>
00458 plint MultiTensorField2D<T,nDim>::getCellDim() const {
00459     return nDim;
00460 }
00461 
00462 template<typename T, int nDim>
00463 int MultiTensorField2D<T,nDim>::getStaticId() const {
00464     return staticId;
00465 }
00466 
00467 template<typename T, int nDim>
00468 void MultiTensorField2D<T,nDim>::copyReceive (
00469                 MultiBlock2D const& fromBlock, Box2D const& fromDomain,
00470                 Box2D const& toDomain, modif::ModifT whichData )
00471 {
00472     MultiTensorField2D<T,nDim> const* fromField =
00473         dynamic_cast<MultiTensorField2D<T,nDim> const* >(&fromBlock);
00474     PLB_ASSERT( fromField );
00475     copy(*fromField, fromDomain, *this, toDomain);
00476 }
00477 
00478 template<typename T, int nDim>
00479 std::string MultiTensorField2D<T,nDim>::getBlockName() const {
00480     return blockName();
00481 }
00482 
00483 template<typename T, int nDim>
00484 std::vector<std::string> MultiTensorField2D<T,nDim>::getTypeInfo() const {
00485     std::vector<std::string> info;
00486     info.push_back(basicType());
00487     return info;
00488 }
00489 
00490 template<typename T, int nDim>
00491 std::string MultiTensorField2D<T,nDim>::blockName() {
00492     return std::string("TensorField2D");
00493 }
00494 
00495 template<typename T, int nDim>
00496 std::string MultiTensorField2D<T,nDim>::basicType() {
00497     return NativeType<T>::getName();
00498 }
00499 
00500 
00502 
00503 template<typename T>
00504 const int MultiNTensorField2D<T>::staticId =
00505 meta::registerMultiBlock2D ( MultiNTensorField2D<T>::basicType(),
00506                              "NA",
00507                              MultiNTensorField2D<T>::blockName(),
00508                              defaultGenerateMultiNTensorField2D<T> );
00509 
00510 template<typename T>
00511 MultiNTensorField2D<T>::MultiNTensorField2D (
00512         plint ndim,
00513         MultiBlockManagement2D const& multiBlockManagement_,
00514         BlockCommunicator2D* blockCommunicator_,
00515         CombinedStatistics* combinedStatistics_,
00516         MultiNTensorAccess2D<T>* multiNTensorAccess_ )
00517     : NTensorFieldBase2D<T>(ndim),
00518       MultiBlock2D(multiBlockManagement_, blockCommunicator_, combinedStatistics_ ),
00519       multiNTensorAccess(multiNTensorAccess_)
00520 {
00521     allocateFields();
00522 }
00523 
00524 template<typename T>
00525 MultiNTensorField2D<T>::MultiNTensorField2D (
00526         plint ndim, T const* iniVal,
00527         MultiBlockManagement2D const& multiBlockManagement_,
00528         BlockCommunicator2D* blockCommunicator_,
00529         CombinedStatistics* combinedStatistics_,
00530         MultiNTensorAccess2D<T>* multiNTensorAccess_ )
00531     : NTensorFieldBase2D<T>(ndim),
00532       MultiBlock2D(multiBlockManagement_, blockCommunicator_, combinedStatistics_ ),
00533       multiNTensorAccess(multiNTensorAccess_)
00534 {
00535     allocateFields(iniVal);
00536 }
00537 
00538 template<typename T>
00539 MultiNTensorField2D<T>::MultiNTensorField2D(plint nx, plint ny, plint ndim)
00540     : NTensorFieldBase2D<T>(ndim),
00541       // Envelope-width defaults to 1.
00542       MultiBlock2D(nx,ny,1),
00543       multiNTensorAccess(defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>())
00544 {
00545     allocateFields();
00546 }
00547 
00548 template<typename T>
00549 MultiNTensorField2D<T>::MultiNTensorField2D(plint nx, plint ny, plint ndim, T const* iniVal)
00550     : NTensorFieldBase2D<T>(ndim),
00551       // Envelope-width defaults to 1.
00552       MultiBlock2D(nx,ny,1),
00553       multiNTensorAccess(defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>())
00554 {
00555     allocateFields(iniVal);
00556 }
00557 
00558 template<typename T>
00559 MultiNTensorField2D<T>::~MultiNTensorField2D() {
00560     deAllocateFields();
00561     delete multiNTensorAccess;
00562 }
00563 
00564 template<typename T>
00565 MultiNTensorField2D<T>::MultiNTensorField2D(MultiNTensorField2D<T> const& rhs)
00566     : NTensorFieldBase2D<T>(rhs),
00567       // Use MultiBlock's sub-domain constructor to avoid that the data-processors are copied
00568       MultiBlock2D(rhs, rhs.getBoundingBox(), false),
00569       multiNTensorAccess(rhs.multiNTensorAccess->clone())
00570 {
00571     allocateFields();
00572     typename BlockMap::iterator it = fields.begin();
00573     typename BlockMap::const_iterator rhsIt = rhs.fields.begin();
00574 
00575     for (; it != fields.end(); ++it, ++rhsIt) {
00576         *(it->second) = *(rhsIt->second);
00577     }
00578 }
00579 
00580 template<typename T>
00581 MultiNTensorField2D<T>::MultiNTensorField2D(plint ndim, MultiBlock2D const& rhs)
00582     : NTensorFieldBase2D<T>(ndim),
00583       MultiBlock2D(rhs),
00584       multiNTensorAccess(defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>())
00585 {
00586     allocateFields();
00587 }
00588 
00589 template<typename T>
00590 MultiNTensorField2D<T>::MultiNTensorField2D(plint ndim, MultiBlock2D const& rhs, Box2D subDomain, bool crop)
00591     : NTensorFieldBase2D<T>(ndim),
00592       MultiBlock2D(rhs, subDomain, crop),
00593       multiNTensorAccess(defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>())
00594 {
00595     allocateFields();
00596 }
00597 
00598 template<typename T>
00599 MultiNTensorField2D<T>& MultiNTensorField2D<T>::operator=(MultiNTensorField2D<T> const& rhs) {
00600     MultiNTensorField2D<T> tmp(rhs);
00601     swap(tmp);
00602     return *this;
00603 }
00604 
00605 template<typename T>
00606 MultiNTensorField2D<T>* MultiNTensorField2D<T>::clone() const {
00607     return new MultiNTensorField2D<T>(*this);
00608 }
00609 
00610 template<typename T>
00611 MultiNTensorField2D<T>* MultiNTensorField2D<T>::clone(MultiBlockManagement2D const& newManagement) const
00612 {
00613     MultiNTensorField2D<T>* newField = new MultiNTensorField2D<T> (
00614         this->getNdim(),
00615         newManagement,
00616         this->getBlockCommunicator().clone(),
00617         this->getCombinedStatistics().clone(),
00618         multiNTensorAccess->clone() );
00619     copy(*this, this->getBoundingBox(), *newField, newField->getBoundingBox());
00620     return newField;
00621 }
00622 
00623 template<typename T>
00624 void MultiNTensorField2D<T>::swap(MultiNTensorField2D<T>& rhs) {
00625     NTensorFieldBase2D<T>::swap(rhs);
00626     MultiBlock2D::swap(rhs);
00627     fields.swap(rhs.fields);
00628     std::swap(multiNTensorAccess, rhs.multiNTensorAccess);
00629 }
00630 
00631 template<typename T>
00632 void MultiNTensorField2D<T>::reset() {
00633     for ( typename BlockMap::iterator it = fields.begin();
00634           it != fields.end(); ++it)
00635     {
00636         it->second->reset();
00637     }
00638 }
00639 
00640 template<typename T>
00641 void MultiNTensorField2D<T>::allocateFields() {
00642     std::vector<T> iniVal(this->getNdim());
00643     std::fill(iniVal.begin(), iniVal.end(), T());
00644     allocateFields(&iniVal[0]);
00645 }
00646 
00647 template<typename T>
00648 void MultiNTensorField2D<T>::allocateFields(T const* iniVal) 
00649 {
00650     for (pluint iBlock=0; iBlock<this->getLocalInfo().getBlocks().size(); ++iBlock) {
00651         plint blockId = this->getLocalInfo().getBlocks()[iBlock];
00652         SmartBulk2D bulk(this->getMultiBlockManagement(), blockId );
00653         Box2D envelope = bulk.computeEnvelope();
00654         NTensorField2D<T>* newField =
00655             new NTensorField2D<T> (
00656                     envelope.getNx(), envelope.getNy(), this->getNdim(), iniVal );
00657         newField -> setLocation(Dot2D(envelope.x0, envelope.y0));
00658         fields[blockId] = newField;
00659     }
00660 }
00661 
00662 template<typename T>
00663 void MultiNTensorField2D<T>::deAllocateFields() 
00664 {
00665     for ( typename BlockMap::iterator it = fields.begin();
00666           it != fields.end(); ++it)
00667     {
00668         delete it->second;
00669     }
00670 }
00671 
00672 template<typename T>
00673 inline T*
00674 MultiNTensorField2D<T>::get(plint iX, plint iY) {
00675     PLB_PRECONDITION(iX>=0 && iX<this->getNx());
00676     PLB_PRECONDITION(iY>=0 && iY<this->getNy());
00677     return multiNTensorAccess->getDistributedNTensor(iX,iY, this->getMultiBlockManagement(), fields);
00678 }
00679 
00680 template<typename T>
00681 inline T const*
00682 MultiNTensorField2D<T>::get(plint iX, plint iY) const {
00683     PLB_PRECONDITION(iX>=0 && iX<this->getNx());
00684     PLB_PRECONDITION(iY>=0 && iY<this->getNy());
00685     return multiNTensorAccess->getDistributedNTensor(iX,iY, this->getMultiBlockManagement(), fields);
00686 }
00687 
00688 template<typename T>
00689 NTensorField2D<T>& MultiNTensorField2D<T>::getComponent(plint blockId) {
00690     typename BlockMap::iterator it = fields.find(blockId);
00691     PLB_ASSERT (it != fields.end());
00692     return *it->second;
00693 }
00694 
00695 template<typename T>
00696 NTensorField2D<T> const& MultiNTensorField2D<T>::getComponent(plint blockId) const {
00697     typename BlockMap::const_iterator it = fields.find(blockId);
00698     PLB_ASSERT (it != fields.end());
00699     return *it->second;
00700 }
00701 
00702 template<typename T>
00703 plint MultiNTensorField2D<T>::sizeOfCell() const {
00704     return this->getNdim()*sizeof(T);
00705 }
00706 
00707 template<typename T>
00708 plint MultiNTensorField2D<T>::getCellDim() const {
00709     return this->getNdim();
00710 }
00711 
00712 template<typename T>
00713 int MultiNTensorField2D<T>::getStaticId() const {
00714     return staticId;
00715 }
00716 
00717 template<typename T>
00718 void MultiNTensorField2D<T>::copyReceive (
00719                 MultiBlock2D const& fromBlock, Box2D const& fromDomain,
00720                 Box2D const& toDomain, modif::ModifT whichData )
00721 {
00722     MultiNTensorField2D<T> const* fromField =
00723         dynamic_cast<MultiNTensorField2D<T> const* >(&fromBlock);
00724     PLB_ASSERT( fromField );
00725     copy(*fromField, fromDomain, *this, toDomain);
00726 }
00727 
00728 template<typename T>
00729 std::string MultiNTensorField2D<T>::getBlockName() const {
00730     return blockName();
00731 }
00732 
00733 template<typename T>
00734 std::vector<std::string> MultiNTensorField2D<T>::getTypeInfo() const {
00735     std::vector<std::string> info;
00736     info.push_back(basicType());
00737     return info;
00738 }
00739 
00740 template<typename T>
00741 std::string MultiNTensorField2D<T>::blockName() {
00742     return std::string("NTensorField2D");
00743 }
00744 
00745 template<typename T>
00746 std::string MultiNTensorField2D<T>::basicType() {
00747     return NativeType<T>::getName();
00748 }
00749 
00750 }  // namespace plb
00751 
00752 #endif   // MULTI_DATA_FIELD_2D_HH