diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index c8ca72b8b383adc721b3e37f4ae7c88b5de546f3..7837b432d83cf04564dcbe12df38d3c116c06f99 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -394,8 +394,7 @@ void ProjectData::parseProcesses(BaseLib::ConfigTree const& processes_config,
         }
         else if (type == "SMALL_DEFORMATION")
         {
-            //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION__dimension}
-            switch (process_config.getConfigParameter<int>("dimension"))
+            switch (_mesh_vec[0]->getDimension())
             {
                 case 2:
                     process = ProcessLib::SmallDeformation::
diff --git a/ProcessLib/SmallDeformation/CreateLocalAssemblers.h b/ProcessLib/SmallDeformation/CreateLocalAssemblers.h
index efeb85943ba80af7017227e2f348385009f27776..5a39df9f1562881803ed82b5ec892a9c00bbf68c 100644
--- a/ProcessLib/SmallDeformation/CreateLocalAssemblers.h
+++ b/ProcessLib/SmallDeformation/CreateLocalAssemblers.h
@@ -22,9 +22,8 @@ namespace SmallDeformation
 {
 namespace detail
 {
-template <unsigned GlobalDim, int DisplacementDim,
-          template <typename, typename, unsigned, int>
-          class LocalAssemblerImplementation,
+template <int GlobalDim,
+          template <typename, typename, int> class LocalAssemblerImplementation,
           typename LocalAssemblerInterface, typename... ExtraCtorArgs>
 void createLocalAssemblers(
     NumLib::LocalToGlobalIndexMap const& dof_table,
@@ -36,7 +35,7 @@ void createLocalAssemblers(
     using LocalDataInitializer =
         LocalDataInitializer<LocalAssemblerInterface,
                              LocalAssemblerImplementation, GlobalDim,
-                             DisplacementDim, ExtraCtorArgs...>;
+                             ExtraCtorArgs...>;
 
     DBUG("Create local assemblers.");
     // Populate the vector of local assemblers.
@@ -65,12 +64,10 @@ void createLocalAssemblers(
  * The first two template parameters cannot be deduced from the arguments.
  * Therefore they always have to be provided manually.
  */
-template <int DisplacementDim,
-          template <typename, typename, unsigned, int>
-          class LocalAssemblerImplementation,
+template <int GlobalDim,
+          template <typename, typename, int> class LocalAssemblerImplementation,
           typename LocalAssemblerInterface, typename... ExtraCtorArgs>
 void createLocalAssemblers(
-    const unsigned dimension,
     std::vector<MeshLib::Element*> const& mesh_elements,
     NumLib::LocalToGlobalIndexMap const& dof_table,
     std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
@@ -78,25 +75,9 @@ void createLocalAssemblers(
 {
     DBUG("Create local assemblers.");
 
-    switch (dimension)
-    {
-        case 2:
-            detail::createLocalAssemblers<2, DisplacementDim,
-                                          LocalAssemblerImplementation>(
-                dof_table, mesh_elements, local_assemblers,
-                std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-            break;
-        case 3:
-            detail::createLocalAssemblers<3, DisplacementDim,
-                                          LocalAssemblerImplementation>(
-                dof_table, mesh_elements, local_assemblers,
-                std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-            break;
-        default:
-            OGS_FATAL(
-                "Meshes with dimension different than two and three are not "
-                "supported.");
-    }
+    detail::createLocalAssemblers<GlobalDim, LocalAssemblerImplementation>(
+        dof_table, mesh_elements, local_assemblers,
+        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
 }
 }  // SmallDeformation
 
diff --git a/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.cpp b/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.cpp
index b326950c169a258ab46de4a01ceca9aaef0838dc..ceb84f4daed87b3042c703bbadf2a4b382acdd17 100644
--- a/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.cpp
+++ b/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.cpp
@@ -23,11 +23,6 @@ namespace ProcessLib
 {
 namespace SmallDeformation
 {
-template <int DisplacementDim>
-class SmallDeformationProcess;
-
-extern template class SmallDeformationProcess<2>;
-extern template class SmallDeformationProcess<3>;
 
 template <int DisplacementDim>
 std::unique_ptr<Process>
diff --git a/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.h b/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.h
index 45d2a6e7638f992917f6c557dddd18e3fdb7777a..3f7f783b25f449151b871b9401723290e40f5537 100644
--- a/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.h
+++ b/ProcessLib/SmallDeformation/CreateSmallDeformationProcess.h
@@ -9,8 +9,24 @@
 
 #pragma once
 
-#include "MaterialLib/SolidModels/CreateLubby2.h"
-#include "ProcessLib/Process.h"
+#include <memory>
+#include <vector>
+
+namespace BaseLib
+{
+class ConfigTree;
+}
+namespace MeshLib
+{
+class Mesh;
+}
+namespace ProcessLib
+{
+class AbstractJacobianAssembler;
+struct ParameterBase;
+class Process;
+class ProcessVariable;
+}
 
 namespace ProcessLib
 {
@@ -25,5 +41,21 @@ std::unique_ptr<Process> createSmallDeformationProcess(
     unsigned const integration_order,
     BaseLib::ConfigTree const& config);
 
+extern template std::unique_ptr<Process> createSmallDeformationProcess<2>(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config);
+
+extern template std::unique_ptr<Process> createSmallDeformationProcess<3>(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config);
+
 }  // namespace SmallDeformation
 }  // namespace ProcessLib
diff --git a/ProcessLib/SmallDeformation/LocalAssemblerInterface.h b/ProcessLib/SmallDeformation/LocalAssemblerInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..01c7f48fa3612ff60019bcde5e484f6b970cd6ef
--- /dev/null
+++ b/ProcessLib/SmallDeformation/LocalAssemblerInterface.h
@@ -0,0 +1,63 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "NumLib/Extrapolation/ExtrapolatableElement.h"
+#include "ProcessLib/LocalAssemblerInterface.h"
+
+namespace ProcessLib
+{
+namespace SmallDeformation
+{
+struct SmallDeformationLocalAssemblerInterface
+    : public ProcessLib::LocalAssemblerInterface,
+      public NumLib::ExtrapolatableElement
+{
+    virtual std::vector<double> const& getIntPtSigmaXX(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaYY(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaZZ(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaXY(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaXZ(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtSigmaYZ(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonXX(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonYY(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonZZ(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonXY(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonXZ(
+        std::vector<double>& cache) const = 0;
+
+    virtual std::vector<double> const& getIntPtEpsilonYZ(
+        std::vector<double>& cache) const = 0;
+};
+
+}  // namespace SmallDeformation
+}  // namespace ProcessLib
diff --git a/ProcessLib/SmallDeformation/LocalDataInitializer.h b/ProcessLib/SmallDeformation/LocalDataInitializer.h
index ee730dce4b7479b2876ac884e4b21f9fdff67216..284373dd68acc47b2ac4616392c5cf36b1d5b7bd 100644
--- a/ProcessLib/SmallDeformation/LocalDataInitializer.h
+++ b/ProcessLib/SmallDeformation/LocalDataInitializer.h
@@ -110,8 +110,9 @@ namespace ProcessLib
 /// For example for MeshLib::Quad a local assembler data with template argument
 /// NumLib::ShapeQuad4 is created.
 template <typename LocalAssemblerInterface,
-          template <typename, typename, unsigned, int> class LocalAssemblerData,
-          unsigned GlobalDim, int DisplacementDim, typename... ConstructorArgs>
+          template <typename, typename, int>
+          class SmallDeformationLocalAssembler,
+          int GlobalDim, typename... ConstructorArgs>
 class LocalDataInitializer final
 {
 public:
@@ -245,9 +246,8 @@ private:
         typename ShapeFunction::MeshElement>::IntegrationMethod;
 
     template <typename ShapeFunction>
-    using LAData =
-        LocalAssemblerData<ShapeFunction, IntegrationMethod<ShapeFunction>,
-                           GlobalDim, DisplacementDim>;
+    using LAData = SmallDeformationLocalAssembler<
+        ShapeFunction, IntegrationMethod<ShapeFunction>, GlobalDim>;
 
     /// A helper forwarding to the correct version of makeLocalAssemblerBuilder
     /// depending whether the global dimension is less than the shape function's
diff --git a/ProcessLib/SmallDeformation/SmallDeformationFEM.h b/ProcessLib/SmallDeformation/SmallDeformationFEM.h
index c636580640c988a12d131d4e5d4f3f5d6330dfc6..1ddad16f816b2e012217084111436422be9bf9d8 100644
--- a/ProcessLib/SmallDeformation/SmallDeformationFEM.h
+++ b/ProcessLib/SmallDeformation/SmallDeformationFEM.h
@@ -71,47 +71,6 @@ struct SecondaryData
     std::vector<ShapeMatrixType, Eigen::aligned_allocator<ShapeMatrixType>> N;
 };
 
-struct SmallDeformationLocalAssemblerInterface
-    : public ProcessLib::LocalAssemblerInterface,
-      public NumLib::ExtrapolatableElement
-{
-    virtual std::vector<double> const& getIntPtSigmaXX(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtSigmaYY(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtSigmaZZ(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtSigmaXY(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtSigmaXZ(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtSigmaYZ(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtEpsilonXX(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtEpsilonYY(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtEpsilonZZ(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtEpsilonXY(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtEpsilonXZ(
-        std::vector<double>& cache) const = 0;
-
-    virtual std::vector<double> const& getIntPtEpsilonYZ(
-        std::vector<double>& cache) const = 0;
-};
-
 template <typename ShapeFunction, typename IntegrationMethod,
           int DisplacementDim>
 class SmallDeformationLocalAssembler
@@ -406,29 +365,5 @@ private:
     bool const _is_axially_symmetric;
 };
 
-template <typename ShapeFunction, typename IntegrationMethod,
-          unsigned GlobalDim, int DisplacementDim>
-class LocalAssemblerData final
-    : public SmallDeformationLocalAssembler<ShapeFunction, IntegrationMethod,
-                                            DisplacementDim>
-{
-public:
-    LocalAssemblerData(LocalAssemblerData const&) = delete;
-    LocalAssemblerData(LocalAssemblerData&&) = delete;
-
-    LocalAssemblerData(
-        MeshLib::Element const& e,
-        std::size_t const local_matrix_size,
-        bool is_axially_symmetric,
-        unsigned const integration_order,
-        SmallDeformationProcessData<DisplacementDim>& process_data)
-        : SmallDeformationLocalAssembler<ShapeFunction, IntegrationMethod,
-                                         DisplacementDim>(
-              e, local_matrix_size, is_axially_symmetric, integration_order,
-              process_data)
-    {
-    }
-};
-
 }  // namespace SmallDeformation
 }  // namespace ProcessLib
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess-fwd.h b/ProcessLib/SmallDeformation/SmallDeformationProcess-fwd.h
deleted file mode 100644
index 0022328eded4c434872ff36fcee2ccf955a03740..0000000000000000000000000000000000000000
--- a/ProcessLib/SmallDeformation/SmallDeformationProcess-fwd.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * \copyright
- * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- *
- */
-
-#pragma once
-
-#include "SmallDeformationProcess.h"
-
-extern template class ProcessLib::SmallDeformation::SmallDeformationProcess<2>;
-extern template class ProcessLib::SmallDeformation::SmallDeformationProcess<3>;
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess-impl.h b/ProcessLib/SmallDeformation/SmallDeformationProcess-impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1212b69a419f865ac19ef0c47c70e9a0f54454d
--- /dev/null
+++ b/ProcessLib/SmallDeformation/SmallDeformationProcess-impl.h
@@ -0,0 +1,198 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include <cassert>
+
+#include "ProcessLib/Process.h"
+#include "ProcessLib/SmallDeformation/CreateLocalAssemblers.h"
+
+#include "SmallDeformationFEM.h"
+
+namespace ProcessLib
+{
+namespace SmallDeformation
+{
+template <int DisplacementDim>
+SmallDeformationProcess<DisplacementDim>::SmallDeformationProcess(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    std::vector<std::reference_wrapper<ProcessVariable>>&& process_variables,
+    SmallDeformationProcessData<DisplacementDim>&& process_data,
+    SecondaryVariableCollection&& secondary_variables,
+    NumLib::NamedFunctionCaller&& named_function_caller)
+    : Process(mesh, std::move(jacobian_assembler), parameters,
+              integration_order, std::move(process_variables),
+              std::move(secondary_variables), std::move(named_function_caller)),
+      _process_data(std::move(process_data))
+{
+    _nodal_forces = MeshLib::getOrCreateMeshProperty<double>(
+        mesh, "NodalForces", MeshLib::MeshItemType::Node, DisplacementDim);
+}
+
+template <int DisplacementDim>
+bool SmallDeformationProcess<DisplacementDim>::isLinear() const
+{
+    return false;
+}
+
+template <int DisplacementDim>
+void SmallDeformationProcess<DisplacementDim>::initializeConcreteProcess(
+    NumLib::LocalToGlobalIndexMap const& dof_table,
+    MeshLib::Mesh const& mesh,
+    unsigned const integration_order)
+{
+    ProcessLib::SmallDeformation::createLocalAssemblers<
+        DisplacementDim, SmallDeformationLocalAssembler>(
+        mesh.getElements(), dof_table, _local_assemblers,
+        mesh.isAxiallySymmetric(), integration_order, _process_data);
+
+    // TODO move the two data members somewhere else.
+    // for extrapolation of secondary variables
+    std::vector<MeshLib::MeshSubsets> all_mesh_subsets_single_component;
+    all_mesh_subsets_single_component.emplace_back(
+        _mesh_subset_all_nodes.get());
+    _local_to_global_index_map_single_component =
+        std::make_unique<NumLib::LocalToGlobalIndexMap>(
+            std::move(all_mesh_subsets_single_component),
+            // by location order is needed for output
+            NumLib::ComponentOrder::BY_LOCATION);
+    _nodal_forces->resize(DisplacementDim * mesh.getNumberOfNodes());
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "sigma_xx", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtSigmaXX));
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "sigma_yy", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtSigmaYY));
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "sigma_zz", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtSigmaZZ));
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "sigma_xy", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtSigmaXY));
+
+    if (DisplacementDim == 3)
+    {
+        Base::_secondary_variables.addSecondaryVariable(
+            "sigma_xz", 1,
+            makeExtrapolator(
+                getExtrapolator(), _local_assemblers,
+                &SmallDeformationLocalAssemblerInterface::getIntPtSigmaXZ));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "sigma_yz", 1,
+            makeExtrapolator(
+                getExtrapolator(), _local_assemblers,
+                &SmallDeformationLocalAssemblerInterface::getIntPtSigmaYZ));
+    }
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "epsilon_xx", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonXX));
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "epsilon_yy", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonYY));
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "epsilon_zz", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonZZ));
+
+    Base::_secondary_variables.addSecondaryVariable(
+        "epsilon_xy", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonXY));
+    if (DisplacementDim == 3)
+    {
+        Base::_secondary_variables.addSecondaryVariable(
+            "epsilon_yz", 1,
+            makeExtrapolator(
+                getExtrapolator(), _local_assemblers,
+                &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonYZ));
+
+        Base::_secondary_variables.addSecondaryVariable(
+            "epsilon_xz", 1,
+            makeExtrapolator(
+                getExtrapolator(), _local_assemblers,
+                &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonXZ));
+    }
+}
+
+template <int DisplacementDim>
+void SmallDeformationProcess<DisplacementDim>::assembleConcreteProcess(
+    const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K,
+    GlobalVector& b, StaggeredCouplingTerm const& coupling_term)
+{
+    DBUG("Assemble SmallDeformationProcess.");
+
+    // Call global assembler for each local assembly item.
+    GlobalExecutor::executeMemberDereferenced(
+        _global_assembler, &VectorMatrixAssembler::assemble, _local_assemblers,
+        *_local_to_global_index_map, t, x, M, K, b, coupling_term);
+}
+
+template <int DisplacementDim>
+void SmallDeformationProcess<DisplacementDim>::
+    assembleWithJacobianConcreteProcess(
+        const double t, GlobalVector const& x, GlobalVector const& xdot,
+        const double dxdot_dx, const double dx_dx, GlobalMatrix& M,
+        GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac,
+        StaggeredCouplingTerm const& coupling_term)
+{
+    DBUG("AssembleWithJacobian SmallDeformationProcess.");
+
+    // Call global assembler for each local assembly item.
+    GlobalExecutor::executeMemberDereferenced(
+        _global_assembler, &VectorMatrixAssembler::assembleWithJacobian,
+        _local_assemblers, *_local_to_global_index_map, t, x, xdot, dxdot_dx,
+        dx_dx, M, K, b, Jac, coupling_term);
+
+    b.copyValues(*_nodal_forces);
+    std::transform(_nodal_forces->begin(), _nodal_forces->end(),
+                   _nodal_forces->begin(), [](double val) { return -val; });
+}
+
+template <int DisplacementDim>
+void SmallDeformationProcess<DisplacementDim>::preTimestepConcreteProcess(
+    GlobalVector const& x, double const t, double const dt)
+{
+    DBUG("PreTimestep SmallDeformationProcess.");
+
+    _process_data.dt = dt;
+    _process_data.t = t;
+
+    GlobalExecutor::executeMemberOnDereferenced(
+        &SmallDeformationLocalAssemblerInterface::preTimestep,
+        _local_assemblers, *_local_to_global_index_map, x, t, dt);
+}
+
+}  // namespace SmallDeformation
+}  // namespace ProcessLib
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
index 9d660d13acce43ae13347a85558c36f6a6b3a447..6aafdb38ce36af31fddcbf4ac6e0da54ec2f44bd 100644
--- a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
+++ b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
@@ -7,8 +7,8 @@
  *
  */
 
-#include "SmallDeformationProcess-fwd.h"
 #include "SmallDeformationProcess.h"
+#include "SmallDeformationProcess-impl.h"
 
 namespace ProcessLib
 {
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess.h b/ProcessLib/SmallDeformation/SmallDeformationProcess.h
index 7cfc20a71d3df7a6fafa77ffe0f860972a69fed3..4cc68df5e74f760931ca82f0ef23dc4a3d5933ea 100644
--- a/ProcessLib/SmallDeformation/SmallDeformationProcess.h
+++ b/ProcessLib/SmallDeformation/SmallDeformationProcess.h
@@ -9,12 +9,8 @@
 
 #pragma once
 
-#include <cassert>
-
+#include "LocalAssemblerInterface.h"
 #include "ProcessLib/Process.h"
-#include "ProcessLib/SmallDeformation/CreateLocalAssemblers.h"
-
-#include "SmallDeformationFEM.h"
 #include "SmallDeformationProcessData.h"
 
 namespace ProcessLib
@@ -37,21 +33,11 @@ public:
             process_variables,
         SmallDeformationProcessData<DisplacementDim>&& process_data,
         SecondaryVariableCollection&& secondary_variables,
-        NumLib::NamedFunctionCaller&& named_function_caller)
-        : Process(mesh, std::move(jacobian_assembler), parameters,
-                  integration_order, std::move(process_variables),
-                  std::move(secondary_variables),
-                  std::move(named_function_caller)),
-          _process_data(std::move(process_data))
-    {
-        _nodal_forces = MeshLib::getOrCreateMeshProperty<double>(
-            mesh, "NodalForces", MeshLib::MeshItemType::Node, DisplacementDim);
-    }
+        NumLib::NamedFunctionCaller&& named_function_caller);
 
     //! \name ODESystem interface
     //! @{
-
-    bool isLinear() const override { return false; }
+    bool isLinear() const override;
     //! @}
 
 private:
@@ -60,149 +46,20 @@ private:
     void initializeConcreteProcess(
         NumLib::LocalToGlobalIndexMap const& dof_table,
         MeshLib::Mesh const& mesh,
-        unsigned const integration_order) override
-    {
-        ProcessLib::SmallDeformation::createLocalAssemblers<DisplacementDim,
-                                                            LocalAssemblerData>(
-            mesh.getDimension(), mesh.getElements(), dof_table,
-            _local_assemblers, mesh.isAxiallySymmetric(), integration_order,
-            _process_data);
-
-        // TODO move the two data members somewhere else.
-        // for extrapolation of secondary variables
-        std::vector<MeshLib::MeshSubsets> all_mesh_subsets_single_component;
-        all_mesh_subsets_single_component.emplace_back(
-            _mesh_subset_all_nodes.get());
-        _local_to_global_index_map_single_component =
-            std::make_unique<NumLib::LocalToGlobalIndexMap>(
-                std::move(all_mesh_subsets_single_component),
-                // by location order is needed for output
-                NumLib::ComponentOrder::BY_LOCATION);
-        _nodal_forces->resize(DisplacementDim * mesh.getNumberOfNodes());
-
-        Base::_secondary_variables.addSecondaryVariable(
-            "sigma_xx", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtSigmaXX));
-
-        Base::_secondary_variables.addSecondaryVariable(
-            "sigma_yy", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtSigmaYY));
-
-        Base::_secondary_variables.addSecondaryVariable(
-            "sigma_zz", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtSigmaZZ));
-
-        Base::_secondary_variables.addSecondaryVariable(
-            "sigma_xy", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtSigmaXY));
-
-        if (DisplacementDim == 3) {
-            Base::_secondary_variables.addSecondaryVariable(
-                "sigma_xz", 1,
-                makeExtrapolator(
-                    getExtrapolator(), _local_assemblers,
-                    &SmallDeformationLocalAssemblerInterface::getIntPtSigmaXZ));
-
-            Base::_secondary_variables.addSecondaryVariable(
-                "sigma_yz", 1,
-                makeExtrapolator(
-                    getExtrapolator(), _local_assemblers,
-                    &SmallDeformationLocalAssemblerInterface::getIntPtSigmaYZ));
-        }
-
-        Base::_secondary_variables.addSecondaryVariable(
-            "epsilon_xx", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonXX));
+        unsigned const integration_order) override;
 
-        Base::_secondary_variables.addSecondaryVariable(
-            "epsilon_yy", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonYY));
-
-        Base::_secondary_variables.addSecondaryVariable(
-            "epsilon_zz", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonZZ));
-
-        Base::_secondary_variables.addSecondaryVariable(
-            "epsilon_xy", 1,
-            makeExtrapolator(
-                getExtrapolator(), _local_assemblers,
-                &SmallDeformationLocalAssemblerInterface::getIntPtEpsilonXY));
-        if (DisplacementDim == 3)
-        {
-            Base::_secondary_variables.addSecondaryVariable(
-                "epsilon_yz", 1,
-                makeExtrapolator(getExtrapolator(), _local_assemblers,
-                                 &SmallDeformationLocalAssemblerInterface::
-                                     getIntPtEpsilonYZ));
-
-            Base::_secondary_variables.addSecondaryVariable(
-                "epsilon_xz", 1,
-                makeExtrapolator(getExtrapolator(), _local_assemblers,
-                                 &SmallDeformationLocalAssemblerInterface::
-                                     getIntPtEpsilonXZ));
-        }
-    }
-
-    void assembleConcreteProcess(const double t, GlobalVector const& x,
-                                 GlobalMatrix& M, GlobalMatrix& K,
-                                 GlobalVector& b,
-                                 StaggeredCouplingTerm const&
-                                 coupling_term) override
-    {
-        DBUG("Assemble SmallDeformationProcess.");
-
-        // Call global assembler for each local assembly item.
-        GlobalExecutor::executeMemberDereferenced(
-            _global_assembler, &VectorMatrixAssembler::assemble,
-            _local_assemblers, *_local_to_global_index_map, t, x, M, K, b,
-            coupling_term);
-    }
+    void assembleConcreteProcess(
+        const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K,
+        GlobalVector& b, StaggeredCouplingTerm const& coupling_term) override;
 
     void assembleWithJacobianConcreteProcess(
         const double t, GlobalVector const& x, GlobalVector const& xdot,
         const double dxdot_dx, const double dx_dx, GlobalMatrix& M,
         GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac,
-        StaggeredCouplingTerm const& coupling_term) override
-    {
-        DBUG("AssembleWithJacobian SmallDeformationProcess.");
-
-        // Call global assembler for each local assembly item.
-        GlobalExecutor::executeMemberDereferenced(
-            _global_assembler, &VectorMatrixAssembler::assembleWithJacobian,
-            _local_assemblers, *_local_to_global_index_map, t, x, xdot,
-            dxdot_dx, dx_dx, M, K, b, Jac, coupling_term);
-
-        b.copyValues(*_nodal_forces);
-        std::transform(_nodal_forces->begin(), _nodal_forces->end(),
-            _nodal_forces->begin(), [](double val) { return -val;});
-    }
+        StaggeredCouplingTerm const& coupling_term) override;
 
     void preTimestepConcreteProcess(GlobalVector const& x, double const t,
-                                    double const dt) override
-    {
-        DBUG("PreTimestep SmallDeformationProcess.");
-
-        _process_data.dt = dt;
-        _process_data.t = t;
-
-        GlobalExecutor::executeMemberOnDereferenced(
-            &SmallDeformationLocalAssemblerInterface::preTimestep,
-            _local_assemblers, *_local_to_global_index_map, x, t, dt);
-    }
+                                    double const dt) override;
 
 private:
     SmallDeformationProcessData<DisplacementDim> _process_data;
@@ -214,5 +71,8 @@ private:
     MeshLib::PropertyVector<double>* _nodal_forces = nullptr;
 };
 
+extern template class SmallDeformationProcess<2>;
+extern template class SmallDeformationProcess<3>;
+
 }  // namespace SmallDeformation
 }  // namespace ProcessLib
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcessData.h b/ProcessLib/SmallDeformation/SmallDeformationProcessData.h
index 72e9dbae7552a457ef8ca163b56b27e11a2ff7cb..3aca5d5630dc0f8263ec91a3bdf41523a00dd6c2 100644
--- a/ProcessLib/SmallDeformation/SmallDeformationProcessData.h
+++ b/ProcessLib/SmallDeformation/SmallDeformationProcessData.h
@@ -9,6 +9,14 @@
 
 #pragma once
 
+namespace MaterialLib
+{
+namespace Solids
+{
+template <int DisplacementDim>
+struct MechanicsBase;
+}
+}
 namespace ProcessLib
 {
 namespace SmallDeformation
diff --git a/Tests/Data b/Tests/Data
index 19d23ab1b47a71dfccd7cc855c5b273e11b01314..e214a64260f54912407cafd30ffa33baf308f492 160000
--- a/Tests/Data
+++ b/Tests/Data
@@ -1 +1 @@
-Subproject commit 19d23ab1b47a71dfccd7cc855c5b273e11b01314
+Subproject commit e214a64260f54912407cafd30ffa33baf308f492