void CFStencil::buildPeriodicVector(Vector<Box>& a_periodicVector, const ProblemDomain& a_fineDomain, const DisjointBoxLayout& a_fineBoxes) { Box periodicTestBox(a_fineDomain.domainBox()); if (a_fineDomain.isPeriodic()) { for (int idir=0; idir<SpaceDim; idir++) { if (a_fineDomain.isPeriodic(idir)) { periodicTestBox.grow(idir,-1); } } } a_periodicVector.clear(); a_periodicVector.reserve(a_fineBoxes.size()); LayoutIterator lit = a_fineBoxes.layoutIterator(); for (lit.reset(); lit.ok(); ++lit) { const Box& box = a_fineBoxes[lit()]; a_periodicVector.push_back(box); // if periodic, also need to add periodic images // only do this IF we're periodic and box // adjacent to the domain box boundary somewhere if (a_fineDomain.isPeriodic() && !periodicTestBox.contains(box)) { ShiftIterator shiftIt = a_fineDomain.shiftIterator(); IntVect shiftMult(a_fineDomain.domainBox().size()); Box shiftedBox(box); for (shiftIt.begin(); shiftIt.ok(); ++shiftIt) { IntVect shiftVect = shiftMult*shiftIt(); shiftedBox.shift(shiftVect); a_periodicVector.push_back(shiftedBox); shiftedBox.shift(-shiftVect); } // end loop over periodic shift directions } // end if periodic } a_periodicVector.sort(); }
void CFStencil::define( const ProblemDomain& a_fineDomain, const Box& a_grid, const DisjointBoxLayout& a_fineBoxes, const DisjointBoxLayout& a_coarBoxes, int a_refRatio, int a_direction, Side::LoHiSide a_hiorlo) { m_isDefined = true; CH_assert(a_refRatio >= 1); CH_assert(a_direction >= 0); CH_assert(a_direction < SpaceDim); CH_assert((a_hiorlo == Side::Lo) || (a_hiorlo == Side::Hi)); CH_assert(!a_fineDomain.isEmpty()); //set internal vars. most of these are kept around //just to keep the class from having an identity crisis. m_direction = a_direction; m_hiorlo = a_hiorlo; Box finebox = a_grid; //compute intvectset of all points on fine grid that //need to be interpolated //shift direction int hilo = sign(a_hiorlo); //create fine stencil Box edgebox; CH_assert((hilo ==1) || (hilo == -1)); if (hilo == -1) { edgebox = adjCellLo(finebox,m_direction,1); } else { edgebox = adjCellHi(finebox,m_direction,1); } edgebox = a_fineDomain & edgebox; if (!edgebox.isEmpty()) { Box periodicTestBox(a_fineDomain.domainBox()); if (a_fineDomain.isPeriodic()) { for (int idir=0; idir<SpaceDim; idir++) { if (a_fineDomain.isPeriodic(idir)) { periodicTestBox.grow(idir,-1); } } } m_fineIVS.define(edgebox); LayoutIterator lit = a_fineBoxes.layoutIterator(); for (lit.reset(); lit.ok(); ++lit) { m_fineIVS -= a_fineBoxes[lit()]; // if periodic, also need to subtract periodic images // only do this IF we're periodic _and_ both boxes // adjoin the domain box boundary somewhere if (a_fineDomain.isPeriodic() && !periodicTestBox.contains(edgebox) && !periodicTestBox.contains(a_fineBoxes[lit()])) { ShiftIterator shiftIt = a_fineDomain.shiftIterator(); IntVect shiftMult(a_fineDomain.domainBox().size()); Box shiftedBox(a_fineBoxes[lit()]); for (shiftIt.begin(); shiftIt.ok(); ++shiftIt) { IntVect shiftVect = shiftMult*shiftIt(); shiftedBox.shift(shiftVect); m_fineIVS -= shiftedBox; shiftedBox.shift(-shiftVect); } // end loop over periodic shift directions } // end if periodic } } //ivs where all coarse slopes are defined //== coarsened fine ivs m_coarIVS.define(m_fineIVS); m_coarIVS.coarsen(a_refRatio); // this is a trick to get around the lack of a IntVectSet intersection // operator which works with a ProblemDomain ProblemDomain coardom= coarsen(a_fineDomain, a_refRatio); Box domainIntersectBox = m_coarIVS.minBox(); domainIntersectBox = coardom & domainIntersectBox; m_coarIVS &= domainIntersectBox; m_packedBox = m_fineIVS.minBox(); if (m_fineIVS.numPts() == m_packedBox.numPts()) { m_isPacked = true; } else { m_isPacked = false; m_packedBox = Box(); } }
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 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 EBCoarseAverage::define(const DisjointBoxLayout& a_dblFine, const DisjointBoxLayout& a_dblCoar, const EBISLayout& a_ebislFine, const EBISLayout& a_ebislCoar, const ProblemDomain& a_domainCoar, const int& a_nref, const int& a_nvar, const EBIndexSpace* ebisPtr) { CH_TIME("EBCoarseAverage::define"); CH_assert(ebisPtr->isDefined()); ProblemDomain domainFine = a_domainCoar; domainFine.refine(a_nref); EBLevelGrid eblgFine; EBLevelGrid eblgCoar = EBLevelGrid(a_dblCoar, a_ebislCoar, a_domainCoar); EBLevelGrid eblgCoFi; //check to see if the input layout is coarsenable. //if so, proceed with ordinary drill //otherwise, see if the layout covers the domain. //if it does, we can use domainsplit if (a_dblFine.coarsenable(a_nref)) { eblgFine = EBLevelGrid(a_dblFine, a_ebislFine, domainFine); m_useFineBuffer = false; } else { Box fineDomBox = refine(a_domainCoar.domainBox(), a_nref); int numPtsDom = fineDomBox.numPts(); //no need for gathers here because the meta data is global int numPtsLayout = 0; for (LayoutIterator lit = a_dblFine.layoutIterator(); lit.ok(); ++lit) { numPtsLayout += a_dblFine.get(lit()).numPts(); } bool coveringDomain = (numPtsDom == numPtsLayout); if (coveringDomain) { m_useFineBuffer = true; int maxBoxSize = 4*a_nref; Vector<Box> boxes; Vector<int> procs; domainSplit(fineDomBox, boxes, maxBoxSize); mortonOrdering(boxes); LoadBalance(procs, boxes); DisjointBoxLayout dblBufFine(boxes, procs); eblgFine = EBLevelGrid(dblBufFine, domainFine, 2, eblgCoar.getEBIS()); } else { pout() << "EBCoarseAverage::input layout is not coarsenable and does not cover the domain--bailing out" << endl; MayDay::Error(); } } coarsen(eblgCoFi, eblgFine, a_nref); define(eblgFine, eblgCoar, eblgCoFi, a_nref, a_nvar); }