OGS
ParameterLib/Parameter.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "Parameter.h"
5
7#include "BaseLib/Error.h"
8#include "BaseLib/Logging.h"
9#include "ConstantParameter.h"
11#include "FunctionParameter.h"
12#include "GroupBasedParameter.h"
14#include "MeshNodeParameter.h"
16#include "RasterParameter.h"
18
19namespace ParameterLib
20{
21std::unique_ptr<ParameterBase> createParameter(
22 BaseLib::ConfigTree const& config,
23 std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes,
24 std::vector<GeoLib::NamedRaster> const& named_rasters,
25 std::map<std::string,
26 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
27 curves)
28{
30 auto const name = config.getConfigParameter<std::string>("name");
32 auto const type = config.peekConfigParameter<std::string>("type");
33
34 // Either the mesh name is given, or the first mesh's name will be
35 // taken.
36 auto const mesh_name =
38 config.getConfigParameter<std::string>("mesh", meshes[0]->getName());
39
40 auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
41
42 // Create parameter based on the provided type.
43 if (type == "Constant")
44 {
45 INFO("ConstantParameter: {:s}", name);
46 return createConstantParameter(name, config);
47 }
48 if (type == "CurveScaled")
49 {
50 INFO("CurveScaledParameter: {:s}", name);
51 return createCurveScaledParameter(name, config, curves);
52 }
53 if (type == "Function")
54 {
55 INFO("FunctionParameter: {:s}", name);
56 return createFunctionParameter(name, config, curves);
57 }
58 if (type == "Group")
59 {
60 INFO("GroupBasedParameter: {:s}", name);
61 return createGroupBasedParameter(name, config, mesh);
62 }
63 if (type == "MeshElement")
64 {
65 INFO("MeshElementParameter: {:s}", name);
66 return createMeshElementParameter(name, config, mesh);
67 }
68 if (type == "MeshNode")
69 {
70 INFO("MeshNodeParameter: {:s}", name);
71 return createMeshNodeParameter(name, config, mesh);
72 }
73 if (type == "RandomFieldMeshElement")
74 {
75 auto& mesh_var = MeshLib::findMeshByName(meshes, mesh_name);
76 INFO("RandomFieldMeshElement: {:s}", name);
77 return createRandomFieldMeshElementParameter(name, config, mesh_var);
78 }
79 if (type == "Raster")
80 {
81 INFO("RasterParameter: {:s}", name);
82 return createRasterParameter(name, config, named_rasters);
83 }
84 if (type == "TimeDependentHeterogeneous" ||
85 type == "TimeDependentHeterogeneousParameter")
86 {
87 if (type == "TimeDependentHeterogeneousParameter")
88 {
89 WARN(
90 "Parameter type 'TimeDependentHeterogeneousParameter' is "
91 "deprecated. Use 'TimeDependentHeterogeneous' instead. "
92 "The old type name will be removed in a future release.");
93 }
94 INFO("TimeDependentHeterogeneous: {:s}", name);
96 }
97
98 OGS_FATAL("Cannot construct a parameter of given type '{:s}'.", type);
99}
100
101std::optional<std::string> isDefinedOnSameMesh(ParameterBase const& parameter,
102 MeshLib::Mesh const& mesh)
103{
104 // Arbitrary domain of definition.
105 if (parameter.mesh() == nullptr)
106 {
107 return {};
108 }
109
110 // Equal meshes.
111 if (*parameter.mesh() == mesh)
112 {
113 return {};
114 }
115
116 return "The parameter's domain of definition mesh '" +
117 parameter.mesh()->getName() + "' differs from the used mesh '" +
118 mesh.getName() +
119 "'. The same mesh (the same name) has to be referenced in the "
120 "project file. Possible reasons are:\n - the parameter used for the "
121 "initial condition is not defined on the bulk mesh,\n - the "
122 "parameter's domain of definition mesh differs from the boundary "
123 "condition or source term domain of definition mesh.";
124}
125
127 std::string const& parameter_or_value,
128 std::vector<std::unique_ptr<ParameterBase>>& parameters,
129 std::string const& property_name,
130 std::string const& inline_suffix)
131{
132 // try to parse number(s) (if empty - no inline-values)
133 std::size_t bad_idx = 0;
134 if (auto values =
135 BaseLib::tryParseVector<double>(parameter_or_value, &bad_idx);
136 values)
137 {
138 if (values->empty())
139 {
140 OGS_FATAL(
141 "Empty inline value list for property '{:s}'. "
142 "Provide at least one numeric value (e.g., \"1.23 4.56\") or "
143 "specify the name of an existing parameter. "
144 "Raw input was: \"{:s}\".",
145 property_name, parameter_or_value);
146 }
147
148 // collect all existing parameter names for checks against uniqueness
149 std::vector<std::string> existing_names;
150 existing_names.reserve(parameters.size());
151 std::transform(parameters.begin(), parameters.end(),
152 std::back_inserter(existing_names),
153 [](auto const& p) { return p->name; });
154
155 // assign inline values as constant parameter
156 std::string pname = BaseLib::getUniqueName(
157 existing_names, property_name + "_" + inline_suffix);
159 parameters.push_back(std::make_unique<P>(pname, std::move(*values)));
160 return static_cast<Parameter<double>&>(*parameters.back());
161 }
162
163 // No inline values -> 'parameter_or_value' is just a parameter name, now
164 // find that parameter.
165 return findParameter<double>(parameter_or_value, parameters, 0, nullptr);
166}
167} // namespace ParameterLib
#define OGS_FATAL(...)
Definition Error.h:10
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
T peekConfigParameter(std::string const &param) const
T getConfigParameter(std::string const &param) const
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:95
std::optional< std::vector< T > > tryParseVector(std::string const &raw, std::size_t *bad_token_idx)
Definition StringTools.h:86
std::string getUniqueName(std::vector< std::string > const &existing_names, std::string const &input_name)
Append '-' and a number such that the name is unique.
Mesh & findMeshByName(std::vector< std::unique_ptr< Mesh > > const &meshes, std::string_view const name)
Definition Mesh.cpp:356
std::unique_ptr< ParameterBase > createRasterParameter(std::string const &name, BaseLib::ConfigTree const &config, std::vector< GeoLib::NamedRaster > const &named_rasters)
std::unique_ptr< ParameterBase > createTimeDependentHeterogeneousParameter(std::string const &name, BaseLib::ConfigTree const &config)
std::optional< std::string > isDefinedOnSameMesh(ParameterBase const &parameter, MeshLib::Mesh const &mesh)
std::unique_ptr< ParameterBase > createParameter(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes, std::vector< GeoLib::NamedRaster > const &named_rasters, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
std::unique_ptr< ParameterBase > createGroupBasedParameter(std::string const &name, BaseLib::ConfigTree const &config, MeshLib::Mesh const &mesh)
std::unique_ptr< ParameterBase > createMeshElementParameter(std::string const &name, BaseLib::ConfigTree const &config, MeshLib::Mesh const &mesh)
OGS_NO_DANGLING Parameter< ParameterDataType > & findParameter(std::string const &parameter_name, std::vector< std::unique_ptr< ParameterBase > > const &parameters, int const num_components, MeshLib::Mesh const *const mesh=nullptr)
std::unique_ptr< ParameterBase > createCurveScaledParameter(std::string const &name, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
std::unique_ptr< ParameterBase > createConstantParameter(std::string const &name, BaseLib::ConfigTree const &config)
std::unique_ptr< ParameterBase > createRandomFieldMeshElementParameter(std::string const &name, BaseLib::ConfigTree const &config, MeshLib::Mesh &mesh)
std::unique_ptr< ParameterBase > createFunctionParameter(std::string const &name, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
Parameter< double > & getNamedOrCreateInlineParameter(std::string const &parameter_or_value, std::vector< std::unique_ptr< ParameterBase > > &parameters, std::string const &property_name, std::string const &inline_suffix)
std::unique_ptr< ParameterBase > createMeshNodeParameter(std::string const &name, BaseLib::ConfigTree const &config, MeshLib::Mesh const &mesh)
Single, constant value parameter.
MeshLib::Mesh const * mesh() const