diff --git a/Documentation/ProjectFile/material/fracture_model/MohrCoulomb/nonlinear_solver b/Documentation/ProjectFile/material/fracture_model/MohrCoulomb/nonlinear_solver
new file mode 120000
index 0000000000000000000000000000000000000000..d410878dc905bfe81ce70c44a5e4e19101394641
--- /dev/null
+++ b/Documentation/ProjectFile/material/fracture_model/MohrCoulomb/nonlinear_solver
@@ -0,0 +1 @@
+../../../nonlinear_solver
\ No newline at end of file
diff --git a/MaterialLib/FractureModels/CreateMohrCoulomb.cpp b/MaterialLib/FractureModels/CreateMohrCoulomb.cpp
index 0f27638fd98e3847d8c075fc392976426cca415b..874695927ed057df2f6c9f04eda318fa8c667e3d 100644
--- a/MaterialLib/FractureModels/CreateMohrCoulomb.cpp
+++ b/MaterialLib/FractureModels/CreateMohrCoulomb.cpp
@@ -9,6 +9,7 @@
 
 #include "CreateMohrCoulomb.h"
 
+#include "MaterialLib/SolidModels/CreateNewtonRaphsonSolverParameters.h"
 #include "ParameterLib/Utils.h"
 
 #include "MohrCoulomb.h"
@@ -57,8 +58,16 @@ std::unique_ptr<FractureModelBase<DisplacementDim>> createMohrCoulomb(
     typename MohrCoulomb::MohrCoulomb<DisplacementDim>::MaterialProperties mp{
         Kn, Ks, friction_angle, dilatancy_angle, cohesion};
 
+    auto const& nonlinear_solver_config =
+        //! \ogs_file_param{material__fracture_model__MohrCoulomb__nonlinear_solver}
+        config.getConfigSubtree("nonlinear_solver");
+    auto const nonlinear_solver_parameters =
+        MaterialLib::createNewtonRaphsonSolverParameters(
+            nonlinear_solver_config);
+
     return std::make_unique<MohrCoulomb::MohrCoulomb<DisplacementDim>>(
-        penalty_aperture_cutoff, tension_cutoff, mp);
+        nonlinear_solver_parameters, penalty_aperture_cutoff, tension_cutoff,
+        mp);
 }
 
 template std::unique_ptr<FractureModelBase<2>> createMohrCoulomb(
diff --git a/MaterialLib/FractureModels/MohrCoulomb.cpp b/MaterialLib/FractureModels/MohrCoulomb.cpp
index cd5ca1abb9eb965a271241103933138eac13faf9..2e7511ff40665978f7774919e6f3ca4b9496fe5a 100644
--- a/MaterialLib/FractureModels/MohrCoulomb.cpp
+++ b/MaterialLib/FractureModels/MohrCoulomb.cpp
@@ -53,11 +53,11 @@ void MohrCoulomb<DisplacementDim>::computeConstitutiveRelation(
     Eigen::Ref<Eigen::VectorXd const>
         sigma0,
     Eigen::Ref<Eigen::VectorXd const>
-        w_prev,
+    /*w_prev*/,
     Eigen::Ref<Eigen::VectorXd const>
         w,
     Eigen::Ref<Eigen::VectorXd const>
-        sigma_prev,
+    /*sigma_prev*/,
     Eigen::Ref<Eigen::VectorXd>
         sigma,
     Eigen::Ref<Eigen::MatrixXd>
@@ -65,14 +65,16 @@ void MohrCoulomb<DisplacementDim>::computeConstitutiveRelation(
     typename FractureModelBase<DisplacementDim>::MaterialStateVariables&
         material_state_variables)
 {
-    material_state_variables.reset();
+    assert(dynamic_cast<StateVariables<DisplacementDim> const*>(
+               &material_state_variables) != nullptr);
+
+    StateVariables<DisplacementDim>& state =
+        static_cast<StateVariables<DisplacementDim>&>(material_state_variables);
 
     MaterialPropertyValues const mat(_mp, t, x);
-    Eigen::VectorXd const dw = w - w_prev;
 
     const int index_ns = DisplacementDim - 1;
     double const aperture = w[index_ns] + aperture0;
-    double const aperture_prev = w_prev[index_ns] + aperture0;
 
     Eigen::MatrixXd Ke;
     {  // Elastic tangent stiffness
@@ -82,84 +84,132 @@ void MohrCoulomb<DisplacementDim>::computeConstitutiveRelation(
             Ke(i, i) = mat.Ks;
         }
 
-        Ke(index_ns, index_ns) =
-            mat.Kn *
-            logPenaltyDerivative(aperture0, aperture, _penalty_aperture_cutoff);
-    }
-
-    Eigen::MatrixXd Ke_prev;
-    {  // Elastic tangent stiffness at w_prev
-        Ke_prev = Eigen::MatrixXd::Zero(DisplacementDim, DisplacementDim);
-        for (int i = 0; i < index_ns; i++)
-        {
-            Ke_prev(i, i) = mat.Ks;
-        }
-
-        Ke_prev(index_ns, index_ns) =
-            mat.Kn * logPenaltyDerivative(
-                         aperture0, aperture_prev, _penalty_aperture_cutoff);
+        Ke(index_ns, index_ns) = mat.Kn;
     }
 
     // Total plastic aperture compression
     // NOTE: Initial condition sigma0 seems to be associated with an initial
     // condition of the w0 = 0. Therefore the initial state is not associated
     // with a plastic aperture change.
-    Eigen::VectorXd const w_p_prev =
-        w_prev - Ke_prev.fullPivLu().solve(sigma_prev - sigma0);
-
     {  // Exact elastic predictor
-        sigma.noalias() = Ke * (w - w_p_prev);
+        sigma.noalias() = Ke * (w - state.w_p_prev);
 
-        sigma.coeffRef(index_ns) =
-            mat.Kn * w[index_ns] *
+        sigma.coeffRef(index_ns) *=
             logPenalty(aperture0, aperture, _penalty_aperture_cutoff);
     }
 
     sigma.noalias() += sigma0;
 
-    double const sigma_n = sigma[index_ns];
-
     // correction for an opening fracture
-    if (_tension_cutoff && sigma_n > 0)
+    if (_tension_cutoff && sigma[DisplacementDim - 1] >= 0)
     {
         Kep.setZero();
         sigma.setZero();
         material_state_variables.setTensileStress(true);
         return;
-    }
 
-    // check shear yield function (Fs)
-    Eigen::VectorXd const sigma_s = sigma.head(DisplacementDim-1);
-    double const mag_tau = sigma_s.norm(); // magnitude
-    double const Fs = mag_tau + sigma_n * std::tan(mat.phi) - mat.c;
+        // TODO (nagel); Update w_p for fracture opening and closing.
+    }
 
-    material_state_variables.setShearYieldFunctionValue(Fs);
-    if (Fs < .0)
-    {
-        Kep = Ke;
-        return;
+    auto yield_function = [&mat](Eigen::VectorXd const& s) {
+        double const sigma_n = s[DisplacementDim - 1];
+        Eigen::VectorXd const sigma_s = s.head(DisplacementDim - 1);
+        double const mag_tau = sigma_s.norm();  // magnitude
+        return mag_tau + sigma_n * std::tan(mat.phi) - mat.c;
+    };
+
+    {  // Exit if still in elastic range by checking the shear yield function.
+        double const Fs = yield_function(sigma);
+        material_state_variables.setShearYieldFunctionValue(Fs);
+        if (Fs < .0)
+        {
+            Kep = Ke;
+            Kep(index_ns, index_ns) *= logPenaltyDerivative(
+                aperture0, aperture, _penalty_aperture_cutoff);
+            return;
+        }
     }
 
-    Eigen::VectorXd dFs_dS(DisplacementDim);
-    dFs_dS.head(DisplacementDim-1).noalias() = sigma_s.normalized();
-    dFs_dS[index_ns] = std::tan(mat.phi);
+    auto yield_function_derivative = [&mat](Eigen::VectorXd const& s) {
+        Eigen::Matrix<double, DisplacementDim, 1> dFs_dS;
+        dFs_dS.template head<DisplacementDim - 1>().noalias() =
+            s.template head<DisplacementDim - 1>().normalized();
+        dFs_dS.coeffRef(DisplacementDim - 1) = std::tan(mat.phi);
+        return dFs_dS;
+    };
 
     // plastic potential function: Qs = |tau| + Sn * tan da
-    Eigen::VectorXd dQs_dS = dFs_dS;
-    dQs_dS[index_ns] = std::tan(mat.psi);
-
-    // plastic multiplier
-    Eigen::RowVectorXd const A = dFs_dS.transpose() * Ke / (dFs_dS.transpose() * Ke * dQs_dS);
-    double const d_eta = A * dw;
+    auto plastic_potential_derivative = [&mat](Eigen::VectorXd const& s) {
+        Eigen::Matrix<double, DisplacementDim, 1> dQs_dS;
+        dQs_dS.template head<DisplacementDim - 1>().noalias() =
+            s.template head<DisplacementDim - 1>().normalized();
+        dQs_dS.coeffRef(DisplacementDim - 1) = std::tan(mat.psi);
+        return dQs_dS;
+    };
+
+    {  // Newton
+
+        Eigen::FullPivLU<Eigen::Matrix<double, 1, 1, Eigen::RowMajor>>
+            linear_solver;
+        using ResidualVectorType = Eigen::Matrix<double, 1, 1, Eigen::RowMajor>;
+        using JacobianMatrix = Eigen::Matrix<double, 1, 1, Eigen::RowMajor>;
+
+        JacobianMatrix jacobian;
+        ResidualVectorType solution;
+        solution << 0;
+
+        auto const update_residual = [&](ResidualVectorType& residual) {
+            residual[0] = yield_function(sigma);
+        };
+
+        auto const update_jacobian = [&](JacobianMatrix& jacobian) {
+            jacobian(0, 0) = -yield_function_derivative(sigma).transpose() *
+                             Ke * plastic_potential_derivative(sigma);
+        };
+
+        auto const update_solution = [&](ResidualVectorType const& increment) {
+            solution += increment;
+            /*DBUG("analytical = %g",
+                 Fs / (mat.Ks + mat.Kn * std::tan(mat.psi) * std::tan(mat.phi)))
+                 */
+            state.w_p = state.w_p_prev +
+                        solution[0] * plastic_potential_derivative(sigma);
+            sigma.noalias() = sigma0 + (Ke * (w - state.w_p)) *
+                                           logPenalty(aperture0, aperture,
+                                                      _penalty_aperture_cutoff);
+        };
+
+        auto newton_solver =
+            NumLib::NewtonRaphson<decltype(linear_solver), JacobianMatrix,
+                                  decltype(update_jacobian), ResidualVectorType,
+                                  decltype(update_residual),
+                                  decltype(update_solution)>(
+                linear_solver, update_jacobian, update_residual,
+                update_solution, _nonlinear_solver_parameters);
+
+        auto const success_iterations = newton_solver.solve(jacobian);
+
+        if (!success_iterations)
+        {
+            OGS_FATAL("MohrCoulomb nonlinear solver didn't converge.");
+        }
 
-    // plastic part of the dispalcement
-    Eigen::VectorXd const dwp = dQs_dS * d_eta;
+        // Solution containing lambda is not needed; w_p and sigma already
+        // up to date.
+    }
 
-    // correct stress
-    sigma.noalias() = sigma_prev + Ke * (dw - dwp);
+    {  // Update material state shear yield function value.
+        double const Fs = yield_function(sigma);
+        material_state_variables.setShearYieldFunctionValue(Fs);
+    }
 
-    // Kep
-    Kep = Ke - Ke * dQs_dS * A;
+    Ke(index_ns, index_ns) *=
+        logPenaltyDerivative(aperture0, aperture, _penalty_aperture_cutoff);
+    Eigen::RowVectorXd const A = yield_function_derivative(sigma).transpose() *
+                                 Ke /
+                                 (yield_function_derivative(sigma).transpose() *
+                                  Ke * plastic_potential_derivative(sigma));
+    Kep = Ke - Ke * plastic_potential_derivative(sigma) * A;
 }
 
 template class MohrCoulomb<2>;
diff --git a/MaterialLib/FractureModels/MohrCoulomb.h b/MaterialLib/FractureModels/MohrCoulomb.h
index 3b9e522e285d6eff975277b67e533e51f1f69689..c0e2ed2234a9a55215808fd7f47257d2834e8f5c 100644
--- a/MaterialLib/FractureModels/MohrCoulomb.h
+++ b/MaterialLib/FractureModels/MohrCoulomb.h
@@ -12,6 +12,7 @@
 #include <Eigen/Eigen>
 #include <utility>
 
+#include "NumLib/NewtonRaphson.h"
 #include "ParameterLib/Parameter.h"
 
 #include "FractureModelBase.h"
@@ -22,9 +23,36 @@ namespace Fracture
 {
 namespace MohrCoulomb
 {
+template <int DisplacementDim>
+struct StateVariables
+    : public FractureModelBase<DisplacementDim>::MaterialStateVariables
+{
+    void setInitialConditions() { w_p = w_p_prev; }
+
+    void pushBackState() override { w_p_prev = w_p; }
+
+    /// Plastic component of the displacement jump in fracture's local
+    /// coordinates.
+    Eigen::Matrix<double, DisplacementDim, 1> w_p =
+        Eigen::Matrix<double, DisplacementDim, 1>::Zero();
+
+    // Initial values from previous timestep
+    Eigen::Matrix<double, DisplacementDim, 1> w_p_prev;  ///< \copydoc w_p
+
+    EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
+};
+
 template <int DisplacementDim>
 class MohrCoulomb final : public FractureModelBase<DisplacementDim>
 {
+public:
+    std::unique_ptr<
+        typename FractureModelBase<DisplacementDim>::MaterialStateVariables>
+    createMaterialStateVariables() override
+    {
+        return std::make_unique<StateVariables<DisplacementDim>>();
+    }
+
 public:
     /// Variables specific to the material model
     struct MaterialProperties
@@ -58,26 +86,14 @@ public:
     };
 
 
-    struct MaterialStateVariables
-        : public FractureModelBase<DisplacementDim>::MaterialStateVariables
-    {
-        void pushBackState() override {}
-    };
-
-    std::unique_ptr<
-        typename FractureModelBase<DisplacementDim>::MaterialStateVariables>
-    createMaterialStateVariables() override
-    {
-        return std::unique_ptr<typename FractureModelBase<
-            DisplacementDim>::MaterialStateVariables>{
-            new MaterialStateVariables};
-    }
-
 public:
-    explicit MohrCoulomb(double const penalty_aperture_cutoff,
-                         bool const tension_cutoff,
-                         MaterialProperties material_properties)
-        : _penalty_aperture_cutoff(penalty_aperture_cutoff),
+    explicit MohrCoulomb(
+        NumLib::NewtonRaphsonSolverParameters nonlinear_solver_parameters,
+        double const penalty_aperture_cutoff,
+        bool const tension_cutoff,
+        MaterialProperties material_properties)
+        : _nonlinear_solver_parameters(std::move(nonlinear_solver_parameters)),
+          _penalty_aperture_cutoff(penalty_aperture_cutoff),
           _tension_cutoff(tension_cutoff),
           _mp(std::move(material_properties))
     {
@@ -117,6 +133,8 @@ public:
             material_state_variables) override;
 
 private:
+    NumLib::NewtonRaphsonSolverParameters const _nonlinear_solver_parameters;
+
     /// Compressive normal displacements above this value will not enter the
     /// computation of the normal stiffness modulus of the fracture.
     /// \note Setting this to the initial aperture value allows negative
diff --git a/ProcessLib/LIE/HydroMechanics/LocalAssembler/HydroMechanicsLocalAssemblerMatrixNearFracture.h b/ProcessLib/LIE/HydroMechanics/LocalAssembler/HydroMechanicsLocalAssemblerMatrixNearFracture.h
index f473ad8e3a33e2b37b114ea9616e4a12919d3e32..be07a6d3fbd7eb0179d5fcda6fcc9c08b4aed364 100644
--- a/ProcessLib/LIE/HydroMechanics/LocalAssembler/HydroMechanicsLocalAssemblerMatrixNearFracture.h
+++ b/ProcessLib/LIE/HydroMechanics/LocalAssembler/HydroMechanicsLocalAssemblerMatrixNearFracture.h
@@ -60,6 +60,16 @@ private:
                                       Eigen::VectorXd& local_b,
                                       Eigen::MatrixXd& local_J) override;
 
+    void preTimestepConcrete(std::vector<double> const& /*local_x*/,
+                             double const /*t*/,
+                             double const /*delta_t*/) override
+    {
+        for (auto& ip_data : _ip_data)
+        {
+            ip_data.pushBackState();
+        }
+    }
+
     void computeSecondaryVariableConcreteWithVector(
         double const t, Eigen::VectorXd const& local_x) override;
 
diff --git a/ProcessLib/LIE/SmallDeformation/Tests.cmake b/ProcessLib/LIE/SmallDeformation/Tests.cmake
index 39b380a42ee9102688c14a16dc16b91f47f98e0f..0dffe32ccd639db97c669f88238eeb3d1440f0f0 100644
--- a/ProcessLib/LIE/SmallDeformation/Tests.cmake
+++ b/ProcessLib/LIE/SmallDeformation/Tests.cmake
@@ -75,8 +75,8 @@ AddTest(
     TESTER vtkdiff
     REQUIREMENTS NOT OGS_USE_MPI
     DIFF_DATA
-    expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu displacement displacement 1e-16 1e-16
-    expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu displacement_jump1 displacement_jump1 1e-16 1e-16
+    expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu displacement displacement 1e-16 0
+    expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu displacement_jump1 displacement_jump1 1e-16 0
     expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu aperture aperture 1e-16 1e-16
 )
 
diff --git a/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_100_t_1.000000.vtu b/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_100_t_1.000000.vtu
new file mode 100644
index 0000000000000000000000000000000000000000..9bf8c80855eb263e9dff9d4be37e4b00403d7d47
--- /dev/null
+++ b/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_100_t_1.000000.vtu
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:71a3b44705cc0e527e05526b352edd1c6d4918e2b4ae6a3a505ce40655264287
+size 4433
diff --git a/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_200_t_2.000000.vtu b/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_200_t_2.000000.vtu
new file mode 100644
index 0000000000000000000000000000000000000000..90c878be402226080855086778fdef7156317daa
--- /dev/null
+++ b/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_200_t_2.000000.vtu
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6d99bd3d2b430b776f420c3700cf4a2080070ba6318f86d4b4f3071716d7bb48
+size 4460
diff --git a/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_401_t_4.000000.vtu b/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_401_t_4.000000.vtu
new file mode 100644
index 0000000000000000000000000000000000000000..48d5eac48dbb24fd64b38064048cb691cd2b2587
--- /dev/null
+++ b/Tests/Data/LIE/Mechanics/expected_mohr_coulomb_load_path_pcs_0_ts_401_t_4.000000.vtu
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1e265fc5987b57e3236f6a17cd95e273b563bb7e5d499c95ce562eaec769cdee
+size 4478
diff --git a/Tests/Data/LIE/Mechanics/expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu b/Tests/Data/LIE/Mechanics/expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu
index 2582e1f3c71ba4b03dc689213b10963cd2cdba9e..f56fb3a2e9b8ca611e1a6186c43e7bc6f5e1c424 100644
--- a/Tests/Data/LIE/Mechanics/expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu
+++ b/Tests/Data/LIE/Mechanics/expected_single_joint_displacement_controlled_pcs_0_ts_10_t_1.000000.vtu
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:fd3522e936d823a0044c7ac34bab82f31976a7639c5db5cadaf3516871517863
-size 22475
+oid sha256:227d8b102806a342bbf649c94a74475e1305dce8ead099a52a7e911877dfd36b
+size 25478
diff --git a/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.gml b/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.gml
new file mode 100644
index 0000000000000000000000000000000000000000..b304ced148e8ab619ffcd159cc710b056eed19b1
--- /dev/null
+++ b/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.gml
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05f98a3c2c0fca6c41e900fda62bba5d69562e94e0c0a84ae51639b90a04e2ce
+size 881
diff --git a/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.prj b/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.prj
new file mode 100644
index 0000000000000000000000000000000000000000..bc9d676c85df48cd6731ddfaa2290875a6a88270
--- /dev/null
+++ b/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.prj
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<OpenGeoSysProject>
+    <mesh>mohr_coulomb_load_path.vtu</mesh>
+    <geometry>mohr_coulomb_load_path.gml</geometry>
+    <processes>
+        <process>
+            <name>SD</name>
+            <type>SMALL_DEFORMATION_WITH_LIE</type>
+            <integration_order>2</integration_order>
+            <dimension>2</dimension>
+            <process_variables>
+                <process_variable>displacement</process_variable>
+                <process_variable>displacement_jump1</process_variable>
+            </process_variables>
+            <constitutive_relation>
+                <type>LinearElasticIsotropic</type>
+                <youngs_modulus>E</youngs_modulus>
+                <poissons_ratio>nu</poissons_ratio>
+            </constitutive_relation>
+            <fracture_model>
+                <type>MohrCoulomb</type>
+                <normal_stiffness>Kn</normal_stiffness>
+                <shear_stiffness>Ks</shear_stiffness>
+                <friction_angle>friction_angle</friction_angle>
+                <dilatancy_angle>dilatancy_angle</dilatancy_angle>
+                <cohesion>cohesion</cohesion>
+                <penalty_aperture_cutoff>10e-6</penalty_aperture_cutoff>
+                <tension_cutoff>1</tension_cutoff>
+                <nonlinear_solver>
+                    <maximum_iterations>100</maximum_iterations>
+                    <error_tolerance>1e-10</error_tolerance>
+                </nonlinear_solver>
+            </fracture_model>
+            <fracture_properties>
+                <material_id>0</material_id>
+                <initial_aperture>aperture0</initial_aperture>
+            </fracture_properties>
+            <secondary_variables>
+                <secondary_variable type="static" internal_name="sigma_xx" output_name="sigma_xx"/>
+                <secondary_variable type="static" internal_name="sigma_yy" output_name="sigma_yy"/>
+                <secondary_variable type="static" internal_name="sigma_xy" output_name="sigma_xy"/>
+            </secondary_variables>
+        </process>
+    </processes>
+    <time_loop>
+        <processes>
+            <process ref="SD">
+                <nonlinear_solver>basic_newton</nonlinear_solver>
+                <convergence_criterion>
+                    <type>PerComponentDeltaX</type>
+                    <norm_type>NORM2</norm_type>
+                    <abstols>1e-16 1e-16 1e-16 1e-16 1e-16 1e-16</abstols>
+                </convergence_criterion>
+                <time_discretization>
+                    <type>BackwardEuler</type>
+                </time_discretization>
+                <time_stepping>
+                    <type>FixedTimeStepping</type>
+                    <t_initial>0</t_initial>
+                    <t_end>4</t_end>
+                    <timesteps>
+                        <pair>
+                            <repeat>10000</repeat>
+                            <delta_t>0.01</delta_t>
+                        </pair>
+                    </timesteps>
+                </time_stepping>
+            </process>
+        </processes>
+        <output>
+            <type>VTK</type>
+            <prefix>mohr_coulomb_load_path</prefix>
+            <timesteps>
+                <pair>
+                    <repeat>5</repeat>
+                    <each_steps>1</each_steps>
+                </pair>
+            </timesteps>
+            <variables>
+                <variable>displacement</variable>
+                <variable>displacement_jump1</variable>
+                <variable>sigma_xx</variable>
+                <variable>sigma_yy</variable>
+                <variable>sigma_xy</variable>
+            </variables>
+        </output>
+    </time_loop>
+    <parameters>
+        <parameter>
+            <name>E</name>
+            <type>Constant</type>
+            <value>200e+16</value>
+        </parameter>
+        <parameter>
+            <name>nu</name>
+            <type>Constant</type>
+            <value>0.3</value>
+        </parameter>
+        <!-- Fracture properties -->
+        <parameter>
+            <name>Kn</name>
+            <type>Constant</type>
+            <value>20e9</value>
+        </parameter>
+        <parameter>
+            <name>Ks</name>
+            <type>Constant</type>
+            <value>20e9</value>
+        </parameter>
+        <parameter>
+            <name>friction_angle</name>
+            <type>Constant</type>
+            <value>22</value>
+        </parameter>
+        <parameter>
+            <name>dilatancy_angle</name>
+            <type>Constant</type>
+            <value>10</value>
+        </parameter>
+        <parameter>
+            <name>cohesion</name>
+            <type>Constant</type>
+            <value>1e3</value>
+        </parameter>
+        <parameter>
+            <name>displacement0</name>
+            <type>Constant</type>
+            <values>0 0</values>
+        </parameter>
+        <parameter>
+            <name>aperture0</name>
+            <type>Constant</type>
+            <value>1e-5</value>
+        </parameter>
+        <parameter>
+            <name>displacement_unit</name>
+            <type>Constant</type>
+            <value>1</value>
+        </parameter>
+        <parameter>
+            <name>displacement_x</name>
+            <type>CurveScaled</type>
+            <curve>timeRamp_displacement_x</curve>
+            <parameter>displacement_unit</parameter>
+        </parameter>
+        <parameter>
+            <name>displacement_y</name>
+            <type>CurveScaled</type>
+            <curve>timeRamp_displacement_y</curve>
+            <parameter>displacement_unit</parameter>
+        </parameter>
+        <parameter>
+            <name>zero_u</name>
+            <type>Constant</type>
+            <value>0</value>
+        </parameter>
+    </parameters>
+    <curves>
+        <curve>
+            <name>timeRamp_displacement_x</name>
+            <coords>0 1 2    4     10  </coords>
+            <values>0 0 1e-5 -1e-5 -1e-5</values>
+        </curve>
+        <curve>
+            <name>timeRamp_displacement_y</name>
+            <coords>0 1      10  </coords>
+            <values>0 -1e-6 -1e-6</values>
+        </curve>
+    </curves>
+    <process_variables>
+        <process_variable>
+            <name>displacement</name>
+            <components>2</components>
+            <order>1</order>
+            <initial_condition>displacement0</initial_condition>
+            <boundary_conditions>
+                <boundary_condition>
+                    <geometrical_set>DoubleEdgeCrack</geometrical_set>
+                    <geometry>PLY_TOP</geometry>
+                    <type>Dirichlet</type>
+                    <component>0</component>
+                    <parameter>displacement_x</parameter>
+                </boundary_condition>
+                <boundary_condition>
+                    <geometrical_set>DoubleEdgeCrack</geometrical_set>
+                    <geometry>PLY_TOP</geometry>
+                    <type>Dirichlet</type>
+                    <component>1</component>
+                    <parameter>displacement_y</parameter>
+                </boundary_condition>
+                <boundary_condition>
+                    <geometrical_set>DoubleEdgeCrack</geometrical_set>
+                    <geometry>PLY_BOTTOM</geometry>
+                    <type>Dirichlet</type>
+                    <component>0</component>
+                    <parameter>zero_u</parameter>
+                </boundary_condition>
+                <boundary_condition>
+                    <geometrical_set>DoubleEdgeCrack</geometrical_set>
+                    <geometry>PLY_BOTTOM</geometry>
+                    <type>Dirichlet</type>
+                    <component>1</component>
+                    <parameter>zero_u</parameter>
+                </boundary_condition>
+            </boundary_conditions>
+        </process_variable>
+        <process_variable>
+            <name>displacement_jump1</name>
+            <components>2</components>
+            <order>1</order>
+            <initial_condition>displacement0</initial_condition>
+            <boundary_conditions>
+            </boundary_conditions>
+        </process_variable>
+    </process_variables>
+    <nonlinear_solvers>
+        <nonlinear_solver>
+            <name>basic_newton</name>
+            <type>Newton</type>
+            <max_iter>25</max_iter>
+            <linear_solver>general_linear_solver</linear_solver>
+        </nonlinear_solver>
+    </nonlinear_solvers>
+    <linear_solvers>
+        <linear_solver>
+            <name>general_linear_solver</name>
+            <eigen>
+                <solver_type>SparseLU</solver_type>
+                <scaling>1</scaling>
+                <precon_type>DIAGONAL</precon_type>
+                <max_iteration_step>10000</max_iteration_step>
+                <error_tolerance>1e-16</error_tolerance>
+            </eigen>
+        </linear_solver>
+    </linear_solvers>
+</OpenGeoSysProject>
diff --git a/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.vtu b/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.vtu
new file mode 100644
index 0000000000000000000000000000000000000000..0d37bfd14e7bb42237eca6bdf690ae78c662222d
--- /dev/null
+++ b/Tests/Data/LIE/Mechanics/mohr_coulomb_load_path.vtu
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:935a92068d70978a79faaffb8c578e817c55f82bad36df3384ad83c849ca913d
+size 1436
diff --git a/Tests/Data/LIE/Mechanics/single_joint_displacement_controlled.prj b/Tests/Data/LIE/Mechanics/single_joint_displacement_controlled.prj
index 86685345ab2d45790221ae3637daef8c810b48eb..b8deb674a9051eb709b1a9116c92c86a83988bef 100644
--- a/Tests/Data/LIE/Mechanics/single_joint_displacement_controlled.prj
+++ b/Tests/Data/LIE/Mechanics/single_joint_displacement_controlled.prj
@@ -26,6 +26,10 @@
                 <cohesion>cohesion</cohesion>
                 <penalty_aperture_cutoff>1e-7</penalty_aperture_cutoff>
                 <tension_cutoff>1</tension_cutoff>
+                <nonlinear_solver>
+                    <maximum_iterations>1000</maximum_iterations>
+                    <error_tolerance>1e-12</error_tolerance>
+                </nonlinear_solver>
             </fracture_model>
             <fracture_properties>
                 <material_id>1</material_id>
@@ -43,9 +47,9 @@
             <process ref="SD">
                 <nonlinear_solver>basic_newton</nonlinear_solver>
                 <convergence_criterion>
-                    <type>Residual</type>
+                    <type>PerComponentDeltaX</type>
                     <norm_type>NORM2</norm_type>
-                    <abstol>1e-11</abstol>
+                    <reltols>1e-15 1e-15 1e-15 1e-15 1e-15 1e-15</reltols>
                 </convergence_criterion>
                 <time_discretization>
                     <type>BackwardEuler</type>
@@ -199,9 +203,7 @@
             <lis>-i bicgstab -p jacobi -tol 1e-16 -maxiter 10000</lis>
             <eigen>
                 <solver_type>SparseLU</solver_type>
-                <precon_type>DIAGONAL</precon_type>
-                <max_iteration_step>10000</max_iteration_step>
-                <error_tolerance>1e-16</error_tolerance>
+                <scaling>1</scaling>
             </eigen>
             <petsc>
                 <prefix>sd</prefix>
diff --git a/Tests/MaterialLib/TestFractureModels.cpp b/Tests/MaterialLib/TestFractureModels.cpp
index 38690268c5c52b1d8d2cb94df04cab3403db19ed..7eaf274b2ce840e7dff20fd31c604f03d9d8d99f 100644
--- a/Tests/MaterialLib/TestFractureModels.cpp
+++ b/Tests/MaterialLib/TestFractureModels.cpp
@@ -21,8 +21,15 @@
 
 using namespace MaterialLib::Fracture;
 
-static const double eps_sigma = 1e6*1e-5;
-static const double eps_C = 1e10*1e-5;
+// For known exact quantities like zero.
+constexpr double eps = std::numeric_limits<double>::epsilon();
+// For numeric in-order-of-sigma comparisons.
+constexpr double eps_sigma = 1e6 * eps;
+// For numeric in-order-of-C comparisons.
+constexpr double eps_C = 2e10 * eps;
+
+static NumLib::NewtonRaphsonSolverParameters const nonlinear_solver_parameters{
+    1000, 1e-16};
 
 TEST(MaterialLib_Fracture, LinearElasticIsotropic)
 {
@@ -37,6 +44,7 @@ TEST(MaterialLib_Fracture, LinearElasticIsotropic)
                                             tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<2>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector2d const w_prev = Eigen::Vector2d::Zero();
     Eigen::Vector2d const sigma0 = Eigen::Vector2d::Zero();
@@ -51,24 +59,23 @@ TEST(MaterialLib_Fracture, LinearElasticIsotropic)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(-1e4, sigma[0], eps_sigma);
-    ASSERT_NEAR(-1e6, sigma[1], eps_sigma);
-    ASSERT_NEAR(1e9, C(0,0), eps_C);
-    ASSERT_NEAR(0, C(0,1), eps_C);
-    ASSERT_NEAR(0, C(1,0), eps_C);
-    ASSERT_NEAR(1e11, C(1,1), eps_C);
-
+    EXPECT_NEAR(-1e4, sigma[0], eps_sigma);
+    EXPECT_NEAR(-1e6, sigma[1], eps_sigma);
+    EXPECT_NEAR(1e9, C(0, 0), eps);
+    EXPECT_NEAR(0, C(0, 1), eps);
+    EXPECT_NEAR(0, C(1, 0), eps);
+    EXPECT_NEAR(1e11, C(1, 1), eps);
 
     w << -1e-5, 1e-5;
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(0, sigma[0], eps_sigma);
-    ASSERT_NEAR(0, sigma[1], eps_sigma);
-    ASSERT_NEAR(0, C(0,0), eps_C);
-    ASSERT_NEAR(0, C(0,1), eps_C);
-    ASSERT_NEAR(0, C(1,0), eps_C);
-    ASSERT_NEAR(0, C(1,1), eps_C);
+    EXPECT_NEAR(0, sigma[0], eps);
+    EXPECT_NEAR(0, sigma[1], eps);
+    EXPECT_NEAR(0, C(0, 0), eps);
+    EXPECT_NEAR(0, C(0, 1), eps);
+    EXPECT_NEAR(0, C(1, 0), eps);
+    EXPECT_NEAR(0, C(1, 1), eps);
 }
 
 TEST(MaterialLib_Fracture, MohrCoulomb2D_elastic)
@@ -84,10 +91,12 @@ TEST(MaterialLib_Fracture, MohrCoulomb2D_elastic)
     double const aperture0 = 1;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<2> fractureModel{penalty_aperture_cutoff,
+    MohrCoulomb::MohrCoulomb<2> fractureModel{nonlinear_solver_parameters,
+                                              penalty_aperture_cutoff,
                                               tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<2>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector2d const w_prev = Eigen::Vector2d::Zero();
     Eigen::Vector2d const sigma0 = Eigen::Vector2d::Zero();
@@ -102,23 +111,24 @@ TEST(MaterialLib_Fracture, MohrCoulomb2D_elastic)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(-1e4, sigma[0], eps_sigma);
-    ASSERT_NEAR(-1e6, sigma[1], eps_sigma);
-    ASSERT_NEAR(1e9, C(0, 0), eps_C);
-    ASSERT_NEAR(0, C(0, 1), eps_C);
-    ASSERT_NEAR(0, C(1, 0), eps_C);
-    ASSERT_NEAR(1e11, C(1, 1), eps_C);
+    EXPECT_NEAR(-1e4, sigma[0], eps_sigma);
+    EXPECT_NEAR(-1e6, sigma[1], eps_sigma);
+    EXPECT_NEAR(1e9, C(0, 0), eps);
+    EXPECT_NEAR(0, C(0, 1), eps);
+    EXPECT_NEAR(0, C(1, 0), eps);
+    EXPECT_NEAR(1e11, C(1, 1), eps);
 
     w << -1e-5, 1e-5;
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(0, sigma[0], eps_sigma);
-    ASSERT_NEAR(0, sigma[1], eps_sigma);
-    ASSERT_NEAR(0, C(0, 0), eps_C);
-    ASSERT_NEAR(0, C(0, 1), eps_C);
-    ASSERT_NEAR(0, C(1, 0), eps_C);
-    ASSERT_NEAR(0, C(1, 1), eps_C);
+    EXPECT_NEAR(0, sigma[0], eps);
+    EXPECT_NEAR(0, sigma[1], eps);
+    EXPECT_NEAR(0, C(0, 0), eps);
+    EXPECT_NEAR(0, C(0, 1), eps);
+    EXPECT_NEAR(0, C(1, 0), eps);
+    EXPECT_NEAR(0, C(1, 1), eps);
+    EXPECT_LE(state->getShearYieldFunctionValue(), 0);
 }
 
 TEST(MaterialLib_Fracture, MohrCoulomb2D_negative_t)
@@ -134,10 +144,12 @@ TEST(MaterialLib_Fracture, MohrCoulomb2D_negative_t)
     double const aperture0 = 1e-5;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<2> fractureModel{penalty_aperture_cutoff,
+    MohrCoulomb::MohrCoulomb<2> fractureModel{nonlinear_solver_parameters,
+                                              penalty_aperture_cutoff,
                                               tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<2>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector2d const w_prev = Eigen::Vector2d::Zero();
     Eigen::Vector2d const sigma0(-3.46e6, -2e6);
@@ -152,13 +164,13 @@ TEST(MaterialLib_Fracture, MohrCoulomb2D_negative_t)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(-3.50360e6, sigma[0], eps_sigma);
-    ASSERT_NEAR(-2.16271e6, sigma[1], eps_sigma);
-    ASSERT_NEAR(1.10723e+09, C(0,0), eps_C);
-    ASSERT_NEAR(1.26558e+10, C(0,1), eps_C);
-    ASSERT_NEAR(4.13226e+09, C(1,0), eps_C);
-    ASSERT_NEAR(4.72319e+10, C(1,1), eps_C);
-    ASSERT_NEAR(1.06608E+5, state->getShearYieldFunctionValue(), eps_sigma);
+    EXPECT_NEAR(-3575294.0369758257, sigma[0], eps_sigma);
+    EXPECT_NEAR(-2147026.5752851903, sigma[1], eps_sigma);
+    EXPECT_NEAR(1107234904.9501991, C(0, 0), eps_C);
+    EXPECT_NEAR(12655752875.023743, C(0, 1), eps_C);
+    EXPECT_NEAR(4132256921.1878347, C(1, 0), eps_C);
+    EXPECT_NEAR(47231912737.624504, C(1, 1), eps_C);
+    EXPECT_NEAR(0, state->getShearYieldFunctionValue(), eps);
 }
 
 
@@ -175,10 +187,12 @@ TEST(MaterialLib_Fracture, MohrCoulomb2D_positive_t)
     double const aperture0 = 1e-5;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<2> fractureModel{penalty_aperture_cutoff,
+    MohrCoulomb::MohrCoulomb<2> fractureModel{nonlinear_solver_parameters,
+                                              penalty_aperture_cutoff,
                                               tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<2>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector2d const w_prev = Eigen::Vector2d::Zero();
     Eigen::Vector2d const sigma0(0, -2e6);
@@ -193,13 +207,13 @@ TEST(MaterialLib_Fracture, MohrCoulomb2D_positive_t)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(253972.0, sigma[0], eps_sigma);
-    ASSERT_NEAR(-2.94784e+06, sigma[1], eps_sigma);
-    ASSERT_NEAR(1.10723e+09, C(0,0), eps_C);
-    ASSERT_NEAR(-1.26558e+10, C(0,1), eps_C);
-    ASSERT_NEAR(-4.13226e+09, C(1,0), eps_C);
-    ASSERT_NEAR(4.72319e+10, C(1,1), eps_C);
-    ASSERT_NEAR(446608.0, state->getShearYieldFunctionValue(), eps_sigma);
+    EXPECT_NEAR(3594117.0303599793, sigma[0], eps_sigma);
+    EXPECT_NEAR(-2217274.9429453835, sigma[1], eps_sigma);
+    EXPECT_NEAR(1107234904.9501991, C(0, 0), eps_C);
+    EXPECT_NEAR(-12655752875.023743, C(0, 1), eps_C);
+    EXPECT_NEAR(-4132256921.1878347, C(1, 0), eps_C);
+    EXPECT_NEAR(47231912737.624504, C(1, 1), eps_C);
+    EXPECT_NEAR(0, state->getShearYieldFunctionValue(), eps);
 }
 
 TEST(MaterialLib_Fracture, MohrCoulomb3D_negative_t1)
@@ -215,10 +229,12 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_negative_t1)
     double const aperture0 = 1e-5;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<3> fractureModel{penalty_aperture_cutoff,
+    MohrCoulomb::MohrCoulomb<3> fractureModel{nonlinear_solver_parameters,
+                                              penalty_aperture_cutoff,
                                               tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<3>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector3d const w_prev = Eigen::Vector3d::Zero();
     Eigen::Vector3d const sigma0(-3.46e6, 0, -2e6);
@@ -233,19 +249,19 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_negative_t1)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(-3.50360e6, sigma[0], eps_sigma);
-    ASSERT_NEAR(0.0, sigma[1], eps_sigma);
-    ASSERT_NEAR(-2.16271e6, sigma[2], eps_sigma);
-    ASSERT_NEAR(1.10723e+09, C(0,0), eps_C);
-    ASSERT_NEAR(0.0, C(0,1), eps_C);
-    ASSERT_NEAR(1.26558e+10, C(0,2), eps_C);
-    ASSERT_NEAR(0.0, C(1,0), eps_C);
-    ASSERT_NEAR(20.e9, C(1,1), eps_C);
-    ASSERT_NEAR(0.0, C(1,2), eps_C);
-    ASSERT_NEAR(4.13226e+09, C(2,0), eps_C);
-    ASSERT_NEAR(0.0, C(2,1), eps_C);
-    ASSERT_NEAR(4.72319e+10, C(2,2), eps_C);
-    ASSERT_NEAR(1.06608E+5, state->getShearYieldFunctionValue(), eps_sigma);
+    EXPECT_NEAR(-3575294.0369758257, sigma[0], eps_sigma);
+    EXPECT_NEAR(0.0, sigma[1], eps);
+    EXPECT_NEAR(-2147026.5752851903, sigma[2], eps_sigma);
+    EXPECT_NEAR(1107234904.9501991, C(0, 0), eps_C);
+    EXPECT_NEAR(0.0, C(0, 1), eps);
+    EXPECT_NEAR(12655752875.023743, C(0, 2), eps_C);
+    EXPECT_NEAR(0.0, C(1, 0), eps);
+    EXPECT_NEAR(20.e9, C(1, 1), eps);
+    EXPECT_NEAR(0.0, C(1, 2), eps);
+    EXPECT_NEAR(4132256921.1878347, C(2, 0), eps_C);
+    EXPECT_NEAR(0.0, C(2, 1), eps);
+    EXPECT_NEAR(47231912737.624504, C(2, 2), eps_C);
+    EXPECT_NEAR(0, state->getShearYieldFunctionValue(), eps);
 }
 
 TEST(MaterialLib_Fracture, MohrCoulomb3D_positive_t1)
@@ -261,10 +277,12 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_positive_t1)
     double const aperture0 = 1e-5;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<3> fractureModel{penalty_aperture_cutoff,
+    MohrCoulomb::MohrCoulomb<3> fractureModel{nonlinear_solver_parameters,
+                                              penalty_aperture_cutoff,
                                               tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<3>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector3d const w_prev = Eigen::Vector3d::Zero();
     Eigen::Vector3d const sigma0(0, 0, -2e6);
@@ -279,19 +297,19 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_positive_t1)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(253972.0, sigma[0], eps_sigma);
-    ASSERT_NEAR(0.0, sigma[1], eps_sigma);
-    ASSERT_NEAR(-2.94784e+06, sigma[2], eps_sigma);
-    ASSERT_NEAR(1.10723e+09, C(0,0), eps_C);
-    ASSERT_NEAR(0.0, C(0,1), eps_C);
-    ASSERT_NEAR(-1.26558e+10, C(0,2), eps_C);
-    ASSERT_NEAR(0.0, C(1,0), eps_C);
-    ASSERT_NEAR(20.e9, C(1,1), eps_C);
-    ASSERT_NEAR(0.0, C(1,2), eps_C);
-    ASSERT_NEAR(-4.13226e+09, C(2,0), eps_C);
-    ASSERT_NEAR(0.0, C(2,1), eps_C);
-    ASSERT_NEAR(4.72319e+10, C(2,2), eps_C);
-    ASSERT_NEAR(446608.0, state->getShearYieldFunctionValue(), eps_sigma);
+    EXPECT_NEAR(3594117.0303599793, sigma[0], eps_sigma);
+    EXPECT_NEAR(0.0, sigma[1], eps);
+    EXPECT_NEAR(-2217274.9429453835, sigma[2], eps_sigma);
+    EXPECT_NEAR(1107234904.9501991, C(0, 0), eps_C);
+    EXPECT_NEAR(0.0, C(0, 1), eps);
+    EXPECT_NEAR(-12655752875.023743, C(0, 2), eps_C);
+    EXPECT_NEAR(0.0, C(1, 0), eps);
+    EXPECT_NEAR(20.e9, C(1, 1), eps);
+    EXPECT_NEAR(0.0, C(1, 2), eps);
+    EXPECT_NEAR(-4132256921.1878347, C(2, 0), eps_C);
+    EXPECT_NEAR(0.0, C(2, 1), eps);
+    EXPECT_NEAR(47231912737.624504, C(2, 2), eps_C);
+    EXPECT_NEAR(0, state->getShearYieldFunctionValue(), eps);
 }
 
 
@@ -308,10 +326,12 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_positive_t2)
     double const aperture0 = 1e-5;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<3> fractureModel{penalty_aperture_cutoff,
+    MohrCoulomb::MohrCoulomb<3> fractureModel{nonlinear_solver_parameters,
+                                              penalty_aperture_cutoff,
                                               tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<3>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector3d const w_prev = Eigen::Vector3d::Zero();
     Eigen::Vector3d const sigma0(0, 0, -2e6);
@@ -326,19 +346,19 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_positive_t2)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(0.0, sigma[0], eps_sigma);
-    ASSERT_NEAR(253972.0, sigma[1], eps_sigma);
-    ASSERT_NEAR(-2.94784e+06, sigma[2], eps_sigma);
-    ASSERT_NEAR(20.e9, C(0,0), eps_C);
-    ASSERT_NEAR(0.0, C(0,1), eps_C);
-    ASSERT_NEAR(0.0, C(0,2), eps_C);
-    ASSERT_NEAR(0.0, C(1,0), eps_C);
-    ASSERT_NEAR(1.10723e+09, C(1,1), eps_C);
-    ASSERT_NEAR(-1.26558e+10, C(1,2), eps_C);
-    ASSERT_NEAR(0.0, C(2,0), eps_C);
-    ASSERT_NEAR(-4.13226e+09, C(2,1), eps_C);
-    ASSERT_NEAR(4.72319e+10, C(2,2), eps_C);
-    ASSERT_NEAR(446608.0, state->getShearYieldFunctionValue(), eps_sigma);
+    EXPECT_NEAR(0.0, sigma[0], eps);
+    EXPECT_NEAR(3594117.0303599793, sigma[1], eps_sigma);
+    EXPECT_NEAR(-2217274.9429453835, sigma[2], eps_sigma);
+    EXPECT_NEAR(20.e9, C(0, 0), eps);
+    EXPECT_NEAR(0.0, C(0, 1), eps);
+    EXPECT_NEAR(0.0, C(0, 2), eps);
+    EXPECT_NEAR(0.0, C(1, 0), eps);
+    EXPECT_NEAR(1107234904.9501991, C(1, 1), eps_C);
+    EXPECT_NEAR(-12655752875.023743, C(1, 2), eps_C);
+    EXPECT_NEAR(0.0, C(2, 0), eps);
+    EXPECT_NEAR(-4132256921.1878347, C(2, 1), eps_C);
+    EXPECT_NEAR(47231912737.624504, C(2, 2), eps_C);
+    EXPECT_NEAR(0, state->getShearYieldFunctionValue(), eps);
 }
 
 
@@ -355,10 +375,11 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_negative_t1t2)
     double const aperture0 = 1e-5;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<3> fractureModel{penalty_aperture_cutoff,
-                                              tension_cutoff, mp};
+    MohrCoulomb::MohrCoulomb<3> fractureModel{
+        {1000, 1e-9}, penalty_aperture_cutoff, tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<3>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector3d const w_prev = Eigen::Vector3d::Zero();
     Eigen::Vector3d const sigma0(-3.46e6 / std::sqrt(2), -3.46e6 / std::sqrt(2),
@@ -374,19 +395,20 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_negative_t1t2)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(-3.50360e6/std::sqrt(2), sigma[0], eps_sigma);
-    ASSERT_NEAR(-3.50360e6/std::sqrt(2), sigma[1], eps_sigma);
-    ASSERT_NEAR(-2.16271e6, sigma[2], eps_sigma);
-    ASSERT_NEAR(1.05536e+10, C(0,0), eps_C);
-    ASSERT_NEAR(-9.44638e+09, C(0,1), eps_C);
-    ASSERT_NEAR(8.94897e+09, C(0,2), eps_C);
-    ASSERT_NEAR(-9.44638e+09, C(1,0), eps_C);
-    ASSERT_NEAR(1.05536e+10, C(1,1), eps_C);
-    ASSERT_NEAR(8.94897e+09, C(1,2), eps_C);
-    ASSERT_NEAR(2.92195e+09, C(2,0), eps_C);
-    ASSERT_NEAR(2.92195e+09, C(2,1), eps_C);
-    ASSERT_NEAR(4.72319e+10, C(2,2), eps_C);
-    ASSERT_NEAR(1.06608E+5, state->getShearYieldFunctionValue(), eps_sigma);
+    EXPECT_NEAR(-3575294.0369758265 / std::sqrt(2), sigma[0], eps_sigma);
+    EXPECT_NEAR(-3575294.0369758265 / std::sqrt(2), sigma[1], eps_sigma);
+    EXPECT_NEAR(-2147026.5752851903, sigma[2], eps_sigma);
+    EXPECT_NEAR(10553617452.475098, C(0, 0), eps_C);
+    EXPECT_NEAR(-9446382547.5249023, C(0, 1), eps_C);
+    EXPECT_NEAR(8948968678.9504356, C(0, 2), eps_C);
+    EXPECT_NEAR(-9446382547.5249023, C(1, 0), eps_C);
+    EXPECT_NEAR(10553617452.475098, C(1, 1), eps_C);
+    EXPECT_NEAR(8948968678.9504356, C(1, 2), eps_C);
+    EXPECT_NEAR(2921946890.5769634, C(2, 0), eps_C);
+    EXPECT_NEAR(2921946890.5769634, C(2, 1), eps_C);
+    EXPECT_NEAR(47231912737.624504, C(2, 2), eps_C);
+    EXPECT_NEAR(0, state->getShearYieldFunctionValue(),
+                1e-9);  // same as newton tolerance
 }
 
 
@@ -403,10 +425,12 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_negative_t1_positive_t2)
     double const aperture0 = 1e-5;
     double const penalty_aperture_cutoff = aperture0;
     bool const tension_cutoff = true;
-    MohrCoulomb::MohrCoulomb<3> fractureModel{penalty_aperture_cutoff,
-                                              tension_cutoff, mp};
+
+    MohrCoulomb::MohrCoulomb<3> fractureModel{
+        {1000, 1e-9}, penalty_aperture_cutoff, tension_cutoff, mp};
     std::unique_ptr<FractureModelBase<3>::MaterialStateVariables> state(
         fractureModel.createMaterialStateVariables());
+    state->pushBackState();
 
     Eigen::Vector3d const w_prev = Eigen::Vector3d::Zero();
     Eigen::Vector3d const sigma0(-3.46e6 / std::sqrt(2), 3.46e6 / std::sqrt(2),
@@ -422,18 +446,19 @@ TEST(MaterialLib_Fracture, MohrCoulomb3D_negative_t1_positive_t2)
     fractureModel.computeConstitutiveRelation(0, x, aperture0, sigma0, w_prev,
                                               w, sigma_prev, sigma, C, *state);
 
-    ASSERT_NEAR(-3.50360e6/std::sqrt(2), sigma[0], eps_sigma);
-    ASSERT_NEAR(3.50360e6/std::sqrt(2), sigma[1], eps_sigma);
-    ASSERT_NEAR(-2.16271e6, sigma[2], eps_sigma);
-    ASSERT_NEAR(1.05536e+10, C(0,0), eps_C);
-    ASSERT_NEAR(9.44638e+09, C(0,1), eps_C);
-    ASSERT_NEAR(8.94897e+09, C(0,2), eps_C);
-    ASSERT_NEAR(9.44638e+09, C(1,0), eps_C);
-    ASSERT_NEAR(1.05536e+10, C(1,1), eps_C);
-    ASSERT_NEAR(-8.94897e+09, C(1,2), eps_C);
-    ASSERT_NEAR(2.92195e+09, C(2,0), eps_C);
-    ASSERT_NEAR(-2.92195e+09, C(2,1), eps_C);
-    ASSERT_NEAR(4.72319e+10, C(2,2), eps_C);
-    ASSERT_NEAR(1.06608E+5, state->getShearYieldFunctionValue(), eps_sigma);
+    EXPECT_NEAR(-3575294.0369758265 / std::sqrt(2), sigma[0], eps_sigma);
+    EXPECT_NEAR(3575294.0369758265 / std::sqrt(2), sigma[1], eps_sigma);
+    EXPECT_NEAR(-2147026.5752851903, sigma[2], eps_sigma);
+    EXPECT_NEAR(10553617452.475098, C(0, 0), eps_C);
+    EXPECT_NEAR(9446382547.5249023, C(0, 1), eps_C);
+    EXPECT_NEAR(8948968678.9504356, C(0, 2), eps_C);
+    EXPECT_NEAR(9446382547.5249023, C(1, 0), eps_C);
+    EXPECT_NEAR(10553617452.475098, C(1, 1), eps_C);
+    EXPECT_NEAR(-8948968678.9504356, C(1, 2), eps_C);
+    EXPECT_NEAR(2921946890.5769634, C(2, 0), eps_C);
+    EXPECT_NEAR(-2921946890.5769634, C(2, 1), eps_C);
+    EXPECT_NEAR(47231912737.624504, C(2, 2), eps_C);
+    EXPECT_NEAR(0, state->getShearYieldFunctionValue(),
+                1e-9);  // same as newton tolerance
 }