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

multiGridGenerator2D.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 
00025 /* Main author: Daniel Lagrava
00026  **/
00027 
00032 #ifndef MULTI_GRID_GENERATOR_2D_HH
00033 #define MULTI_GRID_GENERATOR_2D_HH
00034 
00035 #include "multiGrid/multiGridGenerator2D.h"
00036 
00037 namespace plb {
00038 
00040 template<typename T, template<typename U> class Descriptor>
00041 std::vector<MultiBlockLattice2D<T,Descriptor>*> generateLattices(
00042                 MultiGridManagement2D management,
00043                 std::vector<Dynamics<T,Descriptor>*> backgroundDynamics,
00044                 std::vector<BlockCommunicator2D*> communicators,
00045                 std::vector<CombinedStatistics*> combinedStatistics,
00046                 plint envelopeWidth
00047                 )
00048 {
00049     // get the MPI id's (if available)
00050     std::vector<std::vector<plint> > mpiProcesses = management.getMpiProcesses();
00051     std::vector<std::vector<Box2D> > bulks = management.getBulks();
00052     PLB_PRECONDITION (mpiProcesses.size()==0 || mpiProcesses.size()==bulks.size());
00053     
00054     // allocation of the result vector
00055     std::vector<MultiBlockLattice2D<T,Descriptor>*> multiBlocks(bulks.size());
00056     for (pluint iLevel=0; iLevel<bulks.size(); ++iLevel) {
00057         // create a thread attribution 
00058         ExplicitThreadAttribution* threadAttribution = new ExplicitThreadAttribution;
00059         PLB_ASSERT(mpiProcesses.size()==0 || mpiProcesses[iLevel].size()==bulks[iLevel].size());
00060         SparseBlockStructure2D geometry(management.getBoundingBox(iLevel));
00061         for (pluint iBlock=0; iBlock<bulks[iLevel].size(); ++iBlock) {
00062             plint mpiProcess = mpiProcesses.size() > 0 ? mpiProcesses[iLevel][iBlock] : 0;
00063             plint blockId = geometry.nextIncrementalId();
00064             Box2D bulk = bulks[iLevel][iBlock];
00065             Box2D bb = bulk;
00066             geometry.addBlock(bulk, bulk, blockId);
00067             threadAttribution->addBlock(blockId, mpiProcess);
00068         }
00069         MultiBlockManagement2D
00070             blockManagement( geometry, threadAttribution,
00071                              envelopeWidth, iLevel );
00072         multiBlocks[iLevel] = new MultiBlockLattice2D<T,Descriptor> (
00073             blockManagement,
00074             communicators[iLevel],
00075             combinedStatistics[iLevel],
00076             defaultMultiBlockPolicy2D().getMultiCellAccess<T,Descriptor>(),
00077             backgroundDynamics[iLevel] );
00078         multiBlocks[iLevel] -> periodicity().toggleAll(false);
00079     }
00080     return multiBlocks;
00081 }
00082 
00083 template<typename T, template<typename U> class Descriptor>
00084 std::vector<MultiBlockLattice2D<T,Descriptor>*> generateLattices(
00085                 MultiGridManagement2D management,
00086                 std::vector<Dynamics<T,Descriptor>*> backgroundDynamics,
00087                 plint envelopeWidth )
00088 {
00089     return generateLattices 
00090         (management, backgroundDynamics,
00091          defaultMultiGridPolicy2D().getBlockCommunicator<T>(management.getNumLevels()),
00092          defaultMultiGridPolicy2D().getCombinedStatistics(management.getNumLevels()),
00093          envelopeWidth );
00094 }
00095 
00099 template<typename T>
00100 std::vector<MultiScalarField2D<T>*> generateScalarFields(
00101                         MultiGridManagement2D const& management,
00102                         std::vector<BlockCommunicator2D*> communicators,
00103                         std::vector<CombinedStatistics*> combinedStatistics )
00104 {
00105     std::vector<std::vector<Box2D> > bulks = management.getBulks(); 
00106         std::vector<std::vector<plint> > mpiProcesses = management.getMpiProcesses();
00107     
00108     PLB_PRECONDITION (mpiProcesses.size()==0 || mpiProcesses.size()==bulks.size());
00109     plint envelopeWidth=1;
00110     std::vector<MultiScalarField2D<T>*> scalars(bulks.size());
00111     for (plint iLevel=0; iLevel<(plint)bulks.size(); ++iLevel){
00112         PLB_ASSERT(mpiProcesses.size()==0 || mpiProcesses[iLevel].size()==bulks[iLevel].size());
00113         ExplicitThreadAttribution* threadAttribution = new ExplicitThreadAttribution;
00114         SparseBlockStructure2D geometry(management.getBoundingBox(iLevel));
00115         for (pluint iBlock=0; iBlock<bulks[iLevel].size(); ++iBlock) {
00116             plint mpiProcess = mpiProcesses.size() > 0 ? mpiProcesses[iLevel][iBlock] : 0;
00117             plint blockId = geometry.nextIncrementalId();
00118             geometry.addBlock(bulks[iLevel][iBlock], bulks[iLevel][iBlock], blockId);
00119             threadAttribution->addBlock(blockId, mpiProcess);
00120         }
00121         MultiBlockManagement2D blockManagement (
00122                 geometry, threadAttribution,
00123                 envelopeWidth, iLevel );
00124         scalars[iLevel] = new MultiScalarField2D<T>(
00125                                 blockManagement,communicators[iLevel],
00126                                 combinedStatistics[iLevel], 
00127                                 defaultMultiBlockPolicy2D().getMultiScalarAccess<T>());  
00128         
00129     }
00130     
00131     return scalars;
00132 }
00133 
00134 
00135 template<typename T, int nDim>
00136 std::vector<MultiTensorField2D<T,nDim> *> generateTensorFields (
00137         MultiGridManagement2D const& management,
00138         std::vector<BlockCommunicator2D*> communicators,
00139         std::vector<CombinedStatistics*> combinedStatistics )
00140 {
00141     std::vector<MultiTensorField2D<T,nDim>* > fields(management.getNumLevels());
00142     std::vector<std::vector<Box2D> > bulks = management.getBulks();
00143     std::vector<std::vector<plint> > ids = management.getMpiProcesses();
00144     PLB_PRECONDITION (ids.size()==0 || ids.size()==bulks.size());
00145     
00146     plint envelopeWidth=1;
00147     
00148     fields.resize(bulks.size());
00149     for (plint iLevel=0; iLevel<(plint)bulks.size(); ++iLevel){
00150         ExplicitThreadAttribution* threadAttribution = new ExplicitThreadAttribution;
00151         PLB_ASSERT(ids.size()==0 || ids[iLevel].size()==bulks[iLevel].size());
00152         SparseBlockStructure2D geometry(management.getBoundingBox(iLevel));
00153         for (pluint iBlock=0; iBlock<bulks[iLevel].size(); ++iBlock) {
00154             plint mpiProcess = ids.size() > 0 ? ids[iLevel][iBlock] : 0;
00155             plint blockId = geometry.nextIncrementalId();
00156             geometry.addBlock(bulks[iLevel][iBlock], bulks[iLevel][iBlock], blockId);
00157             threadAttribution->addBlock(blockId, mpiProcess);
00158         }
00159        
00160         MultiBlockManagement2D blockManagement (
00161                 geometry, threadAttribution,
00162                 envelopeWidth, iLevel );
00163         fields[iLevel] = new MultiTensorField2D<T,nDim>(
00164                                     blockManagement,   
00165                                     communicators[iLevel],
00166                                     combinedStatistics[iLevel], 
00167                                     defaultMultiBlockPolicy2D().getMultiTensorAccess<T,nDim>());  
00168         
00169     }
00170     
00171     return fields;
00172 }
00173 
00174 template<typename T, template<typename U> class Descriptor>
00175 void LinearInterpolationFineGridInterfaceInstantiator<T,Descriptor>::instantiateDataProcessors(
00176                                                Box2D fineGridInterface,
00177                                                MultiBlockLattice2D<T,Descriptor>& coarseLattice,
00178                                                MultiBlockLattice2D<T,Descriptor>& fineLattice,
00179                                                plint direction, plint orientation
00180                                                )
00181                                                
00182 {
00183     PLB_PRECONDITION( fineGridInterface.getNx()==1 || fineGridInterface.getNy()==1 );
00184     plint scalingOrder = 0; // decompose in rho, u and fneq
00185     
00186     RescaleEngine<T,Descriptor>* rescaleEngine = new ConvectiveRescaleEngine<T,Descriptor>(scalingOrder);
00187     
00188     // computation of the direction according to the refinement
00189     plint GRdirection = fineGridInterface.getNy()==1 ? 0 : 1;
00190     // computation of the direction according to Palabos BC convention
00191     plint BCdirection = direction;
00192     
00193     
00194     Box2D reducedFineGridInterface(fineGridInterface);
00195     if (GRdirection==0) {  // Interface extends in x-direction.
00196         reducedFineGridInterface.x0 += 1;
00197         reducedFineGridInterface.x1 -= 1;
00198     }
00199     else {  // interface extends in y-direction.
00200         reducedFineGridInterface.y0 += 1;
00201         reducedFineGridInterface.y1 -= 1;
00202     }
00203 
00204     Box2D lowerFineEnd, upperFineEnd;
00205     lowerFineEnd.x0 = lowerFineEnd.x1 = fineGridInterface.x0;
00206     lowerFineEnd.y0 = lowerFineEnd.y1 = fineGridInterface.y0;
00207     upperFineEnd.x0 = upperFineEnd.x1 = fineGridInterface.x1;
00208     upperFineEnd.y0 = upperFineEnd.y1 = fineGridInterface.y1;
00209 
00210     // Number of time steps executed by the fine grid during a coarse iteration.
00211     plint numTimeSteps = 2; 
00212     plint executionTime = numTimeSteps-1;
00213     
00214     // Instantiate specific time-interpolation dynamics on the interface of the fine grid.
00215     Box2D bb = fineGridInterface.multiply(2);
00216 
00217     setCompositeDynamics (
00218             fineLattice,
00219             fineGridInterface.multiply(2),
00220             new FineGridBoundaryDynamics<T,Descriptor> (
00221                 new NoDynamics<T,Descriptor>, fineLattice.getTimeCounter(), numTimeSteps,
00222                 rescaleEngine->getDecompositionOrder() ) );
00223 
00224     // The coarse processors are at processing level 1, because they need to access information
00225     //   from within the coarse envelope.
00226     plint processorLevelCoarse=1;
00227     
00228     // Copy, rescale, and interpolate from coarse to fine in the bulk of the interface.
00229     integrateProcessingFunctional (
00230             new CopyCoarseToFineLinearInterp2D<T, Descriptor,Descriptor> (
00231                 rescaleEngine->clone(), BCdirection, orientation ),
00232             reducedFineGridInterface,
00233             coarseLattice, fineLattice, processorLevelCoarse );   
00234             
00235     // Copy, rescale, and interpolate from coarse to fine at the lower end of the interface.
00236     integrateProcessingFunctional (
00237             new CopyCoarseToFineBoundaryLinearInterp2D<T, Descriptor,Descriptor> (
00238                 rescaleEngine->clone(), BCdirection, orientation, 1 ),
00239             lowerFineEnd,
00240             coarseLattice, fineLattice, processorLevelCoarse );   
00241 
00242     // Copy, rescale, and interpolate from coarse to fine at the upper end of the interface.
00243     integrateProcessingFunctional (
00244             new CopyCoarseToFineBoundaryLinearInterp2D<T, Descriptor,Descriptor> (
00245                 rescaleEngine->clone(), BCdirection, orientation, -1 ),
00246             upperFineEnd,
00247             coarseLattice, fineLattice, processorLevelCoarse );   
00248     
00249 
00250     // Add a data processor which imposes a time-cyclic behavior on the fine grid
00251     //   boundary-dynamics.
00252     integrateProcessingFunctional (
00253             new Copy_t1_to_t0_2D<T, Descriptor>(numTimeSteps, executionTime),
00254             fineGridInterface.multiply(2),
00255             fineLattice );
00256 
00257 
00258     delete rescaleEngine;
00259 }
00260 
00261 
00262 
00263 template<typename T, template<typename U> class Descriptor>
00264 void CubicInterpolationFineGridInterfaceInstantiator<T,Descriptor>::instantiateDataProcessors(
00265                                                Box2D fineGridInterface,
00266                                                MultiBlockLattice2D<T,Descriptor>& coarseLattice,
00267                                                MultiBlockLattice2D<T,Descriptor>& fineLattice,
00268                                                plint direction, plint orientation
00269                                                )
00270                                                
00271 {
00272     PLB_PRECONDITION( fineGridInterface.getNx()==1 || fineGridInterface.getNy()==1 );
00273     plint scalingOrder=0; // to decompose in rho,u and fneq
00274     RescaleEngine<T,Descriptor>* rescaleEngine = new ConvectiveRescaleEngine<T,Descriptor>(scalingOrder);
00275     
00276     // computation of the direction according to the refinement
00277     plint GRdirection = fineGridInterface.getNy()==1 ? 0 : 1;
00278     // computation of the direction according to Palabos BC convention
00279     plint BCdirection = direction;
00280     
00281     Box2D reducedFineGridInterface(fineGridInterface);
00282     if (GRdirection==0) {  // Interface extends in x-direction.
00283         reducedFineGridInterface.x0 += 1;
00284         reducedFineGridInterface.x1 -= 1;
00285     }
00286     else {  // interface extends in y-direction.
00287         reducedFineGridInterface.y0 += 1;
00288         reducedFineGridInterface.y1 -= 1;
00289     }
00290 
00291     Box2D lowerFineEnd, upperFineEnd;
00292     lowerFineEnd.x0 = lowerFineEnd.x1 = fineGridInterface.x0;
00293     lowerFineEnd.y0 = lowerFineEnd.y1 = fineGridInterface.y0;
00294     upperFineEnd.x0 = upperFineEnd.x1 = fineGridInterface.x1;
00295     upperFineEnd.y0 = upperFineEnd.y1 = fineGridInterface.y1;
00296 
00297     // Number of time steps executed by the fine grid during a coarse iteration.
00298     plint numTimeSteps = 2; 
00299     plint executionTime = numTimeSteps-1;
00300     
00301     // Instantiate specific time-interpolation dynamics on the interface of the fine grid.
00302     Box2D bb = fineGridInterface.multiply(2);
00303 
00304     setCompositeDynamics (
00305             fineLattice,
00306             fineGridInterface.multiply(2),
00307             new FineGridBoundaryDynamics<T,Descriptor> (
00308                 new NoDynamics<T,Descriptor>, fineLattice.getTimeCounter(), numTimeSteps,
00309                 rescaleEngine->getDecompositionOrder() ) );
00310 
00311     // The coarse processors are at processing level 1, because they need to access information
00312     //   from within the coarse envelope.
00313     plint processorLevelCoarse=1;
00314     
00315     // Copy, rescale, and interpolate from coarse to fine in the bulk of the interface.
00316     integrateProcessingFunctional (
00317             new CopyCoarseToFineCubicInterp2D<T, Descriptor,Descriptor> (
00318                 rescaleEngine->clone(), BCdirection, orientation ),
00319             reducedFineGridInterface,
00320             coarseLattice, fineLattice, processorLevelCoarse );
00321     
00322     // Copy, rescale, and interpolate from coarse to fine at the lower end of the interface.
00323     integrateProcessingFunctional (
00324             new CopyCoarseToFineBoundaryCubicInterp2D<T, Descriptor,Descriptor> (
00325                 rescaleEngine->clone(), BCdirection, orientation, 1 ),
00326             lowerFineEnd,
00327             coarseLattice, fineLattice, processorLevelCoarse );   
00328 
00329     // Copy, rescale, and interpolate from coarse to fine at the upper end of the interface.
00330     integrateProcessingFunctional (
00331             new CopyCoarseToFineBoundaryCubicInterp2D<T, Descriptor,Descriptor> (
00332                 rescaleEngine->clone(), BCdirection, orientation, -1 ),
00333             upperFineEnd,
00334             coarseLattice, fineLattice, processorLevelCoarse );
00335 
00336     // Add a data processor which imposes a time-cyclic behavior on the fine grid
00337     //   boundary-dynamics.
00338     integrateProcessingFunctional (
00339             new Copy_t1_to_t0_2D<T, Descriptor>(numTimeSteps, executionTime),
00340             fineGridInterface.multiply(2),
00341             fineLattice );
00342 
00343     delete rescaleEngine;
00344 }
00345 
00346 
00347 template<typename T, template<typename U> class Descriptor>
00348 void FilteredCoarseGridInterfaceInstantiator<T,Descriptor>::instantiateDataProcessors(
00349                                                 Box2D coarseGridInterface,
00350                                                 MultiBlockLattice2D<T,Descriptor>& coarseLattice,
00351                                                 MultiBlockLattice2D<T,Descriptor>& fineLattice,
00352                                                 plint direction, plint orientation
00353                                                )
00354 {
00355     // Number of time steps executed by the fine grid during a coarse iteration.
00356     plint numTimeSteps = 2; 
00357     plint executionTime = numTimeSteps-1;
00358     // Add a data processor which copies and rescales from the fine to the coarse lattice.
00359     plint scalingOrder=0; // to decompose in rho,u and fneq
00360     
00361 /*     // computation of the direction according to the refinement
00362     plint GRdirection = coarseGridInterface.getNy()==1 ? 0 : 1;
00363         
00364     Box2D reducedCoarseGridInterface(coarseGridInterface);
00365     if (GRdirection==0) {  // Interface extends in x-direction.
00366         reducedCoarseGridInterface.x0 += 1;
00367         reducedCoarseGridInterface.x1 -= 1;
00368     }
00369     else {  // interface extends in y-direction.
00370         reducedCoarseGridInterface.y0 += 1;
00371         reducedCoarseGridInterface.y1 -= 1;
00372     }
00373 
00374     Box2D lowerFineEnd, upperFineEnd;
00375     lowerFineEnd.x0 = lowerFineEnd.x1 = coarseGridInterface.x0;
00376     lowerFineEnd.y0 = lowerFineEnd.y1 = coarseGridInterface.y0;
00377     upperFineEnd.x0 = upperFineEnd.x1 = coarseGridInterface.x1;
00378     upperFineEnd.y0 = upperFineEnd.y1 = coarseGridInterface.y1;*/
00379     
00380         
00381     integrateProcessingFunctional (
00382             new CopyFineToCoarseWithFiltering2D<T, Descriptor,Descriptor> (
00383                 new ConvectiveRescaleEngine<T,Descriptor>(scalingOrder), 
00384                 numTimeSteps, executionTime, direction, orientation ),
00385             coarseGridInterface.multiply(2),
00386             fineLattice, coarseLattice, 2 );
00387             
00388 //     integrateProcessingFunctional (
00389 //             new CopyFineToCoarse2D<T, Descriptor,Descriptor> (
00390 //                 new ConvectiveRescaleEngine<T,Descriptor>(scalingOrder), 
00391 //                 numTimeSteps, executionTime, direction, orientation ),
00392 //             lowerFineEnd.multiply(2),
00393 //             fineLattice, coarseLattice, 2 );
00394 //             
00395 //     integrateProcessingFunctional (
00396 //             new CopyFineToCoarse2D<T, Descriptor,Descriptor> (
00397 //                 new ConvectiveRescaleEngine<T,Descriptor>(scalingOrder), 
00398 //                 numTimeSteps, executionTime, direction, orientation ),
00399 //             upperFineEnd.multiply(2),
00400 //             fineLattice, coarseLattice, 2 );
00401 }
00402                                              
00403 
00404 
00405 template<typename T, template<typename U> class Descriptor>
00406 void UnfilteredCoarseGridInterfaceInstantiator<T,Descriptor>::instantiateDataProcessors(
00407                                                 Box2D coarseGridInterface,
00408                                                 MultiBlockLattice2D<T,Descriptor>& coarseLattice,
00409                                                 MultiBlockLattice2D<T,Descriptor>& fineLattice,
00410                                                 plint direction, plint orientation
00411                                                )
00412 {
00413     PLB_PRECONDITION( coarseGridInterface.getNx()==1 || coarseGridInterface.getNy()==1 );
00414     
00415     // Number of time steps executed by the fine grid during a coarse iteration.
00416     plint numTimeSteps = 2; 
00417     plint executionTime = numTimeSteps-1;
00418     // Add a data processor which copies and rescales from the fine to the coarse lattice.
00419     plint scalingOrder=0; // to decompose in rho,u and fneq
00420     
00421     integrateProcessingFunctional (
00422             new CopyFineToCoarse2D<T, Descriptor,Descriptor> (
00423                 new ConvectiveRescaleEngine<T,Descriptor>(scalingOrder), 
00424                 numTimeSteps, executionTime, direction, orientation ),
00425             coarseGridInterface.multiply(2),
00426             fineLattice, coarseLattice, 2 );
00427 }
00428 
00429 template<typename T, template<typename U> class Descriptor>
00430 
00431 std::auto_ptr< MultiGridLattice2D<T,Descriptor> > 
00432         MultiGridGenerator2D<T,Descriptor>::createRefinedLatticeCubicInterpolationNoFiltering(
00433                         MultiGridManagement2D management,
00434                         Dynamics<T,Descriptor>* backgroundDynamics, plint behaviorLevel )
00435 {
00436     return std::auto_ptr<MultiGridLattice2D<T,Descriptor> >(
00437         new MultiGridLattice2D<T,Descriptor> 
00438             ( management, 
00439               defaultMultiGridPolicy2D().getBlockCommunicator<T>(management.getNumLevels()),
00440               defaultMultiGridPolicy2D().getCombinedStatistics(management.getNumLevels()),
00441               backgroundDynamics, behaviorLevel,
00442               new CubicInterpolationFineGridInterfaceInstantiator<T,Descriptor>(),
00443               new UnfilteredCoarseGridInterfaceInstantiator<T,Descriptor>()
00444             )
00445     );
00446 }
00447 
00448 template<typename T, template<typename U> class Descriptor>
00449 std::auto_ptr< MultiGridLattice2D<T,Descriptor> > 
00450         MultiGridGenerator2D<T,Descriptor>::createRefinedLatticeLinearInterpolationNoFiltering(
00451                         MultiGridManagement2D management,
00452                         Dynamics<T,Descriptor>* backgroundDynamics, plint behaviorLevel )
00453 {
00454     return std::auto_ptr<MultiGridLattice2D<T,Descriptor> >(
00455         new MultiGridLattice2D<T,Descriptor> 
00456             ( management, 
00457               defaultMultiGridPolicy2D().getBlockCommunicator<T>(management.getNumLevels()),
00458               defaultMultiGridPolicy2D().getCombinedStatistics(management.getNumLevels()),
00459               backgroundDynamics, behaviorLevel,
00460               new LinearInterpolationFineGridInterfaceInstantiator<T,Descriptor>(),
00461               new UnfilteredCoarseGridInterfaceInstantiator<T,Descriptor>()
00462             )
00463     );
00464 }
00465 
00466 template<typename T, template<typename U> class Descriptor>                        
00467 std::auto_ptr< MultiGridLattice2D<T,Descriptor> > 
00468         MultiGridGenerator2D<T,Descriptor>::createRefinedLatticeCubicInterpolationFiltering(
00469                         MultiGridManagement2D management,
00470                         Dynamics<T,Descriptor>* backgroundDynamics, plint behaviorLevel )
00471 {
00472     return std::auto_ptr<MultiGridLattice2D<T,Descriptor> >(
00473         new MultiGridLattice2D<T,Descriptor> 
00474             ( management, 
00475               defaultMultiGridPolicy2D().getBlockCommunicator<T>(management.getNumLevels()),
00476               defaultMultiGridPolicy2D().getCombinedStatistics(management.getNumLevels()),
00477               backgroundDynamics, behaviorLevel,
00478               new CubicInterpolationFineGridInterfaceInstantiator<T,Descriptor>(),
00479               new FilteredCoarseGridInterfaceInstantiator<T,Descriptor>()
00480             )
00481     );
00482 }
00483 
00484 
00485 template<typename T, template<typename U> class Descriptor>
00486 std::auto_ptr< MultiGridLattice2D<T,Descriptor> > 
00487         MultiGridGenerator2D<T,Descriptor>::createRefinedLatticeLinearInterpolationFiltering(
00488                         MultiGridManagement2D management,
00489                         Dynamics<T,Descriptor>* backgroundDynamics, plint behaviorLevel)
00490 {
00491     return std::auto_ptr<MultiGridLattice2D<T,Descriptor> >(
00492         new MultiGridLattice2D<T,Descriptor> 
00493             ( management, 
00494               defaultMultiGridPolicy2D().getBlockCommunicator<T>(management.getNumLevels()),
00495               defaultMultiGridPolicy2D().getCombinedStatistics(management.getNumLevels()),
00496               backgroundDynamics, behaviorLevel,
00497               new LinearInterpolationFineGridInterfaceInstantiator<T,Descriptor>(),
00498               new FilteredCoarseGridInterfaceInstantiator<T,Descriptor>()
00499             )
00500     );
00501 }
00502 
00503 
00504 
00505 } // namespace plb
00506 
00507 #endif  // MULTI_GRID_GENERATOR_2D_HH
00508