Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_YAFluxRegister.H
Go to the documentation of this file.
1#ifndef AMREX_YAFLUXREGISTER_H_
2#define AMREX_YAFLUXREGISTER_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_MultiFab.H>
6#include <AMReX_iMultiFab.H>
7#include <AMReX_Geometry.H>
8#include <AMReX_YAFluxRegister_K.H>
9
15#ifdef AMREX_USE_OMP
16#include <omp.h>
17#endif
18
19namespace amrex {
20
31template <typename MF>
33{
34public:
35
36 using T = typename MF::value_type;
37 using FAB = typename MF::fab_type;
38
40 YAFluxRegisterT () = default;
41
55 YAFluxRegisterT (const BoxArray& fba, const BoxArray& cba,
56 const DistributionMapping& fdm, const DistributionMapping& cdm,
57 const Geometry& fgeom, const Geometry& cgeom,
58 const IntVect& ref_ratio, int fine_lev, int nvar);
59
61 void define (const BoxArray& fba, const BoxArray& cba,
62 const DistributionMapping& fdm, const DistributionMapping& cdm,
63 const Geometry& fgeom, const Geometry& cgeom,
64 const IntVect& ref_ratio, int fine_lev, int nvar);
65
67 void reset ();
68
70 void clear ();
71
81 void CrseAdd (const MFIter& mfi,
82 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
83 const Real* dx, Real dt, RunOn runon) noexcept;
84
97 void CrseAdd (const MFIter& mfi,
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;
101
111 void FineAdd (const MFIter& mfi,
112 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
113 const Real* dx, Real dt, RunOn runon) noexcept;
114
127 void FineAdd (const MFIter& mfi,
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;
131
138 void Reflux (MF& state, int dc = 0);
139
141 void Reflux (MF& state, int srccomp, int destcomp, int numcomp);
142
144 bool CrseHasWork (const MFIter& mfi) const noexcept {
145 return m_crse_fab_flag[mfi.LocalIndex()] != crse_cell;
146 }
147
149 bool FineHasWork (const MFIter& mfi) const noexcept {
150 return !(m_cfp_fab[mfi.LocalIndex()].empty());
151 }
152
154 MF& getFineData ();
155
157 MF& getCrseData ();
158
159 enum CellType : int {
160 // must be same as in AMReX_YAFluxRegiser_K.H
162 };
163
167 void setCrseVolume (MF const* cvol) { m_cvol = cvol; }
168
170 void setDeterministic (bool flag) { m_deterministic = flag; }
171 [[nodiscard]] bool getDeterministic () const { return m_deterministic; }
172
173protected:
174
178
183
186
190
191 MF const* m_cvol = nullptr;
192 bool m_deterministic = false;
193};
194
195template <typename MF>
197 const DistributionMapping& fdm, const DistributionMapping& cdm,
198 const Geometry& fgeom, const Geometry& cgeom,
199 const IntVect& ref_ratio, int fine_lev, int nvar)
200{
201 define(fba, cba, fdm, cdm, fgeom, cgeom, ref_ratio, fine_lev, nvar);
202}
203
204template <typename MF>
205void
207 const DistributionMapping& fdm, const DistributionMapping& cdm,
208 const Geometry& fgeom, const Geometry& cgeom,
209 const IntVect& ref_ratio, int fine_lev, int nvar)
210{
211 clear();
212 m_fine_geom = fgeom;
213 m_crse_geom = cgeom;
214 m_ratio = ref_ratio;
215 m_fine_level = fine_lev;
216 m_ncomp = nvar;
217
218 m_crse_data.define(cba, cdm, nvar, 0);
219
220 m_crse_flag.define(cba, cdm, 1, 1);
221
222 const auto& cperiod = m_crse_geom.periodicity();
223 const std::vector<IntVect>& pshifts = cperiod.shiftIntVect();
224
225 BoxArray cfba = fba;
226 cfba.coarsen(ref_ratio);
227
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);
232 }
233 }
234
235 m_crse_fab_flag.resize(m_crse_flag.local_size(), crse_cell);
236
237 m_crse_flag.setVal(crse_cell);
238 {
239 iMultiFab foo(cfba, fdm, 1, 1, MFInfo().SetAlloc(false));
240 const FabArrayBase::CPC& cpc1 = m_crse_flag.getCPC(IntVect(1), foo, IntVect(1), cperiod);
241 m_crse_flag.setVal(crse_fine_boundary_cell, cpc1, 0, 1);
242 const FabArrayBase::CPC& cpc0 = m_crse_flag.getCPC(IntVect(1), foo, IntVect(0), cperiod);
243 m_crse_flag.setVal(fine_cell, cpc0, 0, 1);
244 auto recv_layout_mask = m_crse_flag.RecvLayoutMask(cpc0);
245#ifdef AMREX_USE_OMP
246#pragma omp parallel if (Gpu::notInLaunchRegion())
247#endif
248 for (MFIter mfi(m_crse_flag); mfi.isValid(); ++mfi) {
249 if (recv_layout_mask[mfi]) {
250 m_crse_fab_flag[mfi.LocalIndex()] = fine_cell;
251 }
252 }
253 }
254
255 BoxList cfp_bl;
256 Vector<int> cfp_procmap;
257 int nlocal = 0;
258 const int myproc = ParallelDescriptor::MyProc();
259 const auto n_cfba = static_cast<int>(cfba.size());
260 cfba.uniqify();
261
262#ifdef AMREX_USE_OMP
263
264 const int nthreads = omp_get_max_threads();
265 Vector<BoxList> bl_priv(nthreads, BoxList());
266 Vector<Vector<int> > procmap_priv(nthreads);
267 Vector<Vector<int> > localindex_priv(nthreads);
268#pragma omp parallel
269 {
270 BoxList bl_tmp;
271 const int tid = omp_get_thread_num();
272 BoxList& bl = bl_priv[tid];
273 Vector<int>& pmp = procmap_priv[tid];
274 Vector<int>& lid = localindex_priv[tid];
275#pragma omp for
276 for (int i = 0; i < n_cfba; ++i)
277 {
278 Box bx = amrex::grow(cfba[i], 1);
279 bx &= cdomain;
280
281 cfba.complementIn(bl_tmp, bx);
282 const auto ntmp = static_cast<int>(bl_tmp.size());
283 bl.join(bl_tmp);
284
285 int proc = fdm[i];
286 for (int j = 0; j < ntmp; ++j) {
287 pmp.push_back(proc);
288 }
289
290 if (proc == myproc) {
291 lid.push_back(ntmp);
292 }
293 }
294 }
295
296 for (auto const& bl : bl_priv) {
297 cfp_bl.join(bl);
298 }
299
300 for (auto const& pmp : procmap_priv) {
301 cfp_procmap.insert(std::end(cfp_procmap), std::begin(pmp), std::end(pmp));
302 }
303
304 for (auto& lid : localindex_priv) {
305 for (int nl : lid) {
306 for (int j = 0; j < nl; ++j) {
307 m_cfp_localindex.push_back(nlocal);
308 }
309 ++nlocal;
310 }
311 }
312
313#else
314
315 BoxList bl_tmp;
316 for (int i = 0; i < n_cfba; ++i)
317 {
318 Box bx = amrex::grow(cfba[i], 1);
319 bx &= cdomain;
320
321 cfba.complementIn(bl_tmp, bx);
322 const auto ntmp = static_cast<int>(bl_tmp.size());
323 cfp_bl.join(bl_tmp);
324
325 int proc = fdm[i];
326 for (int j = 0; j < ntmp; ++j) {
327 cfp_procmap.push_back(proc);
328 }
329
330 if (proc == myproc) {
331 for (int j = 0; j < ntmp; ++j) {
332 m_cfp_localindex.push_back(nlocal); // This Array store local index in fine ba/dm.
333 } // Its size is local size of cfp.
334 ++nlocal;
335 }
336 }
337
338#endif
339
340 // It's safe even if cfp_bl is empty.
341
342 BoxArray cfp_ba(std::move(cfp_bl));
343 DistributionMapping cfp_dm(std::move(cfp_procmap));
344 m_cfpatch.define(cfp_ba, cfp_dm, nvar, 0);
345
346 m_cfp_fab.resize(nlocal);
347 for (MFIter mfi(m_cfpatch); mfi.isValid(); ++mfi)
348 {
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);
353 }
354
355 bool is_periodic = m_fine_geom.isAnyPeriodic();
356 if (is_periodic) {
357 m_cfp_mask.define(cfp_ba, cfp_dm, 1, 0);
358 m_cfp_mask.setVal(T(1.0));
359
361
362 bool run_on_gpu = Gpu::inLaunchRegion();
363 amrex::ignore_unused(run_on_gpu, tags);
364
365 const Box& domainbox = m_crse_geom.Domain();
366
367#ifdef AMREX_USE_OMP
368#pragma omp parallel if (!run_on_gpu)
369#endif
370 {
371 std::vector< std::pair<int,Box> > isects;
372
373 for (MFIter mfi(m_cfp_mask); mfi.isValid(); ++mfi)
374 {
375 const Box& bx = mfi.fabbox();
376 if (!domainbox.contains(bx)) // part of the box is outside periodic boundary
377 {
378 FAB& fab = m_cfp_mask[mfi];
379#ifdef AMREX_USE_GPU
380 auto const& arr = m_cfp_mask.array(mfi);
381#endif
382 for (const auto& iv : pshifts)
383 {
384 if (iv != IntVect::TheZeroVector())
385 {
386 cfba.intersections(bx+iv, isects);
387 for (const auto& is : isects)
388 {
389 const Box& ibx = is.second - iv;
390#ifdef AMREX_USE_GPU
391 if (run_on_gpu) {
392 tags.push_back(Array4BoxTag<T>{.dfab = arr, .dbox = ibx});
393 } else
394#endif
395 {
396 fab.template setVal<RunOn::Host>(T(0.0), ibx);
397 }
398 }
399 }
400 }
401 }
402 }
403 }
404
405#ifdef AMREX_USE_GPU
406 amrex::ParallelFor(tags, 1,
407 [=] AMREX_GPU_DEVICE (int i, int j, int k, int n, Array4BoxTag<T> const& tag) noexcept
408 {
409 tag.dfab(i,j,k,n) = T(0);
410 });
411#endif
412 }
413}
414
415template <typename MF>
416void
418{
419 m_crse_data.setVal(T(0.0));
420 m_cfpatch.setVal(T(0.0));
421}
422
423template <typename MF>
424void
426{
427 // Keep m_deterministic — it is a behavioral preference (how GPU
428 // reductions are done), not tied to the geometry or BoxArrays being
429 // defined. Preserving it avoids surprising the user who set it once.
430 //
431 // m_deterministic is not reset here.
432
433 m_cvol = nullptr;
434 m_ncomp = 0;
435 m_fine_level = 0;
436 m_ratio = IntVect(1);
437 m_crse_geom = Geometry();
438 m_fine_geom = Geometry();
439
440 m_cfp_localindex.clear();
441 m_cfp_fab.clear();
442 m_cfp_mask.clear();
443 m_cfpatch.clear();
444 m_crse_fab_flag.clear();
445 m_crse_flag.clear();
446 m_crse_data.clear();
447}
448
449template <typename MF>
450void
452 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
453 const Real* dx, Real dt, RunOn runon) noexcept
454{
455 BL_ASSERT(m_crse_data.nComp() == flux[0]->nComp());
456 int srccomp = 0;
457 int destcomp = 0;
458 int numcomp = m_crse_data.nComp();
459 CrseAdd(mfi, flux, dx, dt, srccomp, destcomp, numcomp, runon);
460}
461
462template <typename MF>
463void
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
468{
469 BL_ASSERT(m_crse_data.nComp() >= destcomp+numcomp &&
470 flux[0]->nComp() >= srccomp+numcomp);
471
472 //
473 // We assume that the fluxes have been passed in starting at component srccomp
474 // "destcomp" refers to the indexing in the arrays internal to the EBFluxRegister
475 //
476
477 if (m_crse_fab_flag[mfi.LocalIndex()] == crse_cell) {
478 return; // this coarse fab is not close to fine fabs.
479 }
480
481 const Box& bx = mfi.tilebox();
482 AMREX_D_TERM(auto dtdx = static_cast<T>(dt/dx[0]);,
483 auto dtdy = static_cast<T>(dt/dx[1]);,
484 auto dtdz = static_cast<T>(dt/dx[2]););
485 AMREX_D_TERM(FAB const* fx = flux[0];,
486 FAB const* fy = flux[1];,
487 FAB const* fz = flux[2];);
488
489 if (m_cvol) {
490 AMREX_D_TERM(dtdx = T(dt);, dtdy = T(dt);, dtdz = T(dt););
491 }
492
493 auto dest_arr = m_crse_data.array(mfi,destcomp);
494 auto const flag = m_crse_flag.const_array(mfi);
495
496 AMREX_D_TERM(Array4<T const> fxarr = fx->const_array(srccomp);,
497 Array4<T const> fyarr = fy->const_array(srccomp);,
498 Array4<T const> fzarr = fz->const_array(srccomp););
499
501 {
502 yafluxreg_crseadd(tbx, dest_arr, flag, AMREX_D_DECL(fxarr,fyarr,fzarr),
503 AMREX_D_DECL(dtdx,dtdy,dtdz),numcomp);
504 });
505}
506
507template <typename MF>
508void
510 const std::array<FAB const*, AMREX_SPACEDIM>& flux,
511 const Real* dx, Real dt, RunOn runon) noexcept
512{
513 BL_ASSERT(m_crse_data.nComp() == flux[0]->nComp());
514 int srccomp = 0;
515 int destcomp = 0;
516 int numcomp = m_crse_data.nComp();
517 FineAdd(mfi, flux, dx, dt, srccomp, destcomp, numcomp, runon);
518}
519
520template <typename MF>
521void
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
526{
527 BL_ASSERT(m_cfpatch.nComp() >= destcomp+numcomp &&
528 a_flux[0]->nComp() >= srccomp+numcomp);
529
530 //
531 // We assume that the fluxes have been passed in starting at component srccomp
532 // "destcomp" refers to the indexing in the arrays internal to the EBFluxRegister
533 //
534 const int li = mfi.LocalIndex();
535 Vector<FAB*>& cfp_fabs = m_cfp_fab[li];
536 if (cfp_fabs.empty()) { return; }
537
538 const Box& tbx = mfi.tilebox();
539 const Box& bx = amrex::coarsen(tbx, m_ratio);
540 const Box& fbx = amrex::refine(bx, m_ratio);
541
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();
547
548 if (m_cvol) {
549 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
550 dtdx[idim] = T(dt);
551 }
552 }
553
554 int fluxcomp = srccomp;
555 std::array<FAB const*,AMREX_SPACEDIM> flux{{AMREX_D_DECL(a_flux[0],a_flux[1],a_flux[2])}};
556 bool use_gpu = (runon == RunOn::Gpu) && Gpu::inLaunchRegion();
557 amrex::ignore_unused(use_gpu);
558 std::array<FAB,AMREX_SPACEDIM> ftmp;
559 if (fbx != tbx) {
560 AMREX_ASSERT(!use_gpu);
561 for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
562 const Box& b = amrex::surroundingNodes(fbx,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];
567 fluxcomp = 0;
568 }
569 }
570
572
573 for (int idim=0; idim < AMREX_SPACEDIM; ++idim)
574 {
575 const Box& lobx = amrex::adjCellLo(bx, idim);
576 const Box& hibx = amrex::adjCellHi(bx, idim);
577 FAB const* f = flux[idim];
578 for (FAB* cfp : cfp_fabs)
579 {
580 {
581 const Box& lobx_is = lobx & cfp->box();
582 const int side = 0;
583 if (lobx_is.ok())
584 {
585 auto d = cfp->array(destcomp);
586 auto dtdxs = dtdx[idim];
587 int dirside = idim*2+side;
588 Array4<T const> farr = f->const_array(fluxcomp);
589 AMREX_LAUNCH_HOST_DEVICE_LAMBDA_FLAG(runon, lobx_is, tmpbox,
590 {
591 yafluxreg_fineadd(tmpbox, d, farr, dtdxs, numcomp, dirside, rr);
592 });
593 }
594 }
595 {
596 const Box& hibx_is = hibx & cfp->box();
597 const int side = 1;
598 if (hibx_is.ok())
599 {
600 auto d = cfp->array(destcomp);
601 auto dtdxs = dtdx[idim];
602 int dirside = idim*2+side;
603 Array4<T const> farr = f->const_array(fluxcomp);
604 AMREX_LAUNCH_HOST_DEVICE_LAMBDA_FLAG(runon, hibx_is, tmpbox,
605 {
606 yafluxreg_fineadd(tmpbox, d, farr, dtdxs, numcomp, dirside, rr);
607 });
608 }
609 }
610 }
611 }
612}
613
614template <typename MF>
615void
617{
618 int srccomp = 0;
619 int destcomp = dc;
620 int numcomp = m_ncomp;
621 Reflux(state, srccomp, destcomp, numcomp);
622}
623
624template <typename MF>
625void
626YAFluxRegisterT<MF>::Reflux (MF& state, int srccomp, int destcomp, int numcomp)
627{
628 //
629 // Here "srccomp" refers to the indexing in the arrays internal to the EBFluxRegister
630 // "destcomp" refers to the indexing in the external arrays being filled by refluxing
631 //
632 if (!m_cfp_mask.empty())
633 {
634#ifdef AMREX_USE_OMP
635#pragma omp parallel if (Gpu::notInLaunchRegion())
636#endif
637 for (MFIter mfi(m_cfpatch); mfi.isValid(); ++mfi)
638 {
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);
642 AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, numcomp, i, j, k, n,
643 {
644 cfptfab(i,j,k,n) *= maskfab(i,j,k);
645 });
646 }
647 }
648
649 m_crse_data.ParallelCopy(m_cfpatch, srccomp, srccomp, numcomp,
650 IntVect(0), IntVect(0), m_crse_geom.periodicity(),
651 FabArrayBase::ADD, nullptr, m_deterministic);
652
653 BL_ASSERT(state.nComp() >= destcomp + numcomp);
654 if (m_cvol) {
655 auto const& dst = state.arrays();
656 auto const& src = m_crse_data.const_arrays();
657 auto const& vol = m_cvol->const_arrays();
658 amrex::ParallelFor(state, IntVect(0), numcomp,
659 [=] AMREX_GPU_DEVICE (int bno, int i, int j, int k, int n)
660 {
661 dst[bno](i,j,k,destcomp+n) += src[bno](i,j,k,srccomp+n) / vol[bno](i,j,k);
662 });
663 } else {
664 amrex::Add(state, m_crse_data, srccomp, destcomp, numcomp, 0);
665 }
666}
667
668template <typename MF>
669MF&
671{
672 return m_cfpatch;
673}
674
675template <typename MF>
676MF&
678{
679 return m_crse_data;
680}
681
683
684}
685
686#endif
#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