Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MLEBNodeFDLaplacian: Make it work with AMREX_USE_EB but with no EB #4083

Merged
merged 4 commits into from
Aug 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 48 additions & 34 deletions Src/LinearSolvers/MLMG/AMReX_MLEBNodeFDLaplacian.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <AMReX_MultiFabUtil.H>

#ifdef AMREX_USE_EB
#include <AMReX_EB2.H>
#include <AMReX_EBMultiFabUtil.H>
#endif

Expand Down Expand Up @@ -151,10 +152,14 @@ MLEBNodeFDLaplacian::define (const Vector<Geometry>& a_geom,
std::unique_ptr<FabFactory<FArrayBox> >
MLEBNodeFDLaplacian::makeFactory (int amrlev, int mglev) const
{
return makeEBFabFactory(m_geom[amrlev][mglev],
m_grids[amrlev][mglev],
m_dmap[amrlev][mglev],
{1,1,1}, EBSupport::full);
if (EB2::TopIndexSpaceIfPresent()) {
return makeEBFabFactory(m_geom[amrlev][mglev],
m_grids[amrlev][mglev],
m_dmap[amrlev][mglev],
{1,1,1}, EBSupport::full);
} else {
return MLNodeLinOp::makeFactory(amrlev, mglev);
}
}
#endif

Expand Down Expand Up @@ -264,17 +269,19 @@ MLEBNodeFDLaplacian::prepareForSolve ()
for (int amrlev = 0; amrlev < m_num_amr_levels; ++amrlev) {
for (int mglev = 0; mglev < m_num_mg_levels[amrlev]; ++mglev) {
const auto *factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][mglev].get());
auto const& levset_mf = factory->getLevelSet();
auto const& levset_ar = levset_mf.const_arrays();
auto& dmask_mf = *m_dirichlet_mask[amrlev][mglev];
auto const& dmask_ar = dmask_mf.arrays();
amrex::ParallelFor(dmask_mf,
[=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
{
if (levset_ar[box_no](i,j,k) >= Real(0.0)) {
dmask_ar[box_no](i,j,k) = -1;
}
});
if (factory) {
auto const& levset_mf = factory->getLevelSet();
auto const& levset_ar = levset_mf.const_arrays();
auto& dmask_mf = *m_dirichlet_mask[amrlev][mglev];
auto const& dmask_ar = dmask_mf.arrays();
amrex::ParallelFor(dmask_mf,
[=] AMREX_GPU_DEVICE (int box_no, int i, int j, int k) noexcept
{
if (levset_ar[box_no](i,j,k) >= Real(0.0)) {
dmask_ar[box_no](i,j,k) = -1;
}
});
}
}
}
#endif
Expand Down Expand Up @@ -359,8 +366,10 @@ MLEBNodeFDLaplacian::prepareForSolve ()
void
MLEBNodeFDLaplacian::scaleRHS (int amrlev, MultiFab& rhs) const
{
auto const& dmask = *m_dirichlet_mask[amrlev][0];
const auto *factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][0].get());
if (!factory) { return; }

auto const& dmask = *m_dirichlet_mask[amrlev][0];
auto const& edgecent = factory->getEdgeCent();

#ifdef AMREX_USE_OMP
Expand Down Expand Up @@ -407,9 +416,10 @@ MLEBNodeFDLaplacian::Fapply (int amrlev, int mglev, MultiFab& out, const MultiFa
#ifdef AMREX_USE_EB
const auto phieb = (m_in_solution_mode) ? m_s_phi_eb : Real(0.0);
const auto *factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][mglev].get());
auto const& edgecent = factory->getEdgeCent();
auto const& levset_mf = factory->getLevelSet();
auto const& volfrac = factory->getVolFrac();
Array<const MultiCutFab*,AMREX_SPACEDIM> edgecent {AMREX_D_DECL(nullptr,nullptr,nullptr)};
if (factory) {
edgecent = factory->getEdgeCent();
}
#endif

#ifdef AMREX_USE_OMP
Expand All @@ -422,12 +432,12 @@ MLEBNodeFDLaplacian::Fapply (int amrlev, int mglev, MultiFab& out, const MultiFa
Array4<Real> const& yarr = out.array(mfi);
Array4<int const> const& dmarr = dmask.const_array(mfi);
#ifdef AMREX_USE_EB
bool cutfab = edgecent[0]->ok(mfi);
if (cutfab) {
bool cutfab = edgecent[0] && edgecent[0]->ok(mfi);
if (cutfab && factory) { // clang-tidy is not that smart
AMREX_D_TERM(Array4<Real const> const& ecx = edgecent[0]->const_array(mfi);,
Array4<Real const> const& ecy = edgecent[1]->const_array(mfi);,
Array4<Real const> const& ecz = edgecent[2]->const_array(mfi));
auto const& levset = levset_mf.const_array(mfi);
auto const& levset = factory->getVolFrac().const_array(mfi);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a bug

Suggested change
auto const& levset = factory->getVolFrac().const_array(mfi);
auto const& levset = factory->getLevelSet().const_array(mfi);

if (phieb == std::numeric_limits<Real>::lowest()) {
auto const& phiebarr = m_phi_eb[amrlev].const_array(mfi);
#if (AMREX_SPACEDIM == 2)
Expand All @@ -441,7 +451,7 @@ MLEBNodeFDLaplacian::Fapply (int amrlev, int mglev, MultiFab& out, const MultiFa
#endif
if (m_has_sigma_mf) {
auto const& sigarr = m_sigma_mf[amrlev][mglev]->const_array(mfi);
auto const& vfrc = volfrac.const_array(mfi);
auto const& vfrc = factory->getVolFrac().const_array(mfi);
AMREX_HOST_DEVICE_FOR_3D(box, i, j, k,
{
mlebndfdlap_sig_adotx_eb(i,j,k,yarr,xarr,levset,dmarr,AMREX_D_DECL(ecx,ecy,ecz),
Expand All @@ -466,7 +476,7 @@ MLEBNodeFDLaplacian::Fapply (int amrlev, int mglev, MultiFab& out, const MultiFa
#endif
if (m_has_sigma_mf) {
auto const& sigarr = m_sigma_mf[amrlev][mglev]->const_array(mfi);
auto const& vfrc = volfrac.const_array(mfi);
auto const& vfrc = factory->getVolFrac().const_array(mfi);
AMREX_HOST_DEVICE_FOR_3D(box, i, j, k,
{
mlebndfdlap_sig_adotx_eb(i,j,k,yarr,xarr,levset,dmarr,AMREX_D_DECL(ecx,ecy,ecz),
Expand Down Expand Up @@ -533,9 +543,10 @@ MLEBNodeFDLaplacian::Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiF

#ifdef AMREX_USE_EB
const auto *factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][mglev].get());
auto const& edgecent = factory->getEdgeCent();
auto const& levset_mf = factory->getLevelSet();
auto const& volfrac = factory->getVolFrac();
Array<const MultiCutFab*,AMREX_SPACEDIM> edgecent {AMREX_D_DECL(nullptr,nullptr,nullptr)};
if (factory) {
edgecent = factory->getEdgeCent();
}
#endif

#ifdef AMREX_USE_OMP
Expand All @@ -548,12 +559,12 @@ MLEBNodeFDLaplacian::Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiF
Array4<Real const> const& rhsarr = rhs.const_array(mfi);
Array4<int const> const& dmskarr = dmask.const_array(mfi);
#ifdef AMREX_USE_EB
bool cutfab = edgecent[0]->ok(mfi);
if (cutfab) {
bool cutfab = edgecent[0] && edgecent[0]->ok(mfi);
if (cutfab && factory) { // clang-tidy is not that smart
AMREX_D_TERM(Array4<Real const> const& ecx = edgecent[0]->const_array(mfi);,
Array4<Real const> const& ecy = edgecent[1]->const_array(mfi);,
Array4<Real const> const& ecz = edgecent[2]->const_array(mfi));
auto const& levset = levset_mf.const_array(mfi);
auto const& levset = factory->getLevelSet().const_array(mfi);
#if (AMREX_SPACEDIM == 2)
if (m_rz) {
AMREX_HOST_DEVICE_FOR_3D(box, i, j, k,
Expand All @@ -565,7 +576,7 @@ MLEBNodeFDLaplacian::Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiF
#endif
if (m_has_sigma_mf) {
auto const& sigarr = m_sigma_mf[amrlev][mglev]->const_array(mfi);
auto const& vfrc = volfrac.const_array(mfi);
auto const& vfrc = factory->getVolFrac().const_array(mfi);
AMREX_HOST_DEVICE_FOR_3D(box, i, j, k,
{
mlebndfdlap_sig_gsrb_eb(i,j,k,solarr,rhsarr,levset,dmskarr,AMREX_D_DECL(ecx,ecy,ecz),
Expand Down Expand Up @@ -641,8 +652,10 @@ MLEBNodeFDLaplacian::compGrad (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>
auto const& dmask = *m_dirichlet_mask[amrlev][mglev];
const auto phieb = m_s_phi_eb;
const auto *factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][mglev].get());
AMREX_ASSERT(factory);
auto const& edgecent = factory->getEdgeCent();
Array<const MultiCutFab*,AMREX_SPACEDIM> edgecent {AMREX_D_DECL(nullptr,nullptr,nullptr)};
if (factory) {
edgecent = factory->getEdgeCent();
}
#endif

#ifdef AMREX_USE_OMP
Expand All @@ -659,7 +672,7 @@ MLEBNodeFDLaplacian::compGrad (int amrlev, const Array<MultiFab*,AMREX_SPACEDIM>
Array4<Real> const& gpz = grad[2]->array(mfi);)
#ifdef AMREX_USE_EB
Array4<int const> const& dmarr = dmask.const_array(mfi);
bool cutfab = edgecent[0]->ok(mfi);
bool cutfab = edgecent[0] && edgecent[0]->ok(mfi);
AMREX_D_TERM(Array4<Real const> const& ecx
= cutfab ? edgecent[0]->const_array(mfi) : Array4<Real const>{};,
Array4<Real const> const& ecy
Expand Down Expand Up @@ -741,6 +754,7 @@ MLEBNodeFDLaplacian::postSolve (Vector<MultiFab>& sol) const
for (int amrlev = 0; amrlev < m_num_amr_levels; ++amrlev) {
const auto phieb = m_s_phi_eb;
const auto *factory = dynamic_cast<EBFArrayBoxFactory const*>(m_factory[amrlev][0].get());
if (!factory) { return; }
auto const& levset_mf = factory->getLevelSet();
auto const& levset_ar = levset_mf.const_arrays();
MultiFab& mf = sol[amrlev];
Expand Down
Loading