diff --git a/Src/AmrCore/AMReX_FillPatchUtil.H b/Src/AmrCore/AMReX_FillPatchUtil.H index e740ccce0d..2c41e7556d 100644 --- a/Src/AmrCore/AMReX_FillPatchUtil.H +++ b/Src/AmrCore/AMReX_FillPatchUtil.H @@ -694,6 +694,23 @@ namespace amrex const PreInterpHook& pre_interp = {}, const PostInterpHook& post_interp = {}); + /** + * \brief Fill with interpolation of coarse level data + * + * It's the CALLER's responsibility to make sure all ghost cells of the + * coarse MF needed for interpolation are filled already before calling + * this function. It's assumed that the fine level MultiFab mf's + * BoxArray is coarsenable by the refinement ratio. There is no support + * for EB. + */ + template + std::enable_if_t::value> + InterpFromCoarseLevel (MF& mf, IntVect const& nghost, const MF& cmf, + int scomp, int dcomp, int ncomp, + const Geometry& cgeom, const Geometry& fgeom, + const IntVect& ratio, Interp* mapper, + const Vector& bcs); + #ifndef BL_NO_FORT enum InterpEM_t { InterpE, InterpB}; diff --git a/Src/AmrCore/AMReX_FillPatchUtil_I.H b/Src/AmrCore/AMReX_FillPatchUtil_I.H index 190566a7fa..de77f37f88 100644 --- a/Src/AmrCore/AMReX_FillPatchUtil_I.H +++ b/Src/AmrCore/AMReX_FillPatchUtil_I.H @@ -1210,6 +1210,35 @@ InterpFromCoarseLevel (Array const& mf, IntVect const& ngho } } +template +std::enable_if_t::value> +InterpFromCoarseLevel (MF& mf, IntVect const& nghost, const MF& cmf, + int scomp, int dcomp, int ncomp, + const Geometry& cgeom, const Geometry& fgeom, + const IntVect& ratio, Interp* mapper, + const Vector& bcs) +{ + const BoxArray& ba = mf.boxArray(); + const DistributionMapping& dm = mf.DistributionMap(); + + const IndexType& typ = ba.ixType(); + BL_ASSERT(typ == cmf.boxArray().ixType()); + + const InterpolaterBoxCoarsener& coarsener = mapper->BoxCoarsener(ratio); + Box tmp(-nghost, IntVect(32), typ); + Box tmp2 = coarsener.doit(tmp); + IntVect src_ghost = -tmp2.smallEnd(); + + MF mf_crse_patch(amrex::coarsen(ba,ratio), dm, ncomp, src_ghost); + mf_crse_patch.ParallelCopy(cmf, scomp, 0, ncomp, src_ghost, src_ghost, + cgeom.periodicity()); + + Box fdomain_g = amrex::convert(fgeom.Domain(),typ); + fdomain_g.grow(nghost); + FillPatchInterp(mf, dcomp, mf_crse_patch, 0, ncomp, IntVect(0), cgeom, fgeom, + fdomain_g, ratio, mapper, bcs, 0); +} + template std::enable_if_t::value> FillPatchNLevels (MF& mf, int level, const IntVect& nghost, Real time,