103#include <source_location>
108#include <type_traits>
116#include "AMReX_ParmParse.H"
119#define pp_query_required(...) pp.query_required(__VA_ARGS__)
120#define pp_query_default(...) pp.query_default(__VA_ARGS__)
121#define pp_query_validate(...) pp.query_validate(__VA_ARGS__)
122#define pp_query_switch(...) pp.query_switch(__VA_ARGS__)
123#define pp_query_if(...) pp.query_if(__VA_ARGS__)
124#define pp_query_if_else(...) pp.query_if_else(__VA_ARGS__)
125#define pp_query_file(...) pp.query_file(__VA_ARGS__)
126#define pp_queryarr(...) pp.queryarr(__VA_ARGS__)
127#define pp_queryarr_required(...) pp.queryarr_required(__VA_ARGS__)
128#define pp_queryarr_default(...) pp.queryarr_default(__VA_ARGS__)
129#define pp_query(...) pp.query(__VA_ARGS__)
130#define pp_queryclass(...) pp.queryclass(__VA_ARGS__)
131#define pp_forbid(...) pp.forbid(__VA_ARGS__)
140 template<
typename... Args>
148 template<
typename Arg>
150 std::is_lvalue_reference_v<Arg>, Arg, std::remove_cvref_t<Arg>>;
152 template<
typename... Args>
164 std::string inputfile =
"";
165 while (this->querykth(
"input",k,inputfile))
168 this->addfile(inputfile);
175 std::string directive,
176 const std::source_location &location,
177 std::vector<std::string> options = {},
178 std::optional<std::string> default_value = std::nullopt,
179 bool has_unnamed_default =
false);
182 std::vector<std::string> members,
183 std::vector<std::string> units,
184 const std::source_location &location);
188 const std::source_location &location,
189 std::vector<std::string> options = {},
190 std::optional<std::string> default_value = std::nullopt,
191 bool has_unnamed_default =
false,
192 const std::source_location &handler_location = std::source_location::current())
196 std::move(options), std::move(default_value),
197 has_unnamed_default);
201 template<
typename T,
typename... Args>
205 [&](
auto &...constructor_args) -> T *
207 return new T(constructor_args..., pp, name);
212 template<
typename T,
typename =
void>
216 struct HasSelectName<T, std::void_t<decltype(T::name)>> : std::true_type {};
218 template<
typename T,
typename... Args>
220 std::is_constructible_v<T, std::add_lvalue_reference_t<Args>...,
223 template<
typename T,
typename... Args>
227 [&](
auto &...constructor_args) -> T *
229 static_assert( std::is_constructible_v<T,
decltype(constructor_args)...>,
230 "The unnamed select default cannot be constructed from forward_args");
231 return new T(constructor_args...);
236 template<
typename T,
typename... Args>
240 names.emplace_back(T::name);
243 template<
typename T,
typename... Args,
typename PTRTYPE>
252 value = ConstructSelected<T>(args, pp, name +
"." + std::string(T::name));
270 std::string note =
"This input parser is not yet compliant with traversal mode; its inputs are not fully documented.",
271 const std::source_location &location = std::source_location::current());
277 const std::source_location & location = std::source_location::current())
280 (void)amrex::ParmParse::contains(name.c_str());
285 if (m_prefix.length())
286 m_prefix = m_prefix +
"." +
prefix;
293 size_t pos = m_prefix.rfind(
'.');
294 if (pos == std::string::npos)
297 m_prefix = m_prefix.substr(0, pos);
301 void forbid(std::string name, std::string explanation,
302 const std::source_location & location = std::source_location::current())
305 if (amrex::ParmParse::contains(
full(name).c_str()))
310 std::set<std::string> subs = amrex::ParmParse::getEntries(
full(name));
319 const std::source_location & location = std::source_location::current())
322 if (amrex::ParmParse::contains(name.c_str()))
324 if (amrex::ParmParse::contains(
full(name).c_str()))
327 std::set<std::string> subs = amrex::ParmParse::getEntries(name.c_str());
332 std::set<std::string> subs = amrex::ParmParse::getEntries(
full(name).c_str());
340 int query( std::string name, T & value,
341 const std::source_location & location = std::source_location::current())
343 if constexpr (std::is_same_v<std::remove_cv_t<T>,
bool>)
348 return amrex::ParmParse::query(name.c_str(), value);
352 const std::source_location & location = std::source_location::current())
358 std::string strvalue;
359 int retval = amrex::ParmParse::query(name.c_str(),strvalue);
363 catch (std::runtime_error & e)
377 const std::source_location & location = std::source_location::current())
383 int retval =
queryunit(name,value, location);
401 const std::source_location & location = std::source_location::current())
408 int retval =
queryunit(name,read,type, location);
412 catch (std::runtime_error &e)
422 const std::source_location & location = std::source_location::current())
424 if constexpr (std::is_same_v<std::remove_cv_t<T>,
bool>)
430 if (!
contains(name.c_str()))
return 0;
431 return amrex::ParmParse::query(name.c_str(), value);
440 return query(name.c_str(),value);
442 catch (std::runtime_error & e)
457 const std::source_location & location = std::source_location::current())
462 if (!
contains(name.c_str()))
return 0;
463 std::string strvalue;
464 int retval = amrex::ParmParse::query(name.c_str(), strvalue);
476 return queryunit(name.c_str(), value, type, location);
478 catch (std::runtime_error & e)
493 const std::source_location & location = std::source_location::current())
495 if constexpr (std::is_same_v<std::remove_cv_t<T>,
bool>)
504 return amrex::ParmParse::query(name.c_str(), value);
505 value = defaultvalue;
512 add(name.c_str(),defaultvalue);
514 return query(name.c_str(),value);
516 catch (std::runtime_error & e)
531 const std::source_location & location = std::source_location::current())
538 std::string strvalue;
539 int retval = amrex::ParmParse::query(name.c_str(), strvalue);
552 add(name.c_str(),defaultvalue);
554 return queryunit(name.c_str(),value,type, location);
556 catch (std::runtime_error & e)
569 int query_validate( std::string name,
int & value, std::vector<int> possibleintvals,
570 const std::source_location & location = std::source_location::current())
572 std::vector<std::string> options;
573 for (
const auto &possibleval : possibleintvals)
574 options.push_back(std::to_string(possibleval));
579 return amrex::ParmParse::query(name.c_str(), value);
580 value = possibleintvals[0];
591 add(name.c_str(), possibleintvals[0]);
595 int retval =
query(name.c_str(),value);
599 for (
unsigned int i = 0; i < possibleintvals.size(); i++)
601 if (value == possibleintvals[i]) ok =
true;
604 if (ok)
return retval;
606 std::stringstream ss;
607 ss << possibleintvals[0];
608 for (
unsigned int i = 1; i < possibleintvals.size(); i++)
609 ss <<
"," << possibleintvals[i];
614 catch (std::runtime_error & e)
628 int query_validate( std::string name, std::string & value, std::vector<const char *> possiblecharvals,
bool firstbydefault,
629 const std::source_location &location = std::source_location::current())
631 std::vector<std::string> options;
632 for (
const auto &possibleval : possiblecharvals)
633 options.push_back(std::string(possibleval));
638 return amrex::ParmParse::query(name.c_str(), value);
639 value = std::string(possiblecharvals[0]);
648 if (!amrex::ParmParse::contains(name.c_str()))
656 if (!amrex::ParmParse::contains(name.c_str()))
658 add(name.c_str(), std::string(possiblecharvals[0]));
662 int retval = amrex::ParmParse::query(name.c_str(),value);
666 for (
unsigned int i = 0; i < possiblecharvals.size(); i++)
668 if (value == std::string(possiblecharvals[i])) ok =
true;
671 if (ok)
return retval;
673 std::stringstream ss;
674 ss << possiblecharvals[0];
675 for (
unsigned int i = 1; i < possiblecharvals.size(); i++)
676 ss <<
"," << possiblecharvals[i];
680 catch (std::runtime_error & e)
694 int query_validate( std::string name, std::string & value, std::vector<const char *> possiblecharvals,
695 const std::source_location &location = std::source_location::current())
699 return query_validate(name,value,possiblecharvals,
true, location);
701 catch (std::runtime_error & e)
715 std::initializer_list<std::pair<std::string, std::function<
void()>>> cases,
716 const std::source_location &location = std::source_location::current())
719 std::vector<std::string> possiblevals;
720 possiblevals.reserve(cases.size());
721 for (
const auto &entry : cases)
722 possiblevals.push_back(entry.first);
727 auto set_switch_value = [&](
const std::string &switch_value)
729 this->remove(name.c_str());
730 this->add(name.c_str(), switch_value);
733 auto print_switch_branch = [&](
const std::string &switch_value)
738 auto run_case = [&](
const std::string &switch_value,
auto &&action)
740 set_switch_value(switch_value);
741 print_switch_branch(switch_value);
748 std::string original_value;
749 bool had_original_value = amrex::ParmParse::contains(name.c_str());
750 if (had_original_value)
751 amrex::ParmParse::query(name.c_str(), original_value);
753 for (
const auto &entry : cases)
754 run_case(entry.first, entry.second);
756 if (had_original_value)
757 set_switch_value(original_value);
759 this->remove(name.c_str());
766 if (!amrex::ParmParse::contains(name.c_str()))
768 add(name.c_str(), possiblevals[0]);
771 retval = amrex::ParmParse::query(name.c_str(),value);
774 for (
const auto & possibleval : possiblevals)
776 if (value == possibleval) ok =
true;
781 std::stringstream ss;
782 ss << possiblevals[0];
783 for (
unsigned int i = 1; i < possiblevals.size(); i++)
784 ss <<
"," << possiblevals[i];
789 catch (std::runtime_error & e)
798 bool matched =
false;
799 for (
const auto &entry : cases)
801 if (!matched && value == entry.first)
816 template <
typename Action>
818 const std::source_location &location = std::source_location::current())
820 static_assert( std::is_invocable_v<Action &>,
821 "query_if action must be callable without arguments");
825 auto set_value = [&](
const std::string &value)
827 this->remove(name.c_str());
828 this->add(name.c_str(), value);
833 std::string original_value;
834 bool had_original_value = amrex::ParmParse::contains(name.c_str());
835 if (had_original_value)
836 amrex::ParmParse::query(name.c_str(), original_value);
845 if (had_original_value)
846 set_value(original_value);
848 this->remove(name.c_str());
853 int retval = amrex::ParmParse::query(name.c_str(), enabled);
854 if (retval && enabled != 0 && enabled != 1)
861 template <
typename TrueAction,
typename FalseAction>
863 TrueAction &&true_action,
864 FalseAction &&false_action,
865 const std::source_location &location = std::source_location::current())
867 static_assert( std::is_invocable_v<TrueAction &>,
868 "query_if_else true action must be callable without arguments");
869 static_assert( std::is_invocable_v<FalseAction &>,
870 "query_if_else false action must be callable without arguments");
874 auto set_value = [&](
const std::string &value)
876 this->remove(name.c_str());
877 this->add(name.c_str(), value);
880 auto run_action = [&](
const std::string &value,
auto &&action)
890 std::string original_value;
891 bool had_original_value = amrex::ParmParse::contains(name.c_str());
892 if (had_original_value)
893 amrex::ParmParse::query(name.c_str(), original_value);
895 run_action(
"0", false_action);
896 run_action(
"1", true_action);
898 if (had_original_value)
899 set_value(original_value);
901 this->remove(name.c_str());
906 int retval = amrex::ParmParse::query(name.c_str(), enabled);
907 if (retval && enabled != 0 && enabled != 1)
917 int query_default( std::string name, std::string & value,
const char *defaultvalue,
918 const std::source_location &location = std::source_location::current())
922 return query_default(name, value, std::string(defaultvalue), location);
924 catch (std::runtime_error & e)
938 const std::source_location &location = std::source_location::current())
943 if (defaultvalue) defaultint = 1;
946 catch (std::runtime_error & e)
961 int query_file( std::string name, std::string & value,
bool copyfile,
bool checkfile,
962 const std::source_location &location = std::source_location::current())
967 if (!
contains(name.c_str()))
return 0;
968 return amrex::ParmParse::query(name.c_str(), value);
978 int retval =
query(name.c_str(),value);
980 if (
ShouldExecute() && amrex::ParallelDescriptor::IOProcessor())
982 if ( checkfile && ! std::filesystem::exists(value))
987 if ( checkfile && !std::filesystem::is_regular_file(value))
1000 catch (std::runtime_error & e)
1012 int query_file( std::string name, std::string & value,
bool copyfile,
1013 const std::source_location & location = std::source_location::current())
1015 return query_file(name,value,copyfile,
true, location);
1017 int query_file( std::string name, std::string & value,std::source_location loc = std::source_location::current())
1019 return query_file(name,value,
true,
true, loc);
1023 template<
typename T>
1024 int queryarr( std::string name, std::vector<T> & value,
1025 const std::source_location &location = std::source_location::current())
1031 return amrex::ParmParse::queryarr(name.c_str(), value);
1037 return amrex::ParmParse::queryarr(name.c_str(),value);
1047 const std::source_location &location = std::source_location::current())
1055 return amrex::ParmParse::queryarr(name.c_str(), value);
1058 std::vector<std::string> valstrings;
1059 int retval = amrex::ParmParse::queryarr(name.c_str(), valstrings);
1060 for (
unsigned int i = 0; i < valstrings.size(); i++)
1074 return amrex::ParmParse::queryarr(name.c_str(),value);
1079 std::vector<std::string> valstrings;
1080 int retval = amrex::ParmParse::queryarr(name.c_str(), valstrings);
1081 for (
unsigned int i = 0; i < valstrings.size(); i++)
1095 catch (std::runtime_error &e)
1108 const std::source_location &location = std::source_location::current())
1115 std::vector<Set::Scalar> vals;
1117 amrex::ParmParse::queryarr(name.c_str(), vals);
1120 std::vector<std::string> valstrings;
1121 amrex::ParmParse::queryarr(name.c_str(), valstrings);
1122 for (
unsigned int i = 0; i < valstrings.size(); i++)
1128 value = Set::Vector::Zero();
1129 for (
int i = 0; i < AMREX_SPACEDIM && i < static_cast<int>(vals.size()); i++)
1133 value = Set::Vector::Zero();
1138 std::vector<Set::Scalar> vals;
1139 queryarr(name.c_str(), vals, unit);
1140 if (vals.size() < AMREX_SPACEDIM)
1144 " requires at least ", AMREX_SPACEDIM,
1145 " arguments, got ",vals.size());
1147 for (
int i = 0; i < AMREX_SPACEDIM; i++) value(i) = vals[i];
1158 const std::source_location &location = std::source_location::current())
1165 std::vector<Set::Scalar> vals;
1167 amrex::ParmParse::queryarr(name.c_str(), vals);
1170 std::vector<std::string> valstrings;
1171 amrex::ParmParse::queryarr(name.c_str(), valstrings);
1172 for (
unsigned int i = 0; i < valstrings.size(); i++)
1178 value = Set::Matrix::Zero();
1179 for (
int i = 0; i < AMREX_SPACEDIM * AMREX_SPACEDIM && i < static_cast<int>(vals.size()); i++)
1180 value.data()[i] = vals[i];
1183 value = Set::Matrix::Zero();
1186 std::vector<Set::Scalar> vals;
1188 if (vals.size() == 9)
1190#if AMREX_SPACEDIM==2
1191 Util::Warning(
INFO,
"Reading a 3D matrix (",
full(name),
")into a 2D code - some values will be ignored.");
1192 value(0,0) = vals[0]; value(0,1)= vals[1];
1193 value(1,0) = vals[3]; value(1,1)= vals[4];
1195#if AMREX_SPACEDIM==3
1196 value(0,0) = vals[0]; value(0,1)= vals[1]; value(0,2)= vals[2];
1197 value(1,0) = vals[3]; value(1,1)= vals[4]; value(1,2)= vals[5];
1198 value(2,0) = vals[6]; value(2,1)= vals[7]; value(2,2)= vals[8];
1201 else if (vals.size() == 4)
1203#if AMREX_SPACEDIM==2
1204 value(0,0) = vals[0]; value(0,1)= vals[1];
1205 value(1,0) = vals[2]; value(1,1)= vals[3];
1207#if AMREX_SPACEDIM==3
1208 Util::Warning(
INFO,
"Reading a 2D matrix (",
full(name),
")into a 3D code - remaining values will be set to zero.");
1209 value(0,0) = vals[0]; value(0,1)= vals[1]; value(0,2)= 0.0;
1210 value(1,0) = vals[2]; value(1,1)= vals[3]; value(1,2)= 0.0;
1211 value(2,0) = 0.0; value(2,1)= 0.0; value(2,2)= 0.0;
1222 template<
typename T>
1224 const std::source_location &location = std::source_location::current())
1230 return amrex::ParmParse::queryarr(name.c_str(), value);
1239 return queryarr<T>(name,value);
1243 const std::source_location &location = std::source_location::current())
1251 return amrex::ParmParse::queryarr(name.c_str(), value);
1254 std::vector<std::string> valstrings;
1255 int retval = amrex::ParmParse::queryarr(name.c_str(), valstrings);
1256 for (
unsigned int i = 0; i < valstrings.size(); i++)
1274 const std::source_location &location = std::source_location::current())
1281 std::vector<Set::Scalar> vals;
1283 amrex::ParmParse::queryarr(name.c_str(), vals);
1286 std::vector<std::string> valstrings;
1287 amrex::ParmParse::queryarr(name.c_str(), valstrings);
1288 for (
const auto &valstring : valstrings)
1291 value = Set::Vector::Zero();
1292 for (
int i = 0; i < AMREX_SPACEDIM && i < static_cast<int>(vals.size()); i++)
1296 value = Set::Vector::Zero();
1303 int queryarr_default( std::string name, std::vector<std::string> & value, std::vector<std::string> defaultvalue,
1304 const std::source_location &location = std::source_location::current())
1310 return amrex::ParmParse::queryarr(name.c_str(), value);
1311 value = defaultvalue;
1316 addarr(name.c_str(),defaultvalue);
1318 return amrex::ParmParse::queryarr(name.c_str(),value);
1322 const std::source_location &location = std::source_location::current())
1329 amrex::ParmParse::queryarr(name.c_str(), data);
1331 value = Set::Vector::Zero();
1332 for (
int i = 0; i < AMREX_SPACEDIM && i < static_cast<int>(data.size()); i++)
1345 return queryarr(name.c_str(),value,unit);
1347 catch (std::runtime_error &e)
1360 const std::source_location &location = std::source_location::current())
1367 std::vector<Set::Scalar> vals;
1368 amrex::ParmParse::queryarr(name.c_str(), vals);
1369 value = Set::Vector::Zero();
1370 for (
int i = 0; i < AMREX_SPACEDIM && i < static_cast<int>(vals.size()); i++)
1374 value = defaultvalue;
1381 std::vector<Set::Scalar> def_data(AMREX_SPACEDIM);
1382 for (
unsigned int i = 0; i < def_data.size(); i++)
1383 def_data[i] = defaultvalue[i];
1386 value = defaultvalue;
1389 return queryarr(name.c_str(),value);
1400 const std::source_location &location = std::source_location::current())
1407 std::vector<Set::Scalar> vals;
1408 amrex::ParmParse::queryarr(name.c_str(), vals);
1409 value = Set::Matrix::Zero();
1410 for (
int i = 0; i < AMREX_SPACEDIM * AMREX_SPACEDIM && i < static_cast<int>(vals.size()); i++)
1411 value.data()[i] = vals[i];
1421 std::vector<Set::Scalar> def_data(AMREX_SPACEDIM*AMREX_SPACEDIM);
1422 for (
unsigned int i = 0; i < def_data.size(); i++)
1423 def_data[i] = def.data()[i];
1429 return queryarr(name.c_str(),value);
1439 int queryarr_default( std::string name, std::vector<double> & value, std::vector<double> defaultvalue,
1440 const std::source_location &location = std::source_location::current())
1446 return amrex::ParmParse::queryarr(name.c_str(), value);
1447 value = defaultvalue;
1454 addarr(name.c_str(),defaultvalue);
1456 return queryarr(name.c_str(),value);
1466 int queryarr_default( std::string name, std::vector<double> & value, std::vector<std::string> defaultvalue,
Unit unit,
1467 const std::source_location &location = std::source_location::current())
1472 std::vector<std::string> data = defaultvalue;
1474 amrex::ParmParse::queryarr(name.c_str(), data);
1477 for (
const auto &entry : data)
1488 addarr(name.c_str(),defaultvalue);
1501 template <
typename T>
1504 const std::source_location &location = std::source_location::current())
1512 const std::string template_name = a_name +
"0";
1514 this->queryclass<T>(template_name, tmp);
1523 std::string name = a_name;
1526 for (
int n = 0; n < number; n++)
1529 this->queryclass<T>(name, tmp);
1530 value.push_back(tmp);
1543 std::string name0 = a_name + std::to_string(0);
1544 std::string name1 = a_name + std::to_string(1);
1550 else if (this->
contains(name1.c_str()))
1565 for (
int cntr = start; this->
contains(name.c_str()); cntr++)
1570 this->queryclass<T>(name, tmp);
1571 value.push_back(tmp);
1573 name = a_name + std::to_string(cntr+1);
1580 template <
typename T>
1583 const std::source_location &location = std::source_location::current())
1594 std::string name = a_name;
1597 for (
int n = 0; n < number; n++)
1601 value.push_back(tmp);
1614 std::string name0 = a_name + std::to_string(0);
1615 std::string name1 = a_name + std::to_string(1);
1621 else if (this->
contains(name1.c_str()))
1636 for (
int cntr = start; this->
contains(name.c_str()); cntr++)
1642 value.push_back(tmp);
1644 name = a_name + std::to_string(cntr+1);
1650 template <
typename T>
1653 const std::source_location &location = std::source_location::current())
1658 std::string name = a_name;
1661 for (
int n = 0; n < number; n++)
1665 value.push_back(std::move(tmp));
1671 std::string name0 = a_name + std::to_string(0);
1672 std::string name1 = a_name + std::to_string(1);
1678 else if (this->
contains(name1.c_str()))
1689 for (
int cntr = start; this->
contains(name.c_str()); cntr++)
1693 value.push_back(std::move(tmp));
1694 name = a_name + std::to_string(cntr+1);
1705 for (
auto li = m_table->begin(), End = m_table->end(); li != End; ++li)
1707 if (!li->second.m_count)
1711 if (li->first.rfind(
getPrefix()+
".",0) != std::string::npos)
1729 std::vector<std::string> ret;
1730 for (
auto li = m_table->begin(), End = m_table->end(); li != End; ++li)
1732 if (!li->second.m_count && li->first.rfind(
getPrefix()+
".",0) != std::string::npos)
1734 ret.push_back(li->first);
1744 for (
auto li = pp.m_table->begin(), End = pp.m_table->end(); li != End; ++li)
1746 if (!li->second.m_count)
1758 std::string
full (std::string name)
1768 const std::source_location &location = std::source_location::current())
1773 auto old_prefix = m_prefix;
1776 if (old_prefix.empty()) m_prefix = name;
1777 else m_prefix.append(
".").append(name);
1778 T::Parse(*value, *
this);
1780 if (unused_inputs.size())
1782 std::stringstream ss;
1783 for (
unsigned int i=0; i < unused_inputs.size(); i++)
1784 ss <<
"\n\t" << unused_inputs[i];
1791 m_prefix = old_prefix;
1795 m_prefix = old_prefix;
1799 const std::source_location &location = std::source_location::current())
1804 auto old_prefix = m_prefix;
1807 if (old_prefix.empty()) m_prefix = name;
1808 else m_prefix.append(
".").append(name);
1809 T::Parse(value, *
this);
1811 if (unused_inputs.size())
1813 std::stringstream ss;
1814 for (
unsigned int i=0; i < unused_inputs.size(); i++)
1815 ss <<
"\n\t" << unused_inputs[i];
1820 catch (std::runtime_error &e)
1826 m_prefix = old_prefix;
1830 m_prefix = old_prefix;
1835 const std::source_location &location = std::source_location::current())
1840 T::Parse(*value, *
this);
1842 catch (std::runtime_error &e)
1855 const std::source_location &location = std::source_location::current())
1860 T::Parse(value, *
this);
1862 catch (std::runtime_error &e)
1882 template<
typename...
IC,
typename PTRTYPE>
1883 void select ( std::string name, PTRTYPE *& ic_eta,
1884 const std::source_location &location = std::source_location::current())
1887 select<
IC...>(std::move(name), ic_eta, args, location);
1890 template<
typename...
IC,
typename... Args,
typename PTRTYPE>
1892 const std::source_location &location = std::source_location::current())
1896 std::string type_name = name +
".type";
1897 std::vector<std::string> possiblevals = {std::string(IC::name)...};
1905 std::string original_type;
1906 bool had_original_type = this->
contains(type_name.c_str());
1907 if (had_original_type)
1908 amrex::ParmParse::query(type_name.c_str(), original_type);
1910 auto set_select_value = [&](
const std::string &select_value)
1912 this->remove(type_name.c_str());
1913 this->add(type_name.c_str(), select_value);
1916 auto restore_select_value = [&]()
1918 this->remove(type_name.c_str());
1919 if (had_original_type)
1920 this->add(type_name.c_str(), original_type);
1923 auto traverse_one = [&]<
typename T>()
1925 std::string select_value = T::name;
1926 set_select_value(select_value);
1929 PTRTYPE *tmp = ConstructSelected<T>(args, *
this, name +
"." + select_value);
1933 (traverse_one.template operator()<
IC>(), ...);
1934 restore_select_value();
1941 if constexpr (
sizeof...(IC) == 0)
1943 using first_IC = std::tuple_element_t<0, std::tuple<
IC...>>;
1944 ic_eta = ConstructSelected<first_IC>(args, *
this, name +
"." + std::string(first_IC::name));
1949 std::string type =
"";
1951 bool matched = (( type == IC::name
1952 ? (ic_eta = ConstructSelected<IC>(args, *
this, name +
"." + std::string(IC::name))),
1960 catch (std::runtime_error &e)
1977 template<
typename FirstIC,
typename...
IC,
typename PTRTYPE>
1979 const std::source_location &location = std::source_location::current())
1985 template<
typename FirstIC,
typename...
IC,
typename... Args,
typename PTRTYPE>
1987 const std::source_location &location = std::source_location::current())
1989 std::string type =
"";
1990 std::string type_name = name +
".type";
1991 constexpr bool has_unnamed_default =
1994 std::vector<std::string> possiblevals;
1995 AppendSelectName<FirstIC>(possiblevals, args);
1996 (AppendSelectName<IC>(possiblevals, args), ...);
2002 std::nullopt, has_unnamed_default);
2005 std::string original_type;
2006 bool had_original_type = this->
contains(type_name.c_str());
2007 if (had_original_type)
2008 amrex::ParmParse::query(type_name.c_str(), original_type);
2010 auto set_select_value = [&](
const std::string &select_value)
2012 this->remove(type_name.c_str());
2013 this->add(type_name.c_str(), select_value);
2016 auto restore_select_value = [&]()
2018 this->remove(type_name.c_str());
2019 if (had_original_type)
2020 this->add(type_name.c_str(), original_type);
2023 auto traverse_one = [&]<
typename T>()
2027 std::string select_value = T::name;
2028 set_select_value(select_value);
2031 PTRTYPE *tmp = ConstructSelected<T>(args, *
this, name +
"." + select_value);
2036 traverse_one.template operator()<FirstIC>();
2037 (traverse_one.template operator()<
IC>(), ...);
2038 restore_select_value();
2046 this->
query_default(type_name, type, std::string(FirstIC::name));
2050 if (!this->
contains(type_name.c_str()))
2052 ic_eta = ConstructSelectDefault<FirstIC>(args);
2058 bool matched = TrySelectNamed<FirstIC>(type, name, ic_eta, args, *
this);
2059 matched = matched || (TrySelectNamed<IC>(type, name, ic_eta, args, *
this) || ...);
2068 template<
typename...
IC,
typename PTRTYPE>
2070 const std::source_location &location = std::source_location::current())
2076 template<
typename...
IC,
typename... Args,
typename PTRTYPE>
2078 const std::source_location &location = std::source_location::current())
2085 PTRTYPE *tmp =
nullptr;
2086 const std::string template_name = a_name +
"0";
2087 this->
select<
IC...>(template_name, tmp, args, location);
2096 std::string name = a_name;
2100 this->
select<
IC...>(a_name, tmp, args, location);
2101 value.push_back(tmp);
2113 std::string name0 = a_name + std::to_string(0);
2114 std::string name1 = a_name + std::to_string(1);
2120 else if (this->
contains(name1.c_str()))
2135 for (
int cntr = start; this->
contains(name.c_str()); cntr++)
2140 this->
select<
IC...>(name, tmp, args, location);
2141 value.push_back(tmp);
2143 name = a_name + std::to_string(cntr+1);
2152 template<
typename... INTEGRATOR,
typename... Args,
typename PTRTYPE>
2155 std::string type =
"";
2159 bool matched = ((type == INTEGRATOR::name
2160 ? (ic_eta =
new INTEGRATOR(std::forward<Args>(args)..., (*
this))),
2174 template<
typename INTEGRATOR,
typename Args,
typename PTRTYPE>
2177 ic_eta =
new INTEGRATOR(std::forward<Args>(args), (*
this));
2180 template<
typename INTEGRATOR,
typename PTRTYPE>
2183 ic_eta =
new INTEGRATOR((*
this));
2192 template <
typename... OBJ,
typename CLASS>
2193 requires (!std::is_pointer_v<std::remove_reference_t<CLASS>>)
2195 const std::source_location &location = std::source_location::current())
2197#if !AMREX_DEVICE_COMPILE
2199 select<OBJ...>(std::move(name), value, args, location);
2205 template <
typename... OBJ,
typename CLASS,
typename... Args>
2206 requires (!std::is_pointer_v<std::remove_reference_t<CLASS>>)
2208 const std::source_location &location = std::source_location::current())
2210#if !AMREX_DEVICE_COMPILE
2214 std::vector<std::string> possiblevals = {std::string(OBJ::name)...};
2219 std::string original_type;
2220 bool had_original_type = this->
contains(
"type");
2221 if (had_original_type)
2222 amrex::ParmParse::query(
"type", original_type);
2223 int original_selected = value.selected;
2227 this->remove(
"type");
2228 if (had_original_type)
2229 this->add(
"type", original_type);
2230 value.selected = original_selected;
2251 template <
typename CLASS,
int N,
typename... OBJ,
typename... Args>
2254 if constexpr (N <
sizeof...(OBJ))
2256 std::string type = value.names[N];
2257 this->remove(
"type");
2258 this->add(
"type", type);
2266 [&](
auto &...parse_args)
2268 std::get<N>(value.obj).Parse(
2269 std::get<N>(value.obj), *
this, parse_args...);
2280 template <
typename CLASS,
int N,
typename... OBJ,
typename... Args>
2283 if constexpr (N == 0)
2288 for (
unsigned int i = 0; i <
sizeof...(OBJ); i++)
2289 if (type == value.names[i])
2292 if (value.selected < 0)
2296 ", invalid type " + type);
2302 if constexpr (N <
sizeof...(OBJ))
2304 if (value.selected == N)
2307 [&](
auto &...parse_args)
2309 std::get<N>(value.obj).Parse(
2310 std::get<N>(value.obj), *
this, parse_args...);
2326 void query_exactly( std::vector<std::string> names, std::pair<std::string, Set::Scalar> values[N],
2327 std::vector<Unit> units = std::vector<Unit>(),
2328 const std::source_location &location = std::source_location::current())
2330 for (
const auto &name : names)
2332 std::vector<std::string> unit_names;
2333 for (
const auto &unit : units)
2340 for (
unsigned int n = 0; n < names.size() && cnt < N; n++)
2342 if (!
contains(names[n].c_str()))
continue;
2344 values[cnt].first = names[n];
2345 if (units.size() == 0)
2346 amrex::ParmParse::query(names[n].c_str(), values[cnt].second);
2349 std::string strvalue;
2350 amrex::ParmParse::query(names[n].c_str(), strvalue);
2356 for (
unsigned int n = 0; n < names.size() && cnt < N; n++)
2358 if (
contains(names[n].c_str()))
continue;
2360 values[cnt].first = names[n];
2361 values[cnt].second = 1.0;
2370 "# of units must be 0, 1, or ", names.size(),
" but got ", units.size());
2373 std::vector<std::string> read;
2374 for (
unsigned int n = 0; n < names.size(); n++)
2376 if (amrex::ParmParse::contains(names[n].c_str()))
2378 read.push_back(names[n]);
2383 " Incorrect number of values specified: only ", N,
2384 " values are allowed, but received ",
2389 for (
unsigned int n = 0; n < names.size(); n++)
2391 if (amrex::ParmParse::contains(names[n].c_str()))
2393 values[cnt].first = names[n];
2395 if (units.size() == 0)
2397 else if (units.size() == 1)
2407 std::string names_str =
"[";
2408 for (
unsigned int i = 0; i < names.size(); i++)
2410 names_str +=
full(names[i]);
2411 if (i < names.size()-1) names_str +=
", ";
void select_default(std::string name, PTRTYPE *&ic_eta, const std::source_location &location=std::source_location::current())
int queryarr_required(std::string name, Set::Vector &value, Unit unit=Unit::Less(), const std::source_location &location=std::source_location::current())
void RecordInputAndContinue(std::string name, const std::source_location &location, std::vector< std::string > options={}, std::optional< std::string > default_value=std::nullopt, bool has_unnamed_default=false, const std::source_location &handler_location=std::source_location::current())
void queryclass(std::string name, T *value, const std::source_location &location=std::source_location::current())
static constexpr bool HasSelectedConstructor
void forbid(std::string name, std::string explanation, const std::source_location &location=std::source_location::current())
int query_if_else(std::string name, TrueAction &&true_action, FalseAction &&false_action, const std::source_location &location=std::source_location::current())
static void SetTraversalMode(bool enabled)
int queryarr_default(std::string name, std::vector< double > &value, std::vector< double > defaultvalue, const std::source_location &location=std::source_location::current())
void select(std::string name, PTRTYPE *&ic_eta, ForwardArgs< Args... > args, const std::source_location &location=std::source_location::current())
int queryarr(std::string name, Set::Matrix &value, Unit unit=Unit::Less(), const std::source_location &location=std::source_location::current())
int query_validate(std::string name, int &value, std::vector< int > possibleintvals, const std::source_location &location=std::source_location::current())
int queryclass_enumerate(std::string a_name, std::vector< T > &value, int number=1, const std::source_location &location=std::source_location::current())
void ignore(std::string name, const std::source_location &location=std::source_location::current())
int queryarr_required(std::string name, std::vector< T > &value, const std::source_location &location=std::source_location::current())
int queryarr(std::string name, std::vector< T > &value, const std::source_location &location=std::source_location::current())
int query(std::string name, T &value, const std::source_location &location=std::source_location::current())
int query_file(std::string name, std::string &value, bool copyfile, const std::source_location &location=std::source_location::current())
void pushPrefix(const std::string prefix)
int query_default(std::string name, std::string &value, const char *defaultvalue, const std::source_location &location=std::source_location::current())
static const InputNode & InputTree()
void PrintTraversalBranch(std::string name, const std::string &value)
int queryarr_default(std::string name, std::vector< double > &value, std::vector< std::string > defaultvalue, Unit unit, const std::source_location &location=std::source_location::current())
int query_validate(std::string name, std::string &value, std::vector< const char * > possiblecharvals, bool firstbydefault, const std::source_location &location=std::source_location::current())
int AnyUnusedInputs(bool inscopeonly=true, bool verbose=false)
void query_exactly(std::vector< std::string > names, std::pair< std::string, Set::Scalar > values[N], std::vector< Unit > units=std::vector< Unit >(), const std::source_location &location=std::source_location::current())
void select(std::string name, CLASS &value, ForwardArgs< Args... > args, const std::source_location &location=std::source_location::current())
int queryarr_default(std::string name, Set::Vector &value, Set::Vector defaultvalue, const std::source_location &location=std::source_location::current())
int queryarr(std::string name, Set::Vector &value, Unit unit=Unit::Less(), const std::source_location &location=std::source_location::current())
int queryarr_required(std::string name, std::vector< Set::Scalar > &value, Unit unit=Unit::Less(), const std::source_location &location=std::source_location::current())
std::vector< std::string > GetUnusedInputs()
int query_required(std::string name, T &value, const Unit type, const std::source_location &location=std::source_location::current())
int query_default(std::string name, int &value, bool defaultvalue, const std::source_location &location=std::source_location::current())
static void SetTraversalOutputFile(std::string path)
static void AppendSelectName(std::vector< std::string > &names, ForwardArgs< Args... > &)
void queryclass(T *value, const std::source_location &location=std::source_location::current())
std::string getPrefix() const
static bool checked_for_input_files
void RecordInput(std::string name, std::string directive, const std::source_location &location, std::vector< std::string > options={}, std::optional< std::string > default_value=std::nullopt, bool has_unnamed_default=false)
void queryclass(std::string name, T &value, const std::source_location &location=std::source_location::current())
static ForwardArgs< ForwardArgStorage< Args >... > forward_args(Args &&... args)
int query_default(std::string name, T &value, T defaultvalue, const std::source_location &location=std::source_location::current())
void select_enumerate(std::string a_name, std::vector< PTRTYPE * > &value, const std::source_location &location=std::source_location::current())
int queryunit(std::string name, Unit &value, const std::source_location &location=std::source_location::current())
int queryunit(std::string name, Set::Scalar &value, const Unit type, const std::source_location &location=std::source_location::current())
int query_file(std::string name, std::string &value, bool copyfile, bool checkfile, const std::source_location &location=std::source_location::current())
void static_polymorphism_parser(CLASS &value, ForwardArgs< Args... > &args)
int query_switch(std::string name, std::initializer_list< std::pair< std::string, std::function< void()> > > cases, const std::source_location &location=std::source_location::current())
static const std::string & TraversalOutputFile()
std::conditional_t< std::is_lvalue_reference_v< Arg >, Arg, std::remove_cvref_t< Arg > > ForwardArgStorage
int queryarr_default(std::string name, Set::Vector &value, std::string defaultvalue, Unit unit, const std::source_location &location=std::source_location::current())
int query_enumerate(std::string a_name, std::vector< T > &value, int number=1, const std::source_location &location=std::source_location::current())
int queryarr_enumerate(std::string a_name, std::vector< std::vector< T > > &value, int number=1, const std::source_location &location=std::source_location::current())
int query_default(std::string name, T &value, std::string defaultvalue, const Unit type, const std::source_location &location=std::source_location::current())
int query_file(std::string name, std::string &value, std::source_location loc=std::source_location::current())
static void WriteInputTreeJsonFile(const std::string &path)
static int AllUnusedInputs()
InputScraper::InputNode InputNode
static T * ConstructSelectDefault(ForwardArgs< Args... > &args)
int queryarr(std::string name, std::vector< Set::Scalar > &value, Unit unit=Unit::Less(), const std::source_location &location=std::source_location::current())
static bool InTraversalMode()
int query_validate(std::string name, std::string &value, std::vector< const char * > possiblecharvals, const std::source_location &location=std::source_location::current())
void select_enumerate(std::string a_name, std::vector< PTRTYPE * > &value, ForwardArgs< Args... > args, const std::source_location &location=std::source_location::current())
void select_default(std::string name, PTRTYPE *&ic_eta, ForwardArgs< Args... > args, const std::source_location &location=std::source_location::current())
int queryarr_default(std::string name, std::vector< std::string > &value, std::vector< std::string > defaultvalue, const std::source_location &location=std::source_location::current())
static bool ShouldExecute()
bool contains(std::string name, const std::source_location &location=std::source_location::current())
static void ClearInputTree()
void select_only(PTRTYPE *&ic_eta, Args &&args)
void select_main(PTRTYPE *&ic_eta, Args &&... args)
void queryclass(T &value, const std::source_location &location=std::source_location::current())
int queryarr_default(std::string name, Set::Matrix &value, Set::Matrix def, const std::source_location &location=std::source_location::current())
int query_required(std::string name, T &value, const std::source_location &location=std::source_location::current())
void select_only(PTRTYPE *&ic_eta)
void RecordConstraint(std::string kind, int count, std::vector< std::string > members, std::vector< std::string > units, const std::source_location &location)
std::string full(std::string name)
int query_if(std::string name, Action &&action, const std::source_location &location=std::source_location::current())
static bool IgnoreInTraversalMode(std::string note="This input parser is not yet compliant with traversal mode; its inputs are not fully documented.", const std::source_location &location=std::source_location::current())
int queryunit(std::string name, Unit &value, const Unit type, const std::source_location &location=std::source_location::current())
void static_polymorphism_traverser(CLASS &value, ForwardArgs< Args... > &args)
static bool TrySelectNamed(const std::string &type, const std::string &name, PTRTYPE *&value, ForwardArgs< Args... > &args, ParmParse &pp)
void select(std::string name, CLASS &value, const std::source_location &location=std::source_location::current())
static void WriteInputTreeJson(std::ostream &os)
static T * ConstructSelected(ForwardArgs< Args... > &args, ParmParse &pp, const std::string &name)
void select(std::string name, PTRTYPE *&ic_eta, const std::source_location &location=std::source_location::current())
ParmParse(std::string arg)
Initialize a spherical inclusion.
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, AMREX_SPACEDIM > Matrix
AMREX_FORCE_INLINE std::string Join(const std::vector< std::string > &vec, std::string separator="_")
AMREX_FORCE_INLINE std::vector< std::string > Split(std::string &str, const char delim=' ')
void DebugMessage(std::string, std::string, int, Args const &...)
AMREX_FORCE_INLINE void AssertException(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void IgnoreUnused(const Ts &...)
void CopyFileToOutputDir(std::string a_path, bool fullpath, std::string prefix)
void Warning(std::string file, std::string func, int line, Args const &... args)
void Message(std::string file, std::string func, int line, Args const &... args)
AMREX_GPU_HOST_DEVICE void Abort(const char *msg)
void ParmParseException(std::string file, std::string func, int line, std::string fullname, Args const &... args)
void Exception(std::string file, std::string func, int line, Args const &... args)
std::tuple< Args... > values
ForwardArgs(Args... args)
bool isType(const Unit &test) const
std::string normalized_unitstring() const
static Unit Parse(double val, std::string unitstring, bool verbose=false)
double normalized_value() const