14#include <range/v3/range/conversion.hpp>
15#include <range/v3/view/transform.hpp>
18#include <unordered_set>
30 exprtk::symbol_table<T>& symbol_table,
31 std::vector<std::string>
const& string_expressions)
33 exprtk::parser<T> parser;
35 std::vector<exprtk::expression<T>> expressions(string_expressions.size());
36 for (
unsigned i = 0; i < string_expressions.size(); ++i)
38 expressions[i].register_symbol_table(symbol_table);
39 if (!parser.compile(string_expressions[i], expressions[i]))
41 OGS_FATAL(
"Error: {:s}\tExpression: {:s}\n",
43 string_expressions[i]);
50class Function::Implementation
57 std::vector<std::string>
const& variables,
58 std::vector<std::string>
const& value_string_expressions,
59 std::vector<std::pair<std::string, std::vector<std::string>>>
const&
60 dvalue_string_expressions);
66 std::vector<std::string>
const& variables);
75 std::vector<std::pair<Variable, std::vector<Expression>>>
87 std::vector<std::string>
const& variables)
89 exprtk::symbol_table<double> symbol_table;
90 symbol_table.add_constants();
92 symbol_table.create_variable(
"t");
94 for (
auto const& v : variables)
98 symbol_table.create_variable(
"t");
102 symbol_table.create_variable(
"x");
103 spatial_position_is_required =
true;
107 symbol_table.create_variable(
"y");
108 spatial_position_is_required =
true;
112 symbol_table.create_variable(
"z");
113 spatial_position_is_required =
true;
117 auto add_scalar = [&v, &symbol_table](
double& value)
118 { symbol_table.add_variable(v, value); };
121 [&v, &symbol_table](
double* ptr, std::size_t
const size)
122 { symbol_table.add_vector(v, ptr, size); };
126 { add_scalar(*address); },
129 auto constexpr size =
131 auto& result = address->template emplace<
132 Eigen::Matrix<double, size, 1>>();
133 add_vector(result.data(), size);
138 auto& result = address->template emplace<
139 Eigen::Matrix<double, size, 1>>();
140 add_vector(result.data(), size);
144 variable_array.visitVariable(add_any_variable, variable);
152 std::vector<std::string>
const& variables,
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)
157 auto symbol_table = createSymbolTable(variables);
164 for (
auto const& [variable_name, string_expressions] :
165 dvalue_string_expressions)
167 dvalue_expressions.emplace_back(
177 for (
auto const& variable : variables)
182 double const value = *std::get<VariableArray::Scalar const*>(
185 if (std::isnan(value))
188 "Function property: Scalar variable '{:s}' is not "
195 auto assign_kelvin_vector = [&variable, &new_variable_array](
198 auto assign_value = [&destination = *address,
199 &variable]<
typename S>(S
const& source)
201 if constexpr (std::is_same_v<S, std::monostate>)
204 "Function property: Kelvin vector variable '{:s}' is "
210 if (std::holds_alternative<S>(destination))
218 "Function property: Mismatch of Kelvin vector "
219 "sizes for variable {:s}.",
225 std::visit(assign_value,
226 *std::get<VariableArray::KelvinVector const*>(
229 auto assign_deformation_gradient =
233 auto assign_value = [&destination = *address,
234 &variable]<
typename S>(S
const& source)
236 if constexpr (std::is_same_v<S, std::monostate>)
239 "Function property: Vectorized tensor variable '{:s}' "
240 "is not initialized.",
245 if (std::holds_alternative<S>(destination))
247 std::get<S>(destination) = source;
252 "Function property: Mismatch of vectorized tensor "
253 "sizes for variable {:s}.",
259 std::visit(assign_value,
260 *std::get<VariableArray::DeformationGradient const*>(
266 assign_deformation_gradient},
272 std::vector<Variable>
const& variables,
275 std::vector<exprtk::expression<double>>
const& expressions,
277 bool const spatial_position_is_required)
279 std::vector<double> result(expressions.size());
282 std::lock_guard lock_guard(mutex);
287 begin(expressions), end(expressions), begin(result),
288 [t, &pos, spatial_position_is_required](
auto const& e)
290 auto& symbol_table = e.get_symbol_table();
291 symbol_table.get_variable(
"t")->ref() = t;
293 if (spatial_position_is_required)
298 "FunctionParameter: The spatial position "
303 symbol_table.get_variable(
"x")->ref() = coords[0];
304 symbol_table.get_variable(
"y")->ref() = coords[1];
305 symbol_table.get_variable(
"z")->ref() = coords[2];
312 switch (result.size())
320 return Eigen::Vector2d{result[0], result[1]};
324 return Eigen::Vector3d{result[0], result[1], result[2]};
328 Eigen::Matrix<double, 2, 2> m;
329 m = Eigen::Map<Eigen::Matrix<double, 2, 2>
const>(result.data(), 2,
335 Eigen::Matrix<double, 3, 3> m;
336 m = Eigen::Map<Eigen::Matrix<double, 3, 3>
const>(result.data(), 3,
341 OGS_FATAL(
"Cannot convert a vector of size {} to a PropertyDataType",
346 std::vector<std::string>
const& value_string_expressions,
347 std::vector<std::pair<std::string, std::vector<std::string>>>
const&
348 dvalue_string_expressions)
350 std::vector<std::string> variables;
352 auto collect_variables = [&](
auto string_expressions)
354 for (
auto const& string_expression : string_expressions)
356 if (!exprtk::collect_variables(string_expression, variables))
359 "Collecting variables from expression '{}' didn't work.",
365 collect_variables(value_string_expressions);
366 for (
auto const& var_name_string_expression : dvalue_string_expressions)
368 collect_variables(var_name_string_expression.second);
377 std::vector<std::string>
const& value_string_expressions,
378 std::vector<std::pair<std::string, std::vector<std::string>>>
const&
379 dvalue_string_expressions)
383 auto const variables =
387 static const std::unordered_set<std::string> filter_not_variables = {
391 std::views::filter([](
const std::string& s)
392 {
return !filter_not_variables.contains(s); }) |
393 std::views::transform([](std::string
const& s)
395 ranges::to<std::vector>;
397 impl2_ = std::make_unique<Implementation<2>>(
398 variables, value_string_expressions, dvalue_string_expressions);
399 impl3_ = std::make_unique<Implementation<3>>(
400 variables, value_string_expressions, dvalue_string_expressions);
407 if (variable_array.
is2D())
411 if (variable_array.
is3D())
417 "Variable array has vectors for 2 and 3 dimensions simultaneously. "
418 "Mixed dimensions cannot be dealt within Function evaluation.");
423 double const t,
double const )
const
429 impl_ptr->value_expressions,
430 impl_ptr->variable_array,
mutex_,
431 impl_ptr->spatial_position_is_required);
439 double const t,
double const )
const
444 auto const it = std::find_if(begin(impl_ptr->dvalue_expressions),
445 end(impl_ptr->dvalue_expressions),
446 [&variable](
auto const& v)
447 { return v.first == variable; });
449 if (it == end(impl_ptr->dvalue_expressions))
452 "Requested derivative with respect to the variable {:s} "
454 "provided for Function-type property {:s}.",
459 it->second, impl_ptr->variable_array,
461 impl_ptr->spatial_position_is_required);
std::vector< Expression > value_expressions
VariableArray variable_array
bool spatial_position_is_required
Implementation(std::vector< std::string > const &variables, std::vector< std::string > const &value_string_expressions, std::vector< std::pair< std::string, std::vector< std::string > > > const &dvalue_string_expressions)
exprtk::symbol_table< double > createSymbolTable(std::vector< std::string > const &variables)
std::vector< std::pair< Variable, std::vector< Expression > > > dvalue_expressions
exprtk::expression< double > Expression
std::unique_ptr< Implementation< 3 > > impl3_
std::vector< Variable > variables_
Variables used in the exprtk expressions.
std::variant< Function::Implementation< 2 > *, Function::Implementation< 3 > * > getImplementationForDimensionOfVariableArray(VariableArray const &variable_array) const
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)
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
std::unique_ptr< Implementation< 2 > > impl2_
virtual PropertyDataType value() const
std::variant< std::monostate, Eigen::Vector< double, 5 >, Eigen::Vector< double, 9 > > DeformationGradient
std::variant< std::monostate, Eigen::Vector< double, 4 >, Eigen::Vector< double, 6 > > KelvinVector
VariablePointerConst address_of(Variable const v) const
auto visitVariable(Visitor &&visitor, Variable const variable)
std::optional< MathLib::Point3d > const getCoordinates() const
void makeVectorUnique(std::vector< T > &v)
static std::vector< exprtk::expression< T > > compileExpressions(exprtk::symbol_table< T > &symbol_table, std::vector< std::string > const &string_expressions)
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)
static void updateVariableArrayValues(std::vector< Variable > const &variables, VariableArray const &new_variable_array, VariableArray &variable_array)
static PropertyDataType evaluateExpressions(std::vector< Variable > const &variables, VariableArray const &new_variable_array, ParameterLib::SpatialPosition const &pos, double const t, std::vector< exprtk::expression< double > > const &expressions, VariableArray &variable_array, std::mutex &mutex, bool const spatial_position_is_required)
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
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
constexpr int size(int const displacement_dim)
Vectorized tensor size for given displacement dimension.