static void setVal1(const Box& box, int comps, BaseFab<int>& fab) { int center = (box.smallEnd()[0] + box.bigEnd()[0])/2; fab.setVal(center, 0); fab.setVal(2*center, 1); fab.setVal(3*center, 2); }
static void setVal2(const Box& box, int comps, BaseFab<int>& fab) { if ( SpaceDim == 1 ) { fab.setVal(173); } else { int center = (box.smallEnd()[1] + box.bigEnd()[1])/2; fab.setVal(center); } }
template < > int BaseFab<int>::test() { int retbox = testBoxAndComp(); if (retbox != 0) { pout() << "testboxandcomp failed" << endl; return retbox; } Box b(IntVect::Zero, IntVect::Unit); BaseFab<int> blerg; blerg.define(b, 1); int val = 4; blerg.setVal(val); for (BoxIterator bit(b); bit.ok();++bit) { if (blerg(bit(), 0) != val) { pout() << "setval or index busted" << endl; return -1; } } Box bcop(IntVect::Unit, 2*IntVect::Unit); BaseFab<int> bfcopy(bcop, 1); bfcopy.setVal(2*val); bfcopy.copy(blerg, 0, 0, 1); Box binter =bcop; binter &= b; for (BoxIterator bit(binter); bit.ok();++bit) { if (bfcopy(bit(), 0) != val) { pout() << "copy busted" << endl; return -2; } } return 0; }
void AllRegularService::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 { PolyGeom::setVectDx(RealVect::Unit); //set all cells to regular a_regIrregCovered.setVal(1); }
void BaseFab<Real>::performCopy (const BaseFab<Real>& src, const Box& srcbox, int srccomp, const Box& destbox, int destcomp, int numcomp) { BL_ASSERT(destbox.ok()); BL_ASSERT(src.box().contains(srcbox)); BL_ASSERT(box().contains(destbox)); BL_ASSERT(destbox.sameSize(srcbox)); BL_ASSERT(srccomp >= 0 && srccomp+numcomp <= src.nComp()); BL_ASSERT(destcomp >= 0 && destcomp+numcomp <= nComp()); if (destbox == domain && srcbox == src.box()) { Real* data_dst = dataPtr(destcomp); const Real* data_src = src.dataPtr(srccomp); for (long i = 0, N = numcomp*numpts; i < N; i++) { *data_dst++ = *data_src++; } } else { const int* destboxlo = destbox.loVect(); const int* destboxhi = destbox.hiVect(); const int* _th_plo = loVect(); const int* _th_phi = hiVect(); const int* _x_lo = srcbox.loVect(); const int* _x_plo = src.loVect(); const int* _x_phi = src.hiVect(); Real* _th_p = dataPtr(destcomp); const Real* _x_p = src.dataPtr(srccomp); FORT_FASTCOPY(_th_p, ARLIM(_th_plo), ARLIM(_th_phi), D_DECL(destboxlo[0],destboxlo[1],destboxlo[2]), D_DECL(destboxhi[0],destboxhi[1],destboxhi[2]), _x_p, ARLIM(_x_plo), ARLIM(_x_phi), D_DECL(_x_lo[0],_x_lo[1],_x_lo[2]), &numcomp); } }
// ------------------------------------------------------------- void Mask::buildMask(BaseFab<int>& a_mask, const ProblemDomain& a_dProblem, const BoxLayout& a_grids, const BoxLayout* a_fineGridsPtr, int a_nRefFine) { // first set entire box to Physical BC a_mask.setVal(maskPhysical); // now set all of domain interior to coarse Box domainInterior(a_mask.box()); domainInterior &= a_dProblem; a_mask.setVal(maskCoarse,domainInterior,0); // now loop over this level's boxes and set them to "copy" LayoutIterator lit = a_grids.layoutIterator(); for (lit.reset(); lit.ok(); ++lit) { Box intersectBox = a_grids.get(lit()); intersectBox &= a_mask.box(); if (!intersectBox.isEmpty()) { a_mask.setVal(maskCopy,intersectBox,0); } } // if finer grids exist, set them to "covered" if (a_fineGridsPtr != NULL) { CH_assert (a_nRefFine > 1); LayoutIterator litFine = a_fineGridsPtr->layoutIterator(); for (litFine.reset(); litFine.ok(); ++litFine) { Box coarsenedBox(a_fineGridsPtr->get(litFine())); coarsenedBox.coarsen(a_nRefFine); coarsenedBox &= a_mask.box(); if (!coarsenedBox.isEmpty()) { a_mask.setVal(maskCovered,coarsenedBox,0); } } } }
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 PatchPluto::updateSolution(FArrayBox& a_U, FArrayBox& a_Utmp, const FArrayBox& a_dV, FArrayBox& split_tags, BaseFab<unsigned char>& a_Flags, FluxBox& a_F, Time_Step *Dts, const Box& UBox, Grid *grid) /* * * * * *********************************************************************** */ { CH_assert(isDefined()); CH_assert(UBox == m_currentBox); int nv, in; int nxf, nyf, nzf, indf; int nxb, nyb, nzb; int *i, *j, *k; int ii, jj, kk; double ***UU[NVAR]; double *inv_dl, dl2, cylr; static Data d; #ifdef SKIP_SPLIT_CELLS double ***splitcells; #endif #if (PARABOLIC_FLUX & EXPLICIT) static double **dcoeff; #endif Index indx; static State_1D state; Riemann_Solver *Riemann; Riemann = rsolver; #if TIME_STEPPING == RK2 double wflux = 0.5; #else double wflux = 1.; #endif /* ----------------------------------------------------------------- Check algorithm compatibilities ----------------------------------------------------------------- */ if (NX1_TOT > NMAX_POINT || NX2_TOT > NMAX_POINT || NX3_TOT > NMAX_POINT){ print ("!updateSolution (Euler): need to re-allocate matrix\n"); QUIT_PLUTO(1); } /* ----------------------------------------------------------------- Allocate memory ----------------------------------------------------------------- */ #if GEOMETRY != CARTESIAN for (nv = 0; nv < NVAR; nv++) a_U.divide(a_dV,0,nv); #if CHOMBO_CONS_AM == YES #if ROTATING_FRAME == YES Box curBox = a_U.box(); for(BoxIterator bit(curBox); bit.ok(); ++bit) { const IntVect& iv = bit(); a_U(iv,iMPHI) /= a_dV(iv,1); a_U(iv,iMPHI) -= a_U(iv,RHO)*a_dV(iv,1)*g_OmegaZ; } #else a_U.divide(a_dV,1,iMPHI); #endif #endif #else if (g_stretch_fact != 1.) a_U /= g_stretch_fact; #endif for (nv = 0; nv < NVAR; nv++){ UU[nv] = ArrayMap(NX3_TOT, NX2_TOT, NX1_TOT, a_U.dataPtr(nv)); } #ifdef SKIP_SPLIT_CELLS splitcells = ArrayBoxMap(KBEG, KEND, JBEG, JEND, IBEG, IEND, split_tags.dataPtr(0)); #endif #if (TIME_STEPPING == RK2) d.flag = ArrayCharMap(NX3_TOT, NX2_TOT, NX1_TOT,a_Flags.dataPtr(0)); #endif #if RESISTIVE_MHD != NO if (d.J == NULL) d.J = ARRAY_4D(3,NX3_MAX, NX2_MAX, NX1_MAX, double); #endif /* ----------------------------------------------------------- Allocate static memory areas ----------------------------------------------------------- */ if (state.flux == NULL){ MakeState (&state); nxf = nyf = nzf = 1; D_EXPAND(nxf = NMAX_POINT; ,
/** This is called by EBAMRPoissonOp::applyDomainFlux in EBAMRPoissonOp::applyOp for reg cells. For boundary conditions on velocity in viscous operator. */ void InflowOutflowHelmholtzDomainBC::getFaceFlux(BaseFab<Real>& a_faceFlux, const BaseFab<Real>& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useHomogeneous) { //vel: outflow is neumann. all others dirichlet. inflow uses inflow vel as the value int velcomp = DirichletPoissonEBBC::s_velComp; bool isOutflow = ((a_side==Side::Hi) && (a_idir==m_flowDir)); bool isInflow = ((a_side==Side::Lo) && (a_idir==m_flowDir)); bool isSlipWall = ((a_idir!=m_flowDir) && (a_idir != velcomp) && ((m_doSlipWallsHi[a_idir]==1 && a_side == Side::Hi)||(m_doSlipWallsLo[a_idir]==1 && a_side == Side::Lo))); // bool isVelNeum = (isOutflow || isSlipWall); if (isSlipWall) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else if (isInflow) { DirichletPoissonDomainBC diriBC; if (velcomp==m_flowDir) { if (!m_doJet1PoiseInflow) { diriBC.setValue(m_jet1inflowVel); } else if (m_doJet1PoiseInflow) { diriBC.setFunction(m_jet1PoiseInflowFunc); } } else { diriBC.setValue(0.0); } //basefab flux--EBAMRPoissonOp::applyDomainFlux calls this directly for viscous operator if (s_higherOrderHelmBC) { diriBC.getHigherOrderFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else { diriBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } } else if (isOutflow) { if (!m_doJet2) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.); neumannBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else if (m_doJet2) { const RealVect tubeCenter = m_jet2PoiseInflowFunc->getTubeCenter(); Real tubeRadius = m_jet2PoiseInflowFunc->getTubeRadius(); CH_assert(a_phi.nComp() == 1); // start hardwire Real wallThickness = 0.075; Real bcFactor = 0.5; // % of outflow face to be set to inflow condition ParmParse pp; pp.get("wall_thickness",wallThickness); tubeRadius += wallThickness * bcFactor /2.0; // end hardwire for (int comp=0; comp<a_phi.nComp(); comp++) { const Box& box = a_faceFlux.box(); int iside = -1; //a_side == Side::Hi BoxIterator bit(box); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); RealVect loc = EBArith::getIVLocation(iv,a_dx,a_probLo); loc[a_idir] -= iside * 0.5 * a_dx[a_idir];//point is now at the face center CH_assert(loc[m_flowDir] == tubeCenter[m_flowDir]); bool isInsideTube = false; Real radius = m_jet2PoiseInflowFunc->getRadius(loc); if (radius <= tubeRadius) { isInsideTube = true; } if (isInsideTube) // Dirichlet { Real value = 0.0; // takes care of tangential comps if (velcomp == m_flowDir) { if (m_doJet2PoiseInflow) { value = m_jet2PoiseInflowFunc->getVel(radius)[m_flowDir]; } else if (!(m_doJet2PoiseInflow)) { value = m_jet2inflowVel; } } if (s_higherOrderHelmBC) { IntVect iv1 = bit(); Real phi0 = a_phi(iv1,comp); iv1[a_idir] += iside; Real phi1 = a_phi(iv1,comp); iv1[a_idir] -= iside; a_faceFlux(iv,comp) = -iside*(8.0*value + phi1 - 9.0*phi0)/(3.0*a_dx[a_idir]); } else if (!s_higherOrderHelmBC) { Real ihdx = 2.0 / a_dx[a_idir]; Real phiVal = a_phi(iv,comp); a_faceFlux(iv,comp) = iside * ihdx * (phiVal - value); } } else if (!isInsideTube) // Neumann { Real value = 0.0; a_faceFlux(iv,comp) = iside * value; } } } } } else { //wall bc no slip DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); if (s_higherOrderHelmBC) { diriBC.getHigherOrderFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else { diriBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } } }
//////called by MAC projection solver for domain bc on phi void InflowOutflowPoissonDomainBC::getFaceFlux(BaseFab<Real>& a_faceFlux, const BaseFab<Real>& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useHomogeneous) { //for phi: outflow dirichlet. inflow neumann bool isOutflow= (a_side==Side::Hi) && (a_idir==m_flowDir); if (!isOutflow) { NeumannPoissonDomainBC neumannBC; neumannBC.setValue(0.0); neumannBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else { if (!(m_doJet2)) { DirichletPoissonDomainBC diriBC; diriBC.setValue(0.0); diriBC.getFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); // diriBC.getHigherOrderFaceFlux(a_faceFlux, a_phi, a_probLo, a_dx, a_idir, a_side, a_dit, a_time, a_useHomogeneous); } else if (m_doJet2) { const RealVect tubeCenter = m_jet2PoiseInflowFunc->getTubeCenter(); Real tubeRadius = m_jet2PoiseInflowFunc->getTubeRadius(); // start hardwire Real wallThickness = 0.075; Real bcFactor = 0.5; // % of outflow face to be set to inflow condition ParmParse pp; pp.get("wall_thickness",wallThickness); tubeRadius += wallThickness * bcFactor /2.0; // end hardwire CH_assert(a_phi.nComp() == 1); for (int comp=0; comp<a_phi.nComp(); comp++) { const Box& box = a_faceFlux.box(); int iside = -1; // a_side == Side::Hi in this loop Real value = 0.0; BoxIterator bit(box); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); RealVect loc = EBArith::getIVLocation(iv,a_dx,a_probLo); loc[a_idir] -= iside * 0.5 * a_dx[a_idir]; //loc is now at the face center CH_assert(loc[m_flowDir] == tubeCenter[m_flowDir]); bool isInsideTube = false; Real radius = m_jet2PoiseInflowFunc->getRadius(loc); if (radius <= tubeRadius) { isInsideTube = true; } if (isInsideTube) { a_faceFlux(iv,comp) = iside * value; //Neumann } else if (!(isInsideTube)) { Real ihdx = 2.0 / a_dx[a_idir]; Real phiVal = a_phi(iv,comp); a_faceFlux(iv,comp) = iside * ihdx * (phiVal - value); //Dirichlet } } } } } }
void BaseFab<T>::maskLT (BaseFab<int>& mask) const { mask.setVal(0); }
void BaseFab<T>::maskLT (BaseFab<int> & mask) { mask.dataPtr(); }
void NeumannConductivityDomainBC:: getFaceFlux(BaseFab<Real>& a_faceFlux, const BaseFab<Real>& a_phi, const RealVect& a_probLo, const RealVect& a_dx, const int& a_idir, const Side::LoHiSide& a_side, const DataIndex& a_dit, const Real& a_time, const bool& a_useHomogeneous) { CH_TIME("NeumannPoissonDomainBC::getFaceFlux"); CH_assert(a_phi.nComp() == 1); for (int comp=0; comp<a_phi.nComp(); comp++) { const Box& box = a_faceFlux.box(); int iside; if (a_side == Side::Lo) { iside = 1; } else { iside = -1; } if (a_useHomogeneous) { Real value = 0.0; a_faceFlux.setVal(iside * value); } else { if (m_isFunction) { BoxIterator bit(box); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); RealVect point = EBArith::getIVLocation(iv,a_dx,a_probLo); point[a_idir] -= iside * 0.5 * a_dx[a_idir];//point is now at the face center RealVect normal = RealVect::Zero; normal[a_idir] = iside; a_faceFlux(iv,comp) = iside * m_flux->value(iv,a_dit,point,normal,a_time,comp); } } else { if (m_onlyHomogeneous) { MayDay::Error("NeumannPoissonDomainBC::getFaceFlux called with undefined inhomogeneous BC"); } Real value = m_value; a_faceFlux.setVal(iside * value); } } } //again, following the odd convention of EBAMRPoissonOp //(because I am reusing its BC classes), //the input flux here is CELL centered and the input box //is the box adjacent to the domain boundary on the valid side. //because I am not insane (yet) I will just shift the flux's box //over and multiply by the appropriate coefficient a_faceFlux.shiftHalf(a_idir, -sign(a_side)); const Box& faceBox = a_faceFlux.box(); const BaseFab<Real>& regCoef = (*m_bcoef)[a_dit][a_idir].getSingleValuedFAB(); int isrc = 0; int idst = 0; int inum = 1; FORT_MULTIPLYTWOFAB(CHF_FRA(a_faceFlux), CHF_CONST_FRA(regCoef), CHF_BOX(faceBox), CHF_INT(isrc),CHF_INT(idst),CHF_INT(inum)); //shift flux back to cell centered land a_faceFlux.shiftHalf(a_idir, sign(a_side)); }