From 2bdab9e5184787a53c22be3187fe06be19776cf3 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 13:13:55 +0200 Subject: [PATCH 01/26] parametersystem: pass add callback for adding keys to positional parameter handler this way the backing store for the parameters can be an implementation detail of the parameter system --- opm/models/discretization/common/fvbaseproblem.hh | 5 ++++- opm/models/utils/parametersystem.hh | 11 ++++++++--- opm/simulators/flow/FlowGenericProblem.hpp | 3 ++- opm/simulators/flow/FlowGenericProblem_impl.hpp | 4 ++-- opm/simulators/flow/FlowProblem.hpp | 6 ++++-- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/opm/models/discretization/common/fvbaseproblem.hh b/opm/models/discretization/common/fvbaseproblem.hh index 76701c007..98ab65703 100644 --- a/opm/models/discretization/common/fvbaseproblem.hh +++ b/opm/models/discretization/common/fvbaseproblem.hh @@ -37,6 +37,7 @@ #include +#include #include #include #include @@ -268,7 +269,9 @@ public: * the next regular parameter. If this is less than 1, it indicated that the * positional parameter was invalid. */ - static int handlePositionalParameter(std::set&, + static int handlePositionalParameter(std::function, + std::set&, std::string& errorMsg, int, const char** argv, diff --git a/opm/models/utils/parametersystem.hh b/opm/models/utils/parametersystem.hh index b5366884a..8457eb8cd 100644 --- a/opm/models/utils/parametersystem.hh +++ b/opm/models/utils/parametersystem.hh @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -449,7 +450,8 @@ inline void printUsage(const std::string& helpPreamble, } /// \cond 0 -inline int noPositionalParameters_(std::set&, +inline int noPositionalParameters_(std::function, + std::set&, std::string& errorMsg, int, const char** argv, @@ -613,8 +615,11 @@ std::string parseCommandLineOptions(int argc, || argv[i][1] != '-') { std::string errorMsg; - int numHandled = posArgCallback(seenKeys, errorMsg, argc, argv, - i, numPositionalParams); + int numHandled = posArgCallback([](const std::string& k, const std::string& v) + { + MetaData::tree()[k] = v; + }, seenKeys, errorMsg, + argc, argv, i, numPositionalParams); if (numHandled < 1) { std::ostringstream oss; diff --git a/opm/simulators/flow/FlowGenericProblem.hpp b/opm/simulators/flow/FlowGenericProblem.hpp index 2531cd6b2..5d3be7bbd 100644 --- a/opm/simulators/flow/FlowGenericProblem.hpp +++ b/opm/simulators/flow/FlowGenericProblem.hpp @@ -52,7 +52,8 @@ class EclipseState; class Schedule; template class LookUpData; -int eclPositionalParameter(Dune::ParameterTree& tree, +int eclPositionalParameter(std::function addKey, std::set& seenParams, std::string& errorMsg, const char** argv, diff --git a/opm/simulators/flow/FlowGenericProblem_impl.hpp b/opm/simulators/flow/FlowGenericProblem_impl.hpp index 7c0fa2ed1..6c5f6b9b6 100644 --- a/opm/simulators/flow/FlowGenericProblem_impl.hpp +++ b/opm/simulators/flow/FlowGenericProblem_impl.hpp @@ -45,7 +45,7 @@ namespace Opm { -int eclPositionalParameter(Dune::ParameterTree& tree, +int eclPositionalParameter(std::function addKey, std::set& seenParams, std::string& errorMsg, const char** argv, @@ -73,7 +73,7 @@ int eclPositionalParameter(Dune::ParameterTree& tree, return 0; } - tree["EclDeckFileName"] = argv[paramIdx]; + addKey("EclDeckFileName", argv[paramIdx]); seenParams.insert("EclDeckFileName"); return 1; } diff --git a/opm/simulators/flow/FlowProblem.hpp b/opm/simulators/flow/FlowProblem.hpp index e64120946..a7125da59 100644 --- a/opm/simulators/flow/FlowProblem.hpp +++ b/opm/simulators/flow/FlowProblem.hpp @@ -228,14 +228,16 @@ public: /*! * \copydoc FvBaseProblem::handlePositionalParameter */ - static int handlePositionalParameter(std::set& seenParams, + static int handlePositionalParameter(std::function addKey, + std::set& seenParams, std::string& errorMsg, int, const char** argv, int paramIdx, int) { - return eclPositionalParameter(Parameters::MetaData::tree(), + return eclPositionalParameter(addKey, seenParams, errorMsg, argv, From 05f01bf8195dc5e4824a8708d4ea8371bb80e37b Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 12:56:18 +0200 Subject: [PATCH 02/26] parametersystem.hh: rename to .hpp --- CMakeLists_files.cmake | 2 +- flowexperimental/flowexp_blackoil.cpp | 2 +- opm/models/common/multiphasebaseextensivequantities.hh | 2 +- opm/models/discretization/common/fvbasefdlocallinearizer.hh | 2 +- opm/models/discretization/common/fvbaselocalresidual.hh | 2 +- opm/models/io/baseoutputmodule.hh | 2 +- opm/models/io/basevanguard.hh | 2 +- opm/models/io/cubegridvanguard.hh | 2 +- opm/models/io/dgfvanguard.hh | 2 +- opm/models/io/structuredgridvanguard.hh | 2 +- opm/models/io/vtkblackoilenergymodule.hh | 2 +- opm/models/io/vtkblackoilmicpmodule.hh | 2 +- opm/models/io/vtkblackoilmodule.hh | 2 +- opm/models/io/vtkblackoilpolymermodule.hh | 2 +- opm/models/io/vtkblackoilsolventmodule.hh | 2 +- opm/models/io/vtkcompositionmodule.hh | 2 +- opm/models/io/vtkdiffusionmodule.hh | 2 +- opm/models/io/vtkdiscretefracturemodule.hh | 2 +- opm/models/io/vtkenergymodule.hh | 2 +- opm/models/io/vtkmultiphasemodule.hh | 2 +- opm/models/io/vtkphasepresencemodule.hh | 2 +- opm/models/io/vtkprimaryvarsmodule.hh | 2 +- opm/models/io/vtkptflashmodule.hh | 2 +- opm/models/io/vtktemperaturemodule.hh | 2 +- opm/models/parallel/threadmanager.cpp | 2 +- opm/models/utils/basicproperties.hh | 2 +- .../utils/{parametersystem.hh => parametersystem.hpp} | 6 +++--- opm/models/utils/simulator.hh | 2 +- opm/models/utils/start.hh | 2 +- opm/simulators/flow/BlackoilModelParameters.cpp | 2 +- opm/simulators/flow/DamarisParameters.cpp | 2 +- opm/simulators/flow/FlowBaseVanguard.hpp | 2 +- opm/simulators/flow/FlowGenericVanguard.cpp | 2 +- opm/simulators/flow/FlowProblemParameters.cpp | 2 +- opm/simulators/flow/FlowUtils.cpp | 2 +- opm/simulators/flow/Main.hpp | 2 +- opm/simulators/flow/NonlinearSolver.hpp | 2 +- opm/simulators/flow/OutputBlackoilModule.hpp | 2 +- opm/simulators/flow/VtkTracerModule.hpp | 2 +- opm/simulators/flow/python/PyBlackOilSimulator.hpp | 3 ++- opm/simulators/linalg/FlowLinearSolverParameters.cpp | 2 +- opm/simulators/linalg/ISTLSolver.hpp | 2 +- opm/simulators/linalg/istlpreconditionerwrappers.hh | 2 +- opm/simulators/linalg/istlsolverwrappers.hh | 2 +- opm/simulators/linalg/parallelbasebackend.hh | 2 +- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 2 +- opm/simulators/timestepping/EclTimeSteppingParams.cpp | 2 +- opm/simulators/utils/DamarisKeywords.hpp | 2 +- opm/simulators/wells/GasLiftSingleWell.hpp | 2 +- tests/test_glift1.cpp | 2 +- tests/test_parametersystem.cpp | 2 +- 51 files changed, 54 insertions(+), 53 deletions(-) rename opm/models/utils/{parametersystem.hh => parametersystem.hpp} (99%) diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 09148a4dc..2907241f7 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -711,7 +711,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/models/utils/basicparameters.hh opm/models/utils/basicproperties.hh opm/models/utils/genericguard.hh - opm/models/utils/parametersystem.hh + opm/models/utils/parametersystem.hpp opm/models/utils/pffgridvector.hh opm/models/utils/prefetch.hh opm/models/utils/propertysystem.hh diff --git a/flowexperimental/flowexp_blackoil.cpp b/flowexperimental/flowexp_blackoil.cpp index 8f9025b96..36bbc09b6 100644 --- a/flowexperimental/flowexp_blackoil.cpp +++ b/flowexperimental/flowexp_blackoil.cpp @@ -21,7 +21,7 @@ #include "flowexp.hpp" #include -#include +#include #include #include diff --git a/opm/models/common/multiphasebaseextensivequantities.hh b/opm/models/common/multiphasebaseextensivequantities.hh index fde81bb93..b372cd129 100644 --- a/opm/models/common/multiphasebaseextensivequantities.hh +++ b/opm/models/common/multiphasebaseextensivequantities.hh @@ -32,7 +32,7 @@ #include #include -#include +#include #include diff --git a/opm/models/discretization/common/fvbasefdlocallinearizer.hh b/opm/models/discretization/common/fvbasefdlocallinearizer.hh index ab4765079..8cad8e726 100644 --- a/opm/models/discretization/common/fvbasefdlocallinearizer.hh +++ b/opm/models/discretization/common/fvbasefdlocallinearizer.hh @@ -29,7 +29,7 @@ #define EWOMS_FV_BASE_FD_LOCAL_LINEARIZER_HH #include -#include +#include #include #include diff --git a/opm/models/discretization/common/fvbaselocalresidual.hh b/opm/models/discretization/common/fvbaselocalresidual.hh index e8c4d0716..ae21de310 100644 --- a/opm/models/discretization/common/fvbaselocalresidual.hh +++ b/opm/models/discretization/common/fvbaselocalresidual.hh @@ -30,7 +30,7 @@ #include "fvbaseproperties.hh" -#include +#include #include #include diff --git a/opm/models/io/baseoutputmodule.hh b/opm/models/io/baseoutputmodule.hh index 99d0c1789..0966b302a 100644 --- a/opm/models/io/baseoutputmodule.hh +++ b/opm/models/io/baseoutputmodule.hh @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include diff --git a/opm/models/io/basevanguard.hh b/opm/models/io/basevanguard.hh index 57cc7c959..d232be028 100644 --- a/opm/models/io/basevanguard.hh +++ b/opm/models/io/basevanguard.hh @@ -28,7 +28,7 @@ #define EWOMS_BASE_VANGUARD_HH #include -#include +#include #include diff --git a/opm/models/io/cubegridvanguard.hh b/opm/models/io/cubegridvanguard.hh index 7e4ca8c53..a60c214a8 100644 --- a/opm/models/io/cubegridvanguard.hh +++ b/opm/models/io/cubegridvanguard.hh @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include diff --git a/opm/models/io/dgfvanguard.hh b/opm/models/io/dgfvanguard.hh index 2a84e0373..b91726bdd 100644 --- a/opm/models/io/dgfvanguard.hh +++ b/opm/models/io/dgfvanguard.hh @@ -33,7 +33,7 @@ #include #include -#include +#include #include diff --git a/opm/models/io/structuredgridvanguard.hh b/opm/models/io/structuredgridvanguard.hh index 1c7be289c..519493b67 100644 --- a/opm/models/io/structuredgridvanguard.hh +++ b/opm/models/io/structuredgridvanguard.hh @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include diff --git a/opm/models/io/vtkblackoilenergymodule.hh b/opm/models/io/vtkblackoilenergymodule.hh index e782fdbcf..1fcfb516a 100644 --- a/opm/models/io/vtkblackoilenergymodule.hh +++ b/opm/models/io/vtkblackoilenergymodule.hh @@ -38,7 +38,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkblackoilmicpmodule.hh b/opm/models/io/vtkblackoilmicpmodule.hh index cf626b8ed..95723b440 100644 --- a/opm/models/io/vtkblackoilmicpmodule.hh +++ b/opm/models/io/vtkblackoilmicpmodule.hh @@ -38,7 +38,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkblackoilmodule.hh b/opm/models/io/vtkblackoilmodule.hh index 4b0de723d..30b8127ad 100644 --- a/opm/models/io/vtkblackoilmodule.hh +++ b/opm/models/io/vtkblackoilmodule.hh @@ -38,7 +38,7 @@ #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkblackoilpolymermodule.hh b/opm/models/io/vtkblackoilpolymermodule.hh index eb7f7f23d..0f012069b 100644 --- a/opm/models/io/vtkblackoilpolymermodule.hh +++ b/opm/models/io/vtkblackoilpolymermodule.hh @@ -38,7 +38,7 @@ #include #include -#include +#include #include namespace Opm::Properties::TTag { diff --git a/opm/models/io/vtkblackoilsolventmodule.hh b/opm/models/io/vtkblackoilsolventmodule.hh index acb47519a..3dda896e9 100644 --- a/opm/models/io/vtkblackoilsolventmodule.hh +++ b/opm/models/io/vtkblackoilsolventmodule.hh @@ -38,7 +38,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkcompositionmodule.hh b/opm/models/io/vtkcompositionmodule.hh index bc16cf15c..984add073 100644 --- a/opm/models/io/vtkcompositionmodule.hh +++ b/opm/models/io/vtkcompositionmodule.hh @@ -34,7 +34,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkdiffusionmodule.hh b/opm/models/io/vtkdiffusionmodule.hh index 13bf3912f..f8f12a403 100644 --- a/opm/models/io/vtkdiffusionmodule.hh +++ b/opm/models/io/vtkdiffusionmodule.hh @@ -37,7 +37,7 @@ #include #include -#include +#include namespace Opm::Parameters { diff --git a/opm/models/io/vtkdiscretefracturemodule.hh b/opm/models/io/vtkdiscretefracturemodule.hh index 49904a5e9..14251282f 100644 --- a/opm/models/io/vtkdiscretefracturemodule.hh +++ b/opm/models/io/vtkdiscretefracturemodule.hh @@ -37,7 +37,7 @@ #include #include -#include +#include #include diff --git a/opm/models/io/vtkenergymodule.hh b/opm/models/io/vtkenergymodule.hh index 414d545ce..06cc4dad4 100644 --- a/opm/models/io/vtkenergymodule.hh +++ b/opm/models/io/vtkenergymodule.hh @@ -34,7 +34,7 @@ #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkmultiphasemodule.hh b/opm/models/io/vtkmultiphasemodule.hh index b5e86b5e5..bf8e1e7a2 100644 --- a/opm/models/io/vtkmultiphasemodule.hh +++ b/opm/models/io/vtkmultiphasemodule.hh @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include diff --git a/opm/models/io/vtkphasepresencemodule.hh b/opm/models/io/vtkphasepresencemodule.hh index 225218438..c66429c4a 100644 --- a/opm/models/io/vtkphasepresencemodule.hh +++ b/opm/models/io/vtkphasepresencemodule.hh @@ -32,7 +32,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkprimaryvarsmodule.hh b/opm/models/io/vtkprimaryvarsmodule.hh index 8cbd9aae5..5bbbcdc3b 100644 --- a/opm/models/io/vtkprimaryvarsmodule.hh +++ b/opm/models/io/vtkprimaryvarsmodule.hh @@ -32,7 +32,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtkptflashmodule.hh b/opm/models/io/vtkptflashmodule.hh index cb25f1e0d..a7509f8de 100644 --- a/opm/models/io/vtkptflashmodule.hh +++ b/opm/models/io/vtkptflashmodule.hh @@ -34,7 +34,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/io/vtktemperaturemodule.hh b/opm/models/io/vtktemperaturemodule.hh index 96f25c9f0..0cdd62c27 100644 --- a/opm/models/io/vtktemperaturemodule.hh +++ b/opm/models/io/vtktemperaturemodule.hh @@ -34,7 +34,7 @@ #include #include -#include +#include #include namespace Opm::Parameters { diff --git a/opm/models/parallel/threadmanager.cpp b/opm/models/parallel/threadmanager.cpp index f9a77afd2..ea85c4089 100644 --- a/opm/models/parallel/threadmanager.cpp +++ b/opm/models/parallel/threadmanager.cpp @@ -28,7 +28,7 @@ #endif #include -#include +#include namespace Opm { diff --git a/opm/models/utils/basicproperties.hh b/opm/models/utils/basicproperties.hh index 9d751ba9c..2dc15221f 100644 --- a/opm/models/utils/basicproperties.hh +++ b/opm/models/utils/basicproperties.hh @@ -31,7 +31,7 @@ #include #include -#include +#include #include #if HAVE_DUNE_FEM diff --git a/opm/models/utils/parametersystem.hh b/opm/models/utils/parametersystem.hpp similarity index 99% rename from opm/models/utils/parametersystem.hh rename to opm/models/utils/parametersystem.hpp index 8457eb8cd..7e489b6da 100644 --- a/opm/models/utils/parametersystem.hh +++ b/opm/models/utils/parametersystem.hpp @@ -29,8 +29,8 @@ * Dune::ParameterTree with the default value taken from the parameter * definition. */ -#ifndef OPM_PARAMETER_SYSTEM_HH -#define OPM_PARAMETER_SYSTEM_HH +#ifndef OPM_PARAMETER_SYSTEM_HPP +#define OPM_PARAMETER_SYSTEM_HPP #if HAVE_QUAD #include @@ -1074,4 +1074,4 @@ inline void endRegistration() } // namespace Opm::Parameters -#endif // OPM_PARAMETER_SYSTEM_HH +#endif // OPM_PARAMETER_SYSTEM_HPP diff --git a/opm/models/utils/simulator.hh b/opm/models/utils/simulator.hh index 80341db08..93b31ffc8 100644 --- a/opm/models/utils/simulator.hh +++ b/opm/models/utils/simulator.hh @@ -29,7 +29,7 @@ #define EWOMS_SIMULATOR_HH #include -#include +#include #include #include diff --git a/opm/models/utils/start.hh b/opm/models/utils/start.hh index 76ce1def9..8f20314d9 100644 --- a/opm/models/utils/start.hh +++ b/opm/models/utils/start.hh @@ -32,7 +32,7 @@ // dune/common/densematrix.hh because of some c++ ideosyncrasies #include -#include "parametersystem.hh" +#include #include #include diff --git a/opm/simulators/flow/BlackoilModelParameters.cpp b/opm/simulators/flow/BlackoilModelParameters.cpp index e15343d5f..23eae8231 100644 --- a/opm/simulators/flow/BlackoilModelParameters.cpp +++ b/opm/simulators/flow/BlackoilModelParameters.cpp @@ -22,7 +22,7 @@ #include -#include +#include #include #include diff --git a/opm/simulators/flow/DamarisParameters.cpp b/opm/simulators/flow/DamarisParameters.cpp index 22a78d8a0..194217e89 100644 --- a/opm/simulators/flow/DamarisParameters.cpp +++ b/opm/simulators/flow/DamarisParameters.cpp @@ -28,7 +28,7 @@ #include -#include +#include namespace Opm { diff --git a/opm/simulators/flow/FlowBaseVanguard.hpp b/opm/simulators/flow/FlowBaseVanguard.hpp index 361dce241..a0930ba66 100644 --- a/opm/simulators/flow/FlowBaseVanguard.hpp +++ b/opm/simulators/flow/FlowBaseVanguard.hpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/opm/simulators/flow/FlowGenericVanguard.cpp b/opm/simulators/flow/FlowGenericVanguard.cpp index b8acd2026..f80346de1 100644 --- a/opm/simulators/flow/FlowGenericVanguard.cpp +++ b/opm/simulators/flow/FlowGenericVanguard.cpp @@ -81,7 +81,7 @@ #include -#include +#include #include #include diff --git a/opm/simulators/flow/FlowProblemParameters.cpp b/opm/simulators/flow/FlowProblemParameters.cpp index 719b829ce..a5a11008b 100644 --- a/opm/simulators/flow/FlowProblemParameters.cpp +++ b/opm/simulators/flow/FlowProblemParameters.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include diff --git a/opm/simulators/flow/FlowUtils.cpp b/opm/simulators/flow/FlowUtils.cpp index 38a72a2bf..db63cfee4 100644 --- a/opm/simulators/flow/FlowUtils.cpp +++ b/opm/simulators/flow/FlowUtils.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/opm/simulators/flow/Main.hpp b/opm/simulators/flow/Main.hpp index ddd16f28a..014886c6b 100644 --- a/opm/simulators/flow/Main.hpp +++ b/opm/simulators/flow/Main.hpp @@ -57,7 +57,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/flow/NonlinearSolver.hpp b/opm/simulators/flow/NonlinearSolver.hpp index b59441ac9..a3235cf51 100644 --- a/opm/simulators/flow/NonlinearSolver.hpp +++ b/opm/simulators/flow/NonlinearSolver.hpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/flow/OutputBlackoilModule.hpp b/opm/simulators/flow/OutputBlackoilModule.hpp index a3956e74c..60681842a 100644 --- a/opm/simulators/flow/OutputBlackoilModule.hpp +++ b/opm/simulators/flow/OutputBlackoilModule.hpp @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/flow/VtkTracerModule.hpp b/opm/simulators/flow/VtkTracerModule.hpp index f7b9060ad..0701fbef9 100644 --- a/opm/simulators/flow/VtkTracerModule.hpp +++ b/opm/simulators/flow/VtkTracerModule.hpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/opm/simulators/flow/python/PyBlackOilSimulator.hpp b/opm/simulators/flow/python/PyBlackOilSimulator.hpp index 6d17cca59..47db13716 100644 --- a/opm/simulators/flow/python/PyBlackOilSimulator.hpp +++ b/opm/simulators/flow/python/PyBlackOilSimulator.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,6 +32,7 @@ #include namespace Opm::Pybind { + class PyBlackOilSimulator { private: diff --git a/opm/simulators/linalg/FlowLinearSolverParameters.cpp b/opm/simulators/linalg/FlowLinearSolverParameters.cpp index 00a1d183c..08c1ee245 100644 --- a/opm/simulators/linalg/FlowLinearSolverParameters.cpp +++ b/opm/simulators/linalg/FlowLinearSolverParameters.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include namespace Opm { diff --git a/opm/simulators/linalg/ISTLSolver.hpp b/opm/simulators/linalg/ISTLSolver.hpp index 80c9a73ee..85358d72c 100644 --- a/opm/simulators/linalg/ISTLSolver.hpp +++ b/opm/simulators/linalg/ISTLSolver.hpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include diff --git a/opm/simulators/linalg/istlpreconditionerwrappers.hh b/opm/simulators/linalg/istlpreconditionerwrappers.hh index 3a0a5d456..2c41a38fb 100644 --- a/opm/simulators/linalg/istlpreconditionerwrappers.hh +++ b/opm/simulators/linalg/istlpreconditionerwrappers.hh @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/linalg/istlsolverwrappers.hh b/opm/simulators/linalg/istlsolverwrappers.hh index 8d1146ad8..c9713a2f0 100644 --- a/opm/simulators/linalg/istlsolverwrappers.hh +++ b/opm/simulators/linalg/istlsolverwrappers.hh @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/linalg/parallelbasebackend.hh b/opm/simulators/linalg/parallelbasebackend.hh index b79089a84..606cfc295 100644 --- a/opm/simulators/linalg/parallelbasebackend.hh +++ b/opm/simulators/linalg/parallelbasebackend.hh @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 306971163..1fa8fe915 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/timestepping/EclTimeSteppingParams.cpp b/opm/simulators/timestepping/EclTimeSteppingParams.cpp index d675f783f..7a1e3c8db 100644 --- a/opm/simulators/timestepping/EclTimeSteppingParams.cpp +++ b/opm/simulators/timestepping/EclTimeSteppingParams.cpp @@ -25,7 +25,7 @@ #include -#include +#include namespace Opm { diff --git a/opm/simulators/utils/DamarisKeywords.hpp b/opm/simulators/utils/DamarisKeywords.hpp index 600865cee..ca6c04a95 100644 --- a/opm/simulators/utils/DamarisKeywords.hpp +++ b/opm/simulators/utils/DamarisKeywords.hpp @@ -20,7 +20,7 @@ #ifndef OPM_DAMARISKEYWORDS_HEADER_INCLUDED #define OPM_DAMARISKEYWORDS_HEADER_INCLUDED -#include +#include #include #include diff --git a/opm/simulators/wells/GasLiftSingleWell.hpp b/opm/simulators/wells/GasLiftSingleWell.hpp index 4ce75dcef..cd0d530b5 100644 --- a/opm/simulators/wells/GasLiftSingleWell.hpp +++ b/opm/simulators/wells/GasLiftSingleWell.hpp @@ -21,7 +21,7 @@ #define OPM_GASLIFT_SINGLE_WELL_HEADER_INCLUDED #include -#include +#include #include #include #include diff --git a/tests/test_glift1.cpp b/tests/test_glift1.cpp index 6e7145135..4c3a02dc8 100644 --- a/tests/test_glift1.cpp +++ b/tests/test_glift1.cpp @@ -26,7 +26,7 @@ #define BOOST_TEST_MODULE Glift1 #include -#include +#include #include #include diff --git a/tests/test_parametersystem.cpp b/tests/test_parametersystem.cpp index b4d883742..5d3c3200e 100644 --- a/tests/test_parametersystem.cpp +++ b/tests/test_parametersystem.cpp @@ -19,7 +19,7 @@ #include -#include +#include #define BOOST_TEST_MODULE ParameterSystemTest #include From bc83bb6e1cd52ecdc3e6ccf52a6d6714cf29f9dd Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 13:38:44 +0200 Subject: [PATCH 03/26] parametersystem: introduce translation unit --- CMakeLists_files.cmake | 1 + opm/models/utils/parametersystem.cpp | 538 +++++++++++++++++++++++++++ opm/models/utils/parametersystem.hpp | 527 ++------------------------ opm/models/utils/start.hh | 6 +- 4 files changed, 579 insertions(+), 493 deletions(-) create mode 100644 opm/models/utils/parametersystem.cpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 2907241f7..b7188467f 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -64,6 +64,7 @@ list (APPEND MAIN_SOURCE_FILES opm/models/parallel/mpiutil.cpp opm/models/parallel/tasklets.cpp opm/models/parallel/threadmanager.cpp + opm/models/utils/parametersystem.cpp opm/models/utils/timer.cpp opm/simulators/flow/ActionHandler.cpp opm/simulators/flow/Banners.cpp diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp new file mode 100644 index 000000000..8a0cbfc70 --- /dev/null +++ b/opm/models/utils/parametersystem.cpp @@ -0,0 +1,538 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + + Consult the COPYING file in the top-level source directory of this + module for the precise wording of the license and the list of + copyright holders. +*/ +/*! + * \file + * + * \brief This file provides the infrastructure to retrieve run-time parameters + * + * Internally, runtime parameters are implemented using + * Dune::ParameterTree with the default value taken from the parameter + * definition. + */ +#include +#include + +namespace { + +std::string parseQuotedValue(std::string& s, const std::string& errorPrefix) +{ + if (s.empty() || s[0] != '"') + throw std::runtime_error(errorPrefix+"Expected quoted string"); + + std::string result; + unsigned i = 1; + for (; i < s.size(); ++i) { + // handle escape characters + if (s[i] == '\\') { + ++ i; + if (s.size() <= i) + throw std::runtime_error(errorPrefix+"Unexpected end of quoted string"); + + if (s[i] == 'n') + result += '\n'; + else if (s[i] == 'r') + result += '\r'; + else if (s[i] == 't') + result += '\t'; + else if (s[i] == '"') + result += '"'; + else if (s[i] == '\\') + result += '\\'; + else + throw std::runtime_error(errorPrefix+"Unknown escape character '\\" + s[i] + "'"); + } + else if (s[i] == '"') + break; + else + result += s[i]; + } + + s = s.substr(i+1); + return result; +} + +std::string parseUnquotedValue(std::string& s, const std::string&) +{ + unsigned i; + for (i = 0; i < s.size(); ++ i) + if (std::isspace(s[i])) + break; + + std::string ret = s.substr(0, i); + s = s.substr(i); + return ret; +} + +void removeLeadingSpace(std::string& s) +{ + unsigned i; + for (i = 0; i < s.size(); ++ i) + if (!std::isspace(s[i])) + break; + s = s.substr(i); +} + +} // anonymous namespace + +namespace Opm::Parameters { + +bool ParamInfo::operator==(const ParamInfo& other) const +{ + return other.paramName == paramName + && other.paramTypeName == paramTypeName + && other.typeTagName == typeTagName + && other.usageString == usageString; +} + +std::string breakLines(const std::string& msg, + int indentWidth, + int maxWidth) +{ + std::string result; + int startInPos = 0; + int inPos = 0; + int lastBreakPos = 0; + int ttyPos = 0; + for (; inPos < int(msg.size()); ++ inPos, ++ ttyPos) { + if (msg[inPos] == '\n') { + result += msg.substr(startInPos, inPos - startInPos + 1); + startInPos = inPos + 1; + lastBreakPos = startInPos + 1; + + // we need to use -1 here because ttyPos is incremented after the loop body + ttyPos = -1; + continue; + } + + if (std::isspace(msg[inPos])) + lastBreakPos = inPos; + + if (ttyPos >= maxWidth) { + if (lastBreakPos > startInPos) { + result += msg.substr(startInPos, lastBreakPos - startInPos); + startInPos = lastBreakPos + 1; + lastBreakPos = startInPos; + inPos = startInPos; + } + else { + result += msg.substr(startInPos, inPos - startInPos); + startInPos = inPos; + lastBreakPos = startInPos; + inPos = startInPos; + } + + result += "\n"; + for (int i = 0; i < indentWidth; ++i) + result += " "; + ttyPos = indentWidth; + } + } + + result += msg.substr(startInPos); + + return result; +} + +void reset() +{ + MetaData::clear(); +} + +void endRegistration() +{ + if (!MetaData::registrationOpen()) { + throw std::logic_error("Parameter registration was already closed. It is only possible " + "to close it once."); + } + + MetaData::registrationOpen() = false; + + // loop over all parameters and retrieve their values to make sure + // that there is no syntax error + for (const auto& param : MetaData::registrationFinalizers()) { + param->retrieve(); + } + MetaData::registrationFinalizers().clear(); +} + +void printParamUsage(std::ostream& os, const ParamInfo& paramInfo) +{ + std::string paramMessage, paramType, paramDescription; + + int ttyWidth = getTtyWidth(); + + // convert the CamelCase name to a command line --parameter-name. + std::string cmdLineName = "-"; + const std::string camelCaseName = paramInfo.paramName; + for (unsigned i = 0; i < camelCaseName.size(); ++i) { + if (isupper(camelCaseName[i])) + cmdLineName += "-"; + cmdLineName += static_cast(std::tolower(camelCaseName[i])); + } + + // assemble the printed output + paramMessage = " "; + paramMessage += cmdLineName; + + // add the =VALUE_TYPE part + bool isString = false; + if (paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == "const char *") + { + paramMessage += "=STRING"; + isString = true; + } + else if (paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() +#if HAVE_QUAD + || paramInfo.paramTypeName == Dune::className() +#endif // HAVE_QUAD + ) + paramMessage += "=SCALAR"; + else if (paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className()) + paramMessage += "=INTEGER"; + else if (paramInfo.paramTypeName == Dune::className()) + paramMessage += "=BOOLEAN"; + else if (paramInfo.paramTypeName.empty()) { + // the parameter is a flag. Do nothing! + } + else { + // unknown type + paramMessage += "=VALUE"; + } + + // fill up the up help string to the 50th character + paramMessage += " "; + while (paramMessage.size() < 50) + paramMessage += " "; + + + // append the parameter usage string. + paramMessage += paramInfo.usageString; + + // add the default value + if (!paramInfo.paramTypeName.empty()) { + if (paramMessage.back() != '.') + paramMessage += '.'; + paramMessage += " Default: "; + if (paramInfo.paramTypeName == "bool") { + if (paramInfo.defaultValue == "0") + paramMessage += "false"; + else + paramMessage += "true"; + } + else if (isString) { + paramMessage += "\""; + paramMessage += paramInfo.defaultValue; + paramMessage += "\""; + } + else + paramMessage += paramInfo.defaultValue; + } + + paramMessage = breakLines(paramMessage, /*indent=*/52, ttyWidth); + paramMessage += "\n"; + + // print everything + os << paramMessage; +} + +void getFlattenedKeyList(std::list& dest, + const Dune::ParameterTree& tree, + const std::string& prefix) +{ + // add the keys of the current sub-structure + for (const auto& valueKey : tree.getValueKeys()) { + std::string newKey(prefix + valueKey); + dest.push_back(newKey); + } + + // recursively add all substructure keys + for (const auto& subKey : tree.getSubKeys()) { + std::string newPrefix(prefix + subKey + '.'); + getFlattenedKeyList(dest, tree.sub(subKey), newPrefix); + } +} + +// print the values of a list of parameters +void printParamList(std::ostream& os, + const std::list& keyList, + bool printDefaults) +{ + const Dune::ParameterTree& tree = MetaData::tree(); + + for (const auto& key : keyList) { + const auto& paramInfo = MetaData::registry().at(key); + const std::string& defaultValue = paramInfo.defaultValue; + std::string value = defaultValue; + if (tree.hasKey(key)) + value = tree.get(key, ""); + os << key << "=\"" << value << "\""; + if (printDefaults) + os << " # default: \"" << defaultValue << "\""; + os << "\n"; + } +} + +void printUsage(const std::string& helpPreamble, + const std::string& errorMsg, + std::ostream& os, + const bool showAll) +{ + if (!errorMsg.empty()) { + os << errorMsg << "\n\n"; + } + + os << breakLines(helpPreamble, /*indent=*/2, /*maxWidth=*/getTtyWidth()); + os << "\n"; + + os << "Recognized options:\n"; + + if (!helpPreamble.empty()) { + ParamInfo pInfo; + pInfo.paramName = "h,--help"; + pInfo.usageString = "Print this help message and exit"; + printParamUsage(os, pInfo); + pInfo.paramName = "-help-all"; + pInfo.usageString = "Print all parameters, including obsolete, hidden and deprecated ones."; + printParamUsage(os, pInfo); + } + + for (const auto& param : MetaData::registry()) { + if (showAll || !param.second.isHidden) + printParamUsage(os, param.second); + } +} + +int noPositionalParameters_(std::function, + std::set&, + std::string& errorMsg, + int, + const char** argv, + int paramIdx, + int) +{ + errorMsg = std::string("Illegal parameter \"")+argv[paramIdx]+"\"."; + return 0; +} + +void parseParameterFile(const std::string& fileName, bool overwrite) +{ + std::set seenKeys; + std::ifstream ifs(fileName); + unsigned curLineNum = 0; + while (ifs) { + // string and file processing in c++ is quite blunt! + std::string curLine; + std::getline(ifs, curLine); + curLineNum += 1; + std::string errorPrefix = fileName+":"+std::to_string(curLineNum)+": "; + + // strip leading white space + removeLeadingSpace(curLine); + + // ignore empty and comment lines + if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') + continue; + + // TODO (?): support for parameter groups. + + // find the "key" of the key=value pair + std::string key = parseKey(curLine); + std::string canonicalKey = transformKey(key, /*capitalizeFirst=*/true, errorPrefix); + + if (seenKeys.count(canonicalKey) > 0) + throw std::runtime_error(errorPrefix+"Parameter '"+canonicalKey+"' seen multiple times in the same file"); + seenKeys.insert(canonicalKey); + + // deal with the equals sign + removeLeadingSpace(curLine); + if (curLine.empty() || curLine[0] != '=') + std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); + + curLine = curLine.substr(1); + removeLeadingSpace(curLine); + + if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') + std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); + + // get the value + std::string value; + if (curLine[0] == '"') + value = parseQuotedValue(curLine, errorPrefix); + else + value = parseUnquotedValue(curLine, errorPrefix); + + // ignore trailing comments + removeLeadingSpace(curLine); + if (!curLine.empty() && curLine[0] != '#' && curLine[0] != ';') + std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); + + // all went well, add the parameter to the database object + if (overwrite || !MetaData::tree().hasKey(canonicalKey)) { + MetaData::tree()[canonicalKey] = value; + } + } +} + +void printValues(std::ostream& os) +{ + std::list runTimeAllKeyList; + std::list runTimeKeyList; + std::list unknownKeyList; + + getFlattenedKeyList(runTimeAllKeyList, MetaData::tree()); + for (const auto& key : runTimeAllKeyList) { + if (MetaData::registry().find(key) == MetaData::registry().end()) { + // key was not registered by the program! + unknownKeyList.push_back(key); + } + else { + // the key was specified at run-time + runTimeKeyList.push_back(key); + } + } + + // loop over all registered parameters + std::list compileTimeKeyList; + for (const auto& reg : MetaData::registry()) { + // check whether the key was specified at run-time + if (MetaData::tree().hasKey(reg.first)) { + continue; + } else { + compileTimeKeyList.push_back(reg.first); + } + } + + // report the values of all registered (and unregistered) + // parameters + if (runTimeKeyList.size() > 0) { + os << "# [known parameters which were specified at run-time]\n"; + printParamList(os, runTimeKeyList, /*printDefaults=*/true); + } + + if (compileTimeKeyList.size() > 0) { + os << "# [parameters which were specified at compile-time]\n"; + printParamList(os, compileTimeKeyList, /*printDefaults=*/false); + } + + if (unknownKeyList.size() > 0) { + os << "# [unused run-time specified parameters]\n"; + for (const auto& unused : unknownKeyList) { + os << unused << "=\"" << MetaData::tree().get(unused, "") << "\"\n" << std::flush; + } + } +} + +bool printUnused(std::ostream& os) +{ + std::list runTimeAllKeyList; + std::list unknownKeyList; + + getFlattenedKeyList(runTimeAllKeyList, MetaData::tree()); + for (const auto& key : runTimeAllKeyList) { + if (MetaData::registry().find(key) == MetaData::registry().end()) { + // key was not registered by the program! + unknownKeyList.push_back(key); + } + } + + if (unknownKeyList.size() > 0) { + os << "# [unused run-time specified parameters]\n"; + for (const auto& unused : unknownKeyList) { + os << unused << "=\"" + << MetaData::tree().get(unused, "") << "\"\n" << std::flush; + } + return true; + } + return false; +} + +int getTtyWidth() +{ + int ttyWidth = 10*1000; // effectively do not break lines at all. + if (isatty(STDOUT_FILENO)) { +#if defined TIOCGWINSZ + // This is a bit too linux specific, IMO. let's do it anyway + struct winsize ttySize; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ttySize); + ttyWidth = std::max(80, ttySize.ws_col); +#else + // default for systems that do not implement the TIOCGWINSZ ioctl + ttyWidth = 100; +#endif + } + + return ttyWidth; +} + +std::string parseKey(std::string& s) +{ + unsigned i; + for (i = 0; i < s.size(); ++ i) + if (std::isspace(s[i]) || s[i] == '=') + break; + + std::string ret = s.substr(0, i); + s = s.substr(i); + return ret; +} + +std::string transformKey(const std::string& s, + bool capitalizeFirstLetter, + const std::string& errorPrefix) +{ + std::string result; + + if (s.empty()) + throw std::runtime_error(errorPrefix+"Empty parameter names are invalid"); + + if (!std::isalpha(s[0])) + throw std::runtime_error(errorPrefix+"Parameter name '" + s + "' is invalid: First character must be a letter"); + + if (capitalizeFirstLetter) + result += static_cast(std::toupper(s[0])); + else + result += s[0]; + + for (unsigned i = 1; i < s.size(); ++i) { + if (s[i] == '-') { + ++ i; + if (s.size() <= i || !std::isalpha(s[i])) + throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); + result += static_cast(std::toupper(s[i])); + } + else if (!std::isalnum(s[i])) + throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); + else + result += s[i]; + } + + return result; +} + +} // namespace Opm::Parameters diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 7e489b6da..60f67aaaf 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -95,13 +95,7 @@ struct ParamInfo std::string defaultValue; bool isHidden; - bool operator==(const ParamInfo& other) const - { - return other.paramName == paramName - && other.paramTypeName == paramTypeName - && other.typeTagName == typeTagName - && other.usageString == usageString; - } + bool operator==(const ParamInfo& other) const; }; /*! @@ -213,200 +207,28 @@ private: }; // function prototype declarations -void printParamUsage_(std::ostream& os, const ParamInfo& paramInfo); -void getFlattenedKeyList_(std::list& dest, - const Dune::ParameterTree& tree, - const std::string& prefix = ""); +void printParamUsage(std::ostream& os, const ParamInfo& paramInfo); -inline std::string breakLines_(const std::string& msg, - int indentWidth, - int maxWidth) -{ - std::string result; - int startInPos = 0; - int inPos = 0; - int lastBreakPos = 0; - int ttyPos = 0; - for (; inPos < int(msg.size()); ++ inPos, ++ ttyPos) { - if (msg[inPos] == '\n') { - result += msg.substr(startInPos, inPos - startInPos + 1); - startInPos = inPos + 1; - lastBreakPos = startInPos + 1; +std::string breakLines(const std::string& msg, + int indentWidth, + int maxWidth); - // we need to use -1 here because ttyPos is incremented after the loop body - ttyPos = -1; - continue; - } +int getTtyWidth(); - if (std::isspace(msg[inPos])) - lastBreakPos = inPos; +std::string parseKey(std::string& s); - if (ttyPos >= maxWidth) { - if (lastBreakPos > startInPos) { - result += msg.substr(startInPos, lastBreakPos - startInPos); - startInPos = lastBreakPos + 1; - lastBreakPos = startInPos; - inPos = startInPos; - } - else { - result += msg.substr(startInPos, inPos - startInPos); - startInPos = inPos; - lastBreakPos = startInPos; - inPos = startInPos; - } +std::string transformKey(const std::string& s, + bool capitalizeFirstLetter, + const std::string& errorPrefix = ""); - result += "\n"; - for (int i = 0; i < indentWidth; ++i) - result += " "; - ttyPos = indentWidth; - } - } - - result += msg.substr(startInPos); - - return result; -} - -inline int getTtyWidth_() -{ - int ttyWidth = 10*1000; // effectively do not break lines at all. - if (isatty(STDOUT_FILENO)) { -#if defined TIOCGWINSZ - // This is a bit too linux specific, IMO. let's do it anyway - struct winsize ttySize; - ioctl(STDOUT_FILENO, TIOCGWINSZ, &ttySize); - ttyWidth = std::max(80, ttySize.ws_col); -#else - // default for systems that do not implement the TIOCGWINSZ ioctl - ttyWidth = 100; -#endif - } - - return ttyWidth; -} - -inline void printParamUsage_(std::ostream& os, const ParamInfo& paramInfo) -{ - std::string paramMessage, paramType, paramDescription; - - int ttyWidth = getTtyWidth_(); - - // convert the CamelCase name to a command line --parameter-name. - std::string cmdLineName = "-"; - const std::string camelCaseName = paramInfo.paramName; - for (unsigned i = 0; i < camelCaseName.size(); ++i) { - if (isupper(camelCaseName[i])) - cmdLineName += "-"; - cmdLineName += static_cast(std::tolower(camelCaseName[i])); - } - - // assemble the printed output - paramMessage = " "; - paramMessage += cmdLineName; - - // add the =VALUE_TYPE part - bool isString = false; - if (paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == "const char *") - { - paramMessage += "=STRING"; - isString = true; - } - else if (paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() -#if HAVE_QUAD - || paramInfo.paramTypeName == Dune::className() -#endif // HAVE_QUAD - ) - paramMessage += "=SCALAR"; - else if (paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className()) - paramMessage += "=INTEGER"; - else if (paramInfo.paramTypeName == Dune::className()) - paramMessage += "=BOOLEAN"; - else if (paramInfo.paramTypeName.empty()) { - // the parameter is a flag. Do nothing! - } - else { - // unknown type - paramMessage += "=VALUE"; - } - - // fill up the up help string to the 50th character - paramMessage += " "; - while (paramMessage.size() < 50) - paramMessage += " "; - - - // append the parameter usage string. - paramMessage += paramInfo.usageString; - - // add the default value - if (!paramInfo.paramTypeName.empty()) { - if (paramMessage.back() != '.') - paramMessage += '.'; - paramMessage += " Default: "; - if (paramInfo.paramTypeName == "bool") { - if (paramInfo.defaultValue == "0") - paramMessage += "false"; - else - paramMessage += "true"; - } - else if (isString) { - paramMessage += "\""; - paramMessage += paramInfo.defaultValue; - paramMessage += "\""; - } - else - paramMessage += paramInfo.defaultValue; - } - - paramMessage = breakLines_(paramMessage, /*indent=*/52, ttyWidth); - paramMessage += "\n"; - - // print everything - os << paramMessage; -} - -inline void getFlattenedKeyList_(std::list& dest, - const Dune::ParameterTree& tree, - const std::string& prefix) -{ - // add the keys of the current sub-structure - for (const auto& valueKey : tree.getValueKeys()) { - std::string newKey(prefix + valueKey); - dest.push_back(newKey); - } - - // recursively add all substructure keys - for (const auto& subKey : tree.getSubKeys()) { - std::string newPrefix(prefix + subKey + '.'); - getFlattenedKeyList_(dest, tree.sub(subKey), newPrefix); - } -} +void getFlattenedKeyList(std::list& dest, + const Dune::ParameterTree& tree, + const std::string& prefix = ""); // print the values of a list of parameters -inline void printParamList_(std::ostream& os, - const std::list& keyList, - bool printDefaults = false) -{ - const Dune::ParameterTree& tree = MetaData::tree(); - - for (const auto& key : keyList) { - const auto& paramInfo = MetaData::registry().at(key); - const std::string& defaultValue = paramInfo.defaultValue; - std::string value = defaultValue; - if (tree.hasKey(key)) - value = tree.get(key, ""); - os << key << "=\"" << value << "\""; - if (printDefaults) - os << " # default: \"" << defaultValue << "\""; - os << "\n"; - } -} +void printParamList(std::ostream& os, + const std::list& keyList, + bool printDefaults = false); //! \endcond @@ -419,156 +241,22 @@ inline void printParamList_(std::ostream& os, * \param errorMsg The error message to be printed, if any * \param os The \c std::ostream which should be used. */ -inline void printUsage(const std::string& helpPreamble, - const std::string& errorMsg = "", - std::ostream& os = std::cerr, - const bool showAll = false) -{ - if (!errorMsg.empty()) { - os << errorMsg << "\n\n"; - } - - os << breakLines_(helpPreamble, /*indent=*/2, /*maxWidth=*/getTtyWidth_()); - os << "\n"; - - os << "Recognized options:\n"; - - if (!helpPreamble.empty()) { - ParamInfo pInfo; - pInfo.paramName = "h,--help"; - pInfo.usageString = "Print this help message and exit"; - printParamUsage_(os, pInfo); - pInfo.paramName = "-help-all"; - pInfo.usageString = "Print all parameters, including obsolete, hidden and deprecated ones."; - printParamUsage_(os, pInfo); - } - - for (const auto& param : MetaData::registry()) { - if (showAll || !param.second.isHidden) - printParamUsage_(os, param.second); - } -} +void printUsage(const std::string& helpPreamble, + const std::string& errorMsg = "", + std::ostream& os = std::cerr, + const bool showAll = false); /// \cond 0 -inline int noPositionalParameters_(std::function, - std::set&, - std::string& errorMsg, - int, - const char** argv, - int paramIdx, - int) -{ - errorMsg = std::string("Illegal parameter \"")+argv[paramIdx]+"\"."; - return 0; -} +int noPositionalParameters_(std::function, + std::set&, + std::string& errorMsg, + int, + const char** argv, + int paramIdx, + int); /// \endcond - -inline void removeLeadingSpace_(std::string& s) -{ - unsigned i; - for (i = 0; i < s.size(); ++ i) - if (!std::isspace(s[i])) - break; - s = s.substr(i); -} - -inline std::string transformKey_(const std::string& s, - bool capitalizeFirstLetter = true, - const std::string& errorPrefix = "") -{ - std::string result; - - if (s.empty()) - throw std::runtime_error(errorPrefix+"Empty parameter names are invalid"); - - if (!std::isalpha(s[0])) - throw std::runtime_error(errorPrefix+"Parameter name '" + s + "' is invalid: First character must be a letter"); - - if (capitalizeFirstLetter) - result += static_cast(std::toupper(s[0])); - else - result += s[0]; - - for (unsigned i = 1; i < s.size(); ++i) { - if (s[i] == '-') { - ++ i; - if (s.size() <= i || !std::isalpha(s[i])) - throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); - result += static_cast(std::toupper(s[i])); - } - else if (!std::isalnum(s[i])) - throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); - else - result += s[i]; - } - - return result; -} - -inline std::string parseKey_(std::string& s) -{ - unsigned i; - for (i = 0; i < s.size(); ++ i) - if (std::isspace(s[i]) || s[i] == '=') - break; - - std::string ret = s.substr(0, i); - s = s.substr(i); - return ret; -} - -// parse a quoted string -inline std::string parseQuotedValue_(std::string& s, const std::string& errorPrefix) -{ - if (s.empty() || s[0] != '"') - throw std::runtime_error(errorPrefix+"Expected quoted string"); - - std::string result; - unsigned i = 1; - for (; i < s.size(); ++i) { - // handle escape characters - if (s[i] == '\\') { - ++ i; - if (s.size() <= i) - throw std::runtime_error(errorPrefix+"Unexpected end of quoted string"); - - if (s[i] == 'n') - result += '\n'; - else if (s[i] == 'r') - result += '\r'; - else if (s[i] == 't') - result += '\t'; - else if (s[i] == '"') - result += '"'; - else if (s[i] == '\\') - result += '\\'; - else - throw std::runtime_error(errorPrefix+"Unknown escape character '\\" + s[i] + "'"); - } - else if (s[i] == '"') - break; - else - result += s[i]; - } - - s = s.substr(i+1); - return result; -} - -inline std::string parseUnquotedValue_(std::string& s, const std::string&) -{ - unsigned i; - for (i = 0; i < s.size(); ++ i) - if (std::isspace(s[i])) - break; - - std::string ret = s.substr(0, i); - s = s.substr(i); - return ret; -} - /*! * \ingroup Parameter * \brief Parse the parameters provided on the command line. @@ -659,7 +347,7 @@ std::string parseCommandLineOptions(int argc, std::string s(argv[i] + 2); // parse argument - paramName = transformKey_(parseKey_(s), /*capitalizeFirst=*/true); + paramName = transformKey(parseKey(s), /*capitalizeFirst=*/true); if (seenKeys.count(paramName) > 0) { std::string msg = std::string("Parameter '")+paramName+"' specified multiple times as a " @@ -695,64 +383,7 @@ std::string parseCommandLineOptions(int argc, * * This function does some basic syntax checks. */ -inline void parseParameterFile(const std::string& fileName, bool overwrite = true) -{ - std::set seenKeys; - std::ifstream ifs(fileName); - unsigned curLineNum = 0; - while (ifs) { - // string and file processing in c++ is quite blunt! - std::string curLine; - std::getline(ifs, curLine); - curLineNum += 1; - std::string errorPrefix = fileName+":"+std::to_string(curLineNum)+": "; - - // strip leading white space - removeLeadingSpace_(curLine); - - // ignore empty and comment lines - if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') - continue; - - // TODO (?): support for parameter groups. - - // find the "key" of the key=value pair - std::string key = parseKey_(curLine); - std::string canonicalKey = transformKey_(key, /*capitalizeFirst=*/true, errorPrefix); - - if (seenKeys.count(canonicalKey) > 0) - throw std::runtime_error(errorPrefix+"Parameter '"+canonicalKey+"' seen multiple times in the same file"); - seenKeys.insert(canonicalKey); - - // deal with the equals sign - removeLeadingSpace_(curLine); - if (curLine.empty() || curLine[0] != '=') - std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); - - curLine = curLine.substr(1); - removeLeadingSpace_(curLine); - - if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') - std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); - - // get the value - std::string value; - if (curLine[0] == '"') - value = parseQuotedValue_(curLine, errorPrefix); - else - value = parseUnquotedValue_(curLine, errorPrefix); - - // ignore trailing comments - removeLeadingSpace_(curLine); - if (!curLine.empty() && curLine[0] != '#' && curLine[0] != ';') - std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); - - // all went well, add the parameter to the database object - if (overwrite || !MetaData::tree().hasKey(canonicalKey)) { - MetaData::tree()[canonicalKey] = value; - } - } -} +void parseParameterFile(const std::string& fileName, bool overwrite = true); /*! * \ingroup Parameter @@ -760,54 +391,7 @@ inline void parseParameterFile(const std::string& fileName, bool overwrite = tru * * \param os The \c std::ostream on which the message should be printed */ -inline void printValues(std::ostream& os = std::cout) -{ - std::list runTimeAllKeyList; - std::list runTimeKeyList; - std::list unknownKeyList; - - getFlattenedKeyList_(runTimeAllKeyList, MetaData::tree()); - for (const auto& key : runTimeAllKeyList) { - if (MetaData::registry().find(key) == MetaData::registry().end()) { - // key was not registered by the program! - unknownKeyList.push_back(key); - } - else { - // the key was specified at run-time - runTimeKeyList.push_back(key); - } - } - - // loop over all registered parameters - std::list compileTimeKeyList; - for (const auto& reg : MetaData::registry()) { - // check whether the key was specified at run-time - if (MetaData::tree().hasKey(reg.first)) { - continue; - } else { - compileTimeKeyList.push_back(reg.first); - } - } - - // report the values of all registered (and unregistered) - // parameters - if (runTimeKeyList.size() > 0) { - os << "# [known parameters which were specified at run-time]\n"; - printParamList_(os, runTimeKeyList, /*printDefaults=*/true); - } - - if (compileTimeKeyList.size() > 0) { - os << "# [parameters which were specified at compile-time]\n"; - printParamList_(os, compileTimeKeyList, /*printDefaults=*/false); - } - - if (unknownKeyList.size() > 0) { - os << "# [unused run-time specified parameters]\n"; - for (const auto& unused : unknownKeyList) { - os << unused << "=\"" << MetaData::tree().get(unused, "") << "\"\n" << std::flush; - } - } -} +void printValues(std::ostream& os = std::cout); /*! * \ingroup Parameter @@ -817,29 +401,7 @@ inline void printValues(std::ostream& os = std::cout) * * \return true if something was printed */ -inline bool printUnused(std::ostream& os = std::cout) -{ - std::list runTimeAllKeyList; - std::list unknownKeyList; - - getFlattenedKeyList_(runTimeAllKeyList, MetaData::tree()); - for (const auto& key : runTimeAllKeyList) { - if (MetaData::registry().find(key) == MetaData::registry().end()) { - // key was not registered by the program! - unknownKeyList.push_back(key); - } - } - - if (unknownKeyList.size() > 0) { - os << "# [unused run-time specified parameters]\n"; - for (const auto& unused : unknownKeyList) { - os << unused << "=\"" - << MetaData::tree().get(unused, "") << "\"\n" << std::flush; - } - return true; - } - return false; -} +bool printUnused(std::ostream& os = std::cout); template auto Get(bool errorIfNotRegistered) @@ -924,7 +486,7 @@ void getLists(Container& usedParams, Container& unusedParams) // get all parameter keys std::list allKeysList; - getFlattenedKeyList_(allKeysList, MetaData::tree()); + getFlattenedKeyList(allKeysList, MetaData::tree()); for (const auto& key : allKeysList) { if (MetaData::registry().find(key) == MetaData::registry().end()) { @@ -938,10 +500,10 @@ void getLists(Container& usedParams, Container& unusedParams) } } -inline void reset() -{ - MetaData::clear(); -} +/*! + * \brief Reset parameter system. + */ +void reset(); /*! * \brief Returns true if a parameter has been specified at runtime, false @@ -1054,22 +616,7 @@ void Hide() * \c endParamRegistration, a std::logic_error exception * will be thrown. */ -inline void endRegistration() -{ - if (!MetaData::registrationOpen()) { - throw std::logic_error("Parameter registration was already closed. It is only possible " - "to close it once."); - } - - MetaData::registrationOpen() = false; - - // loop over all parameters and retrieve their values to make sure - // that there is no syntax error - for (const auto& param : MetaData::registrationFinalizers()) { - param->retrieve(); - } - MetaData::registrationFinalizers().clear(); -} +void endRegistration(); //! \endcond } // namespace Opm::Parameters diff --git a/opm/models/utils/start.hh b/opm/models/utils/start.hh index 8f20314d9..b64bf917a 100644 --- a/opm/models/utils/start.hh +++ b/opm/models/utils/start.hh @@ -340,9 +340,9 @@ static inline int start(int argc, char **argv, bool registerParams=true) #endif const std::string briefDescription = Problem::briefDescription(); if (!briefDescription.empty()) { - std::string tmp = Parameters::breakLines_(briefDescription, - /*indentWidth=*/0, - Parameters::getTtyWidth_()); + std::string tmp = Parameters::breakLines(briefDescription, + /*indentWidth=*/0, + Parameters::getTtyWidth()); std::cout << tmp << std::endl << std::endl; } else From 427b619ca5e3d17fd33bcc1c5ebe72f9b24aaf7f Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 13:52:54 +0200 Subject: [PATCH 04/26] parametersystem: use a std::function instead of template parameter for callback allows putting implementation in translation unit and this is hardly performance critical --- opm/models/utils/parametersystem.cpp | 103 +++++++++++++++++++++++ opm/models/utils/parametersystem.hpp | 117 ++++----------------------- 2 files changed, 117 insertions(+), 103 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 8a0cbfc70..4e3e3154e 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -399,6 +399,109 @@ void parseParameterFile(const std::string& fileName, bool overwrite) } } +std::string parseCommandLineOptions(int argc, + const char **argv, + const std::string& helpPreamble, + const PositionalArgumentCallback& posArgCallback) +{ + // handle the "--help" parameter + if (!helpPreamble.empty()) { + for (int i = 1; i < argc; ++i) { + if (std::string("-h") == argv[i] + || std::string("--help") == argv[i]) { + printUsage(helpPreamble, /*errorMsg=*/"", std::cout); + return "Help called"; + } + if (std::string("--help-all") == argv[i]) { + printUsage(helpPreamble, /*errorMsg=*/"", std::cout, true); + return "Help called"; + } + } + } + + std::set seenKeys; + int numPositionalParams = 0; + for (int i = 1; i < argc; ++i) { + // All non-positional command line options need to start with '-' + if (strlen(argv[i]) < 4 + || argv[i][0] != '-' + || argv[i][1] != '-') + { + std::string errorMsg; + int numHandled = posArgCallback([](const std::string& k, const std::string& v) + { + MetaData::tree()[k] = v; + }, seenKeys, errorMsg, + argc, argv, i, numPositionalParams); + + if (numHandled < 1) { + std::ostringstream oss; + + if (!helpPreamble.empty()) + printUsage(helpPreamble, errorMsg, std::cerr); + + return errorMsg; + } + else { + ++ numPositionalParams; + i += numHandled - 1; + continue; + } + } + + std::string paramName, paramValue; + + // read a --my-opt=abc option. This gets transformed + // into the parameter "MyOpt" with the value being + // "abc" + + // There is nothing after the '-' + if (argv[i][2] == 0 || !std::isalpha(argv[i][2])) { + std::ostringstream oss; + oss << "Parameter name of argument " << i + << " ('" << argv[i] << "') " + << "is invalid because it does not start with a letter."; + + if (!helpPreamble.empty()) + printUsage(helpPreamble, oss.str(), std::cerr); + + return oss.str(); + } + + // copy everything after the "--" into a separate string + std::string s(argv[i] + 2); + + // parse argument + paramName = transformKey(parseKey(s), /*capitalizeFirst=*/true); + if (seenKeys.count(paramName) > 0) { + std::string msg = + std::string("Parameter '")+paramName+"' specified multiple times as a " + "command line parameter"; + + if (!helpPreamble.empty()) + printUsage(helpPreamble, msg, std::cerr); + return msg; + } + seenKeys.insert(paramName); + + if (s.empty() || s[0] != '=') { + std::string msg = + std::string("Parameter '")+paramName+"' is missing a value. " + +" Please use "+argv[i]+"=value."; + + if (!helpPreamble.empty()) + printUsage(helpPreamble, msg, std::cerr); + return msg; + } + + paramValue = s.substr(1); + + // Put the key=value pair into the parameter tree + MetaData::tree()[paramName] = paramValue; + } + return ""; +} + void printValues(std::ostream& os) { std::list runTimeAllKeyList; diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 60f67aaaf..4e7d7c5bb 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -257,6 +257,15 @@ int noPositionalParameters_(std::function, + std::set&, + std::string&, + int, + const char**, + int, + int)>; /*! * \ingroup Parameter * \brief Parse the parameters provided on the command line. @@ -273,109 +282,11 @@ int noPositionalParameters_(std::function -std::string parseCommandLineOptions(int argc, - const char **argv, - const std::string& helpPreamble = "", - const PositionalArgumentCallback& posArgCallback = noPositionalParameters_) -{ - // handle the "--help" parameter - if (!helpPreamble.empty()) { - for (int i = 1; i < argc; ++i) { - if (std::string("-h") == argv[i] - || std::string("--help") == argv[i]) { - printUsage(helpPreamble, /*errorMsg=*/"", std::cout); - return "Help called"; - } - if (std::string("--help-all") == argv[i]) { - printUsage(helpPreamble, /*errorMsg=*/"", std::cout, true); - return "Help called"; - } - } - } - - std::set seenKeys; - int numPositionalParams = 0; - for (int i = 1; i < argc; ++i) { - // All non-positional command line options need to start with '-' - if (strlen(argv[i]) < 4 - || argv[i][0] != '-' - || argv[i][1] != '-') - { - std::string errorMsg; - int numHandled = posArgCallback([](const std::string& k, const std::string& v) - { - MetaData::tree()[k] = v; - }, seenKeys, errorMsg, - argc, argv, i, numPositionalParams); - - if (numHandled < 1) { - std::ostringstream oss; - - if (!helpPreamble.empty()) - printUsage(helpPreamble, errorMsg, std::cerr); - - return errorMsg; - } - else { - ++ numPositionalParams; - i += numHandled - 1; - continue; - } - } - - std::string paramName, paramValue; - - // read a --my-opt=abc option. This gets transformed - // into the parameter "MyOpt" with the value being - // "abc" - - // There is nothing after the '-' - if (argv[i][2] == 0 || !std::isalpha(argv[i][2])) { - std::ostringstream oss; - oss << "Parameter name of argument " << i - << " ('" << argv[i] << "') " - << "is invalid because it does not start with a letter."; - - if (!helpPreamble.empty()) - printUsage(helpPreamble, oss.str(), std::cerr); - - return oss.str(); - } - - // copy everything after the "--" into a separate string - std::string s(argv[i] + 2); - - // parse argument - paramName = transformKey(parseKey(s), /*capitalizeFirst=*/true); - if (seenKeys.count(paramName) > 0) { - std::string msg = - std::string("Parameter '")+paramName+"' specified multiple times as a " - "command line parameter"; - - if (!helpPreamble.empty()) - printUsage(helpPreamble, msg, std::cerr); - return msg; - } - seenKeys.insert(paramName); - - if (s.empty() || s[0] != '=') { - std::string msg = - std::string("Parameter '")+paramName+"' is missing a value. " - +" Please use "+argv[i]+"=value."; - - if (!helpPreamble.empty()) - printUsage(helpPreamble, msg, std::cerr); - return msg; - } - - paramValue = s.substr(1); - - // Put the key=value pair into the parameter tree - MetaData::tree()[paramName] = paramValue; - } - return ""; -} +std::string +parseCommandLineOptions(int argc, + const char **argv, + const std::string& helpPreamble = "", + const PositionalArgumentCallback& posArgCallback = noPositionalParameters_); /*! * \ingroup Parameter From 7584f588a719e0735cda5ac76ff258232e2ebd1f Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 14:02:15 +0200 Subject: [PATCH 05/26] parametersystem: parseKey/transformKey can now be implementation details --- opm/models/utils/parametersystem.cpp | 91 ++++++++++++++-------------- opm/models/utils/parametersystem.hpp | 6 -- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 4e3e3154e..501bd1631 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -34,6 +34,18 @@ namespace { +std::string parseKey(std::string& s) +{ + unsigned i; + for (i = 0; i < s.size(); ++ i) + if (std::isspace(s[i]) || s[i] == '=') + break; + + std::string ret = s.substr(0, i); + s = s.substr(i); + return ret; +} + std::string parseQuotedValue(std::string& s, const std::string& errorPrefix) { if (s.empty() || s[0] != '"') @@ -92,6 +104,40 @@ void removeLeadingSpace(std::string& s) s = s.substr(i); } +std::string transformKey(const std::string& s, + bool capitalizeFirstLetter, + const std::string& errorPrefix = "") +{ + std::string result; + + if (s.empty()) + throw std::runtime_error(errorPrefix+"Empty parameter names are invalid"); + + if (!std::isalpha(s[0])) + throw std::runtime_error(errorPrefix+"Parameter name '" + s + "' is invalid: First character must be a letter"); + + if (capitalizeFirstLetter) + result += static_cast(std::toupper(s[0])); + else + result += s[0]; + + for (unsigned i = 1; i < s.size(); ++i) { + if (s[i] == '-') { + ++ i; + if (s.size() <= i || !std::isalpha(s[i])) + throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); + result += static_cast(std::toupper(s[i])); + } + else if (!std::isalnum(s[i])) + throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); + else + result += s[i]; + } + + return result; +} + + } // anonymous namespace namespace Opm::Parameters { @@ -593,49 +639,4 @@ int getTtyWidth() return ttyWidth; } -std::string parseKey(std::string& s) -{ - unsigned i; - for (i = 0; i < s.size(); ++ i) - if (std::isspace(s[i]) || s[i] == '=') - break; - - std::string ret = s.substr(0, i); - s = s.substr(i); - return ret; -} - -std::string transformKey(const std::string& s, - bool capitalizeFirstLetter, - const std::string& errorPrefix) -{ - std::string result; - - if (s.empty()) - throw std::runtime_error(errorPrefix+"Empty parameter names are invalid"); - - if (!std::isalpha(s[0])) - throw std::runtime_error(errorPrefix+"Parameter name '" + s + "' is invalid: First character must be a letter"); - - if (capitalizeFirstLetter) - result += static_cast(std::toupper(s[0])); - else - result += s[0]; - - for (unsigned i = 1; i < s.size(); ++i) { - if (s[i] == '-') { - ++ i; - if (s.size() <= i || !std::isalpha(s[i])) - throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); - result += static_cast(std::toupper(s[i])); - } - else if (!std::isalnum(s[i])) - throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); - else - result += s[i]; - } - - return result; -} - } // namespace Opm::Parameters diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 4e7d7c5bb..3c9d00e79 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -215,12 +215,6 @@ std::string breakLines(const std::string& msg, int getTtyWidth(); -std::string parseKey(std::string& s); - -std::string transformKey(const std::string& s, - bool capitalizeFirstLetter, - const std::string& errorPrefix = ""); - void getFlattenedKeyList(std::list& dest, const Dune::ParameterTree& tree, const std::string& prefix = ""); From 48bcf6ac04664e349855c0ec64277798ae37ce51 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 14:19:33 +0200 Subject: [PATCH 06/26] Parameters::Hide split out main implementation allows putting it in translation unit --- opm/models/utils/parametersystem.cpp | 22 +++++++++++++++++++++- opm/models/utils/parametersystem.hpp | 19 ++++--------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 501bd1631..ab32421b0 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -137,11 +137,31 @@ std::string transformKey(const std::string& s, return result; } - } // anonymous namespace namespace Opm::Parameters { +namespace detail { + +void Hide_(const std::string& paramName) +{ + if (!MetaData::registrationOpen()) { + throw std::logic_error("Parameter '" + paramName + "' declared as hidden" + " when parameter registration was already closed."); + } + + auto paramInfoIt = MetaData::mutableRegistry().find(paramName); + if (paramInfoIt == MetaData::mutableRegistry().end()) { + throw std::logic_error("Tried to declare unknown parameter '" + + paramName + "' hidden."); + } + + auto& paramInfo = paramInfoIt->second; + paramInfo.isHidden = true; +} + +} + bool ParamInfo::operator==(const ParamInfo& other) const { return other.paramName == paramName diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 3c9d00e79..3e1a3d2a5 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -84,6 +84,9 @@ auto getParamName() } } +//! \brief Private implementation. +void Hide_(const std::string& paramName); + } struct ParamInfo @@ -489,7 +492,6 @@ void Register(const char* usageString) MetaData::mutableRegistry()[paramName] = paramInfo; } - /*! * \brief Indicate that a given parameter should not be mentioned in the help message * @@ -498,20 +500,7 @@ void Register(const char* usageString) template void Hide() { - const std::string paramName = detail::getParamName(); - if (!MetaData::registrationOpen()) { - throw std::logic_error("Parameter '" +paramName + "' declared as hidden" - " when parameter registration was already closed."); - } - - auto paramInfoIt = MetaData::mutableRegistry().find(paramName); - if (paramInfoIt == MetaData::mutableRegistry().end()) { - throw std::logic_error("Tried to declare unknown parameter '" - + paramName + "' hidden."); - } - - auto& paramInfo = paramInfoIt->second; - paramInfo.isHidden = true; + detail::Hide_(detail::getParamName()); } /*! From 98b33d582fef1e116b80893348c880c585bb54ac Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 14:19:33 +0200 Subject: [PATCH 07/26] Parameters::Register split out parts of implementation allows putting it in translation unit --- opm/models/utils/parametersystem.cpp | 29 ++++++++++++++++++++++++++++ opm/models/utils/parametersystem.hpp | 29 +++++++--------------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index ab32421b0..590dd3799 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -160,6 +160,35 @@ void Hide_(const std::string& paramName) paramInfo.isHidden = true; } +void Register_(const std::string& paramName, + const std::string& paramTypeName, + const std::string& defaultValue, + const char* usageString) +{ + if (!MetaData::registrationOpen()) { + throw std::logic_error("Parameter registration was already closed before " + "the parameter '" + paramName + "' was registered."); + } + + ParamInfo paramInfo; + paramInfo.paramName = paramName; + paramInfo.paramTypeName = paramTypeName; + paramInfo.usageString = usageString; + paramInfo.defaultValue = defaultValue; + paramInfo.isHidden = false; + if (MetaData::registry().find(paramName) != MetaData::registry().end()) { + // allow to register a parameter twice, but only if the + // parameter name, type and usage string are exactly the same. + if (MetaData::registry().at(paramName) == paramInfo) { + return; + } + throw std::logic_error("Parameter " + paramName + +" registered twice with non-matching characteristics."); + } + + MetaData::mutableRegistry()[paramName] = paramInfo; +} + } bool ParamInfo::operator==(const ParamInfo& other) const diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 3e1a3d2a5..9e33a9a99 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -87,6 +87,12 @@ auto getParamName() //! \brief Private implementation. void Hide_(const std::string& paramName); +//! \brief Private implementation. +void Register_(const std::string& paramName, + const std::string& paramTypeName, + const std::string& defaultValue, + const char* usageString); + } struct ParamInfo @@ -459,11 +465,6 @@ template void Register(const char* usageString) { const std::string paramName = detail::getParamName(); - if (!MetaData::registrationOpen()) { - throw std::logic_error("Parameter registration was already closed before " - "the parameter '" + paramName + "' was registered."); - } - const auto defaultValue = Param::value; using ParamType = std::conditional_t, std::string, @@ -471,25 +472,9 @@ void Register(const char* usageString) MetaData::registrationFinalizers().push_back( std::make_unique>()); - ParamInfo paramInfo; - paramInfo.paramName = paramName; - paramInfo.paramTypeName = Dune::className(); - paramInfo.usageString = usageString; std::ostringstream oss; oss << defaultValue; - paramInfo.defaultValue = oss.str(); - paramInfo.isHidden = false; - if (MetaData::registry().find(paramName) != MetaData::registry().end()) { - // allow to register a parameter twice, but only if the - // parameter name, type and usage string are exactly the same. - if (MetaData::registry().at(paramName) == paramInfo) { - return; - } - throw std::logic_error("Parameter " + paramName - +" registered twice with non-matching characteristics."); - } - - MetaData::mutableRegistry()[paramName] = paramInfo; + detail::Register_(paramName, Dune::className(), oss.str(), usageString); } /*! From 741e97da61ce56c8ca6b42cb2e98c43c7c26b856 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 14:19:33 +0200 Subject: [PATCH 08/26] Parameters::IsSet split out parts of implementation allows putting it in translation unit --- opm/models/utils/parametersystem.cpp | 18 ++++++++++++++++++ opm/models/utils/parametersystem.hpp | 19 ++++--------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 590dd3799..5d6f2276d 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -160,6 +160,24 @@ void Hide_(const std::string& paramName) paramInfo.isHidden = true; } +bool IsSet_(const std::string& paramName, bool errorIfNotRegistered) +{ + if (errorIfNotRegistered) { + if (MetaData::registrationOpen()) { + throw std::runtime_error("Parameters can only checked after _all_ of them have " + "been registered."); + } + + if (MetaData::registry().find(paramName) == MetaData::registry().end()) + throw std::runtime_error("Accessing parameter " + std::string(paramName) + + " without prior registration is not allowed."); + } + + // check whether the parameter is in the parameter tree + return MetaData::tree().hasKey(paramName); + +} + void Register_(const std::string& paramName, const std::string& paramTypeName, const std::string& defaultValue, diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 9e33a9a99..177a93ed3 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -87,6 +87,9 @@ auto getParamName() //! \brief Private implementation. void Hide_(const std::string& paramName); +//! \brief Private implementation. +bool IsSet_(const std::string& paramName, bool errorIfNotRegistered); + //! \brief Private implementation. void Register_(const std::string& paramName, const std::string& paramTypeName, @@ -428,21 +431,7 @@ void reset(); template bool IsSet(bool errorIfNotRegistered = true) { - const std::string paramName = detail::getParamName(); - - if (errorIfNotRegistered) { - if (MetaData::registrationOpen()) { - throw std::runtime_error("Parameters can only checked after _all_ of them have " - "been registered."); - } - - if (MetaData::registry().find(paramName) == MetaData::registry().end()) - throw std::runtime_error("Accessing parameter " + std::string(paramName) + - " without prior registration is not allowed."); - } - - // check whether the parameter is in the parameter tree - return MetaData::tree().hasKey(paramName); + return detail::IsSet_(detail::getParamName(), errorIfNotRegistered); } /*! From 65158cd3fb999baaa005b818d7e337fdd17c3ae5 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 14:19:33 +0200 Subject: [PATCH 09/26] Parameters::SetDefault split out parts of implementation allows putting it in translation unit --- opm/models/utils/parametersystem.cpp | 10 ++++++++++ opm/models/utils/parametersystem.hpp | 14 +++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 5d6f2276d..592737283 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -207,6 +207,16 @@ void Register_(const std::string& paramName, MetaData::mutableRegistry()[paramName] = paramInfo; } +void SetDefault_(const std::string& paramName, + const std::string& paramValue) +{ + if (MetaData::registry().find(paramName) == MetaData::registry().end()) { + throw std::runtime_error("Accessing parameter " + paramName + + " without prior registration is not allowed."); + } + MetaData::mutableRegistry()[paramName].defaultValue = paramValue; +} + } bool ParamInfo::operator==(const ParamInfo& other) const diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 177a93ed3..430d13ab0 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -96,6 +96,10 @@ void Register_(const std::string& paramName, const std::string& defaultValue, const char* usageString); +//! \brief Private implementation. +void SetDefault_(const std::string& paramName, + const std::string& paramValue); + } struct ParamInfo @@ -143,7 +147,7 @@ auto Get(bool errorIfNotRegistered = true); * \endcode */ template -auto SetDefault(decltype(Param::value) new_value); +void SetDefault(decltype(Param::value) new_value); class ParamRegFinalizerBase_ { @@ -372,16 +376,12 @@ auto Get(bool errorIfNotRegistered) } template -auto SetDefault(decltype(Param::value) new_value) +void SetDefault(decltype(Param::value) new_value) { const std::string paramName = detail::getParamName(); - if (MetaData::registry().find(paramName) == MetaData::registry().end()) { - throw std::runtime_error("Accessing parameter " + paramName + - " without prior registration is not allowed."); - } std::ostringstream oss; oss << new_value; - MetaData::mutableRegistry()[paramName].defaultValue = oss.str(); + detail::SetDefault_(paramName, oss.str()); } /*! From cfad87b41f2a197c7fdc30c8e3db79ebf7b86a77 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 15:13:46 +0200 Subject: [PATCH 10/26] ParameterSystem: remove ParamFinalizer this adds no extra validation and complicates refactoring --- opm/models/utils/parametersystem.cpp | 7 ------- opm/models/utils/parametersystem.hpp | 27 --------------------------- 2 files changed, 34 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 592737283..ca0009d5d 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -289,13 +289,6 @@ void endRegistration() } MetaData::registrationOpen() = false; - - // loop over all parameters and retrieve their values to make sure - // that there is no syntax error - for (const auto& param : MetaData::registrationFinalizers()) { - param->retrieve(); - } - MetaData::registrationFinalizers().clear(); } void printParamUsage(std::ostream& os, const ParamInfo& paramInfo) diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 430d13ab0..31587c0cd 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -149,26 +149,6 @@ auto Get(bool errorIfNotRegistered = true); template void SetDefault(decltype(Param::value) new_value); -class ParamRegFinalizerBase_ -{ -public: - virtual ~ParamRegFinalizerBase_() - {} - virtual void retrieve() = 0; -}; - -template -class ParamRegFinalizer_ : public ParamRegFinalizerBase_ -{ -public: - void retrieve() override - { - // retrieve the parameter once to make sure that its value does - // not contain a syntax error. - std::ignore = Get(/*errorIfNotRegistered=*/true); - } -}; - struct MetaData { using type = Dune::ParameterTree; @@ -182,16 +162,12 @@ struct MetaData static const std::map& registry() { return storage_().registry; } - static std::list> ®istrationFinalizers() - { return storage_().finalizers; } - static bool& registrationOpen() { return storage_().registrationOpen; } static void clear() { storage_().tree = std::make_unique(); - storage_().finalizers.clear(); storage_().registrationOpen = true; storage_().registry.clear(); } @@ -211,7 +187,6 @@ private: std::unique_ptr tree; std::map registry; - std::list> finalizers; bool registrationOpen; }; @@ -458,8 +433,6 @@ void Register(const char* usageString) using ParamType = std::conditional_t, std::string, std::remove_const_t>; - MetaData::registrationFinalizers().push_back( - std::make_unique>()); std::ostringstream oss; oss << defaultValue; From ae8dd62fe3cee0aac00ad0fc8a9088920ee18b14 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 14:19:33 +0200 Subject: [PATCH 11/26] Parameters::Get split out parts of implementation allows putting it in translation unit --- CMakeLists.txt | 8 ++ opm/models/utils/parametersystem.cpp | 66 +++++++++++++++ opm/models/utils/parametersystem.hpp | 115 +++++++++------------------ 3 files changed, 111 insertions(+), 78 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5526517d..174bfd285 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -317,6 +317,14 @@ macro (sources_hook) include(opencl-source-provider) list(APPEND opm-simulators_SOURCES ${PROJECT_BINARY_DIR}/clSources.cpp) endif() + if(QuadMath_FOUND) + get_target_property(qm_defs QuadMath::QuadMath INTERFACE_COMPILE_DEFINITIONS) + list(APPEND qm_defs HAVE_QUAD=1) + get_target_property(qm_options QuadMath::QuadMath INTERFACE_COMPILE_OPTIONS) + set_source_files_properties(opm/models/utils/parametersystem.cpp + PROPERTIES COMPILE_DEFINITIONS "${qm_defs}" + COMPILE_OPTIONS "${qm_options}") + endif() endmacro (sources_hook) macro (fortran_hook) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index ca0009d5d..23a660dfb 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -32,6 +32,10 @@ #include #include +#if HAVE_QUAD +#include +#endif + namespace { std::string parseKey(std::string& s) @@ -143,6 +147,52 @@ namespace Opm::Parameters { namespace detail { +template +ParamType Get_(const std::string& paramName, ParamType defaultValue, + bool errorIfNotRegistered) +{ + if (errorIfNotRegistered) { + if (MetaData::registrationOpen()) + throw std::runtime_error("Parameters can only retrieved after _all_ of them have " + "been registered."); + + if (MetaData::registry().find(paramName) == MetaData::registry().end()) { + throw std::runtime_error("Accessing parameter " + paramName + +" without prior registration is not allowed."); + } + } + + const std::string& defVal = MetaData::mutableRegistry()[paramName].defaultValue; + if constexpr (std::is_same_v) { + defaultValue = defVal; + } + else if constexpr (std::is_same_v) { + defaultValue = defVal == "1"; + } +#if HAVE_QUAD + else if constexpr (std::is_same_v) { + defaultValue = std::strtold(defVal.data(), nullptr); + } +#endif +#if !HAVE_FLOATING_POINT_FROM_CHARS + else if constexpr (std::is_floating_point_v) { + defaultValue = std::strtod(defVal.c_str(), nullptr); + } +#endif // !HAVE_FLOATING_POINT_FROM_CHARS + else { + std::from_chars(defVal.data(), defVal.data() + defVal.size(), defaultValue); + } + + // prefix the parameter name by the model's GroupName. E.g. If + // the model specifies its group name to be 'Stokes', in an + // INI file this would result in something like: + // + // [Stokes] + // NewtonWriteConvergence = true + // retrieve actual parameter from the parameter tree + return MetaData::tree().template get(paramName, defaultValue); +} + void Hide_(const std::string& paramName) { if (!MetaData::registrationOpen()) { @@ -709,4 +759,20 @@ int getTtyWidth() return ttyWidth; } +namespace detail { + +template bool Get_(const std::string&, bool, bool); +template double Get_(const std::string&, double, bool); +template float Get_(const std::string&, float, bool); +template int Get_(const std::string&, int, bool); +template long Get_(const std::string&, long, bool); +template std::string Get_(const std::string&, std::string, bool); +template unsigned Get_(const std::string&, unsigned, bool); + +#if HAVE_QUAD +template quad Get_(const std::string&, quad, bool); +#endif + +} + } // namespace Opm::Parameters diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 31587c0cd..d8223a2c0 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -84,6 +84,11 @@ auto getParamName() } } +//! \brief Private implementation. +template +ParamType Get_(const std::string& paramName, ParamType defaultValue, + bool errorIfNotRegistered); + //! \brief Private implementation. void Hide_(const std::string& paramName); @@ -114,41 +119,6 @@ struct ParamInfo bool operator==(const ParamInfo& other) const; }; -/*! - * \ingroup Parameter - * - * \brief Retrieve a runtime parameter. - * - * The default value is specified in the parameter struct. - * - * Example: - * - * \code - * // Retrieves value UpwindWeight, default - * // is taken from the property UpwindWeight - * ::Opm::Parameters::get<::Opm::Parameters::UpwindWeight>(); - * \endcode - */ -template -auto Get(bool errorIfNotRegistered = true); - -/*! - * \ingroup Parameter - * - * \brief Set a runtime parameter. - * - * Override the default value specified. - * - * Example: - * - * \code - * // Set the value UpwindWeight - * ::Opm::Parameters::Set<::Opm::Parameters::UpwindWeight>(3.0); - * \endcode - */ -template -void SetDefault(decltype(Param::value) new_value); - struct MetaData { using type = Dune::ParameterTree; @@ -299,57 +269,46 @@ void printValues(std::ostream& os = std::cout); */ bool printUnused(std::ostream& os = std::cout); +/*! + * \ingroup Parameter + * + * \brief Retrieve a runtime parameter. + * + * The default value is specified in the parameter struct. + * + * Example: + * + * \code + * // Retrieves value UpwindWeight, default + * // is taken from the property UpwindWeight + * ::Opm::Parameters::get<::Opm::Parameters::UpwindWeight>(); + * \endcode + */ template -auto Get(bool errorIfNotRegistered) +auto Get(bool errorIfNotRegistered = true) { - const std::string paramName = detail::getParamName(); - if (errorIfNotRegistered) { - if (MetaData::registrationOpen()) - throw std::runtime_error("Parameters can only retrieved after _all_ of them have " - "been registered."); - - if (MetaData::registry().find(paramName) == MetaData::registry().end()) { - throw std::runtime_error("Accessing parameter " + paramName - +" without prior registration is not allowed."); - } - } - using ParamType = std::conditional_t, std::string, std::remove_const_t>; ParamType defaultValue = Param::value; - - const std::string& defVal = MetaData::mutableRegistry()[paramName].defaultValue; - if constexpr (std::is_same_v) { - defaultValue = defVal; - } - else if constexpr (std::is_same_v) { - defaultValue = defVal == "1"; - } -#if HAVE_QUAD - else if constexpr (std::is_same_v) { - defaultValue = std::strtold(defVal.data(), nullptr); - } -#endif -#if !HAVE_FLOATING_POINT_FROM_CHARS - else if constexpr (std::is_floating_point_v) { - defaultValue = std::strtod(defVal.c_str(), nullptr); - } -#endif // !HAVE_FLOATING_POINT_FROM_CHARS - else { - std::from_chars(defVal.data(), defVal.data() + defVal.size(), defaultValue); - } - - // prefix the parameter name by the model's GroupName. E.g. If - // the model specifies its group name to be 'Stokes', in an - // INI file this would result in something like: - // - // [Stokes] - // NewtonWriteConvergence = true - // retrieve actual parameter from the parameter tree - return MetaData::tree().template get(paramName, defaultValue); + return detail::Get_(detail::getParamName(), + defaultValue, errorIfNotRegistered); } +/*! + * \ingroup Parameter + * + * \brief Set a runtime parameter. + * + * Override the default value specified. + * + * Example: + * + * \code + * // Set the value UpwindWeight + * ::Opm::Parameters::Set<::Opm::Parameters::UpwindWeight>(3.0); + * \endcode + */ template void SetDefault(decltype(Param::value) new_value) { From 410039206d4797cc3e8b5f05cf9744e5f9734077 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 15:39:02 +0200 Subject: [PATCH 12/26] add Parameters::Parameter struct this holds a key-value pair for a parameter with some utility functions for comparison and printing. use this to move Parameters::getLists to the translation unit --- opm/models/utils/parametersystem.cpp | 27 +++++++++++++ opm/models/utils/parametersystem.hpp | 59 ++++++++++++++++------------ opm/models/utils/start.hh | 5 +-- tests/test_parametersystem.cpp | 31 +-------------- 4 files changed, 63 insertions(+), 59 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 23a660dfb..0f3a36b66 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -427,6 +427,33 @@ void printParamUsage(std::ostream& os, const ParamInfo& paramInfo) os << paramMessage; } +void getLists(std::vector& usedParams, + std::vector& unusedParams) +{ + usedParams.clear(); + unusedParams.clear(); + + if (MetaData::registrationOpen()) { + throw std::runtime_error("Parameter lists can only retrieved after _all_ of them have " + "been registered."); + } + + // get all parameter keys + std::list allKeysList; + getFlattenedKeyList(allKeysList, MetaData::tree()); + + for (const auto& key : allKeysList) { + if (MetaData::registry().find(key) == MetaData::registry().end()) { + // key was not registered + unusedParams.emplace_back(key, MetaData::tree()[key]); + } + else { + // key was registered + usedParams.emplace_back(key, MetaData::tree()[key]); + } + } +} + void getFlattenedKeyList(std::list& dest, const Dune::ParameterTree& tree, const std::string& prefix) diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index d8223a2c0..6ce92202f 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -50,8 +50,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -318,38 +320,43 @@ void SetDefault(decltype(Param::value) new_value) detail::SetDefault_(paramName, oss.str()); } +/*! + * \brief A struct holding the key-value pair for a parameter. + */ +struct Parameter +{ + Parameter(const std::string& k, const std::string& v) + : key(k), value(v) + {} + + friend std::ostream& operator<<(std::ostream& os, const Parameter& param) + { + os << param.key << "=\"" << param.value << '"'; + return os; + } + + bool operator==(const Parameter& setting) const + { + return setting.key == key + && setting.value == value; + } + + bool operator !=(const Parameter& setting) const + { + return !(*this == setting); + } + + std::string key, value; +}; + /*! * \brief Retrieves the lists of parameters specified at runtime and their values. * * The two arguments besides the TypeTag are assumed to be STL containers which store * std::pair. */ -template -void getLists(Container& usedParams, Container& unusedParams) -{ - usedParams.clear(); - unusedParams.clear(); - - if (MetaData::registrationOpen()) { - throw std::runtime_error("Parameter lists can only retrieved after _all_ of them have " - "been registered."); - } - - // get all parameter keys - std::list allKeysList; - getFlattenedKeyList(allKeysList, MetaData::tree()); - - for (const auto& key : allKeysList) { - if (MetaData::registry().find(key) == MetaData::registry().end()) { - // key was not registered - unusedParams.emplace_back(key, MetaData::tree()[key]); - } - else { - // key was registered - usedParams.emplace_back(key, MetaData::tree()[key]); - } - } -} +void getLists(std::vector& usedParams, + std::vector& unusedParams); /*! * \brief Reset parameter system. diff --git a/opm/models/utils/start.hh b/opm/models/utils/start.hh index b64bf917a..81a47c7eb 100644 --- a/opm/models/utils/start.hh +++ b/opm/models/utils/start.hh @@ -171,8 +171,7 @@ static inline int setupParameters_(int argc, } // make sure that no unknown parameters are encountered - using KeyValuePair = std::pair; - using ParamList = std::list; + using ParamList = std::vector; ParamList usedParams; ParamList unusedParams; @@ -188,7 +187,7 @@ static inline int setupParameters_(int argc, std::cerr << "\n"; for (const auto& keyValue : unusedParams) - std::cerr << " " << keyValue.first << "=\"" << keyValue.second << "\"\n"; + std::cerr << " " << keyValue << "\n"; std::cerr << "\n"; std::cerr << "Use\n" diff --git a/tests/test_parametersystem.cpp b/tests/test_parametersystem.cpp index 5d3c3200e..3c56847d0 100644 --- a/tests/test_parametersystem.cpp +++ b/tests/test_parametersystem.cpp @@ -41,35 +41,6 @@ struct SimpleParamBoolN2 namespace { -class Setting -{ -public: - Setting(const std::string& k, const std::string& v) - : key(k), value(v) - {} - - friend std::ostream& operator<<(std::ostream& os, const Setting& setting) - { - os << setting.key << "=" << setting.value << '\n'; - return os; - } - - bool operator==(const Setting& setting) const - { - return setting.key == key - && setting.value == value; - } - - bool operator !=(const Setting& setting) const - { - return !(*this == setting); - } - -private: - std::string key; - std::string value; -}; - struct Fixture { Fixture() @@ -117,7 +88,7 @@ BOOST_FIXTURE_TEST_CASE(GetLists, Fixture) BOOST_CHECK_EQUAL(Opm::Parameters::IsSet(), false); BOOST_CHECK_EQUAL(Opm::Parameters::IsSet(), false); - using SettingMap = std::vector; + using SettingMap = std::vector; const SettingMap set_ref = { {"SimpleParamBool", "true"}, From 77dc5ad895bf5e5e6b88f960d8cc01d7aac038db Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 15:59:20 +0200 Subject: [PATCH 13/26] Parameters::getFlattenedKeyList can now be an implementation detail --- opm/models/utils/parametersystem.cpp | 36 ++++++++++++++-------------- opm/models/utils/parametersystem.hpp | 4 ---- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 0f3a36b66..48ec7d011 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -38,6 +38,24 @@ namespace { +void getFlattenedKeyList(std::list& dest, + const Dune::ParameterTree& tree, + const std::string& prefix = "") +{ + // add the keys of the current sub-structure + for (const auto& valueKey : tree.getValueKeys()) { + std::string newKey(prefix + valueKey); + dest.push_back(newKey); + } + + // recursively add all substructure keys + for (const auto& subKey : tree.getSubKeys()) { + std::string newPrefix(prefix + subKey + '.'); + getFlattenedKeyList(dest, tree.sub(subKey), newPrefix); + } +} + + std::string parseKey(std::string& s) { unsigned i; @@ -454,24 +472,6 @@ void getLists(std::vector& usedParams, } } -void getFlattenedKeyList(std::list& dest, - const Dune::ParameterTree& tree, - const std::string& prefix) -{ - // add the keys of the current sub-structure - for (const auto& valueKey : tree.getValueKeys()) { - std::string newKey(prefix + valueKey); - dest.push_back(newKey); - } - - // recursively add all substructure keys - for (const auto& subKey : tree.getSubKeys()) { - std::string newPrefix(prefix + subKey + '.'); - getFlattenedKeyList(dest, tree.sub(subKey), newPrefix); - } -} - -// print the values of a list of parameters void printParamList(std::ostream& os, const std::list& keyList, bool printDefaults) diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 6ce92202f..daca5c7da 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -178,10 +178,6 @@ std::string breakLines(const std::string& msg, int getTtyWidth(); -void getFlattenedKeyList(std::list& dest, - const Dune::ParameterTree& tree, - const std::string& prefix = ""); - // print the values of a list of parameters void printParamList(std::ostream& os, const std::list& keyList, From faa963056dc6d545d4ac1257de7c5ddceb050a75 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 15:59:20 +0200 Subject: [PATCH 14/26] Parameters::printParamUsage can now be an implementation detail --- opm/models/utils/parametersystem.cpp | 174 +++++++++++++-------------- opm/models/utils/parametersystem.hpp | 3 - 2 files changed, 87 insertions(+), 90 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 48ec7d011..a7ac6bb4b 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -55,7 +55,6 @@ void getFlattenedKeyList(std::list& dest, } } - std::string parseKey(std::string& s) { unsigned i; @@ -117,6 +116,93 @@ std::string parseUnquotedValue(std::string& s, const std::string&) return ret; } +void printParamUsage(std::ostream& os, + const Opm::Parameters::ParamInfo& paramInfo) +{ + std::string paramMessage, paramType, paramDescription; + + int ttyWidth = Opm::Parameters::getTtyWidth(); + + // convert the CamelCase name to a command line --parameter-name. + std::string cmdLineName = "-"; + const std::string camelCaseName = paramInfo.paramName; + for (unsigned i = 0; i < camelCaseName.size(); ++i) { + if (isupper(camelCaseName[i])) + cmdLineName += "-"; + cmdLineName += static_cast(std::tolower(camelCaseName[i])); + } + + // assemble the printed output + paramMessage = " "; + paramMessage += cmdLineName; + + // add the =VALUE_TYPE part + bool isString = false; + if (paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == "const char *") + { + paramMessage += "=STRING"; + isString = true; + } + else if (paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() +#if HAVE_QUAD + || paramInfo.paramTypeName == Dune::className() +#endif // HAVE_QUAD + ) + paramMessage += "=SCALAR"; + else if (paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className() + || paramInfo.paramTypeName == Dune::className()) + paramMessage += "=INTEGER"; + else if (paramInfo.paramTypeName == Dune::className()) + paramMessage += "=BOOLEAN"; + else if (paramInfo.paramTypeName.empty()) { + // the parameter is a flag. Do nothing! + } + else { + // unknown type + paramMessage += "=VALUE"; + } + + // fill up the up help string to the 50th character + paramMessage += " "; + while (paramMessage.size() < 50) + paramMessage += " "; + + + // append the parameter usage string. + paramMessage += paramInfo.usageString; + + // add the default value + if (!paramInfo.paramTypeName.empty()) { + if (paramMessage.back() != '.') + paramMessage += '.'; + paramMessage += " Default: "; + if (paramInfo.paramTypeName == "bool") { + if (paramInfo.defaultValue == "0") + paramMessage += "false"; + else + paramMessage += "true"; + } + else if (isString) { + paramMessage += "\""; + paramMessage += paramInfo.defaultValue; + paramMessage += "\""; + } + else + paramMessage += paramInfo.defaultValue; + } + + paramMessage = Opm::Parameters::breakLines(paramMessage, /*indent=*/52, ttyWidth); + paramMessage += "\n"; + + // print everything + os << paramMessage; +} + void removeLeadingSpace(std::string& s) { unsigned i; @@ -359,92 +445,6 @@ void endRegistration() MetaData::registrationOpen() = false; } -void printParamUsage(std::ostream& os, const ParamInfo& paramInfo) -{ - std::string paramMessage, paramType, paramDescription; - - int ttyWidth = getTtyWidth(); - - // convert the CamelCase name to a command line --parameter-name. - std::string cmdLineName = "-"; - const std::string camelCaseName = paramInfo.paramName; - for (unsigned i = 0; i < camelCaseName.size(); ++i) { - if (isupper(camelCaseName[i])) - cmdLineName += "-"; - cmdLineName += static_cast(std::tolower(camelCaseName[i])); - } - - // assemble the printed output - paramMessage = " "; - paramMessage += cmdLineName; - - // add the =VALUE_TYPE part - bool isString = false; - if (paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == "const char *") - { - paramMessage += "=STRING"; - isString = true; - } - else if (paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() -#if HAVE_QUAD - || paramInfo.paramTypeName == Dune::className() -#endif // HAVE_QUAD - ) - paramMessage += "=SCALAR"; - else if (paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className()) - paramMessage += "=INTEGER"; - else if (paramInfo.paramTypeName == Dune::className()) - paramMessage += "=BOOLEAN"; - else if (paramInfo.paramTypeName.empty()) { - // the parameter is a flag. Do nothing! - } - else { - // unknown type - paramMessage += "=VALUE"; - } - - // fill up the up help string to the 50th character - paramMessage += " "; - while (paramMessage.size() < 50) - paramMessage += " "; - - - // append the parameter usage string. - paramMessage += paramInfo.usageString; - - // add the default value - if (!paramInfo.paramTypeName.empty()) { - if (paramMessage.back() != '.') - paramMessage += '.'; - paramMessage += " Default: "; - if (paramInfo.paramTypeName == "bool") { - if (paramInfo.defaultValue == "0") - paramMessage += "false"; - else - paramMessage += "true"; - } - else if (isString) { - paramMessage += "\""; - paramMessage += paramInfo.defaultValue; - paramMessage += "\""; - } - else - paramMessage += paramInfo.defaultValue; - } - - paramMessage = breakLines(paramMessage, /*indent=*/52, ttyWidth); - paramMessage += "\n"; - - // print everything - os << paramMessage; -} - void getLists(std::vector& usedParams, std::vector& unusedParams) { diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index daca5c7da..d5b2a8855 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -169,9 +169,6 @@ private: } }; -// function prototype declarations -void printParamUsage(std::ostream& os, const ParamInfo& paramInfo); - std::string breakLines(const std::string& msg, int indentWidth, int maxWidth); From 672de7665d74ce40e7b4b2fc9cf08c50058245a4 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 2 Sep 2024 15:59:20 +0200 Subject: [PATCH 15/26] Parameters::printParamList can now be an implementation detail --- opm/models/utils/parametersystem.cpp | 38 ++++++++++++++-------------- opm/models/utils/parametersystem.hpp | 5 ---- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index a7ac6bb4b..920ca5711 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -116,6 +116,25 @@ std::string parseUnquotedValue(std::string& s, const std::string&) return ret; } +void printParamList(std::ostream& os, + const std::list& keyList, + bool printDefaults = false) +{ + const Dune::ParameterTree& tree = Opm::Parameters::MetaData::tree(); + + for (const auto& key : keyList) { + const auto& paramInfo = Opm::Parameters::MetaData::registry().at(key); + const std::string& defaultValue = paramInfo.defaultValue; + std::string value = defaultValue; + if (tree.hasKey(key)) + value = tree.get(key, ""); + os << key << "=\"" << value << "\""; + if (printDefaults) + os << " # default: \"" << defaultValue << "\""; + os << "\n"; + } +} + void printParamUsage(std::ostream& os, const Opm::Parameters::ParamInfo& paramInfo) { @@ -472,25 +491,6 @@ void getLists(std::vector& usedParams, } } -void printParamList(std::ostream& os, - const std::list& keyList, - bool printDefaults) -{ - const Dune::ParameterTree& tree = MetaData::tree(); - - for (const auto& key : keyList) { - const auto& paramInfo = MetaData::registry().at(key); - const std::string& defaultValue = paramInfo.defaultValue; - std::string value = defaultValue; - if (tree.hasKey(key)) - value = tree.get(key, ""); - os << key << "=\"" << value << "\""; - if (printDefaults) - os << " # default: \"" << defaultValue << "\""; - os << "\n"; - } -} - void printUsage(const std::string& helpPreamble, const std::string& errorMsg, std::ostream& os, diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index d5b2a8855..b131ed18c 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -175,11 +175,6 @@ std::string breakLines(const std::string& msg, int getTtyWidth(); -// print the values of a list of parameters -void printParamList(std::ostream& os, - const std::list& keyList, - bool printDefaults = false); - //! \endcond /*! From 0cda471821201c36db23701ddaa2860c8ef5102d Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 18:44:48 +0200 Subject: [PATCH 16/26] remove Parameters::noPositionalParameters_ only used in a test --- opm/models/utils/parametersystem.cpp | 16 ++-------------- opm/models/utils/parametersystem.hpp | 15 ++------------- opm/models/utils/start.hh | 4 ++-- tests/test_parametersystem.cpp | 17 +++++++++++++++-- 4 files changed, 21 insertions(+), 31 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 920ca5711..fecd600cc 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -521,18 +521,6 @@ void printUsage(const std::string& helpPreamble, } } -int noPositionalParameters_(std::function, - std::set&, - std::string& errorMsg, - int, - const char** argv, - int paramIdx, - int) -{ - errorMsg = std::string("Illegal parameter \"")+argv[paramIdx]+"\"."; - return 0; -} - void parseParameterFile(const std::string& fileName, bool overwrite) { std::set seenKeys; @@ -594,8 +582,8 @@ void parseParameterFile(const std::string& fileName, bool overwrite) std::string parseCommandLineOptions(int argc, const char **argv, - const std::string& helpPreamble, - const PositionalArgumentCallback& posArgCallback) + const PositionalArgumentCallback& posArgCallback, + const std::string& helpPreamble) { // handle the "--help" parameter if (!helpPreamble.empty()) { diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index b131ed18c..e915c8b32 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -191,17 +191,6 @@ void printUsage(const std::string& helpPreamble, std::ostream& os = std::cerr, const bool showAll = false); -/// \cond 0 -int noPositionalParameters_(std::function, - std::set&, - std::string& errorMsg, - int, - const char** argv, - int paramIdx, - int); - -/// \endcond - //! \brief Callback function for command line parsing. using PositionalArgumentCallback = std::function, @@ -230,8 +219,8 @@ using PositionalArgumentCallback = std::function, + std::set&, + std::string&, + int, + const char**, + int, + int) -> int + { + assert("Should not be here!"); + return 0; + }; + + + Opm::Parameters::parseCommandLineOptions(5, argv, noPositional); BOOST_CHECK_EQUAL(Opm::Parameters::IsSet(), true); BOOST_CHECK_EQUAL(Opm::Parameters::IsSet(), true); From 3161b4f54732b424591dccecd73b6662046d67fe Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 18:50:12 +0200 Subject: [PATCH 17/26] ParameterSystem: add function to query if registration is open --- opm/models/utils/parametersystem.cpp | 5 +++++ opm/models/utils/parametersystem.hpp | 6 ++++++ opm/simulators/flow/FlowMain.hpp | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index fecd600cc..af5079b9b 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -454,6 +454,11 @@ void reset() MetaData::clear(); } +bool IsRegistrationOpen() +{ + return MetaData::registrationOpen(); +} + void endRegistration() { if (!MetaData::registrationOpen()) { diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index e915c8b32..dbf3f2d6e 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -393,6 +393,12 @@ void Hide() detail::Hide_(detail::getParamName()); } +/*! + * \brief Query whether parameter registration is open or not. + * \return True if registration is open, false otherwise + */ +bool IsRegistrationOpen(); + /*! * \brief Indicate that all parameters are registered for a given type tag. * diff --git a/opm/simulators/flow/FlowMain.hpp b/opm/simulators/flow/FlowMain.hpp index b9727a85c..d60baa992 100644 --- a/opm/simulators/flow/FlowMain.hpp +++ b/opm/simulators/flow/FlowMain.hpp @@ -84,7 +84,7 @@ namespace Opm { // Read the command line parameters. Throws an exception if something goes wrong. static int setupParameters_(int argc, char** argv, Parallel::Communication comm) { - if (!Parameters::MetaData::registrationOpen()) { + if (!Parameters::IsRegistrationOpen()) { // We have already successfully run setupParameters_(). // For the dynamically chosen runs (as from the main flow // executable) we must run this function again with the From 450750162290e6eb2434c93ac3bfc8e20313c2f8 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 18:47:53 +0200 Subject: [PATCH 18/26] ParameterSystem: the entire backend store can now be an implementation detail --- opm/models/utils/parametersystem.cpp | 81 ++++++++++++++++++++++++---- opm/models/utils/parametersystem.hpp | 60 --------------------- 2 files changed, 70 insertions(+), 71 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index af5079b9b..c3144c32c 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -38,6 +38,73 @@ namespace { +struct ParamInfo +{ + std::string paramName; + std::string paramTypeName; + std::string typeTagName; + std::string usageString; + std::string defaultValue; + bool isHidden; + + bool operator==(const ParamInfo& other) const + { + return other.paramName == paramName + && other.paramTypeName == paramTypeName + && other.typeTagName == typeTagName + && other.usageString == usageString; + } +}; + +struct MetaData +{ + using type = Dune::ParameterTree; + + static Dune::ParameterTree& tree() + { return *storage_().tree; } + + static std::map& mutableRegistry() + { return storage_().registry; } + + static const std::map& registry() + { return storage_().registry; } + + static bool& registrationOpen() + { return storage_().registrationOpen; } + + static void clear() + { + storage_().tree = std::make_unique(); + storage_().registrationOpen = true; + storage_().registry.clear(); + } + +private: + // this is not pretty, but handling these attributes as static variables inside + // member functions of the ParameterMetaData property class triggers a bug in clang + // 3.5's address sanitizer which causes these variables to be initialized multiple + // times... + struct Storage_ + { + Storage_() + { + tree = std::make_unique(); + registrationOpen = true; + } + + std::unique_ptr tree; + std::map registry; + bool registrationOpen; + }; + + static Storage_& storage_() + { + static Storage_ obj; + return obj; + } +}; + + void getFlattenedKeyList(std::list& dest, const Dune::ParameterTree& tree, const std::string& prefix = "") @@ -120,10 +187,10 @@ void printParamList(std::ostream& os, const std::list& keyList, bool printDefaults = false) { - const Dune::ParameterTree& tree = Opm::Parameters::MetaData::tree(); + const Dune::ParameterTree& tree = MetaData::tree(); for (const auto& key : keyList) { - const auto& paramInfo = Opm::Parameters::MetaData::registry().at(key); + const auto& paramInfo = MetaData::registry().at(key); const std::string& defaultValue = paramInfo.defaultValue; std::string value = defaultValue; if (tree.hasKey(key)) @@ -136,7 +203,7 @@ void printParamList(std::ostream& os, } void printParamUsage(std::ostream& os, - const Opm::Parameters::ParamInfo& paramInfo) + const ParamInfo& paramInfo) { std::string paramMessage, paramType, paramDescription; @@ -392,14 +459,6 @@ void SetDefault_(const std::string& paramName, } -bool ParamInfo::operator==(const ParamInfo& other) const -{ - return other.paramName == paramName - && other.paramTypeName == paramTypeName - && other.typeTagName == typeTagName - && other.usageString == usageString; -} - std::string breakLines(const std::string& msg, int indentWidth, int maxWidth) diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index dbf3f2d6e..4c3b618f2 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -109,66 +109,6 @@ void SetDefault_(const std::string& paramName, } -struct ParamInfo -{ - std::string paramName; - std::string paramTypeName; - std::string typeTagName; - std::string usageString; - std::string defaultValue; - bool isHidden; - - bool operator==(const ParamInfo& other) const; -}; - -struct MetaData -{ - using type = Dune::ParameterTree; - - static Dune::ParameterTree& tree() - { return *storage_().tree; } - - static std::map& mutableRegistry() - { return storage_().registry; } - - static const std::map& registry() - { return storage_().registry; } - - static bool& registrationOpen() - { return storage_().registrationOpen; } - - static void clear() - { - storage_().tree = std::make_unique(); - storage_().registrationOpen = true; - storage_().registry.clear(); - } - -private: - // this is not pretty, but handling these attributes as static variables inside - // member functions of the ParameterMetaData property class triggers a bug in clang - // 3.5's address sanitizer which causes these variables to be initialized multiple - // times... - struct Storage_ - { - Storage_() - { - tree = std::make_unique(); - registrationOpen = true; - } - - std::unique_ptr tree; - std::map registry; - bool registrationOpen; - }; - - static Storage_& storage_() - { - static Storage_ obj; - return obj; - } -}; - std::string breakLines(const std::string& msg, int indentWidth, int maxWidth); From ed0c480a198f33e300ae1a7638742c910edacf12 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 19:43:04 +0200 Subject: [PATCH 19/26] Parameters::printUsage: drop default parameter for stream --- opm/models/utils/parametersystem.cpp | 26 +++++++++++++++----------- opm/models/utils/parametersystem.hpp | 2 +- opm/models/utils/start.hh | 12 +++++++----- tests/test_parametersystem.cpp | 4 ++-- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index c3144c32c..9af377750 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -556,8 +556,8 @@ void getLists(std::vector& usedParams, } void printUsage(const std::string& helpPreamble, - const std::string& errorMsg, std::ostream& os, + const std::string& errorMsg, const bool showAll) { if (!errorMsg.empty()) { @@ -654,11 +654,11 @@ std::string parseCommandLineOptions(int argc, for (int i = 1; i < argc; ++i) { if (std::string("-h") == argv[i] || std::string("--help") == argv[i]) { - printUsage(helpPreamble, /*errorMsg=*/"", std::cout); + printUsage(helpPreamble, std::cout, /*errorMsg=*/""); return "Help called"; } if (std::string("--help-all") == argv[i]) { - printUsage(helpPreamble, /*errorMsg=*/"", std::cout, true); + printUsage(helpPreamble, std::cout, /*errorMsg=*/"", true); return "Help called"; } } @@ -682,8 +682,9 @@ std::string parseCommandLineOptions(int argc, if (numHandled < 1) { std::ostringstream oss; - if (!helpPreamble.empty()) - printUsage(helpPreamble, errorMsg, std::cerr); + if (!helpPreamble.empty()) { + printUsage(helpPreamble, std::cerr, errorMsg); + } return errorMsg; } @@ -707,8 +708,9 @@ std::string parseCommandLineOptions(int argc, << " ('" << argv[i] << "') " << "is invalid because it does not start with a letter."; - if (!helpPreamble.empty()) - printUsage(helpPreamble, oss.str(), std::cerr); + if (!helpPreamble.empty()) { + printUsage(helpPreamble, std::cerr, oss.str()); + } return oss.str(); } @@ -723,8 +725,9 @@ std::string parseCommandLineOptions(int argc, std::string("Parameter '")+paramName+"' specified multiple times as a " "command line parameter"; - if (!helpPreamble.empty()) - printUsage(helpPreamble, msg, std::cerr); + if (!helpPreamble.empty()) { + printUsage(helpPreamble, std::cerr, msg); + } return msg; } seenKeys.insert(paramName); @@ -734,8 +737,9 @@ std::string parseCommandLineOptions(int argc, std::string("Parameter '")+paramName+"' is missing a value. " +" Please use "+argv[i]+"=value."; - if (!helpPreamble.empty()) - printUsage(helpPreamble, msg, std::cerr); + if (!helpPreamble.empty()) { + printUsage(helpPreamble, std::cerr, msg); + } return msg; } diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 4c3b618f2..7618bde67 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -127,8 +127,8 @@ int getTtyWidth(); * \param os The \c std::ostream which should be used. */ void printUsage(const std::string& helpPreamble, + std::ostream& os, const std::string& errorMsg = "", - std::ostream& os = std::cerr, const bool showAll = false); //! \brief Callback function for command line parsing. diff --git a/opm/models/utils/start.hh b/opm/models/utils/start.hh index 99a077282..0a97b32e3 100644 --- a/opm/models/utils/start.hh +++ b/opm/models/utils/start.hh @@ -161,7 +161,7 @@ static inline int setupParameters_(int argc, if (myRank == 0) { oss << "Parameter file \"" << paramFileName << "\" does not exist or is not readable."; - Parameters::printUsage(argv[0], oss.str()); + Parameters::printUsage(argv[0], std::cerr, oss.str()); } return /*status=*/1; } @@ -316,18 +316,20 @@ static inline int start(int argc, char **argv, bool registerParams=true) // read the initial time step and the end time Scalar endTime = Parameters::Get>(); if (endTime < -1e50) { - if (myRank == 0) - Parameters::printUsage(argv[0], + if (myRank == 0) { + Parameters::printUsage(argv[0], std::cerr, "Mandatory parameter '--end-time' not specified!"); + } return 1; } Scalar initialTimeStepSize = Parameters::Get>(); if (initialTimeStepSize < -1e50) { - if (myRank == 0) - Parameters::printUsage(argv[0], + if (myRank == 0) { + Parameters::printUsage(argv[0], std::cerr, "Mandatory parameter '--initial-time-step-size' " "not specified!"); + } return 1; } diff --git a/tests/test_parametersystem.cpp b/tests/test_parametersystem.cpp index ca94fecd3..68726a5cd 100644 --- a/tests/test_parametersystem.cpp +++ b/tests/test_parametersystem.cpp @@ -137,7 +137,7 @@ BOOST_FIXTURE_TEST_CASE(ParseParameterFile, Fixture) BOOST_FIXTURE_TEST_CASE(PrintUsage, Fixture) { std::stringstream usage; - Opm::Parameters::printUsage("", "", usage); + Opm::Parameters::printUsage("", usage); BOOST_CHECK_EQUAL(trimString(usage.str()), trimString(R"( Recognized options: @@ -152,7 +152,7 @@ Recognized options: BOOST_FIXTURE_TEST_CASE(PrintUsageAll, Fixture) { std::stringstream usage; - Opm::Parameters::printUsage("===foobar===", "", usage, true); + Opm::Parameters::printUsage("===foobar===", usage, "", true); BOOST_CHECK_EQUAL(trimString(usage.str()), trimString(R"(===foobar=== Recognized options: From 4967323c295d7e97a5a6667790a15828a4b93fcf Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 19:43:04 +0200 Subject: [PATCH 20/26] Parameters::printValues: drop default parameter for stream --- opm/models/utils/parametersystem.hpp | 2 +- opm/models/utils/start.hh | 2 +- opm/simulators/flow/FlowMain.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 7618bde67..3fa230ee7 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -176,7 +176,7 @@ void parseParameterFile(const std::string& fileName, bool overwrite = true); * * \param os The \c std::ostream on which the message should be printed */ -void printValues(std::ostream& os = std::cout); +void printValues(std::ostream& os); /*! * \ingroup Parameter diff --git a/opm/models/utils/start.hh b/opm/models/utils/start.hh index 0a97b32e3..ef8060b7d 100644 --- a/opm/models/utils/start.hh +++ b/opm/models/utils/start.hh @@ -358,7 +358,7 @@ static inline int start(int argc, char **argv, bool registerParams=true) if (printParams) { bool printSeparator = false; if (printParams == 1 || !isatty(fileno(stdout))) { - Parameters::printValues(); + Parameters::printValues(std::cout); printSeparator = true; } else diff --git a/opm/simulators/flow/FlowMain.hpp b/opm/simulators/flow/FlowMain.hpp index d60baa992..df98a48aa 100644 --- a/opm/simulators/flow/FlowMain.hpp +++ b/opm/simulators/flow/FlowMain.hpp @@ -150,7 +150,7 @@ namespace Opm { // deal with --print-parameters and unknown parameters. if (Parameters::Get() == 1) { if (mpiRank == 0) { - Parameters::printValues(); + Parameters::printValues(std::cout); } return -1; } From 218988c85e045c67577a756b12ba1d2110005db0 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 4 Sep 2024 19:43:04 +0200 Subject: [PATCH 21/26] Parameters::printUnused: drop default parameter for stream --- opm/models/utils/parametersystem.hpp | 2 +- opm/models/utils/start.hh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index 3fa230ee7..b8eb9f3d2 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -186,7 +186,7 @@ void printValues(std::ostream& os); * * \return true if something was printed */ -bool printUnused(std::ostream& os = std::cout); +bool printUnused(std::ostream& os); /*! * \ingroup Parameter diff --git a/opm/models/utils/start.hh b/opm/models/utils/start.hh index ef8060b7d..08a3c9bb4 100644 --- a/opm/models/utils/start.hh +++ b/opm/models/utils/start.hh @@ -365,13 +365,13 @@ static inline int start(int argc, char **argv, bool registerParams=true) // always print the list of specified but unused parameters printSeparator = printSeparator || - Parameters::printUnused(); + Parameters::printUnused(std::cout); if (printSeparator) std::cout << endParametersSeparator; } else // always print the list of specified but unused parameters - if (Parameters::printUnused()) + if (Parameters::printUnused(std::cout)) std::cout << endParametersSeparator; } From 36142f588c591b5f9b8ba9d051fbb940b2f3a8ee Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 5 Sep 2024 08:33:41 +0200 Subject: [PATCH 22/26] ParameterSystem: cleanup includes --- .../discretization/common/fvbaseproblem.hh | 1 + opm/models/utils/parametersystem.cpp | 11 +++++++++++ opm/models/utils/parametersystem.hpp | 18 +----------------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/opm/models/discretization/common/fvbaseproblem.hh b/opm/models/discretization/common/fvbaseproblem.hh index 98ab65703..d11f6a3bb 100644 --- a/opm/models/discretization/common/fvbaseproblem.hh +++ b/opm/models/discretization/common/fvbaseproblem.hh @@ -43,6 +43,7 @@ #include #include +#include namespace Opm::Properties { diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 9af377750..dd6c71fed 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -29,13 +29,24 @@ * Dune::ParameterTree with the default value taken from the parameter * definition. */ + #include #include +#include + #if HAVE_QUAD #include #endif +#include +#include +#include +#include +#include +#include +#include + namespace { struct ParamInfo diff --git a/opm/models/utils/parametersystem.hpp b/opm/models/utils/parametersystem.hpp index b8eb9f3d2..483ba7e6c 100644 --- a/opm/models/utils/parametersystem.hpp +++ b/opm/models/utils/parametersystem.hpp @@ -32,32 +32,16 @@ #ifndef OPM_PARAMETER_SYSTEM_HPP #define OPM_PARAMETER_SYSTEM_HPP -#if HAVE_QUAD -#include -#endif // HAVE_QUAD - #include -#include -#include -#include +#include #include -#include -#include -#include -#include #include #include -#include #include -#include -#include #include #include -#include -#include - namespace Opm::Parameters { namespace detail { From 4cc187d2d85e56495397a44ae91de162665340b5 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 5 Sep 2024 08:36:03 +0200 Subject: [PATCH 23/26] ParameterSystem: replace std::list with std::vector --- opm/models/utils/parametersystem.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index dd6c71fed..37d663a49 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -41,7 +41,6 @@ #include #include -#include #include #include #include @@ -116,7 +115,7 @@ private: }; -void getFlattenedKeyList(std::list& dest, +void getFlattenedKeyList(std::vector& dest, const Dune::ParameterTree& tree, const std::string& prefix = "") { @@ -195,7 +194,7 @@ std::string parseUnquotedValue(std::string& s, const std::string&) } void printParamList(std::ostream& os, - const std::list& keyList, + const std::vector& keyList, bool printDefaults = false) { const Dune::ParameterTree& tree = MetaData::tree(); @@ -551,7 +550,7 @@ void getLists(std::vector& usedParams, } // get all parameter keys - std::list allKeysList; + std::vector allKeysList; getFlattenedKeyList(allKeysList, MetaData::tree()); for (const auto& key : allKeysList) { @@ -764,9 +763,9 @@ std::string parseCommandLineOptions(int argc, void printValues(std::ostream& os) { - std::list runTimeAllKeyList; - std::list runTimeKeyList; - std::list unknownKeyList; + std::vector runTimeAllKeyList; + std::vector runTimeKeyList; + std::vector unknownKeyList; getFlattenedKeyList(runTimeAllKeyList, MetaData::tree()); for (const auto& key : runTimeAllKeyList) { @@ -781,7 +780,7 @@ void printValues(std::ostream& os) } // loop over all registered parameters - std::list compileTimeKeyList; + std::vector compileTimeKeyList; for (const auto& reg : MetaData::registry()) { // check whether the key was specified at run-time if (MetaData::tree().hasKey(reg.first)) { @@ -813,8 +812,8 @@ void printValues(std::ostream& os) bool printUnused(std::ostream& os) { - std::list runTimeAllKeyList; - std::list unknownKeyList; + std::vector runTimeAllKeyList; + std::vector unknownKeyList; getFlattenedKeyList(runTimeAllKeyList, MetaData::tree()); for (const auto& key : runTimeAllKeyList) { From 95ab000612beeafa31e08fd45f664f0757476f97 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 5 Sep 2024 08:41:09 +0200 Subject: [PATCH 24/26] ParameterSystem: replace if nest with switch --- opm/models/utils/parametersystem.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 37d663a49..464e38280 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -154,22 +154,19 @@ std::string parseQuotedValue(std::string& s, const std::string& errorPrefix) for (; i < s.size(); ++i) { // handle escape characters if (s[i] == '\\') { - ++ i; + ++i; if (s.size() <= i) throw std::runtime_error(errorPrefix+"Unexpected end of quoted string"); - if (s[i] == 'n') - result += '\n'; - else if (s[i] == 'r') - result += '\r'; - else if (s[i] == 't') - result += '\t'; - else if (s[i] == '"') - result += '"'; - else if (s[i] == '\\') - result += '\\'; - else - throw std::runtime_error(errorPrefix+"Unknown escape character '\\" + s[i] + "'"); + switch (s[i]) { + case 'n': result += '\n'; break; + case 'r': result += '\r'; break; + case 't': result += '\t'; break; + case '"': result += '"'; break; + case '\\': result += '\\'; break; + default: throw std::runtime_error(errorPrefix + + "Unknown escape character '\\" + s[i] + "'"); + } } else if (s[i] == '"') break; From 5b4022921179ed0c2fff5c3e3c450533312b3327 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 5 Sep 2024 08:50:55 +0200 Subject: [PATCH 25/26] ParameterSystem: replace loop with standard algorithms --- opm/models/utils/parametersystem.cpp | 29 ++++++++++------------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index 464e38280..ceb2eae81 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -134,13 +134,10 @@ void getFlattenedKeyList(std::vector& dest, std::string parseKey(std::string& s) { - unsigned i; - for (i = 0; i < s.size(); ++ i) - if (std::isspace(s[i]) || s[i] == '=') - break; - - std::string ret = s.substr(0, i); - s = s.substr(i); + auto it = std::find_if(s.begin(), s.end(), + [](const char ch) { return std::isspace(ch) || ch == '='; }); + std::string ret {s.begin(), it}; + s.erase(s.begin(), it); return ret; } @@ -180,13 +177,9 @@ std::string parseQuotedValue(std::string& s, const std::string& errorPrefix) std::string parseUnquotedValue(std::string& s, const std::string&) { - unsigned i; - for (i = 0; i < s.size(); ++ i) - if (std::isspace(s[i])) - break; - - std::string ret = s.substr(0, i); - s = s.substr(i); + auto it = std::find_if(s.begin(), s.end(), ::isspace); + std::string ret{s.begin(), it}; + s.erase(s.begin(), it); return ret; } @@ -298,11 +291,9 @@ void printParamUsage(std::ostream& os, void removeLeadingSpace(std::string& s) { - unsigned i; - for (i = 0; i < s.size(); ++ i) - if (!std::isspace(s[i])) - break; - s = s.substr(i); + s.erase(s.begin(), + std::find_if(s.begin(), s.end(), + [](const char ch) { return !std::isspace(ch); })); } std::string transformKey(const std::string& s, From 462926a35671cb1ef8d901464aac291398196aad Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 5 Sep 2024 09:16:50 +0200 Subject: [PATCH 26/26] ParameterSystem: cosmetics --- opm/models/utils/parametersystem.cpp | 155 ++++++++++++++++----------- 1 file changed, 94 insertions(+), 61 deletions(-) diff --git a/opm/models/utils/parametersystem.cpp b/opm/models/utils/parametersystem.cpp index ceb2eae81..1dba9fa74 100644 --- a/opm/models/utils/parametersystem.cpp +++ b/opm/models/utils/parametersystem.cpp @@ -143,8 +143,9 @@ std::string parseKey(std::string& s) std::string parseQuotedValue(std::string& s, const std::string& errorPrefix) { - if (s.empty() || s[0] != '"') - throw std::runtime_error(errorPrefix+"Expected quoted string"); + if (s.empty() || s[0] != '"') { + throw std::runtime_error(errorPrefix + "Expected quoted string"); + } std::string result; unsigned i = 1; @@ -152,8 +153,9 @@ std::string parseQuotedValue(std::string& s, const std::string& errorPrefix) // handle escape characters if (s[i] == '\\') { ++i; - if (s.size() <= i) - throw std::runtime_error(errorPrefix+"Unexpected end of quoted string"); + if (s.size() <= i) { + throw std::runtime_error(errorPrefix + "Unexpected end of quoted string"); + } switch (s[i]) { case 'n': result += '\n'; break; @@ -165,10 +167,12 @@ std::string parseQuotedValue(std::string& s, const std::string& errorPrefix) "Unknown escape character '\\" + s[i] + "'"); } } - else if (s[i] == '"') + else if (s[i] == '"') { break; - else + } + else { result += s[i]; + } } s = s.substr(i+1); @@ -193,8 +197,9 @@ void printParamList(std::ostream& os, const auto& paramInfo = MetaData::registry().at(key); const std::string& defaultValue = paramInfo.defaultValue; std::string value = defaultValue; - if (tree.hasKey(key)) + if (tree.hasKey(key)) { value = tree.get(key, ""); + } os << key << "=\"" << value << "\""; if (printDefaults) os << " # default: \"" << defaultValue << "\""; @@ -213,8 +218,9 @@ void printParamUsage(std::ostream& os, std::string cmdLineName = "-"; const std::string camelCaseName = paramInfo.paramName; for (unsigned i = 0; i < camelCaseName.size(); ++i) { - if (isupper(camelCaseName[i])) + if (isupper(camelCaseName[i])) { cmdLineName += "-"; + } cmdLineName += static_cast(std::tolower(camelCaseName[i])); } @@ -236,15 +242,18 @@ void printParamUsage(std::ostream& os, #if HAVE_QUAD || paramInfo.paramTypeName == Dune::className() #endif // HAVE_QUAD - ) + ) { paramMessage += "=SCALAR"; + } else if (paramInfo.paramTypeName == Dune::className() || paramInfo.paramTypeName == Dune::className() || paramInfo.paramTypeName == Dune::className() - || paramInfo.paramTypeName == Dune::className()) + || paramInfo.paramTypeName == Dune::className()) { paramMessage += "=INTEGER"; - else if (paramInfo.paramTypeName == Dune::className()) + } + else if (paramInfo.paramTypeName == Dune::className()) { paramMessage += "=BOOLEAN"; + } else if (paramInfo.paramTypeName.empty()) { // the parameter is a flag. Do nothing! } @@ -264,22 +273,26 @@ void printParamUsage(std::ostream& os, // add the default value if (!paramInfo.paramTypeName.empty()) { - if (paramMessage.back() != '.') + if (paramMessage.back() != '.') { paramMessage += '.'; + } paramMessage += " Default: "; if (paramInfo.paramTypeName == "bool") { - if (paramInfo.defaultValue == "0") + if (paramInfo.defaultValue == "0") { paramMessage += "false"; - else + } + else { paramMessage += "true"; + } } else if (isString) { paramMessage += "\""; paramMessage += paramInfo.defaultValue; paramMessage += "\""; } - else + else { paramMessage += paramInfo.defaultValue; + } } paramMessage = Opm::Parameters::breakLines(paramMessage, /*indent=*/52, ttyWidth); @@ -302,28 +315,36 @@ std::string transformKey(const std::string& s, { std::string result; - if (s.empty()) - throw std::runtime_error(errorPrefix+"Empty parameter names are invalid"); + if (s.empty()) { + throw std::runtime_error(errorPrefix + "Empty parameter names are invalid"); + } - if (!std::isalpha(s[0])) - throw std::runtime_error(errorPrefix+"Parameter name '" + s + "' is invalid: First character must be a letter"); + if (!std::isalpha(s[0])) { + throw std::runtime_error(errorPrefix +" Parameter name '" + s + + "' is invalid: First character must be a letter"); + } - if (capitalizeFirstLetter) + if (capitalizeFirstLetter) { result += static_cast(std::toupper(s[0])); - else + } + else { result += s[0]; + } for (unsigned i = 1; i < s.size(); ++i) { if (s[i] == '-') { - ++ i; - if (s.size() <= i || !std::isalpha(s[i])) - throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); + ++i; + if (s.size() <= i || !std::isalpha(s[i])) { + throw std::runtime_error(errorPrefix + "Invalid parameter name '" + s + "'"); + } result += static_cast(std::toupper(s[i])); } - else if (!std::isalnum(s[i])) - throw std::runtime_error(errorPrefix+"Invalid parameter name '" + s + "'"); - else + else if (!std::isalnum(s[i])) { + throw std::runtime_error(errorPrefix + "Invalid parameter name '" + s + "'"); + } + else { result += s[i]; + } } return result; @@ -340,13 +361,14 @@ ParamType Get_(const std::string& paramName, ParamType defaultValue, bool errorIfNotRegistered) { if (errorIfNotRegistered) { - if (MetaData::registrationOpen()) + if (MetaData::registrationOpen()) { throw std::runtime_error("Parameters can only retrieved after _all_ of them have " "been registered."); + } if (MetaData::registry().find(paramName) == MetaData::registry().end()) { - throw std::runtime_error("Accessing parameter " + paramName - +" without prior registration is not allowed."); + throw std::runtime_error("Accessing parameter " + paramName + + " without prior registration is not allowed."); } } @@ -390,8 +412,8 @@ void Hide_(const std::string& paramName) auto paramInfoIt = MetaData::mutableRegistry().find(paramName); if (paramInfoIt == MetaData::mutableRegistry().end()) { - throw std::logic_error("Tried to declare unknown parameter '" - + paramName + "' hidden."); + throw std::logic_error("Tried to declare unknown parameter '" + + paramName + "' hidden."); } auto& paramInfo = paramInfoIt->second; @@ -406,14 +428,14 @@ bool IsSet_(const std::string& paramName, bool errorIfNotRegistered) "been registered."); } - if (MetaData::registry().find(paramName) == MetaData::registry().end()) + if (MetaData::registry().find(paramName) == MetaData::registry().end()) { throw std::runtime_error("Accessing parameter " + std::string(paramName) + " without prior registration is not allowed."); + } } // check whether the parameter is in the parameter tree return MetaData::tree().hasKey(paramName); - } void Register_(const std::string& paramName, @@ -438,8 +460,8 @@ void Register_(const std::string& paramName, if (MetaData::registry().at(paramName) == paramInfo) { return; } - throw std::logic_error("Parameter " + paramName - +" registered twice with non-matching characteristics."); + throw std::logic_error("Parameter " + paramName + + " registered twice with non-matching characteristics."); } MetaData::mutableRegistry()[paramName] = paramInfo; @@ -455,7 +477,7 @@ void SetDefault_(const std::string& paramName, MetaData::mutableRegistry()[paramName].defaultValue = paramValue; } -} +} // namespace detail std::string breakLines(const std::string& msg, int indentWidth, @@ -477,8 +499,9 @@ std::string breakLines(const std::string& msg, continue; } - if (std::isspace(msg[inPos])) + if (std::isspace(msg[inPos])) { lastBreakPos = inPos; + } if (ttyPos >= maxWidth) { if (lastBreakPos > startInPos) { @@ -495,8 +518,9 @@ std::string breakLines(const std::string& msg, } result += "\n"; - for (int i = 0; i < indentWidth; ++i) + for (int i = 0; i < indentWidth; ++i) { result += " "; + } ttyPos = indentWidth; } } @@ -578,8 +602,9 @@ void printUsage(const std::string& helpPreamble, } for (const auto& param : MetaData::registry()) { - if (showAll || !param.second.isHidden) + if (showAll || !param.second.isHidden) { printParamUsage(os, param.second); + } } } @@ -593,14 +618,15 @@ void parseParameterFile(const std::string& fileName, bool overwrite) std::string curLine; std::getline(ifs, curLine); curLineNum += 1; - std::string errorPrefix = fileName+":"+std::to_string(curLineNum)+": "; + std::string errorPrefix = fileName + ":" + std::to_string(curLineNum) + ": "; // strip leading white space removeLeadingSpace(curLine); // ignore empty and comment lines - if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') + if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') { continue; + } // TODO (?): support for parameter groups. @@ -608,32 +634,39 @@ void parseParameterFile(const std::string& fileName, bool overwrite) std::string key = parseKey(curLine); std::string canonicalKey = transformKey(key, /*capitalizeFirst=*/true, errorPrefix); - if (seenKeys.count(canonicalKey) > 0) - throw std::runtime_error(errorPrefix+"Parameter '"+canonicalKey+"' seen multiple times in the same file"); + if (seenKeys.count(canonicalKey) > 0) { + throw std::runtime_error(errorPrefix + "Parameter '" + canonicalKey + + "' seen multiple times in the same file"); + } seenKeys.insert(canonicalKey); // deal with the equals sign removeLeadingSpace(curLine); - if (curLine.empty() || curLine[0] != '=') + if (curLine.empty() || curLine[0] != '=') { std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); + } curLine = curLine.substr(1); removeLeadingSpace(curLine); - if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') + if (curLine.empty() || curLine[0] == '#' || curLine[0] == ';') { std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); + } // get the value std::string value; - if (curLine[0] == '"') + if (curLine[0] == '"') { value = parseQuotedValue(curLine, errorPrefix); - else + } + else { value = parseUnquotedValue(curLine, errorPrefix); + } // ignore trailing comments removeLeadingSpace(curLine); - if (!curLine.empty() && curLine[0] != '#' && curLine[0] != ';') - std::runtime_error(errorPrefix+"Syntax error, expecting 'key=value'"); + if (!curLine.empty() && curLine[0] != '#' && curLine[0] != ';') { + std::runtime_error(errorPrefix + "Syntax error, expecting 'key=value'"); + } // all went well, add the parameter to the database object if (overwrite || !MetaData::tree().hasKey(canonicalKey)) { @@ -650,8 +683,8 @@ std::string parseCommandLineOptions(int argc, // handle the "--help" parameter if (!helpPreamble.empty()) { for (int i = 1; i < argc; ++i) { - if (std::string("-h") == argv[i] - || std::string("--help") == argv[i]) { + if (std::string("-h") == argv[i] || + std::string("--help") == argv[i]) { printUsage(helpPreamble, std::cout, /*errorMsg=*/""); return "Help called"; } @@ -687,7 +720,7 @@ std::string parseCommandLineOptions(int argc, return errorMsg; } else { - ++ numPositionalParams; + ++numPositionalParams; i += numHandled - 1; continue; } @@ -719,9 +752,9 @@ std::string parseCommandLineOptions(int argc, // parse argument paramName = transformKey(parseKey(s), /*capitalizeFirst=*/true); if (seenKeys.count(paramName) > 0) { - std::string msg = - std::string("Parameter '")+paramName+"' specified multiple times as a " - "command line parameter"; + const std::string msg = "Parameter '" + paramName + + "' specified multiple times as a " + "command line parameter"; if (!helpPreamble.empty()) { printUsage(helpPreamble, std::cerr, msg); @@ -731,9 +764,9 @@ std::string parseCommandLineOptions(int argc, seenKeys.insert(paramName); if (s.empty() || s[0] != '=') { - std::string msg = - std::string("Parameter '")+paramName+"' is missing a value. " - +" Please use "+argv[i]+"=value."; + const std::string msg = "Parameter '" + paramName + + "' is missing a value. " + " Please use " + argv[i] + "=value."; if (!helpPreamble.empty()) { printUsage(helpPreamble, std::cerr, msg); @@ -773,7 +806,7 @@ void printValues(std::ostream& os) // check whether the key was specified at run-time if (MetaData::tree().hasKey(reg.first)) { continue; - } else { + } else { compileTimeKeyList.push_back(reg.first); } } @@ -854,6 +887,6 @@ template unsigned Get_(const std::string&, unsigned, bool); template quad Get_(const std::string&, quad, bool); #endif -} +} // namespace detail } // namespace Opm::Parameters