diff --git a/MathLib/LinAlg/LinAlg.h b/MathLib/LinAlg/LinAlg.h
index 206395e8f907e2e72d3d30b5388030312cfdd7e9..038dd762743c42e75383f6b677ae17a31b9b6563 100644
--- a/MathLib/LinAlg/LinAlg.h
+++ b/MathLib/LinAlg/LinAlg.h
@@ -17,6 +17,8 @@
 
 #ifdef USE_PETSC
 #include <petscsystypes.h>
+
+#include "PETSc/PETScVector.h"
 #endif
 
 namespace MathLib
@@ -204,6 +206,14 @@ void linearSysNormalize(PETScMatrix const& A, PETScMatrix& new_A,
 void finalizeAssembly(PETScMatrix& A);
 void finalizeAssembly(PETScVector& x);
 
+// Reduce operations for interprocess communications while using Petsc
+static inline int reduceMin(int val)
+{
+    int result;
+    MPI_Allreduce(&val, &result, 1, MPI_INTEGER, MPI_MIN, PETSC_COMM_WORLD);
+    return result;
+}
+
 }  // namespace LinAlg
 }  // namespace MathLib
 
@@ -276,6 +286,12 @@ void linearSysNormalize(EigenMatrix const& A, EigenMatrix& new_A,
 void finalizeAssembly(EigenMatrix& x);
 void finalizeAssembly(EigenVector& A);
 
+// Reduce operations for interprocess communications while using Petsc
+static inline int reduceMin(int val)
+{
+    return val;
+}
+
 }  // namespace LinAlg
 
 }  // namespace MathLib
diff --git a/NumLib/ODESolver/NonlinearSolver.cpp b/NumLib/ODESolver/NonlinearSolver.cpp
index 59c0886b55bfc7038cf25188999cb25475cc852d..520e18442d250eaf40200d229feaf2853550099c 100644
--- a/NumLib/ODESolver/NonlinearSolver.cpp
+++ b/NumLib/ODESolver/NonlinearSolver.cpp
@@ -356,6 +356,7 @@ NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Newton>::solve(
 
         BaseLib::RunTime time_assembly;
         time_assembly.start();
+        int ok = 1, g_ok = 0;
         try
         {
             sys.assemble(x, x_prev, process_id);
@@ -366,8 +367,11 @@ NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Newton>::solve(
                 e.what());
             error_norms_met = false;
             iteration = _maxiter;
-            break;
+            ok = 0;
         }
+        g_ok = MathLib::LinAlg::reduceMin(ok);
+        if (g_ok == 0)
+            break;
         sys.getResidual(*x[process_id], *x_prev[process_id], res);
         sys.getJacobian(J);
         INFO("[time] Assembly took {:g} s.", time_assembly.elapsed());
diff --git a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp
index a536e2ff0343aa941c9b615eea9d9b6dc6a0cdb4..cfc584031a5570becbb2001b5c97dcd32fc67269 100644
--- a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp
+++ b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp
@@ -79,11 +79,18 @@ void TimeDiscretizedODESystem<ODESystemTag::FirstOrderImplicitQuasilinear,
 
     _b->setZero();
     _Jac->setZero();
-
-    _ode.preAssemble(t, dt, x_curr);
-    _ode.assembleWithJacobian(t, dt, x_new_timestep, x_prev, process_id, *_b,
-                              *_Jac);
-
+    try
+    {
+        _ode.preAssemble(t, dt, x_curr);
+        _ode.assembleWithJacobian(t, dt, x_new_timestep, x_prev, process_id,
+                                  *_b, *_Jac);
+    }
+    catch (AssemblyException const&)
+    {
+        MathLib::LinAlg::finalizeAssembly(*_b);
+        MathLib::LinAlg::finalizeAssembly(*_Jac);
+        throw;
+    }
     MathLib::LinAlg::finalizeAssembly(*_b);
     MathLib::LinAlg::finalizeAssembly(*_Jac);
 }
diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
index 8e9ea109e5130d0a14fcb488cd31a0c6c369c760..fdb73c825367d474db0fe83c2c7e7e322c6684fb 100644
--- a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
+++ b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp
@@ -14,6 +14,7 @@
 
 #include "MeshLib/Utils/IntegrationPointWriter.h"
 #include "MeshLib/Utils/getOrCreateMeshProperty.h"
+#include "NumLib/Exceptions.h"
 #include "ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h"
 #include "ProcessLib/Output/CellAverageAlgorithm.h"
 #include "ProcessLib/Process.h"
@@ -162,11 +163,20 @@ void SmallDeformationProcess<DisplacementDim>::
     std::vector<NumLib::LocalToGlobalIndexMap const*> dof_table = {
         _local_to_global_index_map.get()};
     // Call global assembler for each local assembly item.
-    GlobalExecutor::executeSelectedMemberDereferenced(
-        _global_assembler, &VectorMatrixAssembler::assembleWithJacobian,
-        _local_assemblers, getActiveElementIDs(), dof_table, t, dt, x, x_prev,
-        process_id, &b, &Jac);
-
+    try
+    {
+        GlobalExecutor::executeSelectedMemberDereferenced(
+            _global_assembler, &VectorMatrixAssembler::assembleWithJacobian,
+            _local_assemblers, getActiveElementIDs(), dof_table, t, dt, x,
+            x_prev, process_id, &b, &Jac);
+    }
+    catch (NumLib::AssemblyException const&)
+    {
+        transformVariableFromGlobalVector(b, 0, *_local_to_global_index_map,
+                                          *_nodal_forces,
+                                          std::negate<double>());
+        throw;
+    }
     transformVariableFromGlobalVector(b, 0, *_local_to_global_index_map,
                                       *_nodal_forces, std::negate<double>());