Parameters::Get split out parts of implementation

allows putting it in translation unit
This commit is contained in:
Arne Morten Kvarving 2024-09-02 14:19:33 +02:00
parent cfad87b41f
commit ae8dd62fe3
3 changed files with 111 additions and 78 deletions

View File

@ -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)

View File

@ -32,6 +32,10 @@
#include <config.h>
#include <opm/models/utils/parametersystem.hpp>
#if HAVE_QUAD
#include <opm/material/common/quad.hpp>
#endif
namespace {
std::string parseKey(std::string& s)
@ -143,6 +147,52 @@ namespace Opm::Parameters {
namespace detail {
template<class ParamType>
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<ParamType, std::string>) {
defaultValue = defVal;
}
else if constexpr (std::is_same_v<ParamType, bool>) {
defaultValue = defVal == "1";
}
#if HAVE_QUAD
else if constexpr (std::is_same_v<ParamType, quad>) {
defaultValue = std::strtold(defVal.data(), nullptr);
}
#endif
#if !HAVE_FLOATING_POINT_FROM_CHARS
else if constexpr (std::is_floating_point_v<ParamType>) {
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<ParamType>(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

View File

@ -84,6 +84,11 @@ auto getParamName()
}
}
//! \brief Private implementation.
template<class ParamType>
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 <class Param>
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 <class Param>
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 <class Param>
auto Get(bool errorIfNotRegistered)
auto Get(bool errorIfNotRegistered = true)
{
const std::string paramName = detail::getParamName<Param>();
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::is_same_v<decltype(Param::value),
const char* const>, std::string,
std::remove_const_t<decltype(Param::value)>>;
ParamType defaultValue = Param::value;
const std::string& defVal = MetaData::mutableRegistry()[paramName].defaultValue;
if constexpr (std::is_same_v<ParamType, std::string>) {
defaultValue = defVal;
}
else if constexpr (std::is_same_v<ParamType, bool>) {
defaultValue = defVal == "1";
}
#if HAVE_QUAD
else if constexpr (std::is_same_v<ParamType, quad>) {
defaultValue = std::strtold(defVal.data(), nullptr);
}
#endif
#if !HAVE_FLOATING_POINT_FROM_CHARS
else if constexpr (std::is_floating_point_v<ParamType>) {
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<ParamType>(paramName, defaultValue);
return detail::Get_(detail::getParamName<Param>(),
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 <class Param>
void SetDefault(decltype(Param::value) new_value)
{