Skip to content

Commit

Permalink
Add more build options for linear solvers
Browse files Browse the repository at this point in the history
Add two new CMake build options, AMReX_LINEAR_SOLVERS_INCFLO and
AMReX_LINEAR_SOLVERS_EM. Both options depend on AMReX_LINEAR_SOLVERS, and
are enabled by default when AMReX_LINEAR_SOLVERS is enabled. By default, the
cell-centered MLABecLaplacian and MLPoisson solvers are always
included. However, these new build options provide finer control over which
solvers to build.

* AMReX_LINEAR_SOLVERS_INCFLO can be used to control the inclusion of
solvers commonly used by incompressible flow codes, such as nodal projection
and Navier-Stokes tensor solvers.

* AMReX_LINEAR_SOLVERS_EM can be used to control the inclusion of solvers
commonly used by electromagnetic applications, such as the curl curl and
tensor Laplacian solvers used by WarpX.

These options are also available in GNU Make as USE_LINEAR_SOLVERS_INCFLO
and USE_LINEAR_SOLVER_EM.
  • Loading branch information
WeiqunZhang committed Oct 3, 2024
1 parent f3514e4 commit 80299b2
Show file tree
Hide file tree
Showing 22 changed files with 1,499 additions and 1,398 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ jobs:
export AMREX_HOME=${PWD}
export MICROPHYSICS_HOME=${PWD}/Microphysics
cd Castro/Exec/hydro_tests/Sedov/
make -j4 CCACHE=ccache USE_MPI=FALSE
make -j4 CCACHE=ccache USE_MPI=FALSE \
USE_LINEAR_SOLVERS_INCFLO=FALSE \
USE_LINEAR_SOLVERS_EM=FALSE
ccache -s
du -hs ~/.cache/ccache
Expand Down Expand Up @@ -92,7 +94,8 @@ jobs:
-DWarpX_QED=OFF \
-DWarpX_OPENPMD=OFF \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DAMReX_LINEAR_SOLVER_INCFLO=OFF
cmake --build WarpX/build -j 4
ccache -s
Expand Down
10 changes: 10 additions & 0 deletions Docs/sphinx_documentation/source/BuildingAMReX.rst
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,12 @@ The list of available options is reported in the :ref:`table <tab:cmakevar>` bel
+------------------------------+-------------------------------------------------+-------------------------+-----------------------+
| AMReX_LINEAR_SOLVERS | Build AMReX linear solvers | YES | YES, NO |
+------------------------------+-------------------------------------------------+-------------------------+-----------------------+
| AMReX_LINEAR_SOLVERS_INCFLO | Build AMReX linear solvers for incompressible | YES | YES, NO |
| | flow | |
+------------------------------+-------------------------------------------------+-------------------------+-----------------------+
| AMReX_LINEAR_SOLVERS_EM | Build AMReX linear solvers for electromagnetic | YES | YES, NO |
| | solvers | |
+------------------------------+-------------------------------------------------+-------------------------+-----------------------+
| AMReX_AMRDATA | Build data services | NO | YES, NO |
+------------------------------+-------------------------------------------------+-------------------------+-----------------------+
| AMReX_AMRLEVEL | Build AmrLevel class | YES | YES, NO |
Expand Down Expand Up @@ -681,6 +687,10 @@ A list of AMReX component names and related configure options are shown in the t
+------------------------------+-----------------+
| AMReX_LINEAR_SOLVERS | LSOLVERS |
+------------------------------+-----------------+
| AMReX_LINEAR_SOLVERS_INCFLO | LSOLVERS_INCFLO |
+------------------------------+-----------------+
| AMReX_LINEAR_SOLVERS_EM | LSOLVERS_EM |
+------------------------------+-----------------+
| AMReX_AMRDATA | AMRDATA |
+------------------------------+-----------------+
| AMReX_AMRLEVEL | AMRLEVEL |
Expand Down
2 changes: 1 addition & 1 deletion Src/Extern/HYPRE/AMReX_Habec_2D_K.H
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <AMReX_EBMultiFabUtil.H>
#include <AMReX_MultiCutFab.H>
#include <AMReX_EBFabFactory.H>
#include <AMReX_MLEBABecLap_K.H>
#include <AMReX_MLLinOp_K.H>
#endif

namespace amrex {
Expand Down
2 changes: 1 addition & 1 deletion Src/Extern/HYPRE/AMReX_Habec_3D_K.H
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <AMReX_EBMultiFabUtil.H>
#include <AMReX_MultiCutFab.H>
#include <AMReX_EBFabFactory.H>
#include <AMReX_MLEBABecLap_K.H>
#include <AMReX_MLLinOp_K.H>
#endif

namespace amrex {
Expand Down
68 changes: 41 additions & 27 deletions Src/LinearSolvers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ foreach(D IN LISTS AMReX_SPACEDIM)
MLMG/AMReX_MLLinOp_K.H
MLMG/AMReX_MLCellLinOp.H
MLMG/AMReX_MLNodeLinOp.H
MLMG/AMReX_MLNodeLinOp_K.H
MLMG/AMReX_MLNodeLinOp_${D}D_K.H
MLMG/AMReX_MLNodeLinOp.cpp
MLMG/AMReX_MLCellABecLap.H
MLMG/AMReX_MLCellABecLap_K.H
Expand All @@ -31,30 +33,6 @@ foreach(D IN LISTS AMReX_SPACEDIM)
MLMG/AMReX_MLPoisson.H
MLMG/AMReX_MLPoisson_K.H
MLMG/AMReX_MLPoisson_${D}D_K.H
MLMG/AMReX_MLNodeLaplacian.H
MLMG/AMReX_MLNodeLaplacian.cpp
MLMG/AMReX_MLNodeLaplacian_sync.cpp
MLMG/AMReX_MLNodeLaplacian_sten.cpp
MLMG/AMReX_MLNodeLaplacian_misc.cpp
MLMG/AMReX_MLNodeLap_K.H
MLMG/AMReX_MLNodeLap_${D}D_K.H
MLMG/AMReX_MLNodeTensorLaplacian.H
MLMG/AMReX_MLNodeTensorLaplacian.cpp
MLMG/AMReX_MLNodeTensorLap_K.H
MLMG/AMReX_MLNodeTensorLap_${D}D_K.H
MLMG/AMReX_MLTensorOp.H
MLMG/AMReX_MLTensorOp.cpp
MLMG/AMReX_MLTensorOp_grad.cpp
MLMG/AMReX_MLTensor_K.H
MLMG/AMReX_MLTensor_${D}D_K.H
MLMG/AMReX_MLEBNodeFDLaplacian.H
MLMG/AMReX_MLEBNodeFDLaplacian.cpp
MLMG/AMReX_MLEBNodeFDLap_K.H
MLMG/AMReX_MLEBNodeFDLap_${D}D_K.H
MLMG/AMReX_MLNodeABecLaplacian.H
MLMG/AMReX_MLNodeABecLaplacian.cpp
MLMG/AMReX_MLNodeABecLap_K.H
MLMG/AMReX_MLNodeABecLap_${D}D_K.H
AMReX_GMRES.H
AMReX_GMRES_MLMG.H
)
Expand All @@ -68,7 +46,7 @@ foreach(D IN LISTS AMReX_SPACEDIM)
)
endif ()

if (NOT D EQUAL 1)
if (NOT D EQUAL 1 AND AMReX_LINEAR_SOLVERS_EM)
target_sources(amrex_${D}d
PRIVATE
MLMG/AMReX_MLCurlCurl.H
Expand All @@ -77,7 +55,7 @@ foreach(D IN LISTS AMReX_SPACEDIM)
)
endif ()

if (AMReX_EB AND NOT D EQUAL 1)
if (AMReX_EB AND NOT D EQUAL 1 AND AMReX_LINEAR_SOLVERS_INCFLO)
target_sources(amrex_${D}d
PRIVATE
MLMG/AMReX_MLNodeLaplacian_eb.cpp
Expand All @@ -94,6 +72,42 @@ foreach(D IN LISTS AMReX_SPACEDIM)
)
endif ()

if (AMReX_LINEAR_SOLVERS_EM)
target_sources(amrex_${D}d
PRIVATE
MLMG/AMReX_MLEBNodeFDLaplacian.H
MLMG/AMReX_MLEBNodeFDLaplacian.cpp
MLMG/AMReX_MLEBNodeFDLap_K.H
MLMG/AMReX_MLEBNodeFDLap_${D}D_K.H
MLMG/AMReX_MLNodeTensorLaplacian.H
MLMG/AMReX_MLNodeTensorLaplacian.cpp
MLMG/AMReX_MLNodeTensorLap_K.H
MLMG/AMReX_MLNodeTensorLap_${D}D_K.H
)
endif ()

if (AMReX_LINEAR_SOLVERS_INCFLO)
target_sources(amrex_${D}d
PRIVATE
MLMG/AMReX_MLNodeABecLaplacian.H
MLMG/AMReX_MLNodeABecLaplacian.cpp
MLMG/AMReX_MLNodeABecLap_K.H
MLMG/AMReX_MLNodeABecLap_${D}D_K.H
MLMG/AMReX_MLNodeLaplacian.H
MLMG/AMReX_MLNodeLaplacian.cpp
MLMG/AMReX_MLNodeLaplacian_sync.cpp
MLMG/AMReX_MLNodeLaplacian_sten.cpp
MLMG/AMReX_MLNodeLaplacian_misc.cpp
MLMG/AMReX_MLNodeLap_K.H
MLMG/AMReX_MLNodeLap_${D}D_K.H
MLMG/AMReX_MLTensorOp.H
MLMG/AMReX_MLTensorOp.cpp
MLMG/AMReX_MLTensorOp_grad.cpp
MLMG/AMReX_MLTensor_K.H
MLMG/AMReX_MLTensor_${D}D_K.H
)
endif ()

if (AMReX_FORTRAN)
target_sources(amrex_${D}d
PRIVATE
Expand All @@ -102,7 +116,7 @@ foreach(D IN LISTS AMReX_SPACEDIM)
)
endif ()

if (AMReX_HYPRE)
if (AMReX_HYPRE AND AMReX_LINEAR_SOLVERS_INCFLO)
target_sources(amrex_${D}d
PRIVATE
MLMG/AMReX_MLNodeLaplacian_hypre.cpp
Expand Down
7 changes: 0 additions & 7 deletions Src/LinearSolvers/MLMG/AMReX_MLEBABecLap_K.H
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@

#include <AMReX_EBCellFlag.H>

namespace amrex {
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
Real get_dx_eb (Real kappa) noexcept {
return amrex::max(Real(0.3),(kappa*kappa-Real(0.25))/(Real(2.0)*kappa));
}
}

#if (AMREX_SPACEDIM == 2)
#include <AMReX_MLEBABecLap_2D_K.H>
#else
Expand Down
2 changes: 1 addition & 1 deletion Src/LinearSolvers/MLMG/AMReX_MLEBNodeFDLaplacian.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <AMReX_MLEBNodeFDLaplacian.H>
#include <AMReX_MLEBNodeFDLap_K.H>
#include <AMReX_MLNodeLap_K.H>
#include <AMReX_MLNodeLinOp_K.H>
#include <AMReX_MLNodeTensorLap_K.H>
#include <AMReX_MultiFabUtil.H>

Expand Down
9 changes: 9 additions & 0 deletions Src/LinearSolvers/MLMG/AMReX_MLLinOp_K.H
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,15 @@ void mllinop_apply_innu_zhi (int i, int j, int k,
}
}

#ifdef AMREX_USE_EB

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
Real get_dx_eb (Real kappa) noexcept {
return amrex::max(Real(0.3),(kappa*kappa-Real(0.25))/(Real(2.0)*kappa));
}

#endif

}

#endif
159 changes: 0 additions & 159 deletions Src/LinearSolvers/MLMG/AMReX_MLNodeLap_1D_K.H
Original file line number Diff line number Diff line change
Expand Up @@ -4,79 +4,6 @@

namespace amrex {

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_set_nodal_mask (int i, int, int, Array4<int> const& nmsk,
Array4<int const> const& cmsk) noexcept
{
using namespace nodelap_detail;

int s = cmsk(i-1,0,0) + cmsk(i,0,0);
if (s == 2*crse_cell) {
nmsk(i,0,0) = crse_node;
} else if (s == 2*fine_cell) {
nmsk(i,0,0) = fine_node;
} else {
nmsk(i,0,0) = crse_fine_node;
}
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_set_dirichlet_mask (Box const& bx, Array4<int> const& dmsk,
Array4<int const> const& omsk, Box const& dom,
GpuArray<LinOpBCType, AMREX_SPACEDIM> const& bclo,
GpuArray<LinOpBCType, AMREX_SPACEDIM> const& bchi) noexcept
{
const auto lo = bx.smallEnd(0);
const auto hi = bx.bigEnd(0);
AMREX_PRAGMA_SIMD
for (int i = lo; i <= hi; ++i) {
if (!dmsk(i,0,0)) {
dmsk(i,0,0) = (omsk(i-1,0,0) == 1 || omsk(i,0,0) == 1);
}
}

const auto domlo = dom.smallEnd(0);
const auto domhi = dom.bigEnd(0);

if (bclo[0] == LinOpBCType::Dirichlet && lo == domlo) {
dmsk(lo,0,0) = 1;
}

if (bchi[0] == LinOpBCType::Dirichlet && hi == domhi) {
dmsk(hi,0,0) = 1;
}
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_set_dot_mask (Box const& bx, Array4<Real> const& dmsk,
Array4<int const> const& omsk, Box const& dom,
GpuArray<LinOpBCType, AMREX_SPACEDIM> const& bclo,
GpuArray<LinOpBCType, AMREX_SPACEDIM> const& bchi) noexcept
{
const auto lo = bx.smallEnd(0);
const auto hi = bx.bigEnd(0);

AMREX_PRAGMA_SIMD
for (int i = lo; i <= hi; ++i) {
dmsk(i,0,0) = static_cast<Real>(omsk(i,0,0));
}

const auto domlo = dom.smallEnd(0);
const auto domhi = dom.bigEnd(0);

if ((bclo[0] == LinOpBCType::Neumann || bclo[0] == LinOpBCType::inflow)
&& lo == domlo)
{
dmsk(lo,0,0) *= Real(0.5);
}

if ((bchi[0] == LinOpBCType::Neumann || bchi[0] == LinOpBCType::inflow)
&& hi == domhi)
{
dmsk(hi,0,0) *= Real(0.5);
}
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_zero_fine (int i, int, int, Array4<Real> const& phi,
Array4<int const> const& msk, int fine_flag) noexcept
Expand Down Expand Up @@ -106,39 +33,6 @@ void mlndlap_semi_avgdown_coeff (int i, int j, int k, Array4<Real> const& crse,
mlndlap_avgdown_coeff_x(i,j,k,crse,fine);
}

template <typename T>
void mlndlap_bc_doit (Box const& vbx, Array4<T> const& a, Box const& domain,
GpuArray<bool,AMREX_SPACEDIM> const& bflo,
GpuArray<bool,AMREX_SPACEDIM> const& bfhi) noexcept
{
Box gdomain = domain;
int const idim = 0;
if (! bflo[idim]) { gdomain.growLo(idim,1); }
if (! bfhi[idim]) { gdomain.growHi(idim,1); }

if (gdomain.strictly_contains(vbx)) { return; }

const int offset = domain.cellCentered() ? 0 : 1;

const auto dlo = domain.smallEnd(0);
const auto dhi = domain.bigEnd(0);

Box const& sbox = amrex::grow(vbx,1);
AMREX_HOST_DEVICE_FOR_3D(sbox, i, j, k,
{
if (! gdomain.contains(IntVect(i))) {
if (i == dlo-1 && bflo[0])
{
a(i,0,0) = a(i+1+offset, j, k);
}
else if (i == dhi+1 && bfhi[0])
{
a(i,0,0) = a(i-1-offset, j, k);
}
}
});
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
Real mlndlap_adotx_c (int i, int, int, Array4<Real const> const& x,
Real sigma, Array4<int const> const& msk,
Expand Down Expand Up @@ -335,59 +229,6 @@ void mlndlap_gauss_seidel_with_line_solve_aa(Box const&, Array4<Real> const&,
amrex::Abort("mlndlap_gauss_seidel_with_line_solve_aa: not implemented in 1D");
}


AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_restriction (int i, int, int, Array4<Real> const& crse,
Array4<Real const> const& fine, Array4<int const> const& msk) noexcept
{
int ii = i*2;
if (msk(ii,0,0)) {
crse(i,0,0) = Real(0.0);
} else {
crse(i,0,0) = Real(1./4.) *(fine(ii-1,0,0)
+ Real(2.)* fine(ii ,0,0)
+ fine(ii+1,0,0));
}
}

template <int rr>
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_restriction (int i, int, int, Array4<Real> const& crse,
Array4<Real const> const& fine, Array4<int const> const& msk,
Box const& fdom,
GpuArray<LinOpBCType, AMREX_SPACEDIM> const& bclo,
GpuArray<LinOpBCType, AMREX_SPACEDIM> const& bchi) noexcept

{
const int ii = i*rr;
if (msk(ii,0,0)) {
crse(i,0,0) = Real(0.0);
} else {
const auto ndlo = fdom.smallEnd(0);
const auto ndhi = fdom.bigEnd(0);
Real tmp = Real(0.0);
for (int ioff = -rr+1; ioff <= rr-1; ++ioff) {
Real wx = rr - std::abs(ioff);
int itmp = ii + ioff;
if ((itmp < ndlo && (bclo[0] == LinOpBCType::Neumann ||
bclo[0] == LinOpBCType::inflow)) ||
(itmp > ndhi && (bchi[0] == LinOpBCType::Neumann ||
bchi[0] == LinOpBCType::inflow))) {
itmp = ii - ioff;
}
tmp += wx*fine(itmp,0,0);
}
crse(i,0,0) = tmp*(Real(1.0)/Real(rr*rr));
}
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_semi_restriction (int /*i*/, int /*j*/, int /*k*/, Array4<Real> const&,
Array4<Real const> const&, Array4<int const> const&, int) noexcept
{
amrex::Abort("mlndlap_semi_restriction: not implemented in 1D");
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void mlndlap_interpadd_c (int i, int , int, Array4<Real> const& fine,
Array4<Real const> const& crse,
Expand Down
Loading

0 comments on commit 80299b2

Please sign in to comment.