void setBorkedFlux(EBFluxFAB& a_flux, const EBISBox& a_ebisBox, const Box& a_box, const RealVect& a_fluxVal, const BaseFab<int>& a_map) { for (int idir = 0; idir < SpaceDim; idir++) { Real bogval = 0; //the bogus value will be zero so it will not //do to have the correct value be zero if (Abs(a_fluxVal[idir]) < 1.0e-3) bogval = 1.0; a_flux[idir].setVal(a_fluxVal[idir]); //if i am in a 1d box and the box next to me //is 2d, set the border flux to for (SideIterator sit; sit.ok(); ++sit) { Box borderBox; if (sit() == Side::Lo) { borderBox = adjCellLo(a_box, idir, -1); } else { borderBox = adjCellHi(a_box, idir, -1); } for (BoxIterator bit(borderBox); bit.ok(); ++bit) { const IntVect& thisIV = bit(); IntVect thatIV = thisIV + sign(sit())*BASISV(idir); if ((a_map(thisIV, 0) == 1) && (a_map(thatIV, 0) == 2)) { Vector<FaceIndex> faces = a_ebisBox.getAllFaces(thisIV, idir, sit()); for (int iface = 0; iface < faces.size(); iface++) { a_flux[idir](faces[iface],0) = bogval; } } } } } }
void CFStencil::define( const ProblemDomain& a_fineDomain, const Box& a_grid, const Vector<Box>& a_periodicVector, 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()) return; int w1 = edgebox.smallEnd()[0]; int w2 = edgebox.bigEnd()[0]; m_fineIVS.define(edgebox); // moving window loop in i-direction (bvs) for (int i=0; i<a_periodicVector.size(); ++i) { const Box& b = a_periodicVector[i]; if (b.bigEnd()[0] >= w1) { m_fineIVS -= b; if (b.smallEnd()[0] > w2) { i=a_periodicVector.size(); } } } //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 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]); } } } } } }
void MappedLevelFluxRegister::incrementFine(const FArrayBox& a_fineFlux, Real a_scale, const DataIndex& a_fineDataIndex, const Interval& a_srcInterval, const Interval& a_dstInterval, int a_dir, Side::LoHiSide a_sd) { CH_assert(isDefined()); if (!(m_isDefined & FluxRegFineDefined)) return; CH_assert(a_srcInterval.size() == a_dstInterval.size()); CH_TIME("MappedLevelFluxRegister::incrementFine"); // We cast away the constness in a_coarseFlux for the scope of this function. This // should be acceptable, since at the end of the day there is no change to it. -JNJ FArrayBox& fineFlux = const_cast<FArrayBox&>(a_fineFlux); // Muhahaha. fineFlux.shiftHalf(a_dir, sign(a_sd)); Real denom = 1.0; if (m_scaleFineFluxes) { denom = m_nRefine.product() / m_nRefine[a_dir]; } Real scale = sign(a_sd) * a_scale / denom; FArrayBox& cFine = m_fineFlux[a_fineDataIndex]; // FArrayBox cFineFortran(cFine.box(), cFine.nComp()); // cFineFortran.copy(cFine); Box clipBox = m_fineFlux.box(a_fineDataIndex); clipBox.refine(m_nRefine); Box fineBox; if (a_sd == Side::Lo) { fineBox = adjCellLo(clipBox, a_dir, 1); fineBox &= fineFlux.box(); } else { fineBox = adjCellHi(clipBox, a_dir, 1); fineBox &= fineFlux.box(); } #if 0 for (BoxIterator b(fineBox); b.ok(); ++b) { int s = a_srcInterval.begin(); int d = a_dstInterval.begin(); for (; s <= a_srcInterval.end(); ++s, ++d) { cFine(coarsen(b(), m_nRefine), d) += scale * fineFlux(b(), s); } } #else // shifting to ensure fineBox is in the positive quadrant, so IntVect coarening // is just integer division. const Box& box = coarsen(fineBox, m_nRefine); Vector<Real> regbefore(cFine.nComp()); Vector<Real> regafter(cFine.nComp()); if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) { for (int ivar = 0; ivar < cFine.nComp(); ivar++) { regbefore[ivar] = cFine(ivdebnoeb, ivar); } } const IntVect& iv = fineBox.smallEnd(); IntVect civ = coarsen(iv, m_nRefine); int srcComp = a_srcInterval.begin(); int destComp = a_dstInterval.begin(); int ncomp = a_srcInterval.size(); FORT_MAPPEDINCREMENTFINE(CHF_CONST_FRA_SHIFT(fineFlux, iv), CHF_FRA_SHIFT(cFine, civ), CHF_BOX_SHIFT(fineBox, iv), CHF_CONST_INTVECT(m_nRefine), CHF_CONST_REAL(scale), CHF_CONST_INT(srcComp), CHF_CONST_INT(destComp), CHF_CONST_INT(ncomp)); if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) { for (int ivar = 0; ivar < cFine.nComp(); ivar++) { regafter[ivar] = cFine(ivdebnoeb, ivar); } } if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) { pout() << "levelfluxreg::incrementFine: scale = " << scale << endl; Box refbox(ivdebnoeb, ivdebnoeb); refbox.refine(m_nRefine); refbox &= fineBox; if (!refbox.isEmpty()) { pout() << "fine fluxes = " << endl; for (BoxIterator bit(refbox); bit.ok(); ++bit) { for (int ivar = 0; ivar < cFine.nComp(); ivar++) { pout() << "iv = " << bit() << "("; for (int ivar = 0; ivar < cFine.nComp(); ivar++) { pout() << fineFlux(bit(), ivar); } pout() << ")" << endl; } } } for (int ivar = 0; ivar < cFine.nComp(); ivar++) { pout() << " reg before = " << regbefore[ivar] << ", "; pout() << " reg after = " << regafter[ivar] << ", "; } pout() << endl; } //fineBox.shift(-shift); // now, check that cFineFortran and cFine are the same //fineBox.coarsen(m_nRefine); // for (BoxIterator b(fineBox); b.ok(); ++b) // { // if (cFineFortran(b(),0) != cFine(b(),0)) // { // MayDay::Error("Fortran doesn't match C++"); // } // } // need to shift boxes back to where they were on entry. // cFine.shift(-shift/m_nRefine); #endif fineFlux.shiftHalf(a_dir, - sign(a_sd)); }
// 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 VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_phi, LevelData<FArrayBox>& a_residual, AMRLevelOp<LevelData<FArrayBox> >* a_finerOp) { CH_TIME("VCAMRPoissonOp2::reflux"); int ncomp = 1; ProblemDomain fineDomain = refine(m_domain, m_refToFiner); LevelFluxRegister levfluxreg(a_phiFine.disjointBoxLayout(), a_phi.disjointBoxLayout(), fineDomain, m_refToFiner, ncomp); levfluxreg.setToZero(); Interval interv(0,a_phi.nComp()-1); DataIterator dit = a_phi.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { const FArrayBox& coarfab = a_phi[dit]; const FluxBox& coarBCoef = (*m_bCoef)[dit]; const Box& gridBox = a_phi.getBoxes()[dit]; for (int idir = 0; idir < SpaceDim; idir++) { FArrayBox coarflux; Box faceBox = surroundingNodes(gridBox, idir); getFlux(coarflux, coarfab, coarBCoef , faceBox, idir); Real scale = 1.0; levfluxreg.incrementCoarse(coarflux, scale,dit(), interv,interv,idir); } } LevelData<FArrayBox>& p = ( LevelData<FArrayBox>&)a_phiFine; // has to be its own object because the finer operator // owns an interpolator and we have no way of getting to it VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp; QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser; quadCFI.coarseFineInterp(p, a_phi); // p.exchange(a_phiFine.interval()); // BVS is pretty sure this is not necesary. IntVect phiGhost = p.ghostVect(); DataIterator ditf = a_phiFine.dataIterator(); const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout(); for (ditf.reset(); ditf.ok(); ++ditf) { const FArrayBox& phifFab = a_phiFine[ditf]; const FluxBox& fineBCoef = (*(finerAMRPOp->m_bCoef))[ditf]; const Box& gridbox = dblFine.get(ditf()); for (int idir = 0; idir < SpaceDim; idir++) { int normalGhost = phiGhost[idir]; SideIterator sit; for (sit.begin(); sit.ok(); sit.next()) { Side::LoHiSide hiorlo = sit(); Box fabbox; Box facebox; // assumption here that the stencil required // to compute the flux in the normal direction // is 2* the number of ghost cells for phi // (which is a reasonable assumption, and probably // better than just assuming you need one cell on // either side of the interface // (dfm 8-4-06) if (sit() == Side::Lo) { fabbox = adjCellLo(gridbox,idir, 2*normalGhost); fabbox.shift(idir, 1); facebox = bdryLo(gridbox, idir,1); } else { fabbox = adjCellHi(gridbox,idir, 2*normalGhost); fabbox.shift(idir, -1); facebox = bdryHi(gridbox, idir, 1); } // just in case we need ghost cells in the transverse direction // (dfm 8-4-06) for (int otherDir=0; otherDir<SpaceDim; ++otherDir) { if (otherDir != idir) { fabbox.grow(otherDir, phiGhost[otherDir]); } } CH_assert(!fabbox.isEmpty()); FArrayBox phifab(fabbox, a_phi.nComp()); phifab.copy(phifFab); FArrayBox fineflux; getFlux(fineflux, phifab, fineBCoef, facebox, idir, m_refToFiner); Real scale = 1.0; levfluxreg.incrementFine(fineflux, scale, ditf(), interv, interv, idir, hiorlo); } } } Real scale = 1.0/m_dx; levfluxreg.reflux(a_residual, scale); }
void oldLoHiCenter(Box& a_loBox, int& a_hasLo, Box& a_hiBox, int& a_hasHi, Box& a_centerBox, Box& a_entireBox, const Box& a_inBox, const ProblemDomain& a_domain, const int& a_dir) { // Make a copy of the input box which can be modified Box inBox = a_inBox; inBox &= a_domain; // The centered difference box is always one smaller in a_dir a_centerBox = inBox; a_centerBox.grow(a_dir,-1); // The union of all the output boxes start off equal to the center // difference portion on the input box (intersected with the domain) a_entireBox = a_centerBox; // See if this chops off the high side of the input box Box tmp = a_inBox; tmp.shift(a_dir,-1); tmp &= a_domain; tmp.shift(a_dir,1); // If so, set up the high, one-sided difference box, a_hiBox, and expand // the entire box to include it if (!a_domain.contains(tmp)) { a_hasHi = 1; tmp.shift(a_dir,-2); a_hiBox = adjCellHi(tmp,a_dir); a_entireBox.growHi(a_dir,1); } else { a_hasHi = 0; a_hiBox = Box(); } // See if this chops off the low side of the input box tmp = a_inBox; tmp.shift(a_dir,1); tmp &= a_domain; tmp.shift(a_dir,-1); // If so, set up the low, one-sided difference box, a_loBox, and expand // the entire box to include it if (!a_domain.contains(tmp)) { a_hasLo = 1; tmp.shift(a_dir,2); a_loBox = adjCellLo(tmp,a_dir); a_entireBox.growLo(a_dir,1); } else { a_hasLo = 0; a_loBox = Box(); } // Make some simple sanity checks CH_assert(a_entireBox.contains(a_centerBox)); if (a_hasLo == 1) { CH_assert(a_entireBox.contains(a_loBox)); } if (a_hasHi == 1) { CH_assert(a_entireBox.contains(a_hiBox)); } }
void EBPoissonOp:: defineStencils() { CH_TIMERS("EBPoissonOp::defineStencils"); CH_TIMER("opStencil_define", t1); CH_TIMER("colorStencil_define", t2); // define ebstencil for irregular applyOp m_opEBStencil.define(m_eblg.getDBL()); // create vofstencils for applyOp LayoutData<BaseIVFAB<VoFStencil> > opStencil; opStencil.define(m_eblg.getDBL()); //define bc stencils and create flux stencil m_ebBC->define((*m_eblg.getCFIVS()), m_dxScale*m_beta); LayoutData<BaseIVFAB<VoFStencil> >* fluxStencil = m_ebBC->getFluxStencil(0); //create and define colored stencils (2 parts) LayoutData<BaseIVFAB<VoFStencil> > colorStencil; colorStencil.define(m_eblg.getDBL()); LayoutData<BaseIVFAB<VoFStencil> > rhsColorStencil; rhsColorStencil.define(m_eblg.getDBL()); m_alphaDiagWeight.define( m_eblg.getDBL()); m_betaDiagWeight.define( m_eblg.getDBL()); m_vofItIrreg.define( m_eblg.getDBL()); // vofiterator cache Box domainBox = m_eblg.getDomain().domainBox(); Box sideBoxLo[SpaceDim]; Box sideBoxHi[SpaceDim]; for (int idir = 0; idir < SpaceDim; idir++) { sideBoxLo[idir] = adjCellLo(domainBox, idir, 1); sideBoxLo[idir].shift(idir, 1); sideBoxHi[idir] = adjCellHi(domainBox, idir, 1); sideBoxHi[idir].shift(idir, -1); m_vofItIrregDomLo[idir].define( m_eblg.getDBL()); // vofiterator cache for domain lo m_vofItIrregDomHi[idir].define( m_eblg.getDBL()); // vofiterator cache for domain hi } CH_START(t1); for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit) { const Box& curBox = m_eblg.getDBL().get(dit()); const EBISBox& curEBISBox = m_eblg.getEBISL()[dit()]; const EBGraph& curEBGraph = curEBISBox.getEBGraph(); IntVectSet notRegular = curEBISBox.getIrregIVS (curBox); BaseIVFAB<VoFStencil>& curStencilBaseIVFAB = opStencil[dit()]; BaseIVFAB<Real>& alphaWeight = m_alphaDiagWeight[dit()]; BaseIVFAB<Real>& betaWeight = m_betaDiagWeight[dit()]; curStencilBaseIVFAB.define(notRegular,curEBGraph, 1); alphaWeight.define( notRegular,curEBGraph, 1); betaWeight.define( notRegular,curEBGraph, 1); //cache the vofIterators m_vofItIrreg[dit()].define(notRegular,curEBISBox.getEBGraph()); for (int idir = 0; idir < SpaceDim; idir++) { IntVectSet loIrreg = notRegular; IntVectSet hiIrreg = notRegular; loIrreg &= sideBoxLo[idir]; hiIrreg &= sideBoxHi[idir]; m_vofItIrregDomLo[idir][dit()].define(loIrreg,curEBISBox.getEBGraph()); m_vofItIrregDomHi[idir][dit()].define(hiIrreg,curEBISBox.getEBGraph()); } //Operator vofstencil VoFIterator& vofit = m_vofItIrreg[dit()]; for (vofit.reset(); vofit.ok(); ++vofit) { const VolIndex& VoF = vofit(); VoFStencil& curStencil = curStencilBaseIVFAB(VoF,0); getOpVoFStencil(curStencil,curEBISBox,VoF); Real& curAlphaWeight = alphaWeight(VoF,0); Real& curBetaWeight = betaWeight(VoF,0); const Real kappa = curEBISBox.volFrac(VoF); curAlphaWeight = kappa; curBetaWeight = 0.0; for (int i = 0; i < curStencil.size(); i++) { if (curStencil.vof(i) == VoF) { curBetaWeight += curStencil.weight(i); break; } } curStencil *= m_beta; if (m_alpha != 0) { curStencil.add(VoF, kappa*m_alpha); } const IntVect& iv = VoF.gridIndex(); for (int idir = 0; idir < SpaceDim; idir++) { Box loSide = bdryLo(m_eblg.getDomain(),idir); loSide.shiftHalf(idir,1); if (loSide.contains(iv)) { Real faceAreaFrac = 0.0; Vector<FaceIndex> faces = curEBISBox.getFaces(VoF,idir,Side::Lo); for (int i = 0; i < faces.size(); i++) { faceAreaFrac += curEBISBox.areaFrac(faces[i]); } curBetaWeight += -faceAreaFrac * m_invDx2[idir]; } Box hiSide = bdryHi(m_eblg.getDomain(),idir); hiSide.shiftHalf(idir,-1); if (hiSide.contains(iv)) { Real faceAreaFrac = 0.0; Vector<FaceIndex> faces = curEBISBox.getFaces(VoF,idir,Side::Hi); for (int i = 0; i < faces.size(); i++) { faceAreaFrac += curEBISBox.areaFrac(faces[i]); } curBetaWeight += -faceAreaFrac * m_invDx2[idir]; } } if (curBetaWeight == 0.0) { curBetaWeight = -1.0; } if (fluxStencil != NULL) { BaseIVFAB<VoFStencil>& fluxStencilBaseIVFAB = (*fluxStencil)[dit()]; VoFStencil& fluxStencilPt = fluxStencilBaseIVFAB(VoF,0); curStencil += fluxStencilPt; } }//vofit //Operator ebstencil m_opEBStencil[dit()] = RefCountedPtr<EBStencil>(new EBStencil(m_vofItIrreg[dit()].getVector(), opStencil[dit()], m_eblg.getDBL().get(dit()), m_eblg.getEBISL()[dit()], m_ghostCellsPhi, m_ghostCellsRHS)); }//dit CH_STOP(t1); //color vofstencils and ebstencils IntVect color = IntVect::Zero; IntVect limit = IntVect::Unit; color[0]=-1; // Loop over all possibilities (in all dimensions) CH_START(t2); for (int icolor = 0; icolor < m_colors.size(); icolor++) { m_colorEBStencil[icolor].define(m_eblg.getDBL()); m_rhsColorEBStencil[icolor].define(m_eblg.getDBL()); m_vofItIrregColor[icolor].define( m_eblg.getDBL()); for (int idir = 0; idir < SpaceDim; idir++) { m_vofItIrregColorDomLo[icolor][idir].define( m_eblg.getDBL()); m_vofItIrregColorDomHi[icolor][idir].define( m_eblg.getDBL()); } for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit) { IntVectSet ivsColor; const EBISBox& curEBISBox = m_eblg.getEBISL()[dit()]; const EBGraph& curEBGraph = curEBISBox.getEBGraph(); Box dblBox( m_eblg.getDBL().get(dit()) ); BaseIVFAB<VoFStencil>& curStencilBaseIVFAB = opStencil[dit()]; BaseIVFAB<VoFStencil>& colorStencilBaseIVFAB = colorStencil[dit()]; BaseIVFAB<VoFStencil>& rhsColorStencilBaseIVFAB = rhsColorStencil[dit()]; const BaseIVFAB<Real>& curAlphaWeight = m_alphaDiagWeight[dit()]; const BaseIVFAB<Real>& curBetaWeight = m_betaDiagWeight[dit()]; VoFIterator& vofit = m_vofItIrreg[dit()]; int vofOrdinal = 0; for (vofit.reset(); vofit.ok(); ++vofit, ++vofOrdinal) { const VolIndex& vof = vofit(); const IntVect& iv = vof.gridIndex(); bool doThisVoF = true; for (int idir = 0; idir < SpaceDim; idir++) { if (iv[idir] % 2 != color[idir]) { doThisVoF = false; break; } } if (doThisVoF) { ivsColor |= iv; } } m_vofItIrregColor[icolor][dit()].define(ivsColor, curEBGraph); colorStencilBaseIVFAB.define(ivsColor, curEBGraph, 1); rhsColorStencilBaseIVFAB.define(ivsColor, curEBGraph, 1); for (int idir = 0; idir < SpaceDim; idir++) { IntVectSet loIrregColor = ivsColor; IntVectSet hiIrregColor = ivsColor; loIrregColor &= sideBoxLo[idir]; hiIrregColor &= sideBoxHi[idir]; m_vofItIrregColorDomLo[icolor][idir][dit()].define(loIrregColor,curEBISBox.getEBGraph()); m_vofItIrregColorDomHi[icolor][idir][dit()].define(hiIrregColor,curEBISBox.getEBGraph()); } VoFIterator& vofitcolor = m_vofItIrregColor[icolor][dit()]; for (vofitcolor.reset(); vofitcolor.ok(); ++vofitcolor) { const VolIndex& vof = vofitcolor(); VoFStencil& curStencil = curStencilBaseIVFAB(vof,0); VoFStencil& colorStencil = colorStencilBaseIVFAB(vof,0); VoFStencil& rhsColorStencil = rhsColorStencilBaseIVFAB(vof,0); Real weightIrreg = m_alpha*curAlphaWeight(vof,0) + m_beta*curBetaWeight(vof,0); colorStencil = curStencil; colorStencil *= (-1.0/weightIrreg); colorStencil.add(vof, 1.0); rhsColorStencil.add(vof, 1.0/weightIrreg); } Vector<VolIndex> srcVofs = m_vofItIrregColor[icolor][dit()].getVector(); //color ebstencils m_colorEBStencil[icolor][dit()] = RefCountedPtr<EBStencil>(new EBStencil(srcVofs, colorStencil[dit()] , m_eblg.getDBL().get(dit()), m_eblg.getEBISL()[dit()], m_ghostCellsPhi, m_ghostCellsPhi)); m_rhsColorEBStencil[icolor][dit()] = RefCountedPtr<EBStencil>(new EBStencil(srcVofs, rhsColorStencil[dit()] , m_eblg.getDBL().get(dit()) , m_eblg.getEBISL()[dit()], m_ghostCellsRHS, m_ghostCellsPhi)); }//dit }//color CH_STOP(t2); }