void VCAMRPoissonOp2::residualI(LevelData<FArrayBox>& a_lhs, const LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs, bool a_homogeneous) { CH_TIME("VCAMRPoissonOp2::residualI"); LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi; Real dx = m_dx; const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout(); DataIterator dit = phi.dataIterator(); { CH_TIME("VCAMRPoissonOp2::residualIBC"); for (dit.begin(); dit.ok(); ++dit) { m_bc(phi[dit], dbl[dit()],m_domain, dx, a_homogeneous); } } phi.exchange(phi.interval(), m_exchangeCopier); for (dit.begin(); dit.ok(); ++dit) { const Box& region = dbl[dit()]; const FluxBox& thisBCoef = (*m_bCoef)[dit]; #if CH_SPACEDIM == 1 FORT_VCCOMPUTERES1D #elif CH_SPACEDIM == 2 FORT_VCCOMPUTERES2D #elif CH_SPACEDIM == 3 FORT_VCCOMPUTERES3D #else This_will_not_compile! #endif (CHF_FRA(a_lhs[dit]), CHF_CONST_FRA(phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA((*m_aCoef)[dit]), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA(thisBCoef[0]), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA(thisBCoef[1]), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA(thisBCoef[2]), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_BOX(region), CHF_CONST_REAL(m_dx)); } // end loop over boxes }
void EBLevelTransport:: divergeF(LevelData<EBCellFAB>& a_divergeF, LevelData<BaseIVFAB<Real> >& a_massDiff, EBFluxRegister& a_fineFluxRegister, EBFluxRegister& a_coarFluxRegister, LevelData<EBCellFAB>& a_consState, //not really changed LevelData<EBCellFAB>& a_normalVel, const LevelData<EBFluxFAB>& a_advVel, const LayoutData< Vector <BaseIVFAB<Real> * > >& a_coveredAdvVelMinu, const LayoutData< Vector <BaseIVFAB<Real> * > >& a_coveredAdvVelPlus, const LevelData<EBCellFAB>& a_source, const LevelData<EBCellFAB>& a_consStateCoarseOld, const LevelData<EBCellFAB>& a_consStateCoarseNew, const LevelData<EBCellFAB>& a_normalVelCoarseOld, const LevelData<EBCellFAB>& a_normalVelCoarseNew, const Real& a_time, const Real& a_coarTimeOld, const Real& a_coarTimeNew, const Real& a_dt) { Interval consInterv(0, m_nCons-1); Interval fluxInterv(0, m_nFlux-1); CH_assert(isDefined()); CH_assert(a_consState.disjointBoxLayout() == m_thisGrids); //fill a_consState with data interpolated between constate and coarser data fillCons(a_consState, a_normalVel, a_consStateCoarseOld, a_consStateCoarseNew, a_normalVelCoarseOld, a_normalVelCoarseNew, a_time, a_coarTimeOld, a_coarTimeNew); // clear flux registers with fine level //remember this level is the coarse level to the fine FR if(m_hasFiner) { a_fineFluxRegister.setToZero(); } //compute flattening coefficients. this saves a ghost cell. woo hoo. computeFlattening(a_consState, a_time, a_dt); //this includes copying flux into flux interpolant and updating //regular grids and incrementing flux registers. doRegularUpdate(a_divergeF, a_consState, a_normalVel, a_advVel, a_coveredAdvVelMinu, a_coveredAdvVelPlus, a_fineFluxRegister, a_coarFluxRegister, a_source, a_time, a_dt); //this does irregular update and deals with flux registers. //also computes the mass increment doIrregularUpdate(a_divergeF, a_consState, a_fineFluxRegister, a_coarFluxRegister, a_massDiff, a_time, a_dt); }
// 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 VCAMRPoissonOp2::applyOpNoBoundary(LevelData<FArrayBox>& a_lhs, const LevelData<FArrayBox>& a_phi) { CH_TIME("VCAMRPoissonOp2::applyOpNoBoundary"); LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi; const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout(); DataIterator dit = phi.dataIterator(); phi.exchange(phi.interval(), m_exchangeCopier); for (dit.begin(); dit.ok(); ++dit) { const Box& region = dbl[dit()]; const FluxBox& thisBCoef = (*m_bCoef)[dit]; #if CH_SPACEDIM == 1 FORT_VCCOMPUTEOP1D #elif CH_SPACEDIM == 2 FORT_VCCOMPUTEOP2D #elif CH_SPACEDIM == 3 FORT_VCCOMPUTEOP3D #else This_will_not_compile! #endif (CHF_FRA(a_lhs[dit]), CHF_CONST_FRA(phi[dit]), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA((*m_aCoef)[dit]), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA(thisBCoef[0]), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA(thisBCoef[1]), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA(thisBCoef[2]), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_BOX(region), CHF_CONST_REAL(m_dx)); } // end loop over boxes }
void VCAMRPoissonOp2::applyOpI(LevelData<FArrayBox>& a_lhs, const LevelData<FArrayBox>& a_phi, bool a_homogeneous ) { CH_TIME("VCAMRPoissonOp2::applyOpI"); LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi; Real dx = m_dx; const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout(); DataIterator dit = phi.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { m_bc(phi[dit], dbl[dit()],m_domain, dx, a_homogeneous); } applyOpNoBoundary(a_lhs, a_phi); }
// Find the maximum wave speed on the current level Real OldLevelGodunov::getMaxWaveSpeed(const LevelData<FArrayBox>& a_U) { const DisjointBoxLayout& disjointBoxLayout = a_U.disjointBoxLayout(); DataIterator dit = disjointBoxLayout.dataIterator(); // Initial maximum wave speed Real speed = 0.0; // This computation doesn't need involve a time but the time being set // is checked by OldPatchGodunov::getMaxWaveSpeed so we have to set it // to something... m_patchGodunov->setCurrentTime(0.0); // Loop over all grids to get the maximum wave speed for (dit.begin(); dit.ok(); ++dit) { const Box& currentBox = disjointBoxLayout.get(dit()); // Set the current box and get the maximum wave speed on the current grid m_patchGodunov->setCurrentBox(currentBox); Real speedOverBox = m_patchGodunov->getMaxWaveSpeed(a_U[dit()], currentBox); // Compute a running maximum speed = Max(speed,speedOverBox); } // Gather maximum wave speeds and broadcast the maximum over these Vector<Real> allSpeeds; gather(allSpeeds,speed,uniqueProc(SerialTask::compute)); if (procID() == uniqueProc(SerialTask::compute)) { speed = allSpeeds[0]; for (int i = 1; i < allSpeeds.size (); ++i) { speed = Max(speed,allSpeeds[i]); } } broadcast(speed,uniqueProc(SerialTask::compute)); // Return the maximum wave speed return speed; }
void EBMGInterp::fillGhostCellsPWC(LevelData<EBCellFAB>& a_data, const EBISLayout& a_ebisl, const ProblemDomain& a_dom) { for (int idir = 0; idir < SpaceDim; idir++) { if (m_ghost[idir] < 1) { MayDay::Error("EBMGInterp:I need a ghost cell for linear interpolation"); } } //extrapolate to every ghost cell const DisjointBoxLayout& dbl = a_data.disjointBoxLayout(); for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit) { const Box& grid = dbl.get(dit()); const EBGraph& ebgraph = a_ebisl[dit()].getEBGraph(); for (int idir = 0; idir < SpaceDim; idir++) { for (SideIterator sit; sit.ok(); ++sit) { Side::LoHiSide flipSide = flip(sit()); Box ghostBox = adjCellBox(grid, idir, sit(), 1); for (BoxIterator boxit(ghostBox); boxit.ok(); ++boxit) { if (a_dom.contains(boxit())) { Vector<VolIndex> vofs = ebgraph.getVoFs(boxit()); for (int ivof = 0; ivof < vofs.size(); ivof++) { Real extrapVal = 0; Vector<FaceIndex> faces = ebgraph.getFaces(vofs[ivof], idir, flipSide); for (int ivar = 0; ivar < a_data.nComp(); ivar++) { for (int iface = 0; iface < faces.size(); iface++) { const VolIndex& flipVoF = faces[iface].getVoF(flipSide); extrapVal += a_data[dit()](flipVoF, ivar); } if (faces.size() > 1) extrapVal /= faces.size(); a_data[dit()](vofs[ivof], ivar) = extrapVal; } } } else { //just put in the single valued part of the data holder something sensible //if not inside domain int isign = sign(flipSide); BaseFab<Real>& bfdata = a_data[dit()].getSingleValuedFAB(); IntVect otherIV = boxit() + isign*BASISV(idir); for (int ivar = 0; ivar < a_data.nComp(); ivar++) { bfdata(boxit(), ivar) = bfdata(otherIV, ivar); } } } } } } //do exchange to overwrite ghost cells where there exists real data a_data.exchange(); }
void VCAMRPoissonOp2::looseGSRB(LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs) { CH_TIME("VCAMRPoissonOp2::looseGSRB"); #if 1 MayDay::Abort("VCAMRPoissonOp2::looseGSRB - Not implemented"); #else // This implementation converges at half the rate of "levelGSRB" in // multigrid solves CH_assert(a_phi.isDefined()); CH_assert(a_rhs.isDefined()); CH_assert(a_phi.ghostVect() >= IntVect::Unit); CH_assert(a_phi.nComp() == a_rhs.nComp()); // Recompute the relaxation coefficient if needed. resetLambda(); const DisjointBoxLayout& dbl = a_phi.disjointBoxLayout(); DataIterator dit = a_phi.dataIterator(); // fill in intersection of ghostcells and a_phi's boxes { CH_TIME("VCAMRPoissonOp2::looseGSRB::homogeneousCFInterp"); homogeneousCFInterp(a_phi); } { CH_TIME("VCAMRPoissonOp2::looseGSRB::exchange"); a_phi.exchange(a_phi.interval(), m_exchangeCopier); } // now step through grids... for (dit.begin(); dit.ok(); ++dit) { // invoke physical BC's where necessary { CH_TIME("VCAMRPoissonOp2::looseGSRB::BCs"); m_bc(a_phi[dit], dbl[dit()], m_domain, m_dx, true); } const Box& region = dbl.get(dit()); const FluxBox& thisBCoef = (*m_bCoef)[dit]; int whichPass = 0; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA((*m_aCoef)[dit]), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA(thisBCoef[0]), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA(thisBCoef[1]), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA(thisBCoef[2]), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); whichPass = 1; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA((*m_aCoef)[dit]), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA(thisBCoef[0]), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA(thisBCoef[1]), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA(thisBCoef[2]), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); } // end loop through grids #endif }
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); }
// // VCAMRPoissonOp2::reflux() // There are currently the new version (first) and the old version (second) // in this file. Brian asked to preserve the old version in this way for // now. - TJL (12/10/2007) // void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_phi, LevelData<FArrayBox>& a_residual, AMRLevelOp<LevelData<FArrayBox> >* a_finerOp) { CH_TIMERS("VCAMRPoissonOp2::reflux"); m_levfluxreg.setToZero(); Interval interv(0,a_phi.nComp()-1); CH_TIMER("VCAMRPoissonOp2::reflux::incrementCoarse", t2); CH_START(t2); 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]; if (m_levfluxreg.hasCF(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; m_levfluxreg.incrementCoarse(coarflux, scale,dit(), interv, interv, idir); } } } CH_STOP(t2); // const cast: OK because we're changing ghost cells only LevelData<FArrayBox>& phiFineRef = ( LevelData<FArrayBox>&)a_phiFine; VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp; QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser; quadCFI.coarseFineInterp(phiFineRef, a_phi); // I'm pretty sure this is not necessary. bvs -- flux calculations use // outer ghost cells, but not inner ones // phiFineRef.exchange(a_phiFine.interval()); IntVect phiGhost = phiFineRef.ghostVect(); int ncomps = a_phiFine.nComp(); CH_TIMER("VCAMRPoissonOp2::reflux::incrementFine", t3); CH_START(t3); 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()) { if (m_levfluxreg.hasCF(ditf(), sit())) { Side::LoHiSide hiorlo = sit(); Box fluxBox = bdryBox(gridbox,idir,hiorlo,1); FArrayBox fineflux(fluxBox,ncomps); getFlux(fineflux, phifFab, fineBCoef, fluxBox, idir, m_refToFiner); Real scale = 1.0; m_levfluxreg.incrementFine(fineflux, scale, ditf(), interv, interv, idir, hiorlo); } } } } CH_STOP(t3); Real scale = 1.0/m_dx; m_levfluxreg.reflux(a_residual, scale); }
void VCAMRPoissonOp2::restrictResidual(LevelData<FArrayBox>& a_resCoarse, LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_rhsFine) { CH_TIME("VCAMRPoissonOp2::restrictResidual"); homogeneousCFInterp(a_phiFine); const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout(); for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit) { FArrayBox& phi = a_phiFine[dit]; m_bc(phi, dblFine[dit()], m_domain, m_dx, true); } a_phiFine.exchange(a_phiFine.interval(), m_exchangeCopier); for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit) { FArrayBox& phi = a_phiFine[dit]; const FArrayBox& rhs = a_rhsFine[dit]; FArrayBox& res = a_resCoarse[dit]; const FArrayBox& thisACoef = (*m_aCoef)[dit]; const FluxBox& thisBCoef = (*m_bCoef)[dit]; Box region = dblFine.get(dit()); const IntVect& iv = region.smallEnd(); IntVect civ = coarsen(iv, 2); res.setVal(0.0); #if CH_SPACEDIM == 1 FORT_RESTRICTRESVC1D #elif CH_SPACEDIM == 2 FORT_RESTRICTRESVC2D #elif CH_SPACEDIM == 3 FORT_RESTRICTRESVC3D #else This_will_not_compile! #endif (CHF_FRA_SHIFT(res, civ), CHF_CONST_FRA_SHIFT(phi, iv), CHF_CONST_FRA_SHIFT(rhs, iv), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA_SHIFT(thisACoef, iv), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA_SHIFT(thisBCoef[0], iv), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA_SHIFT(thisBCoef[1], iv), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA_SHIFT(thisBCoef[2], iv), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_BOX_SHIFT(region, iv), CHF_CONST_REAL(m_dx)); } }
void EBPoissonOp:: restrictResidual(LevelData<EBCellFAB>& a_resCoar, LevelData<EBCellFAB>& a_phiThisLevel, const LevelData<EBCellFAB>& a_rhsThisLevel) { CH_TIME("EBPoissonOp::restrictResidual"); CH_assert(a_resCoar.nComp() == 1); CH_assert(a_phiThisLevel.nComp() == 1); CH_assert(a_rhsThisLevel.nComp() == 1); LevelData<EBCellFAB> resThisLevel; bool homogeneous = true; EBCellFactory ebcellfactTL(m_eblg.getEBISL()); IntVect ghostVec = a_rhsThisLevel.ghostVect(); resThisLevel.define(m_eblg.getDBL(), 1, ghostVec, ebcellfactTL); // Get the residual on the fine grid residual(resThisLevel,a_phiThisLevel,a_rhsThisLevel,homogeneous); // now use our nifty averaging operator Interval variables(0, 0); CH_assert(m_hasMGObjects); m_ebAverageMG.average(a_resCoar, resThisLevel, variables); #ifdef DO_EB_RHS_CORRECTION // Apply error-correction modification to restricted RHS // Right now this only works with Dirichlet BC's, and only makes sense for the EB int correctionType = 0; // Change this to activate RHS correction if (correctionType != 0) { for (DataIterator dit = a_resCoar.disjointBoxLayout().dataIterator(); dit.ok(); ++dit) { EBCellFAB& resFAB = a_resCoar[dit()]; // Extract the FAB for this box const EBISBox& ebis = resFAB.getEBISBox(); // Get the set of all IntVect indices // Iterate over the parts of the RHS corresponding to the irregular cells, // correcting the RHS in each cell VoFIterator ebvofit(ebis.getIrregIVS(ebis.getRegion()), ebis.getEBGraph()); for (ebvofit.reset(); ebvofit.ok(); ++ebvofit) { for (int icomp = 0; icomp < resFAB.nComp(); ++icomp) // For each component of the residual on this VoF { if (correctionType == 1) { // Setting the residual to zero on the irregular cells gives convergence, // though the rate isn't as good as the full correction resFAB(ebvofit(), icomp) = 0.0; } else if (correctionType == 2) { // Kludge valid only for pseudo-1D test case. May not work for you. Real kappa = ebis.volFrac(ebvofit()); kappa = (kappa > 0.5 ? kappa : 0.5); // Floor on kappa to prevent dividing by a tiny number Real rhoCoeff = (kappa + 0.5)/(2.0*kappa); resFAB(ebvofit(), icomp) *= (1.0 - rhoCoeff); } // else silently do nothing } } } } #endif }