Skip to content

Commit f24582d

Browse files
authored
Solvability of bottom solver: Follow-up on #2783 (#2801)
In #2783, the solvability fix at the bottom level of EB nodal projection solver was disabled because we don't have sufficient geometry information. This broke a number of tests. It appears that we should still do the best we can (i.e., use the old approach at the bottom level).
1 parent 1dff173 commit f24582d

File tree

1 file changed

+77
-83
lines changed

1 file changed

+77
-83
lines changed

Src/LinearSolvers/MLMG/AMReX_MLNodeLaplacian.cpp

Lines changed: 77 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -181,59 +181,55 @@ MLNodeLaplacian::getSolvabilityOffset (int amrlev, int mglev, MultiFab const& rh
181181
if (m_coarsening_strategy == CoarseningStrategy::RAP) {
182182
#ifdef AMREX_USE_EB
183183
auto factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][0].get());
184-
if (factory && !factory->isAllRegular()) {
185-
if (mglev > 0) {
186-
return 0._rt;
187-
} else {
188-
const MultiFab& vfrac = factory->getVolFrac();
189-
const auto& vfrac_ma = vfrac.const_arrays();
184+
if (mglev == 0 && factory && !factory->isAllRegular()) {
185+
const MultiFab& vfrac = factory->getVolFrac();
186+
const auto& vfrac_ma = vfrac.const_arrays();
190187

191-
Box dom = Geom(amrlev,mglev).Domain();
192-
for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
193-
if (m_lobc[0][idim] != LinOpBCType::Neumann &&
194-
m_lobc[0][idim] != LinOpBCType::inflow)
195-
{
196-
dom.growLo(idim, 10);
197-
}
198-
if (m_hibc[0][idim] != LinOpBCType::Neumann &&
199-
m_hibc[0][idim] != LinOpBCType::inflow)
200-
{
201-
dom.growHi(idim, 10);
202-
}
188+
Box dom = Geom(amrlev,mglev).Domain();
189+
for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
190+
if (m_lobc[0][idim] != LinOpBCType::Neumann &&
191+
m_lobc[0][idim] != LinOpBCType::inflow)
192+
{
193+
dom.growLo(idim, 10);
194+
}
195+
if (m_hibc[0][idim] != LinOpBCType::Neumann &&
196+
m_hibc[0][idim] != LinOpBCType::inflow)
197+
{
198+
dom.growHi(idim, 10);
203199
}
200+
}
204201

205-
const auto& mask = (mglev+1 == m_num_mg_levels[0]) ? m_bottom_dot_mask : m_coarse_dot_mask;
206-
const auto& mask_ma = mask.const_arrays();
207-
const auto& rhs_ma = rhs.const_arrays();
208-
auto r = ParReduce(TypeList<ReduceOpSum,ReduceOpSum>{}, TypeList<Real,Real>{},
209-
rhs, IntVect(0),
210-
[=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
211-
-> GpuTuple<Real,Real>
212-
{
213-
Real scale = 0.0_rt;
202+
const auto& mask = (mglev+1 == m_num_mg_levels[0]) ? m_bottom_dot_mask : m_coarse_dot_mask;
203+
const auto& mask_ma = mask.const_arrays();
204+
const auto& rhs_ma = rhs.const_arrays();
205+
auto r = ParReduce(TypeList<ReduceOpSum,ReduceOpSum>{}, TypeList<Real,Real>{},
206+
rhs, IntVect(0),
207+
[=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
208+
-> GpuTuple<Real,Real>
209+
{
210+
Real scale = 0.0_rt;
214211
#if (AMREX_SPACEDIM == 3)
215-
int const koff = 1;
216-
Real const fac = 0.125_rt;
212+
int const koff = 1;
213+
Real const fac = 0.125_rt;
217214
#else
218-
int const koff = 0;
219-
Real const fac = 0.25_rt;
215+
int const koff = 0;
216+
Real const fac = 0.25_rt;
220217
#endif
221-
for (int kc = k-koff; kc <= k; ++kc) {
222-
for (int jc = j-1 ; jc <= j; ++jc) {
223-
for (int ic = i-1 ; ic <= i; ++ic) {
224-
if (dom.contains(ic,jc,kc)) {
225-
scale += vfrac_ma[box_no](ic,jc,kc) * fac;
226-
}
227-
}}}
228-
return { mask_ma[box_no](i,j,k) * rhs_ma[box_no](i,j,k),
229-
mask_ma[box_no](i,j,k) * scale };
230-
});
231-
232-
Real s1 = amrex::get<0>(r);
233-
Real s2 = amrex::get<1>(r);
234-
ParallelAllReduce::Sum<Real>({s1,s2}, ParallelContext::CommunicatorSub());
235-
return s1/s2;
236-
}
218+
for (int kc = k-koff; kc <= k; ++kc) {
219+
for (int jc = j-1 ; jc <= j; ++jc) {
220+
for (int ic = i-1 ; ic <= i; ++ic) {
221+
if (dom.contains(ic,jc,kc)) {
222+
scale += vfrac_ma[box_no](ic,jc,kc) * fac;
223+
}
224+
}}}
225+
return { mask_ma[box_no](i,j,k) * rhs_ma[box_no](i,j,k),
226+
mask_ma[box_no](i,j,k) * scale };
227+
});
228+
229+
Real s1 = amrex::get<0>(r);
230+
Real s2 = amrex::get<1>(r);
231+
ParallelAllReduce::Sum<Real>({s1,s2}, ParallelContext::CommunicatorSub());
232+
return s1/s2;
237233
} else
238234
#endif
239235
{
@@ -296,47 +292,45 @@ MLNodeLaplacian::fixSolvabilityByOffset (int amrlev, int mglev, MultiFab& rhs, R
296292
if (m_coarsening_strategy == CoarseningStrategy::RAP) {
297293
#ifdef AMREX_USE_EB
298294
auto factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][0].get());
299-
if (factory && !factory->isAllRegular()) {
300-
if (mglev == 0) {
301-
const MultiFab& vfrac = factory->getVolFrac();
302-
const auto& vfrac_ma = vfrac.const_arrays();
303-
304-
Box dom = Geom(amrlev,mglev).Domain();
305-
for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
306-
if (m_lobc[0][idim] != LinOpBCType::Neumann &&
307-
m_lobc[0][idim] != LinOpBCType::inflow)
308-
{
309-
dom.growLo(idim, 10);
310-
}
311-
if (m_hibc[0][idim] != LinOpBCType::Neumann &&
312-
m_hibc[0][idim] != LinOpBCType::inflow)
313-
{
314-
dom.growHi(idim, 10);
315-
}
295+
if (mglev == 0 && factory && !factory->isAllRegular()) {
296+
const MultiFab& vfrac = factory->getVolFrac();
297+
const auto& vfrac_ma = vfrac.const_arrays();
298+
299+
Box dom = Geom(amrlev,mglev).Domain();
300+
for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
301+
if (m_lobc[0][idim] != LinOpBCType::Neumann &&
302+
m_lobc[0][idim] != LinOpBCType::inflow)
303+
{
304+
dom.growLo(idim, 10);
316305
}
306+
if (m_hibc[0][idim] != LinOpBCType::Neumann &&
307+
m_hibc[0][idim] != LinOpBCType::inflow)
308+
{
309+
dom.growHi(idim, 10);
310+
}
311+
}
317312

318-
auto const& rhs_ma = rhs.arrays();
319-
ParallelFor(rhs, IntVect(0),
320-
[=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
321-
{
322-
Real scale = 0.0_rt;
313+
auto const& rhs_ma = rhs.arrays();
314+
ParallelFor(rhs, IntVect(0),
315+
[=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
316+
{
317+
Real scale = 0.0_rt;
323318
#if (AMREX_SPACEDIM == 3)
324-
int const koff = 1;
325-
Real const fac = 0.125_rt;
319+
int const koff = 1;
320+
Real const fac = 0.125_rt;
326321
#else
327-
int const koff = 0;
328-
Real const fac = 0.25_rt;
322+
int const koff = 0;
323+
Real const fac = 0.25_rt;
329324
#endif
330-
for (int kc = k-koff; kc <= k; ++kc) {
331-
for (int jc = j-1 ; jc <= j; ++jc) {
332-
for (int ic = i-1 ; ic <= i; ++ic) {
333-
if (dom.contains(ic,jc,kc)) {
334-
scale += vfrac_ma[box_no](ic,jc,kc) * fac;
335-
}
336-
}}}
337-
rhs_ma[box_no](i,j,k) -= offset * scale;
338-
});
339-
}
325+
for (int kc = k-koff; kc <= k; ++kc) {
326+
for (int jc = j-1 ; jc <= j; ++jc) {
327+
for (int ic = i-1 ; ic <= i; ++ic) {
328+
if (dom.contains(ic,jc,kc)) {
329+
scale += vfrac_ma[box_no](ic,jc,kc) * fac;
330+
}
331+
}}}
332+
rhs_ma[box_no](i,j,k) -= offset * scale;
333+
});
340334
} else
341335
#endif
342336
{

0 commit comments

Comments
 (0)