diff --git a/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp b/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp
index f7fca31e3c1baedd353ca5cf6646aa7c996ac2c6..fa23c26a5bcac8694bf7b01f25bd11e79dd70198 100644
--- a/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp
+++ b/ProcessLib/ComponentTransport/ComponentTransportProcess.cpp
@@ -63,7 +63,7 @@ void ComponentTransportProcess::assembleConcreteProcess(
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void ComponentTransportProcess::assembleWithJacobianConcreteProcess(
@@ -77,7 +77,7 @@ void ComponentTransportProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 }  // namespace ComponentTransport
diff --git a/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.cpp b/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.cpp
index 43a2c3cd2bc62f1f11b3fdb7784b5aca780a0176..51a7bbf2ba6e40e084e024a9628c774935670e08 100644
--- a/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.cpp
+++ b/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.cpp
@@ -68,7 +68,7 @@ void GroundwaterFlowProcess::assembleConcreteProcess(const double t,
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void GroundwaterFlowProcess::assembleWithJacobianConcreteProcess(
@@ -82,7 +82,7 @@ void GroundwaterFlowProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 }   // namespace GroundwaterFlow
diff --git a/ProcessLib/HT/HTProcess.cpp b/ProcessLib/HT/HTProcess.cpp
index d17adcfe99dba7b44dd5962fbf252862dffb1ff0..d371b551706a58e455da2879c71f4d62617d55f3 100644
--- a/ProcessLib/HT/HTProcess.cpp
+++ b/ProcessLib/HT/HTProcess.cpp
@@ -62,7 +62,7 @@ void HTProcess::assembleConcreteProcess(const double t,
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void HTProcess::assembleWithJacobianConcreteProcess(
@@ -76,7 +76,7 @@ void HTProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 }  // namespace HT
diff --git a/ProcessLib/HeatConduction/HeatConductionProcess.cpp b/ProcessLib/HeatConduction/HeatConductionProcess.cpp
index 049fabc012261e297929166099476d043250ad69..7e6ce63d9921c47cbe01feb48643e13e0bb66d03 100644
--- a/ProcessLib/HeatConduction/HeatConductionProcess.cpp
+++ b/ProcessLib/HeatConduction/HeatConductionProcess.cpp
@@ -95,7 +95,7 @@ void HeatConductionProcess::assembleConcreteProcess(const double t,
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void HeatConductionProcess::assembleWithJacobianConcreteProcess(
@@ -109,7 +109,7 @@ void HeatConductionProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 void HeatConductionProcess::computeSecondaryVariableConcrete(
@@ -119,7 +119,7 @@ void HeatConductionProcess::computeSecondaryVariableConcrete(
     GlobalExecutor::executeMemberOnDereferenced(
             &HeatConductionLocalAssemblerInterface::computeSecondaryVariable,
             _local_assemblers, *_local_to_global_index_map, t, x,
-            *_coupling_term.lock());
+            _coupling_term);
 }
 
 }  // namespace HeatConduction
diff --git a/ProcessLib/HydroMechanics/HydroMechanicsProcess-impl.h b/ProcessLib/HydroMechanics/HydroMechanicsProcess-impl.h
index d9ec27acec176bfffb750439dd54aa0de9feea60..ee8477b123b1e1fdbd73e12cce1670e5daa4e90f 100644
--- a/ProcessLib/HydroMechanics/HydroMechanicsProcess-impl.h
+++ b/ProcessLib/HydroMechanics/HydroMechanicsProcess-impl.h
@@ -192,7 +192,7 @@ void HydroMechanicsProcess<DisplacementDim>::assembleConcreteProcess(
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 template <int DisplacementDim>
@@ -208,7 +208,7 @@ void HydroMechanicsProcess<DisplacementDim>::
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 template <int DisplacementDim>
 void HydroMechanicsProcess<DisplacementDim>::preTimestepConcreteProcess(
diff --git a/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.cpp b/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.cpp
index c063da8245674f0a6470da941c8e900cfbd65c7b..ac106b37e4939f51677c361f8e52c433db9d8a7a 100644
--- a/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.cpp
+++ b/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.cpp
@@ -408,7 +408,7 @@ void HydroMechanicsProcess<GlobalDim>::computeSecondaryVariableConcrete(
     GlobalExecutor::executeMemberOnDereferenced(
         &HydroMechanicsLocalAssemblerInterface::computeSecondaryVariable,
         _local_assemblers, *_local_to_global_index_map, t, x,
-        *_coupling_term.lock());
+        _coupling_term);
 
     // Copy displacement jumps in a solution vector to mesh property
     // Remark: the copy is required because mesh properties for primary
diff --git a/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.h b/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.h
index 93683310f80a3891a16052cc16f6118864cbc796..92bce62c4e0e64e42b34bc533e33fbc6cfa1482d 100644
--- a/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.h
+++ b/ProcessLib/LIE/HydroMechanics/HydroMechanicsProcess.h
@@ -75,7 +75,7 @@ private:
         GlobalExecutor::executeMemberDereferenced(
             _global_assembler, &VectorMatrixAssembler::assemble,
             _local_assemblers, *_local_to_global_index_map, t, x, M, K, b,
-            *_coupling_term.lock());
+            _coupling_term);
     }
 
     void assembleWithJacobianConcreteProcess(
@@ -89,7 +89,7 @@ private:
         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.lock());
+            dxdot_dx, dx_dx, M, K, b, Jac, _coupling_term);
     }
 
     void preTimestepConcreteProcess(GlobalVector const& x, double const t,
diff --git a/ProcessLib/LIE/SmallDeformation/SmallDeformationProcess.h b/ProcessLib/LIE/SmallDeformation/SmallDeformationProcess.h
index fd91315c3dc305039fee56f2946af0146cf2f4dc..5679efc544e806079deb4b76ad532f3434ae59ee 100644
--- a/ProcessLib/LIE/SmallDeformation/SmallDeformationProcess.h
+++ b/ProcessLib/LIE/SmallDeformation/SmallDeformationProcess.h
@@ -73,7 +73,7 @@ private:
         GlobalExecutor::executeMemberDereferenced(
             _global_assembler, &VectorMatrixAssembler::assemble,
             _local_assemblers, *_local_to_global_index_map, t, x, M, K, b,
-            *_coupling_term.lock());
+            _coupling_term);
     }
 
     void assembleWithJacobianConcreteProcess(
@@ -87,7 +87,7 @@ private:
         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.lock());
+            dxdot_dx, dx_dx, M, K, b, Jac, _coupling_term);
     }
 
     void preTimestepConcreteProcess(GlobalVector const& x, double const t,
diff --git a/ProcessLib/LiquidFlow/LiquidFlowProcess.cpp b/ProcessLib/LiquidFlow/LiquidFlowProcess.cpp
index 91236ab430d7aeafa3e1f48271ae5f9da1970dc3..68a7e6552d5330857b98bc750fc66abfd17a004c 100644
--- a/ProcessLib/LiquidFlow/LiquidFlowProcess.cpp
+++ b/ProcessLib/LiquidFlow/LiquidFlowProcess.cpp
@@ -100,7 +100,7 @@ void LiquidFlowProcess::assembleConcreteProcess(
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void LiquidFlowProcess::assembleWithJacobianConcreteProcess(
@@ -114,7 +114,7 @@ void LiquidFlowProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 void LiquidFlowProcess::computeSecondaryVariableConcrete(
@@ -125,7 +125,7 @@ void LiquidFlowProcess::computeSecondaryVariableConcrete(
     GlobalExecutor::executeMemberOnDereferenced(
         &LiquidFlowLocalAssemblerInterface::computeSecondaryVariable,
         _local_assemblers, *_local_to_global_index_map, t, x,
-        *_coupling_term.lock());
+        _coupling_term);
 }
 
 }  // end of namespace
diff --git a/ProcessLib/LocalAssemblerInterface.cpp b/ProcessLib/LocalAssemblerInterface.cpp
index 0732fd810248f3a57ea15a6d24cd4e8c71352049..eb90cdbdb3523200eb2964ba0f9961b31f6f81e2 100644
--- a/ProcessLib/LocalAssemblerInterface.cpp
+++ b/ProcessLib/LocalAssemblerInterface.cpp
@@ -11,6 +11,8 @@
 #include <cassert>
 #include "NumLib/DOF/DOFTableUtil.h"
 
+#include "StaggeredCouplingTerm.h"
+
 namespace ProcessLib
 {
 void LocalAssemblerInterface::assembleWithCoupledTerm(
@@ -55,19 +57,19 @@ void LocalAssemblerInterface::assembleWithJacobianAndCoupling(
 void LocalAssemblerInterface::computeSecondaryVariable(
     std::size_t const mesh_item_id,
     NumLib::LocalToGlobalIndexMap const& dof_table, double const t,
-    GlobalVector const& x, StaggeredCouplingTerm const& coupled_term)
+    GlobalVector const& x, StaggeredCouplingTerm const* coupled_term)
 {
     auto const indices = NumLib::getIndices(mesh_item_id, dof_table);
     auto const local_x = x.get(indices);
 
-    if (coupled_term.empty)
+    if (!coupled_term)
     {
         computeSecondaryVariableConcrete(t, local_x);
     }
     else
     {
         auto const local_coupled_xs =
-            getCurrentLocalSolutionsOfCoupledProcesses(coupled_term.coupled_xs,
+            getCurrentLocalSolutionsOfCoupledProcesses(coupled_term->coupled_xs,
                                                        indices);
         if (!local_coupled_xs.empty())
             computeSecondaryVariableWithCoupledProcessConcrete(
diff --git a/ProcessLib/LocalAssemblerInterface.h b/ProcessLib/LocalAssemblerInterface.h
index 34b88a5c461e0dce441e37f43c9c5b1282aae097..e81bd16290c9a30c251514b175d4306e480bbb07 100644
--- a/ProcessLib/LocalAssemblerInterface.h
+++ b/ProcessLib/LocalAssemblerInterface.h
@@ -15,7 +15,6 @@
 
 #include "NumLib/NumericsConfig.h"
 #include "MathLib/Point3d.h"
-#include "StaggeredCouplingTerm.h"
 
 namespace NumLib
 {
@@ -24,6 +23,8 @@ class LocalToGlobalIndexMap;
 
 namespace ProcessLib
 {
+struct StaggeredCouplingTerm;
+struct LocalCouplingTerm;
 
 /*! Common interface for local assemblers
  * NumLib::ODESystemTag::FirstOrderImplicitQuasilinear ODE systems.
@@ -67,7 +68,7 @@ public:
     virtual void computeSecondaryVariable(std::size_t const mesh_item_id,
                               NumLib::LocalToGlobalIndexMap const& dof_table,
                               const double t, GlobalVector const& x,
-                              StaggeredCouplingTerm const& coupled_term);
+                              StaggeredCouplingTerm const* coupled_term);
 
     virtual void preTimestep(std::size_t const mesh_item_id,
                              NumLib::LocalToGlobalIndexMap const& dof_table,
diff --git a/ProcessLib/PhaseField/PhaseFieldProcess.h b/ProcessLib/PhaseField/PhaseFieldProcess.h
index 97c3b24786cccf6eaa67df62dfe6e4be9d989b2b..6b02f7d187f34f1c0fbb8e085a7619f1ed377b75 100644
--- a/ProcessLib/PhaseField/PhaseFieldProcess.h
+++ b/ProcessLib/PhaseField/PhaseFieldProcess.h
@@ -191,7 +191,7 @@ private:
         GlobalExecutor::executeMemberDereferenced(
             _global_assembler, &VectorMatrixAssembler::assemble,
             _local_assemblers, *_local_to_global_index_map, t, x, M, K, b,
-            *_coupling_term.lock());
+            _coupling_term);
     }
 
     void assembleWithJacobianConcreteProcess(
@@ -205,7 +205,7 @@ private:
         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.lock());
+            dxdot_dx, dx_dx, M, K, b, Jac, _coupling_term);
     }
 
     void preTimestepConcreteProcess(GlobalVector const& x, double const t,
diff --git a/ProcessLib/Process.cpp b/ProcessLib/Process.cpp
index 95ee825f0f0ef85f0db9d8bcfee6cd5d7bcb569d..bb23d059b4356b074bf79e0dce74f52512577a2e 100644
--- a/ProcessLib/Process.cpp
+++ b/ProcessLib/Process.cpp
@@ -31,6 +31,7 @@ Process::Process(
       _secondary_variables(std::move(secondary_variables)),
       _named_function_caller(std::move(named_function_caller)),
       _global_assembler(std::move(jacobian_assembler)),
+      _coupling_term(nullptr),
       _integration_order(integration_order),
       _process_variables(std::move(process_variables)),
       _boundary_conditions(parameters)
diff --git a/ProcessLib/Process.h b/ProcessLib/Process.h
index 852c9abe454c4974b3abcafb7f910dde56867083..1e0a15beae4987439d286fc89f13a95ac63d61ea 100644
--- a/ProcessLib/Process.h
+++ b/ProcessLib/Process.h
@@ -70,8 +70,7 @@ public:
 
     MathLib::MatrixSpecifications getMatrixSpecifications() const final;
 
-    void setStaggeredCouplingTerm(
-        const std::shared_ptr<StaggeredCouplingTerm>& coupling_term)
+    void setStaggeredCouplingTerm(StaggeredCouplingTerm* const coupling_term)
     {
         _coupling_term = coupling_term;
     }
@@ -201,8 +200,10 @@ protected:
 
     VectorMatrixAssembler _global_assembler;
 
-    /// Coupled processes.
-    mutable std::weak_ptr<StaggeredCouplingTerm> _coupling_term;
+    /// Pointer to StaggeredCouplingTerm, which contains the references to the
+    /// coupled processes and the references to the solutions of the coupled
+    /// processes.
+    StaggeredCouplingTerm* _coupling_term;
 
     /// Order of the integration method for element-wise integration.
     /// The Gauss-Legendre integration method and available orders is
diff --git a/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp b/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp
index 7949d6ddc7cec486f6109ceb60dadc91a6477a1b..52372d654e5f211e23dd0d85647b2816f785ea82 100644
--- a/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp
+++ b/ProcessLib/RichardsFlow/RichardsFlowProcess.cpp
@@ -90,7 +90,7 @@ void RichardsFlowProcess::assembleConcreteProcess(
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void RichardsFlowProcess::assembleWithJacobianConcreteProcess(
@@ -104,7 +104,7 @@ void RichardsFlowProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 void RichardsFlowProcess::computeSecondaryVariableConcrete(
@@ -114,7 +114,7 @@ void RichardsFlowProcess::computeSecondaryVariableConcrete(
     GlobalExecutor::executeMemberOnDereferenced(
         &RichardsFlowLocalAssemblerInterface::computeSecondaryVariable,
         _local_assemblers, *_local_to_global_index_map, t, x,
-        *_coupling_term.lock());
+        _coupling_term);
 }
 
 }  // namespace RichardsFlow
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess-impl.h b/ProcessLib/SmallDeformation/SmallDeformationProcess-impl.h
index e1b87408b5903bb19d76d1b2dd0d4eec8c7feee5..b962917fbfbd1ea2aae174b901fa149da68076f3 100644
--- a/ProcessLib/SmallDeformation/SmallDeformationProcess-impl.h
+++ b/ProcessLib/SmallDeformation/SmallDeformationProcess-impl.h
@@ -211,7 +211,7 @@ void SmallDeformationProcess<DisplacementDim>::assembleConcreteProcess(
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 template <int DisplacementDim>
@@ -227,7 +227,7 @@ void SmallDeformationProcess<DisplacementDim>::
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 
     b.copyValues(*_nodal_forces);
     std::transform(_nodal_forces->begin(), _nodal_forces->end(),
diff --git a/ProcessLib/TES/TESProcess.cpp b/ProcessLib/TES/TESProcess.cpp
index 79523dbe73e218004a1498c3430d421ff5586d90..f1efbc72faff6cdc23fada43b888a9fe22240bd5 100644
--- a/ProcessLib/TES/TESProcess.cpp
+++ b/ProcessLib/TES/TESProcess.cpp
@@ -232,7 +232,7 @@ void TESProcess::assembleConcreteProcess(const double t,
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void TESProcess::assembleWithJacobianConcreteProcess(
@@ -243,7 +243,7 @@ void TESProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 void TESProcess::preTimestepConcreteProcess(GlobalVector const& x,
diff --git a/ProcessLib/ThermalTwoPhaseFlowWithPP/ThermalTwoPhaseFlowWithPPProcess.cpp b/ProcessLib/ThermalTwoPhaseFlowWithPP/ThermalTwoPhaseFlowWithPPProcess.cpp
index b9b82ddd421d475127518252bf7cc0b2a0cbf1bd..33a72db4761920709054de61c2d702ecf11b8a89 100644
--- a/ProcessLib/ThermalTwoPhaseFlowWithPP/ThermalTwoPhaseFlowWithPPProcess.cpp
+++ b/ProcessLib/ThermalTwoPhaseFlowWithPP/ThermalTwoPhaseFlowWithPPProcess.cpp
@@ -80,7 +80,7 @@ void ThermalTwoPhaseFlowWithPPProcess::assembleConcreteProcess(
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void ThermalTwoPhaseFlowWithPPProcess::assembleWithJacobianConcreteProcess(
@@ -94,7 +94,7 @@ void ThermalTwoPhaseFlowWithPPProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 void ThermalTwoPhaseFlowWithPPProcess::preTimestepConcreteProcess(
     GlobalVector const& x, double const t, double const delta_t)
diff --git a/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.h b/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.h
index 78e77d62a6b8a53600682cd0923ef57005d4b814..e0d9339821f2e73f32bec08410e0d0bf6578fdd5 100644
--- a/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.h
+++ b/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.h
@@ -164,7 +164,7 @@ private:
         GlobalExecutor::executeMemberDereferenced(
             _global_assembler, &VectorMatrixAssembler::assemble,
             _local_assemblers, *_local_to_global_index_map, t, x, M, K, b,
-            *_coupling_term.lock());
+            _coupling_term);
     }
 
     void assembleWithJacobianConcreteProcess(
@@ -178,7 +178,7 @@ private:
         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.lock());
+            dxdot_dx, dx_dx, M, K, b, Jac, _coupling_term);
     }
 
     void preTimestepConcreteProcess(GlobalVector const& x, double const t,
diff --git a/ProcessLib/TwoPhaseFlowWithPP/TwoPhaseFlowWithPPProcess.cpp b/ProcessLib/TwoPhaseFlowWithPP/TwoPhaseFlowWithPPProcess.cpp
index 1a08460b21df04fec00f9b69570f65e0284b6292..d64c5e6a9adbbf67a7291f919a927f696b9044ea 100644
--- a/ProcessLib/TwoPhaseFlowWithPP/TwoPhaseFlowWithPPProcess.cpp
+++ b/ProcessLib/TwoPhaseFlowWithPP/TwoPhaseFlowWithPPProcess.cpp
@@ -78,7 +78,7 @@ void TwoPhaseFlowWithPPProcess::assembleConcreteProcess(const double t,
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void TwoPhaseFlowWithPPProcess::assembleWithJacobianConcreteProcess(
@@ -92,7 +92,7 @@ void TwoPhaseFlowWithPPProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 
 }  // end of namespace
diff --git a/ProcessLib/TwoPhaseFlowWithPrho/TwoPhaseFlowWithPrhoProcess.cpp b/ProcessLib/TwoPhaseFlowWithPrho/TwoPhaseFlowWithPrhoProcess.cpp
index 2c6fd14e34d6f89ce3d39b86d2742217c3a55ece..a1a4f37bb2ec4d5f43540b584d7622f9b3848721 100644
--- a/ProcessLib/TwoPhaseFlowWithPrho/TwoPhaseFlowWithPrhoProcess.cpp
+++ b/ProcessLib/TwoPhaseFlowWithPrho/TwoPhaseFlowWithPrhoProcess.cpp
@@ -78,7 +78,7 @@ void TwoPhaseFlowWithPrhoProcess::assembleConcreteProcess(const double t,
     // 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.lock());
+        *_local_to_global_index_map, t, x, M, K, b, _coupling_term);
 }
 
 void TwoPhaseFlowWithPrhoProcess::assembleWithJacobianConcreteProcess(
@@ -92,7 +92,7 @@ void TwoPhaseFlowWithPrhoProcess::assembleWithJacobianConcreteProcess(
     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.lock());
+        dx_dx, M, K, b, Jac, _coupling_term);
 }
 void TwoPhaseFlowWithPrhoProcess::preTimestepConcreteProcess(
     GlobalVector const& x, double const t, double const dt)
diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp
index 1dccdef1d6bf5526d050142a3c7846ebc5724866..c025eb239aa410821dc598af87b873ff8e7ddcd0 100644
--- a/ProcessLib/UncoupledProcessesTimeLoop.cpp
+++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp
@@ -940,12 +940,11 @@ bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme(
                 spd->process.preTimestep(x, t, dt);
             }
 
-            std::shared_ptr<StaggeredCouplingTerm> coupling_term =
-                std::make_shared<StaggeredCouplingTerm>(
-                    spd->coupled_processes,
-                    _solutions_of_coupled_processes[pcs_idx], dt);
+            StaggeredCouplingTerm coupling_term(
+                spd->coupled_processes,
+                _solutions_of_coupled_processes[pcs_idx], dt);
 
-            spd->process.setStaggeredCouplingTerm(coupling_term);
+            spd->process.setStaggeredCouplingTerm(&coupling_term);
 
             const auto nonlinear_solver_succeeded = solveOneTimeStepOneProcess(
                 x, timestep_id, t, dt, *spd, *_output);
@@ -1021,11 +1020,10 @@ bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme(
         auto& x = *_process_solutions[pcs_idx];
         pcs.postTimestep(x);
 
-        std::shared_ptr<StaggeredCouplingTerm> coupling_term =
-            std::make_shared<StaggeredCouplingTerm>(
-                spd->coupled_processes,
-                _solutions_of_coupled_processes[pcs_idx], dt);
-        spd->process.setStaggeredCouplingTerm(coupling_term);
+        StaggeredCouplingTerm coupling_term(
+            spd->coupled_processes, _solutions_of_coupled_processes[pcs_idx],
+            dt);
+        spd->process.setStaggeredCouplingTerm(&coupling_term);
 
         pcs.computeSecondaryVariable(t, x);
 
diff --git a/ProcessLib/VectorMatrixAssembler.cpp b/ProcessLib/VectorMatrixAssembler.cpp
index 04b9e6ba71bccdd05b26d795828d6e436e9905ff..d638ca928f641e876a3bd3563d919e6de331b28a 100644
--- a/ProcessLib/VectorMatrixAssembler.cpp
+++ b/ProcessLib/VectorMatrixAssembler.cpp
@@ -59,7 +59,7 @@ void VectorMatrixAssembler::assemble(
     const std::size_t mesh_item_id, LocalAssemblerInterface& local_assembler,
     const NumLib::LocalToGlobalIndexMap& dof_table, const double t,
     const GlobalVector& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b,
-    const StaggeredCouplingTerm& coupling_term)
+    const StaggeredCouplingTerm* coupling_term)
 {
     auto const indices = NumLib::getIndices(mesh_item_id, dof_table);
     auto const local_x = x.get(indices);
@@ -68,17 +68,17 @@ void VectorMatrixAssembler::assemble(
     _local_K_data.clear();
     _local_b_data.clear();
 
-    if (coupling_term.empty)
+    if (!coupling_term)
     {
         local_assembler.assemble(t, local_x, _local_M_data, _local_K_data,
                                  _local_b_data);
     }
     else
     {
-        auto local_coupled_xs0 =
-            getPreviousLocalSolutionsOfCoupledProcesses(coupling_term, indices);
+        auto local_coupled_xs0 = getPreviousLocalSolutionsOfCoupledProcesses(
+            *coupling_term, indices);
         auto local_coupled_xs = getCurrentLocalSolutionsOfCoupledProcesses(
-            coupling_term.coupled_xs, indices);
+            coupling_term->coupled_xs, indices);
 
         if (local_coupled_xs0.empty() || local_coupled_xs.empty())
         {
@@ -88,7 +88,7 @@ void VectorMatrixAssembler::assemble(
         else
         {
             ProcessLib::LocalCouplingTerm local_coupling_term(
-                coupling_term.dt, coupling_term.coupled_processes,
+                coupling_term->dt, coupling_term->coupled_processes,
                 std::move(local_coupled_xs0), std::move(local_coupled_xs));
 
             local_assembler.assembleWithCoupledTerm(
@@ -123,7 +123,7 @@ void VectorMatrixAssembler::assembleWithJacobian(
     NumLib::LocalToGlobalIndexMap const& dof_table, 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, const StaggeredCouplingTerm& coupling_term)
+    GlobalMatrix& Jac, const StaggeredCouplingTerm* coupling_term)
 {
     auto const indices = NumLib::getIndices(mesh_item_id, dof_table);
     auto const local_x = x.get(indices);
@@ -134,7 +134,7 @@ void VectorMatrixAssembler::assembleWithJacobian(
     _local_b_data.clear();
     _local_Jac_data.clear();
 
-    if (coupling_term.empty)
+    if (!coupling_term)
     {
         _jacobian_assembler->assembleWithJacobian(
             local_assembler, t, local_x, local_xdot, dxdot_dx, dx_dx,
@@ -142,10 +142,10 @@ void VectorMatrixAssembler::assembleWithJacobian(
     }
     else
     {
-        auto local_coupled_xs0 =
-            getPreviousLocalSolutionsOfCoupledProcesses(coupling_term, indices);
+        auto local_coupled_xs0 = getPreviousLocalSolutionsOfCoupledProcesses(
+            *coupling_term, indices);
         auto local_coupled_xs = getCurrentLocalSolutionsOfCoupledProcesses(
-            coupling_term.coupled_xs, indices);
+            coupling_term->coupled_xs, indices);
         if (local_coupled_xs0.empty() || local_coupled_xs.empty())
         {
             _jacobian_assembler->assembleWithJacobian(
@@ -155,7 +155,7 @@ void VectorMatrixAssembler::assembleWithJacobian(
         else
         {
             ProcessLib::LocalCouplingTerm local_coupling_term(
-                coupling_term.dt, coupling_term.coupled_processes,
+                coupling_term->dt, coupling_term->coupled_processes,
                 std::move(local_coupled_xs0), std::move(local_coupled_xs));
 
             _jacobian_assembler->assembleWithJacobianAndCoupling(
diff --git a/ProcessLib/VectorMatrixAssembler.h b/ProcessLib/VectorMatrixAssembler.h
index 737805a75efab29cdfdf324bfb89dfb7661a4415..34e8ffa7acac382946118272db6596e62ae11a43 100644
--- a/ProcessLib/VectorMatrixAssembler.h
+++ b/ProcessLib/VectorMatrixAssembler.h
@@ -40,7 +40,7 @@ public:
                   NumLib::LocalToGlobalIndexMap const& dof_table,
                   double const t, GlobalVector const& x, GlobalMatrix& M,
                   GlobalMatrix& K, GlobalVector& b,
-                  const StaggeredCouplingTerm& coupling_term);
+                  const StaggeredCouplingTerm* coupling_term);
 
     //! Assembles \c M, \c K, \c b, and the Jacobian \c Jac of the residual.
     //! \note The Jacobian must be assembled.
@@ -52,7 +52,7 @@ public:
                               const double dx_dx, GlobalMatrix& M,
                               GlobalMatrix& K, GlobalVector& b,
                               GlobalMatrix& Jac,
-                              const StaggeredCouplingTerm& coupling_term);
+                              const StaggeredCouplingTerm* coupling_term);
 
 private:
     // temporary data only stored here in order to avoid frequent memory