diff --git a/MaterialLib/SolidModels/MFront/MFront.cpp b/MaterialLib/SolidModels/MFront/MFront.cpp
index ebd74e3ca69d396a94f8d215bd6be47c4e605d86..91eab146d7cb0ffca6a48096bf1bd8efad5f2920 100644
--- a/MaterialLib/SolidModels/MFront/MFront.cpp
+++ b/MaterialLib/SolidModels/MFront/MFront.cpp
@@ -434,11 +434,12 @@ MFront<DisplacementDim>::getInternalVariables() const
         // MFront stores the variables in local coordinate system.
         // The `size` variable could be used to find out the type of variable.
         typename MechanicsBase<DisplacementDim>::InternalVariable new_variable{
-            name, static_cast<unsigned>(size),
+            name, static_cast<int>(size),
             [offset, size](
                 typename MechanicsBase<
                     DisplacementDim>::MaterialStateVariables const& state,
-                std::vector<double>& cache) -> std::vector<double> const& {
+                std::vector<double>& cache) -> std::vector<double> const&
+            {
                 assert(dynamic_cast<MaterialStateVariables const*>(&state) !=
                        nullptr);
                 auto const& internal_state_variables =
@@ -453,7 +454,8 @@ MFront<DisplacementDim>::getInternalVariables() const
             },
             [offset, size](
                 typename MechanicsBase<DisplacementDim>::MaterialStateVariables&
-                    state) -> BaseLib::DynamicSpan<double> {
+                    state) -> BaseLib::DynamicSpan<double>
+            {
                 assert(dynamic_cast<MaterialStateVariables const*>(&state) !=
                        nullptr);
                 auto& internal_state_variables =
diff --git a/MaterialLib/SolidModels/MechanicsBase.h b/MaterialLib/SolidModels/MechanicsBase.h
index 684509c0da760e8c9218101296b6a965e21ae716..de0ff368303f47b8bb31c74352ee0b623c12f106 100644
--- a/MaterialLib/SolidModels/MechanicsBase.h
+++ b/MaterialLib/SolidModels/MechanicsBase.h
@@ -104,7 +104,7 @@ struct MechanicsBase
         std::string const name;
 
         /// number of components of the internal variable
-        unsigned const num_components;
+        int const num_components;
 
         /// function accessing the internal variable
         Getter const getter;
diff --git a/ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h b/ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h
index 759e09cd0713998d70e733c62403d2df54d965d8..af3109d7a65e8d52ca50fd01fb6fb0b2741d6235 100644
--- a/ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h
+++ b/ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h
@@ -67,7 +67,8 @@ void solidMaterialInternalToSecondaryVariables(
                 auto const& state = loc_asm.getMaterialStateVariablesAt(i);
 
                 auto const& int_pt_values = fct(state, cache_column);
-                assert(int_pt_values.size() == num_components);
+                assert(int_pt_values.size() ==
+                       static_cast<std::size_t>(num_components));
                 auto const int_pt_values_vec = MathLib::toVector(int_pt_values);
 
                 cache_mat.col(i).noalias() = int_pt_values_vec;
@@ -80,14 +81,16 @@ void solidMaterialInternalToSecondaryVariables(
     }
 }
 
-template <typename LocalAssemblerInterface, typename AddIntegrationPointWriter,
+template <typename LocalAssemblerInterface, typename IntegrationPointWriter,
           int DisplacementDim>
 void solidMaterialInternalVariablesToIntegrationPointWriter(
     std::map<int, std::unique_ptr<MaterialLib::Solids::MechanicsBase<
                       DisplacementDim>>> const& solid_materials,
     std::vector<std::unique_ptr<LocalAssemblerInterface>> const&
         local_assemblers,
-    AddIntegrationPointWriter const& add_integration_point_writer)
+    std::vector<std::unique_ptr<IntegrationPointWriter>>&
+        integration_point_writer,
+    int const integration_order)
 {
     // Collect the internal variables for all solid materials.
     std::vector<typename MaterialLib::Solids::MechanicsBase<
@@ -100,34 +103,17 @@ void solidMaterialInternalVariablesToIntegrationPointWriter(
     }
 
     // Create integration point writers for each of the internal variables.
-    for (auto const& internal_variable : internal_variables)
+    for (auto const& iv : internal_variables)
     {
-        auto const& name = internal_variable.name;
-        auto const& fct = internal_variable.reference;
-        auto const n_components = internal_variable.num_components;
         DBUG("Creating integration point writer for  internal variable {:s}.",
-             name);
-
-        auto get_integration_point_data = [fct, n_components,
-                                           &local_assemblers]() {
-            // Result containing integration point data for each local
-            // assembler.
-            std::vector<std::vector<double>> result;
-            result.reserve(local_assemblers.size());
-
-            std::transform(begin(local_assemblers), end(local_assemblers),
-                           back_inserter(result),
-                           [fct, n_components](auto const& local_assembler) {
-                               return local_assembler
-                                   ->getMaterialStateVariableInternalState(
-                                       fct, n_components);
-                           });
-
-            return result;
-        };
-
-        add_integration_point_writer(name, n_components,
-                                     get_integration_point_data);
+             iv.name);
+
+        integration_point_writer.emplace_back(
+            std::make_unique<IntegrationPointWriter>(
+                "material_state_variable_" + iv.name + "_ip", iv.num_components,
+                integration_order, local_assemblers,
+                &LocalAssemblerInterface::getMaterialStateVariableInternalState,
+                iv.reference, iv.num_components));
     }
 }
 }  // namespace ProcessLib::Deformation
diff --git a/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp b/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp
index c9618c48f0a87bcb5dea61a03c9b81f9424d0de3..78354c832f6b8df35759504d4269a958c99c7892 100644
--- a/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp
+++ b/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp
@@ -50,41 +50,14 @@ HydroMechanicsProcess<DisplacementDim>::HydroMechanicsProcess(
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers, &LocalAssemblerIF::getSigma));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "epsilon_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getEpsilon();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerIF::getEpsilon));
 }
 
 template <int DisplacementDim>
diff --git a/ProcessLib/Output/IntegrationPointWriter.h b/ProcessLib/Output/IntegrationPointWriter.h
index 780ac5cba1f5c07277a6e31a6d168c1a98913188..93f341f73ef6142ea0ec9c2f709daf7a847acab0 100644
--- a/ProcessLib/Output/IntegrationPointWriter.h
+++ b/ProcessLib/Output/IntegrationPointWriter.h
@@ -23,18 +23,37 @@ namespace ProcessLib
 {
 struct IntegrationPointWriter final
 {
-    IntegrationPointWriter(std::string const& name,
-                           int const n_components,
-                           int const integration_order,
-                           std::function<std::vector<std::vector<double>>()>
-                               callback)
+    template <typename LocalAssemblerInterface, typename... Args>
+    IntegrationPointWriter(
+        std::string const& name,
+        int const n_components,
+        int const integration_order,
+        std::vector<std::unique_ptr<LocalAssemblerInterface>> const&
+            local_assemblers,
+        std::vector<double> (LocalAssemblerInterface::*getIpData)(Args...)
+            const,
+        Args&&... args)
         : _name(name),
           _n_components(n_components),
-          _integration_order(integration_order),
-          _callback(callback)
+          _integration_order(integration_order)
     {
-    }
+        _callback = [&local_assemblers,
+                     getIpData,
+                     ... f_args = std::forward<Args>(args)]
+        {
+            // Result containing integration point data for each local
+            // assembler.
+            std::vector<std::vector<double>> result;
+            result.reserve(local_assemblers.size());
+
+            std::transform(begin(local_assemblers), end(local_assemblers),
+                           std::back_inserter(result),
+                           [&](auto const& la)
+                           { return (*la.*getIpData)(f_args...); });
 
+            return result;
+        };
+    }
     int numberOfComponents() const { return _n_components; }
     int integrationOrder() const { return _integration_order; }
     std::string name() const { return _name; }
diff --git a/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h b/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h
index 22a37878bac7646f1d04db79c992c8c9016c6962..4bd48c0751814cd0b9e30df10ab8ecc154169f9b 100644
--- a/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h
+++ b/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h
@@ -104,10 +104,9 @@ struct LocalAssemblerInterface : public ProcessLib::LocalAssemblerInterface,
 
     virtual std::vector<double> getMaterialStateVariableInternalState(
         std::function<BaseLib::DynamicSpan<double>(
-            typename MaterialLib::Solids::MechanicsBase<
-                DisplacementDim>::MaterialStateVariables&)>
-            get_values_span,
-        int n_components) const = 0;
+            typename MaterialLib::Solids::MechanicsBase<DisplacementDim>::
+                MaterialStateVariables&)> const& get_values_span,
+        int const& n_components) const = 0;
 
     // TODO move to NumLib::ExtrapolatableElement
     virtual unsigned getNumberOfIntegrationPoints() const = 0;
diff --git a/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h b/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h
index 5213644968816ed44baf4d7e9cc4a5b50f65ff04..17e985b2daeac109483a39c6788487157eaa80c0 100644
--- a/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h
+++ b/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h
@@ -1321,10 +1321,9 @@ std::vector<double> RichardsMechanicsLocalAssembler<
     DisplacementDim>::
     getMaterialStateVariableInternalState(
         std::function<BaseLib::DynamicSpan<double>(
-            typename MaterialLib::Solids::MechanicsBase<
-                DisplacementDim>::MaterialStateVariables&)>
-            get_values_span,
-        int const n_components) const
+            typename MaterialLib::Solids::MechanicsBase<DisplacementDim>::
+                MaterialStateVariables&)> const& get_values_span,
+        int const& n_components) const
 {
     return ProcessLib::getIntegrationPointDataMaterialStateVariables(
         _ip_data, &IpData::material_state_variables, get_values_span,
diff --git a/ProcessLib/RichardsMechanics/RichardsMechanicsFEM.h b/ProcessLib/RichardsMechanics/RichardsMechanicsFEM.h
index fc4c7b9d8583f23a61978e3be70b392a6f197dbb..8771c9ed43e2658a8eaebede40f0ec747f73b2c5 100644
--- a/ProcessLib/RichardsMechanics/RichardsMechanicsFEM.h
+++ b/ProcessLib/RichardsMechanics/RichardsMechanicsFEM.h
@@ -239,10 +239,9 @@ public:
 
     std::vector<double> getMaterialStateVariableInternalState(
         std::function<BaseLib::DynamicSpan<double>(
-            typename MaterialLib::Solids::MechanicsBase<
-                DisplacementDim>::MaterialStateVariables&)>
-            get_values_span,
-        int n_components) const override;
+            typename MaterialLib::Solids::MechanicsBase<DisplacementDim>::
+                MaterialStateVariables&)> const& get_values_span,
+        int const& n_components) const override;
 
     std::vector<double> const& getIntPtDryDensitySolid(
         const double t,
diff --git a/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp b/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp
index 39dd41a6a634748f1fda6d3d1693f383b0a1f4c6..6c3df82fd1c44b57d5b2e42ae457beddd7f33281 100644
--- a/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp
+++ b/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp
@@ -53,121 +53,36 @@ RichardsMechanicsProcess<DisplacementDim>::RichardsMechanicsProcess(
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers, &LocalAssemblerIF::getSigma));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "saturation_ip", 1 /*n components*/, integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getSaturation();
-                }
-
-                return result;
-            }));
+            _local_assemblers, &LocalAssemblerIF::getSaturation));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "porosity_ip", 1 /*n components*/, integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getPorosity();
-                }
-
-                return result;
-            }));
+            _local_assemblers, &LocalAssemblerIF::getPorosity));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "transport_porosity_ip", 1 /*n components*/, integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getTransportPorosity();
-                }
-
-                return result;
-            }));
+            _local_assemblers, &LocalAssemblerIF::getTransportPorosity));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "swelling_stress_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getSwellingStress();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerIF::getSwellingStress));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "epsilon_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getEpsilon();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerIF::getEpsilon));
 }
 
 template <int DisplacementDim>
@@ -346,20 +261,11 @@ void RichardsMechanicsProcess<DisplacementDim>::initializeConcreteProcess(
         LocalAssemblerIF>(_process_data.solid_materials,
                           add_secondary_variable);
 
-    auto add_integration_point_writer =
-        [&](std::string const& name, int const n_components, auto function)
-    {
-        _integration_point_writer.emplace_back(
-            std::make_unique<IntegrationPointWriter>(
-                "material_state_variable_" + name + "_ip", n_components,
-                integration_order, function));
-    };
-
     // Assume all materials have same internal variables.
     ProcessLib::Deformation::
         solidMaterialInternalVariablesToIntegrationPointWriter(
             _process_data.solid_materials, _local_assemblers,
-            add_integration_point_writer);
+            _integration_point_writer, integration_order);
 
     _process_data.element_saturation = MeshLib::getOrCreateMeshProperty<double>(
         const_cast<MeshLib::Mesh&>(mesh), "saturation_avg",
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
index b920a506b3a50341e9d2687ea0076de2e96e3520..5bfb5e6a20f0d816c770b6570ceee6a0c1af3b3f 100644
--- a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
+++ b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
@@ -72,21 +72,8 @@ SmallDeformationProcess<DisplacementDim>::SmallDeformationProcess(
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getSigma));
 }
 
 template <int DisplacementDim>
diff --git a/ProcessLib/SmallDeformationNonlocal/SmallDeformationNonlocalProcess.cpp b/ProcessLib/SmallDeformationNonlocal/SmallDeformationNonlocalProcess.cpp
index e931b4f186eb625c399542b3d0a8fd76ea5ddaab..f2df885616c53920bc591852776b5a8bd24fba5f 100644
--- a/ProcessLib/SmallDeformationNonlocal/SmallDeformationNonlocalProcess.cpp
+++ b/ProcessLib/SmallDeformationNonlocal/SmallDeformationNonlocalProcess.cpp
@@ -48,39 +48,13 @@ SmallDeformationNonlocalProcess<DisplacementDim>::
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getSigma));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
-            "kappa_d_ip", 1 /*n_components*/, integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getKappaD();
-                }
-
-                return result;
-            }));
+            "kappa_d_ip", 1 /*n_components*/, integration_order,
+            _local_assemblers, &LocalAssemblerInterface::getKappaD));
 }
 
 template <int DisplacementDim>
diff --git a/ProcessLib/TH2M/TH2MProcess.cpp b/ProcessLib/TH2M/TH2MProcess.cpp
index fe024cea980c57c9d256cd0a35db6bf9819bb9ee..f19be7589cb7c37f37ca5eab5d8ddedcf847842e 100644
--- a/ProcessLib/TH2M/TH2MProcess.cpp
+++ b/ProcessLib/TH2M/TH2MProcess.cpp
@@ -53,62 +53,20 @@ TH2MProcess<DisplacementDim>::TH2MProcess(
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getSigma));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "saturation_ip", 1 /*n components*/, integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getSaturation();
-                }
-
-                return result;
-            }));
+            _local_assemblers, &LocalAssemblerInterface::getSaturation));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "epsilon_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getEpsilon();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getEpsilon));
 }
 
 template <int DisplacementDim>
diff --git a/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp b/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp
index 11c1318fe9d3e5481b3c40c3f7a9dc25ee1aac60..ba68b2e214b1ed6ebf02542fea9c705f627f80c3 100644
--- a/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp
+++ b/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp
@@ -50,44 +50,15 @@ ThermoHydroMechanicsProcess<DisplacementDim>::ThermoHydroMechanicsProcess(
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getSigma));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "epsilon_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getEpsilon();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getEpsilon));
 }
 
 template <int DisplacementDim>
diff --git a/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp b/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp
index 14eb6fb5a62e2075c61ac868800931827e9a87db..cf5277400bdad3aa1e136f142d338b4590b130c6 100644
--- a/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp
+++ b/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp
@@ -49,61 +49,22 @@ ThermoMechanicsProcess<DisplacementDim>::ThermoMechanicsProcess(
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getSigma));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "epsilon_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getEpsilon();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getEpsilon));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "epsilon_m_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-
-                    result[i] = local_asm.getEpsilonMechanical();
-                }
-
-                return result;
-            }));
+            integration_order, _local_assemblers,
+            &LocalAssemblerInterface::getEpsilonMechanical));
 }
 
 template <int DisplacementDim>
diff --git a/ProcessLib/ThermoRichardsFlow/ThermoRichardsFlowProcess.cpp b/ProcessLib/ThermoRichardsFlow/ThermoRichardsFlowProcess.cpp
index 7aca7870df0b6e15e37abf0c18125484f07b4971..1e92b9a546f61d45bdef25a4316c5876ed8ebf0d 100644
--- a/ProcessLib/ThermoRichardsFlow/ThermoRichardsFlowProcess.cpp
+++ b/ProcessLib/ThermoRichardsFlow/ThermoRichardsFlowProcess.cpp
@@ -50,37 +50,13 @@ ThermoRichardsFlowProcess::ThermoRichardsFlowProcess(
     // See getOrCreateMeshProperty.
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
-            "saturation_ip", 1 /*n components*/, integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getSaturation();
-                }
-
-                return result;
-            }));
+            "saturation_ip", 1 /*n components*/, integration_order,
+            _local_assemblers, &LocalAssemblerIF::getSaturation));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
-            "porosity_ip", 1 /*n components*/, integration_order, [this]() {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(_local_assemblers.size());
-
-                for (std::size_t i = 0; i < _local_assemblers.size(); ++i)
-                {
-                    auto const& local_asm = *_local_assemblers[i];
-                    result[i] = local_asm.getPorosity();
-                }
-
-                return result;
-            }));
+            "porosity_ip", 1 /*n components*/, integration_order,
+            _local_assemblers, &LocalAssemblerIF::getPorosity));
 }
 
 void ThermoRichardsFlowProcess::initializeConcreteProcess(
diff --git a/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp b/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp
index f49a246228811fc58495199dc60ed70ba728f406..96d05a6fc80a14fe8cbf9c4c2ddad2ca8495d206 100644
--- a/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp
+++ b/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp
@@ -54,121 +54,36 @@ ThermoRichardsMechanicsProcess<DisplacementDim>::ThermoRichardsMechanicsProcess(
         std::make_unique<IntegrationPointWriter>(
             "sigma_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(local_assemblers_.size());
-
-                for (std::size_t i = 0; i < local_assemblers_.size(); ++i)
-                {
-                    auto const& local_asm = *local_assemblers_[i];
-                    result[i] = local_asm.getSigma();
-                }
-
-                return result;
-            }));
+            integration_order, local_assemblers_, &LocalAssemblerIF::getSigma));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "saturation_ip", 1 /*n components*/, integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(local_assemblers_.size());
-
-                for (std::size_t i = 0; i < local_assemblers_.size(); ++i)
-                {
-                    auto const& local_asm = *local_assemblers_[i];
-                    result[i] = local_asm.getSaturation();
-                }
-
-                return result;
-            }));
+            local_assemblers_, &LocalAssemblerIF::getSaturation));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "porosity_ip", 1 /*n components*/, integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(local_assemblers_.size());
-
-                for (std::size_t i = 0; i < local_assemblers_.size(); ++i)
-                {
-                    auto const& local_asm = *local_assemblers_[i];
-                    result[i] = local_asm.getPorosity();
-                }
-
-                return result;
-            }));
+            local_assemblers_, &LocalAssemblerIF::getPorosity));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "transport_porosity_ip", 1 /*n components*/, integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(local_assemblers_.size());
-
-                for (std::size_t i = 0; i < local_assemblers_.size(); ++i)
-                {
-                    auto const& local_asm = *local_assemblers_[i];
-                    result[i] = local_asm.getTransportPorosity();
-                }
-
-                return result;
-            }));
+            local_assemblers_, &LocalAssemblerIF::getTransportPorosity));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "swelling_stress_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(local_assemblers_.size());
-
-                for (std::size_t i = 0; i < local_assemblers_.size(); ++i)
-                {
-                    auto const& local_asm = *local_assemblers_[i];
-                    result[i] = local_asm.getSwellingStress();
-                }
-
-                return result;
-            }));
+            integration_order, local_assemblers_,
+            &LocalAssemblerIF::getSwellingStress));
 
     _integration_point_writer.emplace_back(
         std::make_unique<IntegrationPointWriter>(
             "epsilon_ip",
             static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
-            integration_order,
-            [this]()
-            {
-                // Result containing integration point data for each local
-                // assembler.
-                std::vector<std::vector<double>> result;
-                result.resize(local_assemblers_.size());
-
-                for (std::size_t i = 0; i < local_assemblers_.size(); ++i)
-                {
-                    auto const& local_asm = *local_assemblers_[i];
-                    result[i] = local_asm.getEpsilon();
-                }
-
-                return result;
-            }));
+            integration_order, local_assemblers_,
+            &LocalAssemblerIF::getEpsilon));
 }
 
 template <int DisplacementDim>