void LevelFluxRegisterEdge::incrementFine( 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()); CH_assert(!a_fineFlux.box().isEmpty()); CH_assert(a_srcInterval.size() == a_dstInterval.size()); CH_assert(a_srcInterval.begin() >= 0); CH_assert(a_srcInterval.end() < a_fineFlux.nComp()); CH_assert(a_dstInterval.begin() >= 0); CH_assert(a_dstInterval.end() < m_nComp); CH_assert(a_dir >= 0); CH_assert(a_dir < SpaceDim); CH_assert((a_sd == Side::Lo)||(a_sd == Side::Hi)); // // //denom is the number of fine faces per coarse face //this is intrinsically dimension-dependent #if (CH_SPACEDIM == 2) Real denom = 1; #elif (CH_SPACEDIM == 3) Real denom = m_nRefine; #else // This code doesn't make any sense in 1D, and hasn't been implemented // for DIM > 3 Real denom = -1.0; MayDay::Error("LevelFluxRegisterEdge -- bad SpaceDim"); #endif Real scale = a_scale/denom; // need which fluxbox face we're doing this for Box thisBox = a_fineFlux.box(); int fluxComp = -1; for (int sideDir=0; sideDir<SpaceDim; sideDir++) { // we do nothing in the direction normal to face if (sideDir != a_dir) { if (thisBox.type(sideDir) == IndexType::CELL) { fluxComp = sideDir; } } } CH_assert (fluxComp >= 0); int regcomp = getRegComp(a_dir, fluxComp); FluxBox& thisReg = m_fabFine[index(a_dir, a_sd)][a_fineDataIndex]; FArrayBox& reg = thisReg[regcomp]; a_fineFlux.shiftHalf(a_dir, sign(a_sd)); // this is a way of geting a face-centered domain // box which we can then use to intersect with things // to screen out cells outside the physical domain // (nothing is screened out in periodic case) Box shiftedValidDomain = m_domainCoarse.domainBox(); shiftedValidDomain.grow(2); shiftedValidDomain &= m_domainCoarse; shiftedValidDomain.surroundingNodes(regcomp); BoxIterator regIt(reg.box() & shiftedValidDomain); for (regIt.begin(); regIt.ok(); ++regIt) { const IntVect& coarseIndex = regIt(); // create a cell-centered box, then shift back to face-centered Box box(coarseIndex, coarseIndex); box.shiftHalf(regcomp,-1); // to avoid adding in edges which do not overlie coarse-grid // edges, will refine only in non-fluxComp directions to // determine box from which to grab fluxes. IntVect refineVect(m_nRefine*IntVect::Unit); //refineVect.setVal(fluxComp,1); box.refine(refineVect); if (a_sd == Side::Lo) box.growLo(a_dir,-(m_nRefine-1)); else box.growHi(a_dir,-(m_nRefine-1)); BoxIterator fluxIt(box); for (fluxIt.begin(); fluxIt.ok(); ++fluxIt) { int src = a_srcInterval.begin(); int dest = a_dstInterval.begin(); for ( ; src <=a_srcInterval.end(); ++src,++dest) reg(coarseIndex, dest) += scale*a_fineFlux(fluxIt(), src); } } a_fineFlux.shiftHalf(a_dir, -sign(a_sd)); }
// Adjust boundary fluxes to account for artificial viscosity void RampIBC::artViscBC(FArrayBox& a_F, const FArrayBox& a_U, const FArrayBox& a_divVel, const int& a_dir, const Real& a_time) { CH_assert(m_isFortranCommonSet == true); CH_assert(m_isDefined == true); FArrayBox &divVel = (FArrayBox &)a_divVel; Box fluxBox = divVel.box(); fluxBox.enclosedCells(a_dir); fluxBox.grow(a_dir,1); Box loBox,hiBox,centerBox,entireBox; int hasLo,hasHi; loHiCenterFace(loBox,hasLo,hiBox,hasHi,centerBox,entireBox, fluxBox,m_domain,a_dir); if (hasLo == 1) { loBox.shiftHalf(a_dir,1); divVel.shiftHalf(a_dir,1); a_F.shiftHalf(a_dir,1); int loHiSide = -1; FORT_RAMPARTVISCF(CHF_FRA(a_F), CHF_CONST_FRA(a_U), CHF_CONST_FRA1(divVel,0), CHF_CONST_INT(loHiSide), CHF_CONST_REAL(m_dx), CHF_CONST_INT(a_dir), CHF_BOX(loBox)); loBox.shiftHalf(a_dir,-1); divVel.shiftHalf(a_dir,-1); a_F.shiftHalf(a_dir,-1); } if (hasHi == 1) { hiBox.shiftHalf(a_dir,-1); divVel.shiftHalf(a_dir,-1); a_F.shiftHalf(a_dir,-1); int loHiSide = 1; FORT_RAMPARTVISCF(CHF_FRA(a_F), CHF_CONST_FRA(a_U), CHF_CONST_FRA1(divVel,0), CHF_CONST_INT(loHiSide), CHF_CONST_REAL(m_dx), CHF_CONST_INT(a_dir), CHF_BOX(hiBox)); hiBox.shiftHalf(a_dir,1); divVel.shiftHalf(a_dir,1); a_F.shiftHalf(a_dir,1); } }