1#ifndef AMREX_FILLPATCHER_H_
2#define AMREX_FILLPATCHER_H_
3#include <AMReX_Config.H>
76template <
class MF = MultiFab>
129 template <
typename BC,
135 int scomp,
int dcomp,
int ncomp,
136 BC& cbc,
int cbccomp, BC& fbc,
int fbccomp,
138 PreInterpHook
const& pre_interp = {},
139 PostInterpHook
const& post_interp = {});
160 template <
typename BC,
161 typename PreInterpHook=NullInterpHook<MF>,
162 typename PostInterpHook=NullInterpHook<MF> >
166 int scomp,
int dcomp,
int ncomp,
167 BC& cbc,
int cbccomp,
169 PreInterpHook
const& pre_interp = {},
170 PostInterpHook
const& post_interp = {});
181 template <std::
size_t order>
182 requires (order == 3 || order == 4)
202 template <
typename BC>
203 void fillRK (
int stage,
int iteration,
int ncycle, MF& mf,
Real time,
224 std::unique_ptr<MF> m_cf_crse_data_tmp;
225 std::unique_ptr<MF> m_cf_fine_data;
226 Real m_dt_coarse = std::numeric_limits<Real>::lowest();
247 m_eb_index_space(eb_index_space),
248 m_sfine(fba, fdm, 1, nghost,
MFInfo().SetAlloc(false))
251 "FillPatcher<MF>: MF must be FabArray type");
254 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
261template <
typename BC,
typename PreInterpHook,
typename PostInterpHook>
266 int scomp,
int dcomp,
int ncomp,
267 BC& cbc,
int cbccomp,
268 BC& fbc,
int fbccomp,
270 PreInterpHook
const& pre_interp,
271 PostInterpHook
const& post_interp)
276 !fmf.empty() && fmf.
size() == ft.
size() &&
277 m_fba == fmf[0]->boxArray() && m_fdm == fmf[0]->DistributionMap());
279 fillCoarseFineBoundary(mf, nghost, time, cmf, ct, scomp, dcomp, ncomp,
280 cbc, cbccomp, bcs, bcscomp, pre_interp, post_interp);
283 m_fgeom, fbc, fbccomp);
292 m_fgeom, m_cgeom, m_eb_index_space);
296template <
typename BC,
typename PreInterpHook,
typename PostInterpHook>
301 int scomp,
int dcomp,
int ncomp,
302 BC& cbc,
int cbccomp,
304 PreInterpHook
const& pre_interp,
305 PostInterpHook
const& post_interp)
310 nghost.
allLE(m_nghost) &&
311 m_fba == mf.boxArray() &&
312 m_fdm == mf.DistributionMap() &&
313 m_cba == cmf[0]->boxArray() &&
314 m_cdm == cmf[0]->DistributionMap() &&
316 m_ncomp == cmf[0]->nComp());
318 auto const& fpc = getFPinfo();
320 if ( ! fpc.ba_crse_patch.empty())
322 if (m_cf_fine_data ==
nullptr) {
323 m_cf_fine_data = std::make_unique<MF>
324 (detail::make_mf_fine_patch<MF>(fpc, m_ncomp));
327 int ncmfs = cmf.
size();
328 for (
int icmf = 0; icmf < ncmfs; ++icmf) {
330 auto it = std::find_if(m_cf_crse_data.begin(), m_cf_crse_data.end(),
331 [=] (
auto const&
x) {
332 return amrex::almostEqual(x.first,t,5);
335 if (it == std::end(m_cf_crse_data)) {
336 MF mf_crse_patch = detail::make_mf_crse_patch<MF>(fpc, m_ncomp);
337 mf_crse_patch.ParallelCopy(*cmf[icmf], m_cgeom.periodicity());
339 std::pair<Real,std::unique_ptr<MF>> tmp;
341 tmp.second = std::make_unique<MF>(std::move(mf_crse_patch));
342 m_cf_crse_data.push_back(std::move(tmp));
346 if (m_cf_crse_data_tmp ==
nullptr) {
347 m_cf_crse_data_tmp = std::make_unique<MF>
348 (detail::make_mf_crse_patch<MF>(fpc, m_ncomp));
352 IntVect const ng_space_interp = m_nghost/m_ratio + 8;
353 Box domain = m_cgeom.growPeriodicDomain(ng_space_interp);
357 if (m_cf_crse_data.size() == 1) {
359 }
else if (m_cf_crse_data.size() == 2) {
360 Real const teps = std::abs(m_cf_crse_data[1].first -
361 m_cf_crse_data[0].first) * 1.e-3_rt;
362 if (time > m_cf_crse_data[0].first - teps &&
363 time < m_cf_crse_data[0].first + teps) {
365 }
else if (time > m_cf_crse_data[1].first - teps &&
366 time < m_cf_crse_data[1].first + teps) {
373 if (idata == 0 || idata == 1) {
374 auto const& dst = m_cf_crse_data_tmp->arrays();
375 auto const& src = m_cf_crse_data[idata].second->const_arrays();
380 dst[bi](i,j,k,n) = src[bi](i,j,k,n+scomp);
383 }
else if (idata == 2) {
384 Real t0 = m_cf_crse_data[0].first;
385 Real t1 = m_cf_crse_data[1].first;
386 Real alpha = (t1-time)/(t1-t0);
388 auto const& a = m_cf_crse_data_tmp->arrays();
389 auto const& a0 = m_cf_crse_data[0].second->const_arrays();
390 auto const& a1 = m_cf_crse_data[1].second->const_arrays();
396 = alpha*a0[bi](i,j,k,scomp+n)
397 + beta*a1[bi](i,j,k,scomp+n);
403 amrex::Abort(
"FillPatcher: High order interpolation in time not supported. Or FillPatcher was not properly deleted.");
408 cbc(*m_cf_crse_data_tmp, 0, ncomp, m_cf_crse_data_tmp->nGrowVect(), time, cbccomp);
410 detail::call_interp_hook(pre_interp, *m_cf_crse_data_tmp, 0, ncomp);
413 ncomp,
IntVect(0), m_cgeom, m_fgeom,
415 mf.ixType()),nghost),
416 m_ratio, m_interp, bcs, bcscomp);
418 detail::call_interp_hook(post_interp, *m_cf_fine_data, scomp, ncomp);
420 mf.ParallelCopy(*m_cf_fine_data, scomp, dcomp, ncomp,
IntVect{0}, nghost);
424template <
typename MF>
425template <std::
size_t order>
426requires (order == 3 || order == 4)
430 BL_PROFILE(
"FillPatcher::storeRKCoarseData()");
432 m_cf_crse_data.resize(order+1);
434 auto const& fpc = getFPinfo();
436 for (
auto& tmf : m_cf_crse_data) {
437 tmf.first = std::numeric_limits<Real>::lowest();
438 tmf.second = std::make_unique<MF>(detail::make_mf_crse_patch<MF>(fpc, m_ncomp));
440 m_cf_crse_data[0].second->ParallelCopy(S_old, m_cgeom.periodicity());
441 for (std::size_t i = 0; i < order; ++i) {
442 m_cf_crse_data[i+1].second->ParallelCopy(RK_k[i], m_cgeom.periodicity());
446template <
typename MF>
447template <
typename BC>
449 MF& mf,
Real time, BC& cbc, BC& fbc,
453 int rk_order = m_cf_crse_data.size()-1;
454 if (rk_order != 3 && rk_order != 4) {
455 amrex::Abort(
"FillPatcher: unsupported RK order "+std::to_string(rk_order));
460 auto const& fpc = getFPinfo();
461 if (m_cf_crse_data_tmp ==
nullptr) {
462 m_cf_crse_data_tmp = std::make_unique<MF>
463 (detail::make_mf_crse_patch<MF>(fpc, m_ncomp));
466 auto const& u = m_cf_crse_data_tmp->arrays();
467 auto const& u0 = m_cf_crse_data[0].second->const_arrays();
468 auto const& k1 = m_cf_crse_data[1].second->const_arrays();
469 auto const& k2 = m_cf_crse_data[2].second->const_arrays();
470 auto const& k3 = m_cf_crse_data[3].second->const_arrays();
472 Real dtc = m_dt_coarse;
476 IntVect const ng_space_interp = m_nghost/m_ratio + 8;
477 Box cdomain = m_cgeom.growPeriodicDomain(ng_space_interp);
478 cdomain.
convert(m_cf_crse_data_tmp->ixType());
482 Real b1 = xsi -
Real(5./6.)*xsi*xsi;
498 Real kk1 = k1[bi](i,j,k,n);
499 Real kk2 = k2[bi](i,j,k,n);
500 Real kk3 = k3[bi](i,j,k,n);
501 Real uu = b1*kk1 + b2*kk2 + b3*kk3;
502 u[bi](i,j,k,n) = u0[bi](i,j,k,n) + dtc*uu;
505 }
else if (stage == 2) {
510 Real kk1 = k1[bi](i,j,k,n);
511 Real kk2 = k2[bi](i,j,k,n);
512 Real kk3 = k3[bi](i,j,k,n);
513 Real uu = b1*kk1 + b2*kk2 + b3*kk3;
514 Real ut = c1*kk1 + c2*kk2 + c3*kk3;
515 u[bi](i,j,k,n) = u0[bi](i,j,k,n) + dtc*(uu + r*ut);
518 }
else if (stage == 3) {
523 Real kk1 = k1[bi](i,j,k,n);
524 Real kk2 = k2[bi](i,j,k,n);
525 Real kk3 = k3[bi](i,j,k,n);
526 Real uu = b1*kk1 + b2*kk2 + b3*kk3;
527 Real ut = c1*kk1 + c2*kk2 + c3*kk3;
528 Real utt = d1*kk1 + d2*kk2 + d3*kk3;
529 u[bi](i,j,k,n) = u0[bi](i,j,k,n) + dtc*
530 (uu + Real(0.5)*r*ut + Real(0.25)*r*r*utt);
534 }
else if (rk_order == 4) {
535 auto const& k4 = m_cf_crse_data[4].second->const_arrays();
537 Real xsi3 = xsi2*xsi;
563 Real kk1 = k1[bi](i,j,k,n);
564 Real kk2 = k2[bi](i,j,k,n);
565 Real kk3 = k3[bi](i,j,k,n);
566 Real kk4 = k4[bi](i,j,k,n);
567 Real uu = b1*kk1 + b2*kk2 + b3*kk3 + b4*kk4;
568 u[bi](i,j,k,n) = u0[bi](i,j,k,n) + dtc*uu;
571 }
else if (stage == 2) {
576 Real kk1 = k1[bi](i,j,k,n);
577 Real kk2 = k2[bi](i,j,k,n);
578 Real kk3 = k3[bi](i,j,k,n);
579 Real kk4 = k4[bi](i,j,k,n);
580 Real uu = b1*kk1 + b2*kk2 + b3*kk3 + b4*kk4;
581 Real ut = c1*kk1 + c2*kk2 + c3*kk3 + c4*kk4;
582 u[bi](i,j,k,n) = u0[bi](i,j,k,n) + dtc*(uu + Real(0.5)*r*ut);
585 }
else if (stage == 3 || stage == 4) {
588 Real at = (stage == 3) ?
Real(0.5)*r : r;
590 Real attt = (stage == 3) ?
Real(0.0625)*r3 :
Real(0.125)*r3;
596 Real kk1 = k1[bi](i,j,k,n);
597 Real kk2 = k2[bi](i,j,k,n);
598 Real kk3 = k3[bi](i,j,k,n);
599 Real kk4 = k4[bi](i,j,k,n);
600 Real uu = b1*kk1 + b2*kk2 + b3*kk3 + b4*kk4;
601 Real ut = c1*kk1 + c2*kk2 + c3*kk3 + c4*kk4;
602 Real utt = d1*kk1 + d2*kk2 + d3*kk3 + d4*kk4;
603 Real uttt = e1*kk1 + e2*kk2 + e3*kk3 + e4*kk4;
604 u[bi](i,j,k,n) = u0[bi](i,j,k,n) + dtc *
605 (uu + at*ut + att*utt + attt*(uttt+akk*(kk3-kk2)));
613 cbc(*m_cf_crse_data_tmp, 0, m_ncomp, m_cf_crse_data_tmp->nGrowVect(), time, 0);
615 if (m_cf_fine_data ==
nullptr) {
616 m_cf_fine_data = std::make_unique<MF>(detail::make_mf_fine_patch<MF>(fpc, m_ncomp));
620 m_ncomp,
IntVect(0), m_cgeom, m_fgeom,
622 mf.ixType()),m_nghost),
623 m_ratio, m_interp, bcs, 0);
626 mf.ParallelCopy(*m_cf_fine_data, 0, 0, m_ncomp,
IntVect(0), m_nghost);
628 mf.FillBoundary(m_fgeom.periodicity());
629 fbc(mf, 0, m_ncomp, m_nghost, time, 0);
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:562
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
High-level FillPatch helpers for AMR coarse-to-fine synchronization.
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
GpuArray< Real, 3 > beta
Definition AMReX_MLEBNodeFDLaplacian.cpp:1099
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:681
IndexType ixType() const noexcept
Return index type of this BoxArray.
Definition AMReX_BoxArray.H:1268
__host__ __device__ IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:167
__host__ __device__ BoxND & convert(IndexTypeND< dim > typ) noexcept
Convert the BoxND from the current type into the argument type. This may change the BoxND coordinates...
Definition AMReX_Box.H:1008
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:233
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:51
Definition AMReX_EB2.H:28
static const FPinfo & TheFPinfo(const FabArrayBase &srcfa, const FabArrayBase &dstfa, const IntVect &dstng, const BoxConverter &coarsener, const Geometry &fgeom, const Geometry &cgeom, const EB2::IndexSpace *)
Definition AMReX_FabArrayBase.cpp:2074
FillPatcher is for filling a fine level MultiFab/FabArray.
Definition AMReX_FillPatcher.H:78
InterpBase * interp() const noexcept
Interpolater this FillPatcher was built with.
Definition AMReX_FillPatcher.H:207
void storeRKCoarseData(Real time, Real dt, MF const &S_old, Array< MF, order > const &RK_k)
Store coarse AMR level data for RK3 and RK4.
Definition AMReX_FillPatcher.H:427
void fillCoarseFineBoundary(MF &mf, IntVect const &nghost, Real time, Vector< MF * > const &cmf, Vector< Real > const &ct, int scomp, int dcomp, int ncomp, BC &cbc, int cbccomp, Vector< BCRec > const &bcs, int bcscomp, PreInterpHook const &pre_interp={}, PostInterpHook const &post_interp={})
Function to fill data at coarse/fine boundary only.
Definition AMReX_FillPatcher.H:298
void fill(MF &mf, IntVect const &nghost, Real time, Vector< MF * > const &cmf, Vector< Real > const &ct, Vector< MF * > const &fmf, Vector< Real > const &ft, int scomp, int dcomp, int ncomp, BC &cbc, int cbccomp, BC &fbc, int fbccomp, Vector< BCRec > const &bcs, int bcscomp, PreInterpHook const &pre_interp={}, PostInterpHook const &post_interp={})
Function to fill data.
Definition AMReX_FillPatcher.H:263
void fillRK(int stage, int iteration, int ncycle, MF &mf, Real time, BC &cbc, BC &fbc, Vector< BCRec > const &bcs)
Fill ghost cells of fine AMR level for RK3 and RK4.
Definition AMReX_FillPatcher.H:448
FillPatcher(BoxArray const &fba, DistributionMapping const &fdm, Geometry const &fgeom, BoxArray const &cba, DistributionMapping const &cdm, Geometry const &cgeom, IntVect const &nghost, int ncomp, InterpBase *interp, EB2::IndexSpace const *eb_index_space=EB2::TopIndexSpaceIfPresent())
Constructor of FillPatcher.
Definition AMReX_FillPatcher.H:232
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:85
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:244
__host__ __device__ bool cellCentered() const noexcept
True if the IndexTypeND is CELL based in all directions.
Definition AMReX_IndexType.H:102
__host__ __device__ bool nodeCentered() const noexcept
True if the IndexTypeND is NODE based in all directions.
Definition AMReX_IndexType.H:108
__host__ __device__ constexpr bool allLE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is less than or equal to argument for all components. NOTE: This is NOT a strict...
Definition AMReX_IntVect.H:492
Definition AMReX_InterpBase.H:34
Definition AMReX_InterpBase.H:20
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Long size() const noexcept
Definition AMReX_Vector.H:54
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
__host__ __device__ BoxND< dim > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Return a copy of b converted to the nodal flags typ.
Definition AMReX_Box.H:1630
__host__ __device__ BoxND< dim > grow(const BoxND< dim > &b, int i) noexcept
Return a copy of b grown uniformly by i cells in every direction.
Definition AMReX_Box.H:1326
__host__ __device__ BoxND< dim > refine(const BoxND< dim > &b, int ref_ratio) noexcept
Return a copy of b refined by the isotropic ratio ref_ratio.
Definition AMReX_Box.H:1510
std::array< T, N > Array
Definition AMReX_Array.H:31
const IndexSpace * TopIndexSpaceIfPresent() noexcept
Return the top IndexSpace if one has been built (nullptr otherwise).
Definition AMReX_EB2.cpp:93
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
Definition AMReX_Amr.cpp:50
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
void FillPatchSingleLevel(MF &mf, IntVect const &nghost, Real time, const Vector< MF * > &smf, const Vector< Real > &stime, int scomp, int dcomp, int ncomp, const Geometry &geom, BC &physbcf, int bcfcomp)
FillPatch with data from the current level.
Definition AMReX_FillPatchUtil_I.H:75
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:242
void FillPatchInterp(MultiFab &mf_fine_patch, int fcomp, MultiFab const &mf_crse_patch, int ccomp, int ncomp, IntVect const &ng, const Geometry &cgeom, const Geometry &fgeom, Box const &dest_domain, const IntVect &ratio, MFInterpolater *mapper, const Vector< BCRec > &bcs, int bcscomp)
Helper that applies a MFInterpolater to fill a fine patch from a coarse patch.
Definition AMReX_FillPatchUtil.cpp:138
Definition AMReX_FabArrayBase.H:322
Definition AMReX_TypeTraits.H:27
FabArray memory allocation information.
Definition AMReX_FabArray.H:73
Definition AMReX_FillPatchUtil.H:39