aboutsummaryrefslogtreecommitdiff
path: root/Source/Utils/WarpXUtil.cpp
diff options
context:
space:
mode:
authorGravatar AlexanderSinn <64009254+AlexanderSinn@users.noreply.github.com> 2021-10-04 22:53:08 +0200
committerGravatar GitHub <noreply@github.com> 2021-10-04 20:53:08 +0000
commit3d5bc5b6772fa10d7b2ab2c55c97246c779ade79 (patch)
treedecf2a7f2d37b7bc4138cd82b403f3e8e83f5746 /Source/Utils/WarpXUtil.cpp
parentb25e17c6eff01f510104180ad551257bb8bb65a9 (diff)
downloadWarpX-3d5bc5b6772fa10d7b2ab2c55c97246c779ade79.tar.gz
WarpX-3d5bc5b6772fa10d7b2ab2c55c97246c779ade79.tar.zst
WarpX-3d5bc5b6772fa10d7b2ab2c55c97246c779ade79.zip
Fix my_constants being cast to float in single precision (#2369)
* Parse my_constants always as double * remove debug print out * add comment * fix comment * add additional comment
Diffstat (limited to 'Source/Utils/WarpXUtil.cpp')
-rw-r--r--Source/Utils/WarpXUtil.cpp42
1 files changed, 37 insertions, 5 deletions
diff --git a/Source/Utils/WarpXUtil.cpp b/Source/Utils/WarpXUtil.cpp
index 530b10b62..d92f75b9e 100644
--- a/Source/Utils/WarpXUtil.cpp
+++ b/Source/Utils/WarpXUtil.cpp
@@ -331,7 +331,9 @@ Parser makeParser (std::string const& parse_function, amrex::Vector<std::string>
};
for (auto it = symbols.begin(); it != symbols.end(); ) {
- Real v;
+ // Always parsing in double precision avoids potential overflows that may occur when parsing
+ // user's expressions because of the limited range of exponentials in single precision
+ double v;
WarpXUtilMsg::AlwaysAssert(recursive_symbols.count(*it)==0, "Expressions contains recursive symbol "+*it);
recursive_symbols.insert(*it);
@@ -359,12 +361,12 @@ Parser makeParser (std::string const& parse_function, amrex::Vector<std::string>
return parser;
}
-amrex::Real
+double
parseStringtoReal(std::string str)
{
auto parser = makeParser(str, {});
auto exe = parser.compileHost<0>();
- amrex::Real result = exe();
+ double result = exe();
return result;
}
@@ -376,8 +378,12 @@ parseStringtoInt(std::string str, std::string name)
return ival;
}
+// Overloads for float/double instead of amrex::Real to allow makeParser() to query for
+// my_constants as double even in single precision mode
+// Always parsing in double precision avoids potential overflows that may occur when parsing user's
+// expressions because of the limited range of exponentials in single precision
int
-queryWithParser (const amrex::ParmParse& a_pp, char const * const str, amrex::Real& val)
+queryWithParser (const amrex::ParmParse& a_pp, char const * const str, float& val)
{
// call amrex::ParmParse::query, check if the user specified str.
std::string tmp_str;
@@ -394,7 +400,33 @@ queryWithParser (const amrex::ParmParse& a_pp, char const * const str, amrex::Re
}
void
-getWithParser (const amrex::ParmParse& a_pp, char const * const str, amrex::Real& val)
+getWithParser (const amrex::ParmParse& a_pp, char const * const str, float& val)
+{
+ // If so, create a parser object and apply it to the value provided by the user.
+ std::string str_val;
+ Store_parserString(a_pp, str, str_val);
+ val = parseStringtoReal(str_val);
+}
+
+int
+queryWithParser (const amrex::ParmParse& a_pp, char const * const str, double& val)
+{
+ // call amrex::ParmParse::query, check if the user specified str.
+ std::string tmp_str;
+ int is_specified = a_pp.query(str, tmp_str);
+ if (is_specified)
+ {
+ // If so, create a parser object and apply it to the value provided by the user.
+ std::string str_val;
+ Store_parserString(a_pp, str, str_val);
+ val = parseStringtoReal(str_val);
+ }
+ // return the same output as amrex::ParmParse::query
+ return is_specified;
+}
+
+void
+getWithParser (const amrex::ParmParse& a_pp, char const * const str, double& val)
{
// If so, create a parser object and apply it to the value provided by the user.
std::string str_val;