OGS
FunctionParameter.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <exprtk.hpp>
14#include <utility>
15#include <vector>
16
18#include "Parameter.h"
19#include "Utils.h"
20
21namespace ParameterLib
22{
28template <typename T>
29struct FunctionParameter final : public Parameter<T>
30{
31 class CurveWrapper : public exprtk::ifunction<T>
32 {
33 public:
34 explicit CurveWrapper(
36 : exprtk::ifunction<T>(1), _curve(curve)
37 {
38 exprtk::disable_has_side_effects(*this);
39 }
40 double operator()(double const& t) override
41 {
42 return _curve.getValue(t);
43 }
44
45 private:
47 };
48
49 using symbol_table_t = exprtk::symbol_table<T>;
50 using expression_t = exprtk::expression<T>;
51 using parser_t = exprtk::parser<T>;
52
62 std::string const& name,
63 std::vector<std::string> const& vec_expression_str,
64 std::map<std::string,
65 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
66 curves)
67 : Parameter<T>(name, nullptr)
68 {
69 // Convert curves to function objects callable by the exprtk.
70 _curves.reserve(curves.size());
71 std::transform(
72 begin(curves), end(curves), std::back_inserter(_curves),
73 [](auto const& curve) -> std::pair<std::string, CurveWrapper> {
74 return {curve.first, CurveWrapper(*curve.second)};
75 });
76
77 // Create symbol table for variables and functions.
78 _symbol_table.add_constants();
79 _symbol_table.create_variable("x");
80 _symbol_table.create_variable("y");
81 _symbol_table.create_variable("z");
82 _symbol_table.create_variable("t");
83 for (auto& curve : _curves)
84 {
85 _symbol_table.add_function(curve.first, curve.second);
86 }
87
88 // Compile expressions.
89 _vec_expression.resize(vec_expression_str.size());
90 for (unsigned i = 0; i < vec_expression_str.size(); i++)
91 {
92 _vec_expression[i].register_symbol_table(_symbol_table);
93 parser_t parser;
94 if (!parser.compile(vec_expression_str[i], _vec_expression[i]))
95 {
96 OGS_FATAL("Error: {:s}\tExpression: {:s}\n",
97 parser.error(),
98 vec_expression_str[i]);
99 }
100 }
101 }
102
103 bool isTimeDependent() const override { return true; }
104
105 int getNumberOfGlobalComponents() const override
106 {
107 return _vec_expression.size();
108 }
109
110 std::vector<T> operator()(double const t,
111 SpatialPosition const& pos) const override
112 {
113 std::vector<T> cache(getNumberOfGlobalComponents());
114 auto& x = _symbol_table.get_variable("x")->ref();
115 auto& y = _symbol_table.get_variable("y")->ref();
116 auto& z = _symbol_table.get_variable("z")->ref();
117 auto& time = _symbol_table.get_variable("t")->ref();
118 if (!pos.getCoordinates())
119 {
120 OGS_FATAL(
121 "FunctionParameter: The spatial position has to be set by "
122 "coordinates.");
123 }
124 auto const coords = pos.getCoordinates().value();
125
126 {
127 std::lock_guard lock_guard(_mutex);
128 x = coords[0];
129 y = coords[1];
130 z = coords[2];
131 time = t;
132
133 {
134 for (unsigned i = 0; i < _vec_expression.size(); i++)
135 {
136 cache[i] = _vec_expression[i].value();
137 }
138 }
139 }
140
141 if (!this->_coordinate_system)
142 {
143 return cache;
144 }
145
146 return this->rotateWithCoordinateSystem(cache, pos);
147 }
148
149private:
151 std::vector<expression_t> _vec_expression;
152 std::vector<std::pair<std::string, CurveWrapper>> _curves;
153 mutable std::mutex _mutex;
154};
155
156std::unique_ptr<ParameterBase> createFunctionParameter(
157 std::string const& name,
158 BaseLib::ConfigTree const& config,
159 std::map<std::string,
160 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
161 curves);
162
163} // namespace ParameterLib
#define OGS_FATAL(...)
Definition Error.h:26
Definition of the PiecewiseLinearInterpolation class.
double getValue(double pnt_to_interpolate) const
Calculates the interpolation value.
MathLib::PiecewiseLinearInterpolation const & _curve
CurveWrapper(MathLib::PiecewiseLinearInterpolation const &curve)
double operator()(double const &t) override
std::optional< MathLib::Point3d > const & getCoordinates() const
std::unique_ptr< ParameterBase > createFunctionParameter(std::string const &name, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
exprtk::symbol_table< T > symbol_table_t
exprtk::expression< T > expression_t
bool isTimeDependent() const override
std::vector< T > operator()(double const t, SpatialPosition const &pos) const override
Returns the parameter value at the given time and position.
std::vector< std::pair< std::string, CurveWrapper > > _curves
FunctionParameter(std::string const &name, std::vector< std::string > const &vec_expression_str, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
std::vector< expression_t > _vec_expression
int getNumberOfGlobalComponents() const override
std::string const name
Definition Parameter.h:73
std::vector< double > rotateWithCoordinateSystem(std::vector< double > const &values, SpatialPosition const &pos) const
Definition Parameter.h:76
std::optional< CoordinateSystem > _coordinate_system
Definition Parameter.h:126