// --------------------------------------------------------- void NodeQCFI::coarseFineInterp(LevelData<NodeFArrayBox>& a_phiFine, const LevelData<NodeFArrayBox>& a_phiCoarse, bool a_inhomogeneous) { CH_assert(isDefined()); CH_assert(a_phiFine.nComp() == m_ncomp); CH_assert(a_phiCoarse.nComp() == m_ncomp); if (m_coarsenings == 1) { m_qcfi2[0]->coarseFineInterp(a_phiFine, a_phiCoarse); } else // m_coarsenings >= 2 { // if m_coarsenings == 2: // m_qcfi2[1] = new NodeQuadCFInterp2(a_grids, true); // m_qcfi2[0] = new NodeQuadCFInterp2(a_grids.coarsen(2), false); // m_inter[0] = new LevelData(a_grids.coarsen(2)); // m_qcfi2[0] interpolates m_inter[0] from a_phiCoarse on all of it. // m_qcfi2[1] interpolates a_phiFine from m_inter[0] on interface only. m_qcfi2[0]->coarseFineInterp(*m_inter[0], a_phiCoarse); m_inter[0]->exchange(m_inter[0]->interval()); // Set domain and dx for coarsest level refined by 2. ProblemDomain domain(m_domainPenultimate); Real dx = m_dxPenultimate; bool homogeneous = !a_inhomogeneous; const DisjointBoxLayout& dbl0 = m_inter[0]->disjointBoxLayout(); for (DataIterator dit = dbl0.dataIterator(); dit.ok(); ++dit) { m_bc((*m_inter[0])[dit()], dbl0.get(dit()), domain, dx, homogeneous); } for (int interlev = 1; interlev < m_coarsenings - 1; interlev++) { m_qcfi2[interlev]->coarseFineInterp(*m_inter[interlev], *m_inter[interlev-1]); m_inter[interlev]->exchange(m_inter[interlev]->interval()); domain.refine(2); dx *= 0.5; const DisjointBoxLayout& dbl = m_inter[interlev]->disjointBoxLayout(); for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit) { m_bc((*m_inter[interlev])[dit()], dbl.get(dit()), domain, dx, homogeneous); } } m_qcfi2[m_coarsenings-1]->coarseFineInterp(a_phiFine, *m_inter[m_coarsenings-2]); // Don't need to set boundary conditions for a_phiFine // because the calling function will do that. } }
void VCAMRPoissonOp2::residualI(LevelData<FArrayBox>& a_lhs, const LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs, bool a_homogeneous) { CH_TIME("VCAMRPoissonOp2::residualI"); LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi; Real dx = m_dx; const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout(); DataIterator dit = phi.dataIterator(); { CH_TIME("VCAMRPoissonOp2::residualIBC"); for (dit.begin(); dit.ok(); ++dit) { m_bc(phi[dit], dbl[dit()],m_domain, dx, a_homogeneous); } } phi.exchange(phi.interval(), m_exchangeCopier); for (dit.begin(); dit.ok(); ++dit) { const Box& region = dbl[dit()]; const FluxBox& thisBCoef = (*m_bCoef)[dit]; #if CH_SPACEDIM == 1 FORT_VCCOMPUTERES1D #elif CH_SPACEDIM == 2 FORT_VCCOMPUTERES2D #elif CH_SPACEDIM == 3 FORT_VCCOMPUTERES3D #else This_will_not_compile! #endif (CHF_FRA(a_lhs[dit]), CHF_CONST_FRA(phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA((*m_aCoef)[dit]), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA(thisBCoef[0]), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA(thisBCoef[1]), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA(thisBCoef[2]), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_BOX(region), CHF_CONST_REAL(m_dx)); } // end loop over boxes }
void EBMGInterp::pwlInterp(LevelData<EBCellFAB>& a_fineData, const LevelData<EBCellFAB>& a_coarData, const Interval& a_variables) { CH_TIME("EBMGInterp::pwlInterp"); CH_assert(a_fineData.ghostVect() == m_ghost); CH_assert(a_coarData.ghostVect() == m_ghost); CH_assert(m_doLinear); //otherwise stencils have not been defined if (m_layoutChanged) { if (m_coarsenable) { CH_TIME("EBMGInterp::pwlInterp::coarsenable"); EBCellFactory ebcellfact(m_buffEBISL); LevelData<EBCellFAB> coarsenedFineData(m_buffGrids, m_nComp, m_ghost, ebcellfact); a_coarData.copyTo(a_variables, coarsenedFineData, a_variables); fillGhostCellsPWC(coarsenedFineData, m_buffEBISL, m_coarDomain); for (DataIterator dit = m_fineGrids.dataIterator(); dit.ok(); ++dit) { //does incrementonly = true pwlInterpFAB(a_fineData[dit()], m_buffGrids[dit()], coarsenedFineData[dit()], dit(), a_variables); } } else { CH_TIME("EBMGInterp::pwlInterp::uncoarsenable"); EBCellFactory ebcellfact(m_buffEBISL); fillGhostCellsPWC((LevelData<EBCellFAB>&)a_coarData, m_coarEBISL, m_coarDomain); LevelData<EBCellFAB> refinedCoarseData(m_buffGrids, m_nComp, m_ghost, ebcellfact); for (DataIterator dit = m_coarGrids.dataIterator(); dit.ok(); ++dit) { refinedCoarseData[dit()].setVal(0.); pwlInterpFAB(refinedCoarseData[dit()], m_coarGrids[dit()], a_coarData[dit()], dit(), a_variables); } EBAddOp op; refinedCoarseData.copyTo(a_variables, a_fineData, a_variables, m_copierRCtoF, op); } } else { pwcInterpMG(a_fineData, a_coarData, a_variables); } }
void MappedLevelFluxRegister::setToZero() { CH_TIME("MappedLevelFluxRegister::setToZero"); if (m_isDefined & FluxRegCoarseDefined) { for (DataIterator d = m_coarFlux.dataIterator(); d.ok(); ++d) { m_coarFlux[d].setVal(0.0); } } if (m_isDefined & FluxRegFineDefined) { for (DataIterator d = m_fineFlux.dataIterator(); d.ok(); ++d) { m_fineFlux[d].setVal(0.0); } } }
void PoisselleTube:: initializeVelocity(LevelData<EBCellFAB>& a_velocity, const DisjointBoxLayout& a_grids, const EBISLayout& a_ebisl, const ProblemDomain& a_domain, const RealVect& a_origin, const Real& a_time, const RealVect& a_dx) const { for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_grids.get(dit())); for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit) { RealVect xval = EBArith::getVofLocation(vofit() , a_dx, RealVect::Zero); for (int idir = 0; idir < SpaceDim; idir++) { //bogus values for normal and time because they do not matter Real velComp = m_bcval[idir].value(xval, RealVect::Zero, a_time, idir); a_velocity[dit()](vofit(), idir) = velComp; } } } }
void LevelPluto::setGridLevel() { CH_TIME("LevelPluto::setGrid"); m_structs_grid.define(m_grids); #if GEOMETRY != CARTESIAN m_dV.define(m_grids,CHOMBO_NDV,m_numGhost*IntVect::Unit); #endif Real dlMinLoc = 1.e30; for (DataIterator dit = m_grids.dataIterator(); dit.ok(); ++dit) { // The current box Box curBox = m_grids.get(dit()); struct GRID* grid = m_structs_grid[dit].getGrid(); #if GEOMETRY != CARTESIAN FArrayBox& curdV = m_dV[dit()]; #else FArrayBox curdV; #endif m_patchPluto->setGrid(curBox, grid, curdV); for (int idir = 0; idir < SpaceDim; idir++) dlMinLoc = Min(dlMinLoc,grid[idir].dl_min); } #if (GEOMETRY == CARTESIAN) || (GEOMETRY == CYLINDRICAL) D_EXPAND(m_dl_min = m_dx; ,
void NoFlowVortex:: initializeVelocity(LevelData<EBCellFAB>& a_velocity, const DisjointBoxLayout& a_grids, const EBISLayout& a_ebisl, const ProblemDomain& a_domain, const RealVect& a_origin, const Real& a_time, const RealVect& a_dx) const { Real pi = 4.0*atan(1.0); for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { IntVectSet ivsBox(a_grids.get(dit())); for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit) { RealVect xval, velpt; getXVal(xval, a_origin,vofit(), a_dx); getVelPt(velpt, xval, pi); for (int idir = 0; idir < SpaceDim; idir++) { a_velocity[dit()](vofit(), idir) = velpt[idir]; } } } }
// ----------------------------------------------------------------------------- // Interpolate ghosts at CF interface using zeros on coarser grids. // ----------------------------------------------------------------------------- void homogeneousCFInterp (LevelData<FArrayBox>& a_phif, const RealVect& a_fineDx, const RealVect& a_crseDx, const CFRegion& a_cfRegion, const IntVect& a_applyDirs) { CH_TIME("homogeneousCFInterp (full level)"); // Loop over grids, directions, and sides and call the worker function. DataIterator dit = a_phif.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { if (a_phif[dit].box().isEmpty()) continue; for (int dir = 0; dir < SpaceDim; ++dir) { if (a_applyDirs[dir] == 0) continue; SideIterator sit; for (sit.begin(); sit.ok(); sit.next()) { homogeneousCFInterp(a_phif, dit(), dir, sit(), a_fineDx[dir], a_crseDx[dir], a_cfRegion); } } } }
void EBPoissonOp:: getJacobiRelaxCoeff(LevelData<EBCellFAB>& a_relaxCoeff) { // Diagonal weight for Jacobi on regular grid Real weightBase = m_alpha; for (int idir = 0; idir < SpaceDim; idir++) { weightBase += -2.0 * m_beta * m_invDx2[idir]; } weightBase = 1.0 / weightBase; // Weight for plain (non-weighted) Jacobi Real weightRegular = EBPOISSONOP_JACOBI_OMEGA * weightBase; // ... for weighted Jacobi for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit) { // Most of the grid is regular, so set the regular weighting by default a_relaxCoeff[dit()].setVal(weightRegular); // Walk the EB cells, and correct their weighting const BaseIVFAB<Real>& curAlphaWeight = m_alphaDiagWeight[dit()]; const BaseIVFAB<Real>& curBetaWeight = m_betaDiagWeight[dit()]; VoFIterator& ebvofit = m_vofItIrreg[dit()]; for (ebvofit.reset(); ebvofit.ok(); ++ebvofit) { const VolIndex& vof = ebvofit(); Real weightIrreg = EBPOISSONOP_JACOBI_OMEGA / (m_alpha*curAlphaWeight(vof, 0) + m_beta*curBetaWeight(vof, 0)); a_relaxCoeff[dit()](vof, 0) = weightIrreg; } } }
// --------------------------------------------------------- void AMRNavierStokes::computeLapVel(LevelData<FArrayBox>& a_lapVel, LevelData<FArrayBox>& a_vel, const LevelData<FArrayBox>* a_crseVelPtr) { // set BC's VelBCHolder velBC(m_physBCPtr->viscousVelFuncBC()); bool isHomogeneous = false; m_velocityAMRPoissonOp.applyOp(a_lapVel, a_vel, a_crseVelPtr, isHomogeneous, velBC); // may need to extend lapVel to cover ghost cells as well { BCHolder viscBC = m_physBCPtr->viscousFuncBC(); const DisjointBoxLayout& grids = a_lapVel.getBoxes(); DataIterator dit = a_lapVel.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { viscBC(a_lapVel[dit], grids[dit], m_problem_domain, m_dx, false); // not homogeneous } } // finally, do exchange a_lapVel.exchange(a_lapVel.interval()); }
// --------------------------------------------------------- void AMRNavierStokes::computeLapScal(LevelData<FArrayBox>& a_lapScal, LevelData<FArrayBox>& a_scal, const BCHolder& a_physBC, const LevelData<FArrayBox>* a_crseScalPtr) { m_scalarsAMRPoissonOp.setBC(a_physBC); bool isHomogeneous = false; if (a_crseScalPtr != NULL) { m_scalarsAMRPoissonOp.AMROperatorNF(a_lapScal, a_scal, *a_crseScalPtr, isHomogeneous); } else { m_scalarsAMRPoissonOp.applyOpI(a_lapScal, a_scal, isHomogeneous); } BCHolder viscBC = m_physBCPtr->viscousFuncBC(); DataIterator dit = a_lapScal.dataIterator(); const DisjointBoxLayout& grids = a_lapScal.getBoxes(); for (dit.reset(); dit.ok(); ++dit) { viscBC(a_lapScal[dit], grids[dit], m_problem_domain, m_dx, false); // not homogeneous } // finally, do exchange a_lapScal.exchange(a_lapScal.interval()); }
void EBCoarToFineRedist:: defineDataHolders() { CH_TIME("EBCoarToFineRedist::defineDataHolders"); //make mass buffers BaseIVFactory<Real> factCoar(m_ebislCoar, m_setsCoar); IntVect noghost = IntVect::Zero; m_regsCoar.define(m_gridsCoar, m_nComp, noghost, factCoar); BaseIVFactory<Real> factCedFine(m_ebislCedFine, m_setsCedFine); m_regsCedFine.define(m_gridsCedFine, m_nComp, m_redistRad*IntVect::Unit, factCedFine); EBCellFactory ebcellfact(m_ebislCedFine); m_densityCedFine.define(m_gridsCedFine, 1, 2*m_redistRad*IntVect::Unit, ebcellfact); //define the stencils with volume weights. //if you want mass weights or whatever, use reset weights m_stenCedFine.define(m_gridsCedFine); m_volumeStenc.define(m_gridsCedFine); m_standardStenc.define(m_gridsCedFine); RedistStencil stenCedFine(m_gridsCedFine, m_ebislCedFine, m_domainCoar, m_redistRad); for (DataIterator ditCedF = m_gridsCedFine.dataIterator(); ditCedF.ok(); ++ditCedF) { BaseIVFAB<VoFStencil>& stenFAB = m_stenCedFine[ditCedF()]; BaseIVFAB<VoFStencil>& volStenFAB = m_volumeStenc[ditCedF()]; BaseIVFAB<VoFStencil>& stanStenFAB = m_standardStenc[ditCedF()]; const EBISBox& ebisBox = m_ebislCedFine[ditCedF()]; const IntVectSet& ivs = m_setsCedFine[ditCedF()]; const BaseIVFAB<VoFStencil>& rdStenFAB = stenCedFine[ditCedF()]; const Box& gridCedFine = m_gridsCedFine.get(ditCedF()); stenFAB.define(ivs, ebisBox.getEBGraph(), 1); volStenFAB.define(ivs, ebisBox.getEBGraph(), 1); stanStenFAB.define(ivs, ebisBox.getEBGraph(), 1); for (VoFIterator vofit(ivs, ebisBox.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& srcVoF = vofit(); VoFStencil newStencil; const VoFStencil& stanSten = rdStenFAB(srcVoF, 0); for (int istan = 0; istan < stanSten.size(); istan++) { const VolIndex& dstVoF = stanSten.vof(istan); const Real& weight = stanSten.weight(istan); if (gridCedFine.contains(dstVoF.gridIndex())) { newStencil.add(dstVoF, weight); } } stenFAB(srcVoF, 0) = newStencil; //need to keep these around to get mass redist right volStenFAB(srcVoF, 0) = newStencil; stanStenFAB(srcVoF,0) = stanSten; } } }
void EBLevelAdvect:: computeNormalVel(LevelData<EBCellFAB>& a_normalVel, const LevelData<EBFluxFAB>& a_advectionVel, const LayoutData<Vector<BaseIVFAB<Real> * > >& a_coveredVeloLo, const LayoutData<Vector<BaseIVFAB<Real> * > >& a_coveredVeloHi, const LayoutData<Vector<Vector<VolIndex> > >& a_coveredFaceLo, const LayoutData<Vector<Vector<VolIndex> > >& a_coveredFaceHi) const { CH_TIME("EBLevelAdvect::computeNormalVel"); for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit) { const Box& cellBox = m_thisGrids.get(dit()); Box grownBox = grow(cellBox, 1); grownBox &= m_domain; m_ebPatchAdvect[dit]->averageVelToCC(a_normalVel[dit()], a_advectionVel[dit()], a_coveredVeloLo[dit()], a_coveredVeloHi[dit()], a_coveredFaceLo[dit()], a_coveredFaceHi[dit()], grownBox); } }
/// Set up initial conditions void SWIBC::initializeBdry(LevelData<FArrayBox>& a_B) { const Real tmpVal = 0.0; const Real tmpVal2 = 100; for (DataIterator dit = a_B.dataIterator(); dit.ok(); ++dit) { // Storage for current grid FArrayBox& B = a_B[dit()]; // Box of current grid Box bBox = B.box(); bBox &= m_domain; // Set up initial condition in this grid FORT_LINELASTSETFAB(CHF_FRA1(B,4), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,5), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,6), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal2)); } }
int scopingTest() { Vector<Box> boxes; int retflag = 0; setGrids(boxes); LevelData<FArrayBox> levelFab; makeLevelData(boxes, levelFab); const DisjointBoxLayout& dbl = levelFab.getBoxes(); DataIterator dit = dbl.dataIterator(); int ivec = 0; for (dit.begin(); dit.ok(); ++dit) { if (!dbl.check(dit())) { if (verbose) pout() << indent2 << pgmname << ": failed at box " << ivec << endl; retflag = 1; } else { levelFab[dit].setVal(0.); } if (retflag > 0) break; ivec++; } return retflag; }
//----------------------------------------------------------------------- // AMR Factory define function, with coefficient data allocated automagically // for operators. void VCAMRPoissonOp2Factory:: define(const ProblemDomain& a_coarseDomain, const Vector<DisjointBoxLayout>& a_grids, const Vector<int>& a_refRatios, const Real& a_coarsedx, BCHolder a_bc, const IntVect& a_ghostVect) { // This just allocates coefficient data, sets alpha = beta = 1, and calls // the other define() method. Vector<RefCountedPtr<LevelData<FArrayBox> > > aCoef(a_grids.size()); Vector<RefCountedPtr<LevelData<FluxBox> > > bCoef(a_grids.size()); for (int i = 0; i < a_grids.size(); ++i) { aCoef[i] = RefCountedPtr<LevelData<FArrayBox> >( new LevelData<FArrayBox>(a_grids[i], 1, a_ghostVect)); bCoef[i] = RefCountedPtr<LevelData<FluxBox> >( new LevelData<FluxBox>(a_grids[i], 1, a_ghostVect)); // Initialize the a and b coefficients to 1 for starters. for (DataIterator dit = aCoef[i]->dataIterator(); dit.ok(); ++dit) { (*aCoef[i])[dit()].setVal(1.0); for (int idir = 0; idir < SpaceDim; ++idir) (*bCoef[i])[dit()][idir].setVal(1.0); } } Real alpha = 1.0, beta = 1.0; define(a_coarseDomain, a_grids, a_refRatios, a_coarsedx, a_bc, alpha, aCoef, beta, bCoef); }
// --------------------------------------------------------- // 28 March 2003: // This is called by other functions, and should not be called directly. Real integral(const BoxLayoutData<NodeFArrayBox>& a_layout, const Real a_dx, const Interval& a_interval, bool a_verbose) { Real integralTotal = 0.; for (DataIterator it = a_layout.dataIterator(); it.ok(); ++it) { const NodeFArrayBox& thisNfab = a_layout[it()]; const Box& thisBox(a_layout.box(it())); // CELL-centered Real thisNfabIntegral = integral(thisNfab, a_dx, thisBox, a_interval.begin(), a_interval.size()); integralTotal += thisNfabIntegral; } # ifdef CH_MPI Real recv; // add up int result = MPI_Allreduce(&integralTotal, &recv, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); if (result != MPI_SUCCESS) { //bark!!! MayDay::Error("sorry, but I had a communication error on integral"); } integralTotal = recv; # endif return integralTotal; }
// ----------------------------------------------------------------------------- // Semi-implicitly handles the gravity forcing and projection. // The old* inputs should be the values at t^n. // The new* inputs should be the updated values from the TGA solver. // ----------------------------------------------------------------------------- void AMRNavierStokes::doCCIGProjection (LevelData<FArrayBox>& a_newVel, LevelData<FArrayBox>& a_newB, const LevelData<FArrayBox>& a_oldVel, const LevelData<FArrayBox>& a_oldB, const LevelData<FluxBox>& a_advVel, const Real a_oldTime, const Real a_dt, const bool a_doProj) { CH_TIME("AMRNavierStokes::doCCIGProjection"); const Real halfTime = a_oldTime + 0.5 * a_dt; const Real newTime = a_oldTime + 1.0 * a_dt; const Real dummyTime = -1.0e300; const GeoSourceInterface& geoSource = *(m_levGeoPtr->getGeoSourcePtr()); const RealVect& dx = m_levGeoPtr->getDx(); const DisjointBoxLayout& grids = a_newVel.getBoxes(); DataIterator dit = grids.dataIterator(); // 1. Compute the background buoyancy, N, Dinv, etc... // Fill the FC background buoyancy field. LevelData<FluxBox> bbar(grids, 1, 2*IntVect::Unit); for (dit.reset(); dit.ok(); ++dit) { FluxBox& bbarFB = bbar[dit]; D_TERM(m_physBCPtr->setBackgroundScalar(bbarFB[0], 0, *m_levGeoPtr, dit(), dummyTime);, m_physBCPtr->setBackgroundScalar(bbarFB[1], 0, *m_levGeoPtr, dit(), dummyTime);,
// --------------------------------------------------------- void levelDivergenceMAC(LevelData<FArrayBox>& a_div, const LevelData<FluxBox>& a_uEdge, const Real a_dx) { // silly way to do this until i figure out a better // way to make this dimensionally-independent CH_assert (a_uEdge.nComp() >= a_div.nComp()); DataIterator dit = a_div.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { a_div[dit()].setVal(0.0); const FluxBox& thisFluxBox = a_uEdge[dit()]; Box cellBox(thisFluxBox.box()); // just to be sure we don't accidentally trash memory... cellBox &= a_div[dit()].box(); // now loop over coordinate directions and add to divergence for (int dir=0; dir<SpaceDim; dir++) { const FArrayBox& uEdgeDir = thisFluxBox[dir]; FORT_DIVERGENCE(CHF_CONST_FRA(uEdgeDir), CHF_FRA(a_div[dit()]), CHF_BOX(cellBox), CHF_CONST_REAL(a_dx), CHF_INT(dir)); } } }
// this preconditioner first initializes phihat to (IA)phihat = rhshat // (diagonization of L -- A is the matrix version of L) // then smooths with a couple of passes of levelGSRB void VCAMRPoissonOp2::preCond(LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs) { CH_TIME("VCAMRPoissonOp2::preCond"); // diagonal term of this operator in: // // alpha * a(i) // + beta * sum_over_dir (b(i-1/2*e_dir) + b(i+1/2*e_dir)) / (dx*dx) // // The inverse of this is our initial multiplier. int ncomp = a_phi.nComp(); CH_assert(m_lambda.isDefined()); CH_assert(a_rhs.nComp() == ncomp); CH_assert(m_bCoef->nComp() == ncomp); // Recompute the relaxation coefficient if needed. resetLambda(); // don't need to use a Copier -- plain copy will do DataIterator dit = a_phi.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { // also need to average and sum face-centered bCoefs to cell-centers Box gridBox = a_rhs[dit].box(); // approximate inverse a_phi[dit].copy(a_rhs[dit]); a_phi[dit].mult(m_lambda[dit], gridBox, 0, 0, ncomp); } relax(a_phi, a_rhs, 2); }
void initData(LevelData<FArrayBox>& a_data, const Real a_dx) { DataIterator dit = a_data.dataIterator(); const DisjointBoxLayout& interiorBoxes = a_data.getBoxes(); for (dit.begin(); dit.ok(); ++dit) { // first set to a bogus value which will persist in ghost cells // after initialization a_data[dit()].setVal(1.0e9); // this will be slow, but who cares? FArrayBox& localData = a_data[dit()]; BoxIterator boxIt(interiorBoxes[dit()]); Real localVal; for (boxIt.begin(); boxIt.ok(); ++boxIt) { const IntVect& loc = boxIt(); for (int comp=0; comp<localData.nComp(); comp++) { localVal = dataVal(loc, comp); localData(loc, comp) = localVal; } } } }
// --------------------------------------------------------- // 27 March 2003: // This is called by other functions, and should not be called directly. Real maxnorm(const BoxLayoutData<NodeFArrayBox>& a_layout, const Interval& a_interval, bool a_verbose) { Real normTotal = 0.; // a_p == 0: max norm for (DataIterator it = a_layout.dataIterator(); it.ok(); ++it) { const Box& thisBox(a_layout.box(it())); // CELL-centered const NodeFArrayBox& thisNfab = a_layout[it()]; Real thisNfabNorm = maxnorm(thisNfab, thisBox, a_interval.begin(), a_interval.size()); if (a_verbose) cout << "maxnorm(" << thisBox << ") = " << thisNfabNorm << endl; normTotal = Max(normTotal, thisNfabNorm); } # ifdef CH_MPI Real recv; int result = MPI_Allreduce(&normTotal, &recv, 1, MPI_CH_REAL, MPI_MAX, Chombo_MPI::comm); if (result != MPI_SUCCESS) { //bark!!! MayDay::Error("sorry, but I had a communication error on maxnorm"); } normTotal = recv; # endif return normTotal; }
void EBCompositeCCProjector:: averageVelocityToFaces(Vector<LevelData<EBFluxFAB>* >& a_macVeloc, Vector<LevelData<EBCellFAB>* >& a_velocity) { CH_TIME("EBCompositeCCProjector::averageVelocityToFaces"); //interpolate and then send stuff on through to level function // int ncomp = a_velocity[0]->nComp(); Interval interv(0, SpaceDim-1); Vector<LevelData<EBCellFAB> *> amrPhi = m_macProjector->getPhi(); // Real time = 0.; for (int ilev = 0; ilev < m_numLevels; ilev++) { if (ilev > 0) { //so it can be reused quadcfi is a one-variable animal //when we have ebalias, we can accomplish this without copies. //for now, tough luck //use phi for scratch space LevelData<EBCellFAB>& phiCoar = *amrPhi[ilev-1]; LevelData<EBCellFAB>& phiFine = *amrPhi[ilev ]; for (int idir = 0; idir < SpaceDim; idir++) { Interval phiInterv(0, 0); Interval velInterv(idir, idir); a_velocity[ilev-1]->copyTo(velInterv, phiCoar, phiInterv); a_velocity[ilev ]->copyTo(velInterv, phiFine, phiInterv); m_quadCFI[ilev]->interpolate(phiFine, phiCoar, phiInterv); // m_pwlCFI[ilev]->interpolate(phiFine, // phiCoar, // phiCoar, // time, // time, // time, // phiInterv); //on copy back, we need ghost cells, so do the data iterator loop for (DataIterator dit = phiFine.dataIterator(); dit.ok(); ++dit) { Box region = phiFine[dit()].getRegion(); //includes ghost cells (*a_velocity[ilev])[dit()].copy(region, velInterv, region, phiFine[dit()], phiInterv); } EBLevelDataOps::setVal(phiFine, 0.0); EBLevelDataOps::setVal(phiCoar, 0.0); } } a_velocity[ilev]->exchange(interv); ccpAverageVelocityToFaces(*a_macVeloc[ilev], *a_velocity[ilev], m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(), m_eblg[ilev].getDomain(), m_dx[ilev], *m_eblg[ilev].getCFIVS()); } }
void EBCoarToFineRedist:: setToZero() { CH_TIME("EBCoarToFineRedist::setToZero"); for (DataIterator dit = m_gridsCedFine.dataIterator(); dit.ok(); ++dit) { m_regsCedFine[dit()].setVal(0.0); } for (DataIterator dit = m_gridsCoar.dataIterator(); dit.ok(); ++dit) { m_regsCoar[dit()].setVal(0.0); } }
void EBFineToCoarRedist:: setToZero() { CH_TIME("EBFineToCoarRedist::setToZero"); for (DataIterator dit = m_gridsRefCoar.dataIterator(); dit.ok(); ++dit) { m_regsRefCoar[dit()].setVal(0.0); } for (DataIterator dit = m_gridsFine.dataIterator(); dit.ok(); ++dit) { m_regsFine[dit()].setVal(0.0); } }
void EBCoarseAverage::average(LevelData<EBFluxFAB>& a_coarData, const LevelData<EBFluxFAB>& a_fineData, const Interval& a_variables) { CH_TIME("EBCoarseAverage::average(LD<EBFluxFAB>)"); LevelData<EBFluxFAB> coarFiData; LevelData<EBFluxFAB> fineBuffer; CH_assert(isDefined()); { CH_TIME("buffer allocation"); EBFluxFactory factCoFi(m_eblgCoFi.getEBISL()); coarFiData.define( m_eblgCoFi.getDBL(), m_nComp, IntVect::Zero, factCoFi); if (m_useFineBuffer) { EBFluxFactory factFine(m_eblgFine.getEBISL()); fineBuffer.define(m_eblgFine.getDBL(), m_nComp, IntVect::Zero, factFine); } } if (m_useFineBuffer) { CH_TIME("fine_copy"); a_fineData.copyTo(a_variables, fineBuffer, a_variables); } { CH_TIME("averaging"); for (DataIterator dit = m_eblgFine.getDBL().dataIterator(); dit.ok(); ++dit) { const EBFluxFAB* fineFABPtr = NULL; if (m_useFineBuffer) { fineFABPtr = &fineBuffer[dit()]; } else { fineFABPtr = &a_fineData[dit()]; } EBFluxFAB& cofiFAB = coarFiData[dit()]; const EBFluxFAB& fineFAB = *fineFABPtr; for (int idir = 0; idir < SpaceDim; idir++) { averageFAB(cofiFAB[idir], fineFAB[idir], dit(), a_variables, idir); } } } { CH_TIME("copy_coar"); coarFiData.copyTo(a_variables, a_coarData, a_variables); } }
int EBCompositeMACProjector:: project(Vector<LevelData<EBFluxFAB>* >& a_velocity, Vector<LevelData<EBFluxFAB>* >& a_gradient, const Real& a_gradCoef, const Real& a_divuCoef, const Vector<LevelData<BaseIVFAB<Real> >* >* a_boundaryVelo) { CH_TIME("EBCompositeMACProjector::project"); //compute divergence everywhere. This includes refluxing at coarse-fine boundaries kappaDivergence(m_divu, a_velocity, a_boundaryVelo); EBAMRDataOps::scale(m_divu,a_divuCoef); //make an initial guess initialize(m_phi); //solve laplacian phi = div u //zeroPhi=false is inconsequential in solveNoInit because of initialize above bool zeroPhi = false; m_solver.solveNoInit(m_phi, m_divu, m_numLevels-1, 0, zeroPhi); //compute grad phi. This includes replacing coarse grad phi //with average of fine at coarse-fine boundaries gradient(a_gradient, m_phi); enforceGradientBC(a_gradient,m_phi); EBAMRDataOps::scale(a_gradient,a_gradCoef); //average the gradient down to coarser levels EBAMRDataOps::averageDown(a_gradient,m_eblg,m_refRat); if (m_subtractOffMean) { //Subtract off mean of pressure so that convergence tests can make sense. //This is also useful if you are using initial guesses for m_phi with all Neumann bcs EBAMRDataOps::subtractOffMean(m_phi, m_eblg, m_refRat); } //u := u - grad phi for (int ilev = 0; ilev < m_numLevels; ilev++) { for (DataIterator dit = m_eblg[ilev].getDBL().dataIterator(); dit.ok(); ++dit) { for (int idir = 0; idir < SpaceDim; idir++) { EBFaceFAB& velFAB = (*a_velocity[ilev])[dit()][idir]; const EBFaceFAB& gradFAB = (*a_gradient[ilev])[dit()][idir]; velFAB -= gradFAB; } } } return m_solver.m_exitStatus; }
// ---------------------------------------------------------------- void EdgeToCell(const LevelData<FluxBox>& a_edgeData, LevelData<FArrayBox>& a_cellData) { // this is just a wrapper around the single-grid version DataIterator dit = a_edgeData.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { EdgeToCell(a_edgeData[dit()], a_cellData[dit()]); } }
// Set up data on this level after regridding void AMRLevelPluto::regrid(const Vector<Box>& a_newGrids) { CH_assert(allDefined()); if (s_verbosity >= 3) { pout() << "AMRLevelPluto::regrid " << m_level << endl; } // Save original grids and load balance m_level_grids = a_newGrids; m_grids = loadBalance(a_newGrids); if (s_verbosity >= 4) { // Indicate/guarantee that the indexing below is only for reading // otherwise an error/assertion failure occurs const DisjointBoxLayout& constGrids = m_grids; pout() << "new grids: " << endl; for (LayoutIterator lit = constGrids.layoutIterator(); lit.ok(); ++lit) { pout() << constGrids[lit()] << endl; } } // Save data for later DataIterator dit = m_UNew.dataIterator(); for(;dit.ok(); ++dit){ m_UOld[dit()].copy(m_UNew[dit()]); } // Reshape state with new grids IntVect ivGhost = m_numGhost*IntVect::Unit; m_UNew.define(m_grids,m_numStates,ivGhost); // Set up data structures levelSetup(); // Interpolate from coarser level if (m_hasCoarser) { AMRLevelPluto* amrGodCoarserPtr = getCoarserLevel(); m_fineInterp.interpToFine(m_UNew,amrGodCoarserPtr->m_UNew); } // Copy from old state m_UOld.copyTo(m_UOld.interval(), m_UNew, m_UNew.interval()); m_UOld.define(m_grids,m_numStates,ivGhost); }
void EBCoarToFineRedist:: resetWeights(const LevelData<EBCellFAB>& a_modifierCoar, const int& a_ivar) { CH_TIME("EBCoarToFineRedist::resetWeights"); Interval srcInterv(a_ivar, a_ivar); Interval dstInterv(0,0); a_modifierCoar.copyTo(srcInterv, m_densityCedFine, dstInterv); //set the weights to mass weighting if the modifier //is the fine density. for (DataIterator dit = m_gridsFine.dataIterator(); dit.ok(); ++dit) { const IntVectSet& coarSet = m_setsCedFine[dit()]; BaseIVFAB<VoFStencil>& massStenFAB = m_stenCedFine[dit()]; const BaseIVFAB<VoFStencil>& volStenFAB = m_volumeStenc[dit()]; const BaseIVFAB<VoFStencil>& stanStenFAB = m_standardStenc[dit()]; const EBISBox& ebisBoxCoar = m_ebislCedFine[dit()]; const EBCellFAB& modFAB = m_densityCedFine[dit()]; for (VoFIterator vofit(coarSet, ebisBoxCoar.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vofCoar = vofit(); const VoFStencil& stanSten = stanStenFAB(vofCoar, 0); const VoFStencil& volSten = volStenFAB(vofCoar, 0); VoFStencil newSten; for (int isten = 0; isten < volSten.size(); isten++) { const VolIndex& thatVoFCoar = volSten.vof(isten); Real weight = modFAB(thatVoFCoar, 0); //average fine weights onto coarse weight newSten.add(thatVoFCoar, weight); } //need normalize by the whole standard stencil Real sum = 0.0; for (int isten = 0; isten < stanSten.size(); isten++) { const VolIndex& thatVoFCoar = stanSten.vof(isten); Real weight = modFAB(thatVoFCoar, 0); Real volfrac = ebisBoxCoar.volFrac(thatVoFCoar); //it is weight*volfrac that is normalized sum += weight*volfrac; } if (Abs(sum) > 0.0) { Real scaling = 1.0/sum; newSten *= scaling; } massStenFAB(vofCoar, 0) = newSten; } } }