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>
78 void setLevelBC (
int amrlev,
const MF* levelbcdata,
79 const MF* robinbc_a =
nullptr,
80 const MF* robinbc_b =
nullptr,
81 const MF* robinbc_f =
nullptr) final;
84 requires (!std::same_as<MF,AMF>)
86 const AMF* robinbc_a =
nullptr,
87 const AMF* robinbc_b =
nullptr,
88 const AMF* robinbc_f =
nullptr)
117 void updateSolBC (
int amrlev,
const MF& crse_bcdata)
const;
124 void updateCorBC (
int amrlev,
const MF& crse_bcdata)
const;
138 const MLMGBndryT<MF>* bndry=
nullptr,
bool skip_fillboundary=
false)
const;
185 IntVect const& nghost)
const override;
197 const MF& fine_sol,
const MF& fine_rhs)
override;
210 void apply (
int amrlev,
int mglev, MF& out, MF& in,
BCMode bc_mode,
222 void smooth (
int amrlev,
int mglev, MF& sol,
const MF& rhs,
223 bool skip_fillboundary,
int niter)
const final;
235 const MF* crse_bcdata=
nullptr)
override;
243 void prepareForFluxes (
int amrlev,
const MF* crse_bcdata =
nullptr)
override;
257 BCMode bc_mode,
const MF* crse_bcdata=
nullptr) final;
272 void reflux (
int crse_amrlev,
273 MF& res, const MF& crse_sol, const MF&,
274 MF&, MF& fine_sol, const MF&) const final;
283 void compFlux (
int amrlev, const
Array<MF*,AMREX_SPACEDIM>& fluxes,
284 MF& sol,
Location loc) const override;
293 void compGrad (
int amrlev, const
Array<MF*,AMREX_SPACEDIM>& grad,
294 MF& sol,
Location loc) const override;
321 MF const& rhs) const override;
346 RT xdoty (
int amrlev,
int mglev, const MF&
x, const MF&
y,
bool local) const final;
367 virtual
void Fapply (
int amrlev,
int mglev, MF& out, const MF& in) const = 0;
368 virtual
void Fsmooth (
int amrlev,
int mglev, MF& sol, const MF& rhs,
int redblack) const = 0;
370 const
Array<
FAB*,AMREX_SPACEDIM>& flux,
371 const
FAB& sol,
Location loc,
int face_only=0) const = 0;
382 const
Array<MF*,AMREX_SPACEDIM>& ,
393 RT normInf (
int amrlev, MF
const& mf,
bool local)
const override;
409 void avgDownResAmr (
int clev, MF& cres, MF
const& fres)
const override;
455 void setLOBndryConds (
const Geometry& geom,
const Real* dx,
469 const BCTuple& bndryConds (
const MFIter& mfi,
int icomp)
const noexcept {
470 return bcond[mfi][icomp];
472 const RealTuple& bndryLocs (
const MFIter& mfi,
int icomp)
const noexcept {
473 return bcloc[mfi][icomp];
502 void defineAuxData ();
505 void computeVolInv ()
const;
508 int m_interpbndry_halfwidth = 2;
527 Box const& box() const noexcept {
return bx; }
534 Array4<int const> mlo;
535 Array4<int const> mhi;
546 Box const& box() const noexcept {
return bx; }
555 Array4<int const> mlo;
556 Array4<int const> mhi;
567 Box const& box() const noexcept {
return bx; }
571template <
typename MF>
572MLCellLinOpT<MF>::BndryCondLoc::BndryCondLoc (
const BoxArray& ba,
573 const DistributionMapping& dm,
578 bctl_dv(bctl.local_size()*ncomp),
581 auto* dp = bctl_dv.data();
582 for (MFIter mfi(bcloc); mfi.isValid(); ++mfi) {
583 bcond[mfi].resize(ncomp);
584 bcloc[mfi].resize(ncomp);
590template <
typename MF>
592MLCellLinOpT<MF>::BndryCondLoc::
593setLOBndryConds (
const Geometry& geom,
const Real* dx,
594 const Vector<Array<BCType,AMREX_SPACEDIM> >& lobc,
595 const Vector<Array<BCType,AMREX_SPACEDIM> >& hibc,
597 const Array<Real,AMREX_SPACEDIM>& domain_bloc_lo,
598 const Array<Real,AMREX_SPACEDIM>& domain_bloc_hi,
601 const Box& domain = geom.Domain();
606 for (MFIter mfi(bcloc); mfi.isValid(); ++mfi)
608 const Box& bx = mfi.validbox();
609 for (
int icomp = 0; icomp < m_ncomp; ++icomp) {
610 RealTuple & bloc = bcloc[mfi][icomp];
611 BCTuple & bctag = bcond[mfi][icomp];
613 lobc[icomp], hibc[icomp],
614 dx, ratio, interior_bloc,
615 domain_bloc_lo, domain_bloc_hi,
616 geom.isPeriodicArray(),
621 Gpu::PinnedVector<GpuArray<BCTL,2*AMREX_SPACEDIM> > hv;
622 hv.reserve(bctl_dv.size());
623 for (MFIter mfi(bctl); mfi.isValid(); ++mfi)
625 for (
int icomp = 0; icomp < m_ncomp; ++icomp) {
626 GpuArray<BCTL,2*AMREX_SPACEDIM> tmp;
627 for (
int m = 0; m < 2*AMREX_SPACEDIM; ++m) {
628 tmp[m].type = bcond[mfi][icomp][m];
629 tmp[m].location = bcloc[mfi][icomp][m];
631 hv.push_back(std::move(tmp));
640template <
typename MF>
646template <
typename MF>
659template <
typename MF>
665 m_undrrelxr.resize(this->m_num_amr_levels);
666 m_maskvals.resize(this->m_num_amr_levels);
667 m_fluxreg.resize(this->m_num_amr_levels-1);
668 m_norm_fine_mask.resize(this->m_num_amr_levels-1);
669 m_bc_tags.resize(this->m_num_amr_levels);
671 const int ncomp = this->getNComp();
673 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
675 m_undrrelxr[amrlev].resize(this->m_num_mg_levels[amrlev]);
676 m_bc_tags[amrlev].resize(this->m_num_mg_levels[amrlev]);
677 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
679 m_undrrelxr[amrlev][mglev].define(this->m_grids[amrlev][mglev],
680 this->m_dmap[amrlev][mglev],
685 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
687 m_maskvals[amrlev].resize(this->m_num_mg_levels[amrlev]);
688 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
690 for (OrientationIter oitr; oitr; ++oitr)
692 const Orientation face = oitr();
694 const int extent = this->isCrossStencil() ? 0 : 1;
695 m_maskvals[amrlev][mglev][face].define(this->m_grids[amrlev][mglev],
696 this->m_dmap[amrlev][mglev],
697 this->m_geom[amrlev][mglev],
698 face, 0, ngrow, extent, 1,
true);
703 for (
int amrlev = 0; amrlev < this->m_num_amr_levels-1; ++amrlev)
705 const IntVect ratio{this->AMRRefRatioVect(amrlev)};
706 m_fluxreg[amrlev].define(this->m_grids[amrlev+1][0],
707 this->m_grids[amrlev][0],
708 this->m_dmap[amrlev+1][0],
709 this->m_dmap[amrlev][0],
710 this->m_geom[amrlev+1][0],
711 this->m_geom[amrlev][0],
712 ratio, amrlev+1, ncomp);
713 m_fluxreg[amrlev].setDeterministic(this->info.deterministic);
714 m_norm_fine_mask[amrlev] = std::make_unique<iMultiFab>
715 (
makeFineMask(this->m_grids[amrlev][0], this->m_dmap[amrlev][0],
716 this->m_grids[amrlev+1][0],
720#if (AMREX_SPACEDIM != 3)
721 m_has_metric_term = !this->m_geom[0][0].IsCartesian() && this->info.has_metric_term;
725template <
typename MF>
727MLCellLinOpT<MF>::defineBC ()
731 const int ncomp = this->getNComp();
733 m_bndry_sol.resize(this->m_num_amr_levels);
734 m_crse_sol_br.resize(this->m_num_amr_levels);
736 m_bndry_cor.resize(this->m_num_amr_levels);
737 m_crse_cor_br.resize(this->m_num_amr_levels);
739 m_robin_bcval.resize(this->m_num_amr_levels);
741 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
743 m_bndry_sol[amrlev] = std::make_unique<MLMGBndryT<MF>>(this->m_grids[amrlev][0],
744 this->m_dmap[amrlev][0],
746 this->m_geom[amrlev][0]);
749 for (
int amrlev = 1; amrlev < this->m_num_amr_levels; ++amrlev)
751 const int in_rad = 0;
752 const int out_rad = 1;
753 const int extent_rad = 2;
754 const IntVect crse_ratio = this->AMRRefRatioVect(amrlev-1);
755 BoxArray cba = this->m_grids[amrlev][0];
756 cba.coarsen(crse_ratio);
757 m_crse_sol_br[amrlev] = std::make_unique<BndryRegisterT<MF>>
758 (cba, this->m_dmap[amrlev][0], in_rad, out_rad, extent_rad, ncomp);
761 for (
int amrlev = 1; amrlev < this->m_num_amr_levels; ++amrlev)
763 const int in_rad = 0;
764 const int out_rad = 1;
765 const int extent_rad = 2;
766 const IntVect crse_ratio = this->AMRRefRatioVect(amrlev-1);
767 BoxArray cba = this->m_grids[amrlev][0];
768 cba.coarsen(crse_ratio);
769 m_crse_cor_br[amrlev] = std::make_unique<BndryRegisterT<MF>>
770 (cba, this->m_dmap[amrlev][0], in_rad, out_rad, extent_rad, ncomp);
771 m_crse_cor_br[amrlev]->setVal(RT(0.0));
775 for (
int amrlev = 1; amrlev < this->m_num_amr_levels; ++amrlev)
777 m_bndry_cor[amrlev] = std::make_unique<MLMGBndryT<MF>>
778 (this->m_grids[amrlev][0], this->m_dmap[amrlev][0], ncomp, this->m_geom[amrlev][0]);
779 MF bc_data(this->m_grids[amrlev][0], this->m_dmap[amrlev][0], ncomp, 1);
782 m_bndry_cor[amrlev]->setBndryValues(*m_crse_cor_br[amrlev], 0, bc_data, 0, 0, ncomp,
783 this->AMRRefRatioVect(amrlev-1),
785 m_interpbndry_halfwidth);
787 Vector<Array<LinOpBCType,AMREX_SPACEDIM> > bclohi
788 (ncomp,Array<LinOpBCType,AMREX_SPACEDIM>{{
AMREX_D_DECL(BCType::Dirichlet,
790 BCType::Dirichlet)}});
791 m_bndry_cor[amrlev]->setLOBndryConds(bclohi, bclohi, this->AMRRefRatioVect(amrlev-1),
RealVect{});
794 m_bcondloc.resize(this->m_num_amr_levels);
795 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
797 m_bcondloc[amrlev].resize(this->m_num_mg_levels[amrlev]);
798 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
800 m_bcondloc[amrlev][mglev] = std::make_unique<BndryCondLoc>(this->m_grids[amrlev][mglev],
801 this->m_dmap[amrlev][mglev],
807template <
typename MF>
810 const MF* robinbc_b,
const MF* robinbc_f)
816 const int ncomp = this->getNComp();
820 if (this->hasHiddenDimension()) { ng[this->hiddenDirection()] = 0; }
821 if (a_levelbcdata ==
nullptr) {
822 zero.define(this->m_grids[amrlev][0], this->m_dmap[amrlev][0], ncomp, ng);
827 const MF& bcdata = (a_levelbcdata ==
nullptr) ?
zero : *a_levelbcdata;
833 if (this->needsCoarseDataForBC())
836 if (this->hasHiddenDimension()) {
837 int hidden_dir = this->hiddenDirection();
840 br_ref_ratio = this->m_coarse_data_crse_ratio.
allGT(0) ? this->m_coarse_data_crse_ratio :
IntVect(2);
841 if (this->m_crse_sol_br[amrlev] ==
nullptr && br_ref_ratio.
allGT(0))
843 const int in_rad = 0;
844 const int out_rad = 1;
845 const int extent_rad = 2;
846 const IntVect crse_ratio = br_ref_ratio;
847 BoxArray cba = this->m_grids[amrlev][0];
849 this->m_crse_sol_br[amrlev] = std::make_unique<BndryRegisterT<MF>>
850 (cba, this->m_dmap[amrlev][0], in_rad, out_rad, extent_rad, ncomp);
852 if (this->m_coarse_data_for_bc !=
nullptr) {
855 this->m_crse_sol_br[amrlev]->copyFrom(*(this->m_coarse_data_for_bc), 0, 0, 0, ncomp,
856 this->m_geom[0][0].periodicity(
cbx));
858 this->m_crse_sol_br[amrlev]->setVal(
RT(0.0));
860 this->m_bndry_sol[amrlev]->setBndryValues(*(this->m_crse_sol_br[amrlev]), 0,
861 bcdata, 0, 0, ncomp, br_ref_ratio,
863 this->m_interpbndry_halfwidth);
864 br_ref_ratio = this->m_coarse_data_crse_ratio;
868 this->m_bndry_sol[amrlev]->setPhysBndryValues(bcdata,0,0,ncomp);
874 this->m_bndry_sol[amrlev]->setPhysBndryValues(bcdata,0,0,ncomp);
875 br_ref_ratio = this->AMRRefRatioVect(amrlev-1);
879 this->m_bndry_sol[amrlev]->setLOBndryConds(this->m_lobc, this->m_hibc, br_ref_ratio,
880 this->m_coarse_bc_loc, crse_fine_bc_type);
882 const Real* dx = this->m_geom[amrlev][0].CellSize();
883 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
885 this->m_bcondloc[amrlev][mglev]->setLOBndryConds(this->m_geom[amrlev][mglev], dx,
886 this->m_lobc, this->m_hibc,
887 br_ref_ratio, this->m_coarse_bc_loc,
888 this->m_domain_bloc_lo, this->m_domain_bloc_hi,
890 m_bc_tags[amrlev][mglev].undefine();
895 if (this->hasRobinBC() && !this->m_precond_mode) {
896 AMREX_ASSERT(robinbc_a !=
nullptr && robinbc_b !=
nullptr && robinbc_f !=
nullptr);
897 this->m_robin_bcval[amrlev] = std::make_unique<MF>(this->m_grids[amrlev][0],
898 this->m_dmap[amrlev][0],
900 const Box& domain = this->m_geom[amrlev][0].Domain();
904#pragma omp parallel if (Gpu::notInLaunchRegion())
906 for (
MFIter mfi(*(this->m_robin_bcval[amrlev]), mfi_info); mfi.
isValid(); ++mfi) {
907 Box const& vbx = mfi.validbox();
911 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
914 bool outside_domain_lo = !(domain.
contains(blo));
915 bool outside_domain_hi = !(domain.
contains(bhi));
916 if ((!outside_domain_lo) && (!outside_domain_hi)) {
continue; }
917 for (
int icomp = 0; icomp < ncomp; ++icomp) {
918 Array4<RT> const& rbc = (*(this->m_robin_bcval[amrlev]))[mfi].array(icomp*3);
923 rbc(i,j,k,0) = ra(i,j,k,icomp);
924 rbc(i,j,k,1) = rb(i,j,k,icomp);
925 rbc(i,j,k,2) = rf(i,j,k,icomp);
932 rbc(i,j,k,0) = ra(i,j,k,icomp);
933 rbc(i,j,k,1) = rb(i,j,k,icomp);
934 rbc(i,j,k,2) = rf(i,j,k,icomp);
943template <
typename MF>
950template <
typename MF>
957 const int ncomp = this->getNComp();
958 m_crse_sol_br[amrlev]->copyFrom(crse_bcdata, 0, 0, 0, ncomp,
959 this->m_geom[amrlev-1][0].periodicity());
960 m_bndry_sol[amrlev]->updateBndryValues(*m_crse_sol_br[amrlev], 0, 0, ncomp,
961 this->AMRRefRatioVect(amrlev-1),
963 m_interpbndry_halfwidth);
966template <
typename MF>
972 const int ncomp = this->getNComp();
973 m_crse_cor_br[amrlev]->copyFrom(crse_bcdata, 0, 0, 0, ncomp,
974 this->m_geom[amrlev-1][0].periodicity());
975 m_bndry_cor[amrlev]->updateBndryValues(*m_crse_cor_br[amrlev], 0, 0, ncomp,
976 this->AMRRefRatioVect(amrlev-1),
978 m_interpbndry_halfwidth);
981template <
typename MF>
988 BL_ASSERT(mglev == 0 || bc_mode == BCMode::Homogeneous);
989 BL_ASSERT(bndry !=
nullptr || bc_mode == BCMode::Homogeneous);
991 const int ncomp = this->getNComp();
992 const int cross = isCrossStencil();
993 const int tensorop = isTensorOp();
994 if (!skip_fillboundary) {
995 in.FillBoundary(0, ncomp, this->m_geom[amrlev][mglev].periodicity(), cross);
998 int flagbc = bc_mode == BCMode::Inhomogeneous;
999 const int imaxorder = this->maxorder;
1001 const Real* dxinv = this->m_geom[amrlev][mglev].InvCellSize();
1002 const RT dxi =
static_cast<RT>(dxinv[0]);
1003 const RT dyi = (AMREX_SPACEDIM >= 2) ?
static_cast<RT>(dxinv[1]) :
RT(1.0);
1004 const RT dzi = (AMREX_SPACEDIM == 3) ?
static_cast<RT>(dxinv[2]) :
RT(1.0);
1006 const auto& maskvals = m_maskvals[amrlev][mglev];
1007 const auto& bcondloc = *m_bcondloc[amrlev][mglev];
1010 const auto& foo = foofab.const_array();
1016 "non-cross stencil not support for gpu");
1018 const int hidden_direction = this->hiddenDirection();
1023 if (! m_bc_tags[amrlev][mglev].is_defined()) {
1025 tags.reserve(in.local_size()*2*AMREX_SPACEDIM*ncomp);
1027 const Box& vbx = mfi.validbox();
1028 const auto & bdlv = bcondloc.bndryLocs(mfi);
1029 const auto & bdcv = bcondloc.bndryConds(mfi);
1031 const int local_index = mfi.LocalIndex();
1033 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
1034 if (idim != hidden_direction) {
1037 for (
int icomp = 0; icomp < ncomp; ++icomp) {
1039 maskvals[olo].const_array(mfi),
1042 bdcv[icomp][olo], vbx.
length(idim),
1043 icomp, olo, local_index
1046 maskvals[ohi].const_array(mfi),
1049 bdcv[icomp][ohi], vbx.
length(idim),
1050 icomp, ohi, local_index
1056 m_bc_tags[amrlev][mglev].define(tags);
1063 bndry_arrays[ori] = (bndry !=
nullptr) ?
1067 auto inma = in.arrays();
1071 const auto& bcval = bndry_arrays[tag.face][tag.local_index];
1072 const int side = tag.face.faceDir();
1073 if (tag.face.coordDir() == 0) {
1074 mllinop_apply_bc_x(side, i, j, k, tag.blen, inma[tag.local_index],
1075 tag.mask, tag.bctype, tag.bcloc, bcval,
1076 imaxorder, dxi, flagbc, tag.comp);
1078#if (AMREX_SPACEDIM > 1)
1080#
if (AMREX_SPACEDIM > 2)
1081 if (tag.face.coordDir() == 1)
1084 mllinop_apply_bc_y(side, i, j, k, tag.blen, inma[tag.local_index],
1085 tag.mask, tag.bctype, tag.bcloc, bcval,
1086 imaxorder, dyi, flagbc, tag.comp);
1088#if (AMREX_SPACEDIM > 2)
1090 mllinop_apply_bc_z(side, i, j, k, tag.blen, inma[tag.local_index],
1091 tag.mask, tag.bctype, tag.bcloc, bcval,
1092 imaxorder, dzi, flagbc, tag.comp);
1099 if (cross || tensorop)
1102#pragma omp parallel if (Gpu::notInLaunchRegion())
1106 const Box& vbx = mfi.validbox();
1107 const auto& iofab = in.array(mfi);
1109 const auto & bdlv = bcondloc.bndryLocs(mfi);
1110 const auto & bdcv = bcondloc.bndryConds(mfi);
1112 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
1114 if (hidden_direction == idim) {
continue; }
1119 const int blen = vbx.
length(idim);
1120 const auto& mlo = maskvals[olo].array(mfi);
1121 const auto& mhi = maskvals[ohi].array(mfi);
1122 const auto& bvlo = (bndry !=
nullptr) ? bndry->
bndryValues(olo).const_array(mfi) : foo;
1123 const auto& bvhi = (bndry !=
nullptr) ? bndry->
bndryValues(ohi).const_array(mfi) : foo;
1124 for (
int icomp = 0; icomp < ncomp; ++icomp) {
1125 const BoundCond bctlo = bdcv[icomp][olo];
1126 const BoundCond bcthi = bdcv[icomp][ohi];
1127 const RT bcllo = bdlv[icomp][olo];
1128 const RT bclhi = bdlv[icomp][ohi];
1130 mllinop_apply_bc_x(0, blo, blen, iofab, mlo,
1132 imaxorder, dxi, flagbc, icomp);
1133 mllinop_apply_bc_x(1, bhi, blen, iofab, mhi,
1135 imaxorder, dxi, flagbc, icomp);
1136 }
else if (idim == 1) {
1137 mllinop_apply_bc_y(0, blo, blen, iofab, mlo,
1139 imaxorder, dyi, flagbc, icomp);
1140 mllinop_apply_bc_y(1, bhi, blen, iofab, mhi,
1142 imaxorder, dyi, flagbc, icomp);
1144 mllinop_apply_bc_z(0, blo, blen, iofab, mlo,
1146 imaxorder, dzi, flagbc, icomp);
1147 mllinop_apply_bc_z(1, bhi, blen, iofab, mhi,
1149 imaxorder, dzi, flagbc, icomp);
1158 amrex::Abort(
"amrex_mllinop_apply_bc not available when BL_NO_FORT=TRUE");
1160 if constexpr (std::is_same_v<Real,RT>) {
1166 const Box& vbx = mfi.validbox();
1168 const auto & bdlv = bcondloc.bndryLocs(mfi);
1169 const auto & bdcv = bcondloc.bndryConds(mfi);
1172 const BCTuple & bdc = bdcv[0];
1182 const auto& fsfab = (bndry !=
nullptr) ? bndry->
bndryValues(ori)[mfi] : foofab;
1184 const Mask& m = maskvals[ori][mfi];
1191 imaxorder, dxinv, flagbc, ncomp, cross);
1201template <
typename MF>
1205 const Box& dombx = this->m_geom[0].back().Domain();
1207 const BoxArray& old_ba = this->m_grids[0].back();
1208 const int N = old_ba.
size();
1211 for (
int i = 0; i < N; ++i)
1222#if (AMREX_SPACEDIM == 3)
1223 for (
int kk = 0; kk < nblks[2]; ++kk) {
1225#if (AMREX_SPACEDIM >= 2)
1226 for (
int jj = 0; jj < nblks[1]; ++jj) {
1228 for (
int ii = 0; ii < nblks[0]; ++ii)
1235#if (AMREX_SPACEDIM >= 2)
1238#if (AMREX_SPACEDIM == 3)
1243 std::sort(bv.begin(), bv.end());
1244 bv.erase(std::unique(bv.begin(), bv.end()), bv.end());
1251template <
typename MF>
1255 const int ncomp = this->getNComp();
1256 IntVect ratio = (amrlev > 0) ?
IntVect(2) : this->mg_coarsen_ratio_vec[cmglev-1];
1259 if (this->hasHiddenDimension()) { ratio[this->hiddenDirection()] = 1; }
1263template <
typename MF>
1267 const int ncomp = this->getNComp();
1269 Dim3 ratio3 = {.
x = 2, .y = 2, .z = 2};
1270 IntVect ratio = (amrlev > 0) ?
IntVect(2) : this->mg_coarsen_ratio_vec[fmglev];
1271 if (this->hasHiddenDimension()) { ratio[this->hiddenDirection()] = 1; }
1273 ratio3.
y = ratio[1];,
1274 ratio3.
z = ratio[2];);
1278 auto const& finema =
fine.arrays();
1279 auto const& crsema =
crse.const_arrays();
1286 finema[box_no](i,j,k,n) += crsema[box_no](ic,jc,kc,n);
1295#pragma omp parallel if (Gpu::notInLaunchRegion())
1299 const Box& bx = mfi.tilebox();
1307 ffab(i,j,k,n) += cfab(ic,jc,kc,n);
1313template <
typename MF>
1317 const int ncomp = this->getNComp();
1319 const Geometry& crse_geom = this->Geom(amrlev,fmglev+1);
1320 IntVect refratio = (amrlev > 0) ?
IntVect(2) : this->mg_coarsen_ratio_vec[fmglev];
1321 if (this->hasHiddenDimension()) { refratio[this->hiddenDirection()] = 1; }
1337 cfine.setVal(
RT(0.0));
1342 bool isEB =
fine.hasEBFabFactory();
1353#pragma omp parallel if (Gpu::notInLaunchRegion())
1357 const Box& bx = mfi.tilebox();
1358 const auto& ff =
fine.array(mfi);
1359 const auto& cc = cmf->array(mfi);
1364 const auto& flag = (*flags)[mfi];
1371 mlmg_eb_cc_interp_r<2>(tbx, ff, cc, flg, ncomp);
1382 const bool call_lincc =
true;
1386#if (AMREX_SPACEDIM == 3)
1387 if (this->hasHiddenDimension()) {
1388 Box const& bx_2d = this->compactify(bx);
1389 auto const& ff_2d = this->compactify(ff);
1390 auto const& cc_2d = this->compactify(cc);
1393 TwoD::mlmg_lin_cc_interp_r2(tbx, ff_2d, cc_2d, ncomp);
1400 mlmg_lin_cc_interp_r2(tbx, ff, cc, ncomp);
1407template <
typename MF>
1412 const int ncomp = this->getNComp();
1413 const IntVect refratioV = this->AMRRefRatioVect(famrlev-1);
1416 const int refratio = refratioV.
max();
1419 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(famrlev));
1426#pragma omp parallel if (Gpu::notInLaunchRegion())
1430 const Box& bx = mfi.tilebox();
1431 auto const& ff =
fine.array(mfi);
1432 auto const& cc =
crse.const_array(mfi);
1437 const auto& flag = (*flags)[mfi];
1447 mlmg_eb_cc_interp_r<2>(tbx, ff, cc, flg, ncomp);
1455 mlmg_eb_cc_interp_r<4>(tbx, ff, cc, flg, ncomp);
1460 amrex::Abort(
"mlmg_eb_cc_interp: only refratio 2 and 4 are supported");
1471 const bool call_lincc =
true;
1475#if (AMREX_SPACEDIM == 3)
1476 if (this->hasHiddenDimension()) {
1477 Box const& bx_2d = this->compactify(bx);
1478 auto const& ff_2d = this->compactify(ff);
1479 auto const& cc_2d = this->compactify(cc);
1485 TwoD::mlmg_lin_cc_interp_r2(tbx, ff_2d, cc_2d, ncomp);
1493 TwoD::mlmg_lin_cc_interp_r4(tbx, ff_2d, cc_2d, ncomp);
1498 amrex::Abort(
"mlmg_lin_cc_interp: only refratio 2 and 4 are supported");
1508 mlmg_lin_cc_interp_r2(tbx, ff, cc, ncomp);
1516 mlmg_lin_cc_interp_r4(tbx, ff, cc, ncomp);
1521 amrex::Abort(
"mlmg_lin_cc_interp: only refratio 2 and 4 are supported");
1528template <
typename MF>
1531 const MF& fine_sol,
const MF& fine_rhs)
1533 const auto amrrr = this->AMRRefRatioVect(camrlev);
1534 const int ncomp = this->getNComp();
1539template <
typename MF>
1545 applyBC(amrlev, mglev, in, bc_mode, s_mode, bndry);
1546 Fapply(amrlev, mglev, out, in);
1549template <
typename MF>
1552 bool skip_fillboundary,
int niter)
const
1555 for (
int i = 0; i < niter; ++i) {
1556 for (
int redblack = 0; redblack < 2; ++redblack)
1558 applyBC(amrlev, mglev, sol, BCMode::Homogeneous, StateMode::Solution,
1559 nullptr, skip_fillboundary);
1560 Fsmooth(amrlev, mglev, sol, rhs, redblack);
1561 skip_fillboundary =
false;
1566template <
typename MF>
1569 const MF* crse_bcdata)
1571 BL_PROFILE(
"MLCellLinOp::solutionResidual()");
1572 const int ncomp = this->getNComp();
1573 if (crse_bcdata !=
nullptr) {
1574 updateSolBC(amrlev, *crse_bcdata);
1576 const int mglev = 0;
1577 apply(amrlev, mglev, resid,
x, BCMode::Inhomogeneous, StateMode::Solution,
1578 m_bndry_sol[amrlev].
get());
1581 MF::Xpay(resid,
RT(-1.0), b, 0, 0, ncomp,
IntVect(0));
1584template <
typename MF>
1588 if (crse_bcdata !=
nullptr) {
1589 updateSolBC(amrlev, *crse_bcdata);
1593template <
typename MF>
1596 BCMode bc_mode,
const MF* crse_bcdata)
1598 BL_PROFILE(
"MLCellLinOp::correctionResidual()");
1599 const int ncomp = this->getNComp();
1600 if (bc_mode == BCMode::Inhomogeneous)
1605 updateCorBC(amrlev, *crse_bcdata);
1607 apply(amrlev, mglev, resid,
x, BCMode::Inhomogeneous, StateMode::Correction,
1608 m_bndry_cor[amrlev].
get());
1613 apply(amrlev, mglev, resid,
x, BCMode::Homogeneous, StateMode::Correction,
nullptr);
1616 MF::Xpay(resid,
Real(-1.0), b, 0, 0, ncomp,
IntVect(0));
1619template <
typename MF>
1622 MF&, MF& fine_sol,
const MF&)
const
1626 auto& fluxreg = m_fluxreg[crse_amrlev];
1629 const int ncomp = this->getNComp();
1631 const int fine_amrlev = crse_amrlev+1;
1634 const Real* crse_dx = this->m_geom[crse_amrlev][0].CellSize();
1635 const Real* fine_dx = this->m_geom[fine_amrlev][0].CellSize();
1637 const int mglev = 0;
1638 applyBC(fine_amrlev, mglev, fine_sol, BCMode::Inhomogeneous, StateMode::Solution,
1639 m_bndry_sol[fine_amrlev].
get());
1645#pragma omp parallel if (Gpu::notInLaunchRegion())
1654 if (fluxreg.CrseHasWork(mfi))
1656 const Box& tbx = mfi.tilebox();
1660 FFlux(crse_amrlev, mfi, pflux, crse_sol[mfi], Location::FaceCentroid);
1661 fluxreg.CrseAdd(mfi, cpflux, crse_dx, dt,
RunOn::Gpu);
1671 if (fluxreg.FineHasWork(mfi))
1673 const Box& tbx = mfi.tilebox();
1674 const int face_only =
true;
1678 FFlux(fine_amrlev, mfi, pflux, fine_sol[mfi], Location::FaceCentroid, face_only);
1679 fluxreg.FineAdd(mfi, cpflux, fine_dx, dt,
RunOn::Gpu);
1684 fluxreg.Reflux(res);
1685 this->applyOverset(crse_amrlev, res);
1688template <
typename MF>
1695 const int mglev = 0;
1696 const int ncomp = this->getNComp();
1697 applyBC(amrlev, mglev, sol, BCMode::Inhomogeneous, StateMode::Solution,
1698 m_bndry_sol[amrlev].
get());
1704#pragma omp parallel if (Gpu::notInLaunchRegion())
1711 const Box& tbx = mfi.tilebox();
1715 FFlux(amrlev, mfi, pflux, sol[mfi], loc);
1716 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
1717 const Box& nbx = mfi.nodaltilebox(idim);
1718 auto const& dst = fluxes[idim]->array(mfi);
1719 auto const& src = pflux[idim]->const_array();
1722 dst(i,j,k,n) = src(i,j,k,n);
1729template <
typename MF>
1736 if (sol.nComp() > 1) {
1737 amrex::Abort(
"MLCellLinOp::compGrad called, but only works for single-component solves");
1740 const int mglev = 0;
1741 applyBC(amrlev, mglev, sol, BCMode::Inhomogeneous, StateMode::Solution,
1742 m_bndry_sol[amrlev].
get());
1744 const int ncomp = this->getNComp();
1746 AMREX_D_TERM(
const RT dxi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0));,
1747 const RT dyi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(1));,
1748 const RT dzi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(2)););
1750#pragma omp parallel if (Gpu::notInLaunchRegion())
1755 const Box& ybx = mfi.nodaltilebox(1);,
1756 const Box& zbx = mfi.nodaltilebox(2););
1757 const auto& s = sol.array(mfi);
1759 const auto& gy = grad[1]->array(mfi);,
1760 const auto& gz = grad[2]->array(mfi););
1764 gx(i,j,k,n) = dxi*(s(i,j,k,n) - s(i-1,j,k,n));
1766#if (AMREX_SPACEDIM >= 2)
1769 gy(i,j,k,n) = dyi*(s(i,j,k,n) - s(i,j-1,k,n));
1772#if (AMREX_SPACEDIM == 3)
1775 gz(i,j,k,n) = dzi*(s(i,j,k,n) - s(i,j,k-1,n));
1780 addInhomogNeumannFlux(amrlev, grad, sol,
false);
1783template <
typename MF>
1788#if (AMREX_SPACEDIM != 3)
1789 if (!m_has_metric_term) {
return; }
1791 const int ncomp = rhs.nComp();
1793 bool cc = rhs.ixType().cellCentered(0);
1795 const Geometry& geom = this->m_geom[amrlev][mglev];
1797 const RT probxlo =
static_cast<RT>(geom.
ProbLo(0));
1800#pragma omp parallel if (Gpu::notInLaunchRegion())
1804 const Box& tbx = mfi.tilebox();
1805 auto const& rhsarr = rhs.array(mfi);
1806#if (AMREX_SPACEDIM == 1)
1810 RT rc = probxlo + (
RT(i)+
RT(0.5))*dx;
1811 rhsarr(i,j,k,n) *= rc*rc;
1816 RT re = probxlo +
RT(i)*dx;
1817 rhsarr(i,j,k,n) *= re*re;
1820#elif (AMREX_SPACEDIM == 2)
1824 RT rc = probxlo + (
RT(i)+
RT(0.5))*dx;
1825 rhsarr(i,j,k,n) *= rc;
1830 RT re = probxlo +
RT(i)*dx;
1831 rhsarr(i,j,k,n) *= re;
1839template <
typename MF>
1844#if (AMREX_SPACEDIM != 3)
1845 if (!m_has_metric_term) {
return; }
1847 const int ncomp = rhs.nComp();
1849 bool cc = rhs.ixType().cellCentered(0);
1851 const Geometry& geom = this->m_geom[amrlev][mglev];
1853 const RT probxlo =
static_cast<RT>(geom.
ProbLo(0));
1856#pragma omp parallel if (Gpu::notInLaunchRegion())
1860 const Box& tbx = mfi.tilebox();
1861 auto const& rhsarr = rhs.array(mfi);
1862#if (AMREX_SPACEDIM == 1)
1866 RT rcinv =
RT(1.0)/(probxlo + (
RT(i)+
RT(0.5))*dx);
1867 rhsarr(i,j,k,n) *= rcinv*rcinv;
1872 RT re = probxlo +
RT(i)*dx;
1873 RT reinv = (re==
RT(0.0)) ?
RT(0.0) :
RT(1.)/re;
1874 rhsarr(i,j,k,n) *= reinv*reinv;
1877#elif (AMREX_SPACEDIM == 2)
1881 RT rcinv =
RT(1.0)/(probxlo + (
RT(i)+
RT(0.5))*dx);
1882 rhsarr(i,j,k,n) *= rcinv;
1887 RT re = probxlo +
RT(i)*dx;
1888 RT reinv = (re==
RT(0.0)) ?
RT(0.0) :
RT(1.)/re;
1889 rhsarr(i,j,k,n) *= reinv;
1897template <
typename MF>
1904 const int ncomp = this->getNComp();
1908 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(amrlev,mglev));
1909 if (factory && !factory->isAllRegular())
1911 if constexpr (std::is_same<MF,MultiFab>()) {
1913 for (
int c = 0; c < ncomp; ++c) {
1915 * m_volinv[amrlev][mglev];
1918 amrex::Abort(
"TODO: MLMG with EB only works with MultiFab");
1924 for (
int c = 0; c < ncomp; ++c) {
1925 offset[c] = rhs.sum(c,
IntVect(0),
true) * m_volinv[amrlev][mglev];
1934template <
typename MF>
1939 const int ncomp = this->getNComp();
1940 for (
int c = 0; c < ncomp; ++c) {
1941 rhs.plus(-
offset[c], c, 1);
1944 if (!rhs.isAllRegular()) {
1945 if constexpr (std::is_same<MF,MultiFab>()) {
1948 amrex::Abort(
"amrex::EB_set_covered only works with MultiFab");
1954template <
typename MF>
1958 BL_PROFILE(
"MLCellLinOp::prepareForSolve()");
1960 const int imaxorder = this->maxorder;
1961 const int ncomp = this->getNComp();
1962 const int hidden_direction = this->hiddenDirection();
1963 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
1965 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
1967 const auto& bcondloc = *m_bcondloc[amrlev][mglev];
1968 const auto& maskvals = m_maskvals[amrlev][mglev];
1970 const RT dxi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0));
1971 const RT dyi =
static_cast<RT>((AMREX_SPACEDIM >= 2) ? this->m_geom[amrlev][mglev].InvCellSize(1) :
Real(1.0));
1972 const RT dzi =
static_cast<RT>((AMREX_SPACEDIM == 3) ? this->m_geom[amrlev][mglev].InvCellSize(2) :
Real(1.0));
1974 auto& undrrelxr = this->m_undrrelxr[amrlev][mglev];
1975 MF foo(this->m_grids[amrlev][mglev], this->m_dmap[amrlev][mglev], ncomp, 0,
MFInfo().SetAlloc(
false));
1978 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->m_factory[amrlev][mglev].get());
1980 (factory) ? &(factory->getMultiEBCellFlagFab()) :
nullptr;
1981 auto area = (factory) ? factory->getAreaFrac()
1989 if (factory && !factory->isAllRegular()) {
1990#if defined(AMREX_USE_CUDA) && defined(_WIN32)
1991 if (!std::is_same<MF,MultiFab>()) {
1993 if constexpr (!std::is_same<MF,MultiFab>()) {
1995 amrex::Abort(
"MLCellLinOp with EB only works with MultiFab");
1998 tags.reserve(foo.local_size()*AMREX_SPACEDIM*ncomp);
2002 const Box& vbx = mfi.validbox();
2004 const auto & bdlv = bcondloc.bndryLocs(mfi);
2005 const auto & bdcv = bcondloc.bndryConds(mfi);
2009 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
2016 for (
int icomp = 0; icomp < ncomp; ++icomp) {
2017 tags.emplace_back(MLMGPSEBTag<RT>{undrrelxr[olo].array(mfi),
2018 undrrelxr[ohi].array(mfi),
2020 maskvals[olo].const_array(mfi),
2021 maskvals[ohi].const_array(mfi),
2022 bdlv[icomp][olo], bdlv[icomp][ohi],
2024 bdcv[icomp][olo], bdcv[icomp][ohi],
2025 vbx.
length(idim), icomp, idim});
2032 [=]
AMREX_GPU_DEVICE (
int i,
int j,
int k, MLMGPSEBTag<RT>
const& tag)
noexcept
2037 mllinop_comp_interp_coef0_x_eb
2038 (0, i , j, k, tag.blen, tag.flo, tag.mlo, tag.ap,
2039 tag.bctlo, tag.bcllo, imaxorder, dxi, tag.comp);
2040 mllinop_comp_interp_coef0_x_eb
2041 (1, i+tag.blen+1, j, k, tag.blen, tag.fhi, tag.mhi, tag.ap,
2042 tag.bcthi, tag.bclhi, imaxorder, dxi, tag.comp);
2044#if (AMREX_SPACEDIM > 1)
2046#
if (AMREX_SPACEDIM > 2)
2050 mllinop_comp_interp_coef0_y_eb
2051 (0, i, j , k, tag.blen, tag.flo, tag.mlo, tag.ap,
2052 tag.bctlo, tag.bcllo, imaxorder, dyi, tag.comp);
2053 mllinop_comp_interp_coef0_y_eb
2054 (1, i, j+tag.blen+1, k, tag.blen, tag.fhi, tag.mhi, tag.ap,
2055 tag.bcthi, tag.bclhi, imaxorder, dyi, tag.comp);
2057#if (AMREX_SPACEDIM > 2)
2059 mllinop_comp_interp_coef0_z_eb
2060 (0, i, j, k , tag.blen, tag.flo, tag.mlo, tag.ap,
2061 tag.bctlo, tag.bcllo, imaxorder, dzi, tag.comp);
2062 mllinop_comp_interp_coef0_z_eb
2063 (1, i, j, k+tag.blen+1, tag.blen, tag.fhi, tag.mhi, tag.ap,
2064 tag.bcthi, tag.bclhi, imaxorder, dzi, tag.comp);
2071 mllinop_comp_interp_coef0_x
2072 (0, i , j, k, tag.blen, tag.flo, tag.mlo,
2073 tag.bctlo, tag.bcllo, imaxorder, dxi, tag.comp);
2074 mllinop_comp_interp_coef0_x
2075 (1, i+tag.blen+1, j, k, tag.blen, tag.fhi, tag.mhi,
2076 tag.bcthi, tag.bclhi, imaxorder, dxi, tag.comp);
2078#if (AMREX_SPACEDIM > 1)
2080#if (AMREX_SPACEDIM > 2)
2084 mllinop_comp_interp_coef0_y
2085 (0, i, j , k, tag.blen, tag.flo, tag.mlo,
2086 tag.bctlo, tag.bcllo, imaxorder, dyi, tag.comp);
2087 mllinop_comp_interp_coef0_y
2088 (1, i, j+tag.blen+1, k, tag.blen, tag.fhi, tag.mhi,
2089 tag.bcthi, tag.bclhi, imaxorder, dyi, tag.comp);
2091#if (AMREX_SPACEDIM > 2)
2093 mllinop_comp_interp_coef0_z
2094 (0, i, j, k , tag.blen, tag.flo, tag.mlo,
2095 tag.bctlo, tag.bcllo, imaxorder, dzi, tag.comp);
2096 mllinop_comp_interp_coef0_z
2097 (1, i, j, k+tag.blen+1, tag.blen, tag.fhi, tag.mhi,
2098 tag.bcthi, tag.bclhi, imaxorder, dzi, tag.comp);
2109 tags.reserve(foo.local_size()*AMREX_SPACEDIM*ncomp);
2113 const Box& vbx = mfi.validbox();
2115 const auto & bdlv = bcondloc.bndryLocs(mfi);
2116 const auto & bdcv = bcondloc.bndryConds(mfi);
2118 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
2120 if (idim != hidden_direction) {
2123 for (
int icomp = 0; icomp < ncomp; ++icomp) {
2124 tags.emplace_back(MLMGPSTag<RT>{undrrelxr[olo].array(mfi),
2125 undrrelxr[ohi].array(mfi),
2126 maskvals[olo].const_array(mfi),
2127 maskvals[ohi].const_array(mfi),
2128 bdlv[icomp][olo], bdlv[icomp][ohi],
2130 bdcv[icomp][olo], bdcv[icomp][ohi],
2131 vbx.
length(idim), icomp, idim});
2138 [=]
AMREX_GPU_DEVICE (
int i,
int j,
int k, MLMGPSTag<RT>
const& tag)
noexcept
2142 mllinop_comp_interp_coef0_x
2143 (0, i , j, k, tag.blen, tag.flo, tag.mlo,
2144 tag.bctlo, tag.bcllo, imaxorder, dxi, tag.comp);
2145 mllinop_comp_interp_coef0_x
2146 (1, i+tag.blen+1, j, k, tag.blen, tag.fhi, tag.mhi,
2147 tag.bcthi, tag.bclhi, imaxorder, dxi, tag.comp);
2149#if (AMREX_SPACEDIM > 1)
2151#
if (AMREX_SPACEDIM > 2)
2155 mllinop_comp_interp_coef0_y
2156 (0, i, j , k, tag.blen, tag.flo, tag.mlo,
2157 tag.bctlo, tag.bcllo, imaxorder, dyi, tag.comp);
2158 mllinop_comp_interp_coef0_y
2159 (1, i, j+tag.blen+1, k, tag.blen, tag.fhi, tag.mhi,
2160 tag.bcthi, tag.bclhi, imaxorder, dyi, tag.comp);
2162#if (AMREX_SPACEDIM > 2)
2164 mllinop_comp_interp_coef0_z
2165 (0, i, j, k , tag.blen, tag.flo, tag.mlo,
2166 tag.bctlo, tag.bcllo, imaxorder, dzi, tag.comp);
2167 mllinop_comp_interp_coef0_z
2168 (1, i, j, k+tag.blen+1, tag.blen, tag.fhi, tag.mhi,
2169 tag.bcthi, tag.bclhi, imaxorder, dzi, tag.comp);
2183 const Box& vbx = mfi.validbox();
2185 const auto & bdlv = bcondloc.bndryLocs(mfi);
2186 const auto & bdcv = bcondloc.bndryConds(mfi);
2191 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
2193 if (idim == hidden_direction) {
continue; }
2198 const int blen = vbx.
length(idim);
2199 const auto& mlo = maskvals[olo].array(mfi);
2200 const auto& mhi = maskvals[ohi].array(mfi);
2201 const auto& flo = undrrelxr[olo].array(mfi);
2202 const auto& fhi = undrrelxr[ohi].array(mfi);
2203 for (
int icomp = 0; icomp < ncomp; ++icomp) {
2204 const BoundCond bctlo = bdcv[icomp][olo];
2205 const BoundCond bcthi = bdcv[icomp][ohi];
2206 const auto bcllo = bdlv[icomp][olo];
2207 const auto bclhi = bdlv[icomp][ohi];
2210 if constexpr (!std::is_same<MF,MultiFab>()) {
2211 amrex::Abort(
"MLCellLinOp with EB only works with MultiFab");
2213 auto const& ap = area[idim]->const_array(mfi);
2215 mllinop_comp_interp_coef0_x_eb
2216 (0, blo, blen, flo, mlo, ap, bctlo, bcllo,
2217 imaxorder, dxi, icomp);
2218 mllinop_comp_interp_coef0_x_eb
2219 (1, bhi, blen, fhi, mhi, ap, bcthi, bclhi,
2220 imaxorder, dxi, icomp);
2221 }
else if (idim == 1) {
2222 mllinop_comp_interp_coef0_y_eb
2223 (0, blo, blen, flo, mlo, ap, bctlo, bcllo,
2224 imaxorder, dyi, icomp);
2225 mllinop_comp_interp_coef0_y_eb
2226 (1, bhi, blen, fhi, mhi, ap, bcthi, bclhi,
2227 imaxorder, dyi, icomp);
2229 mllinop_comp_interp_coef0_z_eb
2230 (0, blo, blen, flo, mlo, ap, bctlo, bcllo,
2231 imaxorder, dzi, icomp);
2232 mllinop_comp_interp_coef0_z_eb
2233 (1, bhi, blen, fhi, mhi, ap, bcthi, bclhi,
2234 imaxorder, dzi, icomp);
2241 mllinop_comp_interp_coef0_x
2242 (0, blo, blen, flo, mlo, bctlo, bcllo,
2243 imaxorder, dxi, icomp);
2244 mllinop_comp_interp_coef0_x
2245 (1, bhi, blen, fhi, mhi, bcthi, bclhi,
2246 imaxorder, dxi, icomp);
2247 }
else if (idim == 1) {
2248 mllinop_comp_interp_coef0_y
2249 (0, blo, blen, flo, mlo, bctlo, bcllo,
2250 imaxorder, dyi, icomp);
2251 mllinop_comp_interp_coef0_y
2252 (1, bhi, blen, fhi, mhi, bcthi, bclhi,
2253 imaxorder, dyi, icomp);
2255 mllinop_comp_interp_coef0_z
2256 (0, blo, blen, flo, mlo, bctlo, bcllo,
2257 imaxorder, dzi, icomp);
2258 mllinop_comp_interp_coef0_z
2259 (1, bhi, blen, fhi, mhi, bcthi, bclhi,
2260 imaxorder, dzi, icomp);
2271template <
typename MF>
2276 const int ncomp = this->getNComp();
2285template <
typename MF>
2289 const int ncomp = this->getNComp();
2292 for (
int ilev = 0; ilev < this->NAMRLevels()-1; ++ilev) {
2293 result +=
amrex::Dot(*m_norm_fine_mask[ilev], *
x[ilev], 0, *
y[ilev], 0, ncomp, nghost,
true);
2296 *
y[this->NAMRLevels()-1], 0, ncomp, nghost,
true);
2301template <
typename MF>
2305 const int ncomp = this->getNComp();
2308 for (
int ilev = 0; ilev < this->NAMRLevels()-1; ++ilev) {
2309 result +=
amrex::Dot(*m_norm_fine_mask[ilev], *
x[ilev], 0, ncomp, nghost,
true);
2311 result +=
amrex::Dot(*
x[this->NAMRLevels()-1], 0, ncomp, nghost,
true);
2313 return std::sqrt(result);
2316template <
typename MF>
2320 if (!m_volinv.empty()) {
return; }
2322 m_volinv.resize(this->m_num_amr_levels);
2323 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
2324 m_volinv[amrlev].resize(this->NMGLevels(amrlev));
2329 auto f = [&] (
int amrlev,
int mglev) {
2331 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(amrlev,mglev));
2332 if (factory && !factory->isAllRegular())
2334 if constexpr (std::is_same<MF,MultiFab>()) {
2335 const auto&
vfrac = factory->getVolFrac();
2336 m_volinv[amrlev][mglev] =
vfrac.sum(0,
true);
2338 amrex::Abort(
"MLCellLinOp with EB only works with MultiFab");
2345 ? this->compactify(this->Geom(amrlev,mglev).Domain()).d_numPts()
2346 : this->m_grids[amrlev][mglev].d_numPts();
2348 m_volinv[amrlev][mglev] = RT(1.0 / npts);
2355 int mgbottom = this->NMGLevels(0)-1;
2360 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(0,0));
2361 if (factory && !factory->isAllRegular())
2363 ParallelAllReduce::Sum<RT>({m_volinv[0][0], m_volinv[0][mgbottom]},
2365 temp1 = RT(1.0)/m_volinv[0][0];
2366 temp2 = RT(1.0)/m_volinv[0][mgbottom];
2370 temp1 = m_volinv[0][0];
2371 temp2 = m_volinv[0][mgbottom];
2373 m_volinv[0][0] = temp1;
2374 m_volinv[0][mgbottom] = temp2;
2378template <
typename MF>
2382 const int ncomp = this->getNComp();
2383 const int finest_level = this->NAMRLevels() - 1;
2386 const auto *factory =
dynamic_cast<EBFArrayBoxFactory const*
>(this->Factory(amrlev));
2387 if (factory && !factory->isAllRegular()) {
2388#if defined(AMREX_USE_CUDA) && defined(_WIN32)
2389 if (!std::is_same<MF,MultiFab>()) {
2391 if constexpr (!std::is_same<MF,MultiFab>()) {
2393 amrex::Abort(
"MLCellLinOpT with EB only works with MultiFab");
2396 if (amrlev == finest_level) {
2400 auto const& vfrac_ma =
vfrac.const_arrays();
2406 return std::abs(ma[box_no](i,j,k,n)
2407 *vfrac_ma[box_no](i,j,k));
2413#pragma omp parallel reduction(max:norm)
2416 Box const& bx = mfi.tilebox();
2417 auto const& fab = mf.const_array(mfi);
2418 auto const& v =
vfrac.const_array(mfi);
2421 norm = std::max(
norm, std::abs(fab(i,j,k,n)*v(i,j,k)));
2428 auto const& ma = mf.const_arrays();
2429 auto const& mask_ma = m_norm_fine_mask[amrlev]->const_arrays();
2430 auto const& vfrac_ma =
vfrac.const_arrays();
2436 if (mask_ma[box_no](i,j,k)) {
2437 return std::abs(ma[box_no](i,j,k,n)
2438 *vfrac_ma[box_no](i,j,k));
2447#pragma omp parallel reduction(max:norm)
2450 Box const& bx = mfi.tilebox();
2451 auto const& fab = mf.const_array(mfi);
2452 auto const&
mask = m_norm_fine_mask[amrlev]->const_array(mfi);
2453 auto const& v =
vfrac.const_array(mfi);
2457 norm = std::max(
norm, std::abs(fab(i,j,k,n)*v(i,j,k)));
2467 if (amrlev == finest_level) {
2470 norm = mf.norminf(*m_norm_fine_mask[amrlev], 0, ncomp,
IntVect(0),
true);
2478template <
typename MF>
2482 int ncomp = this->getNComp();
2483 for (
int falev = this->NAMRLevels()-1; falev > 0; --falev)
2486 if (!sol[falev].isAllRegular()) {
2487 if constexpr (std::is_same<MF,MultiFab>()) {
2490 amrex::Abort(
"EB_average_down only works with MultiFab");
2500template <
typename MF>
2505 if (!fres.isAllRegular()) {
2506 if constexpr (std::is_same<MF,MultiFab>()) {
2508 this->AMRRefRatioVect(clev));
2510 amrex::Abort(
"EB_average_down only works with MultiFab");
2516 this->AMRRefRatioVect(clev));
2520template <
typename MF>
2524 this->m_precond_mode =
true;
2526 if (m_bndry_sol_zero.empty()) {
2527 m_bndry_sol_zero.resize(m_bndry_sol.size());
2528 const int ncomp = this->getNComp();
2529 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
2530 m_bndry_sol_zero[amrlev] = std::make_unique<MLMGBndryT<MF>>
2531 (this->m_grids[amrlev][0],
2532 this->m_dmap[amrlev][0],
2534 this->m_geom[amrlev][0]);
2536 std::swap(m_bndry_sol, m_bndry_sol_zero);
2537 MF
const* coarse_data_for_bc_save = this->m_coarse_data_for_bc;
2538 this->m_coarse_data_for_bc =
nullptr;
2539 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
2540 this->setLevelBC(amrlev,
nullptr);
2542 this->m_coarse_data_for_bc = coarse_data_for_bc_save;
2544 std::swap(m_bndry_sol, m_bndry_sol_zero);
2548template <
typename MF>
2552 this->m_precond_mode =
false;
2553 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:562
#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:124
#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:1131
Box cbx
Definition AMReX_HypreMLABecLap.cpp:1133
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
Array4< Real const > vfrac
Definition AMReX_MLEBNodeFDLaplacian.cpp:1468
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
Yet-another flux register for refluxing.
const FabSetT< MF > & bndryValues(Orientation face) const noexcept
Access the boundary values stored on orientation face.
Definition AMReX_BndryData.H:93
Maintain an identifier for boundary condition types.
Definition AMReX_BoundCond.H:25
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:681
void define(const Box &bx)
Initialize the BoxArray from a single box.
Definition AMReX_BoxArray.cpp:352
BoxArray & coarsen(int refinement_ratio)
Coarsen each Box in the BoxArray by refinement_ratio.
Definition AMReX_BoxArray.cpp:685
Long size() const noexcept
Return the number of boxes in the BoxArray.
Definition AMReX_BoxArray.H:758
A list of Boxes sharing a common IndexType.
Definition AMReX_BoxList.H:109
__host__ __device__ BoxND & setBig(const IntVectND< dim > &bg) noexcept
Redefine the big end of the BoxND.
Definition AMReX_Box.H:516
__host__ __device__ IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:167
__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__ IntVectND< dim > size() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:160
__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:754
__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:730
__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:783
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Return the inclusive lower bound of the box.
Definition AMReX_Box.H:124
const Real * CellSize() const noexcept
Returns the cellsize for each coordinate direction.
Definition AMReX_CoordSys.H:79
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:51
Definition AMReX_EBFabFactory.H:32
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:356
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Read-only convenience wrapper equivalent to arrays() const.
Definition AMReX_FabArray.H:731
Abstract factory interface for creating, aliasing, and destroying FAB objects.
Definition AMReX_FabFactory.H:73
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:85
Periodicity periodicity() const noexcept
Return the Periodicity based on the length of the domain.
Definition AMReX_Geometry.H:424
const Real * ProbLo() const noexcept
Returns the lo end of the problem domain in each dimension.
Definition AMReX_Geometry.H:208
GPU-compatible tuple.
Definition AMReX_Tuple.H:104
__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:517
__host__ __device__ IntVectND & setVal(int i, int val) noexcept
Set i'th coordinate of IntVectND to val.
Definition AMReX_IntVect.H:373
__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:810
__host__ __device__ constexpr int max() const noexcept
maximum (no absolute values) value
Definition AMReX_IntVect.H:313
An InterpBndryData object adds to a BndryData object the ability to manipulate and set the data store...
Definition AMReX_InterpBndryData.H:45
static constexpr int IBD_max_order_DEF
Definition AMReX_InterpBndryData.H:126
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:88
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:176
Definition AMReX_MLCellLinOp.H:31
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
Compute the average offset needed to enforce solvability constraints.
Definition AMReX_MLCellLinOp.H:1899
void averageDownSolutionRHS(int camrlev, MF &crse_sol, MF &crse_rhs, const MF &fine_sol, const MF &fine_rhs) override
Average fine solution/RHS onto the next coarser AMR level.
Definition AMReX_MLCellLinOp.H:1530
void averageDownAndSync(Vector< MF > &sol) const override
Average the solution hierarchy down (fine-to-coarse) and sync.
Definition AMReX_MLCellLinOp.H:2480
BoxArray makeNGrids(int grid_size) const
Helper that builds a BoxArray for NSolve with boxes no larger than the requested grid_size.
Definition AMReX_MLCellLinOp.H:1203
Vector< YAFluxRegisterT< MF > > m_fluxreg
Definition AMReX_MLCellLinOp.H:496
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
Apply physical BCs (optionally skipping FillBoundary).
Definition AMReX_MLCellLinOp.H:983
void updateSolBC(int amrlev, const MF &crse_bcdata) const
Refresh stored solution BC data from coarse inputs.
Definition AMReX_MLCellLinOp.H:952
Vector< std::unique_ptr< MLMGBndryT< MF > > > m_bndry_sol
Definition AMReX_MLCellLinOp.H:436
MLCellLinOpT< MF > & operator=(const MLCellLinOpT< MF > &)=delete
void compGrad(int amrlev, const Array< MF *, 3 > &grad, MF &sol, Location loc) const override
Compute directional gradients of the solution.
Definition AMReX_MLCellLinOp.H:1731
void avgDownResAmr(int clev, MF &cres, MF const &fres) const override
Average a residual from a fine AMR level to its coarse parent.
Definition AMReX_MLCellLinOp.H:2502
void reflux(int crse_amrlev, MF &res, const MF &crse_sol, const MF &, MF &, MF &fine_sol, const MF &) const final
Reflux fine-level fluxes into the coarse residual.
Definition AMReX_MLCellLinOp.H:1621
RT dotProductPrecond(Vector< MF const * > const &x, Vector< MF const * > const &y) const final
Dot product over the composite AMR hierarchy, excluding cells covered by finer levels (used when the ...
Definition AMReX_MLCellLinOp.H:2287
virtual void Fapply(int amrlev, int mglev, MF &out, const MF &in) const =0
typename FabDataType< MF >::value_type RT
Definition AMReX_MLCellLinOp.H:35
void endPrecondBC() override
Called when the operator stops being used as a preconditioner.
Definition AMReX_MLCellLinOp.H:2550
void update() override
Update for reuse.
Definition AMReX_MLCellLinOp.H:945
void correctionResidual(int amrlev, int mglev, MF &resid, MF &x, const MF &b, BCMode bc_mode, const MF *crse_bcdata=nullptr) final
Compute the correction residual with optional coarse data.
Definition AMReX_MLCellLinOp.H:1595
MLCellLinOpT(const MLCellLinOpT< MF > &)=delete
typename MLLinOpT< MF >::BCMode BCMode
Definition AMReX_MLCellLinOp.H:38
void smooth(int amrlev, int mglev, MF &sol, const MF &rhs, bool skip_fillboundary, int niter) const final
Perform niter smoothing iterations on the supplied residual equation.
Definition AMReX_MLCellLinOp.H:1551
RT normInf(int amrlev, MF const &mf, bool local) const override
Infinity norm helper used by solvers and diagnostics.
Definition AMReX_MLCellLinOp.H:2380
virtual bool isCrossStencil() const
Whether the stencil is the cross shape.
Definition AMReX_MLCellLinOp.H:107
void updateCorBC(int amrlev, const MF &crse_bcdata) const
Refresh stored correction BC data from coarse inputs.
Definition AMReX_MLCellLinOp.H:968
Array< RT, 2 *3 > RealTuple
Definition AMReX_MLCellLinOp.H:447
void interpolation(int amrlev, int fmglev, MF &fine, const MF &crse) const override
Add the prolongation of coarse data onto the fine grid (fine += prolong(crse)).
Definition AMReX_MLCellLinOp.H:1265
RT xdoty(int amrlev, int mglev, const MF &x, const MF &y, bool local) const final
Dot product helper.
Definition AMReX_MLCellLinOp.H:2273
Array< BoundCond, 2 *3 > BCTuple
Definition AMReX_MLCellLinOp.H:448
void prepareForSolve() override
Prepare multilevel metadata before MLMG iterates (coefficients, BC caches, etc.).
Definition AMReX_MLCellLinOp.H:1956
void unapplyMetricTerm(int amrlev, int mglev, MF &rhs) const final
Remove metric scaling previously applied to the RHS.
Definition AMReX_MLCellLinOp.H:1841
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 with boundary conditions.
Definition AMReX_MLCellLinOp.H:1541
void applyMetricTerm(int amrlev, int mglev, MF &rhs) const final
Multiply the RHS by metric terms appropriate for curvilinear coordinates.
Definition AMReX_MLCellLinOp.H:1785
Vector< std::unique_ptr< BndryRegisterT< MF > > > m_crse_cor_br
Definition AMReX_MLCellLinOp.H:440
RT norm2Precond(Vector< MF const * > const &x) const final
L2 norm over the composite AMR hierarchy, excluding cells covered by finer levels (used when the oper...
Definition AMReX_MLCellLinOp.H:2303
void beginPrecondBC() override
Called when the operator starts being used as a preconditioner.
Definition AMReX_MLCellLinOp.H:2522
Vector< Vector< std::unique_ptr< BndryCondLoc > > > m_bcondloc
Definition AMReX_MLCellLinOp.H:486
void restriction(int amrlev, int cmglev, MF &crse, MF &fine) const override
Restrict a fine-grid field onto its coarse counterpart.
Definition AMReX_MLCellLinOp.H:1253
void setGaussSeidel(bool flag) noexcept
Toggle Gauss–Seidel smoothing in place of Jacobi relaxation.
Definition AMReX_MLCellLinOp.H:104
Vector< std::unique_ptr< MF > > m_robin_bcval
Definition AMReX_MLCellLinOp.H:423
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={})
Bind the operator to an AMR hierarchy.
Definition AMReX_MLCellLinOp.H:648
~MLCellLinOpT() override=default
virtual bool isTensorOp() const
Whether this operator is a tensor solve.
Definition AMReX_MLCellLinOp.H:109
void setInterpBndryHalfWidth(int w)
Control how many cells the interpolation boundary stencil spans.
Definition AMReX_MLCellLinOp.H:430
Vector< Vector< BndryRegisterT< MF > > > m_undrrelxr
Definition AMReX_MLCellLinOp.H:489
MLCellLinOpT()
Definition AMReX_MLCellLinOp.H:641
MLCellLinOpT(MLCellLinOpT< MF > &&)=delete
typename FabDataType< MF >::fab_type FAB
Definition AMReX_MLCellLinOp.H:34
void interpAssign(int amrlev, int fmglev, MF &fine, MF &crse) const override
Overwrite fine data with the prolongation of coarse data (fine = prolong(crse)).
Definition AMReX_MLCellLinOp.H:1315
void fixSolvabilityByOffset(int amrlev, int mglev, MF &rhs, Vector< RT > const &offset) const override
Apply solvability offsets to the RHS (subtracting the average).
Definition AMReX_MLCellLinOp.H:1936
Vector< std::unique_ptr< MLMGBndryT< MF > > > m_bndry_cor
Definition AMReX_MLCellLinOp.H:439
void compFlux(int amrlev, const Array< MF *, 3 > &fluxes, MF &sol, Location loc) const override
Compute face-centered fluxes from the supplied solution.
Definition AMReX_MLCellLinOp.H:1690
typename MLLinOpT< MF >::Location Location
Definition AMReX_MLCellLinOp.H:40
void prepareForFluxes(int amrlev, const MF *crse_bcdata=nullptr) override
Ensure BC caches are ready for flux computations (e.g., getFluxes).
Definition AMReX_MLCellLinOp.H:1586
void solutionResidual(int amrlev, MF &resid, MF &x, const MF &b, const MF *crse_bcdata=nullptr) override
Compute the residual resid = b - A(x) using solution boundary data.
Definition AMReX_MLCellLinOp.H:1568
bool m_has_metric_term
Definition AMReX_MLCellLinOp.H:434
bool m_use_gauss_seidel
Definition AMReX_MLCellLinOp.H:498
Vector< std::unique_ptr< MLMGBndryT< MF > > > m_bndry_sol_zero
Definition AMReX_MLCellLinOp.H:442
Vector< std::unique_ptr< BndryRegisterT< MF > > > m_crse_sol_br
Definition AMReX_MLCellLinOp.H:437
void interpolationAmr(int famrlev, MF &fine, const MF &crse, IntVect const &nghost) const override
Prolong AMR-level data during FMG initialization.
Definition AMReX_MLCellLinOp.H:1409
virtual void addInhomogNeumannFlux(int, const Array< MF *, 3 > &, MF const &, bool) const
Optional hook for adding inhomogeneous Neumann contributions.
Definition AMReX_MLCellLinOp.H:381
Vector< std::unique_ptr< iMultiFab > > m_norm_fine_mask
Definition AMReX_MLCellLinOp.H:494
typename MLLinOpT< MF >::StateMode StateMode
Definition AMReX_MLCellLinOp.H:39
void setLevelBC(int amrlev, const MF *levelbcdata, const MF *robinbc_a=nullptr, const MF *robinbc_b=nullptr, const MF *robinbc_f=nullptr) final
Provide per-level inhomogeneous boundary data.
Definition AMReX_MLCellLinOp.H:809
bool needsUpdate() const override
Does it need update if it's reused?
Definition AMReX_MLCellLinOp.H:93
Vector< Vector< Array< MultiMask, 2 *3 > > > m_maskvals
Definition AMReX_MLCellLinOp.H:492
virtual void FFlux(int amrlev, const MFIter &mfi, const Array< FAB *, 3 > &flux, const FAB &sol, Location loc, int face_only=0) const =0
Abstract base class for multilevel linear operators used by MLMG and the bottom solvers.
Definition AMReX_MLLinOp.H:137
virtual bool needsUpdate() const
Does it need update if it's reused?
Definition AMReX_MLLinOp.H:353
virtual void update()
Update for reuse.
Definition AMReX_MLLinOp.H:355
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)
Initialize the operator hierarchy on a set of AMR levels.
Definition AMReX_MLLinOp.H:1089
Boundary helper for MLMG that manages coarse/fine and physical BC metadata.
Definition AMReX_MLMGBndry.H:20
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)
Helper that sets up BC tuples for a single box.
Definition AMReX_MLMGBndry.H:163
Definition AMReX_Mask.H:33
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:29
Checks if a type is amrex::MultiFab-like (i.e., FabArray<FAB>, where FAB is a BaseFabType).
Definition AMReX_Concepts.H:26
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
@ singlevalued
No multivalued cells; not entirely regular or covered.
@ covered
Every cell in the region is covered.
@ regular
Every cell in the region is regular.
__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 > adjCell(const BoxND< dim > &b, Orientation face, int len=1) noexcept
Similar to adjCellLo and adjCellHi except that it operates on the given face of BoxND b.
Definition AMReX_Box.H:1880
__host__ __device__ BoxND< dim > shift(const BoxND< dim > &b, int dir, int nzones) noexcept
Return a copy of b shifted by nzones cells in direction dir.
Definition AMReX_Box.H:1548
__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
std::array< T, N > Array
Definition AMReX_Array.H:31
Arena * The_Async_Arena()
Definition AMReX_Arena.cpp:825
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:37
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:310
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:88
bool notInLaunchRegion() noexcept
Definition AMReX_GpuControl.H:89
bool inNoSyncRegion() noexcept
Definition AMReX_GpuControl.H:148
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
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
__host__ __device__ T norm(const GpuComplex< T > &a_z) noexcept
Return the norm (magnitude squared) of a complex number.
Definition AMReX_GpuComplex.H:349
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 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:359
iMultiFab makeFineMask(const BoxArray &cba, const DistributionMapping &cdm, const BoxArray &fba, const IntVect &ratio, int crse_value, int fine_value, MFInfo const &info)
Definition AMReX_MultiFabUtil.cpp:653
void EB_set_covered(MultiFab &mf, Real val)
Fill all covered cells with a single value val.
Definition AMReX_EBMultiFabUtil.cpp:21
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:1898
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
BoxND< 3 > Box
Box is an alias for amrex::BoxND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:35
bool isMFIterSafe(const FabArrayBase &x, const FabArrayBase &y)
Definition AMReX_MFIter.H:256
LinOpBCType
Definition AMReX_LO_BCTYPES.H:27
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)
Volume-weighted average-down from fine to coarse using EB volume fractions.
Definition AMReX_EBMultiFabUtil.cpp:336
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
RealVectND< 3 > RealVect
Definition AMReX_ParmParse.H:39
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:242
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get I'th element of IntVectND<dim>
Definition AMReX_IntVect.H:1338
A multidimensional array accessor.
Definition AMReX_Array4.H:289
A simple struct holding 3 int values for a 3D index.
Definition AMReX_Dim3.H:24
int x
Definition AMReX_Dim3.H:24
int z
Definition AMReX_Dim3.H:24
int y
Definition AMReX_Dim3.H:24
Type trait specialized for MultiFab-like types and their containers.
Definition AMReX_FabDataType.H:16
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:52
Configuration knobs for multilevel linear operators (grid agglomeration, metrics, etc....
Definition AMReX_MLLinOp.H:51
StateMode
Definition AMReX_MLLinOp.H:118
BCMode
Definition AMReX_MLLinOp.H:117
Location
Definition AMReX_MLLinOp.H:119
FabArray memory allocation information.
Definition AMReX_FabArray.H:73
Definition AMReX_MFIter.H:20
MFItInfo & SetDynamic(bool f) noexcept
Definition AMReX_MFIter.H:43
MFItInfo & EnableTiling(const IntVect &ts=FabArrayBase::mfiter_tile_size) noexcept
Definition AMReX_MFIter.H:31
Definition AMReX_MLCellLinOp.H:26
Definition AMReX_FabArray.H:168
Struct for holding types.
Definition AMReX_TypeList.H:13