OGS
Function.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#ifdef _OPENMP
7#include <omp.h>
8#endif
9
10#include <range/v3/algorithm/contains.hpp>
11#include <range/v3/algorithm/find.hpp>
12#include <range/v3/algorithm/find_if.hpp>
13#include <range/v3/range/conversion.hpp>
14#include <range/v3/view/filter.hpp>
15#include <range/v3/view/transform.hpp>
16#include <unordered_set>
17
18#include "BaseLib/Algorithm.h"
23
24namespace MaterialPropertyLib
25{
26
31{
32 std::ptrdiff_t src_offset;
33 double* dst_ptr;
35
38 Variable var)
39 : src_offset{reinterpret_cast<char const*>(dst) -
40 reinterpret_cast<char const*>(&base)},
41 dst_ptr{dst},
42 variable{var}
43 {
44 }
45
46 void apply(VariableArray const& src) const
47 {
48 double const val = *reinterpret_cast<double const*>(
49 reinterpret_cast<char const*>(&src) + src_offset);
50 if (std::isnan(val))
51 {
53 "Function property: Scalar variable '{:s}' is not "
54 "initialized.",
55 variable_enum_to_string[static_cast<int>(variable)]);
56 }
57 *dst_ptr = val;
58 }
59};
60
65template <int D>
66static exprtk::symbol_table<double> createSymbolTable(
67 std::vector<std::string> const& expression_symbol_names,
68 bool const spatial_position_is_required,
69 std::vector<std::string> const& used_curve_names,
70 std::map<std::string,
71 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
72 curves,
73 VariableArray& variable_array,
74 std::map<std::string, ParameterLib::CurveWrapper>& curve_wrappers)
75{
76 auto symbol_table =
77 ParameterLib::createBaseSymbolTable(spatial_position_is_required);
78
79 std::unordered_set<std::string> curve_name_set(used_curve_names.begin(),
80 used_curve_names.end());
81
82 for (auto const& v : expression_symbol_names)
83 {
84 if (ParameterLib::isBuiltinSymbol(v) || curve_name_set.contains(v))
85 {
86 continue;
87 }
88
89 auto add_scalar = [&v, &symbol_table](double& value)
90 { symbol_table.add_variable(v, value); };
91
92 auto add_vector =
93 [&v, &symbol_table](double* ptr, std::size_t const size)
94 { symbol_table.add_vector(v, ptr, size); };
95
96 auto add_any_variable = BaseLib::Overloaded{
97 [&add_scalar](VariableArray::Scalar* address)
98 { add_scalar(*address); },
99 [&add_vector](VariableArray::KelvinVector* address)
100 {
101 auto constexpr size =
103 auto& result =
104 address->template emplace<Eigen::Matrix<double, size, 1>>();
105 add_vector(result.data(), size);
106 },
107 [&add_vector](VariableArray::DeformationGradient* address)
108 {
109 auto constexpr size = MathLib::VectorizedTensor::size(D);
110 auto& result =
111 address->template emplace<Eigen::Matrix<double, size, 1>>();
112 add_vector(result.data(), size);
113 }};
114
115 Variable const variable = convertStringToVariable(v);
116 variable_array.visitVariable(add_any_variable, variable);
117 }
118
119 ParameterLib::registerCurveWrappers(symbol_table, used_curve_names, curves,
120 curve_wrappers);
121 return symbol_table;
122}
123
127{
130
132 friend bool operator==(VariablePair const& p, VariablePair const& q)
133 {
134 return (p.variable1 == q.variable1 && p.variable2 == q.variable2) ||
135 (p.variable1 == q.variable2 && p.variable2 == q.variable1);
136 }
137};
138
142{
143 D2ValueExpression(Variable const variable1, Variable const variable2,
144 std::vector<exprtk::expression<double>> expressions)
145 : expressions(std::move(expressions)), variables{variable1, variable2}
146 {
147 }
148
149 std::vector<exprtk::expression<double>> expressions;
151};
152
161{
162 template <int D>
164 std::integral_constant<int, D> /*dim_tag*/,
165 std::vector<std::string> const& expression_symbol_names,
166 bool spatial_position_is_required,
167 std::vector<std::string> const& used_curve_names,
168 std::map<std::string,
169 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
170 curves,
171 std::vector<Variable> const& variables_enum,
172 std::vector<Variable>* non_scalar_out,
173 std::vector<std::string> const& value_string_expressions,
174 std::vector<std::pair<std::string, std::vector<std::string>>> const&
175 dvalue_string_expressions,
176 std::vector<D2ValueConfig> const& d2value_string_expressions)
178 expression_symbol_names, spatial_position_is_required,
179 used_curve_names, curves, variable_array, curve_wrappers)),
180 symbol_table_cache(symbol_table, spatial_position_is_required)
181 {
182 buildCopyOps(variables_enum, non_scalar_out);
183 compileExpressions(value_string_expressions, dvalue_string_expressions,
184 d2value_string_expressions);
185 }
186
188 {
189 OGS_FATAL(
190 "MPL's Function property: The internal PerThreadData is not "
191 "move-constructible.");
192 }
193 PerThreadData& operator=(PerThreadData&& other) noexcept = delete;
194 PerThreadData(PerThreadData const&) = delete;
196
198 std::map<std::string, ParameterLib::CurveWrapper> curve_wrappers;
199
204
208 exprtk::symbol_table<double> symbol_table;
209
219 std::vector<exprtk::expression<double>> value_expressions;
220
232 std::vector<std::pair<Variable, std::vector<exprtk::expression<double>>>>
234
248 std::vector<D2ValueExpression> d2value_expressions;
249
252
254 std::vector<ScalarCopyOp> scalar_copy_ops;
255
259 std::vector<Variable> const& non_scalar_variables,
260 VariableArray const& new_variable_array);
261
272 std::vector<Variable> const& non_scalar_variables,
273 VariableArray const& new_variable_array,
274 ParameterLib::SpatialPosition const& pos, double t,
275 std::vector<exprtk::expression<double>> const& expressions);
276
281 void buildCopyOps(std::vector<Variable> const& variables_enum,
282 std::vector<Variable>* non_scalar_out)
283 {
284 for (auto const variable : variables_enum)
285 {
286 auto const add_non_scalar = [&]()
287 {
288 if (non_scalar_out)
289 {
290 non_scalar_out->push_back(variable);
291 }
292 };
293
294 variable_array.visitVariable(
296 {
297 scalar_copy_ops.emplace_back(
298 variable_array, dst, variable);
299 },
301 { add_non_scalar(); },
303 { add_non_scalar(); }},
304 variable);
305 }
306 }
307
315 std::vector<std::string> const& value_string_expressions,
316 std::vector<std::pair<std::string, std::vector<std::string>>> const&
317 dvalue_string_expressions,
318 std::vector<D2ValueConfig> const& d2value_string_expressions)
319 {
321 symbol_table, value_string_expressions);
322
323 for (auto const& [variable_name, string_expressions] :
324 dvalue_string_expressions)
325 {
326 if (string_expressions.size() != value_string_expressions.size())
327 {
328 OGS_FATAL(
329 "The number of dValue expressions ({:d}) for variable "
330 "'{:s}' does not match the number of value expressions "
331 "({:d}).",
332 string_expressions.size(), variable_name,
333 value_string_expressions.size());
334 }
335 dvalue_expressions.emplace_back(
336 convertStringToVariable(variable_name),
338 string_expressions));
339 }
340
341 // Component-count consistency is validated once in the Function
342 // constructor; here only the per-thread compilation remains.
343 for (auto const& [variable_name1, variable_name2, string_expressions] :
344 d2value_string_expressions)
345 {
346 d2value_expressions.emplace_back(
347 convertStringToVariable(variable_name1),
348 convertStringToVariable(variable_name2),
350 string_expressions));
351 }
352 }
353};
354
355template <int D>
357{
358 using Expression = exprtk::expression<double>;
359
361 int num_threads,
362 std::vector<std::string> const& expression_symbol_names,
363 std::vector<Variable> const& variables_enum,
364 std::vector<std::string> const& value_string_expressions,
365 std::vector<std::pair<std::string, std::vector<std::string>>> const&
366 dvalue_string_expressions,
367 std::vector<D2ValueConfig> const& d2value_string_expressions,
368 std::map<std::string,
369 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
370 curves);
371
373 std::vector<PerThreadData> per_thread_data;
374
377 std::vector<Variable> non_scalar_variables;
378
380};
381
382template <int D>
384 int num_threads,
385 std::vector<std::string> const& expression_symbol_names,
386 std::vector<Variable> const& variables_enum,
387 std::vector<std::string> const& value_string_expressions,
388 std::vector<std::pair<std::string, std::vector<std::string>>> const&
389 dvalue_string_expressions,
390 std::vector<D2ValueConfig> const& d2value_string_expressions,
391 std::map<std::string,
392 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
393 curves)
394{
396 ParameterLib::hasSpatialVariables(expression_symbol_names);
397
398 // Determine which curves are actually referenced in the expressions.
399 // The expression symbol names list (from exprtk::collect_variables)
400 // contains both VariableArray field names and curve names as plain
401 // identifiers.
402 auto const used_curve_names =
403 ParameterLib::collectUsedCurveNames(expression_symbol_names, curves);
404
405 per_thread_data.reserve(num_threads);
406 for (int thread_id = 0; thread_id < num_threads; ++thread_id)
407 {
408 per_thread_data.emplace_back(
409 std::integral_constant<int, D>{}, expression_symbol_names,
410 spatial_position_is_required, used_curve_names, curves,
411 variables_enum, thread_id == 0 ? &non_scalar_variables : nullptr,
412 value_string_expressions, dvalue_string_expressions,
413 d2value_string_expressions);
414 }
415}
416
418 std::vector<Variable> const& non_scalar_variables,
419 VariableArray const& new_variable_array)
420{
421 for (auto const& variable : non_scalar_variables)
422 {
423 auto assign_kelvin_vector = [&variable, &new_variable_array](
425 {
426 auto assign_value = [&destination = *address,
427 &variable]<typename S>(S const& source)
428 {
429 if constexpr (std::is_same_v<S, std::monostate>)
430 {
431 OGS_FATAL(
432 "Function property: Kelvin vector variable '{:s}' is "
433 "not initialized.",
434 variable_enum_to_string[static_cast<int>(variable)]);
435 }
436 else
437 {
438 if (std::holds_alternative<S>(destination))
439 {
440 std::get<S>(destination) = MathLib::KelvinVector::
442 }
443 else
444 {
445 OGS_FATAL(
446 "Function property: Mismatch of Kelvin vector "
447 "sizes for variable {:s}.",
448 variable_enum_to_string[static_cast<int>(
449 variable)]);
450 }
451 }
452 };
453 std::visit(assign_value,
454 *std::get<VariableArray::KelvinVector const*>(
455 new_variable_array.address_of(variable)));
456 };
457 auto assign_deformation_gradient =
458 [&variable,
459 &new_variable_array](VariableArray::DeformationGradient* address)
460 {
461 auto assign_value = [&destination = *address,
462 &variable]<typename S>(S const& source)
463 {
464 if constexpr (std::is_same_v<S, std::monostate>)
465 {
466 OGS_FATAL(
467 "Function property: Vectorized tensor variable '{:s}' "
468 "is not initialized.",
469 variable_enum_to_string[static_cast<int>(variable)]);
470 }
471 else
472 {
473 if (std::holds_alternative<S>(destination))
474 {
475 std::get<S>(destination) = source;
476 }
477 else
478 {
479 OGS_FATAL(
480 "Function property: Mismatch of vectorized tensor "
481 "sizes for variable {:s}.",
482 variable_enum_to_string[static_cast<int>(
483 variable)]);
484 }
485 }
486 };
487 std::visit(assign_value,
488 *std::get<VariableArray::DeformationGradient const*>(
489 new_variable_array.address_of(variable)));
490 };
491
492 variable_array.visitVariable(
495 {
496 OGS_FATAL(
497 "Function property: updateNonScalarVariables called "
498 "with a scalar variable.");
499 },
500 assign_kelvin_vector, assign_deformation_gradient},
501 variable);
502 }
503}
504
507template <std::size_t N>
508static std::array<double, N> evaluateToArray(
509 std::vector<exprtk::expression<double>> const& expressions)
510{
511 std::array<double, N> result{};
512 for (std::size_t i = 0; i < N; ++i)
513 {
514 result[i] = expressions[i].value();
515 }
516 return result;
517}
518
520 std::vector<Variable> const& non_scalar_variables,
521 VariableArray const& new_variable_array,
522 ParameterLib::SpatialPosition const& pos, double const t,
523 std::vector<exprtk::expression<double>> const& expressions)
524{
525 // Fast path: direct offset arithmetic.
526 for (auto const& op : scalar_copy_ops)
527 {
528 op.apply(new_variable_array);
529 }
530 // Fallback for KelvinVector / DeformationGradient variables.
531 updateNonScalarVariables(non_scalar_variables, new_variable_array);
532
533 // Set symbol table variables using cached pointers.
534 symbol_table_cache.setTimeAndPosition(t, pos);
535
536 // Dispatch on expression count: template specialisations fix N at compile
537 // time, enabling stack allocation in evaluateToArray and branch-free
538 // conversion in fromArray.
539 auto const n = expressions.size();
540 switch (n)
541 {
542 case 1:
543 return fromArray(evaluateToArray<1>(expressions));
544 case 2:
545 return fromArray(evaluateToArray<2>(expressions));
546 case 3:
547 return fromArray(evaluateToArray<3>(expressions));
548 case 4:
549 return fromArray(evaluateToArray<4>(expressions));
550 case 6:
551 return fromArray(evaluateToArray<6>(expressions));
552 case 9:
553 return fromArray(evaluateToArray<9>(expressions));
554 default:
555 OGS_FATAL(
556 "Cannot convert a vector of size {} to a PropertyDataType", n);
557 }
558}
559
561 std::string name,
562 std::vector<std::string> const& value_string_expressions,
563 std::vector<std::pair<std::string, std::vector<std::string>>> const&
564 dvalue_string_expressions,
565 std::vector<D2ValueConfig> const& d2value_string_expressions,
566 std::map<std::string,
567 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
568 curves)
569{
570 name_ = std::move(name);
571
572 // Validate the d2value blocks once, before the per-thread/per-dimension
573 // Implementations are built: each unordered {v1,v2} pair may appear at
574 // most once, and each block must carry one expression per value component.
575 {
576 std::vector<VariablePair> seen_pairs;
577 for (auto const& [vname1, vname2, exprs] : d2value_string_expressions)
578 {
579 VariablePair const pair{convertStringToVariable(vname1),
581 if (ranges::contains(seen_pairs, pair))
582 {
583 OGS_FATAL(
584 "Function property '{}': duplicate d2value block for "
585 "variable pair '{}'/'{}'. Each unordered pair may "
586 "appear at most once.",
587 name_, vname1, vname2);
588 }
589 seen_pairs.push_back(pair);
590
591 if (exprs.size() != value_string_expressions.size())
592 {
593 OGS_FATAL(
594 "Function property '{}': the number of d2Value expressions "
595 "({:d}) for variables '{:s}'/'{:s}' does not match the "
596 "number of value expressions ({:d}).",
597 name_, exprs.size(), vname1, vname2,
598 value_string_expressions.size());
599 }
600 }
601 }
602
603 // Collect variables from all expressions (value, dvalue, and d2value) so
604 // the symbol table is complete even when a variable appears only in a
605 // derivative.
606 auto all_exprs = value_string_expressions;
607 for (auto const& [_, exprs] : dvalue_string_expressions)
608 {
609 all_exprs.insert(all_exprs.end(), exprs.begin(), exprs.end());
610 }
611 for (auto const& [_1, _2, exprs] : d2value_string_expressions)
612 {
613 all_exprs.insert(all_exprs.end(), exprs.begin(), exprs.end());
614 }
615 auto const expression_symbol_names =
617
619 expression_symbol_names |
620 ranges::views::filter(
621 [&curves](std::string const& s)
622 {
623 return !ParameterLib::isBuiltinSymbol(s) && !curves.contains(s);
624 }) |
625 ranges::views::transform([](std::string const& s)
626 { return convertStringToVariable(s); }) |
627 ranges::to<std::vector>;
628
629 int const num_threads = BaseLib::getNumberOfThreads();
630
631 impl2_ = std::make_unique<Implementation<2>>(
632 num_threads, expression_symbol_names, required_variables_enum_,
633 value_string_expressions, dvalue_string_expressions,
634 d2value_string_expressions, curves);
635 impl3_ = std::make_unique<Implementation<3>>(
636 num_threads, expression_symbol_names, required_variables_enum_,
637 value_string_expressions, dvalue_string_expressions,
638 d2value_string_expressions, curves);
639}
640
641std::variant<Function::Implementation<2>*, Function::Implementation<3>*>
643 VariableArray const& variable_array) const
644{
645 if (variable_array.is2D())
646 {
647 return impl2_.get();
648 }
649 if (variable_array.is3D())
650 {
651 return impl3_.get();
652 }
653
654 OGS_FATAL(
655 "Variable array has vectors for 2 and 3 dimensions simultaneously. "
656 "Mixed dimensions cannot be dealt within Function evaluation.");
657}
658
661static int currentThreadId(std::string const& property_name,
662 std::size_t const num_slots)
663{
664#ifdef _OPENMP
665 int const thread_id = omp_get_thread_num();
666#else
667 int const thread_id = 0;
668#endif
669 if (thread_id >= static_cast<int>(num_slots))
670 {
671 OGS_FATAL(
672 "In Function-type property '{:s}' evaluation the OMP-thread with "
673 "id {:d} exceeds the number of allocated threads {:d}.",
674 property_name, thread_id, num_slots);
675 }
676 return thread_id;
677}
678
681 double const t, double const /*dt*/) const
682{
683 return std::visit(
684 [&](auto&& impl_ptr)
685 {
686 auto& thread_data = impl_ptr->per_thread_data[currentThreadId(
687 name_, impl_ptr->per_thread_data.size())];
688 return thread_data.evaluate(impl_ptr->non_scalar_variables,
689 variable_array, pos, t,
690 thread_data.value_expressions);
691 },
693}
694
696 Variable const variable,
698 double const t, double const /*dt*/) const
699{
700 return std::visit(
701 [&](auto&& impl_ptr)
702 {
703 auto& thread_data = impl_ptr->per_thread_data[currentThreadId(
704 name_, impl_ptr->per_thread_data.size())];
705 auto const it = ranges::find_if(thread_data.dvalue_expressions,
706 [&variable](auto const& v)
707 { return v.first == variable; });
708
709 if (it == end(thread_data.dvalue_expressions))
710 {
711 OGS_FATAL(
712 "Requested derivative with respect to the variable {:s} "
713 "not provided for Function-type property {:s}.",
714 variable_enum_to_string[static_cast<int>(variable)], name_);
715 }
716
717 return thread_data.evaluate(impl_ptr->non_scalar_variables,
718 variable_array, pos, t, it->second);
719 },
721}
722
724 Variable const variable1,
725 Variable const variable2,
727 double const t, double const /*dt*/) const
728{
729 return std::visit(
730 [&](auto&& impl_ptr)
731 {
732 auto& thread_data = impl_ptr->per_thread_data[currentThreadId(
733 name_, impl_ptr->per_thread_data.size())];
734 auto const it = ranges::find(thread_data.d2value_expressions,
735 VariablePair{variable1, variable2},
737
738 if (it == thread_data.d2value_expressions.end())
739 {
740 OGS_FATAL(
741 "Requested second derivative with respect to variables "
742 "'{:s}'/'{:s}' not provided for Function-type property "
743 "'{:s}'.",
744 variable_enum_to_string[static_cast<int>(variable1)],
745 variable_enum_to_string[static_cast<int>(variable2)],
746 name_);
747 }
748
749 return thread_data.evaluate(impl_ptr->non_scalar_variables,
750 variable_array, pos, t,
751 it->expressions);
752 },
754}
755
756Function::~Function() = default;
757
758} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:10
std::unique_ptr< Implementation< 3 > > impl3_
Definition Function.h:72
std::variant< Function::Implementation< 2 > *, Function::Implementation< 3 > * > getImplementationForDimensionOfVariableArray(VariableArray const &variable_array) const
Definition Function.cpp:642
std::vector< Variable > required_variables_enum_
Variables used in the exprtk expressions.
Definition Function.h:79
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, std::vector< D2ValueConfig > const &d2value_string_expressions, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
Definition Function.cpp:560
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
Definition Function.cpp:695
std::unique_ptr< Implementation< 2 > > impl2_
Definition Function.h:71
PropertyDataType d2Value(VariableArray const &variable_array, Variable const variable1, Variable const variable2, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
Default implementation: 2nd derivative of any constant property is zero.
Definition Function.cpp:723
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)
int getNumberOfThreads()
static std::array< double, N > evaluateToArray(std::vector< exprtk::expression< double > > const &expressions)
Definition Function.cpp:508
static int currentThreadId(std::string const &property_name, std::size_t const num_slots)
Definition Function.cpp:661
static exprtk::symbol_table< double > createSymbolTable(std::vector< std::string > const &expression_symbol_names, bool const spatial_position_is_required, std::vector< std::string > const &used_curve_names, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves, VariableArray &variable_array, std::map< std::string, ParameterLib::CurveWrapper > &curve_wrappers)
Definition Function.cpp:66
PropertyDataType fromArray(std::array< double, N > const &values)
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.
std::vector< exprtk::expression< T > > compileExpressions(exprtk::symbol_table< T > &symbol_table, std::vector< std::string > const &string_expressions)
Definition ExprtkUtils.h:74
bool isBuiltinSymbol(std::string_view const name)
exprtk::symbol_table< double > createBaseSymbolTable(bool spatial_position_is_required)
void registerCurveWrappers(exprtk::symbol_table< double > &symbol_table, std::vector< std::string > const &curve_names, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves, std::map< std::string, CurveWrapper > &curve_wrappers)
std::vector< std::string > collectVariables(std::vector< std::string > const &expression_strings)
std::vector< std::string > collectUsedCurveNames(std::vector< std::string > const &expression_symbol_names, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
Returns the subset of expression_symbol_names that are keys in curves.
bool hasSpatialVariables(std::vector< std::string > const &variables)
std::vector< exprtk::expression< double > > expressions
Definition Function.cpp:149
D2ValueExpression(Variable const variable1, Variable const variable2, std::vector< exprtk::expression< double > > expressions)
Definition Function.cpp:143
Implementation(int num_threads, std::vector< std::string > const &expression_symbol_names, std::vector< Variable > const &variables_enum, std::vector< std::string > const &value_string_expressions, std::vector< std::pair< std::string, std::vector< std::string > > > const &dvalue_string_expressions, std::vector< D2ValueConfig > const &d2value_string_expressions, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
Definition Function.cpp:383
std::vector< PerThreadData > per_thread_data
Per-thread data; indexed by omp_get_thread_num().
Definition Function.cpp:373
exprtk::expression< double > Expression
Definition Function.cpp:358
std::vector< ScalarCopyOp > scalar_copy_ops
Scalar copy operations into this thread's symbol table.
Definition Function.cpp:254
PerThreadData & operator=(PerThreadData const &)=delete
PropertyDataType evaluate(std::vector< Variable > const &non_scalar_variables, VariableArray const &new_variable_array, ParameterLib::SpatialPosition const &pos, double t, std::vector< exprtk::expression< double > > const &expressions)
Definition Function.cpp:519
PerThreadData(std::integral_constant< int, D >, std::vector< std::string > const &expression_symbol_names, bool spatial_position_is_required, std::vector< std::string > const &used_curve_names, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves, std::vector< Variable > const &variables_enum, std::vector< Variable > *non_scalar_out, std::vector< std::string > const &value_string_expressions, std::vector< std::pair< std::string, std::vector< std::string > > > const &dvalue_string_expressions, std::vector< D2ValueConfig > const &d2value_string_expressions)
Definition Function.cpp:163
std::map< std::string, ParameterLib::CurveWrapper > curve_wrappers
Curve wrappers owned by this thread; must outlive the symbol table.
Definition Function.cpp:198
std::vector< std::pair< Variable, std::vector< exprtk::expression< double > > > > dvalue_expressions
Definition Function.cpp:233
std::vector< exprtk::expression< double > > value_expressions
Definition Function.cpp:219
void buildCopyOps(std::vector< Variable > const &variables_enum, std::vector< Variable > *non_scalar_out)
Definition Function.cpp:281
std::vector< D2ValueExpression > d2value_expressions
Definition Function.cpp:248
PerThreadData(PerThreadData const &)=delete
ParameterLib::SymbolTableCache symbol_table_cache
Cached pointers to symbol table variables (t, x, y, z).
Definition Function.cpp:251
void compileExpressions(std::vector< std::string > const &value_string_expressions, std::vector< std::pair< std::string, std::vector< std::string > > > const &dvalue_string_expressions, std::vector< D2ValueConfig > const &d2value_string_expressions)
Definition Function.cpp:314
void updateNonScalarVariables(std::vector< Variable > const &non_scalar_variables, VariableArray const &new_variable_array)
Definition Function.cpp:417
PerThreadData & operator=(PerThreadData &&other) noexcept=delete
exprtk::symbol_table< double > symbol_table
Definition Function.cpp:208
Variable variable
for error messages
Definition Function.cpp:34
ScalarCopyOp(VariableArray const &base, VariableArray::Scalar *dst, Variable var)
Definition Function.cpp:36
std::ptrdiff_t src_offset
byte offset from VariableArray start
Definition Function.cpp:32
double * dst_ptr
pointer into this thread's symbol table
Definition Function.cpp:33
void apply(VariableArray const &src) const
Definition Function.cpp:46
friend bool operator==(VariablePair const &p, VariablePair const &q)
Order-independent equality: {a, b} equals {b, a}.
Definition Function.cpp:132