diff --git a/Src/AmrCore/AMReX_FillPatchUtil.H b/Src/AmrCore/AMReX_FillPatchUtil.H index e740ccce0d..7651201a83 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 + * + * No ghost cells of the destination MF on the fine level are + * filled. 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, 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..4aa6f3607e 100644 --- a/Src/AmrCore/AMReX_FillPatchUtil_I.H +++ b/Src/AmrCore/AMReX_FillPatchUtil_I.H @@ -1210,6 +1210,34 @@ InterpFromCoarseLevel (Array const& mf, IntVect const& ngho } } +template +std::enable_if_t::value> +InterpFromCoarseLevel (MF& mf, const MF& cmf, int scomp, int dcomp, int ncomp, + const Geometry& cgeom, const Geometry& fgeom, + const IntVect& ratio, Interp* mapper, + const Vector& bcs) +{ + const InterpolaterBoxCoarsener& coarsener = mapper->BoxCoarsener(ratio); + Box tmp(IntVect(0), IntVect(7)); + tmp.refine(ratio); + Box tmp2 = coarsener.doit(tmp); + IntVect src_ghost = -tmp2.smallEnd(); + + const BoxArray& ba = mf.boxArray(); + const DistributionMapping& dm = mf.DistributionMap(); + + const IndexType& typ = ba.ixType(); + + BL_ASSERT(typ == cmf.boxArray().ixType()); + + 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()); + + FillPatchInterp(mf, dcomp, mf_crse_patch, 0, ncomp, IntVect(0), cgeom, fgeom, + amrex::convert(fgeom.Domain(),typ), ratio, mapper, bcs, 0); +} + template std::enable_if_t::value> FillPatchNLevels (MF& mf, int level, const IntVect& nghost, Real time,