void CompGridVTOBC::operator()( FArrayBox& a_state, const Box& a_valid, const ProblemDomain& a_domain, Real a_dx, bool a_homogeneous) { const Box& domainBox = a_domain.domainBox(); for (int idir = 0; idir < SpaceDim; idir++) { if (!a_domain.isPeriodic(idir)) { for (SideIterator sit; sit.ok(); ++sit) { Side::LoHiSide side = sit(); if (a_valid.sideEnd(side)[idir] == domainBox.sideEnd(side)[idir]) { // Dirichlet BC int isign = sign(side); Box toRegion = adjCellBox(a_valid, idir, side, 1); // include corner cells if possible by growing toRegion in transverse direction toRegion.grow(1); toRegion.grow(idir, -1); toRegion &= a_state.box(); for (BoxIterator bit(toRegion); bit.ok(); ++bit) { IntVect ivTo = bit(); IntVect ivClose = ivTo - isign*BASISV(idir); for (int ighost=0;ighost<m_nGhosts[0];ighost++,ivTo += isign*BASISV(idir)) { //for (int icomp = 0; icomp < a_state.nComp(); icomp++) a_state(ivTo, icomp) = 0.0; IntVect ivFrom = ivClose; // hardwire to linear BCs for now for (int icomp = 0; icomp < a_state.nComp() ; icomp++) { if (m_bcDiri[idir][side][icomp]) { a_state(ivTo, icomp) = (-1.0)*a_state(ivFrom, icomp); } else { a_state(ivTo, icomp) = (1.0)*a_state(ivFrom, icomp); } } } } // end loop over cells } // if ends match } // end loop over sides } // if not periodic in this direction } // end loop over directions }
void VCAMRPoissonOp2::getFlux(FArrayBox& a_flux, const FArrayBox& a_data, const FluxBox& a_bCoef, const Box& a_facebox, int a_dir, int a_ref) const { CH_TIME("VCAMRPoissonOp2::getFlux"); CH_assert(a_dir >= 0); CH_assert(a_dir < SpaceDim); CH_assert(!a_data.box().isEmpty()); CH_assert(!a_facebox.isEmpty()); // probably the simplest way to test centering // a_box needs to be face-centered in the a_dir Box faceTestBox(IntVect::Zero, IntVect::Unit); faceTestBox.surroundingNodes(a_dir); CH_assert(a_facebox.type() == faceTestBox.type()); const FArrayBox& bCoefDir = a_bCoef[a_dir]; // reality check for bCoef CH_assert(bCoefDir.box().contains(a_facebox)); a_flux.resize(a_facebox, a_data.nComp()); BoxIterator bit(a_facebox); Real scale = m_beta * a_ref / m_dx; for ( bit.begin(); bit.ok(); bit.next()) { IntVect iv = bit(); IntVect shiftiv = BASISV(a_dir); IntVect ivlo = iv - shiftiv; IntVect ivhi = iv; CH_assert(a_data.box().contains(ivlo)); CH_assert(a_data.box().contains(ivhi)); for (int ivar = 0; ivar < a_data.nComp(); ivar++) { Real phihi = a_data(ivhi,ivar); Real philo = a_data(ivlo,ivar); Real gradphi = (phihi - philo ) * scale; a_flux(iv,ivar) = -bCoefDir(iv, ivar) * gradphi; } } }
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 SWIBC::dumpBdryData(FILE * a_boundaryDataFile) { // Get the box that defines this layer Box b = m_bdryData->box(); // Remove the ghost cells b.grow(-(IntVect::Unit - BASISV(1))); // loop over the box saving the values BoxIterator bit(b); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); Real x = (iv[0]+0.5)*m_dx-m_fricBoxCenter[0]; Real z = (iv[2]+0.5)*m_dx-m_fricBoxCenter[1]; if(abs(x) <= m_fricBoxWidth[0] & abs(z) <= m_fricBoxWidth[1]) { fprintf(a_boundaryDataFile,"%E %E %E\n", x, z, m_bdryData->get(iv,6)); } } }
int makeGeometry( const Box& a_domain, const RealVect& a_dx, const RealVect& a_origin, const RealVect& a_center, const Real& a_radius) { int eekflag = 0; RealVect normal = BASISV(0); bool insideRegular = false; SphereIF implicit(a_radius,a_center,insideRegular); int verbosity = 0; GeometryShop workshop(implicit,verbosity,a_dx); CH_XD::EBIndexSpace* ebisPtr = Chombo_EBIS::instance(); ebisPtr->define(a_domain,a_origin,a_dx[0], workshop); return eekflag; }
void SlabService::fillGraph(BaseFab<int>& a_regIrregCovered, Vector<IrregNode>& a_nodes, const Box& a_validRegion, const Box& a_ghostRegion, const ProblemDomain& a_domain, const RealVect& a_origin, const Real& a_dx) const { Box grownCovBox = grow(m_coveredRegion, 1); grownCovBox &= a_ghostRegion; IntVectSet ivsIrreg(grownCovBox); ivsIrreg -= m_coveredRegion; ivsIrreg &= a_domain; //set regirregcoverred flags CH_assert(a_regIrregCovered.box().contains(a_ghostRegion)); //set every cell to regular a_regIrregCovered.setVal(1); for (BoxIterator bit(a_ghostRegion); bit.ok(); ++bit) { if (m_coveredRegion.contains(bit())) { //set covered cells to -1 a_regIrregCovered(bit(), 0) = -1; } else if (ivsIrreg.contains(bit())) { //set irreg cells to 0 a_regIrregCovered(bit(), 0) = 0; } } //now loop through irreg cells and make Nodes for them a_nodes.resize(0); for (IVSIterator ivsit(ivsIrreg); ivsit.ok(); ++ivsit) { const IntVect& iv = ivsit(); if (a_validRegion.contains(iv)) { IrregNode node; //first the obvious node.m_cell = iv; node.m_volFrac = 1.0; node.m_cellIndex = 0; node.m_volCentroid = RealVect::Zero; //any time the next cell over is in the covered //region, there is no face. If there is a cell //but it is outside the domain, the arc=-1 to signify //a boundary face. Otherwise, the arc is -2 if it //is to a regular cell and 0 if it is to an irregular cell for (int idir = 0; idir < SpaceDim; idir++) { for (SideIterator sit; sit.ok(); ++sit) { int arcIndex = node.index(idir, sit()); Vector<int>& arcs = node.m_arc[arcIndex]; Vector<Real>& areaFracs= node.m_areaFrac[arcIndex]; Vector<RealVect>& faceCents= node.m_faceCentroid[arcIndex]; IntVect otherIV = iv + sign(sit())*BASISV(idir); if (m_coveredRegion.contains(otherIV)) { //do nothing, covered face. leave the vector empty } else { int otherCellIndex; if (ivsIrreg.contains(otherIV)) { //arc irregular cell inside the domain otherCellIndex = 0; } else if (!a_domain.contains(otherIV)) { //boundary face otherCellIndex = -1; } else { //arc to regular cell otherCellIndex = -2; } arcs.push_back(otherCellIndex); Real areaFrac = 1.0; RealVect faceCent = RealVect::Zero; areaFracs.push_back(areaFrac); faceCents.push_back(faceCent); } //end otherIV not covered } } //the boundary centroid and normal //depend on which side is covered for (int idir = 0; idir < SpaceDim; idir++) { for (SideIterator sit; sit.ok(); ++sit) { int arcIndex = node.index(idir, sit()); Vector<int>& arcs = node.m_arc[arcIndex]; if (arcs.size() == 0) { int isign = sign(sit()); node.m_bndryCentroid[idir] = Real(isign)*0.5; } } } a_nodes.push_back(node); } } }
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 oldLoHiCenterFace(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.surroundingNodes(a_dir); 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_hiBox.shiftHalf(a_dir,1); a_entireBox.growHi(a_dir,1); } else { a_hasHi = 0; a_hiBox = Box().convert(BASISV(a_dir)); } // 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_loBox.shiftHalf(a_dir,-1); a_entireBox.growLo(a_dir,1); } else { a_hasLo = 0; a_loBox = Box().convert(BASISV(a_dir)); } // 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 ConstBCFunction::operator()(FArrayBox& a_state, const Box& a_valid, const ProblemDomain& a_domain, Real a_dx, bool a_homogeneous) { const Box& domainBox = a_domain.domainBox(); for (int idir = 0; idir < SpaceDim; idir++) { if (!a_domain.isPeriodic(idir)) { for (SideIterator sit; sit.ok(); ++sit) { Side::LoHiSide side = sit(); if (a_valid.sideEnd(side)[idir] == domainBox.sideEnd(side)[idir]) { int bcType; Real bcValue; if (side == Side::Lo) { bcType = m_loSideType [idir]; bcValue = m_loSideValue[idir]; } else { bcType = m_hiSideType [idir]; bcValue = m_hiSideValue[idir]; } if (bcType == 0) { // Neumann BC int isign = sign(side); Box toRegion = adjCellBox(a_valid, idir, side, 1); toRegion &= a_state.box(); Box fromRegion = toRegion; fromRegion.shift(idir, -isign); a_state.copy(a_state, fromRegion, 0, toRegion, 0, a_state.nComp()); if (!a_homogeneous) { for (BoxIterator bit(toRegion); bit.ok(); ++bit) { const IntVect& ivTo = bit(); // IntVect ivClose = ivTo - isign*BASISV(idir); for (int icomp = 0; icomp < a_state.nComp(); icomp++) { a_state(ivTo, icomp) += Real(isign)*a_dx*bcValue; } } } } else if (bcType == 1) { // Dirichlet BC int isign = sign(side); Box toRegion = adjCellBox(a_valid, idir, side, 1); toRegion &= a_state.box(); for (BoxIterator bit(toRegion); bit.ok(); ++bit) { const IntVect& ivTo = bit(); IntVect ivClose = ivTo - isign*BASISV(idir); // IntVect ivFar = ivTo - 2*isign*BASISV(idir); Real inhomogVal = 0.0; if (!a_homogeneous) { inhomogVal = bcValue; } for (int icomp = 0; icomp < a_state.nComp(); icomp++) { Real nearVal = a_state(ivClose, icomp); // Real farVal = a_state(ivFar, icomp); Real ghostVal = linearInterp(inhomogVal, nearVal); a_state(ivTo, icomp) = ghostVal; } } } else { MayDay::Abort("ConstBCFunction::operator() - unknown BC type"); } } // if ends match } // end loop over sides } // if not periodic in this direction } // end loop over directions }