This example shows how to use Chombo to do parallel input/output for a full adaptive hierarchy. This page shows the auxiliary functions we use to generate the hierarchy and fill it with data. Here are the header files we need to include.
#include "LevelData.H" #include "FArrayBox.H" #include "SPMD.H" #include "AMRIO.H" #include "BRMeshRefine.H" #include "LoadBalance.H" #include "Misc.H" #include "Vector.H" #include "REAL.H" #include "Box.H" #include "Tuple.H" #include "BoxIterator.H"The function getDataVal returns a data value given a location in space. This function is included largely for completeness' sake.
Real getDataVal(const TupleThe function setGrids sets the grid hierarchy. It sets up a bunch of tags at the base grid level and uses the BRMeshRefine class to get lists of boxes at each level. We then call LoadBalance to generate box-to-processor mappings and use both of these to generate layouts.& location) { Real retval = 7.23; for(int idir = 0; idir < SpaceDim; idir++) { Real x= location[idir]; Real fac = Real(idir); retval += sin(x)+ fac*cos(x); } return retval; }
int setGrids(Vector< DisjointBoxLayout >& a_vectGrids, Box& a_domain, Real& a_dx, Vector< int >& a_refRatio, int& a_numlevels) { Real fillRat = 0.77; int ncells = 64; int maxboxsize = 32; Vector < int > ancells(SpaceDim, ncells); Vector< Real > prob_loa(SpaceDim, 0.0); Vector< Real > prob_hia(SpaceDim, 1.0); a_numlevels = 3; a_refRatio.resize(a_numlevels); for(int ilev = 0; ilev < a_numlevels; ++ilev) a_refRatio[ilev] = 2; IntVect ivlo = IntVect::Zero; IntVect ivhi = (ncells-1)*IntVect::Unit; a_domain = Box(ivlo, ivhi); a_vectGrids.resize(a_numlevels); a_dx = (prob_hia[0]-prob_loa[0])/ancells[0]; int nc = ancells[0]; int nmi = nc/2; int nqu = nc/4; int ntf = (nc*3)/4; int nte = (nc*3)/8; int nfe = (nc*5)/8; #if(CH_SPACEDIM ==2) Box boxf1(IntVect(0, nqu), IntVect(nmi-1,ntf-1)); Box boxf2(IntVect(nmi,nte), IntVect(ntf-1,nfe-1)); Box boxf3(IntVect(nqu,0 ), IntVect(nfe-1,nqu-1)); Box boxf4(IntVect(nfe,nqu), IntVect(nc -1,nte-1)); #else Box boxf1(IntVect(0, nqu,nqu), IntVect(nmi-1,ntf-1,ntf-1)); Box boxf2(IntVect(nmi,nte,nte), IntVect(ntf-1,nfe-1,nfe-1)); Box boxf3(IntVect(nqu,0,0 ), IntVect(nfe-1,nqu-1,nqu-1)); Box boxf4(IntVect(nfe,nqu,nqu), IntVect(nc -1,nte-1,nte-1)); #endif IntVectSet tags; tags |= boxf1; tags |= boxf2; tags |= boxf3; tags |= boxf4; Vector< Vector< Box > > vvboxNew(a_numlevels); Vector< Vector< Box > > vvboxOld(a_numlevels); Vector< Box > vectDomain(a_numlevels); Box domainfine = a_domain; for(int ilev = 0; ilev < a_numlevels; ilev++) { vectDomain[ilev] = domainfine; vvboxOld[ilev].push_back(domainfine); domainfine.refine(a_refRatio[ilev]); } int baseLevel = 0; int topLevel = a_numlevels - 2; int blockFactor = 4; int eekflag = 0; int buffersize = 1; int finestLevel = 0; if(topLevel >= 0) { BRMeshRefine meshrefine(vectDomain[0],a_refRatio, fillRat, blockFactor, buffersize, maxboxsize); finestLevel = meshrefine.regrid(vvboxNew, tags, baseLevel, topLevel, vvboxOld); } else vvboxNew = vvboxOld; Vector< Vector< int > > procAssign; Real effRatio = 0.75; Vector< Vector< long > > loads(a_numlevels); for(int ilev = 0; ilev < a_numlevels; ilev++) { loads[ilev].resize(vvboxNew[ilev].size()); for(int ibox = 0; ibox < vvboxNew[ilev].size() ; ibox++) { loads[ilev][ibox] = vvboxNew[ilev][ibox].numPts(); } } LoadBalance(procAssign, effRatio, vvboxNew, loads, a_refRatio); if(eekflag != 0) { cerr << "setGrids: loadBalance returned error code " << eekflag << endl; return(1); } for(int ilev = 0; ilev < a_numlevels; ilev++) { a_vectGrids[ilev].define(vvboxNew[ilev], procAssign[ilev]); a_vectGrids[ilev].close(); } return 0; }