void PoisselleTube:: initializeVelocity(LevelData<EBCellFAB>& a_velocity, const DisjointBoxLayout& a_grids, const EBISLayout& a_ebisl, const ProblemDomain& a_domain, const RealVect& a_origin, const Real& a_time, const RealVect& a_dx) const { for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_grids.get(dit())); for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit) { RealVect xval = EBArith::getVofLocation(vofit() , a_dx, RealVect::Zero); for (int idir = 0; idir < SpaceDim; idir++) { //bogus values for normal and time because they do not matter Real velComp = m_bcval[idir].value(xval, RealVect::Zero, a_time, idir); a_velocity[dit()](vofit(), idir) = velComp; } } } }
void NoFlowVortex:: initializeVelocity(LevelData<EBCellFAB>& a_velocity, const DisjointBoxLayout& a_grids, const EBISLayout& a_ebisl, const ProblemDomain& a_domain, const RealVect& a_origin, const Real& a_time, const RealVect& a_dx) const { Real pi = 4.0*atan(1.0); for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_grids.get(dit())); for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit) { RealVect xval, velpt; getXVal(xval, a_origin,vofit(), a_dx); getVelPt(velpt, xval, pi); for (int idir = 0; idir < SpaceDim; idir++) { a_velocity[dit()](vofit(), idir) = velpt[idir]; } } } }
void getError(LevelData<EBCellFAB>& a_error, const EBISLayout& a_ebisl, const DisjointBoxLayout& a_dbl, const Real& a_dx) { EBCellFactory ebcellfact(a_ebisl); EBFluxFactory ebfluxfact(a_ebisl); a_error.define(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBCellFAB> divFCalc(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBCellFAB> divFExac(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBFluxFAB> faceFlux(a_dbl, 1, IntVect::Zero, ebfluxfact); for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { a_error[dit()].setVal(0.); divFCalc[dit()].setVal(0.); divFExac[dit()].setVal(0.); } setToExactDivFLD(divFExac, a_ebisl, a_dbl, a_dx); setToExactFluxLD(faceFlux, a_ebisl, a_dbl, a_dx); Interval interv(0, 0); faceFlux.exchange(interv); kappaDivergenceLD(divFCalc, faceFlux, a_ebisl, a_dbl, a_dx); for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { EBCellFAB& errorFAB = a_error[dit()]; EBCellFAB& exactFAB = divFExac[dit()]; EBCellFAB& calcuFAB = divFCalc[dit()]; errorFAB += calcuFAB; errorFAB -= exactFAB; } }
void setToExactFluxLD(LevelData<EBFluxFAB>& a_flux, const EBISLayout& a_ebisl, const DisjointBoxLayout& a_dbl, const Real& a_dx) { for (DataIterator dit= a_dbl.dataIterator(); dit.ok(); ++dit) { setToExactFlux(a_flux[dit()], a_ebisl[dit()], a_dbl.get(dit()), a_dx); } }
void setToExactDivFLD(LevelData<EBCellFAB>& a_soln, const EBISLayout& a_ebisl, const DisjointBoxLayout& a_dbl, const Real& a_dx) { for (DataIterator dit= a_dbl.dataIterator(); dit.ok(); ++dit) { setToExactDivF(a_soln[dit()], a_ebisl[dit()], a_dbl.get(dit()), a_dx); } }
// Set up initial conditions void AdvectTestIBC::initialize(LevelData<FArrayBox>& a_U) { DisjointBoxLayout grids = a_U.disjointBoxLayout(); for (DataIterator dit = grids.dataIterator(); dit.ok(); ++dit) { const Box& grid = grids.get(dit()); FORT_ADVECTINITF(CHF_FRA1(a_U[dit()],0), CHF_CONST_REALVECT(m_center), CHF_CONST_REAL(m_size), CHF_CONST_REAL(m_dx), CHF_BOX(grid)); } }
void kappaDivergenceLD(LevelData<EBCellFAB>& a_divF, const LevelData<EBFluxFAB>& a_flux, const EBISLayout& a_ebisl, const DisjointBoxLayout& a_dbl, const Real& a_dx) { for (DataIterator dit= a_dbl.dataIterator(); dit.ok(); ++dit) { kappaDivergence(a_divF[dit()], a_flux[dit()], a_ebisl[dit()], a_dbl.get(dit()), a_dx); } }
// ------------------------------------------------------------ // version of 27 March 2003 Real norm(const LevelData<NodeFArrayBox>& a_phi, const ProblemDomain& a_domain, const DisjointBoxLayout& a_finerGridsCoarsened, const LayoutData< Vector<Box> >& a_IVSVext, const LayoutData< Vector<Box> >& a_IVSVintFinerCoarsened, const int a_nRefFine, const Real a_dx, const Interval& a_comps, const int a_p, bool a_verbose) { // Idea: copy a_phi to temp, then zero out temp on: // - exterior nodes of grids at this level; // - projections of interior nodes of the finer grids. int ncomps = a_comps.size(); const DisjointBoxLayout& grids = a_phi.getBoxes(); LevelData<NodeFArrayBox> temp(grids, ncomps); // Copy a_phi to temp. Interval newcomps(0, ncomps-1); for (DataIterator dit(grids.dataIterator()); dit.ok(); ++dit) { const NodeFArrayBox& nfab = a_phi[dit()]; const Box& bx = grids.get(dit()); temp[dit()].copy(bx, newcomps, bx, nfab, a_comps); } // Zero out temp on exterior nodes. zeroBoundaryNodes(temp, a_IVSVext); // Define zeroCoarsened to be all zero on the coarsened finer grids. LevelData<NodeFArrayBox> zeroCoarsened(a_finerGridsCoarsened, ncomps, IntVect::Zero); for (DataIterator dit(a_finerGridsCoarsened.dataIterator()); dit.ok(); ++dit) zeroCoarsened[dit()].getFab().setVal(0.); // Set temp to zero on interior nodes of coarsened finer grids. copyInteriorNodes(temp, zeroCoarsened, a_IVSVintFinerCoarsened); Real normLevel = norm(temp, a_dx, a_p, newcomps, a_verbose); return normLevel; }
int EBAMRTestCommon:: checkForZero(const LevelData<EBCellFAB>& a_errorVelo, const DisjointBoxLayout& a_gridsFine, const EBISLayout& a_ebislFine, const Box& a_domainFine, string a_funcname) { int eekflag = 0; Real eps = 1.0e-8; #ifdef CH_USE_FLOAT eps = 1.0e-3; #endif for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { Box grownBox = a_gridsFine.get(dit()); grownBox.grow(1); grownBox &= a_domainFine; IntVectSet ivsBox(grownBox); for (VoFIterator vofit(ivsBox, a_ebislFine[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); int ihere = 0; if (vof.gridIndex() == EBDebugPoint::s_ivd) { ihere = 1; } for (int ivar = 0; ivar < a_errorVelo.nComp(); ivar++) { Real errorIn = a_errorVelo[dit()](vof, ivar); if (Abs(errorIn) > eps) { pout() << "check for zero error too big for test " << a_funcname << endl; pout() << "ivar = " << ivar << endl; pout() << "vof = " << vof.gridIndex() << " error = " << errorIn << endl; return -1; } } } } return eekflag; }
void NoFlowVortex:: initializeScalar ( LevelData<EBCellFAB>& a_scalar, const DisjointBoxLayout& a_grids, const EBISLayout& a_ebisl, const ProblemDomain& a_domain, const RealVect& a_origin, const Real& a_time, const RealVect& a_dx) const { for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_grids.get(dit())); for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit) { RealVect xval; Real scal; getXVal(xval, a_origin,vofit(), a_dx); getScalarPt(scal, xval); a_scalar[dit()](vofit(), 0) = scal; } } }
void NoFlowVortex:: initializePressure(LevelData<EBCellFAB>& a_pressure, const DisjointBoxLayout& a_grids, const EBISLayout& a_ebisl, const ProblemDomain& a_domain, const RealVect& a_origin, const Real& a_time, const RealVect& a_dx) const { for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_grids.get(dit())); for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit) { RealVect xval, pt; getXVal(xval, a_origin,vofit(), a_dx); for (int idir = 0; idir < SpaceDim; idir++) { a_pressure[dit()](vofit(), idir) = 1.e99; } } } }
// new define void LevelFluxRegisterEdge::define( const DisjointBoxLayout& a_dbl, const DisjointBoxLayout& a_dblCoarse, const ProblemDomain& a_dProblem, int a_nRefine, int a_nComp) { m_isDefined = true; CH_assert(a_nRefine > 0); CH_assert(a_nComp > 0); CH_assert(!a_dProblem.isEmpty()); m_nComp = a_nComp; m_nRefine = a_nRefine; m_domainCoarse = coarsen(a_dProblem, a_nRefine); CH_assert (a_dblCoarse.checkPeriodic(m_domainCoarse)); // allocate copiers m_crseCopiers.resize(SpaceDim*2); SideIterator side; // create a Vector<Box> of the fine boxes which also includes periodic images, // since we don't really care about the processor layouts, etc Vector<Box> periodicFineBoxes; CFStencil::buildPeriodicVector(periodicFineBoxes, a_dProblem, a_dbl); // now coarsen these boxes... for (int i=0; i<periodicFineBoxes.size(); i++) { periodicFineBoxes[i].coarsen(m_nRefine); } for (int idir=0 ; idir<SpaceDim; ++idir) { for (side.begin(); side.ok(); ++side) { // step one, build fineBoxes, flux register boxes // indexed by the fine level but in the coarse index // space DisjointBoxLayout fineBoxes,tmp; // first create coarsened dbl, then compute flux register boxes // adjacent to coarsened fine boxes coarsen(tmp, a_dbl, m_nRefine); if (side() == Side::Lo) { adjCellLo(fineBoxes, tmp, idir,1); } else { adjCellHi(fineBoxes, tmp, idir,1); } // now define the FluxBoxes of fabFine on this DisjointBoxLayout m_fabFine[index(idir, side())].define(fineBoxes, a_nComp); LayoutData<Vector<Vector<IntVectSet> > >& ivsetsVect = m_refluxLocations[index(idir, side())]; ivsetsVect.define(a_dblCoarse); LayoutData<Vector<DataIndex> >& mapsV = m_coarToCoarMap[index(idir, side())]; mapsV.define(a_dblCoarse); DisjointBoxLayout coarseBoxes = a_dblCoarse; DataIterator dit = a_dblCoarse.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { unsigned int thisproc = a_dblCoarse.procID(dit()); if (thisproc == procID()) { ivsetsVect[DataIndex(dit())].resize(SpaceDim); } const Box& coarseBox = a_dblCoarse[dit()]; int count = 0; for (int i=0; i<periodicFineBoxes.size(); i++) { Box regBox; if (side() == Side::Lo) { regBox = adjCellLo(periodicFineBoxes[i], idir, 1); } else { regBox = adjCellHi(periodicFineBoxes[i], idir, 1); } // do this little dance in order to ensure that // we catch corner cells which might be in different // boxes. Box testBox(regBox); testBox.grow(1); testBox.grow(idir,-1); if (testBox.intersectsNotEmpty(coarseBox)) { testBox &= coarseBox; ++count; unsigned int proc = a_dblCoarse.procID(dit()); const DataIndex index = DataIndex(dit()); if (proc == procID()) { mapsV[DataIndex(dit())].push_back(index); // loop over face directions here for (int faceDir=0; faceDir<SpaceDim; faceDir++) { // do nothing in normal direction if (faceDir != idir) { // this should give us the face indices for the // faceDir-centered faces adjacent to the coarse-fine // interface which are contained in the current // coarse box Box intersectBox(regBox); Box coarseEdgeBox(coarseBox); coarseEdgeBox.surroundingNodes(faceDir); intersectBox.surroundingNodes(faceDir); intersectBox &= coarseEdgeBox; intersectBox.shiftHalf(faceDir,1); IntVectSet localIV(intersectBox); ivsetsVect[DataIndex(dit())][faceDir].push_back(localIV); } } } } } // end loop over boxes on coarse level } m_regCoarse.define(coarseBoxes, a_nComp, IntVect::Unit); // last thing to do is to define copiers m_crseCopiers[index(idir, side())].define(fineBoxes, coarseBoxes, IntVect::Unit); } } }
void EBMGAverage:: defineStencils() { CH_TIME("EBMGInterp::defineStencils"); DisjointBoxLayout gridsStenCoar; EBISLayout ebislStenCoar; DisjointBoxLayout gridsStenFine; EBISLayout ebislStenFine; if (m_layoutChanged) { if (m_coarsenable) { gridsStenCoar = m_buffGrids; ebislStenCoar = m_buffEBISL; gridsStenFine = m_fineGrids; ebislStenFine = m_fineEBISL; } else { gridsStenCoar = m_coarGrids; ebislStenCoar = m_coarEBISL; gridsStenFine = m_buffGrids; ebislStenFine = m_buffEBISL; } } else { gridsStenCoar = m_coarGrids; ebislStenCoar = m_coarEBISL; gridsStenFine = m_fineGrids; ebislStenFine = m_fineEBISL; } { CH_TIME("graph walking"); LayoutData<Vector<VoFStencil> > averageStencil; LayoutData<VoFIterator > vofItIrregCoar; LayoutData<VoFIterator > vofItIrregFine; m_averageEBStencil.define(gridsStenCoar); averageStencil.define( gridsStenCoar); vofItIrregFine.define( gridsStenCoar); //not wrong. trust me. vofItIrregCoar.define( gridsStenCoar); for (DataIterator dit = gridsStenCoar.dataIterator(); dit.ok(); ++dit) { Box refBox(IntVect::Zero, IntVect::Zero); refBox.refine(m_refRat); int numFinePerCoar = refBox.numPts(); const Box& boxFine = gridsStenFine[dit()]; const EBISBox& ebisBoxFine = ebislStenFine[dit()]; const EBGraph& ebGraphFine = ebisBoxFine.getEBGraph(); const Box& boxCoar = gridsStenCoar[dit()]; const EBISBox& ebisBoxCoar = ebislStenCoar[dit()]; const EBGraph& ebGraphCoar = ebisBoxCoar.getEBGraph(); IntVectSet notRegularCoar = ebisBoxCoar.getIrregIVS(boxCoar); vofItIrregCoar[dit()].define(notRegularCoar, ebGraphCoar); IntVectSet ivsFine = refine(notRegularCoar, m_refRat); vofItIrregFine[dit()].define(ivsFine, ebGraphFine); const Vector<VolIndex>& allCoarVofs = vofItIrregCoar[dit()].getVector(); Vector<VoFStencil>& averageStencils = averageStencil[dit()]; averageStencils.resize(allCoarVofs.size()); for (int icoar = 0; icoar < allCoarVofs.size(); icoar++) { Vector<VolIndex> fineVofs; if (m_refRat > 2) { fineVofs = ebislStenCoar.refine(allCoarVofs[icoar], m_refRat, dit()); } else { fineVofs = ebislStenCoar[dit()].refine(allCoarVofs[icoar]); } VoFStencil& averageStencil = averageStencils[icoar]; for (int ifine = 0; ifine < fineVofs.size(); ifine++) { averageStencil.add(fineVofs[ifine], 1./numFinePerCoar); } } m_averageEBStencil[dit()] = RefCountedPtr<EBStencil>(new EBStencil(allCoarVofs, averageStencil[dit()], boxCoar, boxFine, ebisBoxCoar, ebisBoxFine, m_ghost, m_ghost)); } } }
void EBLevelTGA:: setSourceGhostCells(LevelData<EBCellFAB>& a_src, const DisjointBoxLayout& a_grids, int a_lev) { int ncomp = a_src.nComp(); for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { const Box& grid = a_grids.get(dit()); const Box& srcBox = a_src[dit()].box(); for (int idir = 0; idir < SpaceDim; idir++) { for (SideIterator sit; sit.ok(); ++sit) { int iside = sign(sit()); Box bc_box = adjCellBox(grid, idir, sit(), 1); for (int jdir = 0; jdir < SpaceDim; jdir++) { //want corners too if (jdir != idir) { bc_box.grow(jdir, 1); } } //if fails might not have a ghost cell. bc_box &= m_eblg[a_lev].getDomain().domainBox(); CH_assert(srcBox.contains(bc_box)); if (grid.size(idir) >= 4) { FORT_HORESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()), CHF_BOX(bc_box), CHF_CONST_INT(idir), CHF_CONST_INT(iside), CHF_CONST_INT(ncomp)); } else { // valid region not wide enough to apply HOExtrap -- drop // to linear extrap FORT_RESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()), CHF_BOX(bc_box), CHF_CONST_INT(idir), CHF_CONST_INT(iside), CHF_CONST_INT(ncomp)); } IntVectSet ivs = m_eblg[a_lev].getEBISL()[dit()].getIrregIVS(bc_box); for (VoFIterator vofit(ivs, m_eblg[a_lev].getEBISL()[dit()].getEBGraph()); vofit.ok(); ++vofit) { for (int icomp = 0; icomp < ncomp; icomp++) { Real valNeigh = 0; Vector<FaceIndex> faces = m_eblg[a_lev].getEBISL()[dit()].getFaces(vofit(), idir, flip(sit())); for (int iface = 0; iface < faces.size(); iface++) { VolIndex vofNeigh = faces[iface].getVoF(flip(sit())); valNeigh += a_src[dit()](vofNeigh, icomp); } if (faces.size() > 1) valNeigh /= faces.size(); a_src[dit()](vofit(), icomp) = valNeigh; } } } } } }
int getError(LevelData<EBCellFAB>& a_errorFine, const EBISLayout& a_ebislFine, const DisjointBoxLayout& a_gridsFine, const Box& a_domainFine, const Real& a_dxFine, const EBISLayout& a_ebislCoar, const DisjointBoxLayout& a_gridsCoar, const Box& a_domainCoar, const Real& a_dxCoar, const int& a_refRatio) { int eekflag = 0; int nvar = 1; EBCellFactory ebcellfactFine(a_ebislFine); EBCellFactory ebcellfactCoar(a_ebislCoar); LevelData<EBCellFAB> phiFine(a_gridsFine, nvar, IntVect::Zero,ebcellfactFine); LevelData<EBCellFAB> phiCoar(a_gridsCoar, nvar, IntVect::Zero,ebcellfactCoar); //fill phi fine and phiCExact //put phiFexact into a_errorFine for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_gridsFine.get(dit())); phiFine[dit()].setVal(0.0); EBCellFAB& phiFineFAB = a_errorFine[dit()]; phiFineFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, a_ebislFine[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAns = exactFunc(vof.gridIndex(), a_dxFine); phiFineFAB(vof, 0) = rightAns; } } for (DataIterator dit = a_gridsCoar.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_gridsCoar.get(dit())); EBCellFAB& phiCoarFAB = phiCoar[dit()]; phiCoarFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, a_ebislCoar[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAns = exactFunc(vof.gridIndex(), a_dxCoar); phiCoarFAB(vof, 0) = rightAns; } } EBPWLFineInterp interpOp(a_gridsFine, a_gridsCoar, a_ebislFine, a_ebislCoar, a_domainCoar, a_refRatio, nvar); Interval zeroiv(0,0); interpOp.interpolate(phiFine, phiCoar, zeroiv); //error = phiC - phiCExact for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { EBCellFAB& errorFAB = a_errorFine[dit()]; EBCellFAB& phiFineFAB = phiFine[dit()]; errorFAB -= phiFineFAB; } return eekflag; }
//---------------------------------------------------------------------------- void EBNormalizeByVolumeFraction:: operator()(LevelData<EBCellFAB>& a_Q, const Interval& a_compInterval) const { CH_TIME("EBNormalizer::operator()"); // Endpoints of the given interval. int begin = a_compInterval.begin(), end = a_compInterval.end(), length = a_compInterval.size(); // Loop over the EBISBoxes within our grid. The EB data structures are // indexed in the same manner as the non-EB data structures, so we piggy- // back the former on the latter. a_Q.exchange(); EBISLayout ebisLayout = m_levelGrid.getEBISL(); DisjointBoxLayout layout = m_levelGrid.getDBL(); for (DataIterator dit = layout.dataIterator(); dit.ok(); ++dit) { const EBISBox& box = ebisLayout[dit()]; EBCellFAB& QFAB = a_Q[dit()]; // Go over the irregular cells in this box. const IntVectSet& irregCells = box.getIrregIVS(layout[dit()]); // The average has to be computed from the uncorrected data from all // the neighbors, so we can't apply the corrections in place. For now, // we stash them in a map. map<VolIndex, vector<Real> > correctedValues; for (VoFIterator vit(irregCells, box.getEBGraph()); vit.ok(); ++vit) { Real kappajSum = 0.0; vector<Real> kappajQjSum(length, 0.0); // Get all of the indices of the VoFs within a monotone path // radius of 1. VolIndex vofi = vit(); Vector<VolIndex> vofjs; EBArith::getAllVoFsInMonotonePath(vofjs, vofi, box, 1); // Accumulate the contributions from the neighboring cells. for (unsigned int j = 0; j < vofjs.size(); ++j) { VolIndex vofj = vofjs[j]; Real kappaj = box.volFrac(vofj); for (int icomp = begin; icomp <= end; ++icomp) { kappajQjSum[icomp] += QFAB(vofj, icomp); } // Add this volume fraction to the sum. kappajSum += kappaj; } if (kappajSum > 0.) { // Normalize the quantity and stow it. vector<Real> correctedValue(length); // Real kappai = box.volFrac(vofi); //unused dtg for (int icomp = begin; icomp <= end; ++icomp) { // correctedValue[icomp - begin] = // QFAB(vofi, icomp) + (1.0 - kappai) * kappajQjSum[icomp] / kappajSum; correctedValue[icomp - begin] = kappajQjSum[icomp] / kappajSum; } correctedValues[vofi] = correctedValue; } } // Apply the corrections. for (map<VolIndex, vector<Real> >::const_iterator cit = correctedValues.begin(); cit != correctedValues.end(); ++cit) { for (int icomp = begin; icomp <= end; ++icomp) { QFAB(cit->first, icomp) = cit->second[icomp-begin]; } } } }
// this function works on two solutions on equivalent grids. // It subtracts the computed solution from the exact solution // if a_doGhostCells == true, then does box-by-box comparison, // including ghost cells (boxes must be the same for each). // Otherwise, only does this for valid cells, but boxes don't // need to be the same. void computeSameSizeError(Vector<LevelData<FArrayBox>* >& a_error, const Vector<string>& a_errorVars, const Vector<LevelData<FArrayBox>* >& a_computedSoln, const Vector<string>& a_computedVars, const Vector<DisjointBoxLayout>& a_computedGrids, const Real a_dx, const Vector<int>& a_refRatio, const Vector<LevelData<FArrayBox>* >& a_exactSoln, const Vector<string>& a_exactVars, Real a_bogus_value, bool a_computeRelativeError, bool a_doGhostCells) { int numLevels = a_computedSoln.size(); CH_assert(a_exactSoln.size() == numLevels); CH_assert(a_error.size() == numLevels); CH_assert(a_refRatio.size() >= numLevels - 1); Real dxLevel = a_dx; // outer loop is over levels for (int level = 0; level < numLevels; level++) { LevelData<FArrayBox>& thisLevelError = *a_error[level]; LevelData<FArrayBox>& thisLevelComputed = *a_computedSoln[level]; LevelData<FArrayBox>& thisLevelExact = *a_exactSoln[level]; const DisjointBoxLayout levelGrids = thisLevelComputed.getBoxes(); const DisjointBoxLayout exactGrids = thisLevelExact.getBoxes(); DataIterator levelDit = levelGrids.dataIterator(); for (levelDit.begin(); levelDit.ok(); ++levelDit) { // initialize error to a bogus value thisLevelError[levelDit()].setVal(a_bogus_value); } // loop over variables for (int nErr = 0; nErr < a_errorVars.size(); nErr++) { string thisErrVar = a_errorVars[nErr]; bool done = false; // this is where things differ between the ghost-cell // and non-ghost-cell approach. if (a_doGhostCells) { // this is the older approach to things -- // do everything grid-by-grid // first loop over exact variables for (int exactComp = 0; exactComp < a_exactVars.size(); exactComp++) { string thisExactVar = a_exactVars[exactComp]; // check if this exact variable is "the one" if (thisExactVar == thisErrVar) { int computedComp = 0; // now loop over computed variables while (!done && (computedComp < a_computedVars.size())) { if (a_computedVars[computedComp] == thisErrVar) { // copy exact solution -> error // and then subtract computed solution DataIterator exactDit = thisLevelExact.dataIterator(); for (levelDit.reset(); levelDit.ok(); ++levelDit) { FArrayBox& thisComputed = thisLevelComputed[levelDit()]; FArrayBox& thisError = thisLevelError[levelDit()]; const Box& thisBox = levelGrids[levelDit()]; for (exactDit.begin(); exactDit.ok(); ++exactDit) { if (thisBox.contains(exactGrids[exactDit()])) { thisError.copy(thisLevelExact[exactDit()], exactComp, nErr, 1); } // end if exact and computed boxes match } // end loop over exact grids if (a_computeRelativeError) { // do this a little strangely -- relative // error is one - computed/exact. thisError.divide(thisComputed, computedComp, nErr, 1); thisError.invert(-1.0, nErr, 1); thisError.plus(1.0, nErr, 1); } else { thisError.minus(thisComputed, computedComp, nErr, 1); } } // end loop over grids done = true; } // if a_computedVar is a_errorVar computedComp += 1; } // end loop over a_computedVars if (!done) { pout() << "Variable " << thisErrVar << " not found!!!" << endl; MayDay::Error(); } } // end if this exactVar is correct } // end loop over exact variables } else // non-ghost cell case; this is simpler: { // first loop over exact variables and copy into error for (int exactComp=0; exactComp<a_exactVars.size(); ++exactComp) { string thisExactVar = a_exactVars[exactComp]; // check if this exact variable is "the one" if (thisExactVar == thisErrVar) { // copy exact solution -> error Interval exactInterval(exactComp, exactComp); Interval errInterval(nErr, nErr); thisLevelExact.copyTo(exactInterval, thisLevelError, errInterval); done = true; } // end if this exact var is the error var } // end loop over exact comps if (!done) { pout() << "Variable " << thisErrVar << " not found in exact solution!!!" << endl; MayDay::Error(); } done = false; int computedComp = 0; // now loop over computed variables and subtract computed solution while (!done && (computedComp < a_computedVars.size())) { if (a_computedVars[computedComp] == thisErrVar) { for (levelDit.reset(); levelDit.ok(); ++levelDit) { FArrayBox& thisComputed = thisLevelComputed[levelDit()]; FArrayBox& thisError = thisLevelError[levelDit()]; thisError.minus(thisComputed, computedComp, nErr, 1); } // end loop over computed/error grids done = true; } // if a_computedVar is a_errorVar computedComp += 1; } // end loop over a_computedVars if (!done) { pout() << "Variable " << thisErrVar << " not found!!!" << endl; MayDay::Error(); } } // end non-ghost-cell case } // end loop over errors // now need to set covered regions to 0 if (level < numLevels - 1) { // will need to loop over all boxes in finer level, not just // those on this processor... const BoxLayout& finerGrids = a_computedSoln[level + 1]->boxLayout(); LayoutIterator fineLit = finerGrids.layoutIterator(); // outer loop over this level's grids, since there are fewer of them DataIterator levelDit = thisLevelError.dataIterator(); for (levelDit.reset(); levelDit.ok(); ++levelDit) { const Box& coarseBox = levelGrids[levelDit()]; FArrayBox& thisError = thisLevelError[levelDit()]; int numError = thisError.nComp(); for (fineLit.reset(); fineLit.ok(); ++fineLit) { Box fineBox(finerGrids[fineLit()]); // now coarsen box down to this level fineBox.coarsen(a_refRatio[level]); // if coarsened fine box intersects error's box, set // overlap to 0 fineBox &= coarseBox; if (!fineBox.isEmpty()) { thisError.setVal(0.0, fineBox, 0, numError); } } // end loop over finer-level grids } // end loop over this-level grids // this is a good place to update dx as well dxLevel = dxLevel / a_refRatio[level]; } // end if there is a finer level // finally, if we're not doing ghost cells, do an exchange just // to "prettify" the output if (!a_doGhostCells) { thisLevelError.exchange(thisLevelError.interval()); } } // end loop over levels }
int main(int argc, char* argv[]) { #ifdef CH_MPI MPI_Init(&argc, &argv); // setChomboMPIErrorHandler(); MPI_Barrier(Chombo_MPI::comm); // Barrier #1 #endif // ------------------------------------------------ // parse command line and input file // ------------------------------------------------ // infile must be first if (argc < 2) { cerr << " need inputs file" << endl; abort(); } char* in_file = argv[1]; ParmParse pp(argc-2, argv+2, NULL, in_file); #ifdef CH_MPI MPI_Barrier(Chombo_MPI::comm); #endif pout().setf(ios::scientific); pout().precision(4); // set defaults bool isSameSize = false; bool doGhostCells = false; bool doPlots = true; bool isTimeDep = false; bool verbose = false; bool computeRelativeError = false; bool removeMean = false; bool useUnitDomain = false; bool HOaverage = false; // this is the initial value for the error Real bogusValue = 0.0; string exactRoot, computedRoot, errorRoot; Vector<string> errorVars; int numCrseFinish, numCrseStart, crseStep, crseMult, intFieldSize; init(exactRoot, computedRoot, errorRoot, intFieldSize, numCrseStart, errorVars, numCrseFinish, crseStep, crseMult, doPlots, isTimeDep, isSameSize, bogusValue, computeRelativeError, removeMean, doGhostCells, useUnitDomain, HOaverage,verbose); int nStep, exactStep; if (!isTimeDep) { crseStep = 1; numCrseFinish = numCrseStart; } for (nStep = numCrseStart; nStep <= numCrseFinish; nStep += crseStep) { if (verbose) { pout() << "starting step " << nStep << endl; } exactStep = nStep*crseMult; ostrstream exactFile; ostrstream computedFile; ostrstream errorFile; exactFile.fill('0'); computedFile.fill('0'); errorFile.fill('0'); if (isTimeDep) { constructPlotFileName(exactFile, exactRoot, intFieldSize, exactStep); constructPlotFileName(computedFile, computedRoot, intFieldSize, nStep); constructPlotFileName(errorFile, errorRoot, intFieldSize, nStep); } else { // if not time dependent, file roots are really filenames exactFile << exactRoot << ends; computedFile << computedRoot << ends; errorFile << errorRoot << ends; } pout() << "exact Filename = " << exactFile.str() << endl; pout() << "computed Filename = " << computedFile.str() << endl; if (doPlots) { pout() << "error Filename = " << errorFile.str() << endl; } // declare memory Vector<LevelData<FArrayBox>* > exactSoln; Vector<string> exactVars; // exact solution variable names Vector<DisjointBoxLayout> exactGrids; Box exactDomain; Real exactDx, exactDt, exactTime; Vector<int> exactRefRatio; int exactNumLevels; IntVect ghostVect = IntVect::Unit; string exactFileName(exactFile.str()); // get exact solution if (verbose) { pout() << "read exact solution..." << endl; } ReadAMRHierarchyHDF5(exactFileName, exactGrids, exactSoln, exactVars, exactDomain, exactDx, exactDt, exactTime, exactRefRatio, exactNumLevels); if (verbose) { pout () << "done reading exact soln" << endl; } // we assume that exact soln is single-grid if we're doing averaging if (!isSameSize) { CH_assert(exactNumLevels == 1); } Vector<LevelData<FArrayBox>* > computedSoln; Vector<string> computedVars; // computed soln variable names Vector<DisjointBoxLayout> computedGrids; Box computedDomain; Real computedDx, computedDt, computedTime; Vector<int> computedRefRatio; int computedNumLevels; string computedFileName(computedFile.str()); //ghostVect = IntVect::Zero; // now read in computed solution if (verbose) { pout() << "read computed solution..." << endl; } ReadAMRHierarchyHDF5(computedFileName, computedGrids, computedSoln, computedVars, computedDomain, computedDx, computedDt, computedTime, computedRefRatio, computedNumLevels); if (verbose) { pout() << "done reading computed solution" << endl; } // reality check if ((computedDomain != exactDomain) && isSameSize) { MayDay::Error("Incompatible exact and computed domains for sameSize comparison"); } int numExact = exactVars.size(); int numComputed = computedVars.size(); int numError = errorVars.size(); // If no errorVars were specified if (numError == 0) { // Set errorVars to the intersection of exactVars and computedVars // This numVars^2 method should be changed to something more efficient for (int iExact = 0; iExact < numExact; iExact++) { for (int iComp = 0; iComp < numComputed; iComp++) { if (exactVars[iExact] == computedVars[iComp]) { errorVars.push_back(exactVars[iExact]); break; } } } numError = errorVars.size(); } else { // if errorVars were specified, then do a quick check that // they're present in both exactVars and computedVars for (int errVarNo = 0; errVarNo<errorVars.size(); ++errVarNo) { bool foundComputed = false; for (int i=0; i<numComputed; i++) { if (errorVars[errVarNo] == computedVars[i]) { foundComputed = true; } } // end loop over exact variables if (!foundComputed) { pout() << "errorVar " << errorVars[errVarNo] << " not found in computed solution!" << endl; MayDay::Error(); } bool foundExact = false; for (int i=0; i<numExact; i++) { if (errorVars[errVarNo] == exactVars[i]) { foundExact = true; } } // end loop over exact variables if (!foundExact) { pout() << "errorVar " << errorVars[errVarNo] << " not found in exact solution!" << endl; MayDay::Error(); } } // end loop over errorVars } // end if errorVars was specified in the inputs file Vector<string> errorNames; errorNames.resize(numError); constructErrorNames(errorNames, errorVars); Vector<LevelData<FArrayBox>* > error(computedNumLevels); // allocate error -- same domain as computed solution for (int level = 0; level < computedNumLevels; level++) { error[level] = new LevelData<FArrayBox>(computedGrids[level], numError, ghostVect); } if (!isSameSize) { if (verbose) { pout () << "compute AMR error..." << endl; } computeAMRError(error, errorVars, computedSoln, computedVars, computedGrids, computedDx, computedRefRatio, exactSoln, exactVars, exactDx, bogusValue, HOaverage, computeRelativeError); if (verbose) { pout() << "done computing AMR error" << endl; } } else { // first make sure refRatios are the same for (int lev = 0; lev < computedRefRatio.size() - 1; lev++) { CH_assert(computedRefRatio[lev] == exactRefRatio[lev]); } CH_assert(exactDx == computedDx); if (verbose) { pout () << "compute sameSize error..." << endl; } computeSameSizeError(error, errorVars, computedSoln, computedVars, computedGrids, computedDx, computedRefRatio, exactSoln, exactVars, bogusValue, computeRelativeError, doGhostCells); if (verbose) { pout() << "done computing sameSize error" << endl; } } Vector<Real> mean(numError); // remove mean if (removeMean) { int lBase = 0; int numLevels = error.size(); for (int err = 0; err < numError; err++) { Interval errComps(err, err); if (verbose) { pout() << "compute mean for component " << err << endl; } Real volume; mean[err] = computeSum(volume, error, computedRefRatio, computedDx, errComps, lBase); mean[err] /= volume; if (verbose) { pout() << "comp = " << err << ", mean = " << mean << ", vol = " << volume << endl; } for (int level = 0; level < numLevels; level++) { LevelData<FArrayBox>& thisLevelError = *error[level]; const DisjointBoxLayout levelGrids = error[level]->getBoxes(); DataIterator dit = levelGrids.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { const Box thisBox = levelGrids[dit()]; FArrayBox& thisFabError = thisLevelError[dit()]; thisFabError.plus(-mean[err],err); } // end loop over errors thisLevelError.exchange(); } // end loop over levels } // end loop over errors } // now compute norms pout() << "error, step " << nStep << ": L1, L2, Max, sum" << endl; for (int err = 0; err < numError; err++) { Interval errComps(err, err); Real L0, L1, L2, sum; if (verbose) { pout() << "compute error for component " << err << endl; } int lBase = 0; int normType = 0; Real normDx = computedDx; if (useUnitDomain) { normDx = 1.0/computedDomain.size(0); } L0 = computeNorm(error, computedRefRatio, normDx, errComps, normType, lBase); normType = 1; L1 = computeNorm(error, computedRefRatio, normDx, errComps, normType, lBase); normType = 2; L2 = computeNorm(error, computedRefRatio, normDx, errComps, normType, lBase); sum = computeSum(error, computedRefRatio, normDx, errComps, lBase); pout() << errorNames[err] << ": " << L1 << ", " << L2 << ", " << L0 << ", " << sum; if (removeMean) { pout() << " (" << mean[err] << ")"; } pout() << endl; } // end loop over errors if (doPlots) { if (verbose) { pout() << "begin writing hdf5 file..." << endl; } WriteAMRHierarchyHDF5(errorFile.str(), computedGrids, error, errorNames, computedDomain, computedDx, computedDt, computedTime, computedRefRatio, computedNumLevels); if (verbose) { pout() << "done writing hdf5 file" << endl; } } // clean up memory for (int level = 0; level < exactNumLevels; level++) { if (exactSoln[level] != NULL) { delete exactSoln[level]; exactSoln[level] = NULL; } } for (int level = 0; level < computedNumLevels; level++) { if (computedSoln[level] != NULL) { delete computedSoln[level]; computedSoln[level] = NULL; } if (error[level] != NULL) { delete error[level]; error[level] = NULL; } } } // end loop over timesteps #ifdef CH_MPI dumpmemoryatexit(); MPI_Finalize(); #endif } // end main
int checkEBISL(const EBISLayout& a_ebisl, const DisjointBoxLayout& a_grids, const Box& a_domain, const Real& a_dx, const RealVect& a_origin, const Real& a_radius, const RealVect& a_center, const bool& a_insideRegular) { //check to see that the sum of the volume fractions //comes to close to exactly the total volume int eekflag = 0; //First: calculate volume of domain const IntVect& ivSize = a_domain.size(); RealVect hiCorn; RealVect domLen; Real cellVolume = 1.0; Real totalVolume = 1.0; for (int idir = 0; idir < SpaceDim; idir++) { hiCorn[idir] = a_origin[idir] + a_dx*Real(ivSize[idir]); cellVolume *= a_dx; domLen[idir] = hiCorn[idir] - a_origin[idir]; totalVolume *= domLen[idir]; } // Calculate the exact volume of the regular region Real volExact; Real volError; Real bndryExact; Real bndryError; if (SpaceDim == 2) { volExact = acos(-1.0) * a_radius*a_radius; volError = 0.0001851; bndryExact = 2*acos(-1.0) * a_radius; bndryError = 0.000047; } if (SpaceDim == 3) { volExact = 4.0/3.0 * acos(-1.0) * a_radius*a_radius*a_radius; volError = 0.000585; bndryExact = 4.0 * acos(-1.0) * a_radius*a_radius; bndryError = 0.000287; } if (a_insideRegular == false) { volExact = totalVolume - volExact; } // Now calculate the volume of approximate sphere Real tolerance = 0.001; Real volTotal = 0.0; Real bndryTotal = 0.0; for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { const EBISBox& ebisBox = a_ebisl[dit()]; for (BoxIterator bit(a_grids.get(dit())); bit.ok(); ++bit) { const IntVect& iv = bit(); Vector<VolIndex> vofs = ebisBox.getVoFs(iv); if (vofs.size() > 1) { eekflag = 2; return eekflag; } for (int ivof = 0; ivof < vofs.size(); ivof++) { Real volFrac = ebisBox.volFrac(vofs[ivof]); if (ebisBox.isIrregular(iv)) { pout() << "iv = " << iv << ", volFrac = " << volFrac << endl; } volTotal += volFrac * cellVolume; Real bndryArea = ebisBox.bndryArea(vofs[ivof]); bndryTotal += bndryArea * cellVolume / a_dx; if (volFrac > tolerance && volFrac < 1.0 - tolerance) { if (!ebisBox.isIrregular(iv)) { eekflag = 4; return eekflag; } } } } } #ifdef CH_MPI Real t=volTotal; MPI_Allreduce ( &t, &volTotal, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); t=bndryTotal; MPI_Allreduce ( &t, &bndryTotal, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); #endif //check how close is the answer pout() << endl; Real error; error = volTotal - volExact; if (Abs(error/volExact) > volError) { eekflag = 5; } pout() << "volTotal = " << volTotal << endl; pout() << "volExact = " << volExact << endl; pout() << "error = " << error << endl; pout() << "relError = " << Abs(error/volExact) << endl; pout() << "tolerance = " << volError << endl; pout() << endl; error = bndryTotal - bndryExact; if (Abs(error/bndryExact) > bndryError) { eekflag = 6; } pout() << "bndryTotal = " << bndryTotal << endl; pout() << "bndryExact = " << bndryExact << endl; pout() << "error = " << error << endl; pout() << "relError = " << Abs(error/bndryExact) << endl; pout() << "tolerance = " << bndryError << endl; pout() << endl; return eekflag; }
// --------------------------------------------------------- void NodeQCFI::define(const DisjointBoxLayout& a_grids, Real a_dx, const ProblemDomain& a_domain, const LayoutData<NodeCFIVS>* const a_loCFIVS, const LayoutData<NodeCFIVS>* const a_hiCFIVS, int a_refToCoarse, NodeBCFunc a_bc, int a_interpolationDegree, int a_ncomp, bool a_verbose) { CH_assert(a_refToCoarse >= 2); m_bc = a_bc; m_grids = a_grids; m_dx = a_dx; m_verbose = a_verbose; // m_coarsenings == log2(a_refToCoarse); m_coarsenings = 0; for (int interRatio = a_refToCoarse; interRatio >= 2; interRatio /= 2) m_coarsenings++; m_qcfi2.resize(m_coarsenings); m_inter.resize(m_coarsenings-1); m_loCFIVScoarser.resize(m_coarsenings-1); m_hiCFIVScoarser.resize(m_coarsenings-1); // for i=1:m_c-2, m_qcfi2[i] interpolates m_inter[i] from m_inter[i-1]. if (m_coarsenings == 1) { m_qcfi2[0] = new NodeQuadCFInterp2(a_grids, a_domain, a_loCFIVS, a_hiCFIVS, false, a_interpolationDegree, a_ncomp); } else { // if m_coarsenings == 2: // m_qcfi2[1] = new NodeQuadCFInterp2(a_grids, true); // m_qcfi2[0] = new NodeQuadCFInterp2(a_grids.coarsen(2), false); // m_inter[0] = new LevelData(a_grids.coarsen(2)); ProblemDomain domainLevel(a_domain); Real dxLevel = m_dx; DisjointBoxLayout gridsInterFine(a_grids); DisjointBoxLayout gridsInterCoarse; // m_qcfi2[m_coarsenings-1] interpolates from a 2-coarsening of // the fine grids onto the fine grids (a_grids). // Interpolation is from the interface only. m_qcfi2[m_coarsenings-1] = new NodeQuadCFInterp2(a_grids, domainLevel, a_loCFIVS, a_hiCFIVS, true, a_interpolationDegree, a_ncomp); for (int interlev = m_coarsenings - 2; interlev >= 0; interlev--) { // m_coarsenings >= 2, so this will be executed at least once. coarsen(gridsInterCoarse, gridsInterFine, 2); domainLevel.coarsen(2); dxLevel *= 2.; bool interfaceOnly = (interlev > 0); // m_qcfi2[interlev] interpolates from some coarsening of // the fine grids onto gridsInterCoarse. // Except for the first time (interlev == 0), // interpolation is from the interface only. // Define objects containing the nodes of the coarse/fine interfaces. m_loCFIVScoarser[interlev] = new LayoutData<NodeCFIVS>[SpaceDim]; m_hiCFIVScoarser[interlev] = new LayoutData<NodeCFIVS>[SpaceDim]; for (int idir = 0; idir < SpaceDim; idir++) { LayoutData<NodeCFIVS>& loCFIVS = m_loCFIVScoarser[interlev][idir]; LayoutData<NodeCFIVS>& hiCFIVS = m_hiCFIVScoarser[interlev][idir]; loCFIVS.define(gridsInterCoarse); hiCFIVS.define(gridsInterCoarse); for (DataIterator dit = gridsInterCoarse.dataIterator(); dit.ok(); ++dit) { const Box& bx = gridsInterCoarse.get(dit()); loCFIVS[dit()].define(domainLevel, bx, gridsInterCoarse, idir, Side::Lo); hiCFIVS[dit()].define(domainLevel, bx, gridsInterCoarse, idir, Side::Hi); } } m_qcfi2[interlev] = new NodeQuadCFInterp2(gridsInterCoarse, domainLevel, m_loCFIVScoarser[interlev], m_hiCFIVScoarser[interlev], interfaceOnly, a_interpolationDegree, a_ncomp); m_inter[interlev] = new LevelData<NodeFArrayBox>(gridsInterCoarse, a_ncomp, IntVect::Zero); gridsInterFine = gridsInterCoarse; } m_domainPenultimate = domainLevel; m_dxPenultimate = dxLevel; } m_ncomp = a_ncomp; m_isDefined = true; }
void LevelFluxRegisterEdge::refluxCurl(LevelData<FluxBox>& a_uCoarse, Real a_scale) { CH_assert(isDefined()); CH_assert(a_uCoarse.nComp() == m_nComp); SideIterator side; // idir is the normal direction to the coarse-fine interface for (int idir=0 ; idir<SpaceDim; ++idir) { for (side.begin(); side.ok(); ++side) { LevelData<FluxBox>& fineReg = m_fabFine[index(idir, side())]; // first, create temp LevelData<FluxBox> to hold "coarse flux" const DisjointBoxLayout coarseBoxes = m_regCoarse.getBoxes(); // this fills the place of what used to be m_fabCoarse in the old // implementation LevelData<FluxBox> coarReg(coarseBoxes, m_nComp, IntVect::Unit); // now fill the coarReg with the curl of the stored coarse-level // edge-centered flux DataIterator crseDit = coarseBoxes.dataIterator(); for (crseDit.begin(); crseDit.ok(); ++crseDit) { FluxBox& thisCoarReg = coarReg[crseDit]; thisCoarReg.setVal(0.0); EdgeDataBox& thisEdgeData = m_regCoarse[crseDit]; for (int edgeDir=0; edgeDir<SpaceDim; edgeDir++) { if (idir != edgeDir) { FArrayBox& crseEdgeDataDir = thisEdgeData[edgeDir]; for (int faceDir = 0; faceDir<SpaceDim; faceDir++) { if (faceDir != edgeDir) { FArrayBox& faceData = thisCoarReg[faceDir]; int shiftDir = -1; for (int i=0; i<SpaceDim; i++) { if ((i != faceDir) && (i != edgeDir) ) { shiftDir = i; } } CH_assert(shiftDir >= 0); crseEdgeDataDir.shiftHalf(shiftDir, sign(side())); // scaling already taken care of in incrementCrse Real scale = 1.0; faceData.plus(crseEdgeDataDir, scale, 0, 0, faceData.nComp()); crseEdgeDataDir.shiftHalf(shiftDir, -sign(side())); } // end if not normal direction } // end loop over face directions } // end if edgeDir != idir } // end loop over edge directions } // end loop over crse boxes // first, we need to create a temp LevelData<FluxBox> // to make a local copy in the coarse layout space of // the fine register increments LevelData<FluxBox> fineRegLocal(coarReg.getBoxes(), m_nComp, IntVect::Unit); fineReg.copyTo(fineReg.interval(), fineRegLocal, fineRegLocal.interval(), m_crseCopiers[index(idir,side())]); for (DataIterator it = a_uCoarse.dataIterator(); it.ok(); ++it) { // loop over flux components here for (int fluxComp=0; fluxComp < SpaceDim; fluxComp++) { // we don't do anything in the normal direction if (fluxComp != idir) { // fluxDir is the direction of the face-centered flux FArrayBox& U = a_uCoarse[it()][fluxComp]; // set up IntVectSet to avoid double counting of updates Box coarseGridBox = U.box(); // transfer to Cell-centered, then create IVS coarseGridBox.shiftHalf(fluxComp,1); IntVectSet nonUpdatedEdges(coarseGridBox); // remember, we want to take the curl here // also recall that fluxComp is the component // of the face-centered curl (not the edge-centered // vector field that we're refluxing, which is why // the sign may seem like it's the opposite of what // you might expect! Real local_scale = -sign(side())*a_scale; //int testDir = (fluxComp+1)%(SpaceDim); if (((fluxComp+1)%(SpaceDim)) == idir) local_scale *= -1; Vector<IntVectSet>& ivsV = m_refluxLocations[index(idir, side())][it()][fluxComp]; Vector<DataIndex>& indexV = m_coarToCoarMap[index(idir, side())][it()]; IVSIterator iv; for (int i=0; i<ivsV.size(); ++i) { iv.define(ivsV[i]); const FArrayBox& coar = coarReg[indexV[i]][fluxComp]; const FArrayBox& fine = fineRegLocal[indexV[i]][fluxComp]; for (iv.begin(); iv.ok(); ++iv) { IntVect thisIV = iv(); if (nonUpdatedEdges.contains(thisIV)) { for (int comp=0; comp <m_nComp; ++comp) { //Real coarVal = coar(thisIV, comp); //Real fineVal = fine(thisIV, comp); U(thisIV, comp) -= local_scale*(coar(thisIV, comp) +fine(thisIV, comp)); } nonUpdatedEdges -= thisIV; } } } } // end if not normal face } // end loop over fluxbox directions } // end loop over coarse boxes } // end loop over sides } // end loop over directions }
void MappedLevelFluxRegister::define(const DisjointBoxLayout& a_dbl, const DisjointBoxLayout& a_dblCoarse, const ProblemDomain& a_dProblem, const IntVect& a_nRefine, int a_nComp, bool a_scaleFineFluxes) { CH_TIME("MappedLevelFluxRegister::define"); m_isDefined = FluxRegDefined; // Basically, define was called m_nRefine = a_nRefine; m_scaleFineFluxes = a_scaleFineFluxes; DisjointBoxLayout coarsenedFine; coarsen(coarsenedFine, a_dbl, a_nRefine); #ifndef DISABLE_TEMPORARY_FLUX_REGISTER_OPTIMIZATION // This doesn't work for multi-block calculations, which are // not properly nested. -JNJ //begin temporary optimization. bvs int numPts = 0; for (LayoutIterator lit = a_dblCoarse.layoutIterator(); lit.ok(); ++lit) { numPts += a_dblCoarse[lit].numPts(); } for (LayoutIterator lit = coarsenedFine.layoutIterator(); lit.ok(); ++lit) { numPts -= coarsenedFine[lit].numPts(); } if (numPts == 0) { m_coarFlux.clear(); // OK, fine region completely covers coarse region. no registers. return; } #endif //end temporary optimization. bvs m_coarFlux.define( a_dblCoarse, a_nComp); m_isDefined |= FluxRegCoarseDefined; m_domain = a_dProblem; ProblemDomain coarsenedDomain; coarsen(coarsenedDomain, a_dProblem, a_nRefine); m_fineFlux.define( coarsenedFine, a_nComp, IntVect::Unit); m_isDefined |= FluxRegFineDefined; m_reverseCopier.ghostDefine(coarsenedFine, a_dblCoarse, coarsenedDomain, IntVect::Unit); for (int i = 0; i < CH_SPACEDIM; i++) { m_coarseLocations[i].define(a_dblCoarse); m_coarseLocations[i + CH_SPACEDIM].define(a_dblCoarse); } DataIterator dC = a_dblCoarse.dataIterator(); LayoutIterator dF = coarsenedFine.layoutIterator(); for (dC.begin(); dC.ok(); ++dC) { const Box& cBox = a_dblCoarse.get(dC); for (dF.begin(); dF.ok(); ++dF) { const Box& fBox = coarsenedFine.get(dF); if (fBox.bigEnd(0) + 1 < cBox.smallEnd(0)) { //can skip this box since they cannot intersect, due to sorting } else if (fBox.smallEnd(0) - 1 > cBox.bigEnd(0)) { //skip to end, since all the rest of boxes will not intersect either dF.end(); } else { for (int i = 0; i < CH_SPACEDIM; i++) { Vector<Box>& lo = m_coarseLocations[i][dC]; Vector<Box>& hi = m_coarseLocations[i + CH_SPACEDIM][dC]; Box loBox = adjCellLo(fBox, i, 1); Box hiBox = adjCellHi(fBox, i, 1); if (cBox.intersectsNotEmpty(loBox)) lo.push_back(loBox & cBox); if (cBox.intersectsNotEmpty(hiBox)) hi.push_back(hiBox & cBox); } } } } Box domainBox = coarsenedDomain.domainBox(); if (a_dProblem.isPeriodic()) { Vector<Box> periodicBoxes[2 * CH_SPACEDIM]; for (dF.begin(); dF.ok(); ++dF) { const Box& fBox = coarsenedFine.get(dF); for (int i = 0; i < CH_SPACEDIM; i++) { if (a_dProblem.isPeriodic(i)) { if (fBox.smallEnd(i) == domainBox.smallEnd(i)) periodicBoxes[i].push_back(adjCellLo(fBox, i, 1)); if (fBox.bigEnd(i) == domainBox.bigEnd(i)) periodicBoxes[i + CH_SPACEDIM].push_back(adjCellHi(fBox, i, 1)); } } } for (int i = 0; i < CH_SPACEDIM; i++) { Vector<Box>& loV = periodicBoxes[i]; Vector<Box>& hiV = periodicBoxes[i + CH_SPACEDIM]; int size = domainBox.size(i); for (int j = 0; j < loV.size(); j++) loV[j].shift(i, size); for (int j = 0; j < hiV.size(); j++) hiV[j].shift(i, -size); } for (dC.begin(); dC.ok(); ++dC) { const Box& cBox = a_dblCoarse.get(dC); for (int i = 0; i < CH_SPACEDIM; i++) if (a_dProblem.isPeriodic(i)) { Vector<Box>& loV = periodicBoxes[i]; Vector<Box>& hiV = periodicBoxes[i + CH_SPACEDIM]; if (cBox.smallEnd(i) == domainBox.smallEnd(i) ) { Vector<Box>& hi = m_coarseLocations[i + CH_SPACEDIM][dC]; for (int j = 0; j < hiV.size(); j++) { if (cBox.intersectsNotEmpty(hiV[j])) hi.push_back(cBox & hiV[j]); } } if (cBox.bigEnd(i) == domainBox.bigEnd(i) ) { Vector<Box>& lo = m_coarseLocations[i][dC]; for (int j = 0; j < loV.size(); j++) { if (cBox.intersectsNotEmpty(loV[j])) lo.push_back(cBox & loV[j]); } } } } } }
int getError(LevelData<EBCellFAB>& a_errorFine, const EBISLayout& a_ebislFine, const DisjointBoxLayout& a_gridsFine, const Box& a_domainFine, const Real& a_dxFine) { ParmParse pp; int eekflag = 0; int nvar = 1; int nghost = 2; int nref = 2; int maxsize; pp.get("maxboxsize",maxsize); //generate coarse dx, domain Box domainCoar = coarsen(a_domainFine, nref); Real dxCoar = nref*a_dxFine; //make the coarse grids completely cover the domain Vector<Box> vbox; domainSplit(domainCoar, vbox, maxsize); Vector<int> procAssign; eekflag = LoadBalance(procAssign,vbox); DisjointBoxLayout gridsCoar(vbox, procAssign); //make coarse ebisl EBISLayout ebislCoar; eekflag = makeEBISL(ebislCoar, gridsCoar, domainCoar, nghost); if (eekflag != 0) return eekflag; // pout() << "getError dom coar = " << domainCoar << endl;; // pout() << "getError grids coar = " << gridsCoar << endl;; // pout() << "getError dom fine = " << a_domainFine << endl;; // pout() << "getError grids fine = " << a_gridsFine << endl;; //create data at both refinemenets IntVect ghost = IntVect::Unit; EBCellFactory ebcellfactFine(a_ebislFine); EBCellFactory ebcellfactCoar(ebislCoar); LevelData<EBCellFAB> phiFine(a_gridsFine, nvar, ghost, ebcellfactFine); LevelData<EBCellFAB> oldFine(a_gridsFine, nvar, ghost, ebcellfactFine); LevelData<EBCellFAB> phiCoarOld(gridsCoar, nvar, ghost, ebcellfactCoar); LevelData<EBCellFAB> phiCoarNew(gridsCoar, nvar, ghost, ebcellfactCoar); //fill phi fine and phiCExact //put phiFexact into a_errorFine and phiFine //this should make the error at the interior = 0 for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { Box grownBox = grow(a_gridsFine.get(dit()), 1); grownBox &= a_domainFine; IntVectSet ivsBox(grownBox); phiFine[dit()].setVal(0.0); oldFine[dit()].setVal(0.0); a_errorFine[dit()].setVal(0.0); EBCellFAB& phiFineFAB = phiFine[dit()]; EBCellFAB& oldFineFAB = oldFine[dit()]; EBCellFAB& errFineFAB = a_errorFine[dit()]; phiFineFAB.setCoveredCellVal(0.0,0); oldFineFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, a_ebislFine[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAns = exactFunc(vof.gridIndex(), a_dxFine, g_fineTime); phiFineFAB(vof, 0) = rightAns; oldFineFAB(vof, 0) = rightAns; errFineFAB(vof, 0) = rightAns; } } for (DataIterator dit = gridsCoar.dataIterator(); dit.ok(); ++dit) { Box grownBox = grow(gridsCoar.get(dit()), 1); grownBox &= domainCoar; IntVectSet ivsBox(grownBox); EBCellFAB& phiCoarOldFAB = phiCoarOld[dit()]; EBCellFAB& phiCoarNewFAB = phiCoarNew[dit()]; phiCoarOldFAB.setCoveredCellVal(0.0,0); phiCoarNewFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, ebislCoar[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAnsOld = exactFunc(vof.gridIndex(), dxCoar,g_coarTimeOld); Real rightAnsNew = exactFunc(vof.gridIndex(), dxCoar,g_coarTimeNew); phiCoarOldFAB(vof, 0) = rightAnsOld; phiCoarNewFAB(vof, 0) = rightAnsNew; } } //interpolate phiC onto phiF AggEBPWLFillPatch interpOp(a_gridsFine, gridsCoar, a_ebislFine, ebislCoar, domainCoar, nref, nvar, 1, ghost); //interpolate phiC onto phiF EBPWLFillPatch oldinterpOp(a_gridsFine, gridsCoar, a_ebislFine, ebislCoar, domainCoar, nref, nvar, 1); Interval zeroiv(0,0); interpOp.interpolate(phiFine, phiCoarOld, phiCoarNew, g_coarTimeOld, g_coarTimeNew, g_fineTime, zeroiv); oldinterpOp.interpolate(oldFine, phiCoarOld, phiCoarNew, g_coarTimeOld, g_coarTimeNew, g_fineTime, zeroiv); //error = phiF - phiFExact int ibox = 0; for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit, ++ibox) { Box grownBox = grow(a_gridsFine.get(dit()), 1); grownBox &= a_domainFine; IntVectSet ivsBox(grownBox); EBCellFAB& phiFineFAB = phiFine[dit()]; EBCellFAB& oldFineFAB = oldFine[dit()]; Real maxDiff = 0; VolIndex vofDiff; bool found = false; for (VoFIterator vofit(ivsBox, a_ebislFine[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real diff = Abs(phiFineFAB(vof,0)-oldFineFAB(vof,0)); if (diff > maxDiff) { found = true; vofDiff = vof; maxDiff = diff; } } if (found) { pout() << "max diff = " << maxDiff << endl; pout() << "at intvect = " << vofDiff.gridIndex() << endl; pout() << "at box num = " << ibox << endl; } EBCellFAB& errorFAB = a_errorFine[dit()]; errorFAB -= phiFineFAB; } return eekflag; }
int testIFFAB(const DisjointBoxLayout& a_dbl, const EBISLayout & a_ebisl, const Box & a_domain, const Real & a_dx ) { int faceDir = 0; int nFlux = 1; LayoutData<IntVectSet> irregSetsGrown; LevelData< BaseIFFAB<Real> > fluxInterpolant; EBArith::defineFluxInterpolant(fluxInterpolant, irregSetsGrown, a_dbl, a_ebisl, a_domain, nFlux, faceDir); //set source fab to right ans over set only on grids interior cells int ibox = 0; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()]; srcFab.setVal(-1.0); IntVectSet ivsSmall = irregSetsGrown[dit()]; const Box& grid = a_dbl.get(dit()); ivsSmall &= grid; for (FaceIterator faceit(ivsSmall, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary); faceit.ok(); ++faceit) { srcFab(faceit(), 0) = rightAns(faceit()); } ibox++; } //diagnostics if (g_diagnosticMode) { pout() << " diagnostics for processor " << procID() << endl; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { const IntVectSet& ivsGrown = irregSetsGrown[dit()]; const Box& grid = a_dbl.get(dit()); pout() << "============" << endl; pout() << " box = " << grid; pout() << ", full ivs = " ; dumpIVS(&ivsGrown); pout() << "============" << endl; for (LayoutIterator lit = a_dbl.layoutIterator(); lit.ok(); ++lit) { const Box& grid2 = a_dbl.get(lit()); IntVectSet ivsIntersect = ivsGrown; ivsIntersect &= grid2; pout() << "intersection with box " << grid2 << " = "; dumpIVS(&ivsIntersect); pout() << "============" << endl; } } } BaseIFFAB<Real>::setVerbose(true); //do the evil exchange Interval interv(0, nFlux-1); fluxInterpolant.exchange(interv); ibox = 0; //check the answer over grown set Real tolerance = 0.001; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { const BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()]; const IntVectSet& ivsGrown = irregSetsGrown[dit()]; for (FaceIterator faceit(ivsGrown, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary); faceit.ok(); ++faceit) { Real correct = rightAns(faceit()); Real fabAns = srcFab(faceit(), 0); if (Abs(correct - fabAns) > tolerance) { pout() << "iffab test failed at face " << faceit().gridIndex(Side::Lo) << faceit().gridIndex(Side::Hi) << endl; pout() << " right ans = " << correct << endl; pout() << " data holds= " << fabAns << endl; int eekflag = -3; return eekflag; } } ibox++; } return 0; }
void EBMGInterp:: defineStencils() { CH_TIME("EBMGInterp::defineStencils"); DisjointBoxLayout gridsStenCoar; EBISLayout ebislStenCoar; DisjointBoxLayout gridsStenFine; EBISLayout ebislStenFine; if (m_layoutChanged) { if (m_coarsenable) { gridsStenCoar = m_buffGrids; ebislStenCoar = m_buffEBISL; gridsStenFine = m_fineGrids; ebislStenFine = m_fineEBISL; } else { gridsStenCoar = m_coarGrids; ebislStenCoar = m_coarEBISL; gridsStenFine = m_buffGrids; ebislStenFine = m_buffEBISL; } } else { gridsStenCoar = m_coarGrids; ebislStenCoar = m_coarEBISL; gridsStenFine = m_fineGrids; ebislStenFine = m_fineEBISL; } { CH_TIME("graph walking"); m_interpEBStencil.define(gridsStenCoar); if (m_doLinear) { m_linearEBStencil.define(gridsStenCoar); } for (DataIterator dit = gridsStenCoar.dataIterator(); dit.ok(); ++dit) { const EBISBox& ebisBoxCoar = ebislStenCoar[dit()]; const EBISBox& ebisBoxFine = ebislStenFine[dit()]; const Box& boxFine = gridsStenFine[dit()]; const EBGraph& ebGraphFine = ebisBoxFine.getEBGraph(); const Box& boxCoar = gridsStenCoar[dit()]; IntVectSet notRegularCoar = ebisBoxCoar.getIrregIVS(boxCoar); IntVectSet ivsFine = refine(notRegularCoar, m_refRat); VoFIterator vofItIrregFine(ivsFine, ebGraphFine); const Vector<VolIndex>& allFineVoFs = vofItIrregFine.getVector(); defineConstantStencil(dit(), allFineVoFs, ebislStenFine, ebislStenCoar, boxFine, boxCoar); if (m_doLinear) { defineLinearStencil(dit(), allFineVoFs, ebislStenFine, ebislStenCoar, boxFine, boxCoar); } } } }
int checkEBISL(const EBISLayout& a_ebisl, const DisjointBoxLayout& a_grids, const Box& a_domain, const Real& a_dx, const RealVect& a_origin, const int& a_upDir, const int& a_indepVar, const Real& a_startPt, const Real& a_slope) { //check to see that the sum of the volume fractions //comes to close to exactly the total volume int eekflag = 0; #ifdef CH_USE_FLOAT Real tolerance = 60 * PolyGeom::getTolerance(); #else Real tolerance = PolyGeom::getTolerance(); #endif const IntVect& ivSize= a_domain.size(); RealVect hiCorn; RealVect domLen; Real cellVolume = 1.0; Real totalVolume = 1.0; for (int idir = 0; idir < SpaceDim; idir++) { hiCorn[idir] = a_origin[idir] + a_dx*Real(ivSize[idir]); cellVolume *= a_dx; domLen[idir] = hiCorn[idir] - a_origin[idir]; totalVolume *= domLen[idir]; } //find normal and alpha in the space where the length of //the domain in all directions is unity int iy = a_upDir; int ix = a_indepVar; RealVect normal = RealVect::Zero; normal[iy] = domLen[iy]; normal[ix] = -a_slope*domLen[ix]; Real alpha = a_slope*(a_origin[ix]-a_startPt)-a_origin[iy]; Real volExact = totalVolume*PolyGeom::computeVolume(alpha, normal); RealVect correctNorm = RealVect::Zero; Real sumSquare; correctNorm[a_upDir] = 1.0; correctNorm[a_indepVar] = -a_slope; PolyGeom::unifyVector(correctNorm, sumSquare); // //voltot = sum(cellVolume*volFrac) = numerical domain volume. Real voltot = 0; for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { const EBISBox& ebisBox = a_ebisl[dit()]; for (BoxIterator bit(a_grids.get(dit())); bit.ok(); ++bit) { const IntVect& iv = bit(); Vector<VolIndex> vofs = ebisBox.getVoFs(iv); if (vofs.size() > 1) { eekflag = 2; return eekflag; } for (int ivof = 0; ivof < vofs.size(); ivof++) { Real volFrac = ebisBox.volFrac(vofs[ivof]); voltot += volFrac*cellVolume; if (volFrac > tolerance && volFrac < 1.0-tolerance) { if (!ebisBox.isIrregular(iv)) { eekflag = 4; return eekflag; } RealVect normal= ebisBox.normal(vofs[ivof]); for (int idir = 0; idir < SpaceDim; idir++) { if (Abs(normal[idir] - correctNorm[idir]) > tolerance) { eekflag = 5; return eekflag; } } RealVect centroid= ebisBox.centroid(vofs[ivof]); for (int idir = 0; idir < SpaceDim; idir++) { if (Abs(centroid[idir]) > 0.5) { eekflag = 6; return eekflag; } } } } } } #ifdef CH_MPI Real t=voltot; MPI_Allreduce ( &t, &voltot, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); #endif if (Abs(voltot -volExact) > tolerance) { pout() << Abs(voltot - volExact) << " > " << tolerance << endl; eekflag = 3; return eekflag; } return eekflag; }
int getError(LevelData<EBCellFAB>& a_errorFine, const EBISLayout& a_ebislFine, const DisjointBoxLayout& a_gridsFine, const Box& a_domainFine, const RealVect& a_dxFine) { ParmParse pp; int eekflag = 0; int nvar = 1; int nghost = 1; int nref = 2; pp.get("ref_ratio",nref); int maxsize; pp.get("maxboxsize",maxsize); //generate coarse dx, domain Box domainCoar = coarsen(a_domainFine, nref); RealVect dxCoar = nref*a_dxFine; //make the coarse grids completely cover the domain Vector<Box> vbox; domainSplit(domainCoar, vbox, maxsize); Vector<int> procAssign; eekflag = LoadBalance(procAssign,vbox); DisjointBoxLayout gridsCoar(vbox, procAssign); //make coarse ebisl EBISLayout ebislCoar; eekflag = makeEBISL(ebislCoar, gridsCoar, domainCoar, nghost); if (eekflag != 0) return eekflag; // pout() << "getError dom coar = " << domainCoar << endl;; // pout() << "getError grids coar = " << gridsCoar << endl;; // pout() << "getError dom fine = " << a_domainFine << endl;; // pout() << "getError grids fine = " << a_gridsFine << endl;; //create data at both refinemenets EBCellFactory ebcellfactFine(a_ebislFine); EBCellFactory ebcellfactCoar(ebislCoar); LevelData<EBCellFAB> phiFine(a_gridsFine, nvar, IntVect::Unit,ebcellfactFine); LevelData<EBCellFAB> phiCoar(gridsCoar, nvar, IntVect::Unit,ebcellfactCoar); //fill phi fine and phiCExact //put phiFexact into a_errorFine and phiFine //this should make the error at the interior = 0 for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { Box grownBox = grow(a_gridsFine.get(dit()), 1); grownBox &= a_domainFine; IntVectSet ivsBox(grownBox); phiFine[dit()].setVal(0.0); a_errorFine[dit()].setVal(0.0); EBCellFAB& phiFineFAB = phiFine[dit()]; EBCellFAB& errFineFAB = a_errorFine[dit()]; phiFineFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, a_ebislFine[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAns = exactFunc(vof.gridIndex(), a_dxFine); phiFineFAB(vof, 0) = rightAns; errFineFAB(vof, 0) = rightAns; } } for (DataIterator dit = gridsCoar.dataIterator(); dit.ok(); ++dit) { Box grownBox = grow(gridsCoar.get(dit()), 1); grownBox &= domainCoar; IntVectSet ivsBox(grownBox); EBCellFAB& phiCoarFAB = phiCoar[dit()]; phiCoarFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, ebislCoar[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAns = exactFunc(vof.gridIndex(), dxCoar); phiCoarFAB(vof, 0) = rightAns; } } LayoutData<IntVectSet> cfivs; EBArith::defineCFIVS(cfivs, a_gridsFine, a_domainFine); EBQuadCFInterp interpOp(a_gridsFine, gridsCoar, a_ebislFine, ebislCoar, domainCoar, nref, nvar, cfivs, Chombo_EBIS::instance(), true); Interval interv(0,0); interpOp.interpolate(phiFine, phiCoar, interv); //error = phiF - phiFExact for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { EBCellFAB& errorFAB = a_errorFine[dit()]; EBCellFAB& phiFineFAB = phiFine[dit()]; errorFAB -= phiFineFAB; } return eekflag; }