Block-Structured AMR Software Framework
 
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_Enum.H>
7#include <AMReX_INT.H>
8#include <AMReX_IParser.H>
9#include <AMReX_Parser.H>
10#include <AMReX_TypeTraits.H>
11
12#include <array>
13#include <iosfwd>
14#include <optional>
15#include <set>
16#include <string>
17#include <string_view>
18#include <unordered_map>
19#include <vector>
20
21namespace amrex {
22
23template<int dim>
24class BoxND;
25using Box = BoxND<AMREX_SPACEDIM>;
26template<int dim>
27class IntVectND;
28using IntVect = IntVectND<AMREX_SPACEDIM>;
29class RealVect;
30
31namespace ppdetail {
32 template <class T, class Enable = void>
33 struct ArithmeticOptional_TT : std::false_type {};
34
35 template <class T>
36 struct ArithmeticOptional_TT<T, std::enable_if_t<std::is_arithmetic_v<T>>>
37 : std::true_type
38 {
39 using value_type = T;
40 };
41
42 template <class T>
43 struct ArithmeticOptional_TT<std::optional<T>,
44 std::enable_if_t<std::is_arithmetic_v<T>>>
45 : std::true_type
46 {
47 using value_type = T;
48 };
49
50 template <class T>
52
53 template <class T>
55}
56
57//
58// ParmParse class implements a simple database for the storage and
59// retrieval of command-line and input-file arguments. The entries are
60// stored in a static table in (name,value_list) pairs.
61//
62// The format of the input file is a series of DEFINITIONS.
63//
64// A DEFINITION is of the form <name> = <value> <value> ...
65// The equal sign is important since the list of values can span multiple
66// lines.
67//
68// Comments in an input file include all text from a '#' character to the
69// end of the line. Here is an example input file:
70/*
71 niter = 100 # niter is an integer
72 title = "Double Wammy" # example of a string with spaces
73 cell_size = 0.5 0.75 # cell spacing in each dimension
74 plot.var = Density 1 10 # a list of values
75 plot.var = Energy 5 12 # another list of values
76 bigarray = 1 2 3 4 5 6 7 8 \
77 9 10 11 12 # continuation of bigarray
78 multi_line_string = "This is a
79 multi-line string."
80 test = apple "boy blue" 10 20 30 40
81 FILE = prob_file # insert contents of this "prob_file" here
82*/
83// For values spanning multiple lines, one must use '\' at the end of a line
84// for continuation, otherwise it's a runtime error. Note that there must be
85// at least one space before the continuation character `\`. Multiple lines
86// inside a pair of double quotes are considered a single string containing
87// '\n's. The "FILE = <filename>" definition is special. Rather than just
88// adding this entry to the database, it reads the contents of <filename>
89// into the database.
90// For CI/CD workflows and out-of-source tests, the environment variable
91// AMREX_INPUTS_FILE_PREFIX can be set to prefix every FILE = <filename>
92// with a custom path.
93//
94// ParmParse stores all entries in a static table which is built the
95// first time a ParmParse object is constructed (usually in main()).
96// Subsequent invocations have access to this table.
97// A ParmParse constructor has an optional "prefix" argument that will
98// limit the searches to only those entries of the table with this prefix
99// in name. For example:
100// ParmParse pp("plot");
101// will find only those entries with name given by "plot.<string>".
102//
103// All values in the table are stored as strings. For example, the
104// values of "cell_size" in the above input file are stored as the
105// strings "0.5" and "0.75". These strings can be returned as either
106// strings or numeric values by the query functions.
107// Character strings with spaces must be delimited by double quotes
108// in the input file but the quotes are stripped before they are entered
109// into the table. For example, 'title' in the above input file has a
110// single value, the string 'Double Wammy' (without the quotes).
111// Each value in the list associated with a definition can be referred to
112// by its index number. The index numbers start at 0 just like an array
113// in the C programming language. Consider the definition of "test" in
114// the above input file. The first value 'apple'is a string with index
115// 0. The second value 'boy blue' is a string with index 1. The
116// remaining four values are integers indexed 2, 3, 4, and 5.
117//
118// For a string value to represent an integer or float it must fit the
119// following regular expression:
120// Sign ::= '+' | '-'
121// Digit ::= '0' | '1' | ... | '9'
122// Integer ::= [Sign]Digit+
123// Exp ::= ('e'|'E')Integer
124// Float ::= ( Integer[.Digit*][Exp] | [Integer].Digit+[Exp] )
125//
126// Where '+' indicates one or more occurrences, '*' represents zero or
127// more occurrences, '|' means one or the other and '[]' represents zero
128// or one occurrence.
129//
130// Note that floats and doubles have the same string representation and
131// that the FORTRAN "double" exponent format is not supported.
132// That is, 1.0d+3 is not a valid representation of a floating point
133// number but that 1.0e+3 is acceptable.
134//
135// There are a host of functions allowing the user to query the database
136// and retrieve values. Here are some general rules about the names of
137// the member functions:
138//
139// * Functions with the string "get" in their names attempt to get a
140// value or an array of values from the table. They generate a
141// run-time error if they are not successful.
142//
143// * Functions with the string "query" in their names attempt to get a
144// value or an array of values from the table. They return the value 1
145// (true) if they are successful and 0 (false) if not.
146//
147// * Functions with the string "kth" in their names get values from
148// the Kth entry with the given name in the database. This is
149// necessary since there may be multiple definitions with the same
150// name in the database.
151//
152// * Functions without the string "kth" in their names get values from
153// the last entry with the given name in the database. Note that the
154// definitions from the command line are appended to the database table
155// and hence will be the last entries.
156//
157// * Functions with the string "arr" in their names get an Array of
158// values from the given entry in the table. The array argument is
159// resized (if necessary) to hold all the values requested.
160//
161// * Functions without the string "arr" in their names get single
162// values from the given entry in the table.
163//
164// The following is a code sample showing how to use ParmParse:
165//
166// main(int argc, char **argv)
167// {
168// char* in_file_name = argv[1];
169// ParmParse::Initialize(argc-2, argv+2, in_file_name);
170//
171// // Query table for value of "niter". If not in table
172// // then set to default value
173// if (!pp.query("niter",niter)) niter = 20;
174//
175// // read array of cell sizes if in table
176// Vector<float> dx;
177// if (nx=pp.countval("cell_size")) {
178// // get nx values starting at index 0 and store in dx.
179// // dx is automatically resized here.
180// pp.getarr("cell_size",dx,0,nx);
181// }
182// ParmParse::Finalize();
183// }
184//
185// void do_graphics()
186// {
187// //
188// // Will only query entries with the "plot" prefix:
189// //
190// ParmParse pp("plot");
191// //
192// // Read all variables with "plot.var" keyword.
193// //
194// std::string var_name;
195// Vector<int> range;
196// int num = pp.countname("var");
197// for (int k = 0; k < num; k++)
198// {
199// //
200// // Element 0 in list is a string.
201// //
202// pp.getkth("var",k,var_name,0);
203// //
204// // Elements 1 and 2 are integers.
205// // Note that "range" will be resized to hold 2 elements.
206// //
207// pp.getktharr("var",k,range,1,2);
208// cout << "variable = " << var_name << "lo, hi = ",
209// << range[0] << " " << range[1] << endl;
210// }
211// }
212// -----------------------------------------------------------------
213// ----------------------- END COMMENTS ---------------------------
214// -----------------------------------------------------------------
215
216
320{
321public:
322 enum { LAST = -1, FIRST = 0, ALL = -1 };
330 explicit ParmParse (std::string prefix = std::string(),
331 std::string parser_prefix = std::string());
332
334 [[nodiscard]] bool contains (const char* name) const;
340 [[nodiscard]] int countval (const char* name, int n = LAST) const;
345 [[nodiscard]] int countname (const std::string& name) const;
357 void getkth (const char* name,
358 int k,
359 bool& ref,
360 int ival = FIRST) const;
362 void get (const char* name,
363 bool& ref,
364 int ival = FIRST) const;
372 int querykth (const char* name,
373 int k,
374 bool& ref,
375 int ival = FIRST) const;
377 int query (const char* name,
378 bool& ref,
379 int ival = FIRST) const;
381 void add (const char* name, bool val);
391 void getkth (const char* name,
392 int k,
393 int& ref,
394 int ival = FIRST) const;
395
397 void get (const char* name,
398 int& ref,
399 int ival = FIRST) const;
407 int querykth (const char* name,
408 int k,
409 int& ref,
410 int ival = FIRST) const;
412 int query (const char* name,
413 int& ref,
414 int ival = FIRST) const;
416 void add (const char* name, int val);
426 void getkth (const char* name,
427 int k,
428 long& ref,
429 int ival = FIRST) const;
431 void get (const char* name,
432 long& ref,
433 int ival = FIRST) const;
441 int querykth (const char* name,
442 int k,
443 long& ref,
444 int ival = FIRST) const;
446 int query (const char* name,
447 long& ref,
448 int ival = FIRST) const;
450 void add (const char* name, long val);
460 void getkth (const char* name,
461 int k,
462 long long& ref,
463 int ival = FIRST) const;
465 void get (const char* name,
466 long long& ref,
467 int ival = FIRST) const;
475 int querykth (const char* name,
476 int k,
477 long long& ref,
478 int ival = FIRST) const;
480 int query (const char* name,
481 long long& ref,
482 int ival = FIRST) const;
484 void add (const char* name, long long val);
494 void getkth (const char* name,
495 int k,
496 float& ref,
497 int ival = FIRST) const;
499 void get (const char* name,
500 float& ref,
501 int ival = FIRST) const;
509 int querykth (const char* name,
510 int k,
511 float& ref,
512 int ival = FIRST) const;
514 int query (const char* name,
515 float& ref,
516 int ival = FIRST) const;
518 void add (const char* name, float val);
528 void getkth (const char* name,
529 int k,
530 double& ref,
531 int ival = FIRST) const;
533 void get (const char* name,
534 double& ref,
535 int ival = FIRST) const;
543 int querykth (const char* name,
544 int k,
545 double& ref,
546 int ival = FIRST) const;
548 int query (const char* name,
549 double& ref,
550 int ival = FIRST) const;
552 void add (const char* name, double val);
562 void getkth (const char* name,
563 int k,
564 std::string& ref,
565 int ival = FIRST) const;
566
568 void get (const char* name,
569 std::string& ref,
570 int ival = FIRST) const;
578 int querykth (const char* name,
579 int k,
580 std::string& ref,
581 int ival = FIRST) const;
583 int query (const char* name,
584 std::string& ref,
585 int ival = FIRST) const;
587 void add (const char* name, const std::string& val);
588
598 void getkth (const char* name,
599 int k,
600 IntVect& ref,
601 int ival = FIRST) const;
603 void get (const char* name,
604 IntVect& ref,
605 int ival = FIRST) const;
613 int querykth (const char* name,
614 int k,
615 IntVect& ref,
616 int ival = FIRST) const;
618 int query (const char* name,
619 IntVect& ref,
620 int ival = FIRST) const;
622 void add (const char* name, const IntVect& val);
632 void getkth (const char* name,
633 int k,
634 Box& ref,
635 int ival = FIRST) const;
637 void get (const char* name,
638 Box& ref,
639 int ival = FIRST) const;
647 int querykth (const char* name,
648 int k,
649 Box& ref,
650 int ival = FIRST) const;
652 int query (const char* name,
653 Box& ref,
654 int ival = FIRST) const;
656 void add (const char* name, const Box& val);
669 void getktharr (const char* name,
670 int k,
671 std::vector<int>& ref,
672 int start_ix = FIRST,
673 int num_val = ALL) const;
675 void getarr (const char* name,
676 std::vector<int>& ref,
677 int start_ix = FIRST,
678 int num_val = ALL) const;
680 int queryktharr (const char* name,
681 int k,
682 std::vector<int>& ref,
683 int start_ix = FIRST,
684 int num_val = ALL) const;
686 int queryarr (const char* name,
687 std::vector<int>& ref,
688 int start_ix = FIRST,
689 int num_val = ALL) const;
691 void addarr (const char* name, const std::vector<int>& ref);
692
705 void getktharr (const char* name,
706 int k,
707 std::vector<long>& ref,
708 int start_ix = FIRST,
709 int num_val = ALL) const;
711 void getarr (const char* name,
712 std::vector<long>& ref,
713 int start_ix = FIRST,
714 int num_val = ALL) const;
716 int queryktharr (const char* name,
717 int k,
718 std::vector<long>& ref,
719 int start_ix = FIRST,
720 int num_val = ALL) const;
722 int queryarr (const char* name,
723 std::vector<long>& ref,
724 int start_ix = FIRST,
725 int num_val = ALL) const;
727 void addarr (const char* name, const std::vector<long>& ref);
728
741 void getktharr (const char* name,
742 int k,
743 std::vector<long long>& ref,
744 int start_ix = FIRST,
745 int num_val = ALL) const;
747 void getarr (const char* name,
748 std::vector<long long>& ref,
749 int start_ix = FIRST,
750 int num_val = ALL) const;
752 int queryktharr (const char* name,
753 int k,
754 std::vector<long long>& ref,
755 int start_ix = FIRST,
756 int num_val = ALL) const;
758 int queryarr (const char* name,
759 std::vector<long long>& ref,
760 int start_ix = FIRST,
761 int num_val = ALL) const;
763 void addarr (const char* name, const std::vector<long long>& ref);
764
777 void getktharr (const char* name,
778 int k,
779 std::vector<float>& ref,
780 int start_ix = FIRST,
781 int num_val = ALL) const;
783 void getarr (const char* name,
784 std::vector<float>& ref,
785 int start_ix = FIRST,
786 int num_val = ALL) const;
788 int queryktharr (const char* name,
789 int k,
790 std::vector<float>& ref,
791 int start_ix = FIRST,
792 int num_val = ALL) const;
794 int queryarr (const char* name,
795 std::vector<float>& ref,
796 int start_ix = FIRST,
797 int num_val = ALL) const;
799 void addarr (const char* name, const std::vector<float>& ref);
812 void getktharr (const char* name,
813 int k,
814 std::vector<double>& ref,
815 int start_ix = FIRST,
816 int num_val = ALL) const;
818 void getarr (const char* name,
819 std::vector<double>& ref,
820 int start_ix = FIRST,
821 int num_val = ALL) const;
823 int queryktharr (const char* name,
824 int k,
825 std::vector<double>& ref,
826 int start_ix = FIRST,
827 int num_val = ALL) const;
829 int queryarr (const char* name,
830 std::vector<double>& ref,
831 int start_ix = FIRST,
832 int num_val = ALL) const;
834 void addarr (const char* name, const std::vector<double>& ref);
847 void getktharr (const char* name,
848 int k,
849 std::vector<std::string>& ref,
850 int start_ix = FIRST,
851 int num_val = ALL) const;
853 void getarr (const char* name,
854 std::vector<std::string>& ref,
855 int start_ix = FIRST,
856 int num_val = ALL) const;
858 int queryktharr (const char* name,
859 int k,
860 std::vector<std::string>& ref,
861 int start_ix = FIRST,
862 int num_val = ALL) const;
864 int queryarr (const char* name,
865 std::vector<std::string>& ref,
866 int start_ix = FIRST,
867 int num_val = ALL) const;
869 void addarr (const char* name, const std::vector<std::string>& ref);
882 void getktharr (const char* name,
883 int k,
884 std::vector<IntVect>& ref,
885 int start_ix = FIRST,
886 int num_val = ALL) const;
888 void getarr (const char* name,
889 std::vector<IntVect>& ref,
890 int start_ix = FIRST,
891 int num_val = ALL) const;
893 int queryktharr (const char* name,
894 int k,
895 std::vector<IntVect>& ref,
896 int start_ix = FIRST,
897 int num_val = ALL) const;
899 int queryarr (const char* name,
900 std::vector<IntVect>& ref,
901 int start_ix = FIRST,
902 int num_val = ALL) const;
904 void addarr (const char* name, const std::vector<IntVect>& ref);
917 void getktharr (const char* name,
918 int k,
919 std::vector<Box>& ref,
920 int start_ix = FIRST,
921 int num_val = ALL) const;
923 void getarr (const char* name,
924 std::vector<Box>& ref,
925 int start_ix = FIRST,
926 int num_val = ALL) const;
928 int queryktharr (const char* name,
929 int k,
930 std::vector<Box>& ref,
931 int start_ix = FIRST,
932 int num_val = ALL) const;
934 int queryarr (const char* name,
935 std::vector<Box>& ref,
936 int start_ix = FIRST,
937 int num_val = ALL) const;
939 void addarr (const char* name, const std::vector<Box>& refd);
940
941 /*
942 * \brief Query IntVect from array
943 *
944 * This reads IntVect from an array (e.g., `8 16 8`), not the format
945 * using parentheses (e.g., `(8,16,8)`).
946 */
947 int queryarr (const char* name, IntVect& ref) const;
948
949 /*
950 * \brief Get IntVect from array
951 *
952 * This reads IntVect from an array (e.g., `8 16 8`), not the format
953 * using parentheses (e.g., `(8,16,8)`).
954 */
955 void getarr (const char* name, IntVect& ref) const;
956
958 int queryarr (const char* name, RealVect& ref) const;
959
961 void getarr (const char* name, RealVect& ref) const;
962
963 template <typename T, std::size_t N>
964 void get (const char* name, std::array<T,N>& ref) const {
965 std::vector<T> v;
966 this->getarr(name, v);
967 AMREX_ALWAYS_ASSERT(v.size() >= N);
968 for (std::size_t i = 0; i < N; ++i) {
969 ref[i] = v[i];
970 }
971 }
972
973 template <typename T, std::size_t N>
974 int query (const char* name, std::array<T,N>& ref) const {
975 std::vector<T> v;
976 int exist = this->queryarr(name, v);
977 if (exist) {
978 AMREX_ALWAYS_ASSERT(v.size() >= N);
979 for (std::size_t i = 0; i < N; ++i) {
980 ref[i] = v[i];
981 }
982 }
983 return exist;
984 }
985
992 template <typename T, std::enable_if_t<!IsStdVector<T>::value, int> = 0>
993 int queryAdd (const char* name, T& ref) {
994 int exist = this->query(name, ref);
995 if (!exist) {
996 this->add(name, ref);
997 }
998 return exist;
999 }
1000
1001 int queryAdd (const char* name, std::string& ref) {
1002 int exist = this->query(name, ref);
1003 if (!exist && !ref.empty()) {
1004 this->add(name, ref);
1005 }
1006 return exist;
1007 }
1008
1018 template <typename T>
1019 int queryAdd (const char* name, std::vector<T>& ref) {
1020 std::vector<T> empty;
1021 int exist = this->queryarr(name, empty);
1022 if (exist) {
1023 ref = std::move(empty);
1024 }
1025 if (!exist && !ref.empty()) {
1026 this->addarr(name, ref);
1027 }
1028 return exist;
1029 }
1030
1037 template <typename T>
1038 int queryAdd (const char* name, std::vector<T>& ref, int num_val) {
1039 int exist = this->queryarr(name, ref, 0, num_val);
1040 if (!exist) {
1041 this->addarr(name, ref);
1042 }
1043 return exist;
1044 }
1045
1052 template <typename T, std::size_t N>
1053 int queryAdd (const char* name, std::array<T,N>& ref) {
1054 std::vector<T> v;
1055 int exist = this->queryarr(name, v);
1056 if (exist) {
1057 AMREX_ALWAYS_ASSERT(v.size() >= N);
1058 for (std::size_t i = 0; i < N; ++i) {
1059 ref[i] = v[i];
1060 }
1061 } else {
1062 v.resize(N);
1063 for (std::size_t i = 0; i < N; ++i) {
1064 v[i] = ref[i];
1065 }
1066 this->addarr(name, v);
1067 }
1068 return exist;
1069 }
1070
1077 int queryWithParser (const char* name, int& ref) const;
1078 int queryWithParser (const char* name, long& ref) const;
1079 int queryWithParser (const char* name, long long& ref) const;
1080 int queryWithParser (const char* name, float& ref) const;
1081 int queryWithParser (const char* name, double& ref) const;
1082
1089 int queryarrWithParser (const char* name, int nvals, int* ref) const;
1090 int queryarrWithParser (const char* name, int nvals, long* ref) const;
1091 int queryarrWithParser (const char* name, int nvals, long long* ref) const;
1092 int queryarrWithParser (const char* name, int nvals, float* ref) const;
1093 int queryarrWithParser (const char* name, int nvals, double* ref) const;
1094 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1095 std::is_same_v<T,long> ||
1096 std::is_same_v<T,long long> ||
1097 std::is_same_v<T,float> ||
1098 std::is_same_v<T,double>,int> = 0>
1099 int queryarrWithParser (const char* name, int nvals, std::vector<T>& ref) const
1100 {
1101 if (this->contains(name)) {
1102 if (int(ref.size()) < nvals) { ref.resize(nvals); }
1103 return this->queryarrWithParser(name, nvals, ref.data());
1104 } else {
1105 return 0;
1106 }
1107 }
1108
1115 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1116 std::is_same_v<T,long> ||
1117 std::is_same_v<T,long long> ||
1118 std::is_same_v<T,float> ||
1119 std::is_same_v<T,double>,int> = 0>
1120 int queryAddWithParser (const char* name, T& ref)
1121 {
1122 int exist = this->queryWithParser(name, ref);
1123 if (!exist) {
1124 this->add(name, ref);
1125 }
1126 return exist;
1127 }
1128
1134 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1135 std::is_same_v<T,long> ||
1136 std::is_same_v<T,long long> ||
1137 std::is_same_v<T,float> ||
1138 std::is_same_v<T,double>,int> = 0>
1139 void getWithParser (const char* name, T& ref) const
1140 {
1141 int exist = this->queryWithParser(name, ref);
1142 if (!exist) {
1143 amrex::Error(std::string("ParmParse::getWithParser: failed to get ")+name);
1144 }
1145 }
1146
1152 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1153 std::is_same_v<T,long> ||
1154 std::is_same_v<T,long long> ||
1155 std::is_same_v<T,float> ||
1156 std::is_same_v<T,double>,int> = 0>
1157 void getarrWithParser (const char* name, int nvals, T* ref) const
1158 {
1159 int exist = this->queryarrWithParser(name, nvals, ref);
1160 if (!exist) {
1161 amrex::Error(std::string("ParmParse::getarrWithParser: failed to get ")+name);
1162 }
1163 }
1164
1170 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1171 std::is_same_v<T,long> ||
1172 std::is_same_v<T,long long> ||
1173 std::is_same_v<T,float> ||
1174 std::is_same_v<T,double>,int> = 0>
1175 void getarrWithParser (const char* name, int nvals, std::vector<T>& ref) const
1176 {
1177 int exist = this->queryarrWithParser(name, nvals, ref);
1178 if (!exist) {
1179 amrex::Error(std::string("ParmParse::getarrWithParser: failed to get ")+name);
1180 }
1181 }
1182
1183 /*
1184 * \brief Evaluate given string as math expression
1185 *
1186 * For unknown symbols, ParmParse database will be queried.
1187 */
1188 template <typename T, std::enable_if_t<std::is_same_v<T,int> ||
1189 std::is_same_v<T,long> ||
1190 std::is_same_v<T,long long> ||
1191 std::is_same_v<T,float> ||
1192 std::is_same_v<T,double>,int> = 0>
1193 T eval (std::string const& expr) const
1194 {
1195 if constexpr (std::is_integral_v<T>) {
1196 auto const parser = this->makeIParser(expr, {});
1197 auto const exe = parser.compileHost<0>();
1198 return static_cast<T>(exe()); // In the future, we might add safety check.
1199 } else {
1200 auto const parser = this->makeParser(expr, {});
1201 auto const exe = parser.compileHost<0>();
1202 return static_cast<T>(exe());
1203 }
1204 }
1205
1206 /*
1207 * \brief Query two names.
1208 *
1209 * This function queries with `new_name` first. If it's not found, it
1210 * will try again with `old_name`.
1211 */
1212 template <typename T>
1213 int query (const char* new_name, const char* old_name, T& ref)
1214 {
1215 return (this->query(new_name, ref) ||
1216 this->query(old_name, ref));
1217 }
1218
1226 template <typename T>
1227 void get (const char* new_name, const char* old_name, T& ref)
1228 {
1229 auto exist = this->query(new_name, old_name, ref);
1230 if (!exist) {
1231 amrex::ErrorStream() << "ParmParse::get failed to find "
1232 << new_name << " and " << old_name << '\n';
1234 amrex::Abort();
1235 }
1236 }
1237
1246 template <typename T, typename ET = amrex_enum_traits<T>,
1247 std::enable_if_t<ET::value,int> = 0>
1248 int query (const char* name, T& ref, int ival = FIRST) const
1249 {
1250 std::string s;
1251 int exist = this->query(name, s, ival);
1252 if (exist) {
1253 try {
1254 ref = amrex::getEnum<T>(s);
1255 } catch (...) {
1256 if (amrex::Verbose() > 0 ) {
1257 amrex::Print() << "amrex::ParmParse::query (input name: "
1258 << this->prefixedName(name) << "):\n";
1259 }
1260 throw;
1261 }
1262 }
1263 return exist;
1264 }
1265
1274 template <typename T, typename ET = amrex_enum_traits<T>,
1275 std::enable_if_t<ET::value,int> = 0>
1276 void get (const char* name, T& ref, int ival = FIRST) const
1277 {
1278 std::string s;
1279 this->get(name, s, ival);
1280 try {
1281 ref = amrex::getEnum<T>(s);
1282 } catch (...) {
1283 if (amrex::Verbose() > 0 ) {
1284 amrex::Print() << "amrex::ParmParse::get (input name: "
1285 << this->prefixedName(name) << "):\n";
1286 }
1287 throw;
1288 }
1289 }
1290
1292 template <typename T, typename ET = amrex_enum_traits<T>,
1293 std::enable_if_t<ET::value,int> = 0>
1294 int queryarr (const char* name,
1295 std::vector<T>& ref,
1296 int start_ix = FIRST,
1297 int num_val = ALL) const
1298 {
1299 std::vector<std::string> s;
1300 int exist = this->queryarr(name, s, start_ix, num_val);
1301 if (exist) {
1302 ref.resize(s.size());
1303 for (std::size_t i = 0; i < s.size(); ++i) {
1304 try {
1305 ref[i] = amrex::getEnum<T>(s[i]);
1306 } catch (...) {
1307 if (amrex::Verbose() > 0 ) {
1308 amrex::Print() << "amrex::ParmParse::queryarr (input name: "
1309 << this->prefixedName(name) << "):\n";
1310 }
1311 throw;
1312 }
1313 }
1314 }
1315 return exist;
1316 }
1317
1319 template <typename T, typename ET = amrex_enum_traits<T>,
1320 std::enable_if_t<ET::value,int> = 0>
1321 void getarr (const char* name,
1322 std::vector<T>& ref,
1323 int start_ix = FIRST,
1324 int num_val = ALL) const
1325 {
1326 std::vector<std::string> s;
1327 this->getarr(name, s, start_ix, num_val);
1328 ref.resize(s.size());
1329 for (std::size_t i = 0; i < s.size(); ++i) {
1330 try {
1331 ref[i] = amrex::getEnum<T>(s[i]);
1332 } catch (...) {
1333 if (amrex::Verbose() > 0 ) {
1334 amrex::Print() << "amrex::ParmParse::getarr (input name: "
1335 << this->prefixedName(name) << "):\n";
1336 }
1337 throw;
1338 }
1339 }
1340 }
1341
1352 template <typename T, typename ET = amrex_enum_traits<T>,
1353 std::enable_if_t<ET::value,int> = 0>
1354 int query_enum_case_insensitive (const char* name, T& ref, int ival = FIRST) const
1355 {
1356 std::string s;
1357 int exist = this->query(name, s, ival);
1358 if (exist) {
1359 try {
1360 ref = amrex::getEnumCaseInsensitive<T>(s);
1361 } catch (...) {
1362 if (amrex::Verbose() > 0) {
1363 amrex::Print() << "amrex::ParmParse::query_enum_case_insensitive (input name: "
1364 << this->prefixedName(name) << "):\n";
1365 }
1366 throw;
1367 }
1368 }
1369 return exist;
1370 }
1371
1382 template <typename T, typename ET = amrex_enum_traits<T>,
1383 std::enable_if_t<ET::value,int> = 0>
1384 void get_enum_case_insensitive (const char* name, T& ref, int ival = FIRST) const
1385 {
1386 int exist = this->query_enum_case_insensitive(name, ref, ival);
1387 if (!exist) {
1388 std::string msg("get_enum_case_insensitive(\"");
1389 msg.append(name).append("\",").append(amrex::getEnumClassName<T>())
1390 .append("&) failed.");
1391 amrex::Abort(msg);
1392 }
1393 }
1394
1407 template <typename T, typename ET = amrex_enum_traits<T>,
1408 std::enable_if_t<ET::value,int> = 0>
1409 int query_enum_sloppy (const char* name, T& ref, std::string_view const& ignores,
1410 int ival = FIRST) const
1411 {
1412 std::string s;
1413 int exist = this->query(name, s, ival);
1414 if (exist) {
1415 try {
1416 s.erase(std::remove_if(s.begin(), s.end(),
1417 [&] (auto const& c) {
1418 return ignores.find(c) != std::string_view::npos; }),
1419 s.end());
1420 ref = amrex::getEnumCaseInsensitive<T>(s);
1421 } catch (...) {
1422 if (amrex::Verbose() > 0) {
1423 amrex::Print() << "amrex::ParmParse::query_enum_sloppy (input name: "
1424 << this->prefixedName(name) << "):\n";
1425 }
1426 throw;
1427 }
1428 }
1429 return exist;
1430 }
1431
1444 template <typename T, typename ET = amrex_enum_traits<T>,
1445 std::enable_if_t<ET::value,int> = 0>
1446 void get_enum_sloppy (const char* name, T& ref, std::string_view const& ignores,
1447 int ival = FIRST) const
1448 {
1449 int exist = this->query_enum_sloppy(name, ref, ignores, ival);
1450 if (!exist) {
1451 std::string msg("get_enum_sloppy(\"");
1452 msg.append(name).append("\",").append(amrex::getEnumClassName<T>())
1453 .append("&) failed.");
1454 amrex::Abort(msg);
1455 }
1456 }
1457
1466 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1467 int queryAsDouble (const char* name, T& ref) const
1468 {
1469 using value_type = ppdetail::underlying_type_t<T>;
1470 double dref;
1471 int exist = queryWithParser(name, dref);
1472 if (exist) {
1473 if (std::is_integral_v<value_type>) {
1474 dref = std::round(dref);
1475 }
1476 auto vref = static_cast<value_type>(dref);
1477 if constexpr (std::is_integral_v<value_type> && !std::is_same_v<value_type,bool>) {
1478 if (static_cast<double>(vref) != dref) {
1479 amrex::Abort("ParmParse:: queryAsDouble is not safe");
1480 }
1481 }
1482 ref = vref;
1483 }
1484 return exist;
1485 }
1486
1495 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1496 int queryarrAsDouble (const char* name, int nvals, T* ref) const
1497 {
1498 using value_type = ppdetail::underlying_type_t<T>;
1499 std::vector<double> dref(nvals);
1500 int exist = queryarrWithParser(name, nvals, dref.data());
1501 if (exist) {
1502 for (int i = 0; i < nvals; ++i) {
1503 if (std::is_integral_v<value_type>) {
1504 dref[i] = std::round(dref[i]);
1505 }
1506 auto vref = static_cast<value_type>(dref[i]);
1507 if constexpr (std::is_integral_v<value_type> && !std::is_same_v<value_type,bool>) {
1508 if (static_cast<double>(vref) != dref[i]) {
1509 amrex::Abort("ParmParse:: queryarrAsDouble is not safe");
1510 }
1511 }
1512 ref[i] = vref;
1513 }
1514 }
1515 return exist;
1516 }
1517
1526 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1527 void getAsDouble (const char* name, T& ref) const
1528 {
1529 int exist = this->queryAsDouble(name, ref);
1530 if (!exist) {
1531 amrex::Error(std::string("ParmParse::getAsDouble: failed to get ")+name);
1532 }
1533 }
1534
1543 template <typename T, std::enable_if_t<ppdetail::IsArithmeticOptional_v<T>, int> = 0>
1544 void getarrAsDouble (const char* name, int nvals, T* ref) const
1545 {
1546 int exist = this->queryarrAsDouble(name, nvals, ref);
1547 if (!exist) {
1548 amrex::Error(std::string("ParmParse::getarrAsDouble: failed to get ")+name);
1549 }
1550 }
1551
1553 int remove (const char* name);
1554
1558 [[nodiscard]] Parser makeParser (std::string const& func,
1559 Vector<std::string> const& vars) const;
1560
1564 [[nodiscard]] IParser makeIParser (std::string const& func,
1565 Vector<std::string> const& vars) const;
1566
1574 static void Initialize (int argc, char** argv, const char* parfile);
1579 static void Finalize ();
1580
1582 static void SetParserPrefix (std::string a_prefix);
1583
1584 static int Verbose ();
1585 static void SetVerbose (int v);
1586
1588 static void dumpTable (std::ostream& os, bool prettyPrint = false);
1589
1592 static void prettyPrintTable (std::ostream& os);
1593
1595 static void addfile (std::string const& filename);
1596
1597 static bool QueryUnusedInputs ();
1598
1600 [[nodiscard]] static bool hasUnusedInputs (const std::string& prefix = std::string());
1601
1603 [[nodiscard]] static std::vector<std::string> getUnusedInputs (const std::string& prefix = std::string());
1604
1606 [[nodiscard]] static std::set<std::string> getEntries (const std::string& prefix = std::string());
1607
1608 struct PP_entry {
1609 // There can be multiple occurrences for a given name (e.g.,
1610 // multiple lines starting with `foo =` in inputs. For each
1611 // occurrence, there can be multiple values. Thus, the use of
1612 // vector<vector<std::string>>.
1613 std::vector<std::vector<std::string>> m_vals;
1614 mutable Long m_count = 0;
1615 };
1616 using Table = std::unordered_map<std::string, PP_entry>;
1617
1618 [[nodiscard]] const Table& table() const {return *m_table;}
1619
1621 static std::string const FileKeyword;
1622
1623 static std::string ParserPrefix;
1624
1625 [[nodiscard]] std::string prefixedName (const std::string_view& str) const;
1626
1627protected:
1628
1629 std::string m_prefix; // Prefix used in keyword search
1630 std::string m_parser_prefix; // Prefix used by Parser
1632};
1633
1634}
1635
1636#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:320
bool contains(const char *name) const
Returns true if name is in table.
Definition AMReX_ParmParse.cpp:1916
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:2010
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:1120
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:1175
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:1384
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:1293
void get(const char *name, std::array< T, N > &ref) const
Definition AMReX_ParmParse.H:964
static void prettyPrintTable(std::ostream &os)
Definition AMReX_ParmParse.cpp:1246
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:1088
int queryarrWithParser(const char *name, int nvals, std::vector< T > &ref) const
Definition AMReX_ParmParse.H:1099
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:1063
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:1467
int query(const char *name, T &ref, int ival=FIRST) const
. Query enum value using given name.
Definition AMReX_ParmParse.H:1248
static std::string const FileKeyword
keyword for files to load
Definition AMReX_ParmParse.H:1621
static std::string ParserPrefix
Definition AMReX_ParmParse.H:1623
static int Verbose()
Definition AMReX_ParmParse.cpp:1169
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:1527
static void SetVerbose(int v)
Definition AMReX_ParmParse.cpp:1182
void get(const char *new_name, const char *old_name, T &ref)
Get using two names.
Definition AMReX_ParmParse.H:1227
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:1377
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:1409
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:993
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:1038
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:1363
static bool hasUnusedInputs(const std::string &prefix=std::string())
Any unused [prefix.]* parameters?
Definition AMReX_ParmParse.cpp:1120
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:1139
int remove(const char *name)
Remove given name from the table.
Definition AMReX_ParmParse.cpp:1932
Parser makeParser(std::string const &func, Vector< std::string > const &vars) const
Definition AMReX_ParmParse.cpp:2040
int query(const char *name, std::array< T, N > &ref) const
Definition AMReX_ParmParse.H:974
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:1284
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:1544
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:1370
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:1019
static bool QueryUnusedInputs()
Definition AMReX_ParmParse.cpp:1105
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:1318
T eval(std::string const &expr) const
Definition AMReX_ParmParse.H:1193
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:1356
static void Finalize()
The destructor. The internal static table will only be deleted if there are no other ParmParse object...
Definition AMReX_ParmParse.cpp:1188
std::string m_prefix
Definition AMReX_ParmParse.H:1629
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:1900
const Table & table() const
Definition AMReX_ParmParse.H:1618
std::string prefixedName(const std::string_view &str) const
Definition AMReX_ParmParse.cpp:1049
static void SetParserPrefix(std::string a_prefix)
Set prefix used by math expression Parser.
Definition AMReX_ParmParse.cpp:1215
static std::vector< std::string > getUnusedInputs(const std::string &prefix=std::string())
Returns unused [prefix.]* parameters.
Definition AMReX_ParmParse.cpp:1126
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:1310
@ FIRST
Definition AMReX_ParmParse.H:322
@ LAST
Definition AMReX_ParmParse.H:322
@ ALL
Definition AMReX_ParmParse.H:322
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:1294
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:1980
int query(const char *new_name, const char *old_name, T &ref)
Definition AMReX_ParmParse.H:1213
void get_enum_case_insensitive(const char *name, T &ref, int ival=FIRST) const
. Get enum value using given name.
Definition AMReX_ParmParse.H:1384
Table * m_table
Definition AMReX_ParmParse.H:1631
std::string m_parser_prefix
Definition AMReX_ParmParse.H:1630
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:1272
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:1301
int queryAdd(const char *name, std::string &ref)
Definition AMReX_ParmParse.H:1001
static void dumpTable(std::ostream &os, bool prettyPrint=false)
Write the contents of the table in ASCII to the ostream.
Definition AMReX_ParmParse.cpp:1221
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:1496
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:1157
void get(const char *name, T &ref, int ival=FIRST) const
. Get enum value using given name.
Definition AMReX_ParmParse.H:1276
static std::set< std::string > getEntries(const std::string &prefix=std::string())
Returns [prefix.]* parameters.
Definition AMReX_ParmParse.cpp:1156
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:1321
int query_enum_case_insensitive(const char *name, T &ref, int ival=FIRST) const
. Query enum value using given name.
Definition AMReX_ParmParse.H:1354
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:1446
std::unordered_map< std::string, PP_entry > Table
Definition AMReX_ParmParse.H:1616
IParser makeIParser(std::string const &func, Vector< std::string > const &vars) const
Definition AMReX_ParmParse.cpp:2047
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:1053
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:54
constexpr bool IsArithmeticOptional_v
Definition AMReX_ParmParse.H:51
Definition AMReX_Amr.cpp:49
std::ostream & ErrorStream()
Definition AMReX.cpp:878
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:219
int Verbose() noexcept
Definition AMReX.cpp:164
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:225
Definition AMReX_ParmParse.H:1608
std::vector< std::vector< std::string > > m_vals
Definition AMReX_ParmParse.H:1613
Long m_count
Definition AMReX_ParmParse.H:1614
Definition AMReX_ParmParse.H:33