diff --git a/MaterialLib/MPL/Properties/Function.cpp b/MaterialLib/MPL/Properties/Function.cpp index 42edb90425ab2ba377ee053179968ff02d644c3c..c896f43b36e0052fbbe1e865a3b7e217cab2fa5c 100644 --- a/MaterialLib/MPL/Properties/Function.cpp +++ b/MaterialLib/MPL/Properties/Function.cpp @@ -93,41 +93,27 @@ exprtk::symbol_table<double> Function::Implementation<D>::createSymbolTable( [&v, &symbol_table](double* ptr, std::size_t const size) { symbol_table.add_vector(v, ptr, size); }; - auto add_any_variable = - [&add_scalar, &add_vector]<typename T>(T* address) - { - if constexpr (std::is_same_v<VariableArray::Scalar, T>) - { - add_scalar(*address); - } - else if constexpr (std::is_same_v<VariableArray::KelvinVector, T>) + auto add_any_variable = BaseLib::Overloaded{ + [&add_scalar](VariableArray::Scalar* address) + { add_scalar(*address); }, + [&add_vector](VariableArray::KelvinVector* address) { auto constexpr size = MathLib::KelvinVector::kelvin_vector_dimensions(D); auto& result = address->template emplace<Eigen::Matrix<double, size, 1>>(); add_vector(result.data(), size); - } - else if constexpr (std::is_same_v< - VariableArray::DeformationGradient, T>) + }, + [&add_vector](VariableArray::DeformationGradient* address) { auto constexpr size = MathLib::VectorizedTensor::size(D); auto& result = address->template emplace<Eigen::Matrix<double, size, 1>>(); add_vector(result.data(), size); - } - else - { - static_assert(!std::is_same_v<T, T>, - "Non-exhaustive visitor! The variable type (in " - "the std::is_same_v expression) must be one of " - "the VariableArray::{Scalar, KelvinVector, " - "DeformationGradient}."); - } - }; + }}; Variable const variable = convertStringToVariable(v); - std::visit(add_any_variable, variable_array.address_of(variable)); + variable_array.visitVariable(add_any_variable, variable); } return symbol_table; } @@ -161,102 +147,95 @@ static void updateVariableArrayValues(std::vector<Variable> const& variables, { for (auto const& variable : variables) { - auto assign_variable = - [&variable, &new_variable_array]<typename T>(T* address) + auto assign_scalar = + [&variable, &new_variable_array](VariableArray::Scalar* address) { - if constexpr (std::is_same_v<VariableArray::Scalar, T>) + double const value = *std::get<VariableArray::Scalar const*>( + new_variable_array.address_of(variable)); + + if (std::isnan(value)) { - double const value = *std::get<VariableArray::Scalar const*>( - new_variable_array.address_of(variable)); + OGS_FATAL( + "Function property: Scalar variable '{:s}' is not " + "initialized.", + variable_enum_to_string[static_cast<int>(variable)]); + } - if (std::isnan(value)) + *address = value; + }; + auto assign_kelvin_vector = [&variable, &new_variable_array]( + VariableArray::KelvinVector* address) + { + auto assign_value = [&destination = *address, + &variable]<typename S>(S const& source) + { + if constexpr (std::is_same_v<S, std::monostate>) { OGS_FATAL( - "Function property: Scalar variable '{:s}' is not " - "initialized.", + "Function property: Kelvin vector variable '{:s}' is " + "not initialized.", variable_enum_to_string[static_cast<int>(variable)]); } - - *address = value; - } - else if constexpr (std::is_same_v<VariableArray::KelvinVector, T>) - { - auto assign_value = [&destination = *address, - &variable]<typename S>(S const& source) + else { - if constexpr (std::is_same_v<S, std::monostate>) + if (std::holds_alternative<S>(destination)) { - OGS_FATAL( - "Function property: Kelvin vector variable '{:s}' " - "is not initialized.", - variable_enum_to_string[static_cast<int>( - variable)]); + std::get<S>(destination) = MathLib::KelvinVector:: + kelvinVectorToSymmetricTensor(source); } else { - if (std::holds_alternative<S>(destination)) - { - std::get<S>(destination) = MathLib::KelvinVector:: - kelvinVectorToSymmetricTensor(source); - } - else - { - OGS_FATAL( - "Function property: Mismatch of Kelvin vector " - "sizes for variable {:s}.", - variable_enum_to_string[static_cast<int>( - variable)]); - } + OGS_FATAL( + "Function property: Mismatch of Kelvin vector " + "sizes for variable {:s}.", + variable_enum_to_string[static_cast<int>( + variable)]); } - }; - std::visit(assign_value, - *std::get<VariableArray::KelvinVector const*>( - new_variable_array.address_of(variable))); - } - else if constexpr (std::is_same_v< - VariableArray::DeformationGradient, T>) + } + }; + std::visit(assign_value, + *std::get<VariableArray::KelvinVector const*>( + new_variable_array.address_of(variable))); + }; + auto assign_deformation_gradient = + [&variable, + &new_variable_array](VariableArray::DeformationGradient* address) + { + auto assign_value = [&destination = *address, + &variable]<typename S>(S const& source) { - auto assign_value = [&destination = *address, - &variable]<typename S>(S const& source) + if constexpr (std::is_same_v<S, std::monostate>) { - if constexpr (std::is_same_v<S, std::monostate>) + OGS_FATAL( + "Function property: Vectorized tensor variable '{:s}' " + "is not initialized.", + variable_enum_to_string[static_cast<int>(variable)]); + } + else + { + if (std::holds_alternative<S>(destination)) { - OGS_FATAL( - "Function property: Vectorized tensor variable " - "'{:s}' is not initialized.", - variable_enum_to_string[static_cast<int>( - variable)]); + std::get<S>(destination) = source; } else { - if (std::holds_alternative<S>(destination)) - { - std::get<S>(destination) = source; - } - else - { - OGS_FATAL( - "Function property: Mismatch of vectorized " - "tensor sizes for variable {:s}.", - variable_enum_to_string[static_cast<int>( - variable)]); - } + OGS_FATAL( + "Function property: Mismatch of vectorized tensor " + "sizes for variable {:s}.", + variable_enum_to_string[static_cast<int>( + variable)]); } - }; - std::visit(assign_value, - *std::get<VariableArray::DeformationGradient const*>( - new_variable_array.address_of(variable))); - } - else - { - static_assert(!std::is_same_v<T, T>, - "Non-exhaustive visitor! The variable type (in " - "the std::is_same_v expression) must be one of " - "the VariableArray::{Scalar, KelvinVector, " - "DeformationGradient}."); - } + } + }; + std::visit(assign_value, + *std::get<VariableArray::DeformationGradient const*>( + new_variable_array.address_of(variable))); }; - std::visit(assign_variable, variable_array.address_of(variable)); + + variable_array.visitVariable( + BaseLib::Overloaded{assign_scalar, assign_kelvin_vector, + assign_deformation_gradient}, + variable); } } diff --git a/MaterialLib/MPL/VariableType.h b/MaterialLib/MPL/VariableType.h index 4134437fd16a27760c17c4ceaa0e2936f7b9cc9d..5e0302616a32f8d4b2a0b439409de5c3be64b6ed 100644 --- a/MaterialLib/MPL/VariableType.h +++ b/MaterialLib/MPL/VariableType.h @@ -116,6 +116,22 @@ public: VariablePointer address_of(Variable const v); + template <typename Visitor> + auto visitVariable(Visitor&& visitor, Variable const variable) + { + return std::visit( + BaseLib::Overloaded{ + std::forward<Visitor>(visitor), + []<typename T>(T*) + { + static_assert(!std::is_same_v<T, T>, + "Non-exhaustive visitor! The variable type " + "must be one of the VariableArray::{Scalar, " + "KelvinVector, DeformationGradient}."); + }}, + address_of(variable)); + } + template <typename Visitor> auto visitVariable(Visitor&& visitor, Variable const variable) const {