void getError(LevelData<EBCellFAB>& a_error, const EBISLayout& a_ebisl, const DisjointBoxLayout& a_dbl, const Real& a_dx) { EBCellFactory ebcellfact(a_ebisl); EBFluxFactory ebfluxfact(a_ebisl); a_error.define(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBCellFAB> divFCalc(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBCellFAB> divFExac(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBFluxFAB> faceFlux(a_dbl, 1, IntVect::Zero, ebfluxfact); for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { a_error[dit()].setVal(0.); divFCalc[dit()].setVal(0.); divFExac[dit()].setVal(0.); } setToExactDivFLD(divFExac, a_ebisl, a_dbl, a_dx); setToExactFluxLD(faceFlux, a_ebisl, a_dbl, a_dx); Interval interv(0, 0); faceFlux.exchange(interv); kappaDivergenceLD(divFCalc, faceFlux, a_ebisl, a_dbl, a_dx); for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { EBCellFAB& errorFAB = a_error[dit()]; EBCellFAB& exactFAB = divFExac[dit()]; EBCellFAB& calcuFAB = divFCalc[dit()]; errorFAB += calcuFAB; errorFAB -= exactFAB; } }
void Multigrid::avgDown( LevelData<double >& a_resc, const LevelData<double >& a_res ) { CH_TIMERS("Multigrid::avgDown"); // Conservative, finite-volume averaging from coarse to fine. BLIterator blit(m_bl); for (blit.begin();blit !=blit.end();++blit) { RectMDArray<double >& resc = a_resc[*blit]; resc.setVal(0.0); Box bxc = a_resc.getBoxLayout()[*blit]; const RectMDArray<double >& res = a_res[*blit]; for (int i = 0; i < (1 << DIM); i++) { resc += g_AvgDown[i](res,bxc); } } };
/// Set up initial conditions void SWIBC::initialize(LevelData<FArrayBox>& a_U) { // pout() << "SWIBC::initialize" << endl; CH_assert(m_isFortranCommonSet == true); CH_assert(m_isDefined == true); // Iterator of all grids in this level for (DataIterator dit = a_U.dataIterator(); dit.ok(); ++dit) { // Storage for current grid FArrayBox& U = a_U[dit()]; // Box of current grid Box uBox = U.box(); uBox &= m_domain; // Set up initial condition in this grid FORT_LEINITF(CHF_FRA(U), CHF_CONST_REAL(m_dx), CHF_BOX(uBox)); } }
// ------------------------------------------------------------ // version of 27 March 2003 Real integral(const LevelData<NodeFArrayBox>& a_phi, const ProblemDomain& a_domain, const DisjointBoxLayout* a_finerGridsPtr, const int a_nRefFine, const Real a_dx, const Interval a_comps, bool a_verbose) { const DisjointBoxLayout& grids = a_phi.getBoxes(); LayoutData< Vector<IntVectSet> > IVSVint, IVSVext; interiorBoundaryNodes(IVSVint, grids, a_domain); exteriorBoundaryNodes(IVSVext, IVSVint, grids); Real integralLevel = 0.; if (a_finerGridsPtr == NULL) { integralLevel = integral(a_phi, a_domain, IVSVext, a_dx, a_comps, a_verbose); } else { DisjointBoxLayout coarsenedFinerGrids; coarsen(coarsenedFinerGrids, *a_finerGridsPtr, a_nRefFine); LayoutData< Vector<IntVectSet> > IVSVintFinerCoarsened; interiorBoundaryNodes(IVSVintFinerCoarsened, grids, coarsenedFinerGrids, a_domain); integralLevel = integral(a_phi, a_domain, coarsenedFinerGrids, IVSVext, IVSVintFinerCoarsened, a_nRefFine, a_dx, a_comps, a_verbose); } return integralLevel; }
void EBLevelTGA:: setSourceGhostCells(LevelData<EBCellFAB>& a_src, const DisjointBoxLayout& a_grids, int a_lev) { int ncomp = a_src.nComp(); for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit) { const Box& grid = a_grids.get(dit()); const Box& srcBox = a_src[dit()].box(); for (int idir = 0; idir < SpaceDim; idir++) { for (SideIterator sit; sit.ok(); ++sit) { int iside = sign(sit()); Box bc_box = adjCellBox(grid, idir, sit(), 1); for (int jdir = 0; jdir < SpaceDim; jdir++) { //want corners too if (jdir != idir) { bc_box.grow(jdir, 1); } } //if fails might not have a ghost cell. bc_box &= m_eblg[a_lev].getDomain().domainBox(); CH_assert(srcBox.contains(bc_box)); if (grid.size(idir) >= 4) { FORT_HORESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()), CHF_BOX(bc_box), CHF_CONST_INT(idir), CHF_CONST_INT(iside), CHF_CONST_INT(ncomp)); } else { // valid region not wide enough to apply HOExtrap -- drop // to linear extrap FORT_RESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()), CHF_BOX(bc_box), CHF_CONST_INT(idir), CHF_CONST_INT(iside), CHF_CONST_INT(ncomp)); } IntVectSet ivs = m_eblg[a_lev].getEBISL()[dit()].getIrregIVS(bc_box); for (VoFIterator vofit(ivs, m_eblg[a_lev].getEBISL()[dit()].getEBGraph()); vofit.ok(); ++vofit) { for (int icomp = 0; icomp < ncomp; icomp++) { Real valNeigh = 0; Vector<FaceIndex> faces = m_eblg[a_lev].getEBISL()[dit()].getFaces(vofit(), idir, flip(sit())); for (int iface = 0; iface < faces.size(); iface++) { VolIndex vofNeigh = faces[iface].getVoF(flip(sit())); valNeigh += a_src[dit()](vofNeigh, icomp); } if (faces.size() > 1) valNeigh /= faces.size(); a_src[dit()](vofit(), icomp) = valNeigh; } } } } } }
void VCAMRPoissonOp2::looseGSRB(LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs) { CH_TIME("VCAMRPoissonOp2::looseGSRB"); #if 1 MayDay::Abort("VCAMRPoissonOp2::looseGSRB - Not implemented"); #else // This implementation converges at half the rate of "levelGSRB" in // multigrid solves CH_assert(a_phi.isDefined()); CH_assert(a_rhs.isDefined()); CH_assert(a_phi.ghostVect() >= IntVect::Unit); CH_assert(a_phi.nComp() == a_rhs.nComp()); // Recompute the relaxation coefficient if needed. resetLambda(); const DisjointBoxLayout& dbl = a_phi.disjointBoxLayout(); DataIterator dit = a_phi.dataIterator(); // fill in intersection of ghostcells and a_phi's boxes { CH_TIME("VCAMRPoissonOp2::looseGSRB::homogeneousCFInterp"); homogeneousCFInterp(a_phi); } { CH_TIME("VCAMRPoissonOp2::looseGSRB::exchange"); a_phi.exchange(a_phi.interval(), m_exchangeCopier); } // now step through grids... for (dit.begin(); dit.ok(); ++dit) { // invoke physical BC's where necessary { CH_TIME("VCAMRPoissonOp2::looseGSRB::BCs"); m_bc(a_phi[dit], dbl[dit()], m_domain, m_dx, true); } const Box& region = dbl.get(dit()); const FluxBox& thisBCoef = (*m_bCoef)[dit]; int whichPass = 0; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), 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_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); whichPass = 1; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), 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_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); } // end loop through grids #endif }
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 EBPoissonOp:: restrictResidual(LevelData<EBCellFAB>& a_resCoar, LevelData<EBCellFAB>& a_phiThisLevel, const LevelData<EBCellFAB>& a_rhsThisLevel) { CH_TIME("EBPoissonOp::restrictResidual"); CH_assert(a_resCoar.nComp() == 1); CH_assert(a_phiThisLevel.nComp() == 1); CH_assert(a_rhsThisLevel.nComp() == 1); LevelData<EBCellFAB> resThisLevel; bool homogeneous = true; EBCellFactory ebcellfactTL(m_eblg.getEBISL()); IntVect ghostVec = a_rhsThisLevel.ghostVect(); resThisLevel.define(m_eblg.getDBL(), 1, ghostVec, ebcellfactTL); // Get the residual on the fine grid residual(resThisLevel,a_phiThisLevel,a_rhsThisLevel,homogeneous); // now use our nifty averaging operator Interval variables(0, 0); CH_assert(m_hasMGObjects); m_ebAverageMG.average(a_resCoar, resThisLevel, variables); #ifdef DO_EB_RHS_CORRECTION // Apply error-correction modification to restricted RHS // Right now this only works with Dirichlet BC's, and only makes sense for the EB int correctionType = 0; // Change this to activate RHS correction if (correctionType != 0) { for (DataIterator dit = a_resCoar.disjointBoxLayout().dataIterator(); dit.ok(); ++dit) { EBCellFAB& resFAB = a_resCoar[dit()]; // Extract the FAB for this box const EBISBox& ebis = resFAB.getEBISBox(); // Get the set of all IntVect indices // Iterate over the parts of the RHS corresponding to the irregular cells, // correcting the RHS in each cell VoFIterator ebvofit(ebis.getIrregIVS(ebis.getRegion()), ebis.getEBGraph()); for (ebvofit.reset(); ebvofit.ok(); ++ebvofit) { for (int icomp = 0; icomp < resFAB.nComp(); ++icomp) // For each component of the residual on this VoF { if (correctionType == 1) { // Setting the residual to zero on the irregular cells gives convergence, // though the rate isn't as good as the full correction resFAB(ebvofit(), icomp) = 0.0; } else if (correctionType == 2) { // Kludge valid only for pseudo-1D test case. May not work for you. Real kappa = ebis.volFrac(ebvofit()); kappa = (kappa > 0.5 ? kappa : 0.5); // Floor on kappa to prevent dividing by a tiny number Real rhoCoeff = (kappa + 0.5)/(2.0*kappa); resFAB(ebvofit(), icomp) *= (1.0 - rhoCoeff); } // else silently do nothing } } } } #endif }
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); }
// --------------------------------------------------------------- // tag cells for regridding void AMRNavierStokes::tagCells(IntVectSet & a_tags) { if (s_verbosity >= 3) { pout () << "AMRNavierStokes::tagCells " << m_level << endl; } IntVectSet local_tags; // create tags based on something or other // for now, don't do anything const DisjointBoxLayout& level_domain = newVel().getBoxes(); if (s_tag_vorticity) { LevelData<FArrayBox> vorticity; LevelData<FArrayBox> mag_vorticity; if (SpaceDim == 2) { vorticity.define(level_domain,1); } else if (SpaceDim == 3) { vorticity.define(level_domain,SpaceDim); mag_vorticity.define(level_domain,1); } computeVorticity(vorticity); Interval vortInterval(0,0); if (SpaceDim == 3) { vortInterval = Interval(0,SpaceDim-1); } Real tagLevel = norm(vorticity, vortInterval, 0); // Real tagLevel = 1.0; //tagLevel *= s_vort_factor/m_dx; // actually tag where vort*dx > s_vort_factor*max(vort) tagLevel = s_vort_factor/m_dx; if (tagLevel > 0) { // now tag where vorticity magnitude is greater than or equal // to tagLevel DataIterator dit = vorticity.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { FArrayBox& vortFab = vorticity[dit]; // this only needs to be done in 3d... if (SpaceDim==3) { FArrayBox& magVortFab = mag_vorticity[dit]; FORT_MAGVECT(CHF_FRA1(magVortFab,0), CHF_CONST_FRA(vortFab), CHF_BOX(level_domain[dit])); } BoxIterator bit(vortFab.box()); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); if (SpaceDim == 2) { if (abs(vortFab(iv)) >= tagLevel) { local_tags |= iv; } } else if (SpaceDim == 3) { FArrayBox& magVortFab = mag_vorticity[dit]; if (abs(magVortFab(iv)) >= tagLevel) { local_tags |= iv; } } // end if DIM=3 } // end loop over interior of box } // loop over grids } // if taglevel > 0 } // if tagging on vorticity a_tags = local_tags; }
int testIFFAB(const DisjointBoxLayout& a_dbl, const EBISLayout & a_ebisl, const Box & a_domain, const Real & a_dx ) { int faceDir = 0; int nFlux = 1; LayoutData<IntVectSet> irregSetsGrown; LevelData< BaseIFFAB<Real> > fluxInterpolant; EBArith::defineFluxInterpolant(fluxInterpolant, irregSetsGrown, a_dbl, a_ebisl, a_domain, nFlux, faceDir); //set source fab to right ans over set only on grids interior cells int ibox = 0; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()]; srcFab.setVal(-1.0); IntVectSet ivsSmall = irregSetsGrown[dit()]; const Box& grid = a_dbl.get(dit()); ivsSmall &= grid; for (FaceIterator faceit(ivsSmall, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary); faceit.ok(); ++faceit) { srcFab(faceit(), 0) = rightAns(faceit()); } ibox++; } //diagnostics if (g_diagnosticMode) { pout() << " diagnostics for processor " << procID() << endl; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { const IntVectSet& ivsGrown = irregSetsGrown[dit()]; const Box& grid = a_dbl.get(dit()); pout() << "============" << endl; pout() << " box = " << grid; pout() << ", full ivs = " ; dumpIVS(&ivsGrown); pout() << "============" << endl; for (LayoutIterator lit = a_dbl.layoutIterator(); lit.ok(); ++lit) { const Box& grid2 = a_dbl.get(lit()); IntVectSet ivsIntersect = ivsGrown; ivsIntersect &= grid2; pout() << "intersection with box " << grid2 << " = "; dumpIVS(&ivsIntersect); pout() << "============" << endl; } } } BaseIFFAB<Real>::setVerbose(true); //do the evil exchange Interval interv(0, nFlux-1); fluxInterpolant.exchange(interv); ibox = 0; //check the answer over grown set Real tolerance = 0.001; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { const BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()]; const IntVectSet& ivsGrown = irregSetsGrown[dit()]; for (FaceIterator faceit(ivsGrown, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary); faceit.ok(); ++faceit) { Real correct = rightAns(faceit()); Real fabAns = srcFab(faceit(), 0); if (Abs(correct - fabAns) > tolerance) { pout() << "iffab test failed at face " << faceit().gridIndex(Side::Lo) << faceit().gridIndex(Side::Hi) << endl; pout() << " right ans = " << correct << endl; pout() << " data holds= " << fabAns << endl; int eekflag = -3; return eekflag; } } ibox++; } return 0; }
// migrate only object LDStat in group // leaf nodes actually migrate objects void HybridBaseLB::ReceiveMigration(LBMigrateMsg *msg) { #if CMK_LBDB_ON #if CMK_MEM_CHECKPOINT CkResetInLdb(); #endif FindNeighbors(); int atlevel = msg->level - 1; DEBUGF(("[%d] ReceiveMigration\n", CkMyPe())); LevelData *lData = levelData[atlevel]; // only non NULL when level > 0 LDStats *statsData = lData->statsData; // do LDStats migration const int me = CkMyPe(); lData->migrates_expected = 0; for(int i=0; i < msg->n_moves; i++) { MigrateInfo& move = msg->moves[i]; // incoming if (move.from_pe != me && move.to_pe == me) { // I can not be the parent node DEBUGF(("[%d] expecting LDStats object from %d\n",me,move.from_pe)); // will receive a ObjData message lData->migrates_expected ++; } else if (move.from_pe == me) { // outgoing if (statsData) { // this is inner node // send objdata int obj; int found = 0; for (obj = 0; obj<statsData->n_objs; obj++) { if (move.obj.omID() == statsData->objData[obj].handle.omID() && move.obj.objID() == statsData->objData[obj].handle.objID()) { DEBUGF(("[%d] level: %d sending objData %d to %d. \n", CkMyPe(), atlevel, obj, move.to_pe)); found = 1; // TODO send comm data CkVec<LDCommData> comms; collectCommData(obj, comms, atlevel); if (move.to_pe != -1) { // this object migrates to another PE of the parent domain thisProxy[move.to_pe].ObjMigrated(statsData->objData[obj], comms.getVec(), comms.size(), atlevel); } lData->outObjs.push_back(MigrationRecord(move.obj, lData->children[statsData->from_proc[obj]], -1)); statsData->removeObject(obj); break; } } CmiAssert(found == 1); } else { // this is leave node if (move.to_pe == -1) { lData->outObjs.push_back(MigrationRecord(move.obj, CkMyPe(), -1)); } else { // migrate the object theLbdb->Migrate(move.obj,move.to_pe); } } } // end if } if (lData->migrationDone()) StatsDone(atlevel); #endif }
LevelData &levelData(void) { levelData_.wrap(buffer_, offset_ + 36, actingVersion_, bufferLength_); return levelData_; }
//---------------------------------------------------------------------------- void EBNormalizeByVolumeFraction:: operator()(LevelData<EBCellFAB>& a_Q, const Interval& a_compInterval) const { CH_TIME("EBNormalizer::operator()"); // Endpoints of the given interval. int begin = a_compInterval.begin(), end = a_compInterval.end(), length = a_compInterval.size(); // Loop over the EBISBoxes within our grid. The EB data structures are // indexed in the same manner as the non-EB data structures, so we piggy- // back the former on the latter. a_Q.exchange(); EBISLayout ebisLayout = m_levelGrid.getEBISL(); DisjointBoxLayout layout = m_levelGrid.getDBL(); for (DataIterator dit = layout.dataIterator(); dit.ok(); ++dit) { const EBISBox& box = ebisLayout[dit()]; EBCellFAB& QFAB = a_Q[dit()]; // Go over the irregular cells in this box. const IntVectSet& irregCells = box.getIrregIVS(layout[dit()]); // The average has to be computed from the uncorrected data from all // the neighbors, so we can't apply the corrections in place. For now, // we stash them in a map. map<VolIndex, vector<Real> > correctedValues; for (VoFIterator vit(irregCells, box.getEBGraph()); vit.ok(); ++vit) { Real kappajSum = 0.0; vector<Real> kappajQjSum(length, 0.0); // Get all of the indices of the VoFs within a monotone path // radius of 1. VolIndex vofi = vit(); Vector<VolIndex> vofjs; EBArith::getAllVoFsInMonotonePath(vofjs, vofi, box, 1); // Accumulate the contributions from the neighboring cells. for (unsigned int j = 0; j < vofjs.size(); ++j) { VolIndex vofj = vofjs[j]; Real kappaj = box.volFrac(vofj); for (int icomp = begin; icomp <= end; ++icomp) { kappajQjSum[icomp] += QFAB(vofj, icomp); } // Add this volume fraction to the sum. kappajSum += kappaj; } if (kappajSum > 0.) { // Normalize the quantity and stow it. vector<Real> correctedValue(length); // Real kappai = box.volFrac(vofi); //unused dtg for (int icomp = begin; icomp <= end; ++icomp) { // correctedValue[icomp - begin] = // QFAB(vofi, icomp) + (1.0 - kappai) * kappajQjSum[icomp] / kappajSum; correctedValue[icomp - begin] = kappajQjSum[icomp] / kappajSum; } correctedValues[vofi] = correctedValue; } } // Apply the corrections. for (map<VolIndex, vector<Real> >::const_iterator cit = correctedValues.begin(); cit != correctedValues.end(); ++cit) { for (int icomp = begin; icomp <= end; ++icomp) { QFAB(cit->first, icomp) = cit->second[icomp-begin]; } } } }
void HybridBaseLB::PropagateInfo(Location *loc, int n, int fromlevel) { #if CMK_LBDB_ON int i, obj; int atlevel = fromlevel - 1; LevelData *lData = levelData[atlevel]; CkVec<Location> &matchedObjs = lData->matchedObjs; //CkVec<Location> &unmatchedObjs = lData->unmatchedObjs; std::map<LDObjKey, int> &unmatchedObjs = lData->unmatchedObjs; if (atlevel > 0) { if (_lb_args.debug() > 1) CkPrintf("[%d] PropagateInfo at level %d started at %f\n", CkMyPe(), atlevel, CkWallTimer()); // search in unmatched #if 0 for (i=0; i<n; i++) { // search and see if we have answer, put to matched // store in unknown for (obj=0; obj<unmatchedObjs.size(); obj++) { if (loc[i].key == unmatchedObjs[obj].key) { // answer must exist now CmiAssert(unmatchedObjs[obj].loc != -1 || loc[i].loc != -1); if (unmatchedObjs[obj].loc == -1) unmatchedObjs[obj].loc = loc[i].loc; matchedObjs.push_back(unmatchedObjs[obj]); unmatchedObjs.remove(obj); break; } } } #else for (int i=0; i<n; i++) { // search and see if we have answer, put to matched const LDObjKey key = loc[i].key; std::map<LDObjKey, int>::iterator iter = unmatchedObjs.find(key); if (iter != unmatchedObjs.end()) { // answer must exist now CmiAssert(iter->second != -1 || loc[i].loc != -1); if (loc[i].loc == -1) loc[i].loc = iter->second; matchedObjs.push_back(loc[i]); unmatchedObjs.erase(iter); } } #endif CmiAssert(unmatchedObjs.size() == 0); DEBUGF(("[%d] level %d PropagateInfo had %d matchedObjs. \n", CkMyPe(), atlevel, matchedObjs.size())); // send down thisProxy.PropagateInfo(matchedObjs.getVec(), matchedObjs.size(), atlevel, lData->nChildren, lData->children); lData->statsData->clear(); matchedObjs.free(); } else { // leaf node // now start to migrate CkVec<MigrationRecord> & outObjs = lData->outObjs; int migs = outObjs.size() + newObjs.size(); for (i=0; i<outObjs.size(); i++) { if (outObjs[i].toPe == -1) { for (obj=0; obj<n; obj++) { if (loc[obj].key.omID() == outObjs[i].handle.omID() && loc[obj].key.objID() == outObjs[i].handle.objID()) { outObjs[i].toPe = loc[obj].loc; break; } } CmiAssert(obj < n); } CmiAssert(outObjs[i].toPe != -1); // migrate now! theLbdb->Migrate(outObjs[i].handle,outObjs[i].toPe); } // end for out // incoming lData->migrates_expected = 0; future_migrates_expected = 0; for (i=0; i<newObjs.size(); i++) { if (newObjs[i].loc == -1) { for (obj=0; obj<n; obj++) { if (loc[obj].key == newObjs[i].key) { newObjs[i].loc = loc[obj].loc; break; } } CmiAssert(obj < n); } CmiAssert(newObjs[i].loc != -1); lData->migrates_expected++; } // end of for DEBUGF(("[%d] expecting %d\n", CkMyPe(), lData->migrates_expected)); if (lData->migrationDone()) { MigrationDone(1); } } #endif }
//---------------------------------------------------------------------------- void EBNormalizeByVolumeFraction:: operator()(LevelData<EBCellFAB>& a_Q) const { return (*this)(a_Q, Interval(0, a_Q.nComp()-1)); }
// ----------------------------------------------------------------------------- // Interpolate ghosts at CF interface using zeros on coarser grids. // Only do one face. // ----------------------------------------------------------------------------- void homogeneousCFInterp (LevelData<FArrayBox>& a_phif, const DataIndex& a_index, const int a_dir, const Side::LoHiSide a_side, const Real a_fineDxDir, const Real a_crseDxDir, const CFRegion& a_cfRegion) { CH_TIME("homogeneousCFInterp (single grid)"); // Sanity checks CH_assert((a_dir >= 0) && (a_dir < SpaceDim)); CH_assert(a_phif.ghostVect()[a_dir] >= 1); // Get the C/F region const CFIVS* cfivs_ptr = NULL; if (a_side == Side::Lo) { CFRegion& castCFRegion = (CFRegion&)a_cfRegion; cfivs_ptr = &(castCFRegion.loCFIVS(a_index, a_dir)); } else { CFRegion& castCFRegion = (CFRegion&)a_cfRegion; cfivs_ptr = &(castCFRegion.hiCFIVS(a_index, a_dir)); } if (cfivs_ptr->isPacked()) { // The C/F region is a box. // Iterate over the box and interpolate. int ihiorlo = sign(a_side); FArrayBox& phiFab = a_phif[a_index]; const Box region = cfivs_ptr->packedBox(); CH_assert(a_crseDxDir > 0.0 || region.isEmpty()); if (phiFab.box().size(a_dir) == 3) { // Linear interpolation of fine ghosts assuming // all zeros on coarser level. FORTNT_INTERPHOMOLINEAR( CHF_FRA(phiFab), CHF_BOX(region), CHF_CONST_REAL(a_fineDxDir), CHF_CONST_REAL(a_crseDxDir), CHF_CONST_INT(a_dir), CHF_CONST_INT(ihiorlo)); } else { // Quadratic interpolation of fine ghosts assuming // all zeros on coarser level. FORTNT_INTERPHOMO( CHF_FRA(phiFab), CHF_BOX(region), CHF_CONST_REAL(a_fineDxDir), CHF_CONST_REAL(a_crseDxDir), CHF_CONST_INT(a_dir), CHF_CONST_INT(ihiorlo)); } } else { // The C/F region is sparse. // Iterate over the IVS and interpolate. const IntVectSet& interp_ivs = cfivs_ptr->getFineIVS(); if (!interp_ivs.isEmpty()) { CH_assert(a_crseDxDir > 0.0); interpOnIVSHomo(a_phif, a_index, a_dir, a_side, interp_ivs, a_fineDxDir, a_crseDxDir); } } }
// --------------------------------------------------------- int main(int argc, char* argv[]) { int status = 0; // number of errors detected. // Do nothing if DIM > 3. #if (CH_SPACEDIM <= 3) #ifdef CH_MPI MPI_Init (&argc, &argv); #endif //scoping trick { // test parameters const int testOrder = 4; // expected order of convergence // A test is considered as a failure // if its convergence rate is smaller than below. Real targetConvergeRate = testOrder*0.9; #ifdef CH_USE_FLOAT targetConvergeRate = testOrder*0.89; #endif // number of ghost cells being interpolated int numGhost = 5; // refinement ratio between coarse and fine levels int refRatio = 4; Vector<Interval> fixedDimsAll; if (SpaceDim == 3) { fixedDimsAll.push_back(Interval(SpaceDim-1, SpaceDim-1)); } // Always include empty interval, meaning NO fixed dimensions. fixedDimsAll.push_back(Interval()); // real domain has length 1. in every dimension RealVect physLength = RealVect::Unit; for (int ifixed = 0; ifixed < fixedDimsAll.size(); ifixed++) { const Interval& fixedDims = fixedDimsAll[ifixed]; int nfixed = fixedDims.size(); IntVect interpUnit = IntVect::Unit; IntVect refineVect = refRatio * IntVect::Unit; for (int dirf = fixedDims.begin(); dirf <= fixedDims.end(); dirf++) { interpUnit[dirf] = 0; refineVect[dirf] = 1; } // No ghost cells in fixed dimensions. IntVect ghostVect = numGhost * interpUnit; #ifdef CH_USE_FLOAT // Single precision doesn't get us very far. #if (CH_SPACEDIM == 1) int domainLengthMin = 16; int domainLengthMax = 32; #else int domainLengthMin = 32; int domainLengthMax = 64; #endif #endif #ifdef CH_USE_DOUBLE int domainLengthMin = 32; #if CH_SPACEDIM >= 3 int domainLengthMax = 64; if (nfixed > 0) domainLengthMax = 128; #else int domainLengthMax = 512; #endif #endif Vector<int> domainLengths; int len = domainLengthMin; while (len <= domainLengthMax) { domainLengths.push_back(len); len *= 2; } int nGrids = domainLengths.size(); if (nGrids > 0) { pout() << endl << "Testing FourthOrderFillPatch DIM=" << SpaceDim; if (nfixed > 0) { pout() << " fixing " << fixedDims.begin() << ":" << fixedDims.end(); } pout() << endl; pout() << "size " << "max diff rate"; pout() << endl; } Real diffMaxCoarser; for (int iGrid = 0; iGrid < nGrids; iGrid++) { int domainLength = domainLengths[iGrid]; IntVect lenCoarse = domainLength * IntVect::Unit; RealVect dxCoarseVect = physLength / RealVect(lenCoarse); RealVect dxFineVect = dxCoarseVect / RealVect(refineVect); Box coarDomain, fineDomain; Vector<Box> coarBoxes, fineBoxes; setHierarchy(lenCoarse, refineVect, coarBoxes, fineBoxes, coarDomain, fineDomain); mortonOrdering(coarBoxes); mortonOrdering(fineBoxes); Vector<int> procCoar(coarBoxes.size()); Vector<int> procFine(fineBoxes.size()); LoadBalance(procCoar, coarBoxes); LoadBalance(procFine, fineBoxes); DisjointBoxLayout dblCoar(coarBoxes, procCoar); DisjointBoxLayout dblFine(fineBoxes, procFine); ProblemDomain probCoar(coarDomain); ProblemDomain probFine(fineDomain); FourthOrderFillPatch interpolator; int ncomp = 1; // Set coarseGhostsFill = ceil(numGhosts / refRatio). // int coarseGhostsFill = numGhost / refRatio; // if (coarseGhostsFill * refRatio < numGhost) coarseGhostsFill++; bool fixedTime = true; interpolator.define(dblFine, dblCoar, ncomp, probCoar, refRatio, numGhost, fixedTime, fixedDims); LevelData<FArrayBox> exactCoarse(dblCoar, ncomp); // Set exact value of function on coarse level. for (DataIterator dit = exactCoarse.dataIterator(); dit.ok(); ++dit) { CH_TIME("computing exactCoarse on FAB"); FArrayBox& exactCoarseFab = exactCoarse[dit]; const Box& bx = exactCoarseFab.box(); // Get average of function on each cell. for (BoxIterator bit(bx); bit.ok(); ++bit) { const IntVect& iv = bit(); RealVect cellLo = RealVect(iv) * dxCoarseVect; RealVect cellHi = cellLo + dxCoarseVect; exactCoarseFab(iv, 0) = avgFunVal(cellLo, cellHi, physLength); } } /* Define data holders on fine level. */ Interval intvlExact(0, ncomp-1); Interval intvlCalc(ncomp, 2*ncomp-1); Interval intvlDiff(2*ncomp, 3*ncomp-1); LevelData<FArrayBox> allFine; LevelData<FArrayBox> exactFine, calcFine, diffFine; { CH_TIME("allocate allFine"); allFine.define(dblFine, 3*ncomp, ghostVect); aliasLevelData(exactFine, &allFine, intvlExact); aliasLevelData(calcFine, &allFine, intvlCalc); aliasLevelData(diffFine, &allFine, intvlDiff); } /* Fill in data holders on fine level. */ // Set exact value of function on fine level. Real exactMax = 0.; for (DataIterator dit = exactFine.dataIterator(); dit.ok(); ++dit) { CH_TIME("computing exactFine on FAB"); FArrayBox& exactFineFab = exactFine[dit]; const Box& bx = exactFineFab.box(); // Get average of function on each cell. for (BoxIterator bit(bx); bit.ok(); ++bit) { const IntVect& iv = bit(); RealVect cellLo = RealVect(iv) * dxFineVect; RealVect cellHi = cellLo + dxFineVect; exactFineFab(iv, 0) = avgFunVal(cellLo, cellHi, physLength); } Real exactFabMax = exactFineFab.norm(0); if (exactFabMax > exactMax) exactMax = exactFabMax; } #ifdef CH_MPI reduceReal(exactMax, MPI_MAX); #endif // Fill in valid cells of calcFine by copying from exact. for (DataIterator dit = dblFine.dataIterator(); dit.ok(); ++dit) { const FArrayBox& exactFineFab = exactFine[dit]; FArrayBox& calcFineFab = calcFine[dit]; const Box& bx = dblFine[dit]; calcFineFab.copy(exactFineFab, bx); } // Fill in ghost cells of calcFine by copying where possible. calcFine.exchange(); // Fill in ghost cells of calcFine by interpolation where necessary. interpolator.fillInterp(calcFine, exactCoarse, 0, 0, ncomp); /* Got results. Now take differences, diffFine = calcFine - exactFine. */ Real diffMax = 0.; for (DataIterator dit = diffFine.dataIterator(); dit.ok(); ++dit) { CH_TIME("calculating diffFine"); FArrayBox& diffFineFab = diffFine[dit]; const FArrayBox& exactFineFab = exactFine[dit]; const FArrayBox& calcFineFab = calcFine[dit]; Box bxWithin(diffFineFab.box()); bxWithin &= probFine; diffFineFab.setVal(0.); diffFineFab.copy(exactFineFab, bxWithin); diffFineFab.minus(calcFineFab, bxWithin, 0, 0, ncomp); Real diffFabMax = diffFineFab.norm(0); if (diffFabMax > diffMax) diffMax = diffFabMax; // dummy statement in order to get around gdb bug int dummy_unused = 0; dummy_unused = 0; } #ifdef CH_MPI reduceReal(diffMax, MPI_MAX); #endif pout() << setw(4) << domainLength; pout() << " " << scientific << setprecision(4) << diffMax; if (iGrid > 0) { Real ratio = diffMaxCoarser / diffMax; Real rate = log(ratio) / log(2.0); pout () << " " << fixed << setprecision(2) << rate; if (rate < targetConvergeRate) { status += 1; } } pout() << endl; diffMaxCoarser = diffMax; } // end loop over grid sizes } // end loop over which dimensions are fixed if (status==0) { pout() << "All tests passed!\n"; } else { pout() << status << " tests failed!\n"; } } // end scoping trick #ifdef CH_MPI CH_TIMER_REPORT(); MPI_Finalize(); #endif #endif return status; }
// Advance the solution by "a_dt" by using an unsplit method. // "a_finerFluxRegister" is the flux register with the next finer level. // "a_coarseFluxRegister" is flux register with the next coarser level. // If source terms do not exist, "a_S" should be null constructed and not // defined (i.e. its define() should not be called). Real OldLevelGodunov::step(LevelData<FArrayBox>& a_U, LevelData<FArrayBox> a_flux[CH_SPACEDIM], LevelFluxRegister& a_finerFluxRegister, LevelFluxRegister& a_coarserFluxRegister, const LevelData<FArrayBox>& a_S, const LevelData<FArrayBox>& a_UCoarseOld, const Real& a_TCoarseOld, const LevelData<FArrayBox>& a_UCoarseNew, const Real& a_TCoarseNew, const Real& a_time, const Real& a_dt) { // Make sure everything is defined CH_assert(m_defined); // Clear flux registers with next finer level if (m_hasFiner) { a_finerFluxRegister.setToZero(); } // Setup an interval corresponding to the conserved variables Interval UInterval(0,m_numCons-1); // Create temporary storage with a layer of "m_numGhost" ghost cells IntVect ivGhost = m_numGhost*IntVect::Unit; LevelData<FArrayBox> U(m_grids,m_numCons,ivGhost); for (DataIterator dit = U.dataIterator(); dit.ok(); ++dit) { U[dit()].setVal(0.); } // Copy the current conserved variables into the temporary storage a_U.copyTo(UInterval,U,UInterval); // Fill U's ghost cells using fillInterp if (m_hasCoarser) { // Truncate the fraction to the range [0,1] to remove floating-point // subtraction roundoff effects Real eps = 0.04 * a_dt / m_refineCoarse; // check for current time too far outside the coarse time range if ( a_time+eps < a_TCoarseOld || a_time-eps > a_TCoarseNew ) { pout() << "error: OldLevelGodunov::step: a_time [" << a_time << "] is outside the old,new range of coarse level times [" << a_TCoarseOld << "," << a_TCoarseNew << "]" << endl ; MayDay::Error( "OldLevelGodunov::step: new time is outside acceptable range" ); } // if just a little outside the range (e.g. roundoff errors), just fix it Real curtime = a_time ; if ( a_time < a_TCoarseOld ) curtime = a_TCoarseOld ; if ( a_time > a_TCoarseNew ) curtime = a_TCoarseNew ; // "time" falls in the range of the old and the new coarse times Real alpha = (curtime - a_TCoarseOld) / (a_TCoarseNew - a_TCoarseOld); // Interpolate ghost cells from next coarser level using both space // and time interpolation m_patcher.fillInterp(U, a_UCoarseOld, a_UCoarseNew, alpha, 0,0,m_numCons); } // Exchange all the data between grids at this level // I don't think this is necessary //U.exchange(UInterval); // Potentially used in boundary conditions m_patchGodunov->setCurrentTime(a_time); // Dummy source used if source term passed in is empty FArrayBox zeroSource; // Use to restrict maximum wave speed away from zero Real maxWaveSpeed = 1.0e-12; // Beginning of loop through patches/grids. for (DataIterator dit = m_grids.dataIterator(); dit.ok(); ++dit) { // The current box Box curBox = m_grids.get(dit()); // The current grid of conserved variables FArrayBox& curU = U[dit()]; // The current source terms if they exist const FArrayBox* source = &zeroSource; if (a_S.isDefined()) { source = &a_S[dit()]; } // The fluxes computed for this grid - used for refluxing and returning // other face centered quantities FArrayBox flux[SpaceDim]; // Set the current box for the patch integrator m_patchGodunov->setCurrentBox(curBox); Real maxWaveSpeedGrid; // Update the current grid's conserved variables, return the final // fluxes used for this, and the maximum wave speed for this grid m_patchGodunov->updateState(curU, flux, maxWaveSpeedGrid, *source, a_dt, curBox); // Clamp away from zero maxWaveSpeed = Max(maxWaveSpeed,maxWaveSpeedGrid); // Do flux register updates for (int idir = 0; idir < SpaceDim; idir++) { // Increment coarse flux register between this level and the next // finer level - this level is the next coarser level with respect // to the next finer level if (m_hasFiner) { a_finerFluxRegister.incrementCoarse(flux[idir],a_dt,dit(), UInterval, UInterval,idir); } // Increment fine flux registers between this level and the next // coarser level - this level is the next finer level with respect // to the next coarser level if (m_hasCoarser) { a_coarserFluxRegister.incrementFine(flux[idir],a_dt,dit(), UInterval, UInterval,idir,Side::Lo); a_coarserFluxRegister.incrementFine(flux[idir],a_dt,dit(), UInterval, UInterval,idir,Side::Hi); } } } // Now that we have completed the updates of all the patches, we copy the // contents of temporary storage, U, into the permanent storage, a_U. // U.copyTo(UInterval,a_U,UInterval); for (DataIterator dit = U.dataIterator(); dit.ok(); ++dit) { a_U[dit()].copy(U[dit()]); } // Find the minimum of dt's over this level Real local_dtNew = m_dx / maxWaveSpeed; Real dtNew; #ifdef CH_MPI int result = MPI_Allreduce(&local_dtNew, &dtNew, 1, MPI_CH_REAL, MPI_MIN, Chombo_MPI::comm); if (result != MPI_SUCCESS) { MayDay::Error("sorry, but I had a communcation error on new dt"); } #else dtNew = local_dtNew; #endif // Return the maximum stable time step return dtNew; }
void parseAndAddEvent(LevelData& mLevelData, Json::Value &mEventRoot) { mLevelData.addEvent(mEventRoot); }
void LevelFluxRegisterEdge::refluxCurl(LevelData<FluxBox>& a_uCoarse, Real a_scale) { CH_assert(isDefined()); CH_assert(a_uCoarse.nComp() == m_nComp); SideIterator side; // idir is the normal direction to the coarse-fine interface for (int idir=0 ; idir<SpaceDim; ++idir) { for (side.begin(); side.ok(); ++side) { LevelData<FluxBox>& fineReg = m_fabFine[index(idir, side())]; // first, create temp LevelData<FluxBox> to hold "coarse flux" const DisjointBoxLayout coarseBoxes = m_regCoarse.getBoxes(); // this fills the place of what used to be m_fabCoarse in the old // implementation LevelData<FluxBox> coarReg(coarseBoxes, m_nComp, IntVect::Unit); // now fill the coarReg with the curl of the stored coarse-level // edge-centered flux DataIterator crseDit = coarseBoxes.dataIterator(); for (crseDit.begin(); crseDit.ok(); ++crseDit) { FluxBox& thisCoarReg = coarReg[crseDit]; thisCoarReg.setVal(0.0); EdgeDataBox& thisEdgeData = m_regCoarse[crseDit]; for (int edgeDir=0; edgeDir<SpaceDim; edgeDir++) { if (idir != edgeDir) { FArrayBox& crseEdgeDataDir = thisEdgeData[edgeDir]; for (int faceDir = 0; faceDir<SpaceDim; faceDir++) { if (faceDir != edgeDir) { FArrayBox& faceData = thisCoarReg[faceDir]; int shiftDir = -1; for (int i=0; i<SpaceDim; i++) { if ((i != faceDir) && (i != edgeDir) ) { shiftDir = i; } } CH_assert(shiftDir >= 0); crseEdgeDataDir.shiftHalf(shiftDir, sign(side())); // scaling already taken care of in incrementCrse Real scale = 1.0; faceData.plus(crseEdgeDataDir, scale, 0, 0, faceData.nComp()); crseEdgeDataDir.shiftHalf(shiftDir, -sign(side())); } // end if not normal direction } // end loop over face directions } // end if edgeDir != idir } // end loop over edge directions } // end loop over crse boxes // first, we need to create a temp LevelData<FluxBox> // to make a local copy in the coarse layout space of // the fine register increments LevelData<FluxBox> fineRegLocal(coarReg.getBoxes(), m_nComp, IntVect::Unit); fineReg.copyTo(fineReg.interval(), fineRegLocal, fineRegLocal.interval(), m_crseCopiers[index(idir,side())]); for (DataIterator it = a_uCoarse.dataIterator(); it.ok(); ++it) { // loop over flux components here for (int fluxComp=0; fluxComp < SpaceDim; fluxComp++) { // we don't do anything in the normal direction if (fluxComp != idir) { // fluxDir is the direction of the face-centered flux FArrayBox& U = a_uCoarse[it()][fluxComp]; // set up IntVectSet to avoid double counting of updates Box coarseGridBox = U.box(); // transfer to Cell-centered, then create IVS coarseGridBox.shiftHalf(fluxComp,1); IntVectSet nonUpdatedEdges(coarseGridBox); // remember, we want to take the curl here // also recall that fluxComp is the component // of the face-centered curl (not the edge-centered // vector field that we're refluxing, which is why // the sign may seem like it's the opposite of what // you might expect! Real local_scale = -sign(side())*a_scale; //int testDir = (fluxComp+1)%(SpaceDim); if (((fluxComp+1)%(SpaceDim)) == idir) local_scale *= -1; Vector<IntVectSet>& ivsV = m_refluxLocations[index(idir, side())][it()][fluxComp]; Vector<DataIndex>& indexV = m_coarToCoarMap[index(idir, side())][it()]; IVSIterator iv; for (int i=0; i<ivsV.size(); ++i) { iv.define(ivsV[i]); const FArrayBox& coar = coarReg[indexV[i]][fluxComp]; const FArrayBox& fine = fineRegLocal[indexV[i]][fluxComp]; for (iv.begin(); iv.ok(); ++iv) { IntVect thisIV = iv(); if (nonUpdatedEdges.contains(thisIV)) { for (int comp=0; comp <m_nComp; ++comp) { //Real coarVal = coar(thisIV, comp); //Real fineVal = fine(thisIV, comp); U(thisIV, comp) -= local_scale*(coar(thisIV, comp) +fine(thisIV, comp)); } nonUpdatedEdges -= thisIV; } } } } // end if not normal face } // end loop over fluxbox directions } // end loop over coarse boxes } // end loop over sides } // end loop over directions }
void getError(LevelData<double, 1> & a_error, double & a_maxError, const double & a_dx) { BoxLayout layout = a_error.getBoxLayout(); LevelData<double, 1> phi(layout, s_nghost); LevelData<double, 1> lphcalc(layout, 0); LevelData<double, 1> lphexac(layout, 0); // cout << "initializing phi to sum_dir(sin 2*pi*xdir)" << endl; initialize(phi,lphexac, a_dx); //set ghost cells of phi phi.exchange(); // dumpLevelRDA(&phi); Stencil<double> laplace; setStencil(laplace, a_dx); //apply stencil operator independently on each box a_maxError = 0; for(BLIterator blit(layout); blit != blit.end(); ++blit) { RectMDArray<double>& phiex = phi[*blit]; RectMDArray<double>& lphca = lphcalc[*blit]; RectMDArray<double>& lphex = lphexac[*blit]; RectMDArray<double>& error = a_error[*blit]; //apply is set as an increment so need to set this to zero initially lphca.setVal(0.); Box bxdst=layout[*blit]; // Stencil<double>::apply(laplace, phiex, lphca, bxdst); const class Box sourceBoxRef = phiex . getBox(); const class Box destinationBoxRef = lphca . getBox(); int iter_lb2 = bxdst . getLowCorner ()[2]; int src_lb2 = sourceBoxRef . getLowCorner ()[2]; int dest_lb2 = destinationBoxRef . getLowCorner ()[2]; int k = 0; int iter_ub2 = bxdst . getHighCorner ()[2]; int src_ub2 = sourceBoxRef . getHighCorner ()[2]; int dest_ub2 = destinationBoxRef . getHighCorner ()[2]; int arraySize_X = bxdst . size (0); int arraySize_X_src = sourceBoxRef . size (0); int iter_lb1 = bxdst . getLowCorner ()[1]; int src_lb1 = sourceBoxRef . getLowCorner ()[1]; int dest_lb1 = destinationBoxRef . getLowCorner ()[1]; int j = 0; int iter_ub1 = bxdst . getHighCorner ()[1]; int src_ub1 = sourceBoxRef . getHighCorner ()[1]; int dest_ub1 = destinationBoxRef . getHighCorner ()[1]; int arraySize_Y = bxdst . size (1); int arraySize_Y_src = sourceBoxRef . size (1); int iter_lb0 = bxdst . getLowCorner ()[0]; int src_lb0 = sourceBoxRef . getLowCorner ()[0]; int dest_lb0 = destinationBoxRef . getLowCorner ()[0]; int i = 0; int iter_ub0 = bxdst . getHighCorner ()[0]; int src_ub0 = sourceBoxRef . getHighCorner ()[0]; int dest_ub0 = destinationBoxRef . getHighCorner ()[0]; int arraySize_Z = bxdst . size (2); int arraySize_Z_src = sourceBoxRef . size (2); double *sourceDataPointer = phiex . getPointer(); double *destinationDataPointer = lphca . getPointer(); for (k = iter_lb2; k < iter_ub2; ++k) { for (j = iter_lb1; j < iter_ub1; ++j) { for (i = iter_lb0; i < iter_ub0; ++i) { destinationDataPointer[arraySize_X * (arraySize_Y * (k - dest_lb2) + (j - dest_lb1)) + (i - dest_lb0)] = (1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2 + -1) + (j - src_lb1)) + (i - src_lb0)] + 1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2 + 1) + (j - src_lb1)) + (i - src_lb0)] + 1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1 + -1)) + (i - src_lb0)] + 1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1 + 1)) + (i - src_lb0)] + 1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1)) + (i - src_lb0 + -1)] + 1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1)) + (i - src_lb0 + 1)] + (-2.0*DIM)*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1)) + (i - src_lb0)]) * (1.0/a_dx/a_dx); //cout << destinationDataPointer[arraySize_X * (arraySize_Y * (k - dest_lb2) + (j - dest_lb1)) + (i - dest_lb0)] << " " << lphex.getPointer()[arraySize_X * (arraySize_Y * (k - dest_lb2) + (j - dest_lb1)) + (i - dest_lb0)] << endl; } } } //error = lphicalc -lphiexac lphca.copyTo(error); //here err holds lphi calc double maxbox = forall_max(error, lphex, &errorF, bxdst); cout << "maxbox= " << maxbox << endl; a_maxError = max(maxbox, a_maxError); } }
// ----------------------------------------------------------------------------- // Adds coarse cell values directly to all overlying fine cells, // then removes the average from the fine result. // ----------------------------------------------------------------------------- void ZeroAvgConstInterpPS::prolongIncrement (LevelData<FArrayBox>& a_phiThisLevel, const LevelData<FArrayBox>& a_correctCoarse) { CH_TIME("ZeroAvgConstInterpPS::prolongIncrement"); // Gather grids, domains, refinement ratios... const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes(); const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes(); CH_assert(fineGrids.compatible(crseGrids)); const ProblemDomain& fineDomain = fineGrids.physDomain(); const ProblemDomain& crseDomain = crseGrids.physDomain(); const IntVect mgRefRatio = fineDomain.size() / crseDomain.size(); CH_assert(mgRefRatio.product() > 1); // These will accumulate averaging data. Real localSum = 0.0; Real localVol = 0.0; CH_assert(!m_CCJinvPtr.isNull()); CH_assert(m_dxProduct > 0.0); DataIterator dit = fineGrids.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { // Create references for convenience FArrayBox& fineFAB = a_phiThisLevel[dit]; const FArrayBox& crseFAB = a_correctCoarse[dit]; const Box& fineValid = fineGrids[dit]; const FArrayBox& JinvFAB = (*m_CCJinvPtr)[dit]; // To make things easier, we will offset the // coarse and fine data boxes to zero. const IntVect& fiv = fineValid.smallEnd(); const IntVect civ = coarsen(fiv, mgRefRatio); // Correct the fine data FORT_CONSTINTERPWITHAVGPS ( CHF_FRA_SHIFT(fineFAB, fiv), CHF_CONST_FRA_SHIFT(crseFAB, civ), CHF_BOX_SHIFT(fineValid, fiv), CHF_CONST_INTVECT(mgRefRatio), CHF_CONST_FRA1_SHIFT(JinvFAB,0,fiv), CHF_CONST_REAL(m_dxProduct), CHF_REAL(localVol), CHF_REAL(localSum)); } // Compute global sum (this is where the MPI communication happens) #ifdef CH_MPI Real globalSum = 0.0; int result = MPI_Allreduce(&localSum, &globalSum, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); if (result != MPI_SUCCESS) { MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement"); } Real globalVol = 0.0; result = MPI_Allreduce(&localVol, &globalVol, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); if (result != MPI_SUCCESS) { MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement"); } #else Real globalSum = localSum; Real globalVol = localVol; #endif // Remove the average from phi. Real avgPhi = globalSum / globalVol; for (dit.reset(); dit.ok(); ++dit) { a_phiThisLevel[dit] -= avgPhi; } }
void EBMGAverage::average(LevelData<EBCellFAB>& a_coarData, const LevelData<EBCellFAB>& a_fineData, const Interval& a_variables) { CH_TIMERS("EBMGAverage::average"); CH_TIMER("layout_changed_coarsenable", t1); CH_TIMER("layout_changed_not_coarsenable", t2); CH_TIMER("not_layout_changed", t3); CH_assert(a_fineData.ghostVect() == m_ghost); //CH_assert(a_coarData.ghostVect() == m_ghost); CH_assert(isDefined()); if (m_layoutChanged) { if (m_coarsenable) { CH_START(t1); EBCellFactory ebcellfact(m_buffEBISL); LevelData<EBCellFAB> coarsenedFineData(m_buffGrids, m_nComp, m_ghost, ebcellfact); EBLevelDataOps::setVal(coarsenedFineData, 0.0); for (DataIterator dit = m_fineGrids.dataIterator(); dit.ok(); ++dit) { averageFAB(coarsenedFineData[dit()], m_buffGrids[dit()], a_fineData[dit()], dit(), a_variables); } coarsenedFineData.copyTo(a_variables, a_coarData, a_variables, m_copier); CH_STOP(t1); } else { CH_START(t2); EBCellFactory ebcellfact(m_buffEBISL); LevelData<EBCellFAB> refinedCoarseData(m_buffGrids, m_nComp, m_ghost, ebcellfact); EBLevelDataOps::setVal(refinedCoarseData, 0.0); a_fineData.copyTo(a_variables, refinedCoarseData, a_variables, m_copier); for (DataIterator dit = m_coarGrids.dataIterator(); dit.ok(); ++dit) { averageFAB(a_coarData[dit()], m_coarGrids[dit()], refinedCoarseData[dit()], dit(), a_variables); } CH_STOP(t2); } } else { CH_START(t3); averageMG(a_coarData, a_fineData, a_variables); CH_STOP(t3); } }
void TimeInterpolatorRK4::intermediate(/// intermediate RK4 solution on this level coarsened LevelData<FArrayBox>& a_U, /// time interpolation coefficient in range [0:1] const Real& a_timeInterpCoeff, /// which RK4 stage: 0, 1, 2, 3 const int& a_stage, /// interval of a_U to fill in const Interval& a_intvl) const { CH_assert(m_defined); CH_assert(m_gotFullTaylorPoly); CH_assert(a_U.nComp() == m_numStates); CH_assert(a_stage >= 0); CH_assert(a_stage < 4); Real rinv = 1. / Real(m_refineCoarse); Vector<Real> intermCoeffs(4); // 0 is coefficient of m_taylorCoeffs[0] = Ucoarse(0) // 1 is coefficient of m_taylorCoeffs[1] = K1 // 2 is coefficient of m_taylorCoeffs[2] = 1/2 * (-3*K1 + 2*K2 + 2*K3 - K4) // 3 is coefficient of m_taylorCoeffs[3] = 2/3 * ( K1 - K2 - K3 + K4) Real diff12Coeffs; // coefficient of m_diff12 = - K2 + K3 switch (a_stage) { case 0: intermCoeffs[0] = 1.; intermCoeffs[1] = a_timeInterpCoeff; intermCoeffs[2] = a_timeInterpCoeff * a_timeInterpCoeff; intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff * a_timeInterpCoeff; diff12Coeffs = 0.; break; case 1: intermCoeffs[0] = 1.; intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff; intermCoeffs[2] = a_timeInterpCoeff * (rinv + a_timeInterpCoeff); intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff); diff12Coeffs = 0.; break; case 2: intermCoeffs[0] = 1.; intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff; intermCoeffs[2] = 0.5*rinv*rinv + a_timeInterpCoeff * (rinv + a_timeInterpCoeff); intermCoeffs[3] = 0.375*rinv*rinv*rinv + a_timeInterpCoeff * (1.5*rinv*rinv + a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff)); diff12Coeffs = -0.25 * rinv * rinv; break; case 3: intermCoeffs[0] = 1.; intermCoeffs[1] = rinv + a_timeInterpCoeff; intermCoeffs[2] = rinv*rinv + a_timeInterpCoeff * (2.*rinv + a_timeInterpCoeff); intermCoeffs[3] = 0.75*rinv*rinv*rinv + a_timeInterpCoeff * (3.*rinv*rinv + a_timeInterpCoeff * (3.*rinv + a_timeInterpCoeff)); diff12Coeffs = 0.5 * rinv * rinv; break; default: MayDay::Error("TimeInterpolatorRK4::intermediate must have a_stage in range 0:3"); } LevelData<FArrayBox> UComp; aliasLevelData(UComp, &a_U, a_intvl); // For i in 0:m_numCoeffs-1, // coeffFirst[i] is index of first component of m_taylorCoeffs // that corresponds to a coefficient of t^i. Vector<int> coeffFirst(m_numCoeffs); int intervalLength = a_intvl.size(); for (int i = 0; i < m_numCoeffs; i++) { coeffFirst[i] = a_intvl.begin() + i * m_numStates; } DataIterator dit = UComp.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { FArrayBox& UFab = UComp[dit]; const FArrayBox& taylorFab = m_taylorCoeffs[dit]; // WAS: Evaluate a0 + a1*t + a2*t^2 + a3*t^3 // as a0 + t * (a1 + t * (a2 + t * a3)): // that is, set UFab to // a3, t*a3 + a2, t*(t*a3 + a2) + a1, t*(t*(t*a3 + a2) + a1) * a0. // NEW: Evaluate a0*c0 + a1*c1 + a2*c2 + a3*c3, // where c0, c1, c2, c3 are scalars, // and c0 = intermCoeffs[0] = 1. UFab.copy(taylorFab, coeffFirst[0], 0, intervalLength); for (int ind = 1; ind < 4; ind++) { UFab.plus(taylorFab, intermCoeffs[ind], coeffFirst[ind], 0, intervalLength); } const FArrayBox& diff12Fab = m_diff12[dit]; UFab.plus(diff12Fab, diff12Coeffs, 0, 0, intervalLength); } // dummy statement in order to get around gdb bug int dummy_unused = 0; dummy_unused = 0; }
void EBPoissonOp:: applyOp(LevelData<EBCellFAB>& a_opPhi, const LevelData<EBCellFAB>& a_phi, bool a_homogeneousPhysBC, DataIterator& dit, bool a_do_exchange) { CH_TIMERS("EBPoissonOp::applyOp"); CH_TIMER("regular_apply", t1); CH_TIMER("irregular_apply", t2); CH_TIMER("eb_bcs_apply", t3); CH_TIMER("dom_bcs_apply", t4); CH_TIMER("alpha_apply", t5); CH_assert(a_opPhi.ghostVect() == m_ghostCellsRHS); CH_assert(a_phi.ghostVect() == m_ghostCellsPhi); CH_assert(a_phi.nComp() == a_opPhi.nComp()); LevelData<EBCellFAB>& phi = const_cast<LevelData<EBCellFAB>&>(a_phi); if (a_do_exchange) { phi.exchange(phi.interval()); } int nComps = a_phi.nComp(); for (dit.reset(); dit.ok(); ++dit) { Box dblBox( m_eblg.getDBL().get(dit()) ); const EBCellFAB& phifab = phi[dit()]; Box curPhiBox = phifab.box(); const BaseFab<Real>& curPhiFAB = phifab.getSingleValuedFAB(); EBCellFAB& opphifab = a_opPhi[dit()]; BaseFab<Real>& curOpPhiFAB = opphifab.getSingleValuedFAB(); // Interval interv(0, nComps-1); CH_START(t5); if (m_alpha == 0) { opphifab.setVal(0.0); } else { opphifab.copy(phifab); opphifab.mult(m_alpha); } CH_STOP(t5); Box loBox[SpaceDim],hiBox[SpaceDim]; int hasLo[SpaceDim],hasHi[SpaceDim]; CH_START(t1); applyOpRegularAllDirs( loBox, hiBox, hasLo, hasHi, dblBox, curPhiBox, nComps, curOpPhiFAB, curPhiFAB, a_homogeneousPhysBC, dit(), m_beta); CH_STOP(t1); CH_START(t2); //apply stencil m_opEBStencil[dit()]->apply(opphifab, phifab, false); CH_STOP(t2); //apply inhom boundary conditions CH_START(t3); if (!a_homogeneousPhysBC) { const Real factor = m_dxScale*m_beta; m_ebBC->applyEBFlux(opphifab, phifab, m_vofItIrreg[dit()], (*m_eblg.getCFIVS()), dit(), m_origin, m_dx, factor, a_homogeneousPhysBC, m_time); } CH_STOP(t3); CH_START(t4); int comp = 0; for (int idir = 0; idir < SpaceDim; idir++) { for (m_vofItIrregDomLo[idir][dit()].reset(); m_vofItIrregDomLo[idir][dit()].ok(); ++m_vofItIrregDomLo[idir][dit()]) { Real flux; const VolIndex& vof = m_vofItIrregDomLo[idir][dit()](); m_domainBC->getFaceFlux(flux,vof,comp,a_phi[dit()], m_origin,m_dx,idir,Side::Lo, dit(), m_time, a_homogeneousPhysBC); opphifab(vof,comp) -= flux * m_beta*m_invDx[idir]; } for (m_vofItIrregDomHi[idir][dit()].reset(); m_vofItIrregDomHi[idir][dit()].ok(); ++m_vofItIrregDomHi[idir][dit()]) { Real flux; const VolIndex& vof = m_vofItIrregDomHi[idir][dit()](); m_domainBC->getFaceFlux(flux,vof,comp,a_phi[dit()], m_origin,m_dx,idir,Side::Hi,dit(), m_time, a_homogeneousPhysBC); opphifab(vof,comp) += flux * m_beta*m_invDx[idir]; } } CH_STOP(t4); } }
void VCAMRPoissonOp2::restrictResidual(LevelData<FArrayBox>& a_resCoarse, LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_rhsFine) { CH_TIME("VCAMRPoissonOp2::restrictResidual"); homogeneousCFInterp(a_phiFine); const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout(); for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit) { FArrayBox& phi = a_phiFine[dit]; m_bc(phi, dblFine[dit()], m_domain, m_dx, true); } a_phiFine.exchange(a_phiFine.interval(), m_exchangeCopier); for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit) { FArrayBox& phi = a_phiFine[dit]; const FArrayBox& rhs = a_rhsFine[dit]; FArrayBox& res = a_resCoarse[dit]; const FArrayBox& thisACoef = (*m_aCoef)[dit]; const FluxBox& thisBCoef = (*m_bCoef)[dit]; Box region = dblFine.get(dit()); const IntVect& iv = region.smallEnd(); IntVect civ = coarsen(iv, 2); res.setVal(0.0); #if CH_SPACEDIM == 1 FORT_RESTRICTRESVC1D #elif CH_SPACEDIM == 2 FORT_RESTRICTRESVC2D #elif CH_SPACEDIM == 3 FORT_RESTRICTRESVC3D #else This_will_not_compile! #endif (CHF_FRA_SHIFT(res, civ), CHF_CONST_FRA_SHIFT(phi, iv), CHF_CONST_FRA_SHIFT(rhs, iv), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA_SHIFT(thisACoef, iv), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA_SHIFT(thisBCoef[0], iv), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA_SHIFT(thisBCoef[1], iv), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA_SHIFT(thisBCoef[2], iv), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_BOX_SHIFT(region, iv), CHF_CONST_REAL(m_dx)); } }
// // VCAMRPoissonOp2::reflux() // There are currently the new version (first) and the old version (second) // in this file. Brian asked to preserve the old version in this way for // now. - TJL (12/10/2007) // void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_phi, LevelData<FArrayBox>& a_residual, AMRLevelOp<LevelData<FArrayBox> >* a_finerOp) { CH_TIMERS("VCAMRPoissonOp2::reflux"); m_levfluxreg.setToZero(); Interval interv(0,a_phi.nComp()-1); CH_TIMER("VCAMRPoissonOp2::reflux::incrementCoarse", t2); CH_START(t2); 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]; if (m_levfluxreg.hasCF(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; m_levfluxreg.incrementCoarse(coarflux, scale,dit(), interv, interv, idir); } } } CH_STOP(t2); // const cast: OK because we're changing ghost cells only LevelData<FArrayBox>& phiFineRef = ( LevelData<FArrayBox>&)a_phiFine; VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp; QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser; quadCFI.coarseFineInterp(phiFineRef, a_phi); // I'm pretty sure this is not necessary. bvs -- flux calculations use // outer ghost cells, but not inner ones // phiFineRef.exchange(a_phiFine.interval()); IntVect phiGhost = phiFineRef.ghostVect(); int ncomps = a_phiFine.nComp(); CH_TIMER("VCAMRPoissonOp2::reflux::incrementFine", t3); CH_START(t3); 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()) { if (m_levfluxreg.hasCF(ditf(), sit())) { Side::LoHiSide hiorlo = sit(); Box fluxBox = bdryBox(gridbox,idir,hiorlo,1); FArrayBox fineflux(fluxBox,ncomps); getFlux(fineflux, phifFab, fineBCoef, fluxBox, idir, m_refToFiner); Real scale = 1.0; m_levfluxreg.incrementFine(fineflux, scale, ditf(), interv, interv, idir, hiorlo); } } } } CH_STOP(t3); Real scale = 1.0/m_dx; m_levfluxreg.reflux(a_residual, scale); }
void EBLevelAdvect:: advectToFacesBCG(LevelData< EBFluxFAB >& a_extrapState, const LevelData< EBCellFAB >& a_consState, const LevelData< EBCellFAB >& a_normalVel, const LevelData< EBFluxFAB >& a_advectionVel, const LevelData< EBCellFAB >* a_consStateCoarseOld, const LevelData< EBCellFAB >* a_consStateCoarseNew, const LevelData< EBCellFAB >* a_normalVelCoarseOld, const LevelData< EBCellFAB >* a_normalVelCoarseNew, const Real& a_timeCoarseOld, const Real& a_timeCoarseNew, const Real& a_timeFine, const Real& a_dt, const LevelData<EBCellFAB>* const a_source, const LevelData<EBCellFAB>* const a_sourceCoarOld, const LevelData<EBCellFAB>* const a_sourceCoarNew) { CH_TIME("EBLevelAdvect::advectToFacesBCG (level)"); CH_assert(isDefined()); //create temp data with the correct number of ghost cells IntVect ivGhost = m_nGhost*IntVect::Unit; Interval consInterv(0, m_nVar-1); Interval intervSD(0, SpaceDim-1); // LevelData<EBCellFAB>& consTemp = (LevelData<EBCellFAB>&) a_consState; // LevelData<EBCellFAB>& veloTemp = (LevelData<EBCellFAB>&) a_normalVel; EBCellFactory factory(m_thisEBISL); LevelData<EBCellFAB> consTemp(m_thisGrids, m_nVar, ivGhost, factory); LevelData<EBCellFAB> veloTemp(m_thisGrids, SpaceDim, ivGhost, factory); for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit) { consTemp[dit()].setVal(0.); } a_consState.copyTo(consInterv, consTemp, consInterv); a_normalVel.copyTo(intervSD, veloTemp, intervSD); // Fill ghost cells using fillInterp, and copyTo. if (m_hasCoarser) { CH_TIME("fillPatch"); m_fillPatch.interpolate(consTemp, *a_consStateCoarseOld, *a_consStateCoarseNew, a_timeCoarseOld, a_timeCoarseNew, a_timeFine, consInterv); m_fillPatchVel.interpolate(veloTemp, *a_normalVelCoarseOld, *a_normalVelCoarseNew, a_timeCoarseOld, a_timeCoarseNew, a_timeFine, intervSD); } // Exchange all the data between grids { CH_TIME("initial_exchange"); consTemp.exchange(consInterv); veloTemp.exchange(intervSD); } LevelData<EBCellFAB>* srcTmpPtr = NULL; if (a_source != NULL) { // srcTmpPtr = (LevelData<EBCellFAB>*) a_source; srcTmpPtr = new LevelData<EBCellFAB>(m_thisGrids, m_nVar, ivGhost, factory); for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit) { (*srcTmpPtr)[dit()].setVal(0.); } a_source->copyTo(consInterv, *srcTmpPtr, consInterv); if ( (a_sourceCoarOld != NULL) && (a_sourceCoarNew != NULL) && (m_hasCoarser) ) { CH_TIME("fillPatch"); m_fillPatch.interpolate(*srcTmpPtr, *a_sourceCoarOld, *a_sourceCoarNew, a_timeCoarseOld, a_timeCoarseNew, a_timeFine, consInterv); { CH_TIME("initial_exchange"); srcTmpPtr->exchange(consInterv); } } } { CH_TIME("advectToFaces"); int ibox = 0; for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit) { const Box& cellBox = m_thisGrids.get(dit()); const EBISBox& ebisBox = m_thisEBISL[dit()]; if (!ebisBox.isAllCovered()) { //the viscous term goes into here EBCellFAB dummy; EBCellFAB* srcPtr = &dummy; if (srcTmpPtr != NULL) { srcPtr = (EBCellFAB*)(&((*srcTmpPtr)[dit()])); } const EBCellFAB& source = *srcPtr; //unused in this case BaseIVFAB<Real> boundaryPrim; bool doBoundaryPrim = false; EBFluxFAB& extrapFAB = a_extrapState[dit()]; advectToFacesBCG(extrapFAB, boundaryPrim, consTemp[dit()], veloTemp[dit()], a_advectionVel[dit()], cellBox, ebisBox, a_dt, a_timeFine, source, dit(), doBoundaryPrim); ibox++; } } } if (srcTmpPtr != NULL) { delete srcTmpPtr; } }
void EBFineToCoarRedist:: resetWeights(const LevelData<EBCellFAB>& a_modifierCoar, const int& a_ivar) { CH_TIME("EBFineToCoarRedist::resetWeights"); //set the weights to mass weighting if the modifier //is the coarse density. Interval srcInterv(a_ivar, a_ivar); Interval dstInterv(0,0); a_modifierCoar.copyTo(srcInterv, m_densityCoar, dstInterv); for (DataIterator dit = m_gridsCoar.dataIterator(); dit.ok(); ++dit) { const IntVectSet& fineSet = m_setsRefCoar[dit()]; BaseIVFAB<VoFStencil>& massStenFAB = m_stenRefCoar[dit()]; const BaseIVFAB<VoFStencil>& volStenFAB = m_volumeStenc[dit()]; const BaseIVFAB<VoFStencil>& stanStenFAB = m_standardStenc[dit()]; const EBISBox& ebisBoxFine = m_ebislRefCoar[dit()]; const EBCellFAB& modFAB = m_densityCoar[dit()]; for (VoFIterator vofit(fineSet, ebisBoxFine.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vofFine = vofit(); const VoFStencil& oldSten = volStenFAB(vofFine, 0); const VoFStencil& stanSten = stanStenFAB(vofFine, 0); VoFStencil newSten; for (int isten = 0; isten < oldSten.size(); isten++) { const VolIndex& thatVoFFine = oldSten.vof(isten); VolIndex refCoarVoF = m_ebislRefCoar.coarsen(thatVoFFine, m_refRat, dit()); Real weight = modFAB(refCoarVoF, a_ivar); //it is weight*volfrac that is normalized newSten.add(thatVoFFine, weight); } //have to normalize using the whole stencil Real sum = 0.0; for (int isten = 0; isten < stanSten.size(); isten++) { const VolIndex& thatVoFFine = stanSten.vof(isten); VolIndex refCoarVoF = m_ebislRefCoar.coarsen(thatVoFFine, m_refRat, dit()); Real weight = modFAB(refCoarVoF, a_ivar); Real volfrac = ebisBoxFine.volFrac(thatVoFFine); //it is weight*volfrac that is normalized sum += weight*volfrac; } if (Abs(sum) > 0.0) { Real scaling = 1.0/sum; newSten *= scaling; } massStenFAB(vofFine, 0) = newSten; } } }