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