aboutsummaryrefslogtreecommitdiff
path: root/Source/Utils/WarpXUtil.cpp
diff options
context:
space:
mode:
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