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