1#ifndef AMREX_ML_ABECLAPLACIAN_H_
2#define AMREX_ML_ABECLAPLACIAN_H_
3#include <AMReX_Config.H>
6#include <AMReX_MLABecLap_K.H>
25 using FAB =
typename MF::fab_type;
26 using RT =
typename MF::value_type;
98 template <
typename T1,
typename T2>
99 requires (std::is_convertible_v<T1, typename MF::value_type> && std::is_convertible_v<T2, typename MF::value_type>)
111 template <FabArrayType AMF>
112 requires (std::is_convertible_v<typename AMF::value_type, typename MF::value_type>)
113 void setACoeffs (
int amrlev,
const AMF& alpha);
124 template <
typename T>
125 requires (std::is_convertible_v<T, typename MF::value_type>)
137 template <FabArrayType AMF>
138 requires (std::is_convertible_v<typename AMF::value_type, typename MF::value_type>)
139 void setBCoeffs (
int amrlev,
const Array<AMF const*,AMREX_SPACEDIM>&
beta);
150 template <
typename T>
151 requires (std::is_convertible_v<T, typename MF::value_type>)
163 template <
typename T>
164 requires (std::is_convertible_v<T, typename MF::value_type>)
167 [[nodiscard]]
int getNComp ()
const override {
return m_ncomp; }
186 void Fapply (
int amrlev,
int mglev, MF& out,
const MF& in)
const override;
192 void Fsmooth (
int amrlev,
int mglev, MF& sol,
const MF& rhs,
int redblack)
const override;
201 int face_only=0)
const override;
204 void normalize (
int amrlev,
int mglev, MF& mf)
const override;
211 [[nodiscard]] MF
const*
getACoeffs (
int amrlev,
int mglev)
const final
218 [[nodiscard]] std::unique_ptr<MLLinOpT<MF>>
makeNLinOp (
int )
const final;
255 FAB const& sol,
int face_only,
int ncomp);
274 bool m_needs_update =
true;
281 void define_ab_coeffs ();
283 void update_singular_flags ();
286template <
typename MF>
294 define(a_geom, a_grids, a_dmap, a_info, a_factory, a_ncomp);
297template <
typename MF>
306 define(a_geom, a_grids, a_dmap, a_overset_mask, a_info, a_factory, a_ncomp);
311template <
typename MF>
321 this->m_ncomp = a_ncomp;
326template <
typename MF>
336 BL_PROFILE(
"MLABecLaplacian::define(overset)");
337 this->m_ncomp = a_ncomp;
342template <
typename MF>
346 m_a_coeffs.resize(this->m_num_amr_levels);
347 m_b_coeffs.resize(this->m_num_amr_levels);
348 m_a_metric_applied.assign(this->m_num_amr_levels, 0);
349 m_b_metric_applied.assign(this->m_num_amr_levels, 0);
350 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev)
352 m_a_coeffs[amrlev].resize(this->m_num_mg_levels[amrlev]);
353 m_b_coeffs[amrlev].resize(this->m_num_mg_levels[amrlev]);
354 for (
int mglev = 0; mglev < this->m_num_mg_levels[amrlev]; ++mglev)
356 m_a_coeffs[amrlev][mglev].
define
357 (this->m_grids[amrlev][mglev], this->m_dmap[amrlev][mglev],
358 1, 0,
MFInfo(), *(this->m_factory[amrlev][mglev]));
359 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
363 m_b_coeffs[amrlev][mglev][idim].define
364 (ba, this->m_dmap[amrlev][mglev], m_ncomp, 0,
MFInfo(),
365 *(this->m_factory[amrlev][mglev]));
371template <
typename MF>
372template <
typename T1,
typename T2>
373requires (std::is_convertible_v<T1, typename MF::value_type> && std::is_convertible_v<T2, typename MF::value_type>)
379 if (m_a_scalar ==
RT(0.0)) {
380 for (
int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
381 m_a_coeffs[amrlev][0].setVal(
RT(0.0));
385 m_needs_update =
true;
386 m_scalars_set =
true;
389template <
typename MF>
390template <FabArrayType AMF>
391requires (std::is_convertible_v<typename AMF::value_type, typename MF::value_type>)
396 "MLABecLaplacian::setACoeffs: alpha is supposed to be single component.");
397 m_a_coeffs[amrlev][0].LocalCopy(alpha, 0, 0, 1,
IntVect(0));
398 m_a_metric_applied[amrlev] = 0;
399 m_needs_update =
true;
403template <
typename MF>
405requires (std::is_convertible_v<T, typename MF::value_type>)
409 m_a_coeffs[amrlev][0].setVal(
RT(alpha));
410 m_a_metric_applied[amrlev] = 0;
411 m_needs_update =
true;
416template <
typename MF>
417template <FabArrayType AMF>
418requires (std::is_convertible_v<typename AMF::value_type, typename MF::value_type>)
423 const int ncomp = this->getNComp();
426 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
427 for (
int icomp = 0; icomp < ncomp; ++icomp) {
428 m_b_coeffs[amrlev][0][idim].LocalCopy(*
beta[idim], icomp, icomp, 1,
IntVect(0));
432 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
433 for (
int icomp = 0; icomp < ncomp; ++icomp) {
434 m_b_coeffs[amrlev][0][idim].LocalCopy(*
beta[idim], 0, icomp, 1,
IntVect(0));
438 m_b_metric_applied[amrlev] = 0;
439 m_needs_update =
true;
442template <
typename MF>
444requires (std::is_convertible_v<T, typename MF::value_type>)
449 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
450 m_b_coeffs[amrlev][0][idim].setVal(
RT(
beta));
452 m_b_metric_applied[amrlev] = 0;
453 m_needs_update =
true;
456template <
typename MF>
458requires (std::is_convertible_v<T, typename MF::value_type>)
463 const int ncomp = this->getNComp();
464 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
465 for (
int icomp = 0; icomp < ncomp; ++icomp) {
466 m_b_coeffs[amrlev][0][idim].setVal(
RT(
beta[icomp]), icomp, 1, 0);
469 m_b_metric_applied[amrlev] = 0;
470 m_needs_update =
true;
473template <
typename MF>
481#if (AMREX_SPACEDIM != 3)
482 applyMetricTermsCoeffs();
485 applyRobinBCTermsCoeffs();
489 update_singular_flags();
491 m_needs_update =
false;
494template <
typename MF>
498 BL_PROFILE(
"MLABecLaplacian::prepareForSolve()");
502#if (AMREX_SPACEDIM != 3)
503 applyMetricTermsCoeffs();
506 applyRobinBCTermsCoeffs();
510 update_singular_flags();
512 m_needs_update =
false;
515template <
typename MF>
519#if (AMREX_SPACEDIM != 3)
520 for (
int alev = 0; alev < this->m_num_amr_levels; ++alev)
523 if (!m_a_metric_applied[alev]) {
524 this->applyMetricTerm(alev, mglev, m_a_coeffs[alev][mglev]);
525 m_a_metric_applied[alev] = 1;
527 if (!m_b_metric_applied[alev]) {
528 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
530 this->applyMetricTerm(alev, mglev, m_b_coeffs[alev][mglev][idim]);
532 m_b_metric_applied[alev] = 1;
567template <
typename LP>
568void applyRobinBCTermsCoeffs (LP& linop)
570 using RT =
typename LP::RT;
572 const int ncomp = linop.getNComp();
573 bool reset_alpha =
false;
574 if (linop.m_a_scalar == RT(0.0)) {
575 linop.m_a_scalar = RT(1.0);
578 const RT bovera = linop.m_b_scalar/linop.m_a_scalar;
582 "To reuse solver With Robin BC, one must re-call setScalars (and setACoeffs if the scalar is not zero)");
585 linop.m_scalars_set =
false;
586 linop.m_acoef_set =
false;
588 for (
int amrlev = 0; amrlev < linop.NAMRLevels(); ++amrlev) {
590 const Box& domain = linop.Geom(amrlev,mglev).Domain();
591 const RT dxi =
static_cast<RT
>(linop.Geom(amrlev,mglev).InvCellSize(0));
592 const RT dyi =
static_cast<RT
>((AMREX_SPACEDIM >= 2) ? linop.Geom(amrlev,mglev).InvCellSize(1) :
Real(1.0));
593 const RT dzi =
static_cast<RT
>((AMREX_SPACEDIM == 3) ? linop.Geom(amrlev,mglev).InvCellSize(2) :
Real(1.0));
596 linop.m_a_coeffs[amrlev][mglev].setVal(RT(0.0));
603#pragma omp parallel if (Gpu::notInLaunchRegion())
605 for (MFIter mfi(linop.m_a_coeffs[amrlev][mglev], mfi_info); mfi.isValid(); ++mfi)
607 const Box& vbx = mfi.validbox();
608 auto const& afab = linop.m_a_coeffs[amrlev][mglev].array(mfi);
609 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
610 auto const& bfab = linop.m_b_coeffs[amrlev][mglev][idim].const_array(mfi);
613 bool outside_domain_lo = !(domain.contains(blo));
614 bool outside_domain_hi = !(domain.contains(bhi));
615 if ((!outside_domain_lo) && (!outside_domain_hi)) {
continue; }
616 for (
int icomp = 0; icomp < ncomp; ++icomp) {
617 auto const& rbc = (*(linop.m_robin_bcval[amrlev]))[mfi].const_array(icomp*3);
621 RT fac = bovera*dxi*dxi;
624 RT B = (rbc(i,j,k,1)*dxi - rbc(i,j,k,0)*RT(0.5))
625 / (rbc(i,j,k,1)*dxi + rbc(i,j,k,0)*RT(0.5));
626 afab(i+1,j,k,icomp) += fac*bfab(i+1,j,k,icomp)*(RT(1.0)-B);
628 }
else if (idim == 1) {
629 RT fac = bovera*dyi*dyi;
632 RT B = (rbc(i,j,k,1)*dyi - rbc(i,j,k,0)*RT(0.5))
633 / (rbc(i,j,k,1)*dyi + rbc(i,j,k,0)*RT(0.5));
634 afab(i,j+1,k,icomp) += fac*bfab(i,j+1,k,icomp)*(RT(1.0)-B);
637 RT fac = bovera*dzi*dzi;
640 RT B = (rbc(i,j,k,1)*dzi - rbc(i,j,k,0)*RT(0.5))
641 / (rbc(i,j,k,1)*dzi + rbc(i,j,k,0)*RT(0.5));
642 afab(i,j,k+1,icomp) += fac*bfab(i,j,k+1,icomp)*(RT(1.0)-B);
649 RT fac = bovera*dxi*dxi;
652 RT B = (rbc(i,j,k,1)*dxi - rbc(i,j,k,0)*RT(0.5))
653 / (rbc(i,j,k,1)*dxi + rbc(i,j,k,0)*RT(0.5));
654 afab(i-1,j,k,icomp) += fac*bfab(i,j,k,icomp)*(RT(1.0)-B);
656 }
else if (idim == 1) {
657 RT fac = bovera*dyi*dyi;
660 RT B = (rbc(i,j,k,1)*dyi - rbc(i,j,k,0)*RT(0.5))
661 / (rbc(i,j,k,1)*dyi + rbc(i,j,k,0)*RT(0.5));
662 afab(i,j-1,k,icomp) += fac*bfab(i,j,k,icomp)*(RT(1.0)-B);
665 RT fac = bovera*dzi*dzi;
668 RT B = (rbc(i,j,k,1)*dzi - rbc(i,j,k,0)*RT(0.5))
669 / (rbc(i,j,k,1)*dzi + rbc(i,j,k,0)*RT(0.5));
670 afab(i,j,k-1,icomp) += fac*bfab(i,j,k,icomp)*(RT(1.0)-B);
682template <
typename MF>
686 if (this->hasRobinBC()) {
687 detail::applyRobinBCTermsCoeffs(*
this);
691template <
typename MF>
695 BL_PROFILE(
"MLABecLaplacian::averageDownCoeffs()");
697 for (
int amrlev = this->m_num_amr_levels-1; amrlev > 0; --amrlev)
699 auto& fine_a_coeffs = m_a_coeffs[amrlev];
700 auto& fine_b_coeffs = m_b_coeffs[amrlev];
702 averageDownCoeffsSameAmrLevel(amrlev, fine_a_coeffs, fine_b_coeffs);
703 averageDownCoeffsToCoarseAmrLevel(amrlev);
706 averageDownCoeffsSameAmrLevel(0, m_a_coeffs[0], m_b_coeffs[0]);
709template <
typename MF>
714 int nmglevs = a.
size();
715 for (
int mglev = 1; mglev < nmglevs; ++mglev)
717 IntVect ratio = (amrlev > 0) ?
IntVect(this->mg_coarsen_ratio) : this->mg_coarsen_ratio_vec[mglev-1];
718 if (this->hasHiddenDimension()) { ratio[this->hiddenDirection()] = 1; }
720 if (m_a_scalar == 0.0)
722 a[mglev].setVal(
RT(0.0));
739 for (
int mglev = 1; mglev < nmglevs; ++mglev)
741 if (this->m_overset_mask[amrlev][mglev]) {
742 const RT fac =
static_cast<RT>(1 << mglev);
743 const RT osfac =
RT(2.0)*fac/(fac+
RT(1.0));
744 const int ncomp = this->getNComp();
746#pragma omp parallel if (Gpu::notInLaunchRegion())
751 Box const& ybx = mfi.nodaltilebox(1);,
752 Box const& zbx = mfi.nodaltilebox(2));
754 auto const& by = b[mglev][1].array(mfi);,
755 auto const& bz = b[mglev][2].array(mfi));
756 auto const& osm = this->m_overset_mask[amrlev][mglev]->const_array(mfi);
757#if defined(AMREX_USE_CUDA) && defined(_WIN32)
761 overset_rescale_bcoef_x(t_xbx, bx, osm, ncomp, osfac);
763#if (AMREX_SPACEDIM >= 2)
767 overset_rescale_bcoef_y(t_ybx, by, osm, ncomp, osfac);
770#if (AMREX_SPACEDIM == 3)
774 overset_rescale_bcoef_z(t_zbx, bz, osm, ncomp, osfac);
781 overset_rescale_bcoef_x(t_xbx, bx, osm, ncomp, osfac);
785 overset_rescale_bcoef_y(t_ybx, by, osm, ncomp, osfac);
789 overset_rescale_bcoef_z(t_zbx, bz, osm, ncomp, osfac);
797template <
typename MF>
801 auto& fine_a_coeffs = m_a_coeffs[flev ].back();
802 auto& fine_b_coeffs = m_b_coeffs[flev ].back();
803 auto& crse_a_coeffs = m_a_coeffs[flev-1].front();
804 auto& crse_b_coeffs = m_b_coeffs[flev-1].front();
806 if (m_a_scalar != 0.0) {
814 IntVect(this->mg_coarsen_ratio),
815 this->m_geom[flev-1][0]);
818template <
typename MF>
822 m_is_singular.clear();
823 m_is_singular.resize(this->m_num_amr_levels,
false);
824 auto itlo = std::ranges::find(this->m_lobc[0], BCType::Dirichlet);
825 auto ithi = std::ranges::find(this->m_hibc[0], BCType::Dirichlet);
826 if (itlo == this->m_lobc[0].
end() && ithi == this->m_hibc[0].
end())
828 for (
int alev = 0; alev < this->m_num_amr_levels; ++alev)
831 if (this->m_domain_covered[alev] && !this->m_overset_mask[alev][0])
833 if (m_a_scalar ==
Real(0.0))
835 m_is_singular[alev] =
true;
839 RT asum = m_a_coeffs[alev].back().sum(0,
IntVect(0));
840 RT amax = m_a_coeffs[alev].back().norminf(0,1,
IntVect(0));
841 m_is_singular[alev] = (std::abs(asum) <= amax * RT(1.e-12));
847 if (!m_is_singular[0] && this->m_needs_coarse_data_for_bc &&
852 bool lev0_a_is_zero =
false;
853 if (m_a_scalar ==
Real(0.0)) {
854 lev0_a_is_zero =
true;
856 RT asum = m_a_coeffs[0].back().sum(0,
IntVect(0));
857 RT amax = m_a_coeffs[0].back().norminf(0,1,
IntVect(0));
858 bool a_is_almost_zero = std::abs(asum) <= amax * RT(1.e-12);
859 if (a_is_almost_zero) { lev0_a_is_zero =
true; }
862 if (lev0_a_is_zero) {
863 auto bbox = this->m_grids[0][0].minimalBox();
864 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
872 if (this->m_geom[0][0].Domain().contains(bbox)) {
873 m_is_singular[0] =
true;
879template <
typename MF>
885 const MF& acoef = m_a_coeffs[amrlev][mglev];
886 AMREX_D_TERM(
const MF& bxcoef = m_b_coeffs[amrlev][mglev][0];,
887 const MF& bycoef = m_b_coeffs[amrlev][mglev][1];,
888 const MF& bzcoef = m_b_coeffs[amrlev][mglev][2];);
891 {
AMREX_D_DECL(
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0)),
892 static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(1)),
893 static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(2)))};
895 const RT ascalar = m_a_scalar;
896 const RT bscalar = m_b_scalar;
898 const int ncomp = this->getNComp();
902 const auto& xma = in.const_arrays();
903 const auto& yma = out.arrays();
904 const auto& ama = acoef.arrays();
906 const auto& byma = bycoef.const_arrays();,
907 const auto& bzma = bzcoef.const_arrays(););
908 if (this->m_overset_mask[amrlev][mglev]) {
909 const auto& osmma = this->m_overset_mask[amrlev][mglev]->const_arrays();
913 mlabeclap_adotx_os(i,j,k,n, yma[box_no], xma[box_no], ama[box_no],
915 osmma[box_no], dxinv, ascalar, bscalar);
921 mlabeclap_adotx(i,j,k,n, yma[box_no], xma[box_no], ama[box_no],
923 dxinv, ascalar, bscalar);
933#pragma omp parallel if (Gpu::notInLaunchRegion())
937 const Box& bx = mfi.tilebox();
938 const auto& xfab = in.array(mfi);
939 const auto& yfab = out.array(mfi);
940 const auto& afab = acoef.array(mfi);
942 const auto& byfab = bycoef.array(mfi);,
943 const auto& bzfab = bzcoef.array(mfi););
944 if (this->m_overset_mask[amrlev][mglev]) {
945 const auto& osm = this->m_overset_mask[amrlev][mglev]->const_array(mfi);
948 mlabeclap_adotx_os(i,j,k,n, yfab, xfab, afab,
AMREX_D_DECL(bxfab,byfab,bzfab),
949 osm, dxinv, ascalar, bscalar);
954 mlabeclap_adotx(i,j,k,n, yfab, xfab, afab,
AMREX_D_DECL(bxfab,byfab,bzfab),
955 dxinv, ascalar, bscalar);
962template <
typename MF>
968 bool regular_coarsening =
true;
969 if (amrlev == 0 && mglev > 0) {
970 regular_coarsening = this->mg_coarsen_ratio_vec[mglev-1] == this->mg_coarsen_ratio;
974 if (! this->m_use_gauss_seidel && regular_coarsening) {
975 Ax.define(sol.boxArray(), sol.DistributionMap(), sol.nComp(), 0,
977 Fapply(amrlev, mglev, Ax, sol);
980 const MF& acoef = m_a_coeffs[amrlev][mglev];
982 AMREX_D_TERM(
const MF& bxcoef = m_b_coeffs[amrlev][mglev][0];,
983 const MF& bycoef = m_b_coeffs[amrlev][mglev][1];,
984 const MF& bzcoef = m_b_coeffs[amrlev][mglev][2];);
985 const auto& undrrelxr = this->m_undrrelxr[amrlev][mglev];
986 const auto& maskvals = this->m_maskvals [amrlev][mglev];
990 const auto& f0 = undrrelxr[oitr()]; ++oitr;
991 const auto& f1 = undrrelxr[oitr()]; ++oitr;
992#if (AMREX_SPACEDIM > 1)
993 const auto& f2 = undrrelxr[oitr()]; ++oitr;
994 const auto& f3 = undrrelxr[oitr()]; ++oitr;
995#if (AMREX_SPACEDIM > 2)
996 const auto& f4 = undrrelxr[oitr()]; ++oitr;
997 const auto& f5 = undrrelxr[oitr()]; ++oitr;
1003#if (AMREX_SPACEDIM > 1)
1006#if (AMREX_SPACEDIM > 2)
1012 const int nc = this->getNComp();
1013 const Real* h = this->m_geom[amrlev][mglev].CellSize();
1015 const RT dhy = m_b_scalar/
static_cast<RT>(h[1]*h[1]);,
1016 const RT dhz = m_b_scalar/
static_cast<RT>(h[2]*h[2]));
1017 const RT alpha = m_a_scalar;
1022 || this->m_overset_mask[amrlev][mglev]
1024 "MLABecLaplacian::Fsmooth: line solve is not supported on GPU");
1026 && (this->m_overset_mask[amrlev][mglev] || regular_coarsening))
1030#if (AMREX_SPACEDIM > 1)
1033#if (AMREX_SPACEDIM > 2)
1039 const auto& solnma = sol.arrays();
1040 const auto& rhsma = rhs.const_arrays();
1041 const auto& ama = acoef.const_arrays();
1043 AMREX_D_TERM(
const auto& bxma = bxcoef.const_arrays();,
1044 const auto& byma = bycoef.const_arrays();,
1045 const auto& bzma = bzcoef.const_arrays(););
1047 const auto& f0ma = f0.const_arrays();
1048 const auto& f1ma = f1.const_arrays();
1049#if (AMREX_SPACEDIM > 1)
1050 const auto& f2ma = f2.const_arrays();
1051 const auto& f3ma = f3.const_arrays();
1052#if (AMREX_SPACEDIM > 2)
1053 const auto& f4ma = f4.const_arrays();
1054 const auto& f5ma = f5.const_arrays();
1058 if (this->m_overset_mask[amrlev][mglev]) {
1059 const auto& osmma = this->m_overset_mask[amrlev][mglev]->const_arrays();
1060 if (this->m_use_gauss_seidel) {
1064 Box vbx(ama[box_no]);
1065 abec_gsrb_os(i,j,k,n, solnma[box_no], rhsma[box_no], alpha, ama[box_no],
1072 osmma[box_no], vbx, redblack);
1075 const auto& axma = Ax.const_arrays();
1079 Box vbx(ama[box_no]);
1080 abec_jacobi_os(i,j,k,n, solnma[box_no], rhsma[box_no], axma[box_no],
1088 osmma[box_no], vbx);
1091 }
else if (regular_coarsening) {
1092 if (this->m_use_gauss_seidel) {
1096 Box vbx(ama[box_no]);
1097 abec_gsrb(i,j,k,n, solnma[box_no], rhsma[box_no], alpha, ama[box_no],
1107 const auto& axma = Ax.const_arrays();
1111 Box vbx(ama[box_no]);
1112 abec_jacobi(i,j,k,n, solnma[box_no], rhsma[box_no], axma[box_no],
1135 if (regular_coarsening || this->m_overset_mask[amrlev][mglev]) {
1140#pragma omp parallel if (Gpu::notInLaunchRegion())
1144 const auto& m0 = mm0.
array(mfi);
1145 const auto& m1 = mm1.
array(mfi);
1146#if (AMREX_SPACEDIM > 1)
1147 const auto& m2 = mm2.
array(mfi);
1148 const auto& m3 = mm3.
array(mfi);
1149#if (AMREX_SPACEDIM > 2)
1150 const auto& m4 = mm4.
array(mfi);
1151 const auto& m5 = mm5.
array(mfi);
1155 const Box& tbx = mfi.tilebox();
1156 const Box& vbx = mfi.validbox();
1157 const auto& solnfab = sol.array(mfi);
1158 const auto& rhsfab = rhs.const_array(mfi);
1159 const auto& afab = acoef.const_array(mfi);
1161 AMREX_D_TERM(
const auto& bxfab = bxcoef.const_array(mfi);,
1162 const auto& byfab = bycoef.const_array(mfi);,
1163 const auto& bzfab = bzcoef.const_array(mfi););
1165 const auto& f0fab = f0.const_array(mfi);
1166 const auto& f1fab = f1.const_array(mfi);
1167#if (AMREX_SPACEDIM > 1)
1168 const auto& f2fab = f2.const_array(mfi);
1169 const auto& f3fab = f3.const_array(mfi);
1170#if (AMREX_SPACEDIM > 2)
1171 const auto& f4fab = f4.const_array(mfi);
1172 const auto& f5fab = f5.const_array(mfi);
1176 if (this->m_overset_mask[amrlev][mglev]) {
1177 const auto& osm = this->m_overset_mask[amrlev][mglev]->const_array(mfi);
1178 if (this->m_use_gauss_seidel) {
1181 abec_gsrb_os(i,j,k,n, solnfab, rhsfab, alpha, afab,
1188 osm, vbx, redblack);
1191 const auto& axfab = Ax.const_array(mfi);
1194 abec_jacobi_os(i,j,k,n, solnfab, rhsfab, axfab,
1205 }
else if (regular_coarsening) {
1206 if (this->m_use_gauss_seidel) {
1209 abec_gsrb(i,j,k,n, solnfab, rhsfab, alpha, afab,
1219 const auto& axfab = Ax.const_array(mfi);
1222 abec_jacobi(i,j,k,n, solnfab, rhsfab, axfab,
1236 abec_gsrb_with_line_solve(tbx, solnfab, rhsfab, alpha, afab,
1249template <
typename MF>
1257 const int mglev = 0;
1259 const Real* dxinv = this->m_geom[amrlev][mglev].InvCellSize();
1260 const int ncomp = this->getNComp();
1261 FFlux(box, dxinv, m_b_scalar,
1263 &(m_b_coeffs[amrlev][mglev][1][mfi]),
1264 &(m_b_coeffs[amrlev][mglev][2][mfi]))}},
1265 flux, sol, face_only, ncomp);
1268template <
typename MF>
1273 FAB const& sol,
int face_only,
int ncomp)
1276 const auto by = bcoef[1]->const_array();,
1277 const auto bz = bcoef[2]->const_array(););
1279 const auto& fyarr = flux[1]->array();,
1280 const auto& fzarr = flux[2]->array(););
1281 const auto& solarr = sol.array();
1285 RT fac = bscalar*
static_cast<RT>(dxinv[0]);
1287 int blen = box.
length(0);
1290 mlabeclap_flux_xface(tbox, fxarr, solarr, bx, fac, blen, ncomp);
1292#if (AMREX_SPACEDIM >= 2)
1293 fac = bscalar*
static_cast<RT>(dxinv[1]);
1298 mlabeclap_flux_yface(tbox, fyarr, solarr, by, fac, blen, ncomp);
1301#if (AMREX_SPACEDIM == 3)
1302 fac = bscalar*
static_cast<RT>(dxinv[2]);
1307 mlabeclap_flux_zface(tbox, fzarr, solarr, bz, fac, blen, ncomp);
1313 RT fac = bscalar*
static_cast<RT>(dxinv[0]);
1317 mlabeclap_flux_x(tbox, fxarr, solarr, bx, fac, ncomp);
1319#if (AMREX_SPACEDIM >= 2)
1320 fac = bscalar*
static_cast<RT>(dxinv[1]);
1324 mlabeclap_flux_y(tbox, fyarr, solarr, by, fac, ncomp);
1327#if (AMREX_SPACEDIM == 3)
1328 fac = bscalar*
static_cast<RT>(dxinv[2]);
1332 mlabeclap_flux_z(tbox, fzarr, solarr, bz, fac, ncomp);
1338template <
typename MF>
1344 const auto& acoef = m_a_coeffs[amrlev][mglev];
1345 AMREX_D_TERM(
const auto& bxcoef = m_b_coeffs[amrlev][mglev][0];,
1346 const auto& bycoef = m_b_coeffs[amrlev][mglev][1];,
1347 const auto& bzcoef = m_b_coeffs[amrlev][mglev][2];);
1350 {
AMREX_D_DECL(
static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0)),
1351 static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(1)),
1352 static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(2)))};
1354 const RT ascalar = m_a_scalar;
1355 const RT bscalar = m_b_scalar;
1357 const int ncomp = getNComp();
1361 const auto& ma = mf.arrays();
1362 const auto& ama = acoef.const_arrays();
1363 AMREX_D_TERM(
const auto& bxma = bxcoef.const_arrays();,
1364 const auto& byma = bycoef.const_arrays();,
1365 const auto& bzma = bzcoef.const_arrays(););
1369 mlabeclap_normalize(i,j,k,n, ma[box_no], ama[box_no],
1371 dxinv, ascalar, bscalar);
1380#pragma omp parallel if (Gpu::notInLaunchRegion())
1384 const Box& bx = mfi.tilebox();
1385 const auto& fab = mf.array(mfi);
1386 const auto& afab = acoef.array(mfi);
1388 const auto& byfab = bycoef.array(mfi);,
1389 const auto& bzfab = bzcoef.array(mfi););
1393 mlabeclap_normalize(i,j,k,n, fab, afab,
AMREX_D_DECL(bxfab,byfab,bzfab),
1394 dxinv, ascalar, bscalar);
1400template <
typename MF>
1404 bool support =
false;
1405 if (this->m_overset_mask[0][0]) {
1407 this->mg_domain_min_width)
1416template <
typename MF>
1417std::unique_ptr<MLLinOpT<MF>>
1420 if (this->m_overset_mask[0][0] ==
nullptr) {
return nullptr; }
1422 const Geometry& geom = this->m_geom[0].back();
1423 const BoxArray& ba = this->m_grids[0].back();
1426 std::unique_ptr<MLLinOpT<MF>> r
1436 nop->setMaxOrder(this->maxorder);
1437 nop->setVerbose(this->verbose);
1439 nop->setDomainBC(this->m_lobc, this->m_hibc);
1441 if (this->needsCoarseDataForBC())
1443 const Real* dx0 = this->m_geom[0][0].CellSize();
1444 RealVect fac(this->m_coarse_data_crse_ratio);
1447 nop->setCoarseFineBCLocation(cbloc);
1452 const RT ascalar = (m_a_scalar ==
RT(0.0)) ?
RT(1.0) : m_a_scalar;
1453 const RT afac = m_a_scalar / ascalar;
1454 nop->setScalars(ascalar, m_b_scalar);
1456 MF
const& alpha_bottom = m_a_coeffs[0].back();
1457 iMultiFab const& osm_bottom = *(this->m_overset_mask[0].back());
1458 const int ncomp = alpha_bottom.
nComp();
1461 RT a_max = alpha_bottom.norminf(0, ncomp,
IntVect(0),
true,
true);
1462 const int ncomp_b = m_b_coeffs[0].back()[0].nComp();
1464 RT by_max = m_b_coeffs[0].back()[1].
norminf(0,ncomp_b,
IntVect(0),
true,
true);,
1465 RT bz_max = m_b_coeffs[0].back()[2].
norminf(0,ncomp_b,
IntVect(0),
true,
true));
1470 RT huge_alpha =
RT(1.e30) *
1472 AMREX_D_DECL(std::abs(m_b_scalar)*bx_max*dxinv[0]*dxinv[0],
1473 std::abs(m_b_scalar)*by_max*dxinv[1]*dxinv[1],
1474 std::abs(m_b_scalar)*bz_max*dxinv[2]*dxinv[2]));
1479 auto const& ama = alpha.arrays();
1480 auto const& abotma = alpha_bottom.const_arrays();
1485 if (mma[box_no](i,j,k)) {
1486 ama[box_no](i,j,k,n) = afac*abotma[box_no](i,j,k,n);
1488 ama[box_no](i,j,k,n) = huge_alpha;
1498#pragma omp parallel if (Gpu::notInLaunchRegion())
1501 Box const& bx = mfi.tilebox();
1502 auto const& a = alpha.array(mfi);
1503 auto const& abot = alpha_bottom.const_array(mfi);
1508 a(i,j,k,n) = afac*abot(i,j,k,n);
1510 a(i,j,k,n) = huge_alpha;
1516 nop->setACoeffs(0, alpha);
1522template <
typename MF>
1526 if (this->m_overset_mask[0].back() ==
nullptr) {
return; }
1528 const int ncomp = dst.nComp();
1532 auto const& dstma = dst.arrays();
1533 auto const& srcma = src.const_arrays();
1534 auto const& mma = this->m_overset_mask[0].back()->const_arrays();
1538 if (mma[box_no](i,j,k)) {
1539 dstma[box_no](i,j,k,n) = srcma[box_no](i,j,k,n);
1541 dstma[box_no](i,j,k,n) =
RT(0.0);
1551#pragma omp parallel if (Gpu::notInLaunchRegion())
1554 Box const& bx = mfi.tilebox();
1555 auto const& dfab = dst.array(mfi);
1556 auto const& sfab = src.const_array(mfi);
1557 auto const& m = this->m_overset_mask[0].back()->const_array(mfi);
1561 dfab(i,j,k,n) = sfab(i,j,k,n);
1563 dfab(i,j,k,n) =
RT(0.0);
#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_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:37
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_GPU_LAUNCH_HOST_DEVICE_LAMBDA_RANGE(TN, TI, block)
Definition AMReX_GpuLaunchMacrosC.nolint.H:4
#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_LAUNCH_HOST_DEVICE_LAMBDA_DIM(...)
Definition AMReX_GpuLaunch.nolint.H:37
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
Array4< Real > fine
Definition AMReX_InterpFaceRegister.cpp:90
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
GpuArray< Real, 3 > beta
Definition AMReX_MLEBNodeFDLaplacian.cpp:1099
#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
__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
int nComp() const noexcept
Return number of variables (aka components) associated with each point.
Definition AMReX_FabArrayBase.H:88
MultiArray4< typename FabArray< FAB >::value_type const > const_arrays() const noexcept
Read-only convenience wrapper equivalent to arrays() const.
Definition AMReX_FabArray.H:731
Array4< typename FabArray< FAB >::value_type const > const_array(const MFIter &mfi) const noexcept
Synonym for array(const MFIter&) that highlights read-only semantics.
Definition AMReX_FabArray.H:649
Abstract factory interface for creating, aliasing, and destroying FAB objects.
Definition AMReX_FabFactory.H:73
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:85
__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
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
Definition AMReX_MLABecLaplacian.H:22
RT getBScalar() const final
Scalar beta applied to the b-coefficient term.
Definition AMReX_MLABecLaplacian.H:209
int getNComp() const override
Return number of components.
Definition AMReX_MLABecLaplacian.H:167
void FFlux(int amrlev, const MFIter &mfi, const Array< FAB *, 3 > &flux, const FAB &sol, Location, int face_only=0) const override
Compute fluxes on AMR level amrlev for the tilebox described by mfi using sol, writing to flux and ho...
Definition AMReX_MLABecLaplacian.H:1251
void setACoeffs(int amrlev, const AMF &alpha)
Definition AMReX_MLABecLaplacian.H:393
bool isSingular(int amrlev) const override
Query whether AMR level amrlev is singular (null space present).
Definition AMReX_MLABecLaplacian.H:179
void applyRobinBCTermsCoeffs()
Modify coefficients to honor Robin BC terms introduced at level boundaries.
Definition AMReX_MLABecLaplacian.H:684
Vector< Vector< Array< MF, 3 > > > m_b_coeffs
Definition AMReX_MLABecLaplacian.H:260
typename MF::fab_type FAB
Definition AMReX_MLABecLaplacian.H:25
void setBCoeffs(int amrlev, const Array< AMF const *, 3 > &beta)
Definition AMReX_MLABecLaplacian.H:420
MLABecLaplacianT< MF > & operator=(const MLABecLaplacianT< MF > &)=delete
bool supportRobinBC() const noexcept override
Definition AMReX_MLABecLaplacian.H:270
RT m_b_scalar
Definition AMReX_MLABecLaplacian.H:258
typename MF::value_type RT
Definition AMReX_MLABecLaplacian.H:26
~MLABecLaplacianT() override
void prepareForSolve() override
Finalize singular flags and metric/Robin adjustments prior to calling MLMG.
Definition AMReX_MLABecLaplacian.H:496
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={}, int a_ncomp=1)
Define coefficients/layouts for a standard cell-centered solve.
Definition AMReX_MLABecLaplacian.H:313
RT m_a_scalar
Definition AMReX_MLABecLaplacian.H:257
void averageDownCoeffsToCoarseAmrLevel(int flev)
Average coefficients from fine AMR level flev to coarse AMR level flev-1.
Definition AMReX_MLABecLaplacian.H:799
void averageDownCoeffsSameAmrLevel(int amrlev, Vector< MF > &a, Vector< Array< MF, 3 > > &b)
Average coefficients down within AMR level amrlev (fine-to-coarse multigrid) updating a and b.
Definition AMReX_MLABecLaplacian.H:711
bool m_scalars_set
Definition AMReX_MLABecLaplacian.H:262
Vector< int > m_is_singular
Definition AMReX_MLABecLaplacian.H:267
void averageDownCoeffs()
Average a and b coefficients down across all AMR and MG levels.
Definition AMReX_MLABecLaplacian.H:693
RT getAScalar() const final
Scalar alpha applied to the a-coefficient term.
Definition AMReX_MLABecLaplacian.H:207
void normalize(int amrlev, int mglev, MF &mf) const override
Divide mf by the diagonal of the operator (used by CG-family bottom solvers).
Definition AMReX_MLABecLaplacian.H:1340
void Fsmooth(int amrlev, int mglev, MF &sol, const MF &rhs, int redblack) const override
Perform one smoothing pass on (amrlev,mglev) updating sol against rhs. redblack selects the red (0) o...
Definition AMReX_MLABecLaplacian.H:964
std::unique_ptr< MLLinOpT< MF > > makeNLinOp(int) const final
Build the NSolve counterpart of this operator.
Definition AMReX_MLABecLaplacian.H:1418
bool m_acoef_set
Definition AMReX_MLABecLaplacian.H:263
Array< MF const *, 3 > getBCoeffs(int amrlev, int mglev) const final
Access the stored b coefficients on AMR level amrlev and MG level mglev.
Definition AMReX_MLABecLaplacian.H:214
MLABecLaplacianT(MLABecLaplacianT< MF > &&)=delete
Vector< Vector< MF > > m_a_coeffs
Definition AMReX_MLABecLaplacian.H:259
void setScalars(T1 a, T2 b) noexcept
Definition AMReX_MLABecLaplacian.H:375
bool isBottomSingular() const override
Convenience helper for the coarsest level singularity flag.
Definition AMReX_MLABecLaplacian.H:181
void applyMetricTermsCoeffs()
Apply metric factors to the stored coefficients when solving in mapped space.
Definition AMReX_MLABecLaplacian.H:517
void copyNSolveSolution(MF &dst, MF const &src) const final
Copy an NSolve solution from src to dst.
Definition AMReX_MLABecLaplacian.H:1524
bool supportNSolve() const override
Whether this operator supports NSolve.
Definition AMReX_MLABecLaplacian.H:1402
MLABecLaplacianT()=default
Construct an empty operator; call define() before solving.
typename MLLinOpT< MF >::Location Location
Definition AMReX_MLABecLaplacian.H:29
MF const * getACoeffs(int amrlev, int mglev) const final
Access the stored a coefficient on AMR level amrlev and MG level mglev.
Definition AMReX_MLABecLaplacian.H:211
void update() override
Average coefficients and enforce boundary-provided adjustments when needed.
Definition AMReX_MLABecLaplacian.H:475
bool needsUpdate() const override
True if coefficients need to be averaged down before the next apply().
Definition AMReX_MLABecLaplacian.H:170
void Fapply(int amrlev, int mglev, MF &out, const MF &in) const override
Apply the operator on (amrlev,mglev), storing L(in) in out.
Definition AMReX_MLABecLaplacian.H:881
MLABecLaplacianT(const MLABecLaplacianT< MF > &)=delete
Cell-centered operator that exposes ABec Laplacian helpers to derived classes.
Definition AMReX_MLCellABecLap.H:22
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
void update() override
Average coefficients/metrics when marked dirty.
Definition AMReX_MLCellABecLap.H:302
static constexpr int mg_coarsen_ratio
Definition AMReX_MLLinOp.H:878
static constexpr int mg_box_min_width
Definition AMReX_MLLinOp.H:879
const MLLinOpT< MF > * m_parent
Definition AMReX_MLLinOp.H:894
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
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
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 > 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
std::array< T, N > Array
Definition AMReX_Array.H:31
Arena * The_Async_Arena()
Definition AMReX_Arena.cpp:825
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:53
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
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 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
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
void average_down_faces(const Vector< const MF * > &fine, const Vector< MF * > &crse, const IntVect &ratio, int ngcrse=0)
Average fine face-based FabArray onto crse face-based FabArray.
Definition AMReX_MultiFabUtil.H:1059
std::array< T *, 3 > GetArrOfPtrs(std::array< T, 3 > &a) noexcept
Create an array of pointers from an array of objects.
Definition AMReX_Array.H:1033
int nComp(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nComp().
Definition AMReX_FabArrayBase.cpp:2860
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
MF::value_type norminf(MF const &mf, int scomp, int ncomp, IntVect const &nghost, bool local=false)
Return the infinity norm, with an MPI maximum unless local is true.
Definition AMReX_FabArrayUtility.H:2262
__host__ __device__ Dim3 end(BoxND< dim > const &box) noexcept
Return the iterator end coordinate of box as Dim3.
Definition AMReX_Box.H:2257
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:52
Definition AMReX_GpuDevice.H:574
Configuration knobs for multilevel linear operators (grid agglomeration, metrics, etc....
Definition AMReX_MLLinOp.H:51
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