diff options
author | 2021-08-18 17:13:21 -0700 | |
---|---|---|
committer | 2021-08-19 00:13:21 +0000 | |
commit | 263d9627bb8038227ba1a5f40ee937b0affbf8d6 (patch) | |
tree | 081afc5e2c89293ddaecb73a63c2b3e6b7bd115c /Source/Utils/WarpXUtil.cpp | |
parent | 1bbfd4691301c541a75e1a9e0c26dd4199d66a16 (diff) | |
download | WarpX-263d9627bb8038227ba1a5f40ee937b0affbf8d6.tar.gz WarpX-263d9627bb8038227ba1a5f40ee937b0affbf8d6.tar.zst WarpX-263d9627bb8038227ba1a5f40ee937b0affbf8d6.zip |
Implemented the parsing of integer input parameters (#2138)
* Implemented the integer parser
* Updated comment
* Updated documentation
* Fixed unused parameters
* Added some additional documentation
* Reworked the implementation so that expressions are evaluated as real and rounded to the nearest integer
* Fixed loop type
* Copied over initial value of variable to the real instance
* Update Source/Utils/WarpXUtil.cpp
make result const
* Update Source/Utils/WarpXUtil.cpp
make result const
* Update Source/Utils/WarpXUtil.cpp
Fix comment
* Added safeCastToInt
* Fixed adding of safeCastToInt
* Cleaned up safe casting routine
* Added parsing of more integer inputs
* Cleaned up the integer parser, removing unneeded cast from int to real
* Made x a const in safeCastToInt
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
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 |