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
     {