Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_ParmParse.H
Go to the documentation of this file.
1#ifndef AMREX_PARMPARSE_H_
2#define AMREX_PARMPARSE_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_BLassert.H>
6#include <AMReX_Box.H>
7#include <AMReX_Enum.H>
8#include <AMReX_INT.H>
9#include <AMReX_IntVect.H>
10#include <AMReX_IParser.H>
11#include <AMReX_Parser.H>
12#include <AMReX_TypeTraits.H>
13
14#include <array>
15#include <iosfwd>
16#include <optional>
17#include <set>
18#include <string>
19#include <string_view>
20#include <type_traits>
21#include <unordered_map>
22#include <variant>
23#include <vector>
24
25namespace amrex {
26
27template<int dim>
28class BoxND;
29using Box = BoxND<AMREX_SPACEDIM>;
30template<int dim>
31class IntVectND;
32using IntVect = IntVectND<AMREX_SPACEDIM>;
33class RealVect;
34
35namespace ppdetail {
36 template <class T, class Enable = void>
37 struct ArithmeticOptional_TT : std::false_type {};
38
39 template <class T>
40 struct ArithmeticOptional_TT<T, std::enable_if_t<std::is_arithmetic_v<T>>>
41 : std::true_type
42 {
43 using value_type = T;
44 };
45
46 template <class T>
47 struct ArithmeticOptional_TT<std::optional<T>,
48 std::enable_if_t<std::is_arithmetic_v<T>>>
49 : std::true_type
50 {
51 using value_type = T;
52 };
53
54 template <class T>
56
57 template <class T>
59}
60
61//
62// ParmParse class implements a simple database for the storage and
63// retrieval of command-line and input-file arguments. The entries are
64// stored in a static table in (name,value_list) pairs.
65//
66// The format of the input file is a series of DEFINITIONS.
67//
68// A DEFINITION is of the form <name> = <value> <value> ...
69// The equal sign is important since the list of values can span multiple
70// lines.
71//
72// Comments in an input file include all text from a '#' character to the
73// end of the line. Here is an example input file:
74/*
75 niter = 100 # niter is an integer
76 title = "Double Wammy" # example of a string with spaces
77 cell_size = 0.5 0.75 # cell spacing in each dimension
78 plot.var = Density 1 10 # a list of values
79 plot.var = Energy 5 12 # another list of values
80 bigarray = 1 2 3 4 5 6 7 8 \
81 9 10 11 12 # continuation of bigarray
82 multi_line_string = "This is a
83 multi-line string."
84 test = apple "boy blue" 10 20 30 40
85 FILE = prob_file # insert contents of this "prob_file" here
86*/
87// For values spanning multiple lines, one must use '\' at the end of a line
88// for continuation, otherwise it's a runtime error. Note that there must be
89// at least one space before the continuation character `\`. Multiple lines
90// inside a pair of double quotes are considered a single string containing
91// '\n's. The "FILE = <filename>" definition is special. Rather than just
92// adding this entry to the database, it reads the contents of <filename>
93// into the database.
94// For CI/CD workflows and out-of-source tests, the environment variable
95// AMREX_INPUTS_FILE_PREFIX can be set to prefix every FILE = <filename>
96// with a custom path.
97//
98// ParmParse stores all entries in a static table which is built the
99// first time a ParmParse object is constructed (usually in main()).
100// Subsequent invocations have access to this table.
101// A ParmParse constructor has an optional "prefix" argument that will
102// limit the searches to only those entries of the table with this prefix
103// in name. For example:
104// ParmParse pp("plot");
105// will find only those entries with name given by "plot.<string>".
106//
107// All values in the table are stored as strings. For example, the
108// values of "cell_size" in the above input file are stored as the
109// strings "0.5" and "0.75". These strings can be returned as either
110// strings or numeric values by the query functions.
111// Character strings with spaces must be delimited by double quotes
112// in the input file but the quotes are stripped before they are entered
113// into the table. For example, 'title' in the above input file has a
114// single value, the string 'Double Wammy' (without the quotes).
115// Each value in the list associated with a definition can be referred to
116// by its index number. The index numbers start at 0 just like an array
117// in the C programming language. Consider the definition of "test" in
118// the above input file. The first value 'apple'is a string with index
119// 0. The second value 'boy blue' is a string with index 1. The
120// remaining four values are integers indexed 2, 3, 4, and 5.
121//
122// For a string value to represent an integer or float it must fit the
123// following regular expression:
124// Sign ::= '+' | '-'
125// Digit ::= '0' | '1' | ... | '9'
126// Integer ::= [Sign]Digit+
127// Exp ::= ('e'|'E')Integer
128// Float ::= ( Integer[.Digit*][Exp] | [Integer].Digit+[Exp] )
129//
130// Where '+' indicates one or more occurrences, '*' represents zero or
131// more occurrences, '|' means one or the other and '[]' represents zero
132// or one occurrence.
133//
134// Note that floats and doubles have the same string representation and
135// that the FORTRAN "double" exponent format is not supported.
136// That is, 1.0d+3 is not a valid representation of a floating point
137// number but that 1.0e+3 is acceptable.
138//
139// There are a host of functions allowing the user to query the database
140// and retrieve values. Here are some general rules about the names of
141// the member functions:
142//
143// * Functions with the string "get" in their names attempt to get a
144// value or an array of values from the table. They generate a
145// run-time error if they are not successful.
146//
147// * Functions with the string "query" in their names attempt to get a
148// value or an array of values from the table. They return the value 1
149// (true) if they are successful and 0 (false) if not.
150//
151// * Functions with the string "kth" in their names get values from
152// the Kth entry with the given name in the database. This is
153// necessary since there may be multiple definitions with the same
154// name in the database.
155//
156// * Functions without the string "kth" in their names get values from
157// the last entry with the given name in the database. Note that the
158// definitions from the command line are appended to the database table
159// and hence will be the last entries.
160//
161// * Functions with the string "arr" in their names get an Array of
162// values from the given entry in the table. The array argument is
163// resized (if necessary) to hold all the values requested.
164//
165// * Functions without the string "arr" in their names get single
166// values from the given entry in the table.
167//
168// The following is a code sample showing how to use ParmParse:
169//
170// main(int argc, char **argv)
171// {
172// char* in_file_name = argv[1];
173// ParmParse::Initialize(argc-2, argv+2, in_file_name);
174//
175// // Query table for value of "niter". If not in table
176// // then set to default value
177// if (!pp.query("niter",niter)) niter = 20;
178//
179// // read array of cell sizes if in table
180// Vector<float> dx;
181// if (nx=pp.countval("cell_size")) {
182// // get nx values starting at index 0 and store in dx.
183// // dx is automatically resized here.
184// pp.getarr("cell_size",dx,0,nx);
185// }
186// ParmParse::Finalize();
187// }
188//
189// void do_graphics()
190// {
191// //
192// // Will only query entries with the "plot" prefix:
193// //
194// ParmParse pp("plot");
195// //
196// // Read all variables with "plot.var" keyword.
197// //
198// std::string var_name;
199// Vector<int> range;
200// int num = pp.countname("var");
201// for (int k = 0; k < num; k++)
202// {
203// //
204// // Element 0 in list is a string.
205// //
206// pp.getkth("var",k,var_name,0);
207// //
208// // Elements 1 and 2 are integers.
209// // Note that "range" will be resized to hold 2 elements.
210// //
211// pp.getktharr("var",k,range,1,2);
212// cout << "variable = " << var_name << "lo, hi = ",
213// << range[0] << " " << range[1] << endl;
214// }
215// }
216// -----------------------------------------------------------------
217// ----------------------- END COMMENTS ---------------------------
218// -----------------------------------------------------------------
219
220
324{
325public:
326 enum { LAST = -1, FIRST = 0, ALL = -1 };
334 explicit ParmParse (std::string prefix = std::string(),
335 std::string parser_prefix = std::string());
336
338 [[nodiscard]] bool contains (const char* name) const;
344 [[nodiscard]] int countval (const char* name, int n = LAST) const;
349 [[nodiscard]] int countname (const std::string& name) const;
361 void getkth (const char* name,
362 int k,
363 bool& ref,
364 int ival = FIRST) const;
366 void get (const char* name,
367 bool& ref,
368 int ival = FIRST) const;
376 int querykth (const char* name,
377 int k,
378 bool& ref,
379 int ival = FIRST) const;
381 int query (const char* name,
382 bool& ref,
383 int ival = FIRST) const;
385 void add (const char* name, bool val);
395 void getkth (const char* name,
396 int k,
397 int& ref,
398 int ival = FIRST) const;
399
401 void get (const char* name,
402 int& ref,
403 int ival = FIRST) const;
411 int querykth (const char* name,
412 int k,
413 int& ref,
414 int ival = FIRST) const;
416 int query (const char* name,
417 int& ref,
418 int ival = FIRST) const;
420 void add (const char* name, int val);
430 void getkth (const char* name,
431 int k,
432 long& ref,
433 int ival = FIRST) const;
435 void get (const char* name,
436 long& ref,
437 int ival = FIRST) const;
445 int querykth (const char* name,
446 int k,
447 long& ref,
448 int ival = FIRST) const;
450 int query (const char* name,
451 long& ref,
452 int ival = FIRST) const;
454 void add (const char* name, long val);
464 void getkth (const char* name,
465 int k,
466 long long& ref,
467 int ival = FIRST) const;
469 void get (const char* name,
470 long long& ref,
471 int ival = FIRST) const;
479 int querykth (const char* name,
480 int k,
481 long long& ref,
482 int ival = FIRST) const;
484 int query (const char* name,
485 long long& ref,
486 int ival = FIRST) const;
488 void add (const char* name, long long val);
498 void getkth (const char* name,
499 int k,
500 float& ref,
501 int ival = FIRST) const;
503 void get (const char* name,
504 float& ref,
505 int ival = FIRST) const;
513 int querykth (const char* name,
514 int k,
515 float& ref,
516 int ival = FIRST) const;
518 int query (const char* name,
519 float& ref,
520 int ival = FIRST) const;
522 void add (const char* name, float val);
532 void getkth (const char* name,
533 int k,
534 double& ref,
535 int ival = FIRST) const;
537 void get (const char* name,
538 double& ref,
539 int ival = FIRST) const;
547 int querykth (const char* name,
548 int k,
549 double& ref,
550 int ival = FIRST) const;
552 int query (const char* name,
553 double& ref,
554 int ival = FIRST) const;
556 void add (const char* name, double val);
566 void getkth (const char* name,
567 int k,
568 std::string& ref,
569 int ival = FIRST) const;
570
572 void get (const char* name,
573 std::string& ref,
574 int ival = FIRST) const;
582 int querykth (const char* name,
583 int k,
584 std::string& ref,
585 int ival = FIRST) const;
587 int query (const char* name,
588 std::string& ref,
589 int ival = FIRST) const;
591 void add (const char* name, const std::string& val);
592
593
602 void getline (const char* name, std::string& ref) const;
603
612 int queryline (const char* name, std::string& ref) const;
613
623 void getkth (const char* name,
624 int k,
625 IntVect& ref,
626 int ival = FIRST) const;
628 void get (const char* name,
629 IntVect& ref,
630 int ival = FIRST) const;
638 int querykth (const char* name,
639 int k,
640 IntVect& ref,
641 int ival = FIRST) const;
643 int query (const char* name,
644 IntVect& ref,
645 int ival = FIRST) const;
647 void add (const char* name, const IntVect& val);
657 void getkth (const char* name,
658 int k,
659 Box& ref,
660 int ival = FIRST) const;
662 void get (const char* name,
663 Box& ref,
664 int ival = FIRST) const;
672 int querykth (const char* name,
673 int k,
674 Box& ref,
675 int ival = FIRST) const;
677 int query (const char* name,
678 Box& ref,
679 int ival = FIRST) const;
681 void add (const char* name, const Box& val);
694 void getktharr (const char* name,
695 int k,
696 std::vector<int>& ref,
697 int start_ix = FIRST,
698 int num_val = ALL) const;
700 void getarr (const char* name,
701 std::vector<int>& ref,
702 int start_ix = FIRST,
703 int num_val = ALL) const;
705 int queryktharr (const char* name,
706 int k,
707 std::vector<int>& ref,
708 int start_ix = FIRST,
709 int num_val = ALL) const;
711 int queryarr (const char* name,
712 std::vector<int>& ref,
713 int start_ix = FIRST,
714 int num_val = ALL) const;
716 void addarr (const char* name, const std::vector<int>& ref);
717
730 void getktharr (const char* name,
731 int k,
732 std::vector<long>& ref,
733 int start_ix = FIRST,
734 int num_val = ALL) const;
736 void getarr (const char* name,
737 std::vector<long>& ref,
738 int start_ix = FIRST,
739 int num_val = ALL) const;
741 int queryktharr (const char* name,
742 int k,
743 std::vector<long>& ref,
744 int start_ix = FIRST,
745 int num_val = ALL) const;
747 int queryarr (const char* name,
748 std::vector<long>& ref,
749 int start_ix = FIRST,
750 int num_val = ALL) const;
752 void addarr (const char* name, const std::vector<long>& ref);
753
766 void getktharr (const char* name,
767 int k,
768 std::vector<long long>& ref,
769 int start_ix = FIRST,
770 int num_val = ALL) const;
772 void getarr (const char* name,
773 std::vector<long long>& ref,
774 int start_ix = FIRST,
775 int num_val = ALL) const;
777 int queryktharr (const char* name,
778 int k,
779 std::vector<long long>& ref,
780 int start_ix = FIRST,
781 int num_val = ALL) const;
783 int queryarr (const char* name,
784 std::vector<long long>& ref,
785 int start_ix = FIRST,
786 int num_val = ALL) const;
788 void addarr (const char* name, const std::vector<long long>& ref);
789
802 void getktharr (const char* name,
803 int k,
804 std::vector<float>& ref,
805 int start_ix = FIRST,
806 int num_val = ALL) const;
808 void getarr (const char* name,
809 std::vector<float>& ref,
810 int start_ix = FIRST,
811 int num_val = ALL) const;
813 int queryktharr (const char* name,
814 int k,
815 std::vector<float>& ref,
816 int start_ix = FIRST,
817 int num_val = ALL) const;
819 int queryarr (const char* name,
820 std::vector<float>& ref,
821 int start_ix = FIRST,
822 int num_val = ALL) const;
824 void addarr (const char* name, const std::vector<float>& ref);
837 void getktharr (const char* name,
838 int k,
839 std::vector<double>& ref,
840 int start_ix = FIRST,
841 int num_val = ALL) const;
843 void getarr (const char* name,
844 std::vector<double>& ref,
845 int start_ix = FIRST,
846 int num_val = ALL) const;
848 int queryktharr (const char* name,
849 int k,
850 std::vector<double>& ref,
851 int start_ix = FIRST,
852 int num_val = ALL) const;
854 int queryarr (const char* name,
855 std::vector<double>& ref,
856 int start_ix = FIRST,
857 int num_val = ALL) const;
859 void addarr (const char* name, const std::vector<double>& ref);
872 void getktharr (const char* name,
873 int k,
874 std::vector<std::string>& ref,
875 int start_ix = FIRST,
876 int num_val = ALL) const;
878 void getarr (const char* name,
879 std::vector<std::string>& ref,
880 int start_ix = FIRST,
881 int num_val = ALL) const;
883 int queryktharr (const char* name,
884 int k,
885 std::vector<std::string>& ref,
886 int start_ix = FIRST,
887 int num_val = ALL) const;
889 int queryarr (const char* name,
890 std::vector<std::string>& ref,
891 int start_ix = FIRST,
892 int num_val = ALL) const;
894 void addarr (const char* name, const std::vector<std::string>& ref);
907 void getktharr (const char* name,
908 int k,
909 std::vector<IntVect>& ref,
910 int start_ix = FIRST,
911 int num_val = ALL) const;
913 void getarr (const char* name,
914 std::vector<IntVect>& ref,
915 int start_ix = FIRST,
916 int num_val = ALL) const;
918 int queryktharr (const char* name,
919 int k,
920 std::vector<IntVect>& ref,
921 int start_ix = FIRST,
922 int num_val = ALL) const;
924 int queryarr (const char* name,
925 std::vector<IntVect>& ref,
926 int start_ix = FIRST,
927 int num_val = ALL) const;
929 void addarr (const char* name, const std::vector<IntVect>& ref);
942 void getktharr (const char* name,
943 int k,
944 std::vector<Box>& ref,
945 int start_ix = FIRST,
946 int num_val = ALL) const;
948 void getarr (const char* name,
949 std::vector<Box>& ref,
950 int start_ix = FIRST,
951 int num_val = ALL) const;
953 int queryktharr (const char* name,
954 int k,
955 std::vector<Box>& ref,
956 int start_ix = FIRST,
957 int num_val = ALL) const;
959 int queryarr (const char* name,
960 std::vector<Box>& ref,
961 int start_ix = FIRST,
962 int num_val = ALL) const;
964 void addarr (const char* name, const std::vector<Box>& refd);
965
966 /*
967 * \brief Query IntVect from array
968 *
969 * This reads IntVect from an array (e.g., `8 16 8`), not the format
970 * using parentheses (e.g., `(8,16,8)`).
971 */
972 int queryarr (const char* name, IntVect& ref) const;
973
974 /*
975 * \brief Get IntVect from array
976 *
977 * This reads IntVect from an array (e.g., `8 16 8`), not the format
978 * using parentheses (e.g., `(8,16,8)`).
979 */
980 void getarr (const char* name, IntVect& ref) const;
981
983 int queryarr (const char* name, RealVect& ref) const;
984
986 void getarr (const char* name, RealVect& ref) const;
987
988 template <typename T, std::size_t N>
989 void get (const char* name, std::array<T,N>& ref) const {
990 std::vector<T> v;
991 this->getarr(name, v);
992 AMREX_ALWAYS_ASSERT(v.size() >= N);
993 for (std::size_t i = 0; i < N; ++i) {
994 ref[i] = v[i];
995 }
996 }
997
998 template <typename T, std::size_t N>
999 int query (const char* name, std::array<T,N>& ref) const {
1000 std::vector<T> v;
1001 int exist = this->queryarr(name, v);
1002 if (exist) {
1003 AMREX_ALWAYS_ASSERT(v.size() >= N);
1004 for (std::size_t i = 0; i < N; ++i) {
1005 ref[i] = v[i];
1006 }
1007 }
1008 return exist;
1009 }
1010
1017 template <typename T, std::enable_if_t<!IsStdVector<T>::value, int> = 0>
1018 int queryAdd (const char* name, T& ref) {
1019 int exist = this->query(name, ref);
1020 if (!exist) {
1021 this->add(name, ref);
1022 }
1023 return exist;
1024 }
1025
1026 int queryAdd (const char* name, std::string& ref) {
1027 int exist = this->query(name, ref);
1028 if (!exist && !ref.empty()) {
1029 this->add(name, ref);
1030 }
1031 return exist;
1032 }
1033
1043 template <typename T>
1044 int queryAdd (const char* name, std::vector<T>& ref) {
1045 std::vector<T> empty;
1046 int exist = this->queryarr(name, empty);
1047 if (exist) {
1048 ref = std::move(empty);
1049 }
1050 if (!exist && !ref.empty()) {
1051 this->addarr(name, ref);
1052 }
1053 return exist;
1054 }
1055
1062 template <typename T>
1063 int queryAdd (const char* name, std::vector<T>& ref, int num_val) {
1064 int exist = this->queryarr(name, ref, 0, num_val);
1065 if (!exist) {
1066 this->addarr(name, ref);
1067 }
1068 return exist;
1069 }
1070
1077 template <typename T, std::size_t N>
1078 int queryAdd (const char* name, std::array<T,N>& ref) {
1079 std::vector<T> v;
1080 int exist = this->queryarr(name, v);
1081 if (exist) {
1082 AMREX_ALWAYS_ASSERT(v.size() >= N);
1083 for (std::size_t i = 0; i < N; ++i) {
1084 ref[i] = v[i];
1085 }
1086 } else {
1087 v.resize(N);
1088 for (std::size_t i = 0; i < N; ++i) {
1089 v[i] = ref[i];
1090 }
1091 this->addarr(name, v);
1092 }
1093 return exist;
1094 }
1095
1102 int queryWithParser (const char* name, int& ref) const;
1103 int queryWithParser (const char* name, long& ref) const;
1104 int queryWithParser (const char* name, long long& ref) const;
1105 int queryWithParser (const char* name, float& ref) const;
1106 int queryWithParser (const char* name, double& ref) const;
1107
1114 int queryarrWithParser (const char* name, int nvals, int* ref) const;
1115 int queryarrWithParser (const char* name, int nvals, long* ref) const;
1116 int queryarrWithParser (const char* name, int nvals, long long* ref) const;
1117 int queryarrWithParser (const char* name, int nvals, float* ref) const;
1118 int queryarrWithParser (const char* name, int nvals, double* ref) const;
1119 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1120 std::is_same_v<T,long> ||
1121 std::is_same_v<T,long long> ||
1122 std::is_same_v<T,float> ||
1123 std::is_same_v<T,double>,int> = 0>
1124 int queryarrWithParser (const char* name, int nvals, std::vector<T>& ref) const
1125 {
1126 if (this->contains(name)) {
1127 if (int(ref.size()) < nvals) { ref.resize(nvals); }
1128 return this->queryarrWithParser(name, nvals, ref.data());
1129 } else {
1130 return 0;
1131 }
1132 }
1133
1140 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1141 std::is_same_v<T,long> ||
1142 std::is_same_v<T,long long> ||
1143 std::is_same_v<T,float> ||
1144 std::is_same_v<T,double>,int> = 0>
1145 int queryAddWithParser (const char* name, T& ref)
1146 {
1147 int exist = this->queryWithParser(name, ref);
1148 if (!exist) {
1149 this->add(name, ref);
1150 }
1151 return exist;
1152 }
1153
1159 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1160 std::is_same_v<T,long> ||
1161 std::is_same_v<T,long long> ||
1162 std::is_same_v<T,float> ||
1163 std::is_same_v<T,double>,int> = 0>
1164 void getWithParser (const char* name, T& ref) const
1165 {
1166 int exist = this->queryWithParser(name, ref);
1167 if (!exist) {
1168 amrex::Error(std::string("ParmParse::getWithParser: failed to get ")+name);
1169 }
1170 }
1171
1177 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1178 std::is_same_v<T,long> ||
1179 std::is_same_v<T,long long> ||
1180 std::is_same_v<T,float> ||
1181 std::is_same_v<T,double>,int> = 0>
1182 void getarrWithParser (const char* name, int nvals, T* ref) const
1183 {
1184 int exist = this->queryarrWithParser(name, nvals, ref);
1185 if (!exist) {
1186 amrex::Error(std::string("ParmParse::getarrWithParser: failed to get ")+name);
1187 }
1188 }
1189
1195 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1196 std::is_same_v<T,long> ||
1197 std::is_same_v<T,long long> ||
1198 std::is_same_v<T,float> ||
1199 std::is_same_v<T,double>,int> = 0>
1200 void getarrWithParser (const char* name, int nvals, std::vector<T>& ref) const
1201 {
1202 int exist = this->queryarrWithParser(name, nvals, ref);
1203 if (!exist) {
1204 amrex::Error(std::string("ParmParse::getarrWithParser: failed to get ")+name);
1205 }
1206 }
1207
1208 /*
1209 * \brief Evaluate given string as math expression
1210 *
1211 * For unknown symbols, ParmParse database will be queried.
1212 */
1213 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1214 std::is_same_v<T,long> ||
1215 std::is_same_v<T,long long> ||
1216 std::is_same_v<T,float> ||
1217 std::is_same_v<T,double>,int> = 0>
1218 T eval (std::string const& expr) const
1219 {
1220 if constexpr (std::is_integral_v<T>) {
1221 auto const parser = this->makeIParser(expr, {});
1222 auto const exe = parser.compileHost<0>();
1223 return static_cast<T>(exe()); // In the future, we might add safety check.
1224 } else {
1225 auto const parser = this->makeParser(expr, {});
1226 auto const exe = parser.compileHost<0>();
1227 return static_cast<T>(exe());
1228 }
1229 }
1230
1231 /*
1232 * \brief Query two names.
1233 *
1234 * This function queries with `new_name` first. If it's not found, it
1235 * will try again with `old_name`.
1236 */
1237 template <typename T>
1238 int query (const char* new_name, const char* old_name, T& ref)
1239 {
1240 return (this->query(new_name, ref) ||
1241 this->query(old_name, ref));
1242 }
1243
1251 template <typename T>
1252 void get (const char* new_name, const char* old_name, T& ref)
1253 {
1254 auto exist = this->query(new_name, old_name, ref);
1255 if (!exist) {
1256 amrex::ErrorStream() << "ParmParse::get failed to find "
1257 << new_name << " and " << old_name << '\n';
1259 amrex::Abort();
1260 }
1261 }
1262
1271 template <typename T, typename ET = amrex_enum_traits<T>,
1272 std::enable_if_t<ET::value,int> = 0>
1273 int query (const char* name, T& ref, int ival = FIRST) const
1274 {
1275 std::string s;
1276 int exist = this->query(name, s, ival);
1277 if (exist) {
1278 try {
1279 ref = amrex::getEnum<T>(s);
1280 } catch (...) {
1281 if (amrex::Verbose() > 0 ) {
1282 amrex::Print() << "amrex::ParmParse::query (input name: "
1283 << this->prefixedName(name) << "):\n";
1284 }
1285 throw;
1286 }
1287 }
1288 return exist;
1289 }
1290
1299 template <typename T, typename ET = amrex_enum_traits<T>,
1300 std::enable_if_t<ET::value,int> = 0>
1301 void get (const char* name, T& ref, int ival = FIRST) const
1302 {
1303 std::string s;
1304 this->get(name, s, ival);
1305 try {
1306 ref = amrex::getEnum<T>(s);
1307 } catch (...) {
1308 if (amrex::Verbose() > 0 ) {
1309 amrex::Print() << "amrex::ParmParse::get (input name: "
1310 << this->prefixedName(name) << "):\n";
1311 }
1312 throw;
1313 }
1314 }
1315
1317 template <typename T, typename ET = amrex_enum_traits<T>,
1318 std::enable_if_t<ET::value,int> = 0>
1319 int queryarr (const char* name,
1320 std::vector<T>& ref,
1321 int start_ix = FIRST,
1322 int num_val = ALL) const
1323 {
1324 std::vector<std::string> s;
1325 int exist = this->queryarr(name, s, start_ix, num_val);
1326 if (exist) {
1327 ref.resize(s.size());
1328 for (std::size_t i = 0; i < s.size(); ++i) {
1329 try {
1330 ref[i] = amrex::getEnum<T>(s[i]);
1331 } catch (...) {
1332 if (amrex::Verbose() > 0 ) {
1333 amrex::Print() << "amrex::ParmParse::queryarr (input name: "
1334 << this->prefixedName(name) << "):\n";
1335 }
1336 throw;
1337 }
1338 }
1339 }
1340 return exist;
1341 }
1342
1344 template <typename T, typename ET = amrex_enum_traits<T>,
1345 std::enable_if_t<ET::value,int> = 0>
1346 void getarr (const char* name,
1347 std::vector<T>& ref,
1348 int start_ix = FIRST,
1349 int num_val = ALL) const
1350 {
1351 std::vector<std::string> s;
1352 this->getarr(name, s, start_ix, num_val);
1353 ref.resize(s.size());
1354 for (std::size_t i = 0; i < s.size(); ++i) {
1355 try {
1356 ref[i] = amrex::getEnum<T>(s[i]);
1357 } catch (...) {
1358 if (amrex::Verbose() > 0 ) {
1359 amrex::Print() << "amrex::ParmParse::getarr (input name: "
1360 << this->prefixedName(name) << "):\n";
1361 }
1362 throw;
1363 }
1364 }
1365 }
1366
1377 template <typename T, typename ET = amrex_enum_traits<T>,
1378 std::enable_if_t<ET::value,int> = 0>
1379 int query_enum_case_insensitive (const char* name, T& ref, int ival = FIRST) const
1380 {
1381 std::string s;
1382 int exist = this->query(name, s, ival);
1383 if (exist) {
1384 try {
1385 ref = amrex::getEnumCaseInsensitive<T>(s);
1386 } catch (...) {
1387 if (amrex::Verbose() > 0) {
1388 amrex::Print() << "amrex::ParmParse::query_enum_case_insensitive (input name: "
1389 << this->prefixedName(name) << "):\n";
1390 }
1391 throw;
1392 }
1393 }
1394 return exist;
1395 }
1396
1407 template <typename T, typename ET = amrex_enum_traits<T>,
1408 std::enable_if_t<ET::value,int> = 0>
1409 void get_enum_case_insensitive (const char* name, T& ref, int ival = FIRST) const
1410 {
1411 int exist = this->query_enum_case_insensitive(name, ref, ival);
1412 if (!exist) {
1413 std::string msg("get_enum_case_insensitive(\"");
1414 msg.append(name).append("\",").append(amrex::getEnumClassName<T>())
1415 .append("&) failed.");
1416 amrex::Abort(msg);
1417 }
1418 }
1419
1432 template <typename T, typename ET = amrex_enum_traits<T>,
1433 std::enable_if_t<ET::value,int> = 0>
1434 int query_enum_sloppy (const char* name, T& ref, std::string_view const& ignores,
1435 int ival = FIRST) const
1436 {
1437 std::string s;
1438 int exist = this->query(name, s, ival);
1439 if (exist) {
1440 try {
1441 s.erase(std::remove_if(s.begin(), s.end(),
1442 [&] (auto const& c) {
1443 return ignores.find(c) != std::string_view::npos; }),
1444 s.end());
1445 ref = amrex::getEnumCaseInsensitive<T>(s);
1446 } catch (...) {
1447 if (amrex::Verbose() > 0) {
1448 amrex::Print() << "amrex::ParmParse::query_enum_sloppy (input name: "
1449 << this->prefixedName(name) << "):\n";
1450 }
1451 throw;
1452 }
1453 }
1454 return exist;
1455 }
1456
1469 template <typename T, typename ET = amrex_enum_traits<T>,
1470 std::enable_if_t<ET::value,int> = 0>
1471 void get_enum_sloppy (const char* name, T& ref, std::string_view const& ignores,
1472 int ival = FIRST) const
1473 {
1474 int exist = this->query_enum_sloppy(name, ref, ignores, ival);
1475 if (!exist) {
1476 std::string msg("get_enum_sloppy(\"");
1477 msg.append(name).append("\",").append(amrex::getEnumClassName<T>())
1478 .append("&) failed.");
1479 amrex::Abort(msg);
1480 }
1481 }
1482
1491 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1492 int queryAsDouble (const char* name, T& ref) const
1493 {
1494 using value_type = ppdetail::underlying_type_t<T>;
1495 double dref;
1496 int exist = queryWithParser(name, dref);
1497 if (exist) {
1498 if (std::is_integral_v<value_type>) {
1499 dref = std::round(dref);
1500 }
1501 auto vref = static_cast<value_type>(dref);
1502 if constexpr (std::is_integral_v<value_type> && !std::is_same_v<value_type,bool>) {
1503 if (static_cast<double>(vref) != dref) {
1504 amrex::Abort("ParmParse:: queryAsDouble is not safe");
1505 }
1506 }
1507 ref = vref;
1508 }
1509 return exist;
1510 }
1511
1520 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1521 int queryarrAsDouble (const char* name, int nvals, T* ref) const
1522 {
1523 using value_type = ppdetail::underlying_type_t<T>;
1524 std::vector<double> dref(nvals);
1525 int exist = queryarrWithParser(name, nvals, dref.data());
1526 if (exist) {
1527 for (int i = 0; i < nvals; ++i) {
1528 if (std::is_integral_v<value_type>) {
1529 dref[i] = std::round(dref[i]);
1530 }
1531 auto vref = static_cast<value_type>(dref[i]);
1532 if constexpr (std::is_integral_v<value_type> && !std::is_same_v<value_type,bool>) {
1533 if (static_cast<double>(vref) != dref[i]) {
1534 amrex::Abort("ParmParse:: queryarrAsDouble is not safe");
1535 }
1536 }
1537 ref[i] = vref;
1538 }
1539 }
1540 return exist;
1541 }
1542
1551 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1552 void getAsDouble (const char* name, T& ref) const
1553 {
1554 int exist = this->queryAsDouble(name, ref);
1555 if (!exist) {
1556 amrex::Error(std::string("ParmParse::getAsDouble: failed to get ")+name);
1557 }
1558 }
1559
1568 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1569 void getarrAsDouble (const char* name, int nvals, T* ref) const
1570 {
1571 int exist = this->queryarrAsDouble(name, nvals, ref);
1572 if (!exist) {
1573 amrex::Error(std::string("ParmParse::getarrAsDouble: failed to get ")+name);
1574 }
1575 }
1576
1578 int remove (const char* name);
1579
1583 [[nodiscard]] Parser makeParser (std::string const& func,
1584 Vector<std::string> const& vars) const;
1585
1589 [[nodiscard]] IParser makeIParser (std::string const& func,
1590 Vector<std::string> const& vars) const;
1591
1599 static void Initialize (int argc, char** argv, const char* parfile);
1604 static void Finalize ();
1605
1607 static void SetParserPrefix (std::string a_prefix);
1608
1609 static int Verbose ();
1610 static void SetVerbose (int v);
1611
1613 static void dumpTable (std::ostream& os, bool prettyPrint = false);
1614
1617 static void prettyPrintTable (std::ostream& os);
1618
1620 static void addfile (std::string const& filename);
1621
1622 static bool QueryUnusedInputs ();
1623
1625 [[nodiscard]] static bool hasUnusedInputs (const std::string& prefix = std::string());
1626
1628 [[nodiscard]] static std::vector<std::string> getUnusedInputs (const std::string& prefix = std::string());
1629
1631 [[nodiscard]] static std::set<std::string> getEntries (const std::string& prefix = std::string());
1632
1633 struct PP_entry {
1634 // There can be multiple occurrences for a given name (e.g.,
1635 // multiple lines starting with `foo =` in inputs. For each
1636 // occurrence, there can be multiple values. Thus, the use of
1637 // vector<vector<std::string>>.
1638 std::vector<std::vector<std::string>> m_vals;
1639 mutable Long m_count = 0;
1640 std::variant<
1641 std::string*,
1642 bool*,
1643 int*,
1644 long*,
1645 long long*,
1647 amrex::Box*,
1648 float*,
1649 double*
1650 > m_typehint = static_cast<std::string*>(nullptr);
1651 };
1652 using Table = std::unordered_map<std::string, PP_entry>;
1653
1654 [[nodiscard]] const Table& table() const {return *m_table;}
1655
1657 static std::string const FileKeyword;
1658
1659 static std::string ParserPrefix;
1660
1661 [[nodiscard]] std::string prefixedName (const std::string_view& str) const;
1662
1663protected:
1664
1665 std::string m_prefix; // Prefix used in keyword search
1666 std::string m_parser_prefix; // Prefix used by Parser
1668};
1669
1670}
1671
1672#endif /* AMREX_PARMPARSE_H_ */
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
Definition AMReX_IParser.H:58
IParserExecutor< N > compileHost() const
This compiles for CPU only.
Definition AMReX_IParser.H:111
Parse Parameters From Command Line and Input Files.
Definition AMReX_ParmParse.H:324
bool contains(const char *name) const
Returns true if name is in table.
Definition AMReX_ParmParse.cpp:1947
int queryarrWithParser(const char *name, int nvals, int *ref) const
Query with Parser. The return value indicates whether it's found. Note that queryWithParser will be u...
Definition AMReX_ParmParse.cpp:2041
int queryAddWithParser(const char *name, T &ref)
Query with Parser. If name is found, this uses amrex::Parser to parse the entire list of empty space ...
Definition AMReX_ParmParse.H:1145
void getarrWithParser(const char *name, int nvals, std::vector< T > &ref) const
Get with Parser. If name is not found, it's a runtime error. If the number of elements does not equal...
Definition AMReX_ParmParse.H:1200
void addarr(const char *name, const std::vector< int > &ref)
Add a key 'name' with vector of values 'ref' to the end of the PP table.
Definition AMReX_ParmParse.cpp:1396
void get(const char *name, bool &ref, int ival=FIRST) const
Same as getkth() but searches for the last occurrence of name.
Definition AMReX_ParmParse.cpp:1305
void get(const char *name, std::array< T, N > &ref) const
Definition AMReX_ParmParse.H:989
static void prettyPrintTable(std::ostream &os)
Definition AMReX_ParmParse.cpp:1258
static void Initialize(int argc, char **argv, const char *parfile)
Construct an initial ParmParse object from the argc and argv passed in to main(). An error will be si...
Definition AMReX_ParmParse.cpp:1100
int queryarrWithParser(const char *name, int nvals, std::vector< T > &ref) const
Definition AMReX_ParmParse.H:1124
static void addfile(std::string const &filename)
Add keys and values from a file to the end of the PP table.
Definition AMReX_ParmParse.cpp:1075
int queryAsDouble(const char *name, T &ref) const
Query T with Parser, but treat the number as double precision during parsing.
Definition AMReX_ParmParse.H:1492
int query(const char *name, T &ref, int ival=FIRST) const
. Query enum value using given name.
Definition AMReX_ParmParse.H:1273
static std::string const FileKeyword
keyword for files to load
Definition AMReX_ParmParse.H:1657
static std::string ParserPrefix
Definition AMReX_ParmParse.H:1659
static int Verbose()
Definition AMReX_ParmParse.cpp:1181
void getAsDouble(const char *name, T &ref) const
Get T with Parser, but treat the number as double precision during parsing.
Definition AMReX_ParmParse.H:1552
static void SetVerbose(int v)
Definition AMReX_ParmParse.cpp:1194
void get(const char *new_name, const char *old_name, T &ref)
Get using two names.
Definition AMReX_ParmParse.H:1252
int queryarr(const char *name, std::vector< int > &ref, int start_ix=FIRST, int num_val=ALL) const
Same as queryktharr() but searches for last occurrence of name.
Definition AMReX_ParmParse.cpp:1389
int query_enum_sloppy(const char *name, T &ref, std::string_view const &ignores, int ival=FIRST) const
. Query enum value using given name.
Definition AMReX_ParmParse.H:1434
int queryAdd(const char *name, T &ref)
If name is found, the value in the ParmParse database will be stored in the ref argument....
Definition AMReX_ParmParse.H:1018
int queryAdd(const char *name, std::vector< T > &ref, int num_val)
If name is found, the value in the ParmParse database will be stored in the ref argument....
Definition AMReX_ParmParse.H:1063
void getarr(const char *name, std::vector< int > &ref, int start_ix=FIRST, int num_val=ALL) const
Same as getktharr() but searches for last occurrence of name.
Definition AMReX_ParmParse.cpp:1375
static bool hasUnusedInputs(const std::string &prefix=std::string())
Any unused [prefix.]* parameters?
Definition AMReX_ParmParse.cpp:1132
void getWithParser(const char *name, T &ref) const
Get with Parser. If name is found, this uses amrex::Parser to parse the entire list of empty space se...
Definition AMReX_ParmParse.H:1164
int remove(const char *name)
Remove given name from the table.
Definition AMReX_ParmParse.cpp:1963
Parser makeParser(std::string const &func, Vector< std::string > const &vars) const
Definition AMReX_ParmParse.cpp:2071
int query(const char *name, std::array< T, N > &ref) const
Definition AMReX_ParmParse.H:999
void getkth(const char *name, int k, bool &ref, int ival=FIRST) const
Get the ival'th value of kth occurrence of the requested name. If successful, the value is converted ...
Definition AMReX_ParmParse.cpp:1296
void getarrAsDouble(const char *name, int nvals, T *ref) const
Get T array with Parser, but treat the number as double precision during parsing.
Definition AMReX_ParmParse.H:1569
int queryktharr(const char *name, int k, std::vector< int > &ref, int start_ix=FIRST, int num_val=ALL) const
queryktharr() is to querykth() as getktharr() is to getkth().
Definition AMReX_ParmParse.cpp:1382
int queryAdd(const char *name, std::vector< T > &ref)
If name is found, the value in the ParmParse database will be stored in the ref argument....
Definition AMReX_ParmParse.H:1044
static bool QueryUnusedInputs()
Definition AMReX_ParmParse.cpp:1117
void add(const char *name, bool val)
Add a key 'name'with value 'ref' to the end of the PP table.
Definition AMReX_ParmParse.cpp:1330
T eval(std::string const &expr) const
Definition AMReX_ParmParse.H:1218
void getktharr(const char *name, int k, std::vector< int > &ref, int start_ix=FIRST, int num_val=ALL) const
Gets an std::vector<int> of num_val values from kth occurrence of given name. If successful,...
Definition AMReX_ParmParse.cpp:1368
static void Finalize()
The destructor. The internal static table will only be deleted if there are no other ParmParse object...
Definition AMReX_ParmParse.cpp:1200
std::string m_prefix
Definition AMReX_ParmParse.H:1665
int countname(const std::string &name) const
Returns the number of times the given name (prepended with prefix) appears in the table.
Definition AMReX_ParmParse.cpp:1931
void getline(const char *name, std::string &ref) const
Definition AMReX_ParmParse.cpp:1908
const Table & table() const
Definition AMReX_ParmParse.H:1654
std::string prefixedName(const std::string_view &str) const
Definition AMReX_ParmParse.cpp:1061
static void SetParserPrefix(std::string a_prefix)
Set prefix used by math expression Parser.
Definition AMReX_ParmParse.cpp:1227
static std::vector< std::string > getUnusedInputs(const std::string &prefix=std::string())
Returns unused [prefix.]* parameters.
Definition AMReX_ParmParse.cpp:1138
int query(const char *name, bool &ref, int ival=FIRST) const
Same as querykth() but searches for the last occurrence of name.
Definition AMReX_ParmParse.cpp:1322
@ FIRST
Definition AMReX_ParmParse.H:326
@ LAST
Definition AMReX_ParmParse.H:326
@ ALL
Definition AMReX_ParmParse.H:326
int queryarr(const char *name, std::vector< T > &ref, int start_ix=FIRST, int num_val=ALL) const
Query an array of enum values using given name.
Definition AMReX_ParmParse.H:1319
int queryWithParser(const char *name, int &ref) const
Query with Parser. If name is found, this uses amrex::Parser to parse the entire list of empty space ...
Definition AMReX_ParmParse.cpp:2011
int query(const char *new_name, const char *old_name, T &ref)
Definition AMReX_ParmParse.H:1238
void get_enum_case_insensitive(const char *name, T &ref, int ival=FIRST) const
. Get enum value using given name.
Definition AMReX_ParmParse.H:1409
Table * m_table
Definition AMReX_ParmParse.H:1667
int queryline(const char *name, std::string &ref) const
Definition AMReX_ParmParse.cpp:1916
std::string m_parser_prefix
Definition AMReX_ParmParse.H:1666
int countval(const char *name, int n=LAST) const
Returns the number of values associated with nth occurrence of name (prepended with the prefix) in th...
Definition AMReX_ParmParse.cpp:1284
int querykth(const char *name, int k, bool &ref, int ival=FIRST) const
Similar to getkth() but returns 0 if there is no kth occurrence of name. If successful,...
Definition AMReX_ParmParse.cpp:1313
int queryAdd(const char *name, std::string &ref)
Definition AMReX_ParmParse.H:1026
static void dumpTable(std::ostream &os, bool prettyPrint=false)
Write the contents of the table in ASCII to the ostream.
Definition AMReX_ParmParse.cpp:1233
int queryarrAsDouble(const char *name, int nvals, T *ref) const
Query T array with Parser, but treat the number as double precision during parsing.
Definition AMReX_ParmParse.H:1521
void getarrWithParser(const char *name, int nvals, T *ref) const
Get with Parser. If name is not found, it's a runtime error. If the number of elements does not equal...
Definition AMReX_ParmParse.H:1182
void get(const char *name, T &ref, int ival=FIRST) const
. Get enum value using given name.
Definition AMReX_ParmParse.H:1301
static std::set< std::string > getEntries(const std::string &prefix=std::string())
Returns [prefix.]* parameters.
Definition AMReX_ParmParse.cpp:1168
void getarr(const char *name, std::vector< T > &ref, int start_ix=FIRST, int num_val=ALL) const
Get an array of enum values using given name.
Definition AMReX_ParmParse.H:1346
int query_enum_case_insensitive(const char *name, T &ref, int ival=FIRST) const
. Query enum value using given name.
Definition AMReX_ParmParse.H:1379
void get_enum_sloppy(const char *name, T &ref, std::string_view const &ignores, int ival=FIRST) const
. Get enum value using given name.
Definition AMReX_ParmParse.H:1471
std::unordered_map< std::string, PP_entry > Table
Definition AMReX_ParmParse.H:1652
IParser makeIParser(std::string const &func, Vector< std::string > const &vars) const
Definition AMReX_ParmParse.cpp:2078
int queryAdd(const char *name, std::array< T, N > &ref)
If name is found, the value in the ParmParse database will be stored in the ref argument....
Definition AMReX_ParmParse.H:1078
Definition AMReX_Parser.H:68
ParserExecutor< N > compileHost() const
This compiles for CPU only.
Definition AMReX_Parser.H:124
This class provides the user with a few print options.
Definition AMReX_Print.H:35
A Real vector in SpaceDim-dimensional space.
Definition AMReX_RealVect.H:32
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:27
typename ArithmeticOptional_TT< T >::value_type underlying_type_t
Definition AMReX_ParmParse.H:58
constexpr bool IsArithmeticOptional_v
Definition AMReX_ParmParse.H:55
Definition AMReX_Amr.cpp:49
std::ostream & ErrorStream()
Definition AMReX.cpp:905
BoxND< AMREX_SPACEDIM > Box
Definition AMReX_BaseFwd.H:27
IntVectND< AMREX_SPACEDIM > IntVect
Definition AMReX_BaseFwd.H:30
AMREX_GPU_HOST_DEVICE IntVectND(const Array< int, dim > &) -> IntVectND< dim >
void Error(const std::string &msg)
Print out message to cerr and exit via amrex::Abort().
Definition AMReX.cpp:224
int Verbose() noexcept
Definition AMReX.cpp:169
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
Definition AMReX_ParmParse.H:1633
std::variant< std::string *, bool *, int *, long *, long long *, amrex::IntVect *, amrex::Box *, float *, double * > m_typehint
Definition AMReX_ParmParse.H:1650
std::vector< std::vector< std::string > > m_vals
Definition AMReX_ParmParse.H:1638
Long m_count
Definition AMReX_ParmParse.H:1639
Definition AMReX_ParmParse.H:37