aboutsummaryrefslogtreecommitdiff
path: root/Source/Utils/Parser/ParserUtils.H
diff options
context:
space:
mode:
authorGravatar Luca Fedeli <luca.fedeli@cea.fr> 2022-10-10 20:36:14 +0200
committerGravatar GitHub <noreply@github.com> 2022-10-10 11:36:14 -0700
commite9cc65ffeb0684a97618b67c2164d95ea497226c (patch)
treeed65f7ac86cc4e8945021dc36a79c8bc246c150d /Source/Utils/Parser/ParserUtils.H
parent56e04c1b911f9399662c4ff9ecf6630d686cc220 (diff)
downloadWarpX-e9cc65ffeb0684a97618b67c2164d95ea497226c.tar.gz
WarpX-e9cc65ffeb0684a97618b67c2164d95ea497226c.tar.zst
WarpX-e9cc65ffeb0684a97618b67c2164d95ea497226c.zip
Partial refactoring of the utils directory (#3404)
* initial work to clean WarpX Utils * remove AMRCore from Ionization tables * progress * refactoring of a part of the utils directory * fix bug * fixed bug * fixed bug * remove debug line accidentally slipped into the code * remove debug line accidentally slipped into the code * remove debug line accidentally slipped into the code * cleaning * fixed bug
Diffstat (limited to 'Source/Utils/Parser/ParserUtils.H')
-rw-r--r--Source/Utils/Parser/ParserUtils.H298
1 files changed, 298 insertions, 0 deletions
diff --git a/Source/Utils/Parser/ParserUtils.H b/Source/Utils/Parser/ParserUtils.H
new file mode 100644
index 000000000..4195bed1a
--- /dev/null
+++ b/Source/Utils/Parser/ParserUtils.H
@@ -0,0 +1,298 @@
+/* Copyright 2022 Andrew Myers, Burlen Loring, Luca Fedeli
+ * Maxence Thevenet, Remi Lehe, Revathi Jambunathan
+ *
+ * This file is part of WarpX.
+ *
+ * License: BSD-3-Clause-LBNL
+ */
+
+#ifndef WARPX_UTILS_PARSER_PARSERUTILS_H_
+#define WARPX_UTILS_PARSER_PARSERUTILS_H_
+
+#include <AMReX_ParmParse.H>
+#include <AMReX_Parser.H>
+#include <AMReX_REAL.H>
+#include <AMReX_Vector.H>
+
+#include <cmath>
+#include <string>
+#include <type_traits>
+
+namespace utils::parser
+{
+ /**
+ * \brief Do a safe cast of a real to an int
+ * This ensures that the float value is within the range of ints and if not,
+ * raises an exception.
+ *
+ * \param x Real value to cast
+ * \param real_name String, the name of the variable being casted to use in the error message
+ */
+ int
+ safeCastToInt(amrex::Real x, const std::string& real_name);
+
+
+ /**
+ * \brief Do a safe cast of a real to a long
+ * This ensures that the float value is within the range of longs and if not,
+ * raises an exception.
+ *
+ * \param x Real value to cast
+ * \param real_name String, the name of the variable being casted to use in the error message
+ */
+ long
+ safeCastToLong(amrex::Real x, const std::string& real_name);
+
+
+ /**
+ * \brief Initialize an amrex::Parser object from a string containing a math expression
+ *
+ * \param parse_function String to read to initialize the parser.
+ * \param varnames A list of predefined independent variables
+ */
+ amrex::Parser makeParser (
+ std::string const& parse_function,
+ amrex::Vector<std::string> const& varnames);
+
+
+ /**
+ * \brief Parse a string (typically a mathematical expression) from the
+ * input file and store it into a variable.
+ *
+ * \param pp used to read the query_string `pp.<function>=string`
+ * \param query_string ParmParse.query will look for this string
+ * \param stored_string variable in which the string to parse is stored
+ */
+ void Store_parserString(
+ const amrex::ParmParse &pp,
+ std::string query_string,
+ std::string& stored_string);
+
+
+ /** Parse a string and return as a double precision floating point number
+ *
+ * In case the string cannot be interpreted as a double,
+ * this function ... <throws an exception? aborts with error message?>
+ *
+ * \param str The string to be parsed
+ * \return representation as a double
+ */
+ double parseStringtoDouble(const std::string& str);
+
+
+ /** Parse a string and return an int
+ *
+ * In case the string cannot be interpreted as Real,
+ * this function ... <throws an exception? aborts with error message?>
+ *
+ * \param str The string to be parsed
+ * \param name For integers, the name, to be used in error messages
+ * \return rounded closest integer
+ */
+ int parseStringtoInt(const std::string& str, const std::string& name);
+
+
+ template <int N>
+ amrex::ParserExecutor<N> compileParser (amrex::Parser const* parser)
+ {
+ if (parser) {
+ return parser->compile<N>();
+ } else {
+ return amrex::ParserExecutor<N>{};
+ }
+ }
+
+
+ /** Similar to amrex::ParmParse::query, but also supports math expressions for the value.
+ *
+ * amrex::ParmParse::query reads a name and a value from the input file. This function does the
+ * same, and applies the amrex::Parser to the value, so the user has the choice to specify a value or
+ * a math expression (including user-defined constants).
+ * Works for amrex::Real numbers and integers.
+ *
+ * \param[in] a_pp amrex::ParmParse object
+ * \param[in] str name of the parameter to read
+ * \param[out] val where the value queried and parsed is stored, either a scalar or vector
+ */
+ template <typename T>
+ int queryWithParser (const amrex::ParmParse& a_pp, char const * const str, T& 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);
+
+ auto parser = makeParser(str_val, {});
+
+ if (std::is_same<T, int>::value) {
+
+ val = safeCastToInt(std::round(parser.compileHost<0>()()), str);
+ }
+ else {
+ val = static_cast<T>(parser.compileHost<0>()());
+ }
+ }
+ // return the same output as amrex::ParmParse::query
+ return is_specified;
+ }
+
+
+ template <typename T>
+ int queryArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val)
+ {
+ // call amrex::ParmParse::query, check if the user specified str.
+ std::vector<std::string> tmp_str_arr;
+ int is_specified = a_pp.queryarr(str, tmp_str_arr);
+ if (is_specified)
+ {
+ // If so, create parser objects and apply them to the values provided by the user.
+ int const n = static_cast<int>(tmp_str_arr.size());
+ val.resize(n);
+ for (int i=0 ; i < n ; i++) {
+ auto parser = makeParser(tmp_str_arr[i], {});
+ if (std::is_same<T, int>::value) {
+ val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
+ }
+ else {
+ val[i] = static_cast<T>(parser.compileHost<0>()());
+ }
+ }
+ }
+ // return the same output as amrex::ParmParse::query
+ return is_specified;
+ }
+
+
+ /** Similar to amrex::ParmParse::query, but also supports math expressions for the value.
+ *
+ * amrex::ParmParse::query reads a name and a value from the input file. This function does the
+ * same, and applies the amrex::Parser to the value, so the user has the choice to specify a value or
+ * a math expression (including user-defined constants).
+ * Works for amrex::Real numbers and integers.
+ *
+ * \param[in] a_pp amrex::ParmParse object
+ * \param[in] str name of the parameter to read
+ * \param[out] val where the value queried and parsed is stored, either a scalar or vector
+ * \param[in] start_ix start index in the list of inputs values (optional with arrays, default is
+ * amrex::ParmParse::FIRST for starting with the first input value)
+ * \param[in] num_val number of input values to use (optional with arrays, default is
+ * amrex::ParmParse::LAST for reading until the last input value)
+ */
+ template <typename T>
+ int queryArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val,
+ const int start_ix, const int num_val)
+ {
+ // call amrex::ParmParse::query, check if the user specified str.
+ std::vector<std::string> tmp_str_arr;
+ int is_specified = a_pp.queryarr(str, tmp_str_arr, start_ix, num_val);
+ if (is_specified)
+ {
+ // If so, create parser objects and apply them to the values provided by the user.
+ int const n = static_cast<int>(tmp_str_arr.size());
+ val.resize(n);
+ for (int i=0 ; i < n ; i++) {
+ auto parser = makeParser(tmp_str_arr[i], {});
+ if (std::is_same<T, int>::value) {
+ val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
+ }
+ else {
+ val[i] = static_cast<T>(parser.compileHost<0>()());
+ }
+ }
+ }
+ // return the same output as amrex::ParmParse::query
+ return is_specified;
+ }
+
+
+ /** Similar to amrex::ParmParse::get, but also supports math expressions for the value.
+ *
+ * amrex::ParmParse::get reads a name and a value from the input file. This function does the
+ * same, and applies the Parser to the value, so the user has the choice to specify a value or
+ * a math expression (including user-defined constants).
+ * Works for amrex::Real numbers and integers.
+ *
+ * \param[in] a_pp amrex::ParmParse object
+ * \param[in] str name of the parameter to read
+ * \param[out] val where the value queried and parsed is stored
+ */
+ template <typename T>
+ void getWithParser (const amrex::ParmParse& a_pp, char const * const str, T& 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);
+
+ auto parser = makeParser(str_val, {});
+ if (std::is_same<T, int>::value) {
+ val = safeCastToInt(std::round(parser.compileHost<0>()()), str);
+ }
+ else {
+ val = static_cast<T>(parser.compileHost<0>()());
+ }
+ }
+
+ template <typename T>
+ void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val)
+ {
+ // Create parser objects and apply them to the values provided by the user.
+ std::vector<std::string> tmp_str_arr;
+ a_pp.getarr(str, tmp_str_arr);
+
+ int const n = static_cast<int>(tmp_str_arr.size());
+ val.resize(n);
+ for (int i=0 ; i < n ; i++) {
+ auto parser = makeParser(tmp_str_arr[i], {});
+ if (std::is_same<T, int>::value) {
+ val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
+ }
+ else {
+ val[i] = static_cast<T>(parser.compileHost<0>()());
+ }
+ }
+ }
+
+
+ /** Similar to amrex::ParmParse::get, but also supports math expressions for the value.
+ *
+ * amrex::ParmParse::get reads a name and a value from the input file. This function does the
+ * same, and applies the Parser to the value, so the user has the choice to specify a value or
+ * a math expression (including user-defined constants).
+ * Works for amrex::Real numbers and integers.
+ *
+ * \param[in] a_pp amrex::ParmParse object
+ * \param[in] str name of the parameter to read
+ * \param[out] val where the value queried and parsed is stored
+ * \param[in] start_ix start index in the list of inputs values (optional with arrays, default is
+ * amrex::ParmParse::FIRST for starting with the first input value)
+ * \param[in] num_val number of input values to use (optional with arrays, default is
+ * amrex::ParmParse::LAST for reading until the last input value)
+ */
+ template <typename T>
+ void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val,
+ const int start_ix, const int num_val)
+ {
+ // Create parser objects and apply them to the values provided by the user.
+ std::vector<std::string> tmp_str_arr;
+ a_pp.getarr(str, tmp_str_arr, start_ix, num_val);
+
+ int const n = static_cast<int>(tmp_str_arr.size());
+ val.resize(n);
+ for (int i=0 ; i < n ; i++) {
+ auto parser = makeParser(tmp_str_arr[i], {});
+ if (std::is_same<T, int>::value) {
+ val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
+ }
+ else {
+ val[i] = static_cast<T>(parser.compileHost<0>()());
+ }
+ }
+ }
+
+}
+
+#endif // WARPX_UTILS_PARSER_PARSERUTILS_H_