void EBGradDivFilter:: getAreaFracs(Vector<FaceIndex> a_facesLo[SpaceDim], Vector<FaceIndex> a_facesHi[SpaceDim], bool a_hasFacesLo[SpaceDim], bool a_hasFacesHi[SpaceDim], RealVect& a_areaFracLo, RealVect& a_areaFracHi, const VolIndex& a_vof, const EBISBox& a_ebisBox) { for (int idir = 0; idir < SpaceDim; idir++) { Real areaSumLo = 0; Real areaSumHi = 0; a_facesLo[idir] = a_ebisBox.getFaces(a_vof, idir, Side::Lo); a_facesHi[idir] = a_ebisBox.getFaces(a_vof, idir, Side::Hi); a_hasFacesLo[idir] = ( ( a_facesLo[idir].size() > 0) && (!a_facesLo[idir][0].isBoundary())); a_hasFacesHi[idir] = ( ( a_facesHi[idir].size() > 0) && (!a_facesHi[idir][0].isBoundary())); //want boundary faces to look covered if (a_hasFacesLo[idir]) { for (int iface = 0; iface < a_facesLo[idir].size(); iface++) { areaSumLo += a_ebisBox.areaFrac(a_facesLo[idir][iface]); } } //want boundary faces to look covered if (a_hasFacesHi[idir]) { for (int iface = 0; iface < a_facesHi[idir].size(); iface++) { areaSumHi += a_ebisBox.areaFrac(a_facesHi[idir][iface]); } } a_areaFracLo[idir] = areaSumLo; a_areaFracHi[idir] = areaSumHi; } }
Real divergence(const EBFluxFAB& a_func, const RealVect& a_bndryFlux, const EBISBox& a_ebisBox, const VolIndex& a_vof, const Real& a_dx) { Real retval = 0; Real bndryArea = a_ebisBox.bndryArea(a_vof); RealVect normal = a_ebisBox.normal(a_vof); for (int idir = 0; idir < SpaceDim; idir++) { Real bndryFlux = a_bndryFlux[idir]; //normal already dealt with Real bndryContrib = -bndryFlux*bndryArea*normal[idir]; Real openContrib = 0; if (bndryArea > 1.0e-3) { openContrib = 0; } for (SideIterator sit; sit.ok(); ++sit) { int isign = sign(sit()); Real rsign = isign; Vector<FaceIndex> faces = a_ebisBox.getFaces(a_vof, idir, sit()); for (int iface = 0; iface < faces.size(); ++iface) { Real areaFrac = a_ebisBox.areaFrac(faces[iface]); Real faceFlux = a_func[idir](faces[iface], 0); openContrib += rsign*faceFlux*areaFrac; } } retval += openContrib + bndryContrib; } retval /= a_dx; return retval; }
void kappaDivergence(EBCellFAB& a_divF, const EBFluxFAB& a_flux, const EBISBox& a_ebisBox, const Box& a_box, const Real& a_dx) { //set the divergence initially to zero //then loop through directions and increment the divergence //with each directions flux difference. a_divF.setVal(0.0); BaseFab<Real>& regDivF = a_divF.getSingleValuedFAB(); regDivF.setVal(0.); for (int idir = 0; idir < SpaceDim; idir++) { //update for the regular vofs in the nonconservative //case works for all single valued vofs. /* do the regular vofs */ /**/ const EBFaceFAB& fluxDir = a_flux[idir]; const BaseFab<Real>& regFluxDir = fluxDir.getSingleValuedFAB(); int ncons = 1; FORT_DIVERGEF( CHF_BOX(a_box), CHF_FRA(regDivF), CHF_CONST_FRA(regFluxDir), CHF_CONST_INT(idir), CHF_CONST_INT(ncons), CHF_CONST_REAL(a_dx)); /**/ } //update the irregular vofs using conservative diff IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(a_box); for (VoFIterator vofit(ivsIrreg, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); //divergence was set in regular update. we reset it // to zero and recalc. Real update = 0.; for ( int idir = 0; idir < SpaceDim; idir++) { const EBFaceFAB& fluxDir = a_flux[idir]; for (SideIterator sit; sit.ok(); ++sit) { int isign = sign(sit()); Vector<FaceIndex> faces = a_ebisBox.getFaces(vof, idir, sit()); for (int iface = 0; iface < faces.size(); iface++) { const FaceIndex& face = faces[iface]; Real areaFrac = a_ebisBox.areaFrac(face); Real faceFlux =fluxDir(face, 0); update += isign*areaFrac*faceFlux; } } } //add EB boundary condtions in divergence const IntVect& iv = vof.gridIndex(); Real bndryArea = a_ebisBox.bndryArea(vof); RealVect bndryCent = a_ebisBox.bndryCentroid(vof); RealVect normal = a_ebisBox.normal(vof); RealVect bndryLoc; RealVect exactF; for (int idir = 0; idir < SpaceDim; idir++) { bndryLoc[idir] = a_dx*(iv[idir] + 0.5 + bndryCent[idir]); } for (int idir = 0; idir < SpaceDim; idir++) { exactF[idir] = exactFlux(bndryLoc, idir); } Real bndryFlux = PolyGeom::dot(exactF, normal); update -= bndryFlux*bndryArea; update /= a_dx; //note NOT divided by volfrac a_divF(vof, 0) = update; } }
void EBPoissonOp:: getOpFaceStencil(VoFStencil& a_stencil, const Vector<VolIndex>& a_allMonotoneVoFs, const EBISBox& a_ebisbox, const VolIndex& a_VoF, int a_dir, const Side::LoHiSide& a_side, const FaceIndex& a_face, const bool& a_lowOrder) { a_stencil.clear(); const RealVect& faceCentroid = a_ebisbox.centroid(a_face); const IntVect& origin = a_VoF.gridIndex(); IntVect dirs = IntVect::Zero; for (int idir = 0; idir < SpaceDim; idir++) { if (idir != a_dir) { IntVect ivPlus = origin; ivPlus[idir] += 1; if (faceCentroid[idir] < 0.0) { dirs[idir] = -1; } else if (faceCentroid[idir] > 0.0) { dirs[idir] = 1; } else if (m_eblg.getDomain().contains(ivPlus)) { dirs[idir] = 1; } else { dirs[idir] = -1; } } } bool orderOne = true; if (m_orderEB == 0 || a_lowOrder) { orderOne = false; } else { IntVect loVect = dirs; loVect.min(IntVect::Zero); IntVect hiVect = dirs; hiVect.max(IntVect::Zero); Box fluxBox(loVect,hiVect); IntVectSet fluxIVS(fluxBox); IVSIterator ivsit(fluxIVS); for (ivsit.begin(); ivsit.ok(); ++ivsit) { bool curOkay; IntVect ivDelta = ivsit(); IntVect iv1 = ivDelta; iv1 += origin; VolIndex VoF1; curOkay = EBArith::isVoFHere(VoF1,a_allMonotoneVoFs,iv1); IntVect iv2 = iv1; iv2[a_dir] += sign(a_side); VolIndex VoF2; curOkay = curOkay && EBArith::isVoFHere(VoF2,a_allMonotoneVoFs,iv2); orderOne = orderOne && curOkay; if (curOkay) { VoFStencil curPair; curPair.add(VoF1,-m_invDx2[a_dir]); curPair.add(VoF2, m_invDx2[a_dir]); for (int idir = 0; idir < SpaceDim; idir++) { if (idir != a_dir) { if (ivDelta[idir] == 0) { curPair *= 1 - abs(faceCentroid[idir]); } else { curPair *= abs(faceCentroid[idir]); } } } a_stencil += curPair; } } } if (!orderOne) { VolIndex VoF1 = a_VoF; VolIndex VoF2 = a_face.getVoF(a_side); if (a_ebisbox.getRegion().contains(VoF2.gridIndex())) { a_stencil.clear(); a_stencil.add(VoF1,-m_invDx2[a_dir]); a_stencil.add(VoF2, m_invDx2[a_dir]); } } if (!a_lowOrder) { a_stencil *= a_ebisbox.areaFrac(a_face); } }