1#ifndef AMREX_YAFLUXREGISTER_H_
2#define AMREX_YAFLUXREGISTER_H_
3#include <AMReX_Config.H>
8#include <AMReX_YAFluxRegister_K.H>
36 using T =
typename MF::value_type;
37 using FAB =
typename MF::fab_type;
58 const IntVect& ref_ratio,
int fine_lev,
int nvar);
64 const IntVect& ref_ratio,
int fine_lev,
int nvar);
82 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
98 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
99 const Real* dx,
Real dt,
int srccomp,
int destcomp,
100 int numcomp,
RunOn runon)
noexcept;
112 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
128 const std::array<FAB const*, AMREX_SPACEDIM>& a_flux,
129 const Real* dx,
Real dt,
int srccomp,
int destcomp,
130 int numcomp,
RunOn runon)
noexcept;
138 void Reflux (MF& state,
int dc = 0);
141 void Reflux (MF& state,
int srccomp,
int destcomp,
int numcomp);
150 return !(
m_cfp_fab[mfi.LocalIndex()].empty());
195template <
typename MF>
199 const IntVect& ref_ratio,
int fine_lev,
int nvar)
201 define(fba, cba, fdm, cdm, fgeom, cgeom, ref_ratio, fine_lev, nvar);
204template <
typename MF>
209 const IntVect& ref_ratio,
int fine_lev,
int nvar)
215 m_fine_level = fine_lev;
218 m_crse_data.define(cba, cdm, nvar, 0);
220 m_crse_flag.define(cba, cdm, 1, 1);
222 const auto& cperiod = m_crse_geom.periodicity();
223 const std::vector<IntVect>& pshifts = cperiod.shiftIntVect();
228 Box cdomain = m_crse_geom.Domain();
229 for (
int idim=0; idim < AMREX_SPACEDIM; ++idim) {
230 if (m_crse_geom.isPeriodic(idim)) {
231 cdomain.
grow(idim,1);
235 m_crse_fab_flag.
resize(m_crse_flag.local_size(), crse_cell);
237 m_crse_flag.setVal(crse_cell);
241 m_crse_flag.setVal(crse_fine_boundary_cell, cpc1, 0, 1);
243 m_crse_flag.setVal(fine_cell, cpc0, 0, 1);
244 auto recv_layout_mask = m_crse_flag.RecvLayoutMask(cpc0);
246#pragma omp parallel if (Gpu::notInLaunchRegion())
249 if (recv_layout_mask[mfi]) {
250 m_crse_fab_flag[mfi.LocalIndex()] = fine_cell;
259 const auto n_cfba =
static_cast<int>(cfba.
size());
264 const int nthreads = omp_get_max_threads();
271 const int tid = omp_get_thread_num();
276 for (
int i = 0; i < n_cfba; ++i)
282 const auto ntmp =
static_cast<int>(bl_tmp.
size());
286 for (
int j = 0; j < ntmp; ++j) {
290 if (proc == myproc) {
296 for (
auto const& bl : bl_priv) {
300 for (
auto const& pmp : procmap_priv) {
301 cfp_procmap.insert(std::end(cfp_procmap), std::begin(pmp), std::end(pmp));
304 for (
auto& lid : localindex_priv) {
306 for (
int j = 0; j < nl; ++j) {
307 m_cfp_localindex.push_back(nlocal);
316 for (
int i = 0; i < n_cfba; ++i)
322 const auto ntmp =
static_cast<int>(bl_tmp.
size());
326 for (
int j = 0; j < ntmp; ++j) {
327 cfp_procmap.push_back(proc);
330 if (proc == myproc) {
331 for (
int j = 0; j < ntmp; ++j) {
332 m_cfp_localindex.push_back(nlocal);
344 m_cfpatch.define(cfp_ba, cfp_dm, nvar, 0);
346 m_cfp_fab.resize(nlocal);
349 const int li = mfi.LocalIndex();
350 const int flgi = m_cfp_localindex[li];
351 FAB& fab = m_cfpatch[mfi];
352 m_cfp_fab[flgi].push_back(&fab);
355 bool is_periodic = m_fine_geom.isAnyPeriodic();
357 m_cfp_mask.define(cfp_ba, cfp_dm, 1, 0);
358 m_cfp_mask.setVal(
T(1.0));
365 const Box& domainbox = m_crse_geom.Domain();
368#pragma omp parallel if (!run_on_gpu)
371 std::vector< std::pair<int,Box> > isects;
375 const Box& bx = mfi.fabbox();
378 FAB& fab = m_cfp_mask[mfi];
380 auto const& arr = m_cfp_mask.array(mfi);
382 for (
const auto& iv : pshifts)
387 for (
const auto& is : isects)
389 const Box& ibx = is.second - iv;
396 fab.template setVal<RunOn::Host>(
T(0.0), ibx);
409 tag.
dfab(i,j,k,n) =
T(0);
415template <
typename MF>
419 m_crse_data.setVal(
T(0.0));
420 m_cfpatch.setVal(
T(0.0));
423template <
typename MF>
440 m_cfp_localindex.clear();
444 m_crse_fab_flag.clear();
449template <
typename MF>
452 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
455 BL_ASSERT(m_crse_data.nComp() == flux[0]->nComp());
458 int numcomp = m_crse_data.nComp();
459 CrseAdd(mfi, flux, dx, dt, srccomp, destcomp, numcomp, runon);
462template <
typename MF>
465 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
466 const Real* dx,
Real dt,
int srccomp,
int destcomp,
467 int numcomp,
RunOn runon)
noexcept
469 BL_ASSERT(m_crse_data.nComp() >= destcomp+numcomp &&
470 flux[0]->nComp() >= srccomp+numcomp);
477 if (m_crse_fab_flag[mfi.LocalIndex()] == crse_cell) {
481 const Box& bx = mfi.tilebox();
483 auto dtdy =
static_cast<T>(dt/dx[1]);,
484 auto dtdz =
static_cast<T>(dt/dx[2]););
486 FAB const* fy = flux[1];,
487 FAB const* fz = flux[2];);
493 auto dest_arr = m_crse_data.array(mfi,destcomp);
494 auto const flag = m_crse_flag.const_array(mfi);
502 yafluxreg_crseadd(tbx, dest_arr, flag,
AMREX_D_DECL(fxarr,fyarr,fzarr),
507template <
typename MF>
510 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
513 BL_ASSERT(m_crse_data.nComp() == flux[0]->nComp());
516 int numcomp = m_crse_data.nComp();
517 FineAdd(mfi, flux, dx, dt, srccomp, destcomp, numcomp, runon);
520template <
typename MF>
523 const std::array<FAB const*, AMREX_SPACEDIM>& a_flux,
524 const Real* dx,
Real dt,
int srccomp,
int destcomp,
525 int numcomp,
RunOn runon)
noexcept
527 BL_ASSERT(m_cfpatch.nComp() >= destcomp+numcomp &&
528 a_flux[0]->nComp() >= srccomp+numcomp);
534 const int li = mfi.LocalIndex();
536 if (cfp_fabs.empty()) {
return; }
538 const Box& tbx = mfi.tilebox();
542 const T ratio =
static_cast<T>(
AMREX_D_TERM(m_ratio[0],*m_ratio[1],*m_ratio[2]));
543 std::array<T,AMREX_SPACEDIM> dtdx{{
AMREX_D_DECL(
static_cast<T>(dt/(dx[0]*ratio)),
544 static_cast<T>(dt/(dx[1]*ratio)),
545 static_cast<T>(dt/(dx[2]*ratio)))}};
546 const Dim3 rr = m_ratio.dim3();
549 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
554 int fluxcomp = srccomp;
555 std::array<FAB const*,AMREX_SPACEDIM> flux{{
AMREX_D_DECL(a_flux[0],a_flux[1],a_flux[2])}};
558 std::array<FAB,AMREX_SPACEDIM> ftmp;
561 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
563 ftmp[idim].resize(b,numcomp);
564 ftmp[idim].template setVal<RunOn::Host>(
T(0.0));
565 ftmp[idim].template copy<RunOn::Host>(*a_flux[idim], srccomp, 0, numcomp);
566 flux[idim] = &ftmp[idim];
573 for (
int idim=0; idim < AMREX_SPACEDIM; ++idim)
577 FAB const* f = flux[idim];
578 for (
FAB* cfp : cfp_fabs)
581 const Box& lobx_is = lobx & cfp->box();
585 auto d = cfp->array(destcomp);
586 auto dtdxs = dtdx[idim];
587 int dirside = idim*2+side;
591 yafluxreg_fineadd(tmpbox, d, farr, dtdxs, numcomp, dirside, rr);
596 const Box& hibx_is = hibx & cfp->box();
600 auto d = cfp->array(destcomp);
601 auto dtdxs = dtdx[idim];
602 int dirside = idim*2+side;
606 yafluxreg_fineadd(tmpbox, d, farr, dtdxs, numcomp, dirside, rr);
614template <
typename MF>
620 int numcomp = m_ncomp;
621 Reflux(state, srccomp, destcomp, numcomp);
624template <
typename MF>
632 if (!m_cfp_mask.empty())
635#pragma omp parallel if (Gpu::notInLaunchRegion())
639 const Box& bx = m_cfpatch[mfi].box();
640 auto const maskfab = m_cfp_mask.array(mfi);
641 auto cfptfab = m_cfpatch.array(mfi,srccomp);
644 cfptfab(i,j,k,n) *= maskfab(i,j,k);
649 m_crse_data.ParallelCopy(m_cfpatch, srccomp, srccomp, numcomp,
653 BL_ASSERT(state.nComp() >= destcomp + numcomp);
655 auto const& dst = state.arrays();
656 auto const& src = m_crse_data.const_arrays();
657 auto const& vol = m_cvol->const_arrays();
661 dst[bno](i,j,k,destcomp+n) += src[bno](i,j,k,srccomp+n) / vol[bno](i,j,k);
664 amrex::Add(state, m_crse_data, srccomp, destcomp, numcomp, 0);
668template <
typename MF>
675template <
typename MF>
#define BL_ASSERT(EX)
Definition AMReX_BLassert.H:39
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_HOST_DEVICE_PARALLEL_FOR_4D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:111
#define AMREX_LAUNCH_HOST_DEVICE_LAMBDA_FLAG(where_to_run, box, tbox, block)
Definition AMReX_GpuLaunch.nolint.H:144
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:676
std::vector< std::pair< int, Box > > intersections(const Box &bx) const
Return all intersections of bx with this BoxArray.
Definition AMReX_BoxArray.cpp:1186
BoxList complementIn(const Box &b) const
Return box - boxarray.
Definition AMReX_BoxArray.cpp:1314
BoxArray & coarsen(int refinement_ratio)
Coarsen each Box in the BoxArray by refinement_ratio.
Definition AMReX_BoxArray.cpp:672
Long size() const noexcept
Return the number of boxes in the BoxArray.
Definition AMReX_BoxArray.H:753
void uniqify()
Make ourselves unique.
Definition AMReX_BoxArray.cpp:1613
A list of Boxes sharing a common IndexType.
Definition AMReX_BoxList.H:109
Long size() const noexcept
The number of Boxes in this BoxList.
Definition AMReX_BoxList.H:173
void join(const BoxList &blist)
Join the BoxList to ourselves.
Definition AMReX_BoxList.cpp:71
__host__ __device__ BoxND & grow(int i) noexcept
Grow in all directions by i cells (negative shrinks).
Definition AMReX_Box.H:668
__host__ __device__ BoxND< new_dim > resize() const noexcept
Return a new BoxND of size new_dim by either shrinking or expanding this BoxND.
Definition AMReX_Box.H:927
__host__ __device__ bool cellCentered() const noexcept
Return true if BoxND is cell-centered in all indexing directions.
Definition AMReX_Box.H:356
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:233
__host__ __device__ bool ok() const noexcept
Return true if high bounds are >= low bounds and the index type is valid.
Definition AMReX_Box.H:229
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:51
@ ADD
Definition AMReX_FabArrayBase.H:393
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:75
__host__ static __device__ constexpr IntVectND< dim > TheZeroVector() noexcept
This static member function returns a reference to a constant IntVectND object, all of whose dim argu...
Definition AMReX_IntVect.H:771
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:172
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Definition AMReX_YAFluxRegister.H:33
MF & getFineData()
Mutable access to fine-side accumulation data.
Definition AMReX_YAFluxRegister.H:670
Vector< Vector< FAB * > > m_cfp_fab
The size of this is (# of local fine grids (# of crse/fine patches for that grid))
Definition AMReX_YAFluxRegister.H:181
Vector< int > m_crse_fab_flag
Definition AMReX_YAFluxRegister.H:177
MF m_cfpatch
This is built on crse/fine patches.
Definition AMReX_YAFluxRegister.H:179
void Reflux(MF &state, int dc=0)
Apply the accumulated flux divergence to the coarse MultiFab state.
Definition AMReX_YAFluxRegister.H:616
Geometry m_fine_geom
Definition AMReX_YAFluxRegister.H:184
IntVect m_ratio
Definition AMReX_YAFluxRegister.H:187
void FineAdd(const MFIter &mfi, const std::array< FAB const *, 3 > &flux, const Real *dx, Real dt, RunOn runon) noexcept
Add fine-level fluxes for the tile identified by mfi.
Definition AMReX_YAFluxRegister.H:509
void define(const BoxArray &fba, const BoxArray &cba, const DistributionMapping &fdm, const DistributionMapping &cdm, const Geometry &fgeom, const Geometry &cgeom, const IntVect &ref_ratio, int fine_lev, int nvar)
Define the register using the same arguments as the constructor.
Definition AMReX_YAFluxRegister.H:206
bool CrseHasWork(const MFIter &mfi) const noexcept
Return true if coarse tile mfi abuts a coarse/fine boundary.
Definition AMReX_YAFluxRegister.H:144
YAFluxRegisterT()=default
Construct an empty register; call define() before use.
MF const * m_cvol
Definition AMReX_YAFluxRegister.H:191
iMultiFab m_crse_flag
Definition AMReX_YAFluxRegister.H:176
void setCrseVolume(MF const *cvol)
Definition AMReX_YAFluxRegister.H:167
MF m_crse_data
Definition AMReX_YAFluxRegister.H:175
Geometry m_crse_geom
Definition AMReX_YAFluxRegister.H:185
int m_fine_level
Definition AMReX_YAFluxRegister.H:188
void setDeterministic(bool flag)
Enable deterministic mode for GPU operations via flag (uses deterministic reductions).
Definition AMReX_YAFluxRegister.H:170
typename MF::fab_type FAB
Definition AMReX_YAFluxRegister.H:37
CellType
Definition AMReX_YAFluxRegister.H:159
@ fine_cell
Definition AMReX_YAFluxRegister.H:161
@ crse_cell
Definition AMReX_YAFluxRegister.H:161
@ crse_fine_boundary_cell
Definition AMReX_YAFluxRegister.H:161
bool FineHasWork(const MFIter &mfi) const noexcept
Return true if fine tile mfi has flux registers to update.
Definition AMReX_YAFluxRegister.H:149
void clear()
Deallocate all data and reset to default-constructed state.
Definition AMReX_YAFluxRegister.H:425
MF & getCrseData()
Mutable access to coarse-side accumulation data.
Definition AMReX_YAFluxRegister.H:677
MF m_cfp_mask
Definition AMReX_YAFluxRegister.H:180
Vector< int > m_cfp_localindex
Definition AMReX_YAFluxRegister.H:182
typename MF::value_type T
Definition AMReX_YAFluxRegister.H:36
bool m_deterministic
Definition AMReX_YAFluxRegister.H:192
int m_ncomp
Definition AMReX_YAFluxRegister.H:189
bool getDeterministic() const
Definition AMReX_YAFluxRegister.H:171
void reset()
Reset stored fluxes and flags before a coarse advance.
Definition AMReX_YAFluxRegister.H:417
void CrseAdd(const MFIter &mfi, const std::array< FAB const *, 3 > &flux, const Real *dx, Real dt, RunOn runon) noexcept
Add coarse-level fluxes for the tile indicated by mfi.
Definition AMReX_YAFluxRegister.H:451
A Collection of IArrayBoxes.
Definition AMReX_iMultiFab.H:34
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:79
__host__ __device__ BoxND< dim > adjCellHi(const BoxND< dim > &b, int dir, int len=1) noexcept
Return the BoxND of length len adjacent to b on the high end along coordinate direction dir.
Definition AMReX_Box.H:1848
__host__ __device__ BoxND< dim > adjCellLo(const BoxND< dim > &b, int dir, int len=1) noexcept
Return the BoxND of length len adjacent to b on the low end along coordinate direction dir.
Definition AMReX_Box.H:1817
__host__ __device__ BoxND< dim > surroundingNodes(const BoxND< dim > &b, int dir) noexcept
Return a BoxND with NODE based coordinates in direction dir that encloses BoxND b.
Definition AMReX_Box.H:1582
__host__ __device__ BoxND< dim > coarsen(const BoxND< dim > &b, int ref_ratio) noexcept
Return a copy of b coarsened by the isotropic ratio ref_ratio.
Definition AMReX_Box.H:1469
__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
int MyProc() noexcept
Definition AMReX_ParallelDescriptor.H:128
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:88
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:259
void Add(FabArray< FAB > &dst, FabArray< FAB > const &src, int srccomp, int dstcomp, int numcomp, int nghost)
Definition AMReX_FabArray.H:239
RunOn
Definition AMReX_GpuControl.H:65
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
Definition AMReX_TagParallelFor.H:58
Array4< T > dfab
Definition AMReX_TagParallelFor.H:59
A multidimensional array accessor.
Definition AMReX_Array4.H:288
A simple struct holding 3 int values for a 3D index.
Definition AMReX_Dim3.H:24
parallel copy or add
Definition AMReX_FabArrayBase.H:537
FabArray memory allocation information.
Definition AMReX_FabArray.H:68