diff --git a/Src/LinearSolvers/MLMG/AMReX_MLEBNodeFDLaplacian.cpp b/Src/LinearSolvers/MLMG/AMReX_MLEBNodeFDLaplacian.cpp index 09bb6d87e1..eaaffd97cf 100644 --- a/Src/LinearSolvers/MLMG/AMReX_MLEBNodeFDLaplacian.cpp +++ b/Src/LinearSolvers/MLMG/AMReX_MLEBNodeFDLaplacian.cpp @@ -5,6 +5,7 @@ #include #ifdef AMREX_USE_EB +#include #include #endif @@ -151,10 +152,14 @@ MLEBNodeFDLaplacian::define (const Vector& a_geom, std::unique_ptr > 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 @@ -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(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 @@ -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(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 @@ -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(m_factory[amrlev][mglev].get()); - auto const& edgecent = factory->getEdgeCent(); - auto const& levset_mf = factory->getLevelSet(); - auto const& volfrac = factory->getVolFrac(); + Array edgecent {AMREX_D_DECL(nullptr,nullptr,nullptr)}; + if (factory) { + edgecent = factory->getEdgeCent(); + } #endif #ifdef AMREX_USE_OMP @@ -422,12 +432,12 @@ MLEBNodeFDLaplacian::Fapply (int amrlev, int mglev, MultiFab& out, const MultiFa Array4 const& yarr = out.array(mfi); Array4 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 const& ecx = edgecent[0]->const_array(mfi);, Array4 const& ecy = edgecent[1]->const_array(mfi);, Array4 const& ecz = edgecent[2]->const_array(mfi)); - auto const& levset = levset_mf.const_array(mfi); + auto const& levset = factory->getVolFrac().const_array(mfi); if (phieb == std::numeric_limits::lowest()) { auto const& phiebarr = m_phi_eb[amrlev].const_array(mfi); #if (AMREX_SPACEDIM == 2) @@ -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), @@ -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), @@ -533,9 +543,10 @@ MLEBNodeFDLaplacian::Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiF #ifdef AMREX_USE_EB const auto *factory = dynamic_cast(m_factory[amrlev][mglev].get()); - auto const& edgecent = factory->getEdgeCent(); - auto const& levset_mf = factory->getLevelSet(); - auto const& volfrac = factory->getVolFrac(); + Array edgecent {AMREX_D_DECL(nullptr,nullptr,nullptr)}; + if (factory) { + edgecent = factory->getEdgeCent(); + } #endif #ifdef AMREX_USE_OMP @@ -548,12 +559,12 @@ MLEBNodeFDLaplacian::Fsmooth (int amrlev, int mglev, MultiFab& sol, const MultiF Array4 const& rhsarr = rhs.const_array(mfi); Array4 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 const& ecx = edgecent[0]->const_array(mfi);, Array4 const& ecy = edgecent[1]->const_array(mfi);, Array4 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, @@ -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), @@ -641,8 +652,10 @@ MLEBNodeFDLaplacian::compGrad (int amrlev, const Array auto const& dmask = *m_dirichlet_mask[amrlev][mglev]; const auto phieb = m_s_phi_eb; const auto *factory = dynamic_cast(m_factory[amrlev][mglev].get()); - AMREX_ASSERT(factory); - auto const& edgecent = factory->getEdgeCent(); + Array edgecent {AMREX_D_DECL(nullptr,nullptr,nullptr)}; + if (factory) { + edgecent = factory->getEdgeCent(); + } #endif #ifdef AMREX_USE_OMP @@ -659,7 +672,7 @@ MLEBNodeFDLaplacian::compGrad (int amrlev, const Array Array4 const& gpz = grad[2]->array(mfi);) #ifdef AMREX_USE_EB Array4 const& dmarr = dmask.const_array(mfi); - bool cutfab = edgecent[0]->ok(mfi); + bool cutfab = edgecent[0] && edgecent[0]->ok(mfi); AMREX_D_TERM(Array4 const& ecx = cutfab ? edgecent[0]->const_array(mfi) : Array4{};, Array4 const& ecy @@ -741,6 +754,7 @@ MLEBNodeFDLaplacian::postSolve (Vector& sol) const for (int amrlev = 0; amrlev < m_num_amr_levels; ++amrlev) { const auto phieb = m_s_phi_eb; const auto *factory = dynamic_cast(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];