1#ifndef AMREX_MLPOISSON_H_
2#define AMREX_MLPOISSON_H_
3#include <AMReX_Config.H>
7#include <AMReX_MLPoisson_K.H>
35 using FAB =
typename MF::fab_type;
36 using RT =
typename MF::value_type;
108 [[nodiscard]]
bool isSingular (
int amrlev) const final {
return m_is_singular[amrlev]; }
112 void Fapply (
int amrlev,
int mglev, MF& out,
const MF& in)
const final;
114 void Fsmooth (
int amrlev,
int mglev, MF& sol,
const MF& rhs,
int redblack)
const final;
121 const FAB& sol,
Location loc,
int face_only=0) const final;
124 void normalize (
int amrlev,
int mglev, MF& mf) const final;
131 [[nodiscard]] MF
const*
getACoeffs (
int ,
int )
const final {
return nullptr; }
137 [[nodiscard]] std::unique_ptr<MLLinOpT<MF>>
makeNLinOp (
int grid_size)
const final;
156 Vector<
int> m_is_singular;
159template <typename MF>
166 define(a_geom, a_grids, a_dmap, a_info, a_factory);
169template <
typename MF>
177 define(a_geom, a_grids, a_dmap, a_overset_mask, a_info, a_factory);
180template <
typename MF>
192template <
typename MF>
204 "MLPoisson: overset mask does not support metric terms. Use MLABecLaplacian or LPInfo::setMetricTerm(false).");
207template <
typename MF>
210template <
typename MF>
218 m_is_singular.clear();
220 auto itlo = std::ranges::find(this->
m_lobc[0], BCType::Dirichlet);
221 auto ithi = std::ranges::find(this->
m_hibc[0], BCType::Dirichlet);
229 m_is_singular[alev] =
true;
237 auto bbox = this->
m_grids[0][0].minimalBox();
238 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
246 if (this->
m_geom[0][0].Domain().contains(bbox)) {
247 m_is_singular[0] =
true;
252template <
typename MF>
258 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
261 const RT dhy =
RT(dxinv[1]*dxinv[1]);,
262 const RT dhz =
RT(dxinv[2]*dxinv[2]););
264#if (AMREX_SPACEDIM == 3)
265 RT dh0 = this->
get_d0(dhx, dhy, dhz);
266 RT dh1 = this->
get_d1(dhx, dhy, dhz);
269#if (AMREX_SPACEDIM < 3)
270 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
271 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
276 auto const& xma = in.const_arrays();
277 auto const& yma = out.arrays();
280 const auto& osmma = this->
m_overset_mask[amrlev][mglev]->const_arrays();
285 mlpoisson_adotx_os(
AMREX_D_DECL(i,j,k), yma[box_no], xma[box_no], osmma[box_no],
289#if (AMREX_SPACEDIM < 3)
295 mlpoisson_adotx_m(
AMREX_D_DECL(i,j,k), yma[box_no], xma[box_no],
305 mlpoisson_adotx(
AMREX_D_DECL(i,j,k), yma[box_no], xma[box_no],
317#pragma omp parallel if (Gpu::notInLaunchRegion())
321 const Box& bx = mfi.tilebox();
322 const auto& xfab = in.array(mfi);
323 const auto& yfab = out.array(mfi);
327 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
331 mlpoisson_adotx_os(
AMREX_D_DECL(i,j,k), yfab, xfab, osm,
335#if (AMREX_SPACEDIM == 3)
343 TwoD::mlpoisson_adotx(i, j, yfab2d, xfab2d, dh0, dh1);
348 mlpoisson_adotx(i, j, k, yfab, xfab, dhx, dhy, dhz);
351#elif (AMREX_SPACEDIM == 2)
356 mlpoisson_adotx_m(i, j, yfab, xfab, dhx, dhy, dx, probxlo);
362 mlpoisson_adotx(i, j, yfab, xfab, dhx, dhy);
365#elif (AMREX_SPACEDIM == 1)
370 mlpoisson_adotx_m(i, yfab, xfab, dhx, dx, probxlo);
376 mlpoisson_adotx(i, yfab, xfab, dhx);
385template <
typename MF>
390#if (AMREX_SPACEDIM != 3)
395 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
397 const RT dhy =
RT(dxinv[1]*dxinv[1]);,
398 const RT dhz =
RT(dxinv[2]*dxinv[2]););
399 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
400 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
404 auto const& ma = mf.arrays();
408 mlpoisson_normalize(i,j,k, ma[box_no],
AMREX_D_DECL(dhx,dhy,dhz), dx, probxlo);
417#pragma omp parallel if (Gpu::notInLaunchRegion())
421 const Box& bx = mfi.tilebox();
422 const auto& fab = mf.array(mfi);
424#if (AMREX_SPACEDIM == 2)
427 mlpoisson_normalize(i,j,k, fab, dhx, dhy, dx, probxlo);
432 mlpoisson_normalize(i,j,k, fab, dhx, dx, probxlo);
440template <
typename MF>
448 Ax.define(sol.boxArray(), sol.DistributionMap(), sol.nComp(), 0,
450 Fapply(amrlev, mglev, Ax, sol);
453 const auto& undrrelxr = this->
m_undrrelxr[amrlev][mglev];
454 const auto& maskvals = this->
m_maskvals [amrlev][mglev];
458 const auto& f0 = undrrelxr[oitr()]; ++oitr;
459 const auto& f1 = undrrelxr[oitr()]; ++oitr;
460#if (AMREX_SPACEDIM > 1)
461 const auto& f2 = undrrelxr[oitr()]; ++oitr;
462 const auto& f3 = undrrelxr[oitr()]; ++oitr;
463#if (AMREX_SPACEDIM > 2)
464 const auto& f4 = undrrelxr[oitr()]; ++oitr;
465 const auto& f5 = undrrelxr[oitr()]; ++oitr;
471#if (AMREX_SPACEDIM > 1)
474#if (AMREX_SPACEDIM > 2)
480 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
482 const RT dhy =
RT(dxinv[1]*dxinv[1]);,
483 const RT dhz =
RT(dxinv[2]*dxinv[2]););
485#if (AMREX_SPACEDIM == 3)
490#if (AMREX_SPACEDIM < 3)
491 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
492 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
500 && ! this->hasHiddenDimension())
504#if (AMREX_SPACEDIM > 1)
507#if (AMREX_SPACEDIM > 2)
513 const auto& solnma = sol.arrays();
514 const auto& rhsma = rhs.const_arrays();
518 const auto& f0ma = f0.const_arrays();
519 const auto& f1ma = f1.const_arrays();
520#if (AMREX_SPACEDIM > 1)
521 const auto& f2ma = f2.const_arrays();
522 const auto& f3ma = f3.const_arrays();
523#if (AMREX_SPACEDIM > 2)
524 const auto& f4ma = f4.const_arrays();
525 const auto& f5ma = f5.const_arrays();
531 const auto& osmma = this->
m_overset_mask[amrlev][mglev]->const_arrays();
536 Box vbx(rhsma[box_no]);
537 mlpoisson_gsrb_os(i, j, k, solnma[box_no], rhsma[box_no],
539 f0ma[box_no], m0ma[box_no],
540 f1ma[box_no], m1ma[box_no],
541#
if (AMREX_SPACEDIM > 1)
542 f2ma[box_no], m2ma[box_no],
543 f3ma[box_no], m3ma[box_no],
544#
if (AMREX_SPACEDIM > 2)
545 f4ma[box_no], m4ma[box_no],
546 f5ma[box_no], m5ma[box_no],
552 const auto& axma = Ax.const_arrays();
556 Box vbx(rhsma[box_no]);
557 mlpoisson_jacobi_os(i, j, k, solnma[box_no], rhsma[box_no],
558 axma[box_no], osmma[box_no],
560 f0ma[box_no], m0ma[box_no],
561 f1ma[box_no], m1ma[box_no],
562#
if (AMREX_SPACEDIM > 1)
563 f2ma[box_no], m2ma[box_no],
564 f3ma[box_no], m3ma[box_no],
565#
if (AMREX_SPACEDIM > 2)
566 f4ma[box_no], m4ma[box_no],
567 f5ma[box_no], m5ma[box_no],
574#if (AMREX_SPACEDIM < 3)
580 Box vbx(rhsma[box_no]);
581 mlpoisson_gsrb_m(i, j, k, solnma[box_no], rhsma[box_no],
583 f0ma[box_no], m0ma[box_no],
584 f1ma[box_no], m1ma[box_no],
585#
if (AMREX_SPACEDIM > 1)
586 f2ma[box_no], m2ma[box_no],
587 f3ma[box_no], m3ma[box_no],
593 const auto& axma = Ax.const_arrays();
597 Box vbx(rhsma[box_no]);
598 mlpoisson_jacobi_m(i, j, k, solnma[box_no], rhsma[box_no],
600 f0ma[box_no], m0ma[box_no],
601 f1ma[box_no], m1ma[box_no],
602#
if (AMREX_SPACEDIM > 1)
603 f2ma[box_no], m2ma[box_no],
604 f3ma[box_no], m3ma[box_no],
616 Box vbx(rhsma[box_no]);
617 mlpoisson_gsrb(i, j, k, solnma[box_no], rhsma[box_no],
619 f0ma[box_no], m0ma[box_no],
620 f1ma[box_no], m1ma[box_no],
621#
if (AMREX_SPACEDIM > 1)
622 f2ma[box_no], m2ma[box_no],
623 f3ma[box_no], m3ma[box_no],
624#
if (AMREX_SPACEDIM > 2)
625 f4ma[box_no], m4ma[box_no],
626 f5ma[box_no], m5ma[box_no],
632 const auto& axma = Ax.const_arrays();
636 Box vbx(rhsma[box_no]);
637 mlpoisson_jacobi(i, j, k, solnma[box_no], rhsma[box_no],
639 f0ma[box_no], m0ma[box_no],
640 f1ma[box_no], m1ma[box_no],
641#
if (AMREX_SPACEDIM > 1)
642 f2ma[box_no], m2ma[box_no],
643 f3ma[box_no], m3ma[box_no],
644#
if (AMREX_SPACEDIM > 2)
645 f4ma[box_no], m4ma[box_no],
646 f5ma[box_no], m5ma[box_no],
660#pragma omp parallel if (Gpu::notInLaunchRegion())
664 const auto& m0 = mm0.
array(mfi);
665 const auto& m1 = mm1.
array(mfi);
666#if (AMREX_SPACEDIM > 1)
667 const auto& m2 = mm2.
array(mfi);
668 const auto& m3 = mm3.
array(mfi);
669#if (AMREX_SPACEDIM > 2)
670 const auto& m4 = mm4.
array(mfi);
671 const auto& m5 = mm5.
array(mfi);
675 const Box& tbx = mfi.tilebox();
676 const Box& vbx = mfi.validbox();
677 const auto& solnfab = sol.array(mfi);
678 const auto& rhsfab = rhs.array(mfi);
680 const auto& f0fab = f0.array(mfi);
681 const auto& f1fab = f1.array(mfi);
682#if (AMREX_SPACEDIM > 1)
683 const auto& f2fab = f2.array(mfi);
684 const auto& f3fab = f3.array(mfi);
685#if (AMREX_SPACEDIM > 2)
686 const auto& f4fab = f4.array(mfi);
687 const auto& f5fab = f5.array(mfi);
691#if (AMREX_SPACEDIM == 1)
694 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
698 mlpoisson_gsrb_os(i, j, k, solnfab, rhsfab, osm, dhx,
704 const auto& axfab = Ax.const_array(mfi);
707 mlpoisson_jacobi_os(i, j, k, solnfab, rhsfab, axfab,
718 mlpoisson_gsrb_m(i, j, k, solnfab, rhsfab, dhx,
725 const auto& axfab = Ax.const_array(mfi);
728 mlpoisson_jacobi_m(i, j, k, solnfab, rhsfab, axfab, dhx,
738 mlpoisson_gsrb(i, j, k, solnfab, rhsfab, dhx,
744 const auto& axfab = Ax.const_array(mfi);
747 mlpoisson_jacobi(i, j, k, solnfab, rhsfab, axfab, dhx,
756#if (AMREX_SPACEDIM == 2)
759 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
763 mlpoisson_gsrb_os(i, j, k, solnfab, rhsfab, osm, dhx, dhy,
771 const auto& axfab = Ax.const_array(mfi);
774 mlpoisson_jacobi_os(i, j, k, solnfab, rhsfab, axfab,
787 mlpoisson_gsrb_m(i, j, k, solnfab, rhsfab, dhx, dhy,
796 const auto& axfab = Ax.const_array(mfi);
799 mlpoisson_jacobi_m(i, j, k, solnfab, rhsfab, axfab, dhx, dhy,
811 mlpoisson_gsrb(i, j, k, solnfab, rhsfab, dhx, dhy,
819 const auto& axfab = Ax.const_array(mfi);
822 mlpoisson_jacobi(i, j, k, solnfab, rhsfab, axfab, dhx, dhy,
833#if (AMREX_SPACEDIM == 3)
836 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
840 mlpoisson_gsrb_os(i, j, k, solnfab, rhsfab, osm, dhx, dhy, dhz,
850 const auto& axfab = Ax.const_array(mfi);
853 mlpoisson_jacobi_os(i, j, k, solnfab, rhsfab, axfab,
867 const auto& solnfab_2d = this->
compactify(solnfab);
868 const auto& rhsfab_2d = this->
compactify(rhsfab);
880 TwoD::mlpoisson_gsrb(i, j, k, solnfab_2d, rhsfab_2d, dh0, dh1,
888 const auto& axfab = Ax.const_array(mfi);
889 const auto& axfab_2d = this->
compactify(axfab);
892 TwoD::mlpoisson_jacobi(i, j, k, solnfab_2d, rhsfab_2d,
905 mlpoisson_gsrb(i, j, k, solnfab, rhsfab, dhx, dhy, dhz,
915 const auto& axfab = Ax.const_array(mfi);
918 mlpoisson_jacobi(i, j, k, solnfab, rhsfab, axfab,
935template <
typename MF>
939 const FAB& sol,
Location,
const int face_only)
const
945 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
948 const auto& fyarr = flux[1]->array();,
949 const auto& fzarr = flux[2]->array(););
950 const auto& solarr = sol.array();
952#if (AMREX_SPACEDIM != 3)
953 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
954 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
957#if (AMREX_SPACEDIM == 3)
960 RT fac =
RT(dxinv[0]);
965 mlpoisson_flux_xface(tbox, fxarr, solarr, fac, blen);
968 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
971 RT fac =
RT(dxinv[1]);
976 mlpoisson_flux_yface(tbox, fyarr, solarr, fac, blen);
979 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
982 RT fac =
RT(dxinv[2]);
987 mlpoisson_flux_zface(tbox, fzarr, solarr, fac, blen);
990 flux[2]->template setVal<RunOn::Device>(
RT(0.0));
994 RT fac =
RT(dxinv[0]);
998 mlpoisson_flux_x(tbox, fxarr, solarr, fac);
1001 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
1004 RT fac =
RT(dxinv[1]);
1008 mlpoisson_flux_y(tbox, fyarr, solarr, fac);
1011 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
1014 RT fac =
RT(dxinv[2]);
1018 mlpoisson_flux_z(tbox, fzarr, solarr, fac);
1021 flux[2]->template setVal<RunOn::Device>(
RT(0.0));
1024#elif (AMREX_SPACEDIM == 2)
1027 RT fac =
RT(dxinv[0]);
1029 int blen = box.
length(0);
1033 mlpoisson_flux_xface_m(tbox, fxarr, solarr, fac, blen, dx, probxlo);
1038 mlpoisson_flux_xface(tbox, fxarr, solarr, fac, blen);
1042 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
1045 RT fac =
RT(dxinv[1]);
1047 int blen = box.
length(1);
1051 mlpoisson_flux_yface_m(tbox, fyarr, solarr, fac, blen, dx, probxlo);
1056 mlpoisson_flux_yface(tbox, fyarr, solarr, fac, blen);
1060 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
1064 RT fac =
RT(dxinv[0]);
1069 mlpoisson_flux_x_m(tbox, fxarr, solarr, fac, dx, probxlo);
1074 mlpoisson_flux_x(tbox, fxarr, solarr, fac);
1078 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
1081 RT fac =
RT(dxinv[1]);
1086 mlpoisson_flux_y_m(tbox, fyarr, solarr, fac, dx, probxlo);
1091 mlpoisson_flux_y(tbox, fyarr, solarr, fac);
1095 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
1100 RT fac =
RT(dxinv[0]);
1102 int blen = box.
length(0);
1106 mlpoisson_flux_xface_m(tbox, fxarr, solarr, fac, blen, dx, probxlo);
1111 mlpoisson_flux_xface(tbox, fxarr, solarr, fac, blen);
1115 RT fac =
RT(dxinv[0]);
1120 mlpoisson_flux_x_m(tbox, fxarr, solarr, fac, dx, probxlo);
1125 mlpoisson_flux_x(tbox, fxarr, solarr, fac);
1132template <
typename MF>
1136 bool support =
true;
1139 if (AMREX_SPACEDIM != 3) { support =
false; }
1143template <
typename MF>
1144std::unique_ptr<MLLinOpT<MF>>
1156 for (
int iproc = 0; iproc < nprocs; ++iproc) {
1157 for (
int ibox : sfc[iproc]) {
1161 dm.
define(std::move(pmap));
1167 std::unique_ptr<MLLinOpT<MF>> r{
new MLALaplacianT<MF>({geom}, {ba}, {dm}, minfo)};
1176 nop->setVerbose(this->
verbose);
1182 const Real* dx0 = this->
m_geom[0][0].CellSize();
1186 nop->setCoarseFineBCLocation(cbloc);
1189 nop->setScalars(1.0, -1.0);
1192 RT dxscale =
RT(dxinv[0]);
1193#if (AMREX_SPACEDIM >= 2)
1194 dxscale = std::max(dxscale,
RT(dxinv[1]));
1196#if (AMREX_SPACEDIM == 3)
1197 dxscale = std::max(dxscale,
RT(dxinv[2]));
1201 alpha.setVal(
RT(1.e30)*dxscale*dxscale);
1205 alpha.setVal(
RT(0.0), cpc, 0, 1);
1207 nop->setACoeffs(0, alpha);
1212template <
typename MF>
1216 dst.ParallelCopy(src);
1219template <
typename MF>
1230 Box const& domain0 = this->
m_geom[0][0].Domain();
1232 const RT dyi =
RT(this->
m_geom[0][0].InvCellSize(1));,
1233 const RT dzi =
RT(this->
m_geom[0][0].InvCellSize(2));)
1238 for (
MFIter mfi(phi); mfi.isValid(); ++mfi)
1240 Box const& vbx = mfi.validbox();
1243 if (vbx[face] == domain0[face]) {
1245 auto const& p = phi.const_array(mfi);
1246 auto const& gp = dpdn[dir]->array(mfi);
1250 RT fac = dxi * (face.
isLow() ?
RT(-1.0) :
RT(1.));
1253 gp(i,j,k) = fac * (p(i,j,k) - p(i-1,j,k));
1256#if (AMREX_SPACEDIM > 1)
1257 else if (dir == 1) {
1258 RT fac = dyi * (face.
isLow() ?
RT(-1.0) :
RT(1.));
1261 gp(i,j,k) = fac * (p(i,j,k) - p(i,j-1,k));
1264#if (AMREX_SPACEDIM > 2)
1266 RT fac = dzi * (face.
isLow() ?
RT(-1.0) :
RT(1.));
1269 gp(i,j,k) = fac * (p(i,j,k) - p(i,j,k-1));
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:562
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#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_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:681
Long size() const noexcept
Return the number of boxes in the BoxArray.
Definition AMReX_BoxArray.H:758
__host__ __device__ IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition AMReX_Box.H:167
const Real * InvCellSize() const noexcept
Returns the inverse cellsize for each coordinate direction.
Definition AMReX_CoordSys.H:91
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:51
void define(const BoxArray &boxes, int nprocs=ParallelDescriptor::NProcs())
Build a mapping from a BoxArray using the current strategy.
Definition AMReX_DistributionMapping.cpp:347
static DistributionMapping makeSFC(const MultiFab &weight, bool sort=true)
Build an SFC map weighted by the sum of component 0 over each valid box of weight; sort enables load-...
Definition AMReX_DistributionMapping.cpp:1770
Abstract factory interface for creating, aliasing, and destroying FAB objects.
Definition AMReX_FabFactory.H:73
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:85
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
Box tilebox() const noexcept
Return the tile Box at the current index.
Definition AMReX_MFIter.cpp:389
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:176
Multi-component ALaplacian (a scalar plus optional spatial a coeffs).
Definition AMReX_MLALaplacian.H:22
Cell-centered operator that exposes ABec Laplacian helpers to derived classes.
Definition AMReX_MLCellABecLap.H:22
Vector< Vector< std::unique_ptr< iMultiFab > > > m_overset_mask
Definition AMReX_MLCellABecLap.H:141
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={})
Describe the AMR hierarchy when overset masks are not required.
Definition AMReX_MLCellABecLap.H:150
void prepareForSolve() override
Standard hook called before MLMG iterates (fixes BC data, etc.).
Definition AMReX_MLCellABecLap.H:309
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< Vector< BndryRegisterT< MF > > > m_undrrelxr
Definition AMReX_MLCellLinOp.H:489
bool m_has_metric_term
Definition AMReX_MLCellLinOp.H:434
bool m_use_gauss_seidel
Definition AMReX_MLCellLinOp.H:498
Vector< Vector< Array< MultiMask, 2 *3 > > > m_maskvals
Definition AMReX_MLCellLinOp.H:492
T get_d0(T const &dx, T const &dy, T const &) const noexcept
Definition AMReX_MLLinOp.H:1046
bool doAgglomeration() const noexcept
Definition AMReX_MLLinOp.H:987
Vector< Array< BCType, 3 > > m_hibc
Definition AMReX_MLLinOp.H:870
Vector< Vector< BoxArray > > m_grids
Definition AMReX_MLLinOp.H:906
Vector< Vector< DistributionMapping > > m_dmap
Definition AMReX_MLLinOp.H:907
int verbose
Definition AMReX_MLLinOp.H:884
IntVect m_coarse_data_crse_ratio
Definition AMReX_MLLinOp.H:935
bool needsCoarseDataForBC() const noexcept
Needs coarse data for bc?
Definition AMReX_MLLinOp.H:228
bool hasHiddenDimension() const noexcept
Definition AMReX_MLLinOp.H:1027
int hiddenDirection() const noexcept
Definition AMReX_MLLinOp.H:1028
Vector< Array< BCType, 3 > > m_lobc
Definition AMReX_MLLinOp.H:869
Vector< int > m_domain_covered
Definition AMReX_MLLinOp.H:909
const MLLinOpT< MF > * m_parent
Definition AMReX_MLLinOp.H:894
Vector< Vector< Geometry > > m_geom
first Vector is for amr level and second is mg level
Definition AMReX_MLLinOp.H:905
Box compactify(Box const &b) const noexcept
Definition AMReX_MLLinOp.H:1615
bool m_needs_coarse_data_for_bc
Definition AMReX_MLLinOp.H:933
int maxorder
Definition AMReX_MLLinOp.H:886
LPInfo info
Definition AMReX_MLLinOp.H:882
T get_d1(T const &, T const &dy, T const &dz) const noexcept
Definition AMReX_MLLinOp.H:1056
LinOpBCType m_coarse_fine_bc_type
Definition AMReX_MLLinOp.H:934
int m_num_amr_levels
Definition AMReX_MLLinOp.H:890
Cell-centered Laplacian operator \nabla^2 \phi.
Definition AMReX_MLPoisson.H:32
typename MF::value_type RT
Definition AMReX_MLPoisson.H:36
MLPoissonT< MF > & operator=(const MLPoissonT< MF > &)=delete
void copyNSolveSolution(MF &dst, MF const &src) const final
Copy an NSolve solution from src to dst.
Definition AMReX_MLPoisson.H:1214
void get_dpdn_on_domain_faces(Array< MF *, 3 > const &dpdn, MF const &phi)
Compute dphi/dn on domain faces after the solve.
Definition AMReX_MLPoisson.H:1221
bool isBottomSingular() const final
True if the coarsest level is singular (e.g., pure Neumann BCs).
Definition AMReX_MLPoisson.H:110
void prepareForSolve() final
Prepare coefficients and singularity flags before entering MLMG.
Definition AMReX_MLPoisson.H:212
void Fapply(int amrlev, int mglev, MF &out, const MF &in) const final
Apply the discrete Laplacian to in at (amrlev,mglev), storing the result in out.
Definition AMReX_MLPoisson.H:254
void normalize(int amrlev, int mglev, MF &mf) const final
Divide mf by the diagonal of the operator (used by CG-family bottom solvers).
Definition AMReX_MLPoisson.H:387
typename MF::fab_type FAB
Definition AMReX_MLPoisson.H:35
Array< MF const *, 3 > getBCoeffs(int, int) const final
Poisson never supplies explicit b Multifabs, so this always returns null pointers.
Definition AMReX_MLPoisson.H:133
bool isSingular(int amrlev) const final
True if the operator is singular on AMR level amrlev.
Definition AMReX_MLPoisson.H:108
MLPoissonT(const MLPoissonT< MF > &)=delete
bool supportNSolve() const final
Report whether this operator has nodal-solve support.
Definition AMReX_MLPoisson.H:1134
MLPoissonT(MLPoissonT< MF > &&)=delete
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={})
Define the hierarchy for standard cell-centered data.
Definition AMReX_MLPoisson.H:182
RT getAScalar() const final
Return the constant a coefficient (identically zero for Poisson).
Definition AMReX_MLPoisson.H:127
RT getBScalar() const final
Return the constant b coefficient (-1, cancelling the minus in the ABec form to give \nabla^2).
Definition AMReX_MLPoisson.H:129
MF const * getACoeffs(int, int) const final
Poisson never supplies explicit a coefficients, so this always returns nullptr.
Definition AMReX_MLPoisson.H:131
MLPoissonT()=default
Construct an empty operator; call define() before using it.
void FFlux(int amrlev, const MFIter &mfi, const Array< FAB *, 3 > &flux, const FAB &sol, Location loc, int face_only=0) const final
Compute per-face fluxes from sol on the tilebox described by mfi and write them to flux with location...
Definition AMReX_MLPoisson.H:937
typename MLLinOpT< MF >::Location Location
Definition AMReX_MLPoisson.H:39
void Fsmooth(int amrlev, int mglev, MF &sol, const MF &rhs, int redblack) const final
Perform a smoothing sweep on (amrlev,mglev). redblack selects the red (0) or black (1) half of the gr...
Definition AMReX_MLPoisson.H:442
std::unique_ptr< MLLinOpT< MF > > makeNLinOp(int grid_size) const final
Build the NSolve counterpart with tile size grid_size.
Definition AMReX_MLPoisson.H:1145
Definition AMReX_MultiMask.H:23
MultiArray4< int const > const_arrays() const noexcept
Return const multi-array views (alias of arrays()).
Definition AMReX_MultiMask.H:86
Array4< int const > array(const MFIter &mfi) const noexcept
Return an Array4 view (const) for iterator mfi.
Definition AMReX_MultiMask.H:69
An Iterator over the Orientation of Faces of a Box.
Definition AMReX_Orientation.H:135
__host__ __device__ bool isValid() const noexcept
Is the iterator valid?
Definition AMReX_Orientation.H:156
Encapsulation of the Orientation of the Faces of a Box.
Definition AMReX_Orientation.H:29
__host__ __device__ bool isLow() const noexcept
Returns true if Orientation is low.
Definition AMReX_Orientation.H:89
__host__ __device__ int coordDir() const noexcept
Returns the coordinate direction.
Definition AMReX_Orientation.H:83
static const Periodicity & NonPeriodic() noexcept
Definition AMReX_Periodicity.cpp:52
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
__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 > bdryLo(const BoxND< dim > &b, int dir, int len=1) noexcept
Return the BoxND of length len on the low boundary of b along coordinate direction dir.
Definition AMReX_Box.H:1715
__host__ __device__ BoxND< dim > bdryNode(const BoxND< dim > &b, Orientation face, int len=1) noexcept
Similar to bdryLo and bdryHi except that it operates on the given face of BoxND b.
Definition AMReX_Box.H:1776
std::array< T, N > Array
Definition AMReX_Array.H:31
Arena * The_Async_Arena()
Definition AMReX_Arena.cpp:825
int NProcs() noexcept
Definition AMReX_ParallelDescriptor.H:255
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
MPI_Comm Communicator() noexcept
Definition AMReX_ParallelDescriptor.H:223
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:259
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
LinOpBCType
Definition AMReX_LO_BCTYPES.H:27
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
__host__ __device__ Dim3 end(BoxND< dim > const &box) noexcept
Return the iterator end coordinate of box as Dim3.
Definition AMReX_Box.H:2257
parallel copy or add
Definition AMReX_FabArrayBase.H:630
Configuration knobs for multilevel linear operators (grid agglomeration, metrics, etc....
Definition AMReX_MLLinOp.H:51
bool has_metric_term
Definition AMReX_MLLinOp.H:59
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