// Set boundary fluxes void ExplosionIBC::primBC(FArrayBox& a_WGdnv, const FArrayBox& a_Wextrap, const FArrayBox& a_W, const int& a_dir, const Side::LoHiSide& a_side, const Real& a_time) { CH_assert(m_isFortranCommonSet == true); CH_assert(m_isDefined == true); // In periodic case, this doesn't do anything if (!m_domain.isPeriodic(a_dir)) { int lohisign; Box tmp = a_WGdnv.box(); // Determine which side and thus shifting directions lohisign = sign(a_side); tmp.shiftHalf(a_dir,lohisign); // Is there a domain boundary next to this grid if (!m_domain.contains(tmp)) { tmp &= m_domain; Box boundaryBox; // Find the strip of cells next to the domain boundary if (a_side == Side::Lo) { boundaryBox = bdryLo(tmp,a_dir); } else { boundaryBox = bdryHi(tmp,a_dir); } // Set the boundary fluxes FORT_SOLIDBCF(CHF_FRA(a_WGdnv), CHF_CONST_FRA(a_Wextrap), CHF_CONST_FRA(a_W), CHF_CONST_INT(lohisign), CHF_CONST_INT(a_dir), CHF_BOX(boundaryBox)); } } }
/// Set boundary primitive values. void RSIBC::primBC(FArrayBox& a_WGdnv, const FArrayBox& a_WShiftInside, const FArrayBox& a_W, const int& a_dir, const Side::LoHiSide& a_side, const Real& a_time) { CH_assert(m_isFortranCommonSet == true); // CH_assert(m_isFortranCommonLESet == true); CH_assert(m_isDefined == true); Box boundaryBox; getBoundaryFaces(boundaryBox, a_WGdnv.box(), a_dir, a_side); // In periodic case, this doesn't do anything if (!m_domain.isPeriodic(a_dir)) { int lohisign; Box tmp = a_WGdnv.box(); // Determine which side and thus shifting directions lohisign = sign(a_side); tmp.shiftHalf(a_dir,lohisign); // Is there a domain boundary next to this grid if (!m_domain.contains(tmp)) { tmp &= m_domain; Box boundaryBox; // Find the strip of cells next to the domain boundary if (a_side == Side::Lo) { boundaryBox = bdryLo(tmp,a_dir); } else { boundaryBox = bdryHi(tmp,a_dir); } if(lohisign == -1 && a_dir == 1) { if(m_tmpBdryDataSet) { FORT_RSFAULTBCF(CHF_FRA(a_WGdnv), CHF_CONST_FRA(a_WShiftInside), CHF_CONST_FRA(a_W), CHF_CONST_FRA1((*m_tmpBdryData),RX_PSI), CHF_CONST_INT(lohisign), CHF_CONST_REAL(m_dx), CHF_CONST_REAL(a_time), CHF_CONST_INT(a_dir), CHF_BOX(boundaryBox)); } else { FORT_RSFAULTBCF(CHF_FRA(a_WGdnv), CHF_CONST_FRA(a_WShiftInside), CHF_CONST_FRA(a_W), CHF_CONST_FRA1((*m_bdryData),RX_PSI), CHF_CONST_INT(lohisign), CHF_CONST_REAL(m_dx), CHF_CONST_REAL(a_time), CHF_CONST_INT(a_dir), CHF_BOX(boundaryBox)); } } else if(m_boundaryType[a_dir*2 + (lohisign+1)/2] == 0) { FORT_LINELASTOUTBCF(CHF_FRA(a_WGdnv), CHF_CONST_FRA(a_WShiftInside), CHF_CONST_FRA(a_W), CHF_CONST_INT(lohisign), CHF_CONST_REAL(m_dx), CHF_CONST_INT(a_dir), CHF_BOX(boundaryBox)); } else if(m_boundaryType[a_dir*2 + (lohisign+1)/2] == 1) { FORT_LINELASTFREEBCF(CHF_FRA(a_WGdnv), CHF_CONST_FRA(a_WShiftInside), CHF_CONST_FRA(a_W), CHF_CONST_INT(lohisign), CHF_CONST_REAL(m_dx), CHF_CONST_INT(a_dir), CHF_BOX(boundaryBox)); } else { MayDay::Error("Invalid Boundary Type"); } } } }
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); }
// Set boundary fluxes void VelIBC::primBC(FArrayBox& a_WGdnv, const FArrayBox& a_Wextrap, const FArrayBox& a_W, const int& a_dir, const Side::LoHiSide& a_side, const Real& a_time) { CH_assert(m_isDefined == true); // In periodic case, this doesn't do anything if (!m_domain.isPeriodic(a_dir)) { // This needs to be fixed // CH_assert(m_isBCvalSet); int lohisign; Box tmp = a_WGdnv.box() & m_domain; Real bcVal; // Determine which side and thus shifting directions if (a_side == Side::Lo) { lohisign = -1; bcVal = m_bcVal[a_dir][0]; } else { lohisign = 1; bcVal = m_bcVal[a_dir][1]; } tmp.shiftHalf(a_dir,lohisign); // Is there a domain boundary next to this grid if (!m_domain.contains(tmp)) { tmp &= m_domain; Box boundaryBox; // Find the strip of cells next to the domain boundary if (a_side == Side::Lo) { boundaryBox = bdryLo(tmp,a_dir); } else { boundaryBox = bdryHi(tmp,a_dir); } // Set the boundary fluxes FORT_SOLIDVELBCF(CHF_FRA(a_WGdnv), CHF_CONST_FRA(a_Wextrap), CHF_CONST_REAL(bcVal), CHF_CONST_INT(lohisign), CHF_CONST_REAL(m_dx), CHF_CONST_INT(a_dir), CHF_BOX(boundaryBox)); } } }
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); }