Skip to content

Commit 60b45bc

Browse files
authored
MLEBABecLap: Support Robin BC at Domain Boundaries (#3617)
1 parent 9e35dc1 commit 60b45bc

File tree

5 files changed

+71
-46
lines changed

5 files changed

+71
-46
lines changed

Src/LinearSolvers/MLMG/AMReX_MLABecLaplacian.H

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,15 @@ public:
190190
Array<FAB*,AMREX_SPACEDIM> const& flux,
191191
FAB const& sol, int face_only, int ncomp);
192192

193-
protected:
194-
195-
bool m_needs_update = true;
196-
197193
RT m_a_scalar = std::numeric_limits<RT>::quiet_NaN();
198194
RT m_b_scalar = std::numeric_limits<RT>::quiet_NaN();
199195
Vector<Vector<MF> > m_a_coeffs;
200196
Vector<Vector<Array<MF,AMREX_SPACEDIM> > > m_b_coeffs;
201197

198+
protected:
199+
200+
bool m_needs_update = true;
201+
202202
Vector<int> m_is_singular;
203203

204204
[[nodiscard]] bool supportRobinBC () const noexcept override { return true; }
@@ -474,29 +474,29 @@ MLABecLaplacianT<MF>::applyMetricTermsCoeffs ()
474474
// \tilde{alpha}_i = alpha_i + (1-B) beta_{i+1/2} / h^2
475475
// \tilde{rhs}_i = rhs_i + A beta_{i+1/2} / h^2
476476
//
477-
template <typename MF>
478-
void
479-
MLABecLaplacianT<MF>::applyRobinBCTermsCoeffs ()
477+
namespace detail {
478+
template <typename LP>
479+
void applyRobinBCTermsCoeffs (LP& linop)
480480
{
481-
if (!(this->hasRobinBC())) { return; }
481+
using RT = typename LP::RT;
482482

483-
const int ncomp = this->getNComp();
483+
const int ncomp = linop.getNComp();
484484
bool reset_alpha = false;
485-
if (m_a_scalar == RT(0.0)) {
486-
m_a_scalar = RT(1.0);
485+
if (linop.m_a_scalar == RT(0.0)) {
486+
linop.m_a_scalar = RT(1.0);
487487
reset_alpha = true;
488488
}
489-
const RT bovera = m_b_scalar/m_a_scalar;
489+
const RT bovera = linop.m_b_scalar/linop.m_a_scalar;
490490

491-
for (int amrlev = 0; amrlev < this->m_num_amr_levels; ++amrlev) {
491+
for (int amrlev = 0; amrlev < linop.NAMRLevels(); ++amrlev) {
492492
const int mglev = 0;
493-
const Box& domain = this->m_geom[amrlev][mglev].Domain();
494-
const RT dxi = static_cast<RT>(this->m_geom[amrlev][mglev].InvCellSize(0));
495-
const RT dyi = static_cast<RT>((AMREX_SPACEDIM >= 2) ? this->m_geom[amrlev][mglev].InvCellSize(1) : Real(1.0));
496-
const RT dzi = static_cast<RT>((AMREX_SPACEDIM == 3) ? this->m_geom[amrlev][mglev].InvCellSize(2) : Real(1.0));
493+
const Box& domain = linop.Geom(amrlev,mglev).Domain();
494+
const RT dxi = static_cast<RT>(linop.Geom(amrlev,mglev).InvCellSize(0));
495+
const RT dyi = static_cast<RT>((AMREX_SPACEDIM >= 2) ? linop.Geom(amrlev,mglev).InvCellSize(1) : Real(1.0));
496+
const RT dzi = static_cast<RT>((AMREX_SPACEDIM == 3) ? linop.Geom(amrlev,mglev).InvCellSize(2) : Real(1.0));
497497

498498
if (reset_alpha) {
499-
m_a_coeffs[amrlev][mglev].setVal(RT(0.0));
499+
linop.m_a_coeffs[amrlev][mglev].setVal(RT(0.0));
500500
}
501501

502502
MFItInfo mfi_info;
@@ -505,20 +505,20 @@ MLABecLaplacianT<MF>::applyRobinBCTermsCoeffs ()
505505
#ifdef AMREX_USE_OMP
506506
#pragma omp parallel if (Gpu::notInLaunchRegion())
507507
#endif
508-
for (MFIter mfi(m_a_coeffs[amrlev][mglev], mfi_info); mfi.isValid(); ++mfi)
508+
for (MFIter mfi(linop.m_a_coeffs[amrlev][mglev], mfi_info); mfi.isValid(); ++mfi)
509509
{
510510
const Box& vbx = mfi.validbox();
511-
auto const& afab = m_a_coeffs[amrlev][mglev].array(mfi);
511+
auto const& afab = linop.m_a_coeffs[amrlev][mglev].array(mfi);
512512
for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
513-
auto const& bfab = m_b_coeffs[amrlev][mglev][idim].const_array(mfi);
513+
auto const& bfab = linop.m_b_coeffs[amrlev][mglev][idim].const_array(mfi);
514514
const Box& blo = amrex::adjCellLo(vbx,idim);
515515
const Box& bhi = amrex::adjCellHi(vbx,idim);
516516
bool outside_domain_lo = !(domain.contains(blo));
517517
bool outside_domain_hi = !(domain.contains(bhi));
518518
if ((!outside_domain_lo) && (!outside_domain_hi)) { continue; }
519519
for (int icomp = 0; icomp < ncomp; ++icomp) {
520-
auto const& rbc = (*(this->m_robin_bcval[amrlev]))[mfi].const_array(icomp*3);
521-
if (this->m_lobc_orig[icomp][idim] == LinOpBCType::Robin && outside_domain_lo)
520+
auto const& rbc = (*(linop.m_robin_bcval[amrlev]))[mfi].const_array(icomp*3);
521+
if (linop.m_lobc_orig[icomp][idim] == LinOpBCType::Robin && outside_domain_lo)
522522
{
523523
if (idim == 0) {
524524
RT fac = bovera*dxi*dxi;
@@ -546,7 +546,7 @@ MLABecLaplacianT<MF>::applyRobinBCTermsCoeffs ()
546546
});
547547
}
548548
}
549-
if (this->m_hibc_orig[icomp][idim] == LinOpBCType::Robin && outside_domain_hi)
549+
if (linop.m_hibc_orig[icomp][idim] == LinOpBCType::Robin && outside_domain_hi)
550550
{
551551
if (idim == 0) {
552552
RT fac = bovera*dxi*dxi;
@@ -579,6 +579,16 @@ MLABecLaplacianT<MF>::applyRobinBCTermsCoeffs ()
579579
}
580580
}
581581
}
582+
} // namespace detail
583+
584+
template <typename MF>
585+
void
586+
MLABecLaplacianT<MF>::applyRobinBCTermsCoeffs ()
587+
{
588+
if (this->hasRobinBC()) {
589+
detail::applyRobinBCTermsCoeffs(*this);
590+
}
591+
}
582592

583593
template <typename MF>
584594
void

Src/LinearSolvers/MLMG/AMReX_MLCellLinOp.H

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ public:
131131
RT location;
132132
};
133133

134+
Vector<std::unique_ptr<MF> > m_robin_bcval;
135+
134136
protected:
135137

136138
bool m_has_metric_term = false;
@@ -182,8 +184,6 @@ protected:
182184
};
183185
Vector<Vector<std::unique_ptr<BndryCondLoc> > > m_bcondloc;
184186

185-
Vector<std::unique_ptr<MF> > m_robin_bcval;
186-
187187
// used to save interpolation coefficients of the first interior cells
188188
mutable Vector<Vector<BndryRegisterT<MF>> > m_undrrelxr;
189189

Src/LinearSolvers/MLMG/AMReX_MLEBABecLap.H

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ public:
114114
void getEBFluxes (const Vector<MultiFab*>& a_flux,
115115
const Vector<MultiFab*>& a_sol) const override;
116116

117+
void applyRobinBCTermsCoeffs ();
118+
117119
#if defined(AMREX_USE_HYPRE) && (AMREX_SPACEDIM > 1)
118120
[[nodiscard]] std::unique_ptr<Hypre> makeHypre (Hypre::Interface hypre_interface) const override;
119121
#endif
@@ -122,6 +124,11 @@ public:
122124
[[nodiscard]] std::unique_ptr<PETScABecLap> makePETSc () const override;
123125
#endif
124126

127+
Real m_a_scalar = std::numeric_limits<Real>::quiet_NaN();
128+
Real m_b_scalar = std::numeric_limits<Real>::quiet_NaN();
129+
Vector<Vector<MultiFab> > m_a_coeffs;
130+
Vector<Vector<Array<MultiFab,AMREX_SPACEDIM> > > m_b_coeffs;
131+
125132
protected:
126133

127134
int m_ncomp = 1;
@@ -131,10 +138,6 @@ protected:
131138
Location m_beta_loc; // Location of coefficients: face centers or face centroids
132139
Location m_phi_loc; // Location of solution variable: cell centers or cell centroids
133140

134-
Real m_a_scalar = std::numeric_limits<Real>::quiet_NaN();
135-
Real m_b_scalar = std::numeric_limits<Real>::quiet_NaN();
136-
Vector<Vector<MultiFab> > m_a_coeffs;
137-
Vector<Vector<Array<MultiFab,AMREX_SPACEDIM> > > m_b_coeffs;
138141
Vector<Vector<iMultiFab> > m_cc_mask;
139142

140143
Vector<std::unique_ptr<MultiFab> > m_eb_phi;
@@ -154,6 +157,8 @@ protected:
154157
const Vector<MultiFab*>& b_eb);
155158
void averageDownCoeffs ();
156159
void averageDownCoeffsToCoarseAmrLevel (int flev);
160+
161+
[[nodiscard]] bool supportRobinBC () const noexcept override { return true; }
157162
};
158163

159164
}

Src/LinearSolvers/MLMG/AMReX_MLEBABecLap.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,8 @@ MLEBABecLap::prepareForSolve ()
685685

686686
MLCellABecLap::prepareForSolve();
687687

688+
applyRobinBCTermsCoeffs();
689+
688690
averageDownCoeffs();
689691

690692
if (m_eb_phi[0]) {
@@ -1285,6 +1287,14 @@ MLEBABecLap::getEBFluxes (const Vector<MultiFab*>& a_flux, const Vector<MultiFab
12851287
}
12861288
}
12871289

1290+
void
1291+
MLEBABecLap::applyRobinBCTermsCoeffs ()
1292+
{
1293+
if (this->hasRobinBC()) {
1294+
detail::applyRobinBCTermsCoeffs(*this);
1295+
}
1296+
}
1297+
12881298
#if defined(AMREX_USE_HYPRE) && (AMREX_SPACEDIM > 1)
12891299
std::unique_ptr<Hypre>
12901300
MLEBABecLap::makeHypre (Hypre::Interface hypre_interface) const

Src/LinearSolvers/MLMG/AMReX_MLLinOp.H

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,22 @@ public:
488488

489489
[[nodiscard]] bool isMFIterSafe (int amrlev, int mglev1, int mglev2) const;
490490

491+
//! Return the number of AMR levels
492+
[[nodiscard]] int NAMRLevels () const noexcept { return m_num_amr_levels; }
493+
494+
//! Return the number of MG levels at given AMR level
495+
[[nodiscard]] int NMGLevels (int amrlev) const noexcept { return m_num_mg_levels[amrlev]; }
496+
497+
[[nodiscard]] const Geometry& Geom (int amr_lev, int mglev=0) const noexcept { return m_geom[amr_lev][mglev]; }
498+
499+
// BC
500+
Vector<Array<BCType, AMREX_SPACEDIM> > m_lobc;
501+
Vector<Array<BCType, AMREX_SPACEDIM> > m_hibc;
502+
// Need to save the original copy because we change the BC type to
503+
// Neumann for inhomogeneous Neumann and Robin.
504+
Vector<Array<BCType, AMREX_SPACEDIM> > m_lobc_orig;
505+
Vector<Array<BCType, AMREX_SPACEDIM> > m_hibc_orig;
506+
491507
protected:
492508

493509
static constexpr int mg_coarsen_ratio = 2;
@@ -544,14 +560,6 @@ protected:
544560
};
545561
std::unique_ptr<CommContainer> m_raii_comm;
546562

547-
// BC
548-
Vector<Array<BCType, AMREX_SPACEDIM> > m_lobc;
549-
Vector<Array<BCType, AMREX_SPACEDIM> > m_hibc;
550-
// Need to save the original copy because we change the BC type to
551-
// Neumann for inhomogeneous Neumann and Robin.
552-
Vector<Array<BCType, AMREX_SPACEDIM> > m_lobc_orig;
553-
Vector<Array<BCType, AMREX_SPACEDIM> > m_hibc_orig;
554-
555563
Array<Real, AMREX_SPACEDIM> m_domain_bloc_lo {{AMREX_D_DECL(0._rt,0._rt,0._rt)}};
556564
Array<Real, AMREX_SPACEDIM> m_domain_bloc_hi {{AMREX_D_DECL(0._rt,0._rt,0._rt)}};
557565

@@ -561,20 +569,12 @@ protected:
561569
const MF* m_coarse_data_for_bc = nullptr;
562570
MF m_coarse_data_for_bc_raii;
563571

564-
//! Return the number of AMR levels
565-
[[nodiscard]] int NAMRLevels () const noexcept { return m_num_amr_levels; }
566-
567-
//! Return the number of MG levels at given AMR level
568-
[[nodiscard]] int NMGLevels (int amrlev) const noexcept { return m_num_mg_levels[amrlev]; }
569-
570572
//! Return AMR refinement ratios
571573
[[nodiscard]] const Vector<int>& AMRRefRatio () const noexcept { return m_amr_ref_ratio; }
572574

573575
//! Return AMR refinement ratio at given AMR level
574576
[[nodiscard]] int AMRRefRatio (int amr_lev) const noexcept { return m_amr_ref_ratio[amr_lev]; }
575577

576-
[[nodiscard]] const Geometry& Geom (int amr_lev, int mglev=0) const noexcept { return m_geom[amr_lev][mglev]; }
577-
578578
[[nodiscard]] FabFactory<FAB> const* Factory (int amr_lev, int mglev=0) const noexcept {
579579
return m_factory[amr_lev][mglev].get();
580580
}

0 commit comments

Comments
 (0)