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>
205template <
typename MF>
208template <
typename MF>
216 m_is_singular.clear();
218 auto itlo = std::ranges::find(this->
m_lobc[0], BCType::Dirichlet);
219 auto ithi = std::ranges::find(this->
m_hibc[0], BCType::Dirichlet);
227 m_is_singular[alev] =
true;
235 auto bbox = this->
m_grids[0][0].minimalBox();
236 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
244 if (this->
m_geom[0][0].Domain().contains(bbox)) {
245 m_is_singular[0] =
true;
250template <
typename MF>
256 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
259 const RT dhy =
RT(dxinv[1]*dxinv[1]);,
260 const RT dhz =
RT(dxinv[2]*dxinv[2]););
262#if (AMREX_SPACEDIM == 3)
263 RT dh0 = this->
get_d0(dhx, dhy, dhz);
264 RT dh1 = this->
get_d1(dhx, dhy, dhz);
267#if (AMREX_SPACEDIM < 3)
268 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
269 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
274 auto const& xma = in.const_arrays();
275 auto const& yma = out.arrays();
278 const auto& osmma = this->
m_overset_mask[amrlev][mglev]->const_arrays();
283 mlpoisson_adotx_os(
AMREX_D_DECL(i,j,k), yma[box_no], xma[box_no], osmma[box_no],
287#if (AMREX_SPACEDIM < 3)
293 mlpoisson_adotx_m(
AMREX_D_DECL(i,j,k), yma[box_no], xma[box_no],
303 mlpoisson_adotx(
AMREX_D_DECL(i,j,k), yma[box_no], xma[box_no],
315#pragma omp parallel if (Gpu::notInLaunchRegion())
319 const Box& bx = mfi.tilebox();
320 const auto& xfab = in.array(mfi);
321 const auto& yfab = out.array(mfi);
325 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
329 mlpoisson_adotx_os(
AMREX_D_DECL(i,j,k), yfab, xfab, osm,
333#if (AMREX_SPACEDIM == 3)
341 TwoD::mlpoisson_adotx(i, j, yfab2d, xfab2d, dh0, dh1);
346 mlpoisson_adotx(i, j, k, yfab, xfab, dhx, dhy, dhz);
349#elif (AMREX_SPACEDIM == 2)
354 mlpoisson_adotx_m(i, j, yfab, xfab, dhx, dhy, dx, probxlo);
360 mlpoisson_adotx(i, j, yfab, xfab, dhx, dhy);
363#elif (AMREX_SPACEDIM == 1)
368 mlpoisson_adotx_m(i, yfab, xfab, dhx, dx, probxlo);
374 mlpoisson_adotx(i, yfab, xfab, dhx);
383template <
typename MF>
388#if (AMREX_SPACEDIM != 3)
393 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
395 const RT dhy =
RT(dxinv[1]*dxinv[1]);,
396 const RT dhz =
RT(dxinv[2]*dxinv[2]););
397 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
398 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
402 auto const& ma = mf.arrays();
406 mlpoisson_normalize(i,j,k, ma[box_no],
AMREX_D_DECL(dhx,dhy,dhz), dx, probxlo);
415#pragma omp parallel if (Gpu::notInLaunchRegion())
419 const Box& bx = mfi.tilebox();
420 const auto& fab = mf.array(mfi);
422#if (AMREX_SPACEDIM == 2)
425 mlpoisson_normalize(i,j,k, fab, dhx, dhy, dx, probxlo);
430 mlpoisson_normalize(i,j,k, fab, dhx, dx, probxlo);
438template <
typename MF>
446 Ax.define(sol.boxArray(), sol.DistributionMap(), sol.nComp(), 0);
447 Fapply(amrlev, mglev, Ax, sol);
450 const auto& undrrelxr = this->
m_undrrelxr[amrlev][mglev];
451 const auto& maskvals = this->
m_maskvals [amrlev][mglev];
455 const auto& f0 = undrrelxr[oitr()]; ++oitr;
456 const auto& f1 = undrrelxr[oitr()]; ++oitr;
457#if (AMREX_SPACEDIM > 1)
458 const auto& f2 = undrrelxr[oitr()]; ++oitr;
459 const auto& f3 = undrrelxr[oitr()]; ++oitr;
460#if (AMREX_SPACEDIM > 2)
461 const auto& f4 = undrrelxr[oitr()]; ++oitr;
462 const auto& f5 = undrrelxr[oitr()]; ++oitr;
468#if (AMREX_SPACEDIM > 1)
471#if (AMREX_SPACEDIM > 2)
477 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
479 const RT dhy =
RT(dxinv[1]*dxinv[1]);,
480 const RT dhz =
RT(dxinv[2]*dxinv[2]););
482#if (AMREX_SPACEDIM == 3)
487#if (AMREX_SPACEDIM < 3)
488 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
489 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
497 && ! this->hasHiddenDimension())
501#if (AMREX_SPACEDIM > 1)
504#if (AMREX_SPACEDIM > 2)
510 const auto& solnma = sol.arrays();
511 const auto& rhsma = rhs.const_arrays();
515 const auto& f0ma = f0.const_arrays();
516 const auto& f1ma = f1.const_arrays();
517#if (AMREX_SPACEDIM > 1)
518 const auto& f2ma = f2.const_arrays();
519 const auto& f3ma = f3.const_arrays();
520#if (AMREX_SPACEDIM > 2)
521 const auto& f4ma = f4.const_arrays();
522 const auto& f5ma = f5.const_arrays();
528 const auto& osmma = this->
m_overset_mask[amrlev][mglev]->const_arrays();
533 Box vbx(rhsma[box_no]);
534 mlpoisson_gsrb_os(i, j, k, solnma[box_no], rhsma[box_no],
536 f0ma[box_no], m0ma[box_no],
537 f1ma[box_no], m1ma[box_no],
538#
if (AMREX_SPACEDIM > 1)
539 f2ma[box_no], m2ma[box_no],
540 f3ma[box_no], m3ma[box_no],
541#
if (AMREX_SPACEDIM > 2)
542 f4ma[box_no], m4ma[box_no],
543 f5ma[box_no], m5ma[box_no],
549 const auto& axma = Ax.const_arrays();
553 Box vbx(rhsma[box_no]);
554 mlpoisson_jacobi_os(i, j, k, solnma[box_no], rhsma[box_no],
555 axma[box_no], osmma[box_no],
557 f0ma[box_no], m0ma[box_no],
558 f1ma[box_no], m1ma[box_no],
559#
if (AMREX_SPACEDIM > 1)
560 f2ma[box_no], m2ma[box_no],
561 f3ma[box_no], m3ma[box_no],
562#
if (AMREX_SPACEDIM > 2)
563 f4ma[box_no], m4ma[box_no],
564 f5ma[box_no], m5ma[box_no],
571#if (AMREX_SPACEDIM < 3)
577 Box vbx(rhsma[box_no]);
578 mlpoisson_gsrb_m(i, j, k, solnma[box_no], rhsma[box_no],
580 f0ma[box_no], m0ma[box_no],
581 f1ma[box_no], m1ma[box_no],
582#
if (AMREX_SPACEDIM > 1)
583 f2ma[box_no], m2ma[box_no],
584 f3ma[box_no], m3ma[box_no],
590 const auto& axma = Ax.const_arrays();
594 Box vbx(rhsma[box_no]);
595 mlpoisson_jacobi_m(i, j, k, solnma[box_no], rhsma[box_no],
597 f0ma[box_no], m0ma[box_no],
598 f1ma[box_no], m1ma[box_no],
599#
if (AMREX_SPACEDIM > 1)
600 f2ma[box_no], m2ma[box_no],
601 f3ma[box_no], m3ma[box_no],
613 Box vbx(rhsma[box_no]);
614 mlpoisson_gsrb(i, j, k, solnma[box_no], rhsma[box_no],
616 f0ma[box_no], m0ma[box_no],
617 f1ma[box_no], m1ma[box_no],
618#
if (AMREX_SPACEDIM > 1)
619 f2ma[box_no], m2ma[box_no],
620 f3ma[box_no], m3ma[box_no],
621#
if (AMREX_SPACEDIM > 2)
622 f4ma[box_no], m4ma[box_no],
623 f5ma[box_no], m5ma[box_no],
629 const auto& axma = Ax.const_arrays();
633 Box vbx(rhsma[box_no]);
634 mlpoisson_jacobi(i, j, k, solnma[box_no], rhsma[box_no],
636 f0ma[box_no], m0ma[box_no],
637 f1ma[box_no], m1ma[box_no],
638#
if (AMREX_SPACEDIM > 1)
639 f2ma[box_no], m2ma[box_no],
640 f3ma[box_no], m3ma[box_no],
641#
if (AMREX_SPACEDIM > 2)
642 f4ma[box_no], m4ma[box_no],
643 f5ma[box_no], m5ma[box_no],
654#pragma omp parallel if (Gpu::notInLaunchRegion())
658 const auto& m0 = mm0.
array(mfi);
659 const auto& m1 = mm1.
array(mfi);
660#if (AMREX_SPACEDIM > 1)
661 const auto& m2 = mm2.
array(mfi);
662 const auto& m3 = mm3.
array(mfi);
663#if (AMREX_SPACEDIM > 2)
664 const auto& m4 = mm4.
array(mfi);
665 const auto& m5 = mm5.
array(mfi);
669 const Box& tbx = mfi.tilebox();
670 const Box& vbx = mfi.validbox();
671 const auto& solnfab = sol.array(mfi);
672 const auto& rhsfab = rhs.array(mfi);
674 const auto& f0fab = f0.array(mfi);
675 const auto& f1fab = f1.array(mfi);
676#if (AMREX_SPACEDIM > 1)
677 const auto& f2fab = f2.array(mfi);
678 const auto& f3fab = f3.array(mfi);
679#if (AMREX_SPACEDIM > 2)
680 const auto& f4fab = f4.array(mfi);
681 const auto& f5fab = f5.array(mfi);
685#if (AMREX_SPACEDIM == 1)
688 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
692 mlpoisson_gsrb_os(i, j, k, solnfab, rhsfab, osm, dhx,
698 const auto& axfab = Ax.const_array(mfi);
701 mlpoisson_jacobi_os(i, j, k, solnfab, rhsfab, axfab,
712 mlpoisson_gsrb_m(i, j, k, solnfab, rhsfab, dhx,
719 const auto& axfab = Ax.const_array(mfi);
722 mlpoisson_jacobi_m(i, j, k, solnfab, rhsfab, axfab, dhx,
732 mlpoisson_gsrb(i, j, k, solnfab, rhsfab, dhx,
738 const auto& axfab = Ax.const_array(mfi);
741 mlpoisson_jacobi(i, j, k, solnfab, rhsfab, axfab, dhx,
750#if (AMREX_SPACEDIM == 2)
753 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
757 mlpoisson_gsrb_os(i, j, k, solnfab, rhsfab, osm, dhx, dhy,
765 const auto& axfab = Ax.const_array(mfi);
768 mlpoisson_jacobi_os(i, j, k, solnfab, rhsfab, axfab,
781 mlpoisson_gsrb_m(i, j, k, solnfab, rhsfab, dhx, dhy,
790 const auto& axfab = Ax.const_array(mfi);
793 mlpoisson_jacobi_m(i, j, k, solnfab, rhsfab, axfab, dhx, dhy,
805 mlpoisson_gsrb(i, j, k, solnfab, rhsfab, dhx, dhy,
813 const auto& axfab = Ax.const_array(mfi);
816 mlpoisson_jacobi(i, j, k, solnfab, rhsfab, axfab, dhx, dhy,
827#if (AMREX_SPACEDIM == 3)
830 const auto& osm = this->
m_overset_mask[amrlev][mglev]->const_array(mfi);
834 mlpoisson_gsrb_os(i, j, k, solnfab, rhsfab, osm, dhx, dhy, dhz,
844 const auto& axfab = Ax.const_array(mfi);
847 mlpoisson_jacobi_os(i, j, k, solnfab, rhsfab, axfab,
861 const auto& solnfab_2d = this->
compactify(solnfab);
862 const auto& rhsfab_2d = this->
compactify(rhsfab);
874 TwoD::mlpoisson_gsrb(i, j, k, solnfab_2d, rhsfab_2d, dh0, dh1,
882 const auto& axfab = Ax.const_array(mfi);
883 const auto& axfab_2d = this->
compactify(axfab);
886 TwoD::mlpoisson_jacobi(i, j, k, solnfab_2d, rhsfab_2d,
899 mlpoisson_gsrb(i, j, k, solnfab, rhsfab, dhx, dhy, dhz,
909 const auto& axfab = Ax.const_array(mfi);
912 mlpoisson_jacobi(i, j, k, solnfab, rhsfab, axfab,
929template <
typename MF>
933 const FAB& sol,
Location,
const int face_only)
const
939 const Real* dxinv = this->
m_geom[amrlev][mglev].InvCellSize();
942 const auto& fyarr = flux[1]->array();,
943 const auto& fzarr = flux[2]->array(););
944 const auto& solarr = sol.array();
946#if (AMREX_SPACEDIM != 3)
947 const RT dx =
RT(this->
m_geom[amrlev][mglev].CellSize(0));
948 const RT probxlo =
RT(this->
m_geom[amrlev][mglev].ProbLo(0));
951#if (AMREX_SPACEDIM == 3)
954 RT fac =
RT(dxinv[0]);
959 mlpoisson_flux_xface(tbox, fxarr, solarr, fac, blen);
962 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
965 RT fac =
RT(dxinv[1]);
970 mlpoisson_flux_yface(tbox, fyarr, solarr, fac, blen);
973 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
976 RT fac =
RT(dxinv[2]);
981 mlpoisson_flux_zface(tbox, fzarr, solarr, fac, blen);
984 flux[2]->template setVal<RunOn::Device>(
RT(0.0));
988 RT fac =
RT(dxinv[0]);
992 mlpoisson_flux_x(tbox, fxarr, solarr, fac);
995 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
998 RT fac =
RT(dxinv[1]);
1002 mlpoisson_flux_y(tbox, fyarr, solarr, fac);
1005 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
1008 RT fac =
RT(dxinv[2]);
1012 mlpoisson_flux_z(tbox, fzarr, solarr, fac);
1015 flux[2]->template setVal<RunOn::Device>(
RT(0.0));
1018#elif (AMREX_SPACEDIM == 2)
1021 RT fac =
RT(dxinv[0]);
1023 int blen = box.
length(0);
1027 mlpoisson_flux_xface_m(tbox, fxarr, solarr, fac, blen, dx, probxlo);
1032 mlpoisson_flux_xface(tbox, fxarr, solarr, fac, blen);
1036 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
1039 RT fac =
RT(dxinv[1]);
1041 int blen = box.
length(1);
1045 mlpoisson_flux_yface_m(tbox, fyarr, solarr, fac, blen, dx, probxlo);
1050 mlpoisson_flux_yface(tbox, fyarr, solarr, fac, blen);
1054 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
1058 RT fac =
RT(dxinv[0]);
1063 mlpoisson_flux_x_m(tbox, fxarr, solarr, fac, dx, probxlo);
1068 mlpoisson_flux_x(tbox, fxarr, solarr, fac);
1072 flux[0]->template setVal<RunOn::Device>(
RT(0.0));
1075 RT fac =
RT(dxinv[1]);
1080 mlpoisson_flux_y_m(tbox, fyarr, solarr, fac, dx, probxlo);
1085 mlpoisson_flux_y(tbox, fyarr, solarr, fac);
1089 flux[1]->template setVal<RunOn::Device>(
RT(0.0));
1094 RT fac =
RT(dxinv[0]);
1096 int blen = box.
length(0);
1100 mlpoisson_flux_xface_m(tbox, fxarr, solarr, fac, blen, dx, probxlo);
1105 mlpoisson_flux_xface(tbox, fxarr, solarr, fac, blen);
1109 RT fac =
RT(dxinv[0]);
1114 mlpoisson_flux_x_m(tbox, fxarr, solarr, fac, dx, probxlo);
1119 mlpoisson_flux_x(tbox, fxarr, solarr, fac);
1126template <
typename MF>
1130 bool support =
true;
1133 if (AMREX_SPACEDIM != 3) { support =
false; }
1137template <
typename MF>
1138std::unique_ptr<MLLinOpT<MF>>
1150 for (
int iproc = 0; iproc < nprocs; ++iproc) {
1151 for (
int ibox : sfc[iproc]) {
1155 dm.
define(std::move(pmap));
1161 std::unique_ptr<MLLinOpT<MF>> r{
new MLALaplacianT<MF>({geom}, {ba}, {dm}, minfo)};
1170 nop->setVerbose(this->
verbose);
1176 const Real* dx0 = this->
m_geom[0][0].CellSize();
1180 nop->setCoarseFineBCLocation(cbloc);
1183 nop->setScalars(1.0, -1.0);
1186 RT dxscale =
RT(dxinv[0]);
1187#if (AMREX_SPACEDIM >= 2)
1188 dxscale = std::max(dxscale,
RT(dxinv[1]));
1190#if (AMREX_SPACEDIM == 3)
1191 dxscale = std::max(dxscale,
RT(dxinv[2]));
1194 MF alpha(ba, dm, 1, 0);
1195 alpha.setVal(
RT(1.e30)*dxscale*dxscale);
1199 alpha.setVal(
RT(0.0), cpc, 0, 1);
1201 nop->setACoeffs(0, alpha);
1206template <
typename MF>
1210 dst.ParallelCopy(src);
1213template <
typename MF>
1224 Box const& domain0 = this->
m_geom[0][0].Domain();
1226 const RT dyi =
RT(this->
m_geom[0][0].InvCellSize(1));,
1227 const RT dzi =
RT(this->
m_geom[0][0].InvCellSize(2));)
1232 for (
MFIter mfi(phi); mfi.isValid(); ++mfi)
1234 Box const& vbx = mfi.validbox();
1237 if (vbx[face] == domain0[face]) {
1239 auto const& p = phi.const_array(mfi);
1240 auto const& gp = dpdn[dir]->array(mfi);
1244 RT fac = dxi * (face.
isLow() ?
RT(-1.0) :
RT(1.));
1247 gp(i,j,k) = fac * (p(i,j,k) - p(i-1,j,k));
1250#if (AMREX_SPACEDIM > 1)
1251 else if (dir == 1) {
1252 RT fac = dyi * (face.
isLow() ?
RT(-1.0) :
RT(1.));
1255 gp(i,j,k) = fac * (p(i,j,k) - p(i,j-1,k));
1258#if (AMREX_SPACEDIM > 2)
1260 RT fac = dzi * (face.
isLow() ?
RT(-1.0) :
RT(1.));
1263 gp(i,j,k) = fac * (p(i,j,k) - p(i,j,k-1));
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#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:676
Long size() const noexcept
Return the number of boxes in the BoxArray.
Definition AMReX_BoxArray.H:753
__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:1767
Definition AMReX_FabFactory.H:50
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:75
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:172
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:305
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:1200
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:1013
bool doAgglomeration() const noexcept
Definition AMReX_MLLinOp.H:966
Vector< Array< BCType, 3 > > m_hibc
Definition AMReX_MLLinOp.H:849
Vector< Vector< BoxArray > > m_grids
Definition AMReX_MLLinOp.H:885
Vector< Vector< DistributionMapping > > m_dmap
Definition AMReX_MLLinOp.H:886
int verbose
Definition AMReX_MLLinOp.H:863
IntVect m_coarse_data_crse_ratio
Definition AMReX_MLLinOp.H:914
bool needsCoarseDataForBC() const noexcept
Needs coarse data for bc?
Definition AMReX_MLLinOp.H:228
bool hasHiddenDimension() const noexcept
Definition AMReX_MLLinOp.H:994
int hiddenDirection() const noexcept
Definition AMReX_MLLinOp.H:995
Vector< Array< BCType, 3 > > m_lobc
Definition AMReX_MLLinOp.H:848
Vector< int > m_domain_covered
Definition AMReX_MLLinOp.H:888
const MLLinOpT< MF > * m_parent
Definition AMReX_MLLinOp.H:873
Vector< Vector< Geometry > > m_geom
first Vector is for amr level and second is mg level
Definition AMReX_MLLinOp.H:884
Box compactify(Box const &b) const noexcept
Definition AMReX_MLLinOp.H:1571
bool m_needs_coarse_data_for_bc
Definition AMReX_MLLinOp.H:912
int maxorder
Definition AMReX_MLLinOp.H:865
LPInfo info
Definition AMReX_MLLinOp.H:861
T get_d1(T const &, T const &dy, T const &dz) const noexcept
Definition AMReX_MLLinOp.H:1023
LinOpBCType m_coarse_fine_bc_type
Definition AMReX_MLLinOp.H:913
int m_num_amr_levels
Definition AMReX_MLLinOp.H:869
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:1208
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:1215
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:210
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:252
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:385
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:1128
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:931
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:440
std::unique_ptr< MLLinOpT< MF > > makeNLinOp(int grid_size) const final
Build the NSolve counterpart with tile size grid_size.
Definition AMReX_MLPoisson.H:1139
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:79
__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
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:537
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:68
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