Skip to content

Commit

Permalink
Move CheckDims and ParseGeometryInput out of WarpXUtil (#5354)
Browse files Browse the repository at this point in the history
This PR moves the function `ParseGeometryInput` into
`WarpXAMReXInit.cpp`, and the function `CheckDims` into
`WarpXInit.H/cpp`. It also makes sure that `CheckDims` is called only
once. Note that the check on `geom.ProbLo(0)` depending on the EM/ES
solver is extracted from `ParseGeometryInput` and placed inside
`WarpX.cpp` . Note also that `parse_geometry_input`, despite being
conceptually related to the initialization of AMReX, must run **after**
having called `amrex::Initialize` .

The idea is to distribute the content of the miscellaneous
`WarpXUtil.H/cpp` files into more appropriate source files.
  • Loading branch information
lucafedeli88 authored Jan 21, 2025
1 parent d07326b commit 11808ea
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 116 deletions.
85 changes: 77 additions & 8 deletions Source/Initialization/WarpXAMReXInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@

#include "Initialization/WarpXAMReXInit.H"

#include "Utils/Parser/ParserUtils.H"
#include "Utils/TextMsg.H"

#include <AMReX.H>
#include <AMReX_BLProfiler.H>
#include <AMReX_ccse-mpi.H>
#include <AMReX_Vector.H>
#include <AMReX_ParmParse.H>
#include <AMReX_BLProfiler.H>
#include <AMReX_REAL.H>

#include <algorithm>
#include <string>

namespace {
Expand Down Expand Up @@ -105,6 +109,66 @@ namespace {
set_device_synchronization();
override_default_tiling_option_for_particles();
}

/** Parse prob_lo and hi
*
* Parse prob_lo and hi evaluating any expressions since geometry
* does not parse its input. Note that this operation has to be
* performed after having initialized AMReX
*/
void parse_geometry_input ()
{
auto pp_geometry = amrex::ParmParse {"geometry"};

auto prob_lo = amrex::Vector<amrex::Real>(AMREX_SPACEDIM);
auto prob_hi = amrex::Vector<amrex::Real>(AMREX_SPACEDIM);

utils::parser::getArrWithParser(
pp_geometry, "prob_lo", prob_lo, 0, AMREX_SPACEDIM);
utils::parser::getArrWithParser(
pp_geometry, "prob_hi", prob_hi, 0, AMREX_SPACEDIM);

AMREX_ALWAYS_ASSERT(prob_lo.size() == AMREX_SPACEDIM);
AMREX_ALWAYS_ASSERT(prob_hi.size() == AMREX_SPACEDIM);

pp_geometry.addarr("prob_lo", prob_lo);
pp_geometry.addarr("prob_hi", prob_hi);

// Parse amr input, evaluating any expressions since amr does not parse its input
auto pp_amr = amrex::ParmParse{"amr"};

// Note that n_cell is replaced so that only the parsed version is written out to the
// warpx_job_info file. This must be done since yt expects to be able to parse
// the value of n_cell from that file. For the rest, this doesn't matter.
auto preparse_amrex_input_int_array =
[&pp_amr](const std::string& input_str, const bool replace = false)
{
const auto *const c_input_str = input_str.c_str();
if (pp_amr.contains(c_input_str)) {
amrex::Vector<int> input_array;
utils::parser::getArrWithParser(pp_amr,c_input_str, input_array);
if (replace) {
pp_amr.remove(c_input_str);
}
pp_amr.addarr(c_input_str, input_array);
}
};

preparse_amrex_input_int_array("n_cell", true);

const auto params_to_parse = std::vector<std::string>{
"max_grid_size", "max_grid_size_x", "max_grid_size_y", "max_grid_size_z",
"blocking_factor", "blocking_factor_x", "blocking_factor_y", "blocking_factor_z"};
std::for_each(params_to_parse.begin(), params_to_parse.end(), preparse_amrex_input_int_array);
}

/** This method groups calls to functions related to the initialization of AMReX
* that can run only after having called amrex::Initialize
*/
void amrex_post_initialize ()
{
parse_geometry_input();
}
}

namespace warpx::initialization
Expand All @@ -113,13 +177,18 @@ namespace warpx::initialization
amrex::AMReX*
amrex_init (int& argc, char**& argv, bool build_parm_parse)
{
return amrex::Initialize(
argc,
argv,
build_parm_parse,
MPI_COMM_WORLD,
::overwrite_amrex_parser_defaults
);
amrex::AMReX* amrex =
amrex::Initialize(
argc,
argv,
build_parm_parse,
MPI_COMM_WORLD,
::overwrite_amrex_parser_defaults
);

::amrex_post_initialize();

return amrex;
}

}
4 changes: 4 additions & 0 deletions Source/Initialization/WarpXInit.H
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ namespace warpx::initialization
* - the MPI library through the mpi_finalize helper function in ablastr
*/
void finalize_external_libraries();

/** Check that warpx.dims matches the binary name
*/
void check_dims ();
}

#endif //WARPX_INIT_H_
32 changes: 32 additions & 0 deletions Source/Initialization/WarpXInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
#include "WarpXInit.H"

#include "Initialization/WarpXAMReXInit.H"
#include "Utils/TextMsg.H"

#include <AMReX.H>
#include <AMReX_ParmParse.H>

#include <ablastr/math/fft/AnyFFT.H>
#include <ablastr/parallelization/MPIInitHelpers.H>

#include <string>

void warpx::initialization::initialize_external_libraries(int argc, char* argv[])
{
ablastr::parallelization::mpi_init(argc, argv);
Expand All @@ -27,3 +31,31 @@ void warpx::initialization::finalize_external_libraries()
amrex::Finalize();
ablastr::parallelization::mpi_finalize();
}

void warpx::initialization::check_dims()
{
// Ensure that geometry.dims is set properly.
#if defined(WARPX_DIM_3D)
std::string const dims_compiled = "3";
#elif defined(WARPX_DIM_XZ)
std::string const dims_compiled = "2";
#elif defined(WARPX_DIM_1D_Z)
std::string const dims_compiled = "1";
#elif defined(WARPX_DIM_RZ)
std::string const dims_compiled = "RZ";
#endif
const amrex::ParmParse pp_geometry("geometry");
std::string dims;
std::string dims_error = "The selected WarpX executable was built as '";
dims_error.append(dims_compiled).append("'-dimensional, but the ");
if (pp_geometry.contains("dims")) {
pp_geometry.get("dims", dims);
dims_error.append("inputs file declares 'geometry.dims = ").append(dims).append("'.\n");
dims_error.append("Please re-compile with a different WarpX_DIMS option or select the right executable name.");
} else {
dims = "Not specified";
dims_error.append("inputs file does not declare 'geometry.dims'. Please add 'geometry.dims = ");
dims_error.append(dims_compiled).append("' to inputs file.");
}
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(dims == dims_compiled, dims_error);
}
6 changes: 0 additions & 6 deletions Source/Utils/WarpXUtil.H
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
#include <string>
#include <vector>

void ParseGeometryInput();

void ReadBoostedFrameParameters(amrex::Real& gamma_boost, amrex::Real& beta_boost,
amrex::Vector<int>& boost_direction);

Expand All @@ -44,10 +42,6 @@ void ConvertLabParamsToBoost();
*/
void ReadBCParams ();

/** Check the warpx.dims matches the binary name
*/
void CheckDims ();

/** Check the warpx.dims matches the binary name & set up RZ gridding
*
* Ensures that the blocks are setup correctly for the RZ spectral solver
Expand Down
99 changes: 0 additions & 99 deletions Source/Utils/WarpXUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,74 +43,6 @@

using namespace amrex;

void PreparseAMReXInputIntArray(amrex::ParmParse& a_pp, char const * const input_str, const bool replace)
{
const int cnt = a_pp.countval(input_str);
if (cnt > 0) {
Vector<int> input_array;
utils::parser::getArrWithParser(a_pp, input_str, input_array);
if (replace) {
a_pp.remove(input_str);
}
a_pp.addarr(input_str, input_array);
}
}

void ParseGeometryInput()
{
// Ensure that geometry.dims is set properly.
CheckDims();

// Parse prob_lo and hi, evaluating any expressions since geometry does not
// parse its input
ParmParse pp_geometry("geometry");

Vector<Real> prob_lo(AMREX_SPACEDIM);
Vector<Real> prob_hi(AMREX_SPACEDIM);

utils::parser::getArrWithParser(
pp_geometry, "prob_lo", prob_lo, 0, AMREX_SPACEDIM);
AMREX_ALWAYS_ASSERT(prob_lo.size() == AMREX_SPACEDIM);
utils::parser::getArrWithParser(
pp_geometry, "prob_hi", prob_hi, 0, AMREX_SPACEDIM);
AMREX_ALWAYS_ASSERT(prob_hi.size() == AMREX_SPACEDIM);

#ifdef WARPX_DIM_RZ
const ParmParse pp_algo("algo");
auto electromagnetic_solver_id = ElectromagneticSolverAlgo::Default;
pp_algo.query_enum_sloppy("maxwell_solver", electromagnetic_solver_id, "-_");
if (electromagnetic_solver_id == ElectromagneticSolverAlgo::PSATD)
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(prob_lo[0] == 0.,
"Lower bound of radial coordinate (prob_lo[0]) with RZ PSATD solver must be zero");
}
else
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(prob_lo[0] >= 0.,
"Lower bound of radial coordinate (prob_lo[0]) with RZ FDTD solver must be non-negative");
}
#endif

pp_geometry.addarr("prob_lo", prob_lo);
pp_geometry.addarr("prob_hi", prob_hi);

// Parse amr input, evaluating any expressions since amr does not parse its input
ParmParse pp_amr("amr");

// Note that n_cell is replaced so that only the parsed version is written out to the
// warpx_job_info file. This must be done since yt expects to be able to parse
// the value of n_cell from that file. For the rest, this doesn't matter.
PreparseAMReXInputIntArray(pp_amr, "n_cell", true);
PreparseAMReXInputIntArray(pp_amr, "max_grid_size", false);
PreparseAMReXInputIntArray(pp_amr, "max_grid_size_x", false);
PreparseAMReXInputIntArray(pp_amr, "max_grid_size_y", false);
PreparseAMReXInputIntArray(pp_amr, "max_grid_size_z", false);
PreparseAMReXInputIntArray(pp_amr, "blocking_factor", false);
PreparseAMReXInputIntArray(pp_amr, "blocking_factor_x", false);
PreparseAMReXInputIntArray(pp_amr, "blocking_factor_y", false);
PreparseAMReXInputIntArray(pp_amr, "blocking_factor_z", false);
}

void ReadBoostedFrameParameters(Real& gamma_boost, Real& beta_boost,
Vector<int>& boost_direction)
{
Expand Down Expand Up @@ -352,40 +284,9 @@ namespace WarpXUtilIO{
}
}

void CheckDims ()
{
// Ensure that geometry.dims is set properly.
#if defined(WARPX_DIM_3D)
std::string const dims_compiled = "3";
#elif defined(WARPX_DIM_XZ)
std::string const dims_compiled = "2";
#elif defined(WARPX_DIM_1D_Z)
std::string const dims_compiled = "1";
#elif defined(WARPX_DIM_RZ)
std::string const dims_compiled = "RZ";
#endif
const ParmParse pp_geometry("geometry");
std::string dims;
std::string dims_error = "The selected WarpX executable was built as '";
dims_error.append(dims_compiled).append("'-dimensional, but the ");
if (pp_geometry.contains("dims")) {
pp_geometry.get("dims", dims);
dims_error.append("inputs file declares 'geometry.dims = ").append(dims).append("'.\n");
dims_error.append("Please re-compile with a different WarpX_DIMS option or select the right executable name.");
} else {
dims = "Not specified";
dims_error.append("inputs file does not declare 'geometry.dims'. Please add 'geometry.dims = ");
dims_error.append(dims_compiled).append("' to inputs file.");
}
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(dims == dims_compiled, dims_error);
}

void CheckGriddingForRZSpectral ()
{
#ifdef WARPX_DIM_RZ
// Ensure that geometry.dims is set properly.
CheckDims();

const ParmParse pp_algo("algo");
auto electromagnetic_solver_id = ElectromagneticSolverAlgo::Default;
pp_algo.query_enum_sloppy("maxwell_solver", electromagnetic_solver_id, "-_");
Expand Down
18 changes: 15 additions & 3 deletions Source/WarpX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "FieldSolver/WarpX_FDTD.H"
#include "Filter/NCIGodfreyFilter.H"
#include "Initialization/ExternalField.H"
#include "Initialization/WarpXInit.H"
#include "Particles/MultiParticleContainer.H"
#include "Fluids/MultiFluidContainer.H"
#include "Fluids/WarpXFluidContainer.H"
Expand Down Expand Up @@ -214,7 +215,7 @@ namespace

void WarpX::MakeWarpX ()
{
ParseGeometryInput();
warpx::initialization::check_dims();

ReadMovingWindowParameters(
do_moving_window, start_moving_window_step, end_moving_window_step,
Expand Down Expand Up @@ -467,8 +468,6 @@ WarpX::~WarpX ()
void
WarpX::ReadParameters ()
{
// Ensure that geometry.dims is set properly.
CheckDims();

{
const ParmParse pp;// Traditionally, max_step and stop_time do not have prefix.
Expand All @@ -489,6 +488,19 @@ WarpX::ReadParameters ()
if (electromagnetic_solver_id == ElectromagneticSolverAlgo::ECT && !EB::enabled()) {
throw std::runtime_error("ECP Solver requires to enable embedded boundaries at runtime.");
}
#ifdef WARPX_DIM_RZ
if (electromagnetic_solver_id == ElectromagneticSolverAlgo::PSATD)
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(Geom(0).ProbLo(0) == 0.,
"Lower bound of radial coordinate (prob_lo[0]) with RZ PSATD solver must be zero");
}
else
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(Geom(0).ProbLo(0) >= 0.,
"Lower bound of radial coordinate (prob_lo[0]) with RZ FDTD solver must be non-negative");
}
#endif

pp_algo.query_enum_sloppy("evolve_scheme", evolve_scheme, "-_");
}

Expand Down

0 comments on commit 11808ea

Please sign in to comment.