OGS
Function.cpp
Go to the documentation of this file.
1 
11 
12 #include <numeric>
13 
14 #include "BaseLib/Algorithm.h"
15 
16 namespace MaterialPropertyLib
17 {
18 // Passing symbol table by reference as required by register_symbol_table()
19 // call.
20 template <typename T>
21 static std::vector<exprtk::expression<T>> compileExpressions(
22  exprtk::symbol_table<T>& symbol_table,
23  std::vector<std::string> const& string_expressions)
24 {
25  exprtk::parser<T> parser;
26 
27  std::vector<exprtk::expression<T>> expressions(string_expressions.size());
28  expressions.resize(string_expressions.size());
29  for (unsigned i = 0; i < string_expressions.size(); ++i)
30  {
31  expressions[i].register_symbol_table(symbol_table);
32  if (!parser.compile(string_expressions[i], expressions[i]))
33  {
34  OGS_FATAL("Error: {:s}\tExpression: {:s}\n",
35  parser.error(),
36  string_expressions[i]);
37  }
38  }
39  return expressions;
40 }
41 
43  std::vector<std::pair<int, double*>> const& symbol_values,
44  VariableArray const& variable_array)
45 {
46  for (auto& index_value_ptr_pair : symbol_values)
47  {
48  auto const index = index_value_ptr_pair.first;
49 
50  double* value_ptr = index_value_ptr_pair.second;
51  std::visit(
52  [&value_ptr, &index](auto&& v)
53  {
54  using T = std::decay_t<decltype(v)>;
55  if constexpr (std::is_same_v<T, std::monostate>)
56  {
57  OGS_FATAL(
58  "Function property: variable {:s} value needed for "
59  "evaluation of the expression was not set by the "
60  "caller.",
62  }
63  else if constexpr (std::is_same_v<T, double>)
64  {
65  *value_ptr = v;
66  }
67  else
68  {
69  OGS_FATAL(
70  "Function property: not implemented handling for a "
71  "type {:s} of variable {:s}.",
72  typeid(T).name(), variable_enum_to_string[index]);
73  }
74  },
75  variable_array[index]);
76  }
77 }
78 
80  std::vector<std::pair<int, double*>> const& symbol_values,
81  VariableArray const& variable_array,
82  std::vector<exprtk::expression<double>> const& expressions)
83 {
84  updateVariableValues(symbol_values, variable_array);
85 
86  std::vector<double> result(expressions.size());
87  std::transform(begin(expressions), end(expressions), begin(result),
88  [](auto const& e) { return e.value(); });
89 
90  switch (result.size())
91  {
92  case 1:
93  {
94  return result[0];
95  }
96  case 2:
97  {
98  return Eigen::Vector2d{result[0], result[1]};
99  }
100  case 3:
101  {
102  return Eigen::Vector3d{result[0], result[1], result[2]};
103  }
104  case 4:
105  {
106  Eigen::Matrix<double, 2, 2> m;
107  m = Eigen::Map<Eigen::Matrix<double, 2, 2> const>(result.data(), 2,
108  2);
109  return m;
110  }
111  case 9:
112  {
113  Eigen::Matrix<double, 3, 3> m;
114  m = Eigen::Map<Eigen::Matrix<double, 3, 3> const>(result.data(), 3,
115  3);
116  return m;
117  }
118  }
119  OGS_FATAL("Cannot convert a vector of size {} to a PropertyDataType",
120  result.size());
121 }
122 
123 static std::vector<std::string> collectVariables(
124  std::vector<std::string> const& value_string_expressions,
125  std::vector<std::pair<std::string, std::vector<std::string>>> const&
126  dvalue_string_expressions)
127 {
128  std::vector<std::string> variables;
129 
130  auto collect_variables = [&](auto string_expressions)
131  {
132  for (auto const& string_expression : string_expressions)
133  {
134  if (!exprtk::collect_variables(string_expression, variables))
135  {
136  OGS_FATAL("Collecting variables didn't work.");
137  }
138  }
139  };
140 
141  collect_variables(value_string_expressions);
142  for (auto const& var_name_string_expression : dvalue_string_expressions)
143  {
144  collect_variables(var_name_string_expression.second);
145  }
146 
147  BaseLib::makeVectorUnique(variables);
148  return variables;
149 }
150 
152  std::string name,
153  std::vector<std::string> const& value_string_expressions,
154  std::vector<std::pair<std::string, std::vector<std::string>>> const&
155  dvalue_string_expressions)
156 {
157  name_ = std::move(name);
158 
159  // Create symbol table for used variables.
160  exprtk::symbol_table<double> symbol_table;
161 
162  for (auto const& v :
163  collectVariables(value_string_expressions, dvalue_string_expressions))
164  {
165  symbol_table.create_variable(v);
166  // Store variables index in the variable array and the pointer to the
167  // value in the symbol table for fast access later.
168  int const variable_array_index =
169  static_cast<int>(convertStringToVariable(v));
170  symbol_values_.emplace_back(variable_array_index,
171  &symbol_table.get_variable(v)->ref());
172  }
173 
174  // value expressions.
176  compileExpressions(symbol_table, value_string_expressions);
177 
178  // dValue expressions.
179  for (auto const& [variable_name, string_expressions] :
180  dvalue_string_expressions)
181  {
182  dvalue_expressions_.emplace_back(
183  convertStringToVariable(variable_name),
184  compileExpressions(symbol_table, string_expressions));
185  }
186 }
187 
189  ParameterLib::SpatialPosition const& /*pos*/,
190  double const /*t*/, double const /*dt*/) const
191 {
192  return evaluateExpressions(symbol_values_, variable_array,
194 }
195 
197  Variable const primary_variable,
198  ParameterLib::SpatialPosition const& /*pos*/,
199  double const /*t*/, double const /*dt*/) const
200 {
201  auto const it = std::find_if(begin(dvalue_expressions_),
202  end(dvalue_expressions_),
203  [&primary_variable](auto const& v)
204  { return v.first == primary_variable; });
205 
206  if (it == end(dvalue_expressions_))
207  {
208  OGS_FATAL(
209  "Requested derivative with respect to the variable {:s} not "
210  "provided for Function-type property {:s}.",
211  variable_enum_to_string[static_cast<int>(primary_variable)], name_);
212  }
213 
214  return evaluateExpressions(symbol_values_, variable_array, it->second);
215 }
216 
217 } // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition: Error.h:26
PropertyDataType dValue(VariableArray const &variable_array, Variable const primary_variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
Definition: Function.cpp:196
std::vector< std::pair< int, double * > > symbol_values_
Mapping from variable array index to symbol table values.
Definition: Function.h:50
std::vector< Expression > value_expressions_
Definition: Function.h:53
Function(std::string name, std::vector< std::string > const &value_string_expressions, std::vector< std::pair< std::string, std::vector< std::string >>> const &dvalue_string_expressions)
Definition: Function.cpp:151
std::vector< std::pair< Variable, std::vector< Expression > > > dvalue_expressions_
Definition: Function.h:57
virtual PropertyDataType value() const
Definition: Property.cpp:72
void makeVectorUnique(std::vector< T > &v)
Definition: Algorithm.h:209
static PropertyDataType evaluateExpressions(std::vector< std::pair< int, double * >> const &symbol_values, VariableArray const &variable_array, std::vector< exprtk::expression< double >> const &expressions)
Definition: Function.cpp:79
static const std::array< std::string, static_cast< int >Variable::number_of_variables)> variable_enum_to_string
Definition: VariableType.h:74
std::variant< double, Eigen::Matrix< double, 2, 1 >, Eigen::Matrix< double, 3, 1 >, Eigen::Matrix< double, 2, 2 >, Eigen::Matrix< double, 3, 3 >, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 > > PropertyDataType
Definition: Property.h:35
static std::vector< exprtk::expression< T > > compileExpressions(exprtk::symbol_table< T > &symbol_table, std::vector< std::string > const &string_expressions)
Definition: Function.cpp:21
std::array< VariableType, static_cast< int >(Variable::number_of_variables)> VariableArray
Definition: VariableType.h:108
static std::vector< std::string > collectVariables(std::vector< std::string > const &value_string_expressions, std::vector< std::pair< std::string, std::vector< std::string >>> const &dvalue_string_expressions)
Definition: Function.cpp:123
Variable convertStringToVariable(std::string const &string)
static void updateVariableValues(std::vector< std::pair< int, double * >> const &symbol_values, VariableArray const &variable_array)
Definition: Function.cpp:42