OGS
ParameterLib/Parameter.h
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#pragma once
5
6#include <Eigen/Core>
7#include <map>
8#include <memory>
9#include <optional>
10#include <utility>
11#include <vector>
12
13#include "BaseLib/Error.h"
14#include "CoordinateSystem.h"
15#include "GeoLib/Raster.h"
17#include "MeshLib/Node.h"
18#include "SpatialPosition.h"
19
20namespace BaseLib
21{
22class ConfigTree;
23} // namespace BaseLib
24
25namespace MathLib
26{
28} // namespace MathLib
29
30namespace MeshLib
31{
32class Mesh;
33} // namespace MeshLib
34
35namespace ParameterLib
36{
41{
42 explicit ParameterBase(std::string name_,
43 MeshLib::Mesh const* mesh = nullptr)
44 : name(std::move(name_)), _mesh(mesh)
45 {
46 }
47
48 virtual ~ParameterBase() = default;
49
50 virtual bool isTimeDependent() const = 0;
51
52 void setCoordinateSystem(CoordinateSystem const& coordinate_system)
53 {
54 _coordinate_system = coordinate_system;
55 }
56
59 virtual void initialize(
60 std::vector<std::unique_ptr<ParameterBase>> const& /*parameters*/)
61 {
62 }
63
64 MeshLib::Mesh const* mesh() const { return _mesh; }
65
66 std::string const name;
67
68protected:
69 std::vector<double> rotateWithCoordinateSystem(
70 std::vector<double> const& values, SpatialPosition const& pos) const
71 {
72 assert(!!_coordinate_system); // It is checked before calling this
73 // function.
74
75 // Don't rotate isotropic/scalar values.
76 if (values.size() == 1)
77 {
78 return {values[0]};
79 }
80 if (values.size() == 2)
81 {
82 auto const result =
83 _coordinate_system->rotateDiagonalTensor<2>(values, pos);
84 return {result(0, 0), result(0, 1), result(1, 0), result(1, 1)};
85 }
86 if (values.size() == 3)
87 {
88 auto const result =
89 _coordinate_system->rotateDiagonalTensor<3>(values, pos);
90 return {
91 result(0, 0), result(0, 1), result(0, 2),
92 result(1, 0), result(1, 1), result(1, 2),
93 result(2, 0), result(2, 1), result(2, 2),
94 };
95 }
96 if (values.size() == 4)
97 {
98 auto const result =
99 _coordinate_system->rotateTensor<2>(values, pos);
100 return {result(0, 0), result(0, 1), result(1, 0), result(1, 1)};
101 }
102 if (values.size() == 9)
103 {
104 auto const result =
105 _coordinate_system->rotateTensor<3>(values, pos);
106 return {
107 result(0, 0), result(0, 1), result(0, 2),
108 result(1, 0), result(1, 1), result(1, 2),
109 result(2, 0), result(2, 1), result(2, 2),
110 };
111 }
112 OGS_FATAL(
113 "Coordinate transformation for a {:d}-component parameter is not "
114 "implemented.",
115 values.size());
116 }
117
118protected:
119 std::optional<CoordinateSystem> _coordinate_system;
120
124};
125
132template <typename T>
134{
136
137 ~Parameter() override = default;
138
141 virtual int getNumberOfGlobalComponents() const = 0;
142
144 virtual std::vector<T> operator()(double const t,
145 SpatialPosition const& pos) const = 0;
146
148 //
149 // The matrix is of the shape NxC, where N is the number of nodes and C is
150 // the number of components, such that subsequent multiplication with shape
151 // functions matrix from left (which is a row vector) results in a row
152 // vector of length C.
153 //
154 // The default implementation covers all cases, but the derived classes may
155 // provide faster implementations.
156 virtual Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
158 double const t) const
159 {
160 auto const n_nodes = static_cast<int>(element.getNumberOfNodes());
161 auto const n_components = getNumberOfGlobalComponents();
162 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> result(n_nodes,
163 n_components);
164
165 // Column vector of values, copied for each node.
166 auto const nodes = element.getNodes();
167 for (int i = 0; i < n_nodes; ++i)
168 {
169 SpatialPosition const x_position{nodes[i]->getID(), element.getID(),
170 *nodes[i]};
171 auto const& values = this->operator()(t, x_position);
172 auto const row_values =
173 Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> const>(
174 values.data(), values.size());
175 result.row(i) = row_values;
176 }
177
178 return result;
179 }
180};
181
187std::unique_ptr<ParameterBase> createParameter(
188 BaseLib::ConfigTree const& config,
189 const std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes,
190 std::vector<GeoLib::NamedRaster> const& named_rasters,
191 std::map<std::string,
192 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
193 curves);
194
201std::optional<std::string> isDefinedOnSameMesh(ParameterBase const& parameter,
202 MeshLib::Mesh const& mesh);
203
221Parameter<double>& getNamedOrCreateInlineParameter(
222 BaseLib::ConfigTree const& config,
223 std::vector<std::unique_ptr<ParameterBase>>& parameters,
224 std::string const& property_name,
225 std::string const& tag_name,
226 std::string const& inline_suffix);
227
228} // namespace ParameterLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual unsigned getNumberOfNodes() const =0
virtual Node *const * getNodes() const =0
Get array of element nodes.
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:80
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)
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)
A local coordinate system used for tensor transformations.
virtual bool isTimeDependent() const =0
MeshLib::Mesh const * mesh() const
virtual void initialize(std::vector< std::unique_ptr< ParameterBase > > const &)
std::vector< double > rotateWithCoordinateSystem(std::vector< double > const &values, SpatialPosition const &pos) const
ParameterBase(std::string name_, MeshLib::Mesh const *mesh=nullptr)
std::optional< CoordinateSystem > _coordinate_system
void setCoordinateSystem(CoordinateSystem const &coordinate_system)
virtual ~ParameterBase()=default
~Parameter() override=default
ParameterBase(std::string name_, MeshLib::Mesh const *mesh=nullptr)
virtual int getNumberOfGlobalComponents() const =0
virtual Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > getNodalValuesOnElement(MeshLib::Element const &element, double const t) const
Returns a matrix of values for all nodes of the given element.
virtual std::vector< T > operator()(double const t, SpatialPosition const &pos) const =0
Returns the parameter value at the given time and position.