1#ifndef AMREX_ML_CELL_LINOP_H_
2#define AMREX_ML_CELL_LINOP_H_
3#include <AMReX_Config.H>
9#include <AMReX_MLLinOp_K.H>
10#include <AMReX_MLMG_K.H>
49 void setLevelBC (
int amrlev,
const MF* levelbcdata,
50 const MF* robinbc_a =
nullptr,
51 const MF* robinbc_b =
nullptr,
52 const MF* robinbc_f =
nullptr) final;
54 template <typename AMF, std::enable_if_t<!std::is_same_v<MF,AMF> &&
57 const AMF* robinbc_a =
nullptr,
58 const AMF* robinbc_b =
nullptr,
59 const AMF* robinbc_f =
nullptr)
74 void updateSolBC (
int amrlev,
const MF& crse_bcdata)
const;
75 void updateCorBC (
int amrlev,
const MF& crse_bcdata)
const;
78 const MLMGBndryT<MF>* bndry=
nullptr,
bool skip_fillboundary=
false)
const;
89 IntVect const& nghost)
const override;
92 const MF& fine_sol,
const MF& fine_rhs)
override;
94 void apply (
int amrlev,
int mglev, MF& out, MF& in,
BCMode bc_mode,
96 void smooth (
int amrlev,
int mglev, MF& sol,
const MF& rhs,
97 bool skip_fillboundary,
int niter)
const final;
100 const MF* crse_bcdata=
nullptr)
override;
102 void prepareForFluxes (
int amrlev,
const MF* crse_bcdata =
nullptr)
override;
105 BCMode bc_mode,
const MF* crse_bcdata=
nullptr) final;
108 void reflux (
int crse_amrlev,
109 MF& res, const MF& crse_sol, const MF&,
110 MF&, MF& fine_sol, const MF&) const final;
111 void compFlux (
int amrlev, const
Array<MF*,AMREX_SPACEDIM>& fluxes,
112 MF& sol,
Location loc) const override;
113 void compGrad (
int amrlev, const
Array<MF*,AMREX_SPACEDIM>& grad,
114 MF& sol,
Location loc) const override;
119 MF const& rhs) const override;
125 RT xdoty (
int amrlev,
int mglev, const MF&
x, const MF&
y,
bool local) const final;
131 virtual
void Fapply (
int amrlev,
int mglev, MF& out, const MF& in) const = 0;
132 virtual
void Fsmooth (
int amrlev,
int mglev, MF& sol, const MF& rhs,
int redblack) const = 0;
134 const
Array<
FAB*,AMREX_SPACEDIM>& flux,
135 const
FAB& sol,
Location loc,
int face_only=0) const = 0;
138 const
Array<MF*,AMREX_SPACEDIM>& ,
142 RT normInf (
int amrlev, MF
const& mf,
bool local)
const override;
146 void avgDownResAmr (
int clev, MF& cres, MF
const& fres)
const override;
185 void setLOBndryConds (
const Geometry& geom,
const Real* dx,
199 const BCTuple& bndryConds (
const MFIter& mfi,
int icomp)
const noexcept {
200 return bcond[mfi][icomp];
202 const RealTuple& bndryLocs (
const MFIter& mfi,
int icomp)
const noexcept {
203 return bcloc[mfi][icomp];
232 void defineAuxData ();
235 void computeVolInv ()
const;
238 int m_interpbndry_halfwidth = 2;
257 Box const& box() const noexcept {
return bx; }
264 Array4<int const> mlo;
265 Array4<int const> mhi;
276 Box const& box() const noexcept {
return bx; }
285 Array4<int const> mlo;
286 Array4<int const> mhi;
297 Box const& box() const noexcept {
return bx; }
301template <
typename MF>
302MLCellLinOpT<MF>::BndryCondLoc::BndryCondLoc (
const BoxArray& ba,
303 const DistributionMapping& dm,
308 bctl_dv(bctl.local_size()*ncomp),
311 auto* dp = bctl_dv.data();
312 for (MFIter mfi(bcloc); mfi.isValid(); ++mfi) {
313 bcond[mfi].resize(ncomp);
314 bcloc[mfi].resize(ncomp);
320template <
typename MF>
322MLCellLinOpT<MF>::BndryCondLoc::
323setLOBndryConds (
const Geometry& geom,
const Real* dx,
324 const Vector<Array<BCType,AMREX_SPACEDIM> >& lobc,
325 const Vector<Array<BCType,AMREX_SPACEDIM> >& hibc,
327 const Array<Real,AMREX_SPACEDIM>& domain_bloc_lo,
328 const Array<Real,AMREX_SPACEDIM>& domain_bloc_hi,
331 const Box& domain = geom.Domain();
336 for (MFIter mfi(bcloc); mfi.isValid(); ++mfi)
338 const Box& bx = mfi.validbox();
339 for (
int icomp = 0; icomp < m_ncomp; ++icomp) {
340 RealTuple & bloc = bcloc[mfi][icomp];
341 BCTuple & bctag = bcond[mfi][icomp];
343 lobc[icomp], hibc[icomp],
344 dx, ratio, interior_bloc,
345 domain_bloc_lo, domain_bloc_hi,
346 geom.isPeriodicArray(),
351 Gpu::PinnedVector<GpuArray<BCTL,2*AMREX_SPACEDIM> > hv;
352 hv.reserve(bctl_dv.size());
353 for (MFIter mfi(bctl); mfi.isValid(); ++mfi)
355 for (
int icomp = 0; icomp < m_ncomp; ++icomp) {
356 GpuArray<BCTL,2*AMREX_SPACEDIM> tmp;
357 for (
int m = 0; m < 2*AMREX_SPACEDIM; ++m) {
358 tmp[m].type = bcond[mfi][icomp][m];
359 tmp[m].location = bcloc[mfi][icomp][m];
361 hv.push_back(std::move(tmp));
370template <
typename MF>
376template <
typename MF>
389template <
typename MF>
395 m_undrrelxr.resize(this->m_num_amr_levels);
396 m_maskvals.resize(this->m_num_amr_levels);
397 m_fluxreg.resize(this->m_num_amr_levels-1);
398 m_norm_fine_mask.resize(this->m_num_amr_levels-1);
399 m_bc_tags.resize(this->m_num_amr_levels);
401 const int ncomp = this->getNComp();
403 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
405 m_undrrelxr[amrlev].resize(this->m_num_mg_levels[amrlev]);
406 m_bc_tags[amrlev].resize(this->m_num_mg_levels[amrlev]);
407 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
409 m_undrrelxr[amrlev][mglev].define(this->m_grids[amrlev][mglev],
410 this->m_dmap[amrlev][mglev],
415 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
417 m_maskvals[amrlev].resize(this->m_num_mg_levels[amrlev]);
418 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
420 for (OrientationIter oitr; oitr; ++oitr)
422 const Orientation face = oitr();
424 const int extent = this->isCrossStencil() ? 0 : 1;
425 m_maskvals[amrlev][mglev][face].define(this->m_grids[amrlev][mglev],
426 this->m_dmap[amrlev][mglev],
427 this->m_geom[amrlev][mglev],
428 face, 0, ngrow, extent, 1,
true);
433 for (
int amrlev = 0; amrlev < this->m_num_amr_levels-1; ++amrlev)
435 const IntVect ratio{this->m_amr_ref_ratio[amrlev]};
436 m_fluxreg[amrlev].define(this->m_grids[amrlev+1][0],
437 this->m_grids[amrlev][0],
438 this->m_dmap[amrlev+1][0],
439 this->m_dmap[amrlev][0],
440 this->m_geom[amrlev+1][0],
441 this->m_geom[amrlev][0],
442 ratio, amrlev+1, ncomp);
443 m_fluxreg[amrlev].setDeterministic(this->info.deterministic);
444 m_norm_fine_mask[amrlev] = std::make_unique<iMultiFab>
445 (
makeFineMask(this->m_grids[amrlev][0], this->m_dmap[amrlev][0],
446 this->m_grids[amrlev+1][0],
450#if (AMREX_SPACEDIM != 3)
451 m_has_metric_term = !this->m_geom[0][0].IsCartesian() && this->info.has_metric_term;
455template <
typename MF>
457MLCellLinOpT<MF>::defineBC ()
461 const int ncomp = this->getNComp();
463 m_bndry_sol.resize(this->m_num_amr_levels);
464 m_crse_sol_br.resize(this->m_num_amr_levels);
466 m_bndry_cor.resize(this->m_num_amr_levels);
467 m_crse_cor_br.resize(this->m_num_amr_levels);
469 m_robin_bcval.resize(this->m_num_amr_levels);
471 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
473 m_bndry_sol[amrlev] = std::make_unique<MLMGBndryT<MF>>(this->m_grids[amrlev][0],
474 this->m_dmap[amrlev][0],
476 this->m_geom[amrlev][0]);
479 for (
int amrlev = 1; amrlev < this->m_num_amr_levels; ++amrlev)
481 const int in_rad = 0;
482 const int out_rad = 1;
483 const int extent_rad = 2;
484 const int crse_ratio = this->m_amr_ref_ratio[amrlev-1];
485 BoxArray cba = this->m_grids[amrlev][0];
486 cba.coarsen(crse_ratio);
487 m_crse_sol_br[amrlev] = std::make_unique<BndryRegisterT<MF>>
488 (cba, this->m_dmap[amrlev][0], in_rad, out_rad, extent_rad, ncomp);
491 for (
int amrlev = 1; amrlev < this->m_num_amr_levels; ++amrlev)
493 const int in_rad = 0;
494 const int out_rad = 1;
495 const int extent_rad = 2;
496 const int crse_ratio = this->m_amr_ref_ratio[amrlev-1];
497 BoxArray cba = this->m_grids[amrlev][0];
498 cba.coarsen(crse_ratio);
499 m_crse_cor_br[amrlev] = std::make_unique<BndryRegisterT<MF>>
500 (cba, this->m_dmap[amrlev][0], in_rad, out_rad, extent_rad, ncomp);
501 m_crse_cor_br[amrlev]->setVal(RT(0.0));
505 for (
int amrlev = 1; amrlev < this->m_num_amr_levels; ++amrlev)
507 m_bndry_cor[amrlev] = std::make_unique<MLMGBndryT<MF>>
508 (this->m_grids[amrlev][0], this->m_dmap[amrlev][0], ncomp, this->m_geom[amrlev][0]);
509 MF bc_data(this->m_grids[amrlev][0], this->m_dmap[amrlev][0], ncomp, 1);
512 m_bndry_cor[amrlev]->setBndryValues(*m_crse_cor_br[amrlev], 0, bc_data, 0, 0, ncomp,
513 IntVect(this->m_amr_ref_ratio[amrlev-1]),
515 m_interpbndry_halfwidth);
517 Vector<Array<LinOpBCType,AMREX_SPACEDIM> > bclohi
518 (ncomp,Array<LinOpBCType,AMREX_SPACEDIM>{{
AMREX_D_DECL(BCType::Dirichlet,
520 BCType::Dirichlet)}});
521 m_bndry_cor[amrlev]->setLOBndryConds(bclohi, bclohi, this->m_amr_ref_ratio[amrlev-1],
RealVect{});
524 m_bcondloc.resize(this->m_num_amr_levels);
525 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
527 m_bcondloc[amrlev].resize(this->m_num_mg_levels[amrlev]);
528 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
530 m_bcondloc[amrlev][mglev] = std::make_unique<BndryCondLoc>(this->m_grids[amrlev][mglev],
531 this->m_dmap[amrlev][mglev],
537template <
typename MF>
540 const MF* robinbc_b,
const MF* robinbc_f)
546 const int ncomp = this->getNComp();
550 if (this->hasHiddenDimension()) { ng[this->hiddenDirection()] = 0; }
551 if (a_levelbcdata ==
nullptr) {
552 zero.define(this->m_grids[amrlev][0], this->m_dmap[amrlev][0], ncomp, ng);
557 const MF& bcdata = (a_levelbcdata ==
nullptr) ?
zero : *a_levelbcdata;
563 if (this->needsCoarseDataForBC())
566 if (this->hasHiddenDimension()) {
567 int hidden_dir = this->hiddenDirection();
570 br_ref_ratio = this->m_coarse_data_crse_ratio.
allGT(0) ? this->m_coarse_data_crse_ratio :
IntVect(2);
571 if (this->m_crse_sol_br[amrlev] ==
nullptr && br_ref_ratio.
allGT(0))
573 const int in_rad = 0;
574 const int out_rad = 1;
575 const int extent_rad = 2;
576 const IntVect crse_ratio = br_ref_ratio;
577 BoxArray cba = this->m_grids[amrlev][0];
579 this->m_crse_sol_br[amrlev] = std::make_unique<BndryRegisterT<MF>>
580 (cba, this->m_dmap[amrlev][0], in_rad, out_rad, extent_rad, ncomp);
582 if (this->m_coarse_data_for_bc !=
nullptr) {
585 this->m_crse_sol_br[amrlev]->copyFrom(*(this->m_coarse_data_for_bc), 0, 0, 0, ncomp,
586 this->m_geom[0][0].periodicity(
cbx));
588 this->m_crse_sol_br[amrlev]->setVal(
RT(0.0));
590 this->m_bndry_sol[amrlev]->setBndryValues(*(this->m_crse_sol_br[amrlev]), 0,
591 bcdata, 0, 0, ncomp, br_ref_ratio,
593 this->m_interpbndry_halfwidth);
594 br_ref_ratio = this->m_coarse_data_crse_ratio;
598 this->m_bndry_sol[amrlev]->setPhysBndryValues(bcdata,0,0,ncomp);
604 this->m_bndry_sol[amrlev]->setPhysBndryValues(bcdata,0,0,ncomp);
605 br_ref_ratio =
IntVect(this->m_amr_ref_ratio[amrlev-1]);
609 this->m_bndry_sol[amrlev]->setLOBndryConds(this->m_lobc, this->m_hibc, br_ref_ratio,
610 this->m_coarse_bc_loc, crse_fine_bc_type);
612 const Real* dx = this->m_geom[amrlev][0].CellSize();
613 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
615 this->m_bcondloc[amrlev][mglev]->setLOBndryConds(this->m_geom[amrlev][mglev], dx,
616 this->m_lobc, this->m_hibc,
617 br_ref_ratio, this->m_coarse_bc_loc,
618 this->m_domain_bloc_lo, this->m_domain_bloc_hi,
622 if (this->hasRobinBC()) {
623 AMREX_ASSERT(robinbc_a !=
nullptr && robinbc_b !=
nullptr && robinbc_f !=
nullptr);
624 this->m_robin_bcval[amrlev] = std::make_unique<MF>(this->m_grids[amrlev][0],
625 this->m_dmap[amrlev][0],
627 const Box& domain = this->m_geom[amrlev][0].Domain();
631#pragma omp parallel if (Gpu::notInLaunchRegion())
633 for (
MFIter mfi(*(this->m_robin_bcval[amrlev]), mfi_info); mfi.
isValid(); ++mfi) {
634 Box const& vbx = mfi.validbox();
638 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
641 bool outside_domain_lo = !(domain.
contains(blo));
642 bool outside_domain_hi = !(domain.
contains(bhi));
643 if ((!outside_domain_lo) && (!outside_domain_hi)) {
continue; }
644 for (
int icomp = 0; icomp < ncomp; ++icomp) {
645 Array4<RT> const& rbc = (*(this->m_robin_bcval[amrlev]))[mfi].array(icomp*3);
650 rbc(i,j,k,0) = ra(i,j,k,icomp);
651 rbc(i,j,k,1) = rb(i,j,k,icomp);
652 rbc(i,j,k,2) = rf(i,j,k,icomp);
659 rbc(i,j,k,0) = ra(i,j,k,icomp);
660 rbc(i,j,k,1) = rb(i,j,k,icomp);
661 rbc(i,j,k,2) = rf(i,j,k,icomp);
670template <
typename MF>
677template <
typename MF>
684 const int ncomp = this->getNComp();
685 m_crse_sol_br[amrlev]->copyFrom(crse_bcdata, 0, 0, 0, ncomp,
686 this->m_geom[amrlev-1][0].periodicity());
687 m_bndry_sol[amrlev]->updateBndryValues(*m_crse_sol_br[amrlev], 0, 0, ncomp,
688 IntVect(this->m_amr_ref_ratio[amrlev-1]),
690 m_interpbndry_halfwidth);
693template <
typename MF>
699 const int ncomp = this->getNComp();
700 m_crse_cor_br[amrlev]->copyFrom(crse_bcdata, 0, 0, 0, ncomp,
701 this->m_geom[amrlev-1][0].periodicity());
702 m_bndry_cor[amrlev]->updateBndryValues(*m_crse_cor_br[amrlev], 0, 0, ncomp,
703 IntVect(this->m_amr_ref_ratio[amrlev-1]),
705 m_interpbndry_halfwidth);
708template <
typename MF>
715 BL_ASSERT(mglev == 0 || bc_mode == BCMode::Homogeneous);
716 BL_ASSERT(bndry !=
nullptr || bc_mode == BCMode::Homogeneous);
718 const int ncomp = this->getNComp();
719 const int cross = isCrossStencil();
720 const int tensorop = isTensorOp();
721 if (!skip_fillboundary) {
722 in.FillBoundary(0, ncomp, this->m_geom[amrlev][mglev].periodicity(), cross);
725 int flagbc = bc_mode == BCMode::Inhomogeneous;
726 const int imaxorder = this->maxorder;
728 const Real* dxinv = this->m_geom[amrlev][mglev].InvCellSize();
729 const RT dxi =
static_cast<RT>(dxinv[0]);
730 const RT dyi = (AMREX_SPACEDIM >= 2) ?
static_cast<RT>(dxinv[1]) :
RT(1.0);
731 const RT dzi = (AMREX_SPACEDIM == 3) ?
static_cast<RT>(dxinv[2]) :
RT(1.0);
733 const auto& maskvals = m_maskvals[amrlev][mglev];
734 const auto& bcondloc = *m_bcondloc[amrlev][mglev];
737 const auto& foo = foofab.const_array();
743 "non-cross stencil not support for gpu");
745 const int hidden_direction = this->hiddenDirection();
750 if (! m_bc_tags[amrlev][mglev].is_defined()) {
752 tags.reserve(in.local_size()*2*AMREX_SPACEDIM*ncomp);
754 const Box& vbx = mfi.validbox();
755 const auto & bdlv = bcondloc.bndryLocs(mfi);
756 const auto & bdcv = bcondloc.bndryConds(mfi);
758 const int local_index = mfi.LocalIndex();
760 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
761 if (idim != hidden_direction) {
764 for (
int icomp = 0; icomp < ncomp; ++icomp) {
766 maskvals[olo].const_array(mfi),
769 bdcv[icomp][olo], vbx.
length(idim),
770 icomp, olo, local_index
773 maskvals[ohi].const_array(mfi),
776 bdcv[icomp][ohi], vbx.
length(idim),
777 icomp, ohi, local_index
783 m_bc_tags[amrlev][mglev].define(tags);
790 bndry_arrays[ori] = (bndry !=
nullptr) ?
794 auto inma = in.arrays();
798 const auto& bcval = bndry_arrays[tag.face][tag.local_index];
799 const int side = tag.face.faceDir();
800 if (tag.face.coordDir() == 0) {
801 mllinop_apply_bc_x(side, i, j, k, tag.blen, inma[tag.local_index],
802 tag.mask, tag.bctype, tag.bcloc, bcval,
803 imaxorder, dxi, flagbc, tag.comp);
805#if (AMREX_SPACEDIM > 1)
807#
if (AMREX_SPACEDIM > 2)
808 if (tag.face.coordDir() == 1)
811 mllinop_apply_bc_y(side, i, j, k, tag.blen, inma[tag.local_index],
812 tag.mask, tag.bctype, tag.bcloc, bcval,
813 imaxorder, dyi, flagbc, tag.comp);
815#if (AMREX_SPACEDIM > 2)
817 mllinop_apply_bc_z(side, i, j, k, tag.blen, inma[tag.local_index],
818 tag.mask, tag.bctype, tag.bcloc, bcval,
819 imaxorder, dzi, flagbc, tag.comp);
826 if (cross || tensorop)
829#pragma omp parallel if (Gpu::notInLaunchRegion())
833 const Box& vbx = mfi.validbox();
834 const auto& iofab = in.array(mfi);
836 const auto & bdlv = bcondloc.bndryLocs(mfi);
837 const auto & bdcv = bcondloc.bndryConds(mfi);
839 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
841 if (hidden_direction == idim) {
continue; }
846 const int blen = vbx.
length(idim);
847 const auto& mlo = maskvals[olo].array(mfi);
848 const auto& mhi = maskvals[ohi].array(mfi);
849 const auto& bvlo = (bndry !=
nullptr) ? bndry->
bndryValues(olo).const_array(mfi) : foo;
850 const auto& bvhi = (bndry !=
nullptr) ? bndry->
bndryValues(ohi).const_array(mfi) : foo;
851 for (
int icomp = 0; icomp < ncomp; ++icomp) {
852 const BoundCond bctlo = bdcv[icomp][olo];
853 const BoundCond bcthi = bdcv[icomp][ohi];
854 const RT bcllo = bdlv[icomp][olo];
855 const RT bclhi = bdlv[icomp][ohi];
857 mllinop_apply_bc_x(0, blo, blen, iofab, mlo,
859 imaxorder, dxi, flagbc, icomp);
860 mllinop_apply_bc_x(1, bhi, blen, iofab, mhi,
862 imaxorder, dxi, flagbc, icomp);
863 }
else if (idim == 1) {
864 mllinop_apply_bc_y(0, blo, blen, iofab, mlo,
866 imaxorder, dyi, flagbc, icomp);
867 mllinop_apply_bc_y(1, bhi, blen, iofab, mhi,
869 imaxorder, dyi, flagbc, icomp);
871 mllinop_apply_bc_z(0, blo, blen, iofab, mlo,
873 imaxorder, dzi, flagbc, icomp);
874 mllinop_apply_bc_z(1, bhi, blen, iofab, mhi,
876 imaxorder, dzi, flagbc, icomp);
885 amrex::Abort(
"amrex_mllinop_apply_bc not available when BL_NO_FORT=TRUE");
887 if constexpr (std::is_same_v<Real,RT>) {
893 const Box& vbx = mfi.validbox();
895 const auto & bdlv = bcondloc.bndryLocs(mfi);
896 const auto & bdcv = bcondloc.bndryConds(mfi);
909 const auto& fsfab = (bndry !=
nullptr) ? bndry->
bndryValues(ori)[mfi] : foofab;
911 const Mask& m = maskvals[ori][mfi];
918 imaxorder, dxinv, flagbc, ncomp, cross);
928template <
typename MF>
932 const Box& dombx = this->m_geom[0].back().Domain();
934 const BoxArray& old_ba = this->m_grids[0].back();
935 const int N = old_ba.
size();
938 for (
int i = 0; i < N; ++i)
949#if (AMREX_SPACEDIM == 3)
950 for (
int kk = 0; kk < nblks[2]; ++kk) {
952#if (AMREX_SPACEDIM >= 2)
953 for (
int jj = 0; jj < nblks[1]; ++jj) {
955 for (
int ii = 0; ii < nblks[0]; ++ii)
962#if (AMREX_SPACEDIM >= 2)
965#if (AMREX_SPACEDIM == 3)
970 std::sort(bv.begin(), bv.end());
971 bv.erase(std::unique(bv.begin(), bv.end()), bv.end());
978template <
typename MF>
982 const int ncomp = this->getNComp();
983 IntVect ratio = (amrlev > 0) ?
IntVect(2) : this->mg_coarsen_ratio_vec[cmglev-1];
987template <
typename MF>
991 const int ncomp = this->getNComp();
993 Dim3 ratio3 = {2,2,2};
994 IntVect ratio = (amrlev > 0) ?
IntVect(2) : this->mg_coarsen_ratio_vec[fmglev];
996 ratio3.
y = ratio[1];,
997 ratio3.
z = ratio[2];);
1001 auto const& finema =
fine.arrays();
1002 auto const& crsema =
crse.const_arrays();
1009 finema[box_no](i,j,k,n) += crsema[box_no](ic,jc,kc,n);
1016#pragma omp parallel if (Gpu::notInLaunchRegion())
1020 const Box& bx = mfi.tilebox();
1028 ffab(i,j,k,n) += cfab(ic,jc,kc,n);
1034template <
typename MF>
1038 const int ncomp = this->getNComp();
1040 const Geometry& crse_geom = this->Geom(amrlev,fmglev+1);
1041 const IntVect refratio = (amrlev > 0) ?
IntVect(2) : this->mg_coarsen_ratio_vec[fmglev];
1056 cfine.
define(cba,
fine.DistributionMap(), ncomp, ng);
1057 cfine.setVal(
RT(0.0));
1062 bool isEB =
fine.hasEBFabFactory();
1073#pragma omp parallel if (Gpu::notInLaunchRegion())
1077 const Box& bx = mfi.tilebox();
1078 const auto& ff =
fine.array(mfi);
1079 const auto& cc = cmf->array(mfi);
1084 const auto& flag = (*flags)[mfi];
1091 mlmg_eb_cc_interp_r<2>(tbx, ff, cc, flg, ncomp);
1102 const bool call_lincc =
true;
1106#if (AMREX_SPACEDIM == 3)
1107 if (this->hasHiddenDimension()) {
1108 Box const& bx_2d = this->compactify(bx);
1109 auto const& ff_2d = this->compactify(ff);
1110 auto const& cc_2d = this->compactify(cc);
1113 TwoD::mlmg_lin_cc_interp_r2(tbx, ff_2d, cc_2d, ncomp);
1120 mlmg_lin_cc_interp_r2(tbx, ff, cc, ncomp);
1127template <
typename MF>
1132 const int ncomp = this->getNComp();
1133 const int refratio = this->AMRRefRatio(famrlev-1);
1136 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(famrlev));
1143#pragma omp parallel if (Gpu::notInLaunchRegion())
1147 const Box& bx = mfi.tilebox();
1148 auto const& ff =
fine.array(mfi);
1149 auto const& cc =
crse.const_array(mfi);
1154 const auto& flag = (*flags)[mfi];
1164 mlmg_eb_cc_interp_r<2>(tbx, ff, cc, flg, ncomp);
1172 mlmg_eb_cc_interp_r<4>(tbx, ff, cc, flg, ncomp);
1177 amrex::Abort(
"mlmg_eb_cc_interp: only refratio 2 and 4 are supported");
1188 const bool call_lincc =
true;
1197 mlmg_lin_cc_interp_r2(tbx, ff, cc, ncomp);
1205 mlmg_lin_cc_interp_r4(tbx, ff, cc, ncomp);
1210 amrex::Abort(
"mlmg_lin_cc_interp: only refratio 2 and 4 are supported");
1216template <
typename MF>
1219 const MF& fine_sol,
const MF& fine_rhs)
1221 const auto amrrr = this->AMRRefRatio(camrlev);
1222 const int ncomp = this->getNComp();
1227template <
typename MF>
1233 applyBC(amrlev, mglev, in, bc_mode, s_mode, bndry);
1234 Fapply(amrlev, mglev, out, in);
1237template <
typename MF>
1240 bool skip_fillboundary,
int niter)
const
1243 for (
int i = 0; i < niter; ++i) {
1244 for (
int redblack = 0; redblack < 2; ++redblack)
1246 applyBC(amrlev, mglev, sol, BCMode::Homogeneous, StateMode::Solution,
1247 nullptr, skip_fillboundary);
1248 Fsmooth(amrlev, mglev, sol, rhs, redblack);
1249 skip_fillboundary =
false;
1254template <
typename MF>
1257 const MF* crse_bcdata)
1259 BL_PROFILE(
"MLCellLinOp::solutionResidual()");
1260 const int ncomp = this->getNComp();
1261 if (crse_bcdata !=
nullptr) {
1262 updateSolBC(amrlev, *crse_bcdata);
1264 const int mglev = 0;
1265 apply(amrlev, mglev, resid,
x, BCMode::Inhomogeneous, StateMode::Solution,
1266 m_bndry_sol[amrlev].
get());
1269 MF::Xpay(resid,
RT(-1.0), b, 0, 0, ncomp,
IntVect(0));
1272template <
typename MF>
1276 if (crse_bcdata !=
nullptr) {
1277 updateSolBC(amrlev, *crse_bcdata);
1281template <
typename MF>
1284 BCMode bc_mode,
const MF* crse_bcdata)
1286 BL_PROFILE(
"MLCellLinOp::correctionResidual()");
1287 const int ncomp = this->getNComp();
1288 if (bc_mode == BCMode::Inhomogeneous)
1293 updateCorBC(amrlev, *crse_bcdata);
1295 apply(amrlev, mglev, resid,
x, BCMode::Inhomogeneous, StateMode::Correction,
1296 m_bndry_cor[amrlev].
get());
1301 apply(amrlev, mglev, resid,
x, BCMode::Homogeneous, StateMode::Correction,
nullptr);
1304 MF::Xpay(resid,
Real(-1.0), b, 0, 0, ncomp,
IntVect(0));
1307template <
typename MF>
1310 MF&, MF& fine_sol,
const MF&)
const
1314 auto& fluxreg = m_fluxreg[crse_amrlev];
1317 const int ncomp = this->getNComp();
1319 const int fine_amrlev = crse_amrlev+1;
1322 const Real* crse_dx = this->m_geom[crse_amrlev][0].CellSize();
1323 const Real* fine_dx = this->m_geom[fine_amrlev][0].CellSize();
1325 const int mglev = 0;
1326 applyBC(fine_amrlev, mglev, fine_sol, BCMode::Inhomogeneous, StateMode::Solution,
1327 m_bndry_sol[fine_amrlev].
get());
1333#pragma omp parallel if (Gpu::notInLaunchRegion())
1342 if (fluxreg.CrseHasWork(mfi))
1344 const Box& tbx = mfi.tilebox();
1348 FFlux(crse_amrlev, mfi, pflux, crse_sol[mfi], Location::FaceCentroid);
1349 fluxreg.CrseAdd(mfi, cpflux, crse_dx, dt,
RunOn::Gpu);
1359 if (fluxreg.FineHasWork(mfi))
1361 const Box& tbx = mfi.tilebox();
1362 const int face_only =
true;
1366 FFlux(fine_amrlev, mfi, pflux, fine_sol[mfi], Location::FaceCentroid, face_only);
1367 fluxreg.FineAdd(mfi, cpflux, fine_dx, dt,
RunOn::Gpu);
1372 fluxreg.Reflux(res);
1375template <
typename MF>
1382 const int mglev = 0;
1383 const int ncomp = this->getNComp();
1384 applyBC(amrlev, mglev, sol, BCMode::Inhomogeneous, StateMode::Solution,
1385 m_bndry_sol[amrlev].
get());
1391#pragma omp parallel if (Gpu::notInLaunchRegion())
1398 const Box& tbx = mfi.tilebox();
1402 FFlux(amrlev, mfi, pflux, sol[mfi], loc);
1403 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
1404 const Box& nbx = mfi.nodaltilebox(idim);
1405 auto const& dst = fluxes[idim]->array(mfi);
1406 auto const& src = pflux[idim]->const_array();
1409 dst(i,j,k,n) = src(i,j,k,n);
1416template <
typename MF>
1423 if (sol.nComp() > 1) {
1424 amrex::Abort(
"MLCellLinOp::compGrad called, but only works for single-component solves");
1427 const int mglev = 0;
1428 applyBC(amrlev, mglev, sol, BCMode::Inhomogeneous, StateMode::Solution,
1429 m_bndry_sol[amrlev].
get());
1431 const int ncomp = this->getNComp();
1433 AMREX_D_TERM(
const RT dxi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0));,
1434 const RT dyi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(1));,
1435 const RT dzi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(2)););
1437#pragma omp parallel if (Gpu::notInLaunchRegion())
1442 const Box& ybx = mfi.nodaltilebox(1);,
1443 const Box& zbx = mfi.nodaltilebox(2););
1444 const auto& s = sol.array(mfi);
1446 const auto& gy = grad[1]->array(mfi);,
1447 const auto& gz = grad[2]->array(mfi););
1451 gx(i,j,k,n) = dxi*(s(i,j,k,n) - s(i-1,j,k,n));
1453#if (AMREX_SPACEDIM >= 2)
1456 gy(i,j,k,n) = dyi*(s(i,j,k,n) - s(i,j-1,k,n));
1459#if (AMREX_SPACEDIM == 3)
1462 gz(i,j,k,n) = dzi*(s(i,j,k,n) - s(i,j,k-1,n));
1467 addInhomogNeumannFlux(amrlev, grad, sol,
false);
1470template <
typename MF>
1475#if (AMREX_SPACEDIM != 3)
1476 if (!m_has_metric_term) {
return; }
1478 const int ncomp = rhs.nComp();
1480 bool cc = rhs.ixType().cellCentered(0);
1482 const Geometry& geom = this->m_geom[amrlev][mglev];
1484 const RT probxlo =
static_cast<RT>(geom.
ProbLo(0));
1487#pragma omp parallel if (Gpu::notInLaunchRegion())
1491 const Box& tbx = mfi.tilebox();
1492 auto const& rhsarr = rhs.array(mfi);
1493#if (AMREX_SPACEDIM == 1)
1497 RT rc = probxlo + (i+
RT(0.5))*dx;
1498 rhsarr(i,j,k,n) *= rc*rc;
1503 RT re = probxlo + i*dx;
1504 rhsarr(i,j,k,n) *= re*re;
1507#elif (AMREX_SPACEDIM == 2)
1511 RT rc = probxlo + (i+
RT(0.5))*dx;
1512 rhsarr(i,j,k,n) *= rc;
1517 RT re = probxlo + i*dx;
1518 rhsarr(i,j,k,n) *= re;
1526template <
typename MF>
1531#if (AMREX_SPACEDIM != 3)
1532 if (!m_has_metric_term) {
return; }
1534 const int ncomp = rhs.nComp();
1536 bool cc = rhs.ixType().cellCentered(0);
1538 const Geometry& geom = this->m_geom[amrlev][mglev];
1540 const RT probxlo =
static_cast<RT>(geom.
ProbLo(0));
1543#pragma omp parallel if (Gpu::notInLaunchRegion())
1547 const Box& tbx = mfi.tilebox();
1548 auto const& rhsarr = rhs.array(mfi);
1549#if (AMREX_SPACEDIM == 1)
1553 RT rcinv =
RT(1.0)/(probxlo + (i+
RT(0.5))*dx);
1554 rhsarr(i,j,k,n) *= rcinv*rcinv;
1559 RT re = probxlo + i*dx;
1560 RT reinv = (re==
RT(0.0)) ?
RT(0.0) :
RT(1.)/re;
1561 rhsarr(i,j,k,n) *= reinv*reinv;
1564#elif (AMREX_SPACEDIM == 2)
1568 RT rcinv =
RT(1.0)/(probxlo + (i+
RT(0.5))*dx);
1569 rhsarr(i,j,k,n) *= rcinv;
1574 RT re = probxlo + i*dx;
1575 RT reinv = (re==
RT(0.0)) ?
RT(0.0) :
RT(1.)/re;
1576 rhsarr(i,j,k,n) *= reinv;
1584template <
typename MF>
1591 const int ncomp = this->getNComp();
1595 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(amrlev,mglev));
1596 if (factory && !factory->isAllRegular())
1598 if constexpr (std::is_same<MF,MultiFab>()) {
1599 const MultiFab& vfrac = factory->getVolFrac();
1600 for (
int c = 0; c < ncomp; ++c) {
1602 * m_volinv[amrlev][mglev];
1605 amrex::Abort(
"TODO: MLMG with EB only works with MultiFab");
1611 for (
int c = 0; c < ncomp; ++c) {
1612 offset[c] = rhs.sum(c,
IntVect(0),
true) * m_volinv[amrlev][mglev];
1621template <
typename MF>
1626 const int ncomp = this->getNComp();
1627 for (
int c = 0; c < ncomp; ++c) {
1628 rhs.plus(-
offset[c], c, 1);
1631 if (!rhs.isAllRegular()) {
1632 if constexpr (std::is_same<MF,MultiFab>()) {
1635 amrex::Abort(
"amrex::EB_set_covered only works with MultiFab");
1641template <
typename MF>
1645 BL_PROFILE(
"MLCellLinOp::prepareForSolve()");
1647 const int imaxorder = this->maxorder;
1648 const int ncomp = this->getNComp();
1649 const int hidden_direction = this->hiddenDirection();
1650 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
1652 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
1654 const auto& bcondloc = *m_bcondloc[amrlev][mglev];
1655 const auto& maskvals = m_maskvals[amrlev][mglev];
1657 const RT dxi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0));
1658 const RT dyi =
static_cast<RT>((AMREX_SPACEDIM >= 2) ? this->m_geom[amrlev][mglev].InvCellSize(1) :
Real(1.0));
1659 const RT dzi =
static_cast<RT>((AMREX_SPACEDIM == 3) ? this->m_geom[amrlev][mglev].InvCellSize(2) :
Real(1.0));
1661 auto& undrrelxr = this->m_undrrelxr[amrlev][mglev];
1662 MF foo(this->m_grids[amrlev][mglev], this->m_dmap[amrlev][mglev], ncomp, 0,
MFInfo().SetAlloc(
false));
1665 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->m_factory[amrlev][mglev].get());
1667 (factory) ? &(factory->getMultiEBCellFlagFab()) :
nullptr;
1668 auto area = (factory) ? factory->getAreaFrac()
1676 if (factory && !factory->isAllRegular()) {
1677#if defined(AMREX_USE_CUDA) && defined(_WIN32)
1678 if (!std::is_same<MF,MultiFab>()) {
1680 if constexpr (!std::is_same<MF,MultiFab>()) {
1682 amrex::Abort(
"MLCellLinOp with EB only works with MultiFab");
1685 tags.reserve(foo.local_size()*AMREX_SPACEDIM*ncomp);
1689 const Box& vbx = mfi.validbox();
1691 const auto & bdlv = bcondloc.bndryLocs(mfi);
1692 const auto & bdcv = bcondloc.bndryConds(mfi);
1696 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
1703 for (
int icomp = 0; icomp < ncomp; ++icomp) {
1704 tags.emplace_back(MLMGPSEBTag<RT>{undrrelxr[olo].array(mfi),
1705 undrrelxr[ohi].array(mfi),
1707 maskvals[olo].const_array(mfi),
1708 maskvals[ohi].const_array(mfi),
1709 bdlv[icomp][olo], bdlv[icomp][ohi],
1711 bdcv[icomp][olo], bdcv[icomp][ohi],
1712 vbx.
length(idim), icomp, idim});
1719 [=]
AMREX_GPU_DEVICE (
int i,
int j,
int k, MLMGPSEBTag<RT>
const& tag)
noexcept
1724 mllinop_comp_interp_coef0_x_eb
1725 (0, i , j, k, tag.blen, tag.flo, tag.mlo, tag.ap,
1726 tag.bctlo, tag.bcllo, imaxorder, dxi, tag.comp);
1727 mllinop_comp_interp_coef0_x_eb
1728 (1, i+tag.blen+1, j, k, tag.blen, tag.fhi, tag.mhi, tag.ap,
1729 tag.bcthi, tag.bclhi, imaxorder, dxi, tag.comp);
1731#if (AMREX_SPACEDIM > 1)
1733#
if (AMREX_SPACEDIM > 2)
1737 mllinop_comp_interp_coef0_y_eb
1738 (0, i, j , k, tag.blen, tag.flo, tag.mlo, tag.ap,
1739 tag.bctlo, tag.bcllo, imaxorder, dyi, tag.comp);
1740 mllinop_comp_interp_coef0_y_eb
1741 (1, i, j+tag.blen+1, k, tag.blen, tag.fhi, tag.mhi, tag.ap,
1742 tag.bcthi, tag.bclhi, imaxorder, dyi, tag.comp);
1744#if (AMREX_SPACEDIM > 2)
1746 mllinop_comp_interp_coef0_z_eb
1747 (0, i, j, k , tag.blen, tag.flo, tag.mlo, tag.ap,
1748 tag.bctlo, tag.bcllo, imaxorder, dzi, tag.comp);
1749 mllinop_comp_interp_coef0_z_eb
1750 (1, i, j, k+tag.blen+1, tag.blen, tag.fhi, tag.mhi, tag.ap,
1751 tag.bcthi, tag.bclhi, imaxorder, dzi, tag.comp);
1758 mllinop_comp_interp_coef0_x
1759 (0, i , j, k, tag.blen, tag.flo, tag.mlo,
1760 tag.bctlo, tag.bcllo, imaxorder, dxi, tag.comp);
1761 mllinop_comp_interp_coef0_x
1762 (1, i+tag.blen+1, j, k, tag.blen, tag.fhi, tag.mhi,
1763 tag.bcthi, tag.bclhi, imaxorder, dxi, tag.comp);
1765#if (AMREX_SPACEDIM > 1)
1767#if (AMREX_SPACEDIM > 2)
1771 mllinop_comp_interp_coef0_y
1772 (0, i, j , k, tag.blen, tag.flo, tag.mlo,
1773 tag.bctlo, tag.bcllo, imaxorder, dyi, tag.comp);
1774 mllinop_comp_interp_coef0_y
1775 (1, i, j+tag.blen+1, k, tag.blen, tag.fhi, tag.mhi,
1776 tag.bcthi, tag.bclhi, imaxorder, dyi, tag.comp);
1778#if (AMREX_SPACEDIM > 2)
1780 mllinop_comp_interp_coef0_z
1781 (0, i, j, k , tag.blen, tag.flo, tag.mlo,
1782 tag.bctlo, tag.bcllo, imaxorder, dzi, tag.comp);
1783 mllinop_comp_interp_coef0_z
1784 (1, i, j, k+tag.blen+1, tag.blen, tag.fhi, tag.mhi,
1785 tag.bcthi, tag.bclhi, imaxorder, dzi, tag.comp);
1796 tags.reserve(foo.local_size()*AMREX_SPACEDIM*ncomp);
1800 const Box& vbx = mfi.validbox();
1802 const auto & bdlv = bcondloc.bndryLocs(mfi);
1803 const auto & bdcv = bcondloc.bndryConds(mfi);
1805 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
1807 if (idim != hidden_direction) {
1810 for (
int icomp = 0; icomp < ncomp; ++icomp) {
1811 tags.emplace_back(MLMGPSTag<RT>{undrrelxr[olo].array(mfi),
1812 undrrelxr[ohi].array(mfi),
1813 maskvals[olo].const_array(mfi),
1814 maskvals[ohi].const_array(mfi),
1815 bdlv[icomp][olo], bdlv[icomp][ohi],
1817 bdcv[icomp][olo], bdcv[icomp][ohi],
1818 vbx.
length(idim), icomp, idim});
1825 [=]
AMREX_GPU_DEVICE (
int i,
int j,
int k, MLMGPSTag<RT>
const& tag)
noexcept
1829 mllinop_comp_interp_coef0_x
1830 (0, i , j, k, tag.blen, tag.flo, tag.mlo,
1831 tag.bctlo, tag.bcllo, imaxorder, dxi, tag.comp);
1832 mllinop_comp_interp_coef0_x
1833 (1, i+tag.blen+1, j, k, tag.blen, tag.fhi, tag.mhi,
1834 tag.bcthi, tag.bclhi, imaxorder, dxi, tag.comp);
1836#if (AMREX_SPACEDIM > 1)
1838#
if (AMREX_SPACEDIM > 2)
1842 mllinop_comp_interp_coef0_y
1843 (0, i, j , k, tag.blen, tag.flo, tag.mlo,
1844 tag.bctlo, tag.bcllo, imaxorder, dyi, tag.comp);
1845 mllinop_comp_interp_coef0_y
1846 (1, i, j+tag.blen+1, k, tag.blen, tag.fhi, tag.mhi,
1847 tag.bcthi, tag.bclhi, imaxorder, dyi, tag.comp);
1849#if (AMREX_SPACEDIM > 2)
1851 mllinop_comp_interp_coef0_z
1852 (0, i, j, k , tag.blen, tag.flo, tag.mlo,
1853 tag.bctlo, tag.bcllo, imaxorder, dzi, tag.comp);
1854 mllinop_comp_interp_coef0_z
1855 (1, i, j, k+tag.blen+1, tag.blen, tag.fhi, tag.mhi,
1856 tag.bcthi, tag.bclhi, imaxorder, dzi, tag.comp);
1870 const Box& vbx = mfi.validbox();
1872 const auto & bdlv = bcondloc.bndryLocs(mfi);
1873 const auto & bdcv = bcondloc.bndryConds(mfi);
1878 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
1880 if (idim == hidden_direction) {
continue; }
1885 const int blen = vbx.
length(idim);
1886 const auto& mlo = maskvals[olo].array(mfi);
1887 const auto& mhi = maskvals[ohi].array(mfi);
1888 const auto& flo = undrrelxr[olo].array(mfi);
1889 const auto& fhi = undrrelxr[ohi].array(mfi);
1890 for (
int icomp = 0; icomp < ncomp; ++icomp) {
1891 const BoundCond bctlo = bdcv[icomp][olo];
1892 const BoundCond bcthi = bdcv[icomp][ohi];
1893 const auto bcllo = bdlv[icomp][olo];
1894 const auto bclhi = bdlv[icomp][ohi];
1897 if constexpr (!std::is_same<MF,MultiFab>()) {
1898 amrex::Abort(
"MLCellLinOp with EB only works with MultiFab");
1900 auto const& ap = area[idim]->const_array(mfi);
1902 mllinop_comp_interp_coef0_x_eb
1903 (0, blo, blen, flo, mlo, ap, bctlo, bcllo,
1904 imaxorder, dxi, icomp);
1905 mllinop_comp_interp_coef0_x_eb
1906 (1, bhi, blen, fhi, mhi, ap, bcthi, bclhi,
1907 imaxorder, dxi, icomp);
1908 }
else if (idim == 1) {
1909 mllinop_comp_interp_coef0_y_eb
1910 (0, blo, blen, flo, mlo, ap, bctlo, bcllo,
1911 imaxorder, dyi, icomp);
1912 mllinop_comp_interp_coef0_y_eb
1913 (1, bhi, blen, fhi, mhi, ap, bcthi, bclhi,
1914 imaxorder, dyi, icomp);
1916 mllinop_comp_interp_coef0_z_eb
1917 (0, blo, blen, flo, mlo, ap, bctlo, bcllo,
1918 imaxorder, dzi, icomp);
1919 mllinop_comp_interp_coef0_z_eb
1920 (1, bhi, blen, fhi, mhi, ap, bcthi, bclhi,
1921 imaxorder, dzi, icomp);
1928 mllinop_comp_interp_coef0_x
1929 (0, blo, blen, flo, mlo, bctlo, bcllo,
1930 imaxorder, dxi, icomp);
1931 mllinop_comp_interp_coef0_x
1932 (1, bhi, blen, fhi, mhi, bcthi, bclhi,
1933 imaxorder, dxi, icomp);
1934 }
else if (idim == 1) {
1935 mllinop_comp_interp_coef0_y
1936 (0, blo, blen, flo, mlo, bctlo, bcllo,
1937 imaxorder, dyi, icomp);
1938 mllinop_comp_interp_coef0_y
1939 (1, bhi, blen, fhi, mhi, bcthi, bclhi,
1940 imaxorder, dyi, icomp);
1942 mllinop_comp_interp_coef0_z
1943 (0, blo, blen, flo, mlo, bctlo, bcllo,
1944 imaxorder, dzi, icomp);
1945 mllinop_comp_interp_coef0_z
1946 (1, bhi, blen, fhi, mhi, bcthi, bclhi,
1947 imaxorder, dzi, icomp);
1958template <
typename MF>
1963 const int ncomp = this->getNComp();
1972template <
typename MF>
1976 const int ncomp = this->getNComp();
1979 for (
int ilev = 0; ilev < this->NAMRLevels()-1; ++ilev) {
1980 result +=
amrex::Dot(*m_norm_fine_mask[ilev], *
x[ilev], 0, *
y[ilev], 0, ncomp, nghost,
true);
1983 *
y[this->NAMRLevels()-1], 0, ncomp, nghost,
true);
1988template <
typename MF>
1992 const int ncomp = this->getNComp();
1995 for (
int ilev = 0; ilev < this->NAMRLevels()-1; ++ilev) {
1996 result +=
amrex::Dot(*m_norm_fine_mask[ilev], *
x[ilev], 0, ncomp, nghost,
true);
1998 result +=
amrex::Dot(*
x[this->NAMRLevels()-1], 0, ncomp, nghost,
true);
2000 return std::sqrt(result);
2003template <
typename MF>
2007 if (!m_volinv.empty()) {
return; }
2009 m_volinv.resize(this->m_num_amr_levels);
2010 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
2011 m_volinv[amrlev].resize(this->NMGLevels(amrlev));
2016 auto f = [&] (
int amrlev,
int mglev) {
2018 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(amrlev,mglev));
2019 if (factory && !factory->isAllRegular())
2021 if constexpr (std::is_same<MF,MultiFab>()) {
2022 const auto& vfrac = factory->getVolFrac();
2023 m_volinv[amrlev][mglev] = vfrac.sum(0,
true);
2025 amrex::Abort(
"MLCellLinOp with EB only works with MultiFab");
2032 ? this->compactify(this->Geom(amrlev,mglev).Domain()).d_numPts()
2033 : this->m_grids[amrlev][mglev].d_numPts();
2035 m_volinv[amrlev][mglev] = RT(1.0 / npts);
2042 int mgbottom = this->NMGLevels(0)-1;
2047 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(0,0));
2048 if (factory && !factory->isAllRegular())
2050 ParallelAllReduce::Sum<RT>({m_volinv[0][0], m_volinv[0][mgbottom]},
2052 temp1 = RT(1.0)/m_volinv[0][0];
2053 temp2 = RT(1.0)/m_volinv[0][mgbottom];
2057 temp1 = m_volinv[0][0];
2058 temp2 = m_volinv[0][mgbottom];
2060 m_volinv[0][0] = temp1;
2061 m_volinv[0][mgbottom] = temp2;
2065template <
typename MF>
2069 const int ncomp = this->getNComp();
2070 const int finest_level = this->NAMRLevels() - 1;
2073 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(amrlev));
2074 if (factory && !factory->isAllRegular()) {
2075#if defined(AMREX_USE_CUDA) && defined(_WIN32)
2076 if (!std::is_same<MF,MultiFab>()) {
2078 if constexpr (!std::is_same<MF,MultiFab>()) {
2080 amrex::Abort(
"MLCellLinOpT with EB only works with MultiFab");
2082 const MultiFab& vfrac = factory->getVolFrac();
2083 if (amrlev == finest_level) {
2093 return std::abs(ma[box_no](i,j,k,n)
2094 *vfrac_ma[box_no](i,j,k));
2100#pragma omp parallel reduction(max:norm)
2103 Box const& bx = mfi.tilebox();
2104 auto const& fab = mf.const_array(mfi);
2108 norm = std::max(
norm, std::abs(fab(i,j,k,n)*v(i,j,k)));
2115 auto const& ma = mf.const_arrays();
2116 auto const& mask_ma = m_norm_fine_mask[amrlev]->const_arrays();
2123 if (mask_ma[box_no](i,j,k)) {
2124 return std::abs(ma[box_no](i,j,k,n)
2125 *vfrac_ma[box_no](i,j,k));
2134#pragma omp parallel reduction(max:norm)
2137 Box const& bx = mfi.tilebox();
2138 auto const& fab = mf.const_array(mfi);
2139 auto const&
mask = m_norm_fine_mask[amrlev]->const_array(mfi);
2144 norm = std::max(
norm, std::abs(fab(i,j,k,n)*v(i,j,k)));
2154 if (amrlev == finest_level) {
2157 norm = mf.norminf(*m_norm_fine_mask[amrlev], 0, ncomp,
IntVect(0),
true);
2165template <
typename MF>
2169 int ncomp = this->getNComp();
2170 for (
int falev = this->NAMRLevels()-1; falev > 0; --falev)
2173 if (!sol[falev].isAllRegular()) {
2174 if constexpr (std::is_same<MF,MultiFab>()) {
2177 amrex::Abort(
"EB_average_down only works with MultiFab");
2187template <
typename MF>
2192 if (!fres.isAllRegular()) {
2193 if constexpr (std::is_same<MF,MultiFab>()) {
2195 this->AMRRefRatio(clev));
2197 amrex::Abort(
"EB_average_down only works with MultiFab");
2203 this->AMRRefRatio(clev));
2207template <
typename MF>
2211 this->m_precond_mode =
true;
2213 if (m_bndry_sol_zero.empty()) {
2214 m_bndry_sol_zero.resize(m_bndry_sol.size());
2215 const int ncomp = this->getNComp();
2216 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
2217 m_bndry_sol_zero[amrlev] = std::make_unique<MLMGBndryT<MF>>
2218 (this->m_grids[amrlev][0],
2219 this->m_dmap[amrlev][0],
2221 this->m_geom[amrlev][0]);
2223 std::swap(m_bndry_sol, m_bndry_sol_zero);
2224 MF
const* coarse_data_for_bc_save = this->m_coarse_data_for_bc;
2225 this->m_coarse_data_for_bc =
nullptr;
2226 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
2227 this->setLevelBC(amrlev,
nullptr);
2229 this->m_coarse_data_for_bc = coarse_data_for_bc_save;
2231 std::swap(m_bndry_sol, m_bndry_sol_zero);
2235template <
typename MF>
2239 this->m_precond_mode =
false;
2240 std::swap(m_bndry_sol, m_bndry_sol_zero);
#define BL_TO_FORTRAN_BOX(x)
Definition AMReX_ArrayLim.H:51
#define BL_TO_FORTRAN_ANYD(x)
Definition AMReX_ArrayLim.H:44
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define BL_ASSERT(EX)
Definition AMReX_BLassert.H:39
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_HOST_DEVICE_PARALLEL_FOR_3D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:110
#define AMREX_GPU_LAUNCH_HOST_DEVICE_LAMBDA_RANGE(TN, TI, block)
Definition AMReX_GpuLaunchMacrosC.nolint.H:4
#define AMREX_HOST_DEVICE_PARALLEL_FOR_4D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:111
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1089
Box cbx
Definition AMReX_HypreMLABecLap.cpp:1091
Array4< Real > fine
Definition AMReX_InterpFaceRegister.cpp:90
Array4< int const > mask
Definition AMReX_InterpFaceRegister.cpp:93
Array4< Real const > crse
Definition AMReX_InterpFaceRegister.cpp:92
#define AMREX_LOOP_4D(bx, ncomp, i, j, k, n, block)
Definition AMReX_Loop.nolint.H:16
void amrex_mllinop_apply_bc(const int *lo, const int *hi, amrex_real *phi, const int *philo, const int *phihi, const int *mask, const int *mlo, const int *mhi, int cdir, int bct, amrex_real bcl, const amrex_real *bcval, const int *blo, const int *bhi, int maxorder, const amrex_real *dxinv, int inhomog, int nc, int cross)
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
const FabSetT< MF > & bndryValues(Orientation face) const noexcept
Return FabSet on given face.
Definition AMReX_BndryData.H:77
Maintain an identifier for boundary condition types.
Definition AMReX_BoundCond.H:20
A collection of Boxes stored in an Array.
Definition AMReX_BoxArray.H:567
void define(const Box &bx)
Initialize the BoxArray from a single box. It is an error if the BoxArray has already been initialize...
Definition AMReX_BoxArray.cpp:352
BoxArray & coarsen(int refinement_ratio)
Coarsen each Box in the BoxArray to the specified ratio.
Definition AMReX_BoxArray.cpp:672
Long size() const noexcept
Return the number of boxes in the BoxArray.
Definition AMReX_BoxArray.H:614
A class for managing a List of Boxes that share a common IndexType. This class implements operations ...
Definition AMReX_BoxList.H:52
__host__ __device__ BoxND & setBig(const IntVectND< dim > &bg) noexcept
Redefine the big end of the BoxND.
Definition AMReX_Box.H:487
__host__ __device__ IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:154
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:212
__host__ __device__ IntVectND< dim > size() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:147
__host__ __device__ BoxND & coarsen(int ref_ratio) noexcept
Coarsen BoxND by given (positive) refinement ratio. NOTE: if type(dir) = CELL centered: lo <- lo/rati...
Definition AMReX_Box.H:722
__host__ __device__ BoxND & refine(int ref_ratio) noexcept
Refine BoxND by given (positive) refinement ratio. NOTE: if type(dir) = CELL centered: lo <- lo*ratio...
Definition AMReX_Box.H:698
__host__ static __device__ BoxND TheUnitBox() noexcept
This static member function returns a constant reference to an object of type BoxND representing the ...
Definition AMReX_Box.H:751
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Return the inclusive lower bound of the box.
Definition AMReX_Box.H:111
const Real * CellSize() const noexcept
Returns the cellsize for each coordinate direction.
Definition AMReX_CoordSys.H:71
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:43
Definition AMReX_EBFabFactory.H:25
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:347
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi) const noexcept
Definition AMReX_FabArray.H:587
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Definition AMReX_FabArray.H:649
Definition AMReX_FabFactory.H:50
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:74
Periodicity periodicity() const noexcept
Definition AMReX_Geometry.H:356
const Real * ProbLo() const noexcept
Returns the lo end of the problem domain in each dimension.
Definition AMReX_Geometry.H:179
GPU-compatible tuple.
Definition AMReX_Tuple.H:98
__host__ __device__ constexpr bool allGT(const IntVectND< dim > &rhs) const noexcept
Returns true if this is greater than argument for all components. NOTE: This is NOT a strict weak ord...
Definition AMReX_IntVect.H:425
__host__ __device__ IntVectND & setVal(int i, int val) noexcept
Set i'th coordinate of IntVectND to val.
Definition AMReX_IntVect.H:281
__host__ static __device__ constexpr IntVectND< dim > TheCellVector() noexcept
This static member function returns a reference to a constant IntVectND object, all of whose dim argu...
Definition AMReX_IntVect.H:718
An InterpBndryData object adds to a BndryData object the ability to manipulate and set the data store...
Definition AMReX_InterpBndryData.H:40
static constexpr int IBD_max_order_DEF
Definition AMReX_InterpBndryData.H:115
a one-thingy-per-box distributed object
Definition AMReX_LayoutData.H:13
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:85
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:169
Definition AMReX_MLCellLinOp.H:24
virtual void Fsmooth(int amrlev, int mglev, MF &sol, const MF &rhs, int redblack) const =0
Vector< RT > getSolvabilityOffset(int amrlev, int mglev, MF const &rhs) const override
get offset for fixing solvability
Definition AMReX_MLCellLinOp.H:1586
void averageDownSolutionRHS(int camrlev, MF &crse_sol, MF &crse_rhs, const MF &fine_sol, const MF &fine_rhs) override
Average-down data from fine AMR level to coarse AMR level.
Definition AMReX_MLCellLinOp.H:1218
void averageDownAndSync(Vector< MF > &sol) const override
Definition AMReX_MLCellLinOp.H:2167
BoxArray makeNGrids(int grid_size) const
Definition AMReX_MLCellLinOp.H:930
Vector< YAFluxRegisterT< MF > > m_fluxreg
Definition AMReX_MLCellLinOp.H:226
virtual void applyBC(int amrlev, int mglev, MF &in, BCMode bc_mode, StateMode s_mode, const MLMGBndryT< MF > *bndry=nullptr, bool skip_fillboundary=false) const
Definition AMReX_MLCellLinOp.H:710
void updateSolBC(int amrlev, const MF &crse_bcdata) const
Definition AMReX_MLCellLinOp.H:679
Vector< std::unique_ptr< MLMGBndryT< MF > > > m_bndry_sol
Definition AMReX_MLCellLinOp.H:166
MLCellLinOpT< MF > & operator=(const MLCellLinOpT< MF > &)=delete
void compGrad(int amrlev, const Array< MF *, 3 > &grad, MF &sol, Location loc) const override
Compute gradients of the solution.
Definition AMReX_MLCellLinOp.H:1418
void avgDownResAmr(int clev, MF &cres, MF const &fres) const override
Definition AMReX_MLCellLinOp.H:2189
void reflux(int crse_amrlev, MF &res, const MF &crse_sol, const MF &, MF &, MF &fine_sol, const MF &) const final
Reflux at AMR coarse/fine boundary.
Definition AMReX_MLCellLinOp.H:1309
RT dotProductPrecond(Vector< MF const * > const &x, Vector< MF const * > const &y) const final
Definition AMReX_MLCellLinOp.H:1974
virtual void Fapply(int amrlev, int mglev, MF &out, const MF &in) const =0
typename FabDataType< MF >::value_type RT
Definition AMReX_MLCellLinOp.H:28
void endPrecondBC() override
Definition AMReX_MLCellLinOp.H:2237
void update() override
Update for reuse.
Definition AMReX_MLCellLinOp.H:672
void correctionResidual(int amrlev, int mglev, MF &resid, MF &x, const MF &b, BCMode bc_mode, const MF *crse_bcdata=nullptr) final
Compute residual for the residual-correction form, resid = b - L(x)
Definition AMReX_MLCellLinOp.H:1283
MLCellLinOpT(const MLCellLinOpT< MF > &)=delete
typename MLLinOpT< MF >::BCMode BCMode
Definition AMReX_MLCellLinOp.H:31
void smooth(int amrlev, int mglev, MF &sol, const MF &rhs, bool skip_fillboundary, int niter) const final
Smooth.
Definition AMReX_MLCellLinOp.H:1239
RT normInf(int amrlev, MF const &mf, bool local) const override
Definition AMReX_MLCellLinOp.H:2067
virtual bool isCrossStencil() const
Definition AMReX_MLCellLinOp.H:71
void updateCorBC(int amrlev, const MF &crse_bcdata) const
Definition AMReX_MLCellLinOp.H:695
Array< RT, 2 *3 > RealTuple
Definition AMReX_MLCellLinOp.H:177
void interpolation(int amrlev, int fmglev, MF &fine, const MF &crse) const override
Add interpolated coarse MG level data to fine MG level data.
Definition AMReX_MLCellLinOp.H:989
RT xdoty(int amrlev, int mglev, const MF &x, const MF &y, bool local) const final
x dot y, used by the bottom solver
Definition AMReX_MLCellLinOp.H:1960
Array< BoundCond, 2 *3 > BCTuple
Definition AMReX_MLCellLinOp.H:178
void prepareForSolve() override
Definition AMReX_MLCellLinOp.H:1643
void unapplyMetricTerm(int amrlev, int mglev, MF &rhs) const final
unapply metric terms if there are any
Definition AMReX_MLCellLinOp.H:1528
void apply(int amrlev, int mglev, MF &out, MF &in, BCMode bc_mode, StateMode s_mode, const MLMGBndryT< MF > *bndry=nullptr) const override
Apply the linear operator, out = L(in)
Definition AMReX_MLCellLinOp.H:1229
void applyMetricTerm(int amrlev, int mglev, MF &rhs) const final
apply metric terms if there are any
Definition AMReX_MLCellLinOp.H:1472
Vector< std::unique_ptr< BndryRegisterT< MF > > > m_crse_cor_br
Definition AMReX_MLCellLinOp.H:170
RT norm2Precond(Vector< MF const * > const &x) const final
Definition AMReX_MLCellLinOp.H:1990
void beginPrecondBC() override
Definition AMReX_MLCellLinOp.H:2209
Vector< Vector< std::unique_ptr< BndryCondLoc > > > m_bcondloc
Definition AMReX_MLCellLinOp.H:216
void setGaussSeidel(bool flag) noexcept
Definition AMReX_MLCellLinOp.H:69
Vector< std::unique_ptr< MF > > m_robin_bcval
Definition AMReX_MLCellLinOp.H:158
void define(const Vector< Geometry > &a_geom, const Vector< BoxArray > &a_grids, const Vector< DistributionMapping > &a_dmap, const LPInfo &a_info=LPInfo(), const Vector< FabFactory< FAB > const * > &a_factory={})
Definition AMReX_MLCellLinOp.H:378
~MLCellLinOpT() override=default
virtual bool isTensorOp() const
Definition AMReX_MLCellLinOp.H:72
void setInterpBndryHalfWidth(int w)
Definition AMReX_MLCellLinOp.H:160
void restriction(int, int, MF &crse, MF &fine) const override
Restriction onto coarse MG level.
Definition AMReX_MLCellLinOp.H:980
Vector< Vector< BndryRegisterT< MF > > > m_undrrelxr
Definition AMReX_MLCellLinOp.H:219
MLCellLinOpT()
Definition AMReX_MLCellLinOp.H:371
MLCellLinOpT(MLCellLinOpT< MF > &&)=delete
typename FabDataType< MF >::fab_type FAB
Definition AMReX_MLCellLinOp.H:27
void interpAssign(int amrlev, int fmglev, MF &fine, MF &crse) const override
Overwrite fine MG level data with interpolated coarse data.
Definition AMReX_MLCellLinOp.H:1036
void fixSolvabilityByOffset(int amrlev, int mglev, MF &rhs, Vector< RT > const &offset) const override
fix solvability by subtracting offset from RHS
Definition AMReX_MLCellLinOp.H:1623
Vector< std::unique_ptr< MLMGBndryT< MF > > > m_bndry_cor
Definition AMReX_MLCellLinOp.H:169
void compFlux(int amrlev, const Array< MF *, 3 > &fluxes, MF &sol, Location loc) const override
Compute fluxes.
Definition AMReX_MLCellLinOp.H:1377
typename MLLinOpT< MF >::Location Location
Definition AMReX_MLCellLinOp.H:33
void prepareForFluxes(int amrlev, const MF *crse_bcdata=nullptr) override
Definition AMReX_MLCellLinOp.H:1274
void solutionResidual(int amrlev, MF &resid, MF &x, const MF &b, const MF *crse_bcdata=nullptr) override
Compute residual for solution.
Definition AMReX_MLCellLinOp.H:1256
bool m_has_metric_term
Definition AMReX_MLCellLinOp.H:164
bool m_use_gauss_seidel
Definition AMReX_MLCellLinOp.H:228
Vector< std::unique_ptr< MLMGBndryT< MF > > > m_bndry_sol_zero
Definition AMReX_MLCellLinOp.H:172
Vector< std::unique_ptr< BndryRegisterT< MF > > > m_crse_sol_br
Definition AMReX_MLCellLinOp.H:167
void interpolationAmr(int famrlev, MF &fine, const MF &crse, IntVect const &nghost) const override
Interpolation between AMR levels.
Definition AMReX_MLCellLinOp.H:1129
virtual void addInhomogNeumannFlux(int, const Array< MF *, 3 > &, MF const &, bool) const
Definition AMReX_MLCellLinOp.H:137
Vector< std::unique_ptr< iMultiFab > > m_norm_fine_mask
Definition AMReX_MLCellLinOp.H:224
typename MLLinOpT< MF >::StateMode StateMode
Definition AMReX_MLCellLinOp.H:32
void setLevelBC(int amrlev, const MF *levelbcdata, const MF *robinbc_a=nullptr, const MF *robinbc_b=nullptr, const MF *robinbc_f=nullptr) final
Set boundary conditions for given level. For cell-centered solves only.
Definition AMReX_MLCellLinOp.H:539
bool needsUpdate() const override
Does it need update if it's reused?
Definition AMReX_MLCellLinOp.H:64
Vector< Vector< Array< MultiMask, 2 *3 > > > m_maskvals
Definition AMReX_MLCellLinOp.H:222
virtual void FFlux(int amrlev, const MFIter &mfi, const Array< FAB *, 3 > &flux, const FAB &sol, Location loc, int face_only=0) const =0
Definition AMReX_MLLinOp.H:102
virtual bool needsUpdate() const
Does it need update if it's reused?
Definition AMReX_MLLinOp.H:271
virtual void update()
Update for reuse.
Definition AMReX_MLLinOp.H:273
void define(const Vector< Geometry > &a_geom, const Vector< BoxArray > &a_grids, const Vector< DistributionMapping > &a_dmap, const LPInfo &a_info, const Vector< FabFactory< FAB > const * > &a_factory, bool eb_limit_coarsening=true)
Definition AMReX_MLLinOp.H:778
Definition AMReX_MLMGBndry.H:12
static void setBoxBC(RealTuple &bloc, BCTuple &bctag, const Box &bx, const Box &domain, const Array< LinOpBCType, 3 > &lo, const Array< LinOpBCType, 3 > &hi, const Real *dx, IntVect const &ratio, const RealVect &interior_bloc, const Array< Real, 3 > &domain_bloc_lo, const Array< Real, 3 > &domain_bloc_hi, const GpuArray< int, 3 > &is_periodic, LinOpBCType a_crse_fine_bc_type)
Definition AMReX_MLMGBndry.H:107
Definition AMReX_Mask.H:28
A collection (stored as an array) of FArrayBox objects.
Definition AMReX_MultiFab.H:40
An Iterator over the Orientation of Faces of a Box.
Definition AMReX_Orientation.H:135
Encapsulation of the Orientation of the Faces of a Box.
Definition AMReX_Orientation.H:29
@ low
Definition AMReX_Orientation.H:34
@ high
Definition AMReX_Orientation.H:34
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:79
__host__ __device__ BoxND< dim > coarsen(const BoxND< dim > &b, int ref_ratio) noexcept
Coarsen BoxND by given (positive) coarsening ratio.
Definition AMReX_Box.H:1409
__host__ __device__ BoxND< dim > grow(const BoxND< dim > &b, int i) noexcept
Grow BoxND in all directions by given amount.
Definition AMReX_Box.H:1280
std::array< T, N > Array
Definition AMReX_Array.H:26
Arena * The_Async_Arena()
Definition AMReX_Arena.cpp:793
void Sum(T &v, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:221
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
void copyAsync(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition AMReX_GpuContainers.H:228
static constexpr HostToDevice hostToDevice
Definition AMReX_GpuContainers.H:105
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:263
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:92
bool notInLaunchRegion() noexcept
Definition AMReX_GpuControl.H:93
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
Definition AMReX_Amr.cpp:49
__host__ __device__ BoxND< dim > adjCellHi(const BoxND< dim > &b, int dir, int len=1) noexcept
Similar to adjCellLo but builds an adjacent BoxND on the high end.
Definition AMReX_Box.H:1735
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:138
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:193
__host__ __device__ T norm(const GpuComplex< T > &a_z) noexcept
Return the norm (magnitude squared) of a complex number.
Definition AMReX_GpuComplex.H:349
void average_down(const MultiFab &S_fine, MultiFab &S_crse, const Geometry &fgeom, const Geometry &cgeom, int scomp, int ncomp, int rr)
Definition AMReX_MultiFabUtil.cpp:336
__host__ __device__ BoxND< dim > adjCellLo(const BoxND< dim > &b, int dir, int len=1) noexcept
Return the cell centered BoxND of length len adjacent to b on the low end along the coordinate direct...
Definition AMReX_Box.H:1714
__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:1522
ReduceData< Ts... >::Type ParReduce(TypeList< Ops... > operation_list, TypeList< Ts... > type_list, FabArray< FAB > const &fa, IntVect const &nghost, F &&f)
Parallel reduce for MultiFab/FabArray. The reduce result is local and it's the user's responsibility ...
Definition AMReX_ParReduce.H:48
void EB_set_covered(MultiFab &mf, Real val)
Definition AMReX_EBMultiFabUtil.cpp:21
constexpr bool IsMultiFabLike_v
Definition AMReX_TypeTraits.H:49
BoxND< 3 > Box
Box is an alias for amrex::BoxND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:30
__host__ __device__ BoxND< dim > adjCell(const BoxND< dim > &b, Orientation face, int len=1) noexcept
Similar to adjCellLo and adjCellHi; operates on given face.
Definition AMReX_Box.H:1757
bool isMFIterSafe(const FabArrayBase &x, const FabArrayBase &y)
Definition AMReX_MFIter.H:249
__host__ __device__ BoxND< dim > shift(const BoxND< dim > &b, int dir, int nzones) noexcept
Return a BoxND with indices shifted by nzones in dir direction.
Definition AMReX_Box.H:1495
LinOpBCType
Definition AMReX_LO_BCTYPES.H:22
void EB_average_down(const MultiFab &S_fine, MultiFab &S_crse, const MultiFab &vol_fine, const MultiFab &vfrac_fine, int scomp, int ncomp, const IntVect &ratio)
Definition AMReX_EBMultiFabUtil.cpp:336
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:33
RealVectND< 3 > RealVect
Definition AMReX_ParmParse.H:35
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
FAB::value_type Dot(FabArray< FAB > const &x, int xcomp, FabArray< FAB > const &y, int ycomp, int ncomp, IntVect const &nghost, bool local=false)
Compute dot products of two FabArrays.
Definition AMReX_FabArrayUtility.H:1673
iMultiFab makeFineMask(const BoxArray &cba, const DistributionMapping &cdm, const BoxArray &fba, const IntVect &ratio, int crse_value, int fine_value)
Definition AMReX_MultiFabUtil.cpp:629
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get I'th element of IntVectND<dim>
Definition AMReX_IntVect.H:1230
A multidimensional array accessor.
Definition AMReX_Array4.H:224
Definition AMReX_Dim3.H:12
int x
Definition AMReX_Dim3.H:12
int z
Definition AMReX_Dim3.H:12
int y
Definition AMReX_Dim3.H:12
Definition AMReX_FabDataType.H:9
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:41
Definition AMReX_MLLinOp.H:36
StateMode
Definition AMReX_MLLinOp.H:89
BCMode
Definition AMReX_MLLinOp.H:88
Location
Definition AMReX_MLLinOp.H:90
FabArray memory allocation information.
Definition AMReX_FabArray.H:66
Definition AMReX_MFIter.H:20
MFItInfo & SetDynamic(bool f) noexcept
Definition AMReX_MFIter.H:40
MFItInfo & EnableTiling(const IntVect &ts=FabArrayBase::mfiter_tile_size) noexcept
Definition AMReX_MFIter.H:31
Definition AMReX_MLCellLinOp.H:19
Definition AMReX_FabArray.H:153
Struct for holding types.
Definition AMReX_TypeList.H:12