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