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

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