diff --git a/dune/tectonic/globalruinanonlinearity.hh b/dune/tectonic/globalruinanonlinearity.hh
index 0edc2361b4ef097e7736fff708cf8cb16d7ae1bb..9378c10677101b25e94f213c216b9fcdf41f1fed 100644
--- a/dune/tectonic/globalruinanonlinearity.hh
+++ b/dune/tectonic/globalruinanonlinearity.hh
@@ -25,12 +25,14 @@ class GlobalRuinaNonlinearity
       shared_ptr<BlockVector<FieldVector<double, 1>> const> a,
       shared_ptr<BlockVector<FieldVector<double, 1>> const> mu,
       shared_ptr<BlockVector<FieldVector<double, 1>> const> eta,
-      shared_ptr<BlockVector<FieldVector<double, 1>> const> normalStress)
+      shared_ptr<BlockVector<FieldVector<double, 1>> const> normalStress,
+      shared_ptr<BlockVector<FieldVector<double, 1>> const> state)
       : nodalIntegrals(nodalIntegrals),
         a(a),
         mu(mu),
         eta(eta),
         normalStress(normalStress),
+        state(state),
         trivialNonlinearity(
             new LocalNonlinearity<dim>(make_shared<TrivialFunction const>())),
         restrictions(nodalIntegrals->size()) // TODO: can we get the size from
@@ -52,7 +54,7 @@ class GlobalRuinaNonlinearity
 
     auto const func = make_shared<RuinaFunction const>(
         (*nodalIntegrals)[i][0], (*a)[i][0], (*mu)[i][0], (*eta)[i][0],
-        (*normalStress)[i][0]);
+        (*normalStress)[i][0], (*state)[i][0]);
     restrictions[i] = make_shared<LocalNonlinearity<dim> const>(func);
     return restrictions[i];
   }
@@ -65,6 +67,7 @@ class GlobalRuinaNonlinearity
   shared_ptr<BlockVector<FieldVector<double, 1>> const> mu;
   shared_ptr<BlockVector<FieldVector<double, 1>> const> eta;
   shared_ptr<BlockVector<FieldVector<double, 1>> const> normalStress;
+  shared_ptr<BlockVector<FieldVector<double, 1>> const> state;
 
   std::vector<shared_ptr<LocalNonlinearity<dim> const>> mutable restrictions;
 };
diff --git a/dune/tectonic/nicefunction.hh b/dune/tectonic/nicefunction.hh
index dc9a3eaa33867ea2582ca190277e9114ca1125db..d144d3ec7725a6d59a8768ac151ff01c6f7cabc7 100644
--- a/dune/tectonic/nicefunction.hh
+++ b/dune/tectonic/nicefunction.hh
@@ -31,13 +31,14 @@ class NiceFunction : public VirtualFunction<double, double> {
 class RuinaFunction : public NiceFunction {
 public:
   RuinaFunction(double coefficient, double a, double mu, double eta,
-                double normalStress)
+                double normalStress, double state)
       : coefficient(coefficient),
         a(a),
         mu(mu),
         rho(exp(-mu / a)),
         eta(eta),
-        normalStress(normalStress) {}
+        normalStress(normalStress),
+        state(state) {}
 
   /*
     If mu and sigma_n denote the coefficient of friction and the
@@ -55,8 +56,8 @@ class RuinaFunction : public NiceFunction {
   */
   void virtual evaluate(double const &x, double &y) const {
     double const arg = std::max(eta * x, rho);
-    double const h = arg * (a * (std::log(arg) - 1) + mu);
-    y = 1 / eta * normalStress * h + a * rho + mu;
+    double const h = arg * (a * (std::log(arg) - 1) + mu + state);
+    y = 1 / eta * normalStress * h + a * rho + mu + state;
     y *= coefficient;
   }
 
@@ -71,7 +72,7 @@ class RuinaFunction : public NiceFunction {
     if (eta * s <= rho)
       return 0;
 
-    return coefficient * normalStress * (a * std::log(eta * s) + mu);
+    return coefficient * normalStress * (a * std::log(eta * s) + mu + state);
   }
 
   /* see above */
@@ -79,7 +80,7 @@ class RuinaFunction : public NiceFunction {
     if (eta * s <= rho)
       return 0;
 
-    return coefficient * normalStress * (a * std::log(eta * s) + mu);
+    return coefficient * normalStress * (a * std::log(eta * s) + mu + state);
   }
 
   /*
@@ -108,6 +109,7 @@ class RuinaFunction : public NiceFunction {
   double const mu;
   double const eta;
   double const normalStress;
+  double const state;
 
   double const rho;
 };
diff --git a/src/one-body-sample.cc b/src/one-body-sample.cc
index ecf9fa0edeb4ee81f5ffa198abe9e5e741fd3eba..050c1e5624a4b931c86cf4bcee7d777673e7592c 100644
--- a/src/one-body-sample.cc
+++ b/src/one-body-sample.cc
@@ -144,7 +144,8 @@ Dune::shared_ptr<Dune::GlobalNonlinearity<VectorType, MatrixType> const>
 assemble_nonlinearity(
     int size, Dune::ParameterTree const &parset,
     Dune::shared_ptr<Dune::BlockVector<Dune::FieldVector<double, 1>>>
-        nodalIntegrals) {
+        nodalIntegrals,
+    Dune::shared_ptr<Dune::BlockVector<Dune::FieldVector<double, 1>>> state) {
   typedef Dune::BlockVector<Dune::FieldVector<double, 1>> SingletonVectorType;
 
   // {{{ Assemble terms for the nonlinearity
@@ -165,7 +166,7 @@ assemble_nonlinearity(
 
     return Dune::make_shared<
         Dune::GlobalRuinaNonlinearity<VectorType, MatrixType> const>(
-        nodalIntegrals, a, mu, eta, normalStress);
+        nodalIntegrals, a, mu, eta, normalStress, state);
   } else if (friction_model == std::string("Laursen")) {
     return Dune::make_shared<Dune::GlobalLaursenNonlinearity<
         Dune::LinearFunction, VectorType, MatrixType> const>(mu, normalStress,
@@ -269,8 +270,10 @@ int main(int argc, char *argv[]) {
     auto nodalIntegrals =
         assemble_frictional<GridType, GridView, SmallVector, P1Basis>(
             leafView, p1Basis, frictionalNodes);
-    auto myGlobalNonlinearity = assemble_nonlinearity<VectorType, OperatorType>(
-        grid->size(grid->maxLevel(), dim), parset, nodalIntegrals);
+    auto state =
+        Dune::make_shared<Dune::BlockVector<Dune::FieldVector<double, 1>>>(
+            grid->size(grid->maxLevel(), dim));
+    *state = 0.0;
 
     // {{{ Set up TNNMG solver
     // linear iteration step components
@@ -334,6 +337,10 @@ int main(int argc, char *argv[]) {
       stiffnessMatrix.mmv(u4, b4);
 
       if (parset.get<bool>("solver.nonlineargs.use")) {
+        auto myGlobalNonlinearity =
+            assemble_nonlinearity<VectorType, OperatorType>(
+                grid->size(grid->maxLevel(), dim), parset, nodalIntegrals,
+                state);
         MyConvexProblemType myConvexProblem(stiffnessMatrix,
                                             *myGlobalNonlinearity, b1);
         MyBlockProblemType myBlockProblem(parset, myConvexProblem);
@@ -349,6 +356,10 @@ int main(int argc, char *argv[]) {
       u1 += u1_diff;
 
       if (parset.get<bool>("solver.tnnmg.use")) {
+        auto myGlobalNonlinearity =
+            assemble_nonlinearity<VectorType, OperatorType>(
+                grid->size(grid->maxLevel(), dim), parset, nodalIntegrals,
+                state);
         MyConvexProblemType myConvexProblem(stiffnessMatrix,
                                             *myGlobalNonlinearity, b4);