diff options
Diffstat (limited to 'Source/Utils/WarpXUtil.cpp')
-rw-r--r-- | Source/Utils/WarpXUtil.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/Source/Utils/WarpXUtil.cpp b/Source/Utils/WarpXUtil.cpp index 03e800e54..6124e8afa 100644 --- a/Source/Utils/WarpXUtil.cpp +++ b/Source/Utils/WarpXUtil.cpp @@ -34,11 +34,27 @@ #include <fstream> #include <set> #include <string> +#include <limits> 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; + getArrWithParser(a_pp, input_str, input_array); + if (replace) { + a_pp.remove(input_str); + } + a_pp.addarr(input_str, input_array); + } +} + void ParseGeometryInput() { + // 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); @@ -66,6 +82,22 @@ void ParseGeometryInput() 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, @@ -239,6 +271,30 @@ void Store_parserString(const amrex::ParmParse& pp, std::string query_string, f.clear(); } +int safeCastToInt(const amrex::Real x, const std::string& real_name) { + int result = 0; + bool error_detected = false; + std::string assert_msg; + // (2.0*(numeric_limits<int>::max()/2+1)) converts numeric_limits<int>::max()+1 to a real ensuring accuracy to all digits + // This accepts x = 2**31-1 but rejects 2**31. + if (x < (2.0*(std::numeric_limits<int>::max()/2+1))) { + if (std::ceil(x) >= std::numeric_limits<int>::min()) { + result = static_cast<int>(x); + } else { + error_detected = true; + assert_msg = "Error: Negative overflow detected when casting " + real_name + " = " + std::to_string(x) + " to int"; + } + } else if (x > 0) { + error_detected = true; + assert_msg = "Error: Overflow detected when casting " + real_name + " = " + std::to_string(x) + " to int"; + } else { + error_detected = true; + assert_msg = "Error: NaN detected when casting " + real_name + " to int"; + } + WarpXUtilMsg::AlwaysAssert(!error_detected, assert_msg); + return result; +} + Parser makeParser (std::string const& parse_function, amrex::Vector<std::string> const& varnames) { // Since queryWithParser recursively calls this routine, keep track of symbols @@ -391,6 +447,53 @@ getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vec } } +int queryWithParser (const amrex::ParmParse& a_pp, char const * const str, int& val) { + amrex::Real rval; + const int result = queryWithParser(a_pp, str, rval); + if (result) { + val = safeCastToInt(std::round(rval), str); + } + return result; +} + +void getWithParser (const amrex::ParmParse& a_pp, char const * const str, int& val) { + amrex::Real rval; + getWithParser(a_pp, str, rval); + val = safeCastToInt(std::round(rval), str); +} + +int queryArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<int>& val, + const int start_ix, const int num_val) { + std::vector<amrex::Real> rval; + const int result = queryArrWithParser(a_pp, str, rval, start_ix, num_val); + if (result) { + val.resize(rval.size()); + for (unsigned long i = 0 ; i < val.size() ; i++) { + val[i] = safeCastToInt(std::round(rval[i]), str); + } + } + return result; +} + +void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<int>& val) { + std::vector<amrex::Real> rval; + getArrWithParser(a_pp, str, rval); + val.resize(rval.size()); + for (unsigned long i = 0 ; i < val.size() ; i++) { + val[i] = safeCastToInt(std::round(rval[i]), str); + } +} + +void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<int>& val, + const int start_ix, const int num_val) { + std::vector<amrex::Real> rval; + getArrWithParser(a_pp, str, rval, start_ix, num_val); + val.resize(rval.size()); + for (unsigned long i = 0 ; i < val.size() ; i++) { + val[i] = safeCastToInt(std::round(rval[i]), str); + } +} + /** * \brief Ensures that the blocks are setup correctly for the RZ spectral solver * When using the RZ spectral solver, the Hankel transform cannot be |