aboutsummaryrefslogtreecommitdiff
path: root/Source/Utils/WarpXUtil.cpp
diff options
context:
space:
mode:
authorGravatar David Grote <grote1@llnl.gov> 2021-08-18 17:13:21 -0700
committerGravatar GitHub <noreply@github.com> 2021-08-19 00:13:21 +0000
commit263d9627bb8038227ba1a5f40ee937b0affbf8d6 (patch)
tree081afc5e2c89293ddaecb73a63c2b3e6b7bd115c /Source/Utils/WarpXUtil.cpp
parent1bbfd4691301c541a75e1a9e0c26dd4199d66a16 (diff)
downloadWarpX-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.cpp103
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