WarpX
ParserUtils.H
Go to the documentation of this file.
1 /* Copyright 2022 Andrew Myers, Burlen Loring, Luca Fedeli
2  * Maxence Thevenet, Remi Lehe, Revathi Jambunathan
3  *
4  * This file is part of WarpX.
5  *
6  * License: BSD-3-Clause-LBNL
7  */
8 
9 #ifndef WARPX_UTILS_PARSER_PARSERUTILS_H_
10 #define WARPX_UTILS_PARSER_PARSERUTILS_H_
11 
12 #include <AMReX_ParmParse.H>
13 #include <AMReX_Parser.H>
14 #include <AMReX_REAL.H>
15 #include <AMReX_Vector.H>
16 
17 #include <cmath>
18 #include <string>
19 #include <type_traits>
20 
21 namespace utils::parser
22 {
31  int
32  safeCastToInt(amrex::Real x, const std::string& real_name);
33 
34 
43  long
44  safeCastToLong(amrex::Real x, const std::string& real_name);
45 
46 
54  std::string const& parse_function,
55  amrex::Vector<std::string> const& varnames);
56 
57 
66  void Store_parserString(
67  amrex::ParmParse const& pp,
68  std::string const& query_string,
69  std::string& stored_string);
70 
84  void Store_parserString(
85  const amrex::ParmParse &pp,
86  std::string const& group,
87  std::string const& query_string,
88  std::string& stored_string);
89 
90 
99  double parseStringtoDouble(const std::string& str);
100 
101 
111  int parseStringtoInt(const std::string& str, const std::string& name);
112 
113 
114  template <int N>
116  {
117  if (parser) {
118  return parser->compile<N>();
119  } else {
120  return amrex::ParserExecutor<N>{};
121  }
122  }
123 
124 
136  template <typename T>
137  int queryWithParser (const amrex::ParmParse& a_pp, char const * const str, T& val)
138  {
139  // call amrex::ParmParse::query, check if the user specified str.
140  std::string tmp_str;
141  const int is_specified = a_pp.query(str, tmp_str);
142  if (is_specified)
143  {
144  // If so, create a parser object and apply it to the value provided by the user.
145  std::string str_val;
146  Store_parserString(a_pp, str, str_val);
147 
148  auto parser = makeParser(str_val, {});
149 
150  if constexpr (std::is_same<T, int>::value) {
151 
152  val = safeCastToInt(
153  static_cast<amrex::Real>(std::round(parser.compileHost<0>()())), str);
154  }
155  else {
156  val = static_cast<T>(parser.compileHost<0>()());
157  }
158  }
159  // return the same output as amrex::ParmParse::query
160  return is_specified;
161  }
162 
163 
164  template <typename T>
165  int queryArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val)
166  {
167  // call amrex::ParmParse::query, check if the user specified str.
168  std::vector<std::string> tmp_str_arr;
169  const int is_specified = a_pp.queryarr(str, tmp_str_arr);
170  if (is_specified)
171  {
172  // If so, create parser objects and apply them to the values provided by the user.
173  int const n = static_cast<int>(tmp_str_arr.size());
174  val.resize(n);
175  for (int i=0 ; i < n ; i++) {
176  auto parser = makeParser(tmp_str_arr[i], {});
177  if constexpr (std::is_same<T, int>::value) {
178  val[i] = safeCastToInt(
179  static_cast<amrex::Real>(std::round(parser.compileHost<0>()())), str);
180  }
181  else {
182  val[i] = static_cast<T>(parser.compileHost<0>()());
183  }
184  }
185  }
186  // return the same output as amrex::ParmParse::query
187  return is_specified;
188  }
189 
190 
206  template <typename T>
207  int queryArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val,
208  const int start_ix, const int num_val)
209  {
210  // call amrex::ParmParse::query, check if the user specified str.
211  std::vector<std::string> tmp_str_arr;
212  const int is_specified = a_pp.queryarr(str, tmp_str_arr, start_ix, num_val);
213  if (is_specified)
214  {
215  // If so, create parser objects and apply them to the values provided by the user.
216  int const n = static_cast<int>(tmp_str_arr.size());
217  val.resize(n);
218  for (int i=0 ; i < n ; i++) {
219  auto parser = makeParser(tmp_str_arr[i], {});
220  if constexpr (std::is_same<T, int>::value) {
221  val[i] = safeCastToInt(
222  static_cast<amrex::Real>(std::round(parser.compileHost<0>()())), str);
223  }
224  else {
225  val[i] = static_cast<T>(parser.compileHost<0>()());
226  }
227  }
228  }
229  // return the same output as amrex::ParmParse::query
230  return is_specified;
231  }
232 
233 
245  template <typename T>
246  void getWithParser (const amrex::ParmParse& a_pp, char const * const str, T& val)
247  {
248  // If so, create a parser object and apply it to the value provided by the user.
249  std::string str_val;
250  Store_parserString(a_pp, str, str_val);
251 
252  auto parser = makeParser(str_val, {});
253  if constexpr (std::is_same<T, int>::value) {
254  val = safeCastToInt(
255  static_cast<amrex::Real>(std::round(parser.compileHost<0>()())), str);
256  }
257  else {
258  val = static_cast<T>(parser.compileHost<0>()());
259  }
260  }
261 
262  template <typename T>
263  void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val)
264  {
265  // Create parser objects and apply them to the values provided by the user.
266  std::vector<std::string> tmp_str_arr;
267  a_pp.getarr(str, tmp_str_arr);
268 
269  int const n = static_cast<int>(tmp_str_arr.size());
270  val.resize(n);
271  for (int i=0 ; i < n ; i++) {
272  auto parser = makeParser(tmp_str_arr[i], {});
273  if constexpr (std::is_same<T, int>::value) {
274  val[i] = safeCastToInt(
275  static_cast<amrex::Real>(std::round(parser.compileHost<0>()())), str);
276  }
277  else {
278  val[i] = static_cast<T>(parser.compileHost<0>()());
279  }
280  }
281  }
282 
283 
299  template <typename T>
300  void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std::vector<T>& val,
301  const int start_ix, const int num_val)
302  {
303  // Create parser objects and apply them to the values provided by the user.
304  std::vector<std::string> tmp_str_arr;
305  a_pp.getarr(str, tmp_str_arr, start_ix, num_val);
306 
307  int const n = static_cast<int>(tmp_str_arr.size());
308  val.resize(n);
309  for (int i=0 ; i < n ; i++) {
310  auto parser = makeParser(tmp_str_arr[i], {});
311  if constexpr (std::is_same<T, int>::value) {
312  val[i] = safeCastToInt(
313  static_cast<amrex::Real>(std::round(parser.compileHost<0>()())), str);
314  }
315  else {
316  val[i] = static_cast<T>(parser.compileHost<0>()());
317  }
318  }
319  }
320 
321 
338  template <typename T>
339  int queryWithParser (const amrex::ParmParse& a_pp, std::string const& group, char const * const str, T& val)
340  {
341  const bool is_specified_without_group = a_pp.contains(str);
342  const std::string grp_str = group + "." + std::string(str);
343  const bool is_specified_with_group = (group.empty() ? false : a_pp.contains(grp_str.c_str()));
344 
345  if (is_specified_without_group && !is_specified_with_group) {
346  // If found without the group but not with the group, then use the one without the group.
347  return queryWithParser(a_pp, str, val);
348  } else {
349  // Otherwise, use the one with the group even if not found, in which case an exception may be raised.
350  return queryWithParser(a_pp, grp_str.c_str(), val);
351  }
352  }
353 
354 
355  template <typename T>
356  int queryArrWithParser (const amrex::ParmParse& a_pp, std::string const& group, char const * const str, std::vector<T>& val)
357  {
358  const bool is_specified_without_group = a_pp.contains(str);
359  const std::string grp_str = group + "." + std::string(str);
360  const bool is_specified_with_group = (group.empty() ? false : a_pp.contains(grp_str.c_str()));
361 
362  if (is_specified_without_group && !is_specified_with_group) {
363  // If found without the group but not with the group, then use the one without the group.
364  return queryArrWithParser(a_pp, str, val);
365  } else {
366  // Otherwise, use the one with the group even if not found, in which case an exception may be raised.
367  return queryArrWithParser(a_pp, grp_str.c_str(), val);
368  }
369  }
370 
371 
392  template <typename T>
393  int queryArrWithParser (const amrex::ParmParse& a_pp, std::string const& group, char const * const str, std::vector<T>& val,
394  const int start_ix, const int num_val)
395  {
396  const bool is_specified_without_group = a_pp.contains(str);
397  const std::string grp_str = group + "." + std::string(str);
398  const bool is_specified_with_group = (group.empty() ? false : a_pp.contains(grp_str.c_str()));
399 
400  if (is_specified_without_group && !is_specified_with_group) {
401  // If found without the group but not with the group, then use the one without the group.
402  return queryArrWithParser(a_pp, str, val, start_ix, num_val);
403  } else {
404  // Otherwise, use the one with the group even if not found, in which case an exception may be raised.
405  return queryArrWithParser(a_pp, grp_str.c_str(), val, start_ix, num_val);
406  }
407  }
408 
421  int query (const amrex::ParmParse& a_pp, std::string const& group, char const * str, std::string& val);
422 
439  template <typename T>
440  void getWithParser (const amrex::ParmParse& a_pp, std::string const& group, char const * const str, T& val)
441  {
442  const bool is_specified_without_group = a_pp.contains(str);
443  const std::string grp_str = group + "." + std::string(str);
444  const bool is_specified_with_group = (group.empty() ? false : a_pp.contains(grp_str.c_str()));
445 
446  if (is_specified_without_group && !is_specified_with_group) {
447  // If found without the group but not with the group, then use the one without the group.
448  getWithParser(a_pp, str, val);
449  } else {
450  // Otherwise, use the one with the group even if not found, in which case an exception may be raised.
451  getWithParser(a_pp, grp_str.c_str(), val);
452  }
453  }
454 
455  template <typename T>
456  void getArrWithParser (const amrex::ParmParse& a_pp, std::string const& group, char const * const str, std::vector<T>& val)
457  {
458  const bool is_specified_without_group = a_pp.contains(str);
459  const std::string grp_str = group + "." + std::string(str);
460  const bool is_specified_with_group = (group.empty() ? false : a_pp.contains(grp_str.c_str()));
461 
462  if (is_specified_without_group && !is_specified_with_group) {
463  // If found without the group but not with the group, then use the one without the group.
464  getArrWithParser(a_pp, str, val);
465  } else {
466  // Otherwise, use the one with the group even if not found, in which case an exception may be raised.
467  getArrWithParser(a_pp, grp_str.c_str(), val);
468  }
469  }
470 
471 
492  template <typename T>
493  void getArrWithParser (const amrex::ParmParse& a_pp, std::string const& group, char const * const str, std::vector<T>& val,
494  const int start_ix, const int num_val)
495  {
496  const bool is_specified_without_group = a_pp.contains(str);
497  const std::string grp_str = group + "." + std::string(str);
498  const bool is_specified_with_group = (group.empty() ? false : a_pp.contains(grp_str.c_str()));
499 
500  if (is_specified_without_group && !is_specified_with_group) {
501  // If found without the group but not with the group, then use the one without the group.
502  getArrWithParser(a_pp, str, val, start_ix, num_val);
503  } else {
504  // Otherwise, use the one with the group even if not found, in which case an exception may be raised.
505  getArrWithParser(a_pp, grp_str.c_str(), val, start_ix, num_val);
506  }
507  }
508 
521  void get (amrex::ParmParse const& a_pp, std::string const& group, char const * str, std::string& val);
522 
523 }
524 
525 #endif // WARPX_UTILS_PARSER_PARSERUTILS_H_
bool contains(const char *name) const
int queryarr(const char *name, std::vector< int > &ref, int start_ix=FIRST, int num_val=ALL) const
void getarr(const char *name, std::vector< int > &ref, int start_ix=FIRST, int num_val=ALL) const
int query(const char *name, bool &ref, int ival=FIRST) const
i
Definition: check_interp_points_and_weights.py:174
str
Definition: run_alltests_1node.py:72
name
Definition: run_automated.py:229
parser
Definition: stencil.py:411
value
Definition: updateAMReX.py:141
Definition: IntervalsParser.H:17
int queryArrWithParser(const amrex::ParmParse &a_pp, char const *const str, std::vector< T > &val)
Definition: ParserUtils.H:165
int safeCastToInt(amrex::Real x, const std::string &real_name)
Do a safe cast of a real to an int This ensures that the float value is within the range of ints and ...
Definition: ParserUtils.cpp:117
amrex::Parser makeParser(std::string const &parse_function, amrex::Vector< std::string > const &varnames)
Initialize an amrex::Parser object from a string containing a math expression.
Definition: ParserUtils.cpp:127
long safeCastToLong(amrex::Real x, const std::string &real_name)
Do a safe cast of a real to a long This ensures that the float value is within the range of longs and...
Definition: ParserUtils.cpp:122
int parseStringtoInt(const std::string &str, const std::string &name)
Definition: ParserUtils.cpp:209
double parseStringtoDouble(const std::string &str)
Definition: ParserUtils.cpp:199
void getWithParser(const amrex::ParmParse &a_pp, char const *const str, T &val)
Definition: ParserUtils.H:246
int query(const amrex::ParmParse &a_pp, std::string const &group, char const *str, std::string &val)
Definition: ParserUtils.cpp:54
amrex::ParserExecutor< N > compileParser(amrex::Parser const *parser)
Definition: ParserUtils.H:115
void Store_parserString(amrex::ParmParse const &pp, std::string const &query_string, std::string &stored_string)
Parse a string (typically a mathematical expression) from the input file and store it into a variable...
Definition: ParserUtils.cpp:21
void getArrWithParser(const amrex::ParmParse &a_pp, char const *const str, std::vector< T > &val)
Definition: ParserUtils.H:263
void get(amrex::ParmParse const &a_pp, std::string const &group, char const *str, std::string &val)
Definition: ParserUtils.cpp:69
int queryWithParser(const amrex::ParmParse &a_pp, char const *const str, T &val)
Definition: ParserUtils.H:137