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

multiBlockGenerator2D.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_BLOCK_GENERATOR_2D_HH
00030 #define MULTI_BLOCK_GENERATOR_2D_HH
00031 
00032 #include "core/globalDefs.h"
00033 #include "multiBlock/sparseBlockStructure2D.h"
00034 #include "multiBlock/localMultiBlockInfo2D.h"
00035 #include "multiBlock/nonLocalTransfer2D.h"
00036 #include "multiBlock/defaultMultiBlockPolicy2D.h"
00037 #include "multiBlock/multiBlockOperations2D.h"
00038 #include "dataProcessors/dataAnalysisWrapper2D.h"
00039 #include "dataProcessors/ntensorAnalysisWrapper2D.h"
00040 
00041 namespace plb {
00042 
00043 inline void transferDataProcessors(MultiBlock2D const& from, MultiBlock2D& to)
00044 {
00045     std::vector<MultiBlock2D::ProcessorStorage2D>
00046         newProcessors(from.getStoredProcessors());
00047     // Redirect all references-to-self to the new self.
00048     id_t oldId = from.getId();
00049     id_t newId = to.getId();
00050     for (pluint iProcessor=0; iProcessor<newProcessors.size(); ++iProcessor) {
00051         newProcessors[iProcessor].replace(oldId, newId);
00052         DataProcessorGenerator2D* newGenerator = newProcessors[iProcessor].getGenerator().clone();
00053         if (newGenerator->extract(to.getBoundingBox())) {
00054             addInternalProcessor( *newGenerator,
00055                                   newProcessors[iProcessor].getMultiBlocks(),
00056                                   newProcessors[iProcessor].getLevel() );
00057         }
00058         delete newGenerator;
00059     }
00060 }
00061 
00062 /* *************** 1. MultiScalarField ************************************** */
00063 
00064 template<typename T>
00065 void transferScalarFieldLocal (
00066         MultiScalarField2D<T>& from, MultiScalarField2D<T>& to, Box2D const& domain )
00067 {
00068     // 1. Copy all data from the old to the new field.
00069     plb::copy(from, to, from.getBoundingBox());
00070     // 2. Reconstruct the data processors.
00071     transferDataProcessors(from, to);
00072 }
00073 
00074 template<typename T>
00075 void transferScalarFieldNonLocal (
00076         MultiScalarField2D<T> const& from, MultiScalarField2D<T>& to, Box2D const& domain )
00077 {
00078     // 1. Copy all data from the old to the new field. This includes dynamics
00079     //    objects which must be fully serialized and regenerated.
00080     copyNonLocal(from, to, domain);
00081     // 2. Reconstruct the data processors.
00082     transferDataProcessors(from, to);
00083 }
00084 
00085 template<typename T>
00086 std::auto_ptr<MultiScalarField2D<T> > generateMultiScalarField (
00087         Box2D boundingBox, plint envelopeWidth )
00088 {
00089     return std::auto_ptr<MultiScalarField2D<T> > (
00090         new MultiScalarField2D<T> (
00091             defaultMultiBlockPolicy2D().getMultiBlockManagement(boundingBox, envelopeWidth),
00092             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00093             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00094             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00095     );
00096 }
00097 
00098 template<typename T>
00099 std::auto_ptr<MultiScalarField2D<T> > generateMultiScalarField (
00100         Box2D boundingBox, T iniVal, plint envelopeWidth )
00101 {
00102     return std::auto_ptr<MultiScalarField2D<T> > (
00103         new MultiScalarField2D<T> (
00104             defaultMultiBlockPolicy2D().getMultiBlockManagement(boundingBox, envelopeWidth),
00105             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00106             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00107             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>(), iniVal )
00108     );
00109 }
00110 
00111 template<typename T>
00112 std::auto_ptr<MultiScalarField2D<T> > defaultGenerateMultiScalarField2D (
00113         MultiBlockManagement2D const& management, plint nDim )
00114 {
00115     return std::auto_ptr<MultiScalarField2D<T> > (
00116         new MultiScalarField2D<T> (
00117             management,
00118             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00119             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00120             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>(), T() )
00121     );
00122 }
00123 
00124 template<typename T>
00125 std::auto_ptr<MultiScalarField2D<T> > clone (
00126         MultiScalarField2D<T>& originalField,
00127         Box2D const& subDomain, bool crop )
00128 {
00129     std::auto_ptr<MultiScalarField2D<T> > clonedField (
00130             generateMultiScalarField<T>(originalField, subDomain, crop) );
00131 
00132     transferScalarFieldLocal( originalField, *clonedField,
00133                               originalField.getBoundingBox() );
00134 
00135     return clonedField;
00136 }
00137 
00138 template<typename T>
00139 std::auto_ptr<MultiScalarField2D<T> > generateMultiScalarField (
00140         MultiBlock2D const& originalField, Box2D const& intersection,
00141         bool crop )
00142 {
00143     return std::auto_ptr<MultiScalarField2D<T> > (
00144         new MultiScalarField2D<T> (
00145             intersect(originalField.getMultiBlockManagement(), intersection, crop),
00146             originalField.getBlockCommunicator().clone(),
00147             originalField.getCombinedStatistics().clone(),
00148             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00149     );
00150 }
00151 
00152 template<typename T>
00153 std::auto_ptr<MultiScalarField2D<T> > generateIntersectMultiScalarField (
00154         MultiBlock2D const& originalField1,
00155         MultiBlock2D const& originalField2, bool crop )
00156 {
00157     return std::auto_ptr<MultiScalarField2D<T> > (
00158         new MultiScalarField2D<T> (
00159             intersect(originalField1.getMultiBlockManagement(),
00160                       originalField2.getMultiBlockManagement(), crop),
00161             originalField1.getBlockCommunicator().clone(),
00162             originalField1.getCombinedStatistics().clone(),
00163             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00164     );
00165 }
00166 
00167 template<typename T>
00168 std::auto_ptr<MultiScalarField2D<T> > generateIntersectMultiScalarField (
00169         MultiBlock2D const& originalField1,
00170         MultiBlock2D const& originalField2,
00171         Box2D const& intersection, bool crop )
00172 {
00173     MultiBlockManagement2D intersectedBlocks (
00174             intersect ( originalField1.getMultiBlockManagement(),
00175                         originalField2.getMultiBlockManagement(), crop ) );
00176     MultiBlockManagement2D intersectWithDomain (
00177             intersect( intersectedBlocks, intersection, crop ) );
00178     return std::auto_ptr<MultiScalarField2D<T> > (
00179         new MultiScalarField2D<T> (
00180             intersectWithDomain,
00181             originalField1.getBlockCommunicator().clone(),
00182             originalField1.getCombinedStatistics().clone(),
00183             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00184     );
00185 }
00186 
00187 template<typename T>
00188 std::auto_ptr<MultiScalarField2D<T> > generateJoinMultiScalarField (
00189         MultiBlock2D const& originalField1,
00190         MultiBlock2D const& originalField2 )
00191 {
00192     return std::auto_ptr<MultiScalarField2D<T> > (
00193         new MultiScalarField2D<T> (
00194             block_union (
00195                 originalField1.getMultiBlockManagement(),
00196                 originalField2.getMultiBlockManagement() ),
00197             originalField1.getBlockCommunicator().clone(),
00198             originalField1.getCombinedStatistics().clone(),
00199             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00200     );
00201 }
00202 
00203 template<typename T>
00204 std::auto_ptr<MultiScalarField2D<T> > extend (
00205         MultiScalarField2D<T>& originalBlock, Box2D const& addedBlock )
00206 {
00207     std::auto_ptr<MultiScalarField2D<T> > newBlock (
00208         new MultiScalarField2D<T> (
00209             extend( originalBlock.getMultiBlockManagement(), addedBlock, addedBlock ),
00210             originalBlock.getBlockCommunicator().clone(),
00211             originalBlock.getCombinedStatistics().clone(),
00212             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00213     );
00214 
00215     transferScalarFieldLocal( originalBlock, *newBlock,
00216                               originalBlock.getBoundingBox() );
00217 
00218     return newBlock;
00219 }
00220 
00221 template<typename T>
00222 std::auto_ptr<MultiScalarField2D<T> > except (
00223         MultiScalarField2D<T>& originalBlock,
00224         Box2D const& exceptedBlock )
00225 {
00226     std::auto_ptr<MultiScalarField2D<T> > newBlock (
00227         new MultiScalarField2D<T> (
00228             except( originalBlock.getMultiBlockManagement(), exceptedBlock),
00229             originalBlock.getBlockCommunicator().clone(),
00230             originalBlock.getCombinedStatistics().clone(),
00231             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00232     );
00233 
00234     transferScalarFieldLocal( originalBlock, *newBlock,
00235                               originalBlock.getBoundingBox() );
00236 
00237     return newBlock;
00238 }
00239 
00240 
00241 template<typename T>
00242 std::auto_ptr<MultiScalarField2D<T> > redistribute (
00243         MultiScalarField2D<T> const& originalField,
00244         SparseBlockStructure2D const& newBlockStructure )
00245 {
00246     std::auto_ptr<MultiScalarField2D<T> > newField (
00247         new MultiScalarField2D<T> (
00248             MultiBlockManagement2D (
00249                 newBlockStructure,
00250                 originalField.getMultiBlockManagement().getThreadAttribution().clone(),
00251                 originalField.getMultiBlockManagement().getEnvelopeWidth() ),
00252             originalField.getBlockCommunicator().clone(),
00253             originalField.getCombinedStatistics().clone(),
00254             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00255     );
00256 
00257     transferScalarFieldNonLocal(originalField, *newField, originalField.getBoundingBox());
00258 
00259     return newField;
00260 }
00261 
00262 template<typename T>
00263 std::auto_ptr<MultiScalarField2D<T> > redistribute (
00264         MultiScalarField2D<T> const& originalField,
00265         SparseBlockStructure2D const& newBlockStructure,
00266         Box2D const& intersection, bool crop )
00267 {
00268     return redistribute(originalField, intersect(newBlockStructure, intersection, crop));
00269 }
00270 
00271 template<typename T>
00272 std::auto_ptr<MultiScalarField2D<T> > align (
00273         MultiScalarField2D<T> const& originalBlock,
00274         MultiBlock2D const& partnerBlock )
00275 {
00276     std::auto_ptr<MultiScalarField2D<T> > newBlock (
00277         new MultiScalarField2D<T> (
00278             align(originalBlock.getMultiBlockManagement(),
00279                   partnerBlock.getMultiBlockManagement()),
00280             originalBlock.getBlockCommunicator().clone(),
00281             originalBlock.getCombinedStatistics().clone(),
00282             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00283     );
00284 
00285     transferScalarFieldNonLocal( originalBlock, *newBlock,
00286                                  originalBlock.getBoundingBox() );
00287 
00288     return newBlock;
00289 }
00290 
00291 template<typename T>
00292 std::auto_ptr<MultiScalarField2D<T> > reparallelize (
00293         MultiScalarField2D<T> const& originalBlock )
00294 {
00295     return reparallelize(originalBlock, 64, 64);
00296 }
00297 
00298 template<typename T>
00299 std::auto_ptr<MultiScalarField2D<T> > reparallelize (
00300         MultiScalarField2D<T> const& originalBlock,
00301         plint blockLx, plint blockLy )
00302 {
00303     std::auto_ptr<MultiScalarField2D<T> > newBlock (
00304         new MultiScalarField2D<T> (
00305             reparallelize (
00306                 originalBlock.getMultiBlockManagement(), blockLx, blockLy ),
00307             originalBlock.getBlockCommunicator().clone(),
00308             originalBlock.getCombinedStatistics().clone(),
00309             defaultMultiBlockPolicy2D().getMultiScalarAccess<T>() )
00310     );
00311 
00312     transferScalarFieldNonLocal( originalBlock, *newBlock,
00313                                  originalBlock.getBoundingBox() );
00314 
00315     return newBlock;
00316 }
00317 
00318 
00319 /* *************** 2. MultiNTensorField ************************************** */
00320 
00321 template<typename T>
00322 std::auto_ptr<MultiNTensorField2D<T> > defaultGenerateMultiNTensorField2D (
00323         MultiBlockManagement2D const& management, plint nDim )
00324 {
00325     MultiNTensorField2D<T>* field = new MultiNTensorField2D<T> (
00326         nDim, management,
00327         defaultMultiBlockPolicy2D().getBlockCommunicator(),
00328         defaultMultiBlockPolicy2D().getCombinedStatistics(),
00329         defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00330     field->periodicity().toggleAll(true);
00331     return std::auto_ptr<MultiNTensorField2D<T> >(field);
00332 }
00333 
00334 template<typename T>
00335 MultiNTensorField2D<T>* generateMultiNTensorField2D(Box2D const& domain, plint ndim)
00336 {
00337     plint defaultEnvelopeWidth = 1;
00338     MultiNTensorField2D<T>* field = new MultiNTensorField2D<T> (
00339         ndim,
00340         defaultMultiBlockPolicy2D().getMultiBlockManagement(domain,defaultEnvelopeWidth),
00341         defaultMultiBlockPolicy2D().getBlockCommunicator(),
00342         defaultMultiBlockPolicy2D().getCombinedStatistics(),
00343         defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00344     field->periodicity().toggleAll(true);
00345     return field;
00346 }
00347 
00348 
00349 template<typename T>
00350 void transferNTensorFieldLocal (
00351         MultiNTensorField2D<T>& from, MultiNTensorField2D<T>& to, Box2D const& domain )
00352 {
00353     // 1. Copy all data from the old to the new field.
00354     plb::copy(from, to, from.getBoundingBox());
00355     // 2. Reconstruct the data processors.
00356     transferDataProcessors(from, to);
00357 }
00358 
00359 template<typename T>
00360 void transferNTensorFieldNonLocal (
00361         MultiNTensorField2D<T> const& from, MultiNTensorField2D<T>& to, Box2D const& domain )
00362 {
00363     // 1. Copy all data from the old to the new field. This includes dynamics
00364     //    objects which must be fully serialized and regenerated.
00365     copyNonLocal(from, to, domain);
00366     // 2. Reconstruct the data processors.
00367     transferDataProcessors(from, to);
00368 }
00369 
00370 template<typename T>
00371 MultiNTensorField2D<T>* clone (
00372         MultiNTensorField2D<T>& originalField,
00373         Box2D const& subDomain, bool crop )
00374 {
00375     MultiNTensorField2D<T>* clonedField =
00376             generateMultiNTensorField<T>(originalField, subDomain, crop);
00377     clonedField->periodicity()=originalField.periodicity();
00378 
00379     transferNTensorFieldLocal( originalField, *clonedField,
00380                                originalField.getBoundingBox() );
00381 
00382     return clonedField;
00383 }
00384 
00385 template<typename T>
00386 MultiNTensorField2D<T>* generateMultiNTensorField (
00387         MultiBlock2D const& originalField, Box2D const& intersection,
00388         plint nDim, bool crop )
00389 {
00390     MultiNTensorField2D<T>* newField = new MultiNTensorField2D<T> (
00391             nDim,
00392             intersect(originalField.getMultiBlockManagement(), intersection, crop),
00393             originalField.getBlockCommunicator().clone(),
00394             originalField.getCombinedStatistics().clone(),
00395             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00396     newField->periodicity() = originalField.periodicity();
00397     return newField;
00398 }
00399 
00400 template<typename T1, typename T2>
00401 MultiNTensorField2D<T2>*
00402     generateNTensorFieldFromNTensor2D (
00403             MultiNTensorField2D<T1> const& field,
00404             Box2D const& intersection, plint nDim )
00405 {
00406     MultiNTensorField2D<T2>* newField = generateMultiNTensorField<T2>(field, intersection, nDim);
00407     newField->periodicity() = field.periodicity();
00408     return newField;
00409 }
00410 
00411 template<typename T1, typename T2, template<typename U> class Descriptor>
00412 MultiNTensorField2D<T1>*
00413     generateNTensorFieldFromBlockLattice2D (
00414             MultiBlockLattice2D<T2,Descriptor> const& lattice,
00415             Box2D const& intersection, plint nDim )
00416 {
00417     MultiNTensorField2D<T1>* newField = generateMultiNTensorField<T1>(lattice, intersection, nDim);
00418     newField->periodicity() = lattice.periodicity();
00419     return newField;
00420 }
00421 
00422 
00423 template<typename T>
00424 MultiNTensorField2D<T>* generateIntersectMultiNTensorField (
00425         MultiBlock2D const& originalField1,
00426         MultiBlock2D const& originalField2, plint nDim, bool crop )
00427 {
00428     MultiNTensorField2D<T>* newField = new MultiNTensorField2D<T> (
00429             nDim,
00430             intersect(originalField1.getMultiBlockManagement(),
00431                       originalField2.getMultiBlockManagement(), crop),
00432             originalField1.getBlockCommunicator().clone(),
00433             originalField1.getCombinedStatistics().clone(),
00434             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00435     newField->periodicity() = originalField1.periodicity();
00436     return newField;
00437 }
00438 
00439 template<typename T>
00440 MultiNTensorField2D<T>* generateIntersectMultiNTensorField (
00441         MultiBlock2D const& originalField1,
00442         MultiBlock2D const& originalField2,
00443         Box2D const& intersection, plint nDim, bool crop )
00444 {
00445     MultiBlockManagement2D intersectedBlocks (
00446             intersect ( originalField1.getMultiBlockManagement(),
00447                         originalField2.getMultiBlockManagement(), crop ) );
00448     MultiBlockManagement2D intersectWithDomain (
00449             intersect( intersectedBlocks, intersection, crop ) );
00450     MultiNTensorField2D<T>* newField = new MultiNTensorField2D<T> (
00451             nDim,
00452             intersectWithDomain,
00453             originalField1.getBlockCommunicator().clone(),
00454             originalField1.getCombinedStatistics().clone(),
00455             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00456     newField->periodicity() = originalField1.periodicity();
00457     return newField;
00458 }
00459 
00460 template<typename T>
00461 MultiNTensorField2D<T>* generateJoinMultiNTensorField (
00462         MultiBlock2D const& originalField1,
00463         MultiBlock2D const& originalField2, plint nDim )
00464 {
00465     MultiNTensorField2D<T>* newField = new MultiNTensorField2D<T> (
00466             nDim,
00467             block_union (
00468                 originalField1.getMultiBlockManagement(),
00469                 originalField2.getMultiBlockManagement() ),
00470             originalField1.getBlockCommunicator().clone(),
00471             originalField1.getCombinedStatistics().clone(),
00472             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00473     newField->periodicity() = originalField1.periodicity();
00474     return newField;
00475 }
00476 
00477 template<typename T>
00478 MultiNTensorField2D<T>* extend (
00479         MultiNTensorField2D<T>& originalBlock, Box2D const& addedBlock )
00480 {
00481     MultiNTensorField2D<T>* newBlock =
00482         new MultiNTensorField2D<T> (
00483             originalBlock.getNdim(),
00484             extend( originalBlock.getMultiBlockManagement(), addedBlock, addedBlock ),
00485             originalBlock.getBlockCommunicator().clone(),
00486             originalBlock.getCombinedStatistics().clone(),
00487             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00488     newBlock->periodicity() = originalBlock.periodicity();
00489 
00490     transferNTensorFieldLocal( originalBlock, *newBlock,
00491                                originalBlock.getBoundingBox() );
00492 
00493     return newBlock;
00494 }
00495 
00496 template<typename T>
00497 MultiNTensorField2D<T>* except (
00498         MultiNTensorField2D<T>& originalBlock,
00499         Box2D const& exceptedBlock )
00500 {
00501     MultiNTensorField2D<T>* newBlock =
00502         new MultiNTensorField2D<T> (
00503             originalBlock.getNdim(),
00504             except( originalBlock.getMultiBlockManagement(), exceptedBlock),
00505             originalBlock.getBlockCommunicator().clone(),
00506             originalBlock.getCombinedStatistics().clone(),
00507             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00508     newBlock->periodicity() = originalBlock.periodicity();
00509 
00510     transferNTensorFieldLocal( originalBlock, *newBlock,
00511                                originalBlock.getBoundingBox() );
00512 
00513     return newBlock;
00514 }
00515 
00516 template<typename T>
00517 MultiNTensorField2D<T>* align (
00518         MultiNTensorField2D<T> const& originalBlock,
00519         MultiBlock2D const& partnerBlock )
00520 {
00521     MultiNTensorField2D<T>* newBlock =
00522         new MultiNTensorField2D<T> (
00523             originalBlock.getNdim(),
00524             align(originalBlock.getMultiBlockManagement(),
00525                   partnerBlock.getMultiBlockManagement()),
00526             originalBlock.getBlockCommunicator().clone(),
00527             originalBlock.getCombinedStatistics().clone(),
00528             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00529     newBlock->periodicity() = originalBlock.periodicity();
00530 
00531     transferNTensorFieldNonLocal( originalBlock, *newBlock,
00532                                   originalBlock.getBoundingBox() );
00533 
00534     return newBlock;
00535 }
00536 
00537 template<typename T>
00538 MultiNTensorField2D<T>* reparallelize (
00539         MultiNTensorField2D<T> const& originalBlock )
00540 {
00541     MultiNTensorField2D<T>* newBlock =
00542         new MultiNTensorField2D<T> (
00543             originalBlock.getNdim(),
00544             reparallelize(originalBlock.getMultiBlockManagement(), 64,64),
00545             originalBlock.getBlockCommunicator().clone(),
00546             originalBlock.getCombinedStatistics().clone(),
00547             defaultMultiBlockPolicy2D().getMultiNTensorAccess<T>() );
00548     newBlock->periodicity() = originalBlock.periodicity();
00549 
00550     transferNTensorFieldNonLocal( originalBlock, *newBlock,
00551                                   originalBlock.getBoundingBox() );
00552 
00553     return newBlock;
00554 }
00555 
00556 /* *************** 3. MultiTensorField ************************************** */
00557 
00558 template<typename T, int nDim>
00559 void transferTensorFieldLocal (
00560         MultiTensorField2D<T,nDim>& from, MultiTensorField2D<T,nDim>& to, Box2D const& domain )
00561 {
00562     // 1. Copy all data from the old to the new field.
00563     plb::copy(from, to, from.getBoundingBox());
00564     // 2. Reconstruct the data processors.
00565     transferDataProcessors(from, to);
00566 }
00567 
00568 template<typename T, int nDim>
00569 void transferTensorFieldNonLocal (
00570         MultiTensorField2D<T,nDim> const& from, MultiTensorField2D<T,nDim>& to, Box2D const& domain )
00571 {
00572     // 1. Copy all data from the old to the new field. This includes dynamics
00573     //    objects which must be fully serialized and regenerated.
00574     copyNonLocal(from, to, domain);
00575     // 2. Reconstruct the data processors.
00576     transferDataProcessors(from, to);
00577 }
00578 
00579 template<typename T, int nDim>
00580 std::auto_ptr<MultiTensorField2D<T,nDim> > generateMultiTensorField (
00581         Box2D boundingBox, plint envelopeWidth )
00582 {
00583     return std::auto_ptr<MultiTensorField2D<T,nDim> > (
00584         new MultiTensorField2D<T,nDim> (
00585             defaultMultiBlockPolicy2D().getMultiBlockManagement(boundingBox, envelopeWidth),
00586             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00587             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00588             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00589     );
00590 }
00591 
00592 template<typename T, int nDim>
00593 std::auto_ptr<MultiTensorField2D<T,nDim> > generateMultiTensorField (
00594         Box2D boundingBox, Array<T,nDim> const& iniVal, plint envelopeWidth )
00595 {
00596     return std::auto_ptr<MultiTensorField2D<T,nDim> > (
00597         new MultiTensorField2D<T,nDim> (
00598             defaultMultiBlockPolicy2D().getMultiBlockManagement(boundingBox, envelopeWidth),
00599             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00600             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00601             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>(), iniVal )
00602     );
00603 }
00604 
00605 template<typename T, int nDim>
00606 std::auto_ptr<MultiTensorField2D<T,nDim> > defaultGenerateMultiTensorField2D (
00607         MultiBlockManagement2D const& management, plint nDimParam )
00608 {
00609     Array<T,nDim> iniVal;
00610     iniVal.resetToZero();
00611     return std::auto_ptr<MultiTensorField2D<T,nDim> > (
00612         new MultiTensorField2D<T,nDim> (
00613             management,
00614             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00615             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00616             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>(), iniVal )
00617     );
00618 }
00619 
00620 template<typename T, int nDim>
00621 std::auto_ptr<MultiTensorField2D<T,nDim> > clone (
00622         MultiTensorField2D<T,nDim>& originalField,
00623         Box2D const& subDomain, bool crop )
00624 {
00625     std::auto_ptr<MultiTensorField2D<T,nDim> > clonedField (
00626             generateMultiTensorField<T,nDim>(originalField, subDomain, crop) );
00627 
00628     transferTensorFieldLocal( originalField, *clonedField,
00629                               originalField.getBoundingBox() );
00630 
00631     return clonedField;
00632 }
00633 
00634 template<typename T, int nDim>
00635 std::auto_ptr<MultiTensorField2D<T,nDim> > generateMultiTensorField (
00636         MultiBlock2D const& originalField, Box2D const& intersection,
00637         bool crop )
00638 {
00639     return std::auto_ptr<MultiTensorField2D<T,nDim> > (
00640         new MultiTensorField2D<T,nDim> (
00641             intersect(originalField.getMultiBlockManagement(), intersection, crop),
00642             originalField.getBlockCommunicator().clone(),
00643             originalField.getCombinedStatistics().clone(),
00644             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00645     );
00646 }
00647 
00648 template<typename T, int nDim>
00649 std::auto_ptr<MultiTensorField2D<T,nDim> > generateIntersectMultiTensorField (
00650         MultiBlock2D const& originalField1,
00651         MultiBlock2D const& originalField2, bool crop )
00652 {
00653     return std::auto_ptr<MultiTensorField2D<T,nDim> > (
00654         new MultiTensorField2D<T,nDim> (
00655             intersect(originalField1.getMultiBlockManagement(),
00656                       originalField2.getMultiBlockManagement(), crop),
00657             originalField1.getBlockCommunicator().clone(),
00658             originalField1.getCombinedStatistics().clone(),
00659             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00660     );
00661 }
00662 
00663 template<typename T, int nDim>
00664 std::auto_ptr<MultiTensorField2D<T,nDim> > generateIntersectMultiTensorField (
00665         MultiBlock2D const& originalField1,
00666         MultiBlock2D const& originalField2,
00667         Box2D const& intersection, bool crop )
00668 {
00669     MultiBlockManagement2D intersectedBlocks (
00670             intersect ( originalField1.getMultiBlockManagement(),
00671                         originalField2.getMultiBlockManagement(), crop ) );
00672     MultiBlockManagement2D intersectWithDomain (
00673             intersect( intersectedBlocks, intersection, crop ) );
00674     return std::auto_ptr<MultiTensorField2D<T,nDim> > (
00675         new MultiTensorField2D<T,nDim> (
00676             intersectWithDomain,
00677             originalField1.getBlockCommunicator().clone(),
00678             originalField1.getCombinedStatistics().clone(),
00679             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00680     );
00681 }
00682 
00683 template<typename T, int nDim>
00684 std::auto_ptr<MultiTensorField2D<T,nDim> > generateJoinMultiTensorField (
00685         MultiBlock2D const& originalField1,
00686         MultiBlock2D const& originalField2 )
00687 {
00688     return std::auto_ptr<MultiTensorField2D<T,nDim> > (
00689         new MultiTensorField2D<T,nDim> (
00690             block_union (
00691                 originalField1.getMultiBlockManagement(),
00692                 originalField2.getMultiBlockManagement() ),
00693             originalField1.getBlockCommunicator().clone(),
00694             originalField1.getCombinedStatistics().clone(),
00695             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00696     );
00697 }
00698 
00699 template<typename T, int nDim>
00700 std::auto_ptr<MultiTensorField2D<T,nDim> > extend (
00701         MultiTensorField2D<T,nDim>& originalBlock, Box2D const& addedBlock )
00702 {
00703     std::auto_ptr<MultiTensorField2D<T,nDim> > newBlock (
00704         new MultiTensorField2D<T,nDim> (
00705             extend( originalBlock.getMultiBlockManagement(), addedBlock, addedBlock ),
00706             originalBlock.getBlockCommunicator().clone(),
00707             originalBlock.getCombinedStatistics().clone(),
00708             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00709     );
00710 
00711     transferTensorFieldLocal( originalBlock, *newBlock,
00712                               originalBlock.getBoundingBox() );
00713 
00714     return newBlock;
00715 }
00716 
00717 template<typename T, int nDim>
00718 std::auto_ptr<MultiTensorField2D<T,nDim> > except (
00719         MultiTensorField2D<T,nDim>& originalBlock,
00720         Box2D const& exceptedBlock )
00721 {
00722     std::auto_ptr<MultiTensorField2D<T,nDim> > newBlock (
00723         new MultiTensorField2D<T,nDim> (
00724             except( originalBlock.getMultiBlockManagement(), exceptedBlock),
00725             originalBlock.getBlockCommunicator().clone(),
00726             originalBlock.getCombinedStatistics().clone(),
00727             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00728     );
00729 
00730     transferTensorFieldLocal( originalBlock, *newBlock,
00731                               originalBlock.getBoundingBox() );
00732 
00733     return newBlock;
00734 }
00735 
00736 template<typename T, int nDim>
00737 std::auto_ptr<MultiTensorField2D<T,nDim> > redistribute (
00738         MultiTensorField2D<T,nDim> const& originalField,
00739         SparseBlockStructure2D const& newBlockStructure )
00740 {
00741     std::auto_ptr<MultiTensorField2D<T,nDim> > newField (
00742         new MultiTensorField2D<T,nDim> (
00743             MultiBlockManagement2D (
00744                 newBlockStructure,
00745                 originalField.getMultiBlockManagement().getThreadAttribution().clone(),
00746                 originalField.getMultiBlockManagement().getEnvelopeWidth() ),
00747             originalField.getBlockCommunicator().clone(),
00748             originalField.getCombinedStatistics().clone(),
00749             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00750     );
00751     transferTensorFieldNonLocal(originalField, *newField, originalField.getBoundingBox());
00752 
00753     return newField;
00754 }
00755 
00756 template<typename T, int nDim>
00757 std::auto_ptr<MultiTensorField2D<T,nDim> > redistribute (
00758         MultiTensorField2D<T,nDim> const& originalField,
00759         SparseBlockStructure2D const& newBlockStructure,
00760         Box2D const& intersection, bool crop  )
00761 {
00762     return redistribute(originalField, intersect(newBlockStructure, intersection, crop));
00763 }
00764 
00765 
00766 template<typename T, int nDim>
00767 std::auto_ptr<MultiTensorField2D<T,nDim> > align (
00768         MultiTensorField2D<T,nDim> const& originalBlock,
00769         MultiBlock2D const& partnerBlock )
00770 {
00771     std::auto_ptr<MultiTensorField2D<T,nDim> > newBlock (
00772         new MultiTensorField2D<T,nDim> (
00773             align(originalBlock.getMultiBlockManagement(),
00774                   partnerBlock.getMultiBlockManagement()),
00775             originalBlock.getBlockCommunicator().clone(),
00776             originalBlock.getCombinedStatistics().clone(),
00777             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00778     );
00779 
00780     transferTensorFieldNonLocal( originalBlock, *newBlock,
00781                                  originalBlock.getBoundingBox() );
00782 
00783     return newBlock;
00784 }
00785 
00786 template<typename T, int nDim>
00787 std::auto_ptr<MultiTensorField2D<T,nDim> > reparallelize (
00788         MultiTensorField2D<T,nDim> const& originalBlock )
00789 {
00790     return reparallelize(originalBlock, 64, 64);
00791 }
00792 
00793 template<typename T, int nDim>
00794 std::auto_ptr<MultiTensorField2D<T,nDim> > reparallelize (
00795         MultiTensorField2D<T,nDim> const& originalBlock,
00796         plint blockLx, plint blockLy )
00797 {
00798     std::auto_ptr<MultiTensorField2D<T,nDim> > newBlock (
00799         new MultiTensorField2D<T,nDim> (
00800             reparallelize (
00801                 originalBlock.getMultiBlockManagement(), blockLx, blockLy ),
00802             originalBlock.getBlockCommunicator().clone(),
00803             originalBlock.getCombinedStatistics().clone(),
00804             defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>() )
00805     );
00806 
00807     transferTensorFieldNonLocal( originalBlock, *newBlock,
00808                                  originalBlock.getBoundingBox() );
00809 
00810     return newBlock;
00811 }
00812 
00813 
00814 /* *************** 4. MultiBlockLattice ************************************** */
00815 
00816 template<typename T, template<typename U> class Descriptor>
00817 void transferBlockLatticeLocal (
00818         MultiBlockLattice2D<T,Descriptor>& from,
00819         MultiBlockLattice2D<T,Descriptor>& to, Box2D const& domain )
00820 {
00821     // 1. Copy static and dynamic data to the new block.
00822     copyRegenerate(from, to, from.getBoundingBox());
00823 
00824     // 2. Reconstruct the data processors.
00825     transferDataProcessors(from, to);
00826 }
00827 
00828 template<typename T, template<typename U> class Descriptor>
00829 void transferBlockLatticeNonLocal (
00830         MultiBlockLattice2D<T,Descriptor> const& from,
00831         MultiBlockLattice2D<T,Descriptor>& to, Box2D const& domain )
00832 {
00833     // 1. Copy all data from the old to the new field. This includes dynamics
00834     //    objects which must be fully serialized and regenerated.
00835     copyNonLocal(from, to, domain, modif::dataStructure);
00836     // 2. Reconstruct the data processors.
00837     transferDataProcessors(from, to);
00838 }
00839 
00840 
00841 template<typename T, template<typename U> class Descriptor>
00842 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > generateMultiBlockLattice (
00843         Box2D boundingBox, Dynamics<T,Descriptor>* backgroundDynamics, plint envelopeWidth )
00844 {
00845     return std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > (
00846         new MultiBlockLattice2D<T,Descriptor> (
00847             defaultMultiBlockPolicy2D().getMultiBlockManagement(boundingBox, envelopeWidth),
00848             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00849             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00850             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00851             backgroundDynamics )
00852     );
00853 }
00854 
00855 template<typename T, template<typename U> class Descriptor>
00856 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > defaultGenerateMultiBlockLattice2D (
00857         MultiBlockManagement2D const& management, plint nDim )
00858 {
00859     return std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > (
00860         new MultiBlockLattice2D<T,Descriptor> (
00861             management,
00862             defaultMultiBlockPolicy2D().getBlockCommunicator(),
00863             defaultMultiBlockPolicy2D().getCombinedStatistics(),
00864             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00865             new NoDynamics<T,Descriptor> )
00866     );
00867 }
00868 
00869 template<typename T, template<typename U> class Descriptor>
00870 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > clone (
00871         MultiBlockLattice2D<T,Descriptor>& originalLattice,
00872         Box2D const& subDomain, bool crop )
00873 {
00874     std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > clonedLattice (
00875             generateMultiBlockLattice<T,Descriptor>(originalLattice, subDomain, crop) );
00876 
00877     transferBlockLatticeLocal( originalLattice, *clonedLattice,
00878                                originalLattice.getBoundingBox() );
00879 
00880     return clonedLattice;
00881 }
00882 
00883 template<typename T, template<typename U> class Descriptor>
00884 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > generateMultiBlockLattice (
00885         MultiBlock2D const& originalBlock, Box2D const& intersection,
00886         bool crop )
00887 {
00888     return std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > (
00889         new MultiBlockLattice2D<T,Descriptor> (
00890             intersect(originalBlock.getMultiBlockManagement(), intersection, crop),
00891             originalBlock.getBlockCommunicator().clone(),
00892             originalBlock.getCombinedStatistics().clone(),
00893             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00894             new NoDynamics<T,Descriptor> )
00895     );
00896 }
00897 
00898 template<typename T, template<typename U> class Descriptor>
00899 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > generateIntersectMultiBlockLattice (
00900         MultiBlock2D const& originalBlock1,
00901         MultiBlock2D const& originalBlock2, bool crop )
00902 {
00903     return std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > (
00904         new MultiBlockLattice2D<T,Descriptor> (
00905             intersect(originalBlock1.getMultiBlockManagement(),
00906                       originalBlock2.getMultiBlockManagement(), crop),
00907             originalBlock1.getBlockCommunicator().clone(),
00908             originalBlock1.getCombinedStatistics().clone(),
00909             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00910             new NoDynamics<T,Descriptor> )
00911     );
00912 }
00913 
00914 template<typename T, template<typename U> class Descriptor>
00915 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > generateIntersectMultiBlockLattice (
00916         MultiBlock2D const& originalBlock1,
00917         MultiBlock2D const& originalBlock2,
00918         Box2D const& intersection, bool crop )
00919 {
00920     MultiBlockManagement2D intersectedBlocks (
00921             intersect ( originalBlock1.getMultiBlockManagement(),
00922                         originalBlock2.getMultiBlockManagement(), crop ) );
00923     MultiBlockManagement2D intersectWithDomain (
00924             intersect( intersectedBlocks, intersection, crop ) );
00925     return std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > (
00926         new MultiBlockLattice2D<T,Descriptor> (
00927             intersectWithDomain,
00928             originalBlock1.getBlockCommunicator().clone(),
00929             originalBlock1.getCombinedStatistics().clone(),
00930             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00931             new NoDynamics<T,Descriptor> )
00932     );
00933 }
00934 
00935 template<typename T, template<typename U> class Descriptor>
00936 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > generateJoinMultiBlockLattice (
00937         MultiBlock2D const& originalBlock1,
00938         MultiBlock2D const& originalBlock2 )
00939 {
00940     return std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > (
00941         new MultiBlockLattice2D<T,Descriptor> (
00942             block_union (
00943                 originalBlock1.getMultiBlockManagement(),
00944                 originalBlock2.getMultiBlockManagement() ),
00945             originalBlock1.getBlockCommunicator().clone(),
00946             originalBlock1.getCombinedStatistics().clone(),
00947             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00948             new NoDynamics<T,Descriptor> )
00949     );
00950 }
00951 
00952 template<typename T, template<typename U> class Descriptor>
00953 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > extend (
00954         MultiBlockLattice2D<T,Descriptor>& originalBlock, Box2D const& addedBlock )
00955 {
00956     std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > newBlock (
00957         new MultiBlockLattice2D<T,Descriptor> (
00958             extend( originalBlock.getMultiBlockManagement(), addedBlock, addedBlock ),
00959             originalBlock.getBlockCommunicator().clone(),
00960             originalBlock.getCombinedStatistics().clone(),
00961             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00962             originalBlock.getBackgroundDynamics().clone() )
00963     );
00964 
00965     transferBlockLatticeLocal( originalBlock, *newBlock,
00966                                originalBlock.getBoundingBox() );
00967 
00968     return newBlock;
00969 }
00970 
00971 template<typename T, template<typename U> class Descriptor>
00972 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > except (
00973         MultiBlockLattice2D<T,Descriptor>& originalBlock,
00974         Box2D const& exceptedBlock )
00975 {
00976     std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > newBlock (
00977         new MultiBlockLattice2D<T,Descriptor> (
00978             except( originalBlock.getMultiBlockManagement(), exceptedBlock),
00979             originalBlock.getBlockCommunicator().clone(),
00980             originalBlock.getCombinedStatistics().clone(),
00981             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00982             originalBlock.getBackgroundDynamics().clone() )
00983     );
00984 
00985     transferBlockLatticeLocal( originalBlock, *newBlock,
00986                                originalBlock.getBoundingBox() );
00987 
00988     return newBlock;
00989 }
00990 
00991 template<typename T, template<typename U> class Descriptor>
00992 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > redistribute (
00993         MultiBlockLattice2D<T,Descriptor> const& originalBlock,
00994         SparseBlockStructure2D const& newBlockStructure )
00995 {
00996     std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > newBlock (
00997         new MultiBlockLattice2D<T,Descriptor> (
00998             MultiBlockManagement2D (
00999                 newBlockStructure,
01000                 originalBlock.getMultiBlockManagement().getThreadAttribution().clone(),
01001                 originalBlock.getMultiBlockManagement().getEnvelopeWidth() ),
01002             originalBlock.getBlockCommunicator().clone(),
01003             originalBlock.getCombinedStatistics().clone(),
01004             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
01005             originalBlock.getBackgroundDynamics().clone() )
01006     );
01007 
01008     transferBlockLatticeNonLocal( originalBlock, *newBlock,
01009                                   originalBlock.getBoundingBox() );
01010 
01011     return newBlock;
01012 }
01013 
01014 template<typename T, template<typename U> class Descriptor>
01015 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > redistribute (
01016         MultiBlockLattice2D<T,Descriptor> const& originalBlock,
01017         SparseBlockStructure2D const& newBlockStructure,
01018         Box2D const& intersection, bool crop )
01019 {
01020     return redistribute(originalBlock, intersect(newBlockStructure, intersection, crop));
01021 }
01022 
01023 template<typename T, template<typename U> class Descriptor>
01024 std::auto_ptr<MultiBlockLattice2D<T, Descriptor> > align (
01025         MultiBlockLattice2D<T, Descriptor> const& originalBlock,
01026         MultiBlock2D const& partnerBlock )
01027 {
01028     std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > newBlock (
01029         new MultiBlockLattice2D<T,Descriptor> (
01030             align(originalBlock.getMultiBlockManagement(),
01031                   partnerBlock.getMultiBlockManagement()),
01032             originalBlock.getBlockCommunicator().clone(),
01033             originalBlock.getCombinedStatistics().clone(),
01034             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
01035             originalBlock.getBackgroundDynamics().clone() )
01036     );
01037 
01038     transferBlockLatticeNonLocal( originalBlock, *newBlock,
01039                                   originalBlock.getBoundingBox() );
01040 
01041     return newBlock;
01042 }
01043 
01044 template<typename T, template<typename U> class Descriptor>
01045 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > reparallelize (
01046         MultiBlockLattice2D<T,Descriptor> const& originalBlock )
01047 {
01048     return reparallelize(originalBlock, 64, 64);
01049 }
01050 
01051 template<typename T, template<typename U> class Descriptor>
01052 std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > reparallelize (
01053         MultiBlockLattice2D<T,Descriptor> const& originalBlock,
01054         plint blockLx, plint blockLy )
01055 {
01056     std::auto_ptr<MultiBlockLattice2D<T,Descriptor> > newBlock (
01057         new MultiBlockLattice2D<T,Descriptor> (
01058             reparallelize (
01059                 originalBlock.getMultiBlockManagement(), blockLx, blockLy ),
01060             originalBlock.getBlockCommunicator().clone(),
01061             originalBlock.getCombinedStatistics().clone(),
01062             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
01063             originalBlock.getBackgroundDynamics().clone() )
01064     );
01065 
01066     transferBlockLatticeNonLocal( originalBlock, *newBlock,
01067                                   originalBlock.getBoundingBox() );
01068 
01069     return newBlock;
01070 }
01071 
01072 }  // namespace plb
01073 
01074 #endif  // MULTI_BLOCK_GENERATOR_2D_HH