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