1#ifndef AMREX_ML_CELL_ABECLAP_H_
2#define AMREX_ML_CELL_ABECLAP_H_
3#include <AMReX_Config.H>
6#include <AMReX_MLCellABecLap_K.H>
25 using FAB =
typename MF::fab_type;
26 using RT =
typename MF::value_type;
107 amrex::Abort(
"MLCellABecLap::getFluxes: How did we get here?");
115 virtual MF
const*
getACoeffs (
int amrlev,
int mglev)
const = 0;
125 MF
const& sol,
bool mult_bcoef)
const final;
131 [[nodiscard]]
virtual MF
const*
getEBBCoeffs (
int ,
int )
const {
return nullptr; }
133 [[nodiscard]] std::unique_ptr<MLAlgMG>
makeAlgMG (
int mglev)
const override;
134 [[nodiscard]]
bool supportsAlgMG ()
const override {
return std::is_same_v<MF,MultiFab>; }
140#if defined(AMREX_USE_HYPRE) && (AMREX_SPACEDIM > 1)
145#if defined(AMREX_USE_PETSC) && (AMREX_SPACEDIM > 1)
147 [[nodiscard]] std::unique_ptr<PETScABecLap> makePETSc ()
const override;
158template <
typename MF>
168 this->m_overset_mask.resize(this->m_num_amr_levels);
169 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
170 this->m_overset_mask[amrlev].resize(this->m_num_mg_levels[amrlev]);
174template <
typename MF>
187 this->m_lpinfo_arg = a_info;
189 auto namrlevs =
static_cast<int>(a_geom.
size());
190 this->m_overset_mask.resize(namrlevs);
191 for (
int amrlev = 0; amrlev < namrlevs; ++amrlev)
193 this->m_overset_mask[amrlev].push_back(std::make_unique<iMultiFab>(a_grids[amrlev],
194 a_dmap[amrlev], 1, 1));
195 iMultiFab::Copy(*(this->m_overset_mask[amrlev][0]), *a_overset_mask[amrlev], 0, 0, 1, 0);
198 == a_geom[amrlev].Domain());
203 Box dom = a_geom[0].Domain();
207 iMultiFab const&
fine = *(this->m_overset_mask[amrlev][mglev-1]);
211 fine.DistributionMap(), 1, 1);
214 using ReduceTuple =
typename decltype(reduce_data)::Type;
216#pragma omp parallel if (Gpu::notInLaunchRegion())
220 const Box& bx = mfi.tilebox();
223 reduce_op.
eval(bx, reduce_data,
226 return { coarsen_overset_mask(b, cmsk, fmsk) };
229 ReduceTuple hv = reduce_data.
value(reduce_op);
230 if (amrex::get<0>(hv) == 0) {
231 this->m_overset_mask[amrlev].push_back(std::move(
crse));
239 int max_overset_mask_coarsening_level = this->m_overset_mask[amrlev].size()-1;
241 this->m_overset_mask[amrlev].resize(max_overset_mask_coarsening_level+1);
245 max_overset_mask_coarsening_level);
254 for (
int mglev = 1; mglev < this->m_num_mg_levels[amrlev]; ++mglev) {
255 MF foo(this->m_grids[amrlev][mglev], this->m_dmap[amrlev][mglev], 1, 0,
MFInfo().SetAlloc(
false));
257 auto osm = std::make_unique<iMultiFab>(this->m_grids[amrlev][mglev],
258 this->m_dmap[amrlev][mglev], 1, 1);
259 osm->ParallelCopy(*(this->m_overset_mask[amrlev][mglev]));
260 std::swap(osm, this->m_overset_mask[amrlev][mglev]);
264 for (amrlev = 1; amrlev < this->m_num_amr_levels; ++amrlev) {
265 for (
int mglev = 1; mglev < this->m_num_mg_levels[amrlev]; ++mglev) {
266 this->m_overset_mask[amrlev].push_back(std::make_unique<iMultiFab>(this->m_grids[amrlev][mglev],
267 this->m_dmap[amrlev][mglev],
272 auto const& crsema = this->m_overset_mask[amrlev][mglev]->arrays();
273 auto const& finema = this->m_overset_mask[amrlev][mglev-1]->const_arrays();
274 ParallelFor(*(this->m_overset_mask[amrlev][mglev]),
277 coarsen_overset_mask(i,j,k, crsema[box_no], finema[box_no]);
286#pragma omp parallel if (Gpu::notInLaunchRegion())
290 const Box& bx = mfi.tilebox();
291 Array4<int> const& cmsk = this->m_overset_mask[amrlev][mglev]->array(mfi);
292 Array4<int const> const fmsk = this->m_overset_mask[amrlev][mglev-1]->const_array(mfi);
295 coarsen_overset_mask(i,j,k, cmsk, fmsk);
302 for (amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
303 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev) {
304 this->m_overset_mask[amrlev][mglev]->setBndry(1);
305 this->m_overset_mask[amrlev][mglev]->FillBoundary(this->m_geom[amrlev][mglev].periodicity());
310template <
typename MF>
317template <
typename MF>
324template <
typename MF>
328 auto const* omask = this->getOversetMask(amrlev, mglev);
330 const int ncomp = this->getNComp();
331 auto const& mskma = omask->const_arrays();
332 auto const& ma = mf.arrays();
336 if (mskma[bno](i,j,k) == 0) { ma[bno](i,j,k,n) =
RT(0.0); }
344template <
typename MF>
352 const int ncomp = this->getNComp();
353 const RT betainv =
RT(1.0) / getBScalar();
354 const int nlevs = this->NAMRLevels();
357 const bool has_bcoef = (getBCoeffs(0,0)[0] !=
nullptr);
358 for (
int alev = 0; alev < nlevs; ++alev) {
359 this->compFlux(alev, a_flux[alev], *a_sol[alev], a_loc);
360 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
361 if (betainv !=
RT(1.0)) {
362 a_flux[alev][idim]->mult(betainv, 0, ncomp);
365 this->unapplyMetricTerm(alev, 0, *a_flux[alev][idim]);
368 this->addInhomogNeumannFlux(alev, a_flux[alev], *a_sol[alev],
true);
370 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
371 this->unapplyMetricTerm(alev, 0, *a_flux[alev][idim]);
377template <
typename MF>
381 bool has_inhomog_neumann = this->hasInhomogNeumannBC();
382 bool has_robin = this->hasRobinBC();
385 if (this->m_precond_mode) {
return; }
386 if (!has_inhomog_neumann && !has_robin) {
return; }
388 int ncomp = this->getNComp();
391 const auto problo = this->m_geom[amrlev][mglev].ProbLoArray();
392 const auto probhi = this->m_geom[amrlev][mglev].ProbHiArray();
394 const RT dxi =
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0));
395 const RT dyi =
static_cast<RT>((AMREX_SPACEDIM >= 2) ? this->m_geom[amrlev][mglev].InvCellSize(1) :
Real(1.0));
396 const RT dzi =
static_cast<RT>((AMREX_SPACEDIM == 3) ? this->m_geom[amrlev][mglev].InvCellSize(2) :
Real(1.0));
397 const RT xlo =
static_cast<RT>(problo[0]);
398 const RT dx =
static_cast<RT>(this->m_geom[amrlev][mglev].CellSize(0));
399 const Box& domain = this->m_geom[amrlev][mglev].Domain();
401 const RT beta = getBScalar();
404 bool has_bcoef = (bcoef[0] !=
nullptr);
406 const auto& maskvals = this->m_maskvals[amrlev][mglev];
407 const auto& bcondloc = *(this->m_bcondloc[amrlev][mglev]);
408 const auto& bndry = *(this->m_bndry_sol[amrlev]);
414#pragma omp parallel if (Gpu::notInLaunchRegion())
418 const Box& vbx = mfi.validbox();
419 auto const& rhsfab = rhs.array(mfi);
421 const auto & bdlv = bcondloc.bndryLocs(mfi);
422 const auto & bdcv = bcondloc.bndryConds(mfi);
424 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
426 auto const bfab = (has_bcoef)
427 ? bcoef[idim]->const_array(mfi) : foo.const_array();
432 const auto& mlo = maskvals[olo].array(mfi);
433 const auto& mhi = maskvals[ohi].array(mfi);
434 const auto& bvlo = bndry.bndryValues(olo).array(mfi);
435 const auto& bvhi = bndry.bndryValues(ohi).array(mfi);
436 bool outside_domain_lo = !(domain.
contains(blo));
437 bool outside_domain_hi = !(domain.
contains(bhi));
438 if ((!outside_domain_lo) && (!outside_domain_hi)) {
continue; }
439 for (
int icomp = 0; icomp < ncomp; ++icomp) {
440 const BoundCond bctlo = bdcv[icomp][olo];
441 const BoundCond bcthi = bdcv[icomp][ohi];
442 const RT bcllo = bdlv[icomp][olo];
443 const RT bclhi = bdlv[icomp][ohi];
448 if (this->m_has_metric_term && !has_bcoef) {
449#if (AMREX_SPACEDIM == 1)
450 fac *=
static_cast<RT>(problo[0]*problo[0]);
451#elif (AMREX_SPACEDIM == 2)
452 fac *=
static_cast<RT>(problo[0]);
457 mllinop_apply_innu_xlo(i,j,k, rhsfab, mlo, bfab,
459 fac, has_bcoef, icomp);
461 }
else if (idim == 1) {
463 if (this->m_has_metric_term && !has_bcoef) {
466 mllinop_apply_innu_ylo_m(i,j,k, rhsfab, mlo,
468 fac, xlo, dx, icomp);
474 mllinop_apply_innu_ylo(i,j,k, rhsfab, mlo, bfab,
476 fac, has_bcoef, icomp);
483 mllinop_apply_innu_zlo(i,j,k, rhsfab, mlo, bfab,
485 fac, has_bcoef, icomp);
493 if (this->m_has_metric_term && !has_bcoef) {
494#if (AMREX_SPACEDIM == 1)
495 fac *=
static_cast<RT>(probhi[0]*probhi[0]);
496#elif (AMREX_SPACEDIM == 2)
497 fac *=
static_cast<RT>(probhi[0]);
502 mllinop_apply_innu_xhi(i,j,k, rhsfab, mhi, bfab,
504 fac, has_bcoef, icomp);
506 }
else if (idim == 1) {
508 if (this->m_has_metric_term && !has_bcoef) {
511 mllinop_apply_innu_yhi_m(i,j,k, rhsfab, mhi,
513 fac, xlo, dx, icomp);
518 mllinop_apply_innu_yhi(i,j,k, rhsfab, mhi, bfab,
520 fac, has_bcoef, icomp);
527 mllinop_apply_innu_zhi(i,j,k, rhsfab, mhi, bfab,
529 fac, has_bcoef, icomp);
537 auto const& rbc = (*this->m_robin_bcval[amrlev])[mfi].const_array(icomp*3);
545 / (rbc(i,j,k,1)*dxi + rbc(i,j,k,0)*
RT(0.5));
546 rhsfab(i+1,j,k,icomp) += fac*bfab(i+1,j,k,icomp)*A;
548 }
else if (idim == 1) {
553 / (rbc(i,j,k,1)*dyi + rbc(i,j,k,0)*
RT(0.5));
554 rhsfab(i,j+1,k,icomp) += fac*bfab(i,j+1,k,icomp)*A;
561 / (rbc(i,j,k,1)*dzi + rbc(i,j,k,0)*
RT(0.5));
562 rhsfab(i,j,k+1,icomp) += fac*bfab(i,j,k+1,icomp)*A;
573 / (rbc(i,j,k,1)*dxi + rbc(i,j,k,0)*
RT(0.5));
574 rhsfab(i-1,j,k,icomp) += fac*bfab(i,j,k,icomp)*A;
576 }
else if (idim == 1) {
581 / (rbc(i,j,k,1)*dyi + rbc(i,j,k,0)*
RT(0.5));
582 rhsfab(i,j-1,k,icomp) += fac*bfab(i,j,k,icomp)*A;
589 / (rbc(i,j,k,1)*dzi + rbc(i,j,k,0)*
RT(0.5));
590 rhsfab(i,j,k-1,icomp) += fac*bfab(i,j,k,icomp)*A;
601template <
typename MF>
605 bool mult_bcoef)
const
613 RT fac = mult_bcoef ?
RT(-1.0) :
RT(1.0);
615 bool has_inhomog_neumann = this->hasInhomogNeumannBC();
616 bool has_robin = this->hasRobinBC();
618 if (!has_inhomog_neumann && !has_robin) {
return; }
620 int ncomp = this->getNComp();
623 const auto dxinv = this->m_geom[amrlev][mglev].InvCellSize();
624 const Box domain = this->m_geom[amrlev][mglev].growPeriodicDomain(1);
628 bcoef = getBCoeffs(amrlev,mglev);
631 const auto& bndry = *this->m_bndry_sol[amrlev];
637#pragma omp parallel if (Gpu::notInLaunchRegion())
641 Box const& vbx = mfi.validbox();
647 const RT dxi =
static_cast<RT>(dxinv[idim]);
649 for (
int icomp = 0; icomp < ncomp; ++icomp) {
650 auto const& phi = sol.const_array(mfi,icomp);
651 auto const& bv = bndry.bndryValues(ori).multiFab().const_array(mfi,icomp);
652 auto const& bc = bcoef[idim] ? bcoef[idim]->const_array(mfi,icomp)
654 auto const& f = grad[idim]->array(mfi,icomp);
656 if (this->m_lobc_orig[icomp][idim] ==
663 RT b = bc ? bc(ii,jj,kk) :
RT(1.0);
664 f(ii,jj,kk) = fac*b*bv(i,j,k);
666 }
else if (this->m_lobc_orig[icomp][idim] ==
668 auto const& rbc = (*this->m_robin_bcval[amrlev])[mfi].const_array(icomp*3);
675 (rbc(i,j,k,1)*dxi + rbc(i,j,k,0)*
RT(0.5));
676 RT RA = rbc(i,j,k,2) * tmp;
677 RT RB = (rbc(i,j,k,1)*dxi - rbc(i,j,k,0)*
RT(0.5)) * tmp;
678 RT b = bc ? bc(ii,jj,kk) :
RT(1.0);
679 f(ii,jj,kk) = fac*b*dxi*((
RT(1.0)-RB)*phi(ii,jj,kk)-RA);
683 if (this->m_hibc_orig[icomp][idim] ==
687 RT b = bc ? bc(i,j,k) :
RT(1.0);
688 f(i,j,k) = fac*b*bv(i,j,k);
690 }
else if (this->m_hibc_orig[icomp][idim] ==
692 auto const& rbc = (*this->m_robin_bcval[amrlev])[mfi].const_array(icomp*3);
696 (rbc(i,j,k,1)*dxi + rbc(i,j,k,0)*
RT(0.5));
697 RT RA = rbc(i,j,k,2) * tmp;
698 RT RB = (rbc(i,j,k,1)*dxi - rbc(i,j,k,0)*
RT(0.5)) * tmp;
699 RT b = bc ? bc(i,j,k) :
RT(1.0);
700 f(i,j,k) = fac*b*dxi*(RA+(RB-
RT(1.0))*
701 phi(i-os.
x,j-os.
y,k-os.
z));
711template <
typename MF>
715 if (m_overset_mask[amrlev][0]) {
716 const int ncomp = this->getNComp();
719 auto const& osma = m_overset_mask[amrlev][0]->const_arrays();
720 auto const& rhsa = rhs.arrays();
724 if (osma[box_no](i,j,k) == 0) {
725 rhsa[box_no](i,j,k,n) =
RT(0.0);
735#pragma omp parallel if (Gpu::notInLaunchRegion())
739 const Box& bx = mfi.tilebox();
740 auto const& rfab = rhs.array(mfi);
741 auto const& osm = m_overset_mask[amrlev][0]->const_array(mfi);
744 if (osm(i,j,k) == 0) { rfab(i,j,k,n) =
RT(0.0); }
751template <
typename MF>
755 const int amrlev = 0;
757 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
760 this->m_dmap[amrlev][mglev], 1, 0,
762 *(this->m_factory[amrlev][mglev]));
763 beta[idim].setVal(
RT(1.0));
764 this->applyMetricTerm(amrlev, mglev,
beta[idim]);
769template <
typename MF>
770std::unique_ptr<MLAlgMG>
773 if constexpr (!std::is_same<MF,MultiFab>()) {
775 amrex::Abort(
"MLCellABecLap: AlgMG only supports MultiFab");
778 const int amrlev = 0;
779 const BoxArray& ba = this->m_grids[amrlev][mglev];
781 const Geometry& geom = this->m_geom[amrlev][mglev];
782 const auto& factory = *(this->m_factory[amrlev][mglev]);
784 auto const& bcondloc = *(this->m_bcondloc[amrlev][mglev]);
789 int const cdir = oit();
790 bctype[mfi][cdir] = bcondloc.bndryConds(mfi, 0)[cdir];
791 bcl[mfi][cdir] = bcondloc.bndryLocs(mfi, 0)[cdir];
795 auto ac = getACoeffs(amrlev, mglev);
796 auto bc = getBCoeffs(amrlev, mglev);
798 if (bc[0] ==
nullptr) {
799 beta = makeDefaultBCoeffs(mglev);
802 return std::make_unique<MLAlgMG>(mglev, ba, dm, geom, factory,
803 getOversetMask(amrlev, mglev),
804 getAScalar(), getBScalar(), ac, bc,
805 getEBBCoeffs(amrlev, mglev), bctype, bcl,
806 this->getMaxOrder());
810#if defined(AMREX_USE_HYPRE) && (AMREX_SPACEDIM > 1)
811template <
typename MF>
812std::unique_ptr<Hypre>
815 if constexpr (!std::is_same<MF,MultiFab>()) {
816 amrex::Abort(
"MLCellABecLap Hypre interface only supports MultiFab");
818 const BoxArray& ba = this->m_grids[0].back();
819 const DistributionMapping& dm = this->m_dmap[0].back();
820 const Geometry& geom = this->m_geom[0].back();
821 const auto& factory = *(this->m_factory[0].back());
822 MPI_Comm comm = this->BottomCommunicator();
824 const int mglev = this->NMGLevels(0)-1;
826 auto om = getOversetMask(0, mglev);
828 auto hypre_solver =
amrex::makeHypre(ba, dm, geom, comm, hypre_interface, om);
830 hypre_solver->setScalars(getAScalar(), getBScalar());
832 auto ac = getACoeffs(0, mglev);
835 hypre_solver->setACoeffs(*ac);
839 MultiFab alpha(ba,dm,1,0,MFInfo().SetArena(
The_Async_Arena()),factory);
841 hypre_solver->setACoeffs(alpha);
844 auto bc = getBCoeffs(0, mglev);
847 hypre_solver->setBCoeffs(bc);
851 auto beta = makeDefaultBCoeffs(mglev);
854 hypre_solver->setIsMatrixSingular(this->isBottomSingular());
862#if defined(AMREX_USE_PETSC) && (AMREX_SPACEDIM > 1)
863template <
typename MF>
864std::unique_ptr<PETScABecLap>
865MLCellABecLapT<MF>::makePETSc ()
const
867 if constexpr (!std::is_same<MF,MultiFab>()) {
868 amrex::Abort(
"MLCellABecLap PETSc interface only supports MultiFab");
870 const BoxArray& ba = this->m_grids[0].back();
871 const DistributionMapping& dm = this->m_dmap[0].back();
872 const Geometry& geom = this->m_geom[0].back();
873 const auto& factory = *(this->m_factory[0].back());
874 MPI_Comm comm = this->BottomCommunicator();
876 auto petsc_solver =
makePetsc(ba, dm, geom, comm);
878 petsc_solver->setScalars(getAScalar(), getBScalar());
880 const int mglev = this->NMGLevels(0)-1;
881 auto ac = getACoeffs(0, mglev);
884 petsc_solver->setACoeffs(*ac);
888 MultiFab alpha(ba,dm,1,0,MFInfo().SetArena(
The_Async_Arena()),factory);
890 petsc_solver->setACoeffs(alpha);
893 auto bc = getBCoeffs(0, mglev);
896 petsc_solver->setBCoeffs(bc);
900 auto beta = makeDefaultBCoeffs(mglev);
909extern template class MLCellABecLapT<MultiFab>;
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:562
#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_HOST_DEVICE_FOR_3D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:106
#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< Real > fine
Definition AMReX_InterpFaceRegister.cpp:90
Array4< Real const > crse
Definition AMReX_InterpFaceRegister.cpp:92
GpuArray< Real, 3 > beta
Definition AMReX_MLEBNodeFDLaplacian.cpp:1834
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
Maintain an identifier for boundary condition types.
Definition AMReX_BoundCond.H:25
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:681
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:233
__host__ __device__ bool coarsenable(const IntVectND< dim > &refrat, const IntVectND< dim > &min_width) const noexcept
Return whether this Box is coarsenable.
Definition AMReX_Box.H:802
__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
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:51
const FAB & get(const MFIter &mfi) const noexcept
Return a constant reference to the FAB associated with mfi.
Definition AMReX_FabArray.H:558
Abstract factory interface for creating, aliasing, and destroying FAB objects.
Definition AMReX_FabFactory.H:73
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:85
Interface
HYPRE interface modes supported.
Definition AMReX_Hypre.H:70
__host__ static __device__ constexpr IntVectND< dim > TheDimensionVector(int d) noexcept
This static member function returns a reference to a constant IntVectND object, all of whose dim argu...
Definition AMReX_IntVect.H:790
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
Cell-centered operator that exposes ABec Laplacian helpers to derived classes.
Definition AMReX_MLCellABecLap.H:22
void addInhomogNeumannFlux(int amrlev, const Array< MF *, 3 > &grad, MF const &sol, bool mult_bcoef) const final
Add inhomogeneous Neumann/Robin flux contributions into grad from sol (include b when mult_bcoef is t...
Definition AMReX_MLCellABecLap.H:603
MLCellABecLapT(const MLCellABecLapT< MF > &)=delete
void getFluxes(const Vector< MF * > &a_flux, const Vector< MF * > &a_sol) const final
Guard overload that aborts if called (cell-centered flux extraction requires per-direction face array...
Definition AMReX_MLCellABecLap.H:104
Array< MF, 3 > makeDefaultBCoeffs(int mglev) const
Definition AMReX_MLCellABecLap.H:753
LPInfo m_lpinfo_arg
Definition AMReX_MLCellABecLap.H:153
virtual MF const * getACoeffs(int amrlev, int mglev) const =0
Cell-centered a coefficient MultiFab for AMR level amrlev and MG level mglev.
std::unique_ptr< MLAlgMG > makeAlgMG(int mglev) const override
Build the algebraic system of MG level mglev of AMR level 0 for the AlgMG solver. Operators that hypr...
Definition AMReX_MLCellABecLap.H:771
void getFluxes(const Vector< Array< MF *, 3 > > &a_flux, const Vector< MF * > &a_sol, Location a_loc) const final
Fill per-face fluxes using the supplied solution hierarchy.
Definition AMReX_MLCellABecLap.H:346
MLCellABecLapT< MF > & operator=(const MLCellABecLapT< MF > &)=delete
MLCellABecLapT(MLCellABecLapT< MF > &&)=delete
virtual Array< MF const *, 3 > getBCoeffs(int amrlev, int mglev) const =0
Face-centered b coefficients for AMR level amrlev and MG level mglev.
typename MF::value_type RT
Definition AMReX_MLCellABecLap.H:26
void setDirichletNodesToZero(int amrlev, int mglev, MF &mf) const override
Zero out Dirichlet nodes on (amrlev,mglev) so that GMRES can treat them as known.
Definition AMReX_MLCellABecLap.H:326
void applyOverset(int amrlev, MF &rhs) const override
Zero RHS entries in rhs that are covered by overset masks on level amrlev.
Definition AMReX_MLCellABecLap.H:713
virtual RT getBScalar() const =0
Scalar applied to b on the current operator.
iMultiFab const * getOversetMask(int amrlev, int mglev) const
Overset mask for (amrlev,mglev); returns nullptr when not defined.
Definition AMReX_MLCellABecLap.H:71
bool needsUpdate() const override
Does it need update if it's reused?
Definition AMReX_MLCellABecLap.H:75
typename MLLinOpT< MF >::Location Location
Definition AMReX_MLCellABecLap.H:28
typename MF::fab_type FAB
Definition AMReX_MLCellABecLap.H:25
Vector< Vector< std::unique_ptr< iMultiFab > > > m_overset_mask
Definition AMReX_MLCellABecLap.H:151
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:160
bool supportInhomogNeumannBC() const noexcept override
Definition AMReX_MLCellABecLap.H:155
void prepareForSolve() override
Standard hook called before MLMG iterates (fixes BC data, etc.).
Definition AMReX_MLCellABecLap.H:319
~MLCellABecLapT() override=default
bool supportsAlgMG() const override
True if makeAlgMG is implemented for this operator.
Definition AMReX_MLCellABecLap.H:134
virtual RT getAScalar() const =0
Scalar applied to a on the current operator.
void applyInhomogNeumannTerm(int amrlev, MF &rhs) const final
Apply stored Neumann data to the RHS rhs on AMR level amrlev.
Definition AMReX_MLCellABecLap.H:379
void update() override
Average coefficients/metrics when marked dirty.
Definition AMReX_MLCellABecLap.H:312
virtual MF const * getEBBCoeffs(int, int) const
EB Dirichlet b coefficient for the matrix assembly (nullptr without EB).
Definition AMReX_MLCellABecLap.H:131
Definition AMReX_MLCellLinOp.H:31
void update() override
Update for reuse.
Definition AMReX_MLCellLinOp.H:948
void prepareForSolve() override
Prepare multilevel metadata before MLMG iterates (coefficients, BC caches, etc.).
Definition AMReX_MLCellLinOp.H:1961
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
bool needsUpdate() const override
Does it need update if it's reused?
Definition AMReX_MLCellLinOp.H:93
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
@ low
Definition AMReX_Orientation.H:34
@ high
Definition AMReX_Orientation.H:34
Definition AMReX_Reduce.H:438
Type value()
Definition AMReX_Reduce.H:473
Definition AMReX_Reduce.H:597
void eval(MF const &mf, IntVect const &nghost, D &reduce_data, F &&f)
Definition AMReX_Reduce.H:734
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Long size() const noexcept
Definition AMReX_Vector.H:54
A Collection of IArrayBoxes.
Definition AMReX_iMultiFab.H:34
static void Copy(iMultiFab &dst, const iMultiFab &src, int srccomp, int dstcomp, int numcomp, int nghost)
Copy from src to dst including nghost ghost cells. The two iMultiFabs MUST have the same underlying B...
Definition AMReX_iMultiFab.cpp:51
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
__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 > convert(const BoxND< dim > &b, const IntVectND< dim > &typ) noexcept
Return a copy of b converted to the nodal flags typ.
Definition AMReX_Box.H:1630
__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 > 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 > refine(const BoxND< dim > &b, int ref_ratio) noexcept
Return a copy of b refined by the isotropic ratio ref_ratio.
Definition AMReX_Box.H:1510
std::array< T, N > Array
Definition AMReX_Array.H:31
Arena * The_Async_Arena()
Definition AMReX_Arena.cpp:839
void Min(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:161
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
int MPI_Comm
Definition AMReX_ccse-mpi.H:51
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:273
std::array< T const *, 3 > GetArrOfConstPtrs(const std::array< T, 3 > &a) noexcept
Create an array of const-qualified pointers from an array of objects.
Definition AMReX_Array.H:1079
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
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
std::unique_ptr< Hypre > makeHypre(const BoxArray &grids, const DistributionMapping &dmap, const Geometry &geom, MPI_Comm comm_, Hypre::Interface interface, const iMultiFab *overset_mask)
Factory that instantiates the requested HYPRE interface.
Definition AMReX_Hypre.cpp:12
bool TilingIfNotGPU() noexcept
Definition AMReX_MFIter.H:12
std::unique_ptr< PETScABecLap > makePetsc(const BoxArray &grids, const DistributionMapping &dmap, const Geometry &geom, MPI_Comm comm_)
Factory helper that instantiates a PETSc ABec Laplacian on one level.
Definition AMReX_PETSc.cpp:67
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:244
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
Configuration knobs for multilevel linear operators (grid agglomeration, metrics, etc....
Definition AMReX_MLLinOp.H:53
bool do_semicoarsening
Definition AMReX_MLLinOp.H:56
int max_coarsening_level
Definition AMReX_MLLinOp.H:62
Location
Definition AMReX_MLLinOp.H:121
FabArray memory allocation information.
Definition AMReX_FabArray.H:73
Definition AMReX_MFIter.H:20
MFItInfo & SetDynamic(bool f) noexcept
Definition AMReX_MFIter.H:43