diff --git a/src/Makefile.am b/src/Makefile.am
index 170446c7d675b9659e1484f5f83f2fc7d54a8d66..46010a7ace993dce98a84add41d30bdab34ccb06 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,7 +6,9 @@ bin_PROGRAMS = \
 
 SOURCES = \
 	assemblers.cc \
-	compute_state_dieterich.cc \
+	compute_state_dieterich_newmark.cc \
+	compute_state_dieterich_euler.cc \
+	compute_state_dieterich_common.cc \
 	compute_state_ruina.cc \
 	mysolver.cc \
 	one-body-sample.cc \
diff --git a/src/compute_state_dieterich.cc b/src/compute_state_dieterich.cc
deleted file mode 100644
index 3b8441cfe58d489177e436f6bed89803ab0a0a77..0000000000000000000000000000000000000000
--- a/src/compute_state_dieterich.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <cassert>
-
-#include <dune/common/fvector.hh>
-#include <dune/common/fmatrix.hh>
-#include <dune/fufem/interval.hh>
-
-#include <dune/tnnmg/problem-classes/bisection.hh>
-
-#include <dune/tectonic/mydirectionalconvexfunction.hh>
-
-#include "compute_state_dieterich.hh"
-
-// psi(beta) = V/L beta + e^(-beta)
-class DieterichNonlinearity {
-public:
-  typedef Dune::FieldVector<double, 1> VectorType;
-  typedef Dune::FieldMatrix<double, 1, 1> MatrixType;
-
-  DieterichNonlinearity(double _VoL) : VoL(_VoL) {}
-
-  void directionalSubDiff(VectorType const &u, VectorType const &v,
-                          Interval<double> &D) const {
-    D[0] = D[1] = v[0] * (VoL - std::exp(-u[0]));
-  }
-
-  void directionalDomain(VectorType const &, VectorType const &,
-                         Interval<double> &dom) const {
-    dom[0] = -std::numeric_limits<double>::max();
-    dom[1] = std::numeric_limits<double>::max();
-  }
-
-private:
-  double const VoL;
-};
-
-double state_update_dieterich_bisection(double tau, double VoL,
-                                        double old_state) {
-  DieterichNonlinearity::VectorType const start(0);
-  DieterichNonlinearity::VectorType const direction(1);
-  DieterichNonlinearity const phi(VoL);
-  MyDirectionalConvexFunction<DieterichNonlinearity> const J(
-      1.0 / tau, old_state / tau, phi, start, direction);
-
-  int bisectionsteps = 0;
-  Bisection const bisection(0.0, 1.0, 1e-12, true, 0);    // TODO
-  return bisection.minimize(J, 0.0, 0.0, bisectionsteps); // TODO
-}
-
-double state_update_dieterich(double tau, double VoL, double old_state) {
-  double const ret = state_update_dieterich_bisection(tau, VoL, old_state);
-  /* We have
-
-     ret - old_state + tau * VoL = tau*exp(-ret)
-
-     or
-
-     log((ret - old_state)/tau + VoL) = -ret
-  */
-  assert(std::min(std::abs(ret - old_state + tau * (VoL - std::exp(-ret))),
-                  std::abs(std::log((ret - old_state) / tau + VoL) + ret)) <
-         1e-12);
-  return ret;
-}
diff --git a/src/compute_state_dieterich.hh b/src/compute_state_dieterich.hh
deleted file mode 100644
index 49fe3dcc3d7bc112b31d0d8d2193a12811b5121a..0000000000000000000000000000000000000000
--- a/src/compute_state_dieterich.hh
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef COMPUTE_STATE_HH
-#define COMPUTE_STATE_HH
-
-double state_update_dieterich(double h, double VoL, double old_state);
-#endif
diff --git a/src/compute_state_dieterich_common.cc b/src/compute_state_dieterich_common.cc
new file mode 100644
index 0000000000000000000000000000000000000000..449bcbe356cfda2636cd21b24d7e0ffaa0470ad0
--- /dev/null
+++ b/src/compute_state_dieterich_common.cc
@@ -0,0 +1,16 @@
+#include "compute_state_dieterich_common.hh"
+
+DieterichNonlinearity::DieterichNonlinearity(double _VoL) : VoL(_VoL) {}
+
+void DieterichNonlinearity::directionalSubDiff(VectorType const &u,
+                                               VectorType const &v,
+                                               Interval<double> &D) const {
+  D[0] = D[1] = v[0] * (VoL - std::exp(-u[0]));
+}
+
+void DieterichNonlinearity::directionalDomain(VectorType const &,
+                                              VectorType const &,
+                                              Interval<double> &dom) const {
+  dom[0] = -std::numeric_limits<double>::max();
+  dom[1] = std::numeric_limits<double>::max();
+}
diff --git a/src/compute_state_dieterich_common.hh b/src/compute_state_dieterich_common.hh
new file mode 100644
index 0000000000000000000000000000000000000000..39f5f62745a7efb022868737a1bef52f4177239c
--- /dev/null
+++ b/src/compute_state_dieterich_common.hh
@@ -0,0 +1,18 @@
+#include <dune/common/fvector.hh>
+#include <dune/common/fmatrix.hh>
+#include <dune/fufem/interval.hh>
+
+class DieterichNonlinearity {
+public:
+  typedef Dune::FieldVector<double, 1> VectorType;
+  typedef Dune::FieldMatrix<double, 1, 1> MatrixType;
+
+  DieterichNonlinearity(double _VoL);
+  void directionalSubDiff(VectorType const &u, VectorType const &v,
+                          Interval<double> &D) const;
+  void directionalDomain(VectorType const &, VectorType const &,
+                         Interval<double> &dom) const;
+
+private:
+  double const VoL;
+};
diff --git a/src/compute_state_dieterich_euler.cc b/src/compute_state_dieterich_euler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ca51487a4e892f8c9f8d15ed4fca21de844eb2ec
--- /dev/null
+++ b/src/compute_state_dieterich_euler.cc
@@ -0,0 +1,38 @@
+#include <cassert>
+
+#include <dune/tnnmg/problem-classes/bisection.hh>
+
+#include <dune/tectonic/mydirectionalconvexfunction.hh>
+
+#include "compute_state_dieterich_common.hh"
+#include "compute_state_dieterich_euler.hh"
+
+double state_update_dieterich_euler_bisection(double tau, double VoL,
+                                              double old_state) {
+  DieterichNonlinearity::VectorType const start(0);
+  DieterichNonlinearity::VectorType const direction(1);
+  DieterichNonlinearity const phi(VoL);
+  MyDirectionalConvexFunction<DieterichNonlinearity> const J(
+      1.0 / tau, old_state / tau, phi, start, direction);
+
+  int bisectionsteps = 0;
+  Bisection const bisection(0.0, 1.0, 1e-12, true, 0);    // TODO
+  return bisection.minimize(J, 0.0, 0.0, bisectionsteps); // TODO
+}
+
+double state_update_dieterich_euler(double tau, double VoL, double old_state) {
+  double const ret =
+      state_update_dieterich_euler_bisection(tau, VoL, old_state);
+  /* We have
+
+     ret - old_state + tau * VoL = tau*exp(-ret)
+
+     or
+
+     log((ret - old_state)/tau + VoL) = -ret
+  */
+  assert(std::min(std::abs(ret - old_state + tau * (VoL - std::exp(-ret))),
+                  std::abs(std::log((ret - old_state) / tau + VoL) + ret)) <
+         1e-12);
+  return ret;
+}
diff --git a/src/compute_state_dieterich_euler.hh b/src/compute_state_dieterich_euler.hh
new file mode 100644
index 0000000000000000000000000000000000000000..5c6c5f9162cb9413b0b38dc1a5e13ade0c4fb6e7
--- /dev/null
+++ b/src/compute_state_dieterich_euler.hh
@@ -0,0 +1,5 @@
+#ifndef COMPUTE_STATE_DIETERICH_EULER_HH
+#define COMPUTE_STATE_DIETERICH_EULER_HH
+
+double state_update_dieterich_euler(double h, double VoL, double old_state);
+#endif
diff --git a/src/compute_state_dieterich_newmark.cc b/src/compute_state_dieterich_newmark.cc
new file mode 100644
index 0000000000000000000000000000000000000000..18704f488bd3eb96e2466857a763c9227d59cd20
--- /dev/null
+++ b/src/compute_state_dieterich_newmark.cc
@@ -0,0 +1,35 @@
+#include <cassert>
+
+#include <dune/tnnmg/problem-classes/bisection.hh>
+
+#include <dune/tectonic/mydirectionalconvexfunction.hh>
+
+#include "compute_state_dieterich_common.hh"
+#include "compute_state_dieterich_newmark.hh"
+
+double state_update_dieterich_newmark_bisection(double tau, double VoL,
+                                                double old_state,
+                                                double old_stated) {
+  DieterichNonlinearity::VectorType const start(0);
+  DieterichNonlinearity::VectorType const direction(1);
+  DieterichNonlinearity const phi(VoL);
+  MyDirectionalConvexFunction<DieterichNonlinearity> const J(
+      2.0 / tau, old_stated + 2.0 / tau * old_state, phi, start, direction);
+
+  int bisectionsteps = 0;
+  Bisection const bisection(0.0, 1.0, 1e-12, true, 0);    // TODO
+  return bisection.minimize(J, 0.0, 0.0, bisectionsteps); // TODO
+}
+
+double state_update_dieterich_newmark(double tau, double VoL, double old_state,
+                                      double old_stated) {
+  double const new_state =
+      state_update_dieterich_newmark_bisection(tau, VoL, old_state, old_stated);
+  double const new_stated = 2.0 / tau * (new_state - old_state) - old_stated;
+  double const rhs = -new_stated;
+  double const lhs = VoL - std::exp(-new_state);
+
+  assert(std::abs(lhs - rhs) < 1e-10);
+
+  return new_state;
+}
diff --git a/src/compute_state_dieterich_newmark.hh b/src/compute_state_dieterich_newmark.hh
new file mode 100644
index 0000000000000000000000000000000000000000..755dbf03fbef3ca2de041e441c2351ea680d66d7
--- /dev/null
+++ b/src/compute_state_dieterich_newmark.hh
@@ -0,0 +1,6 @@
+#ifndef COMPUTE_STATE_DIETERICH_NEWMARK_HH
+#define COMPUTE_STATE_DIETERICH_NEWMARK_HH
+
+double state_update_dieterich_newmark(double h, double VoL, double old_state,
+                                      double old_stated);
+#endif
diff --git a/src/one-body-sample.cc b/src/one-body-sample.cc
index b4f376aec869b57f7719caea47f167cb69556d4b..8551d62ed936e46d6e9fa7439bea7365cae5db37 100644
--- a/src/one-body-sample.cc
+++ b/src/one-body-sample.cc
@@ -65,7 +65,8 @@
 #include <dune/tectonic/myconvexproblem.hh>
 
 #include "assemblers.hh"
-#include "compute_state_dieterich.hh"
+#include "compute_state_dieterich_euler.hh"
+#include "compute_state_dieterich_newmark.hh"
 #include "compute_state_ruina.hh"
 #include "mysolver.hh"
 #include "vtk.hh"
@@ -255,6 +256,10 @@ int main(int argc, char *argv[]) {
     alpha_old = parset.get<double>("boundary.friction.state.initial");
     SingletonVectorType alpha(alpha_old);
 
+    SingletonVectorType alphad_old(finestSize);
+    alphad_old = 0.0;
+    SingletonVectorType alphad(alphad_old);
+
     SingletonVectorType vonMisesStress;
     // }}}
 
@@ -375,7 +380,21 @@ int main(int argc, char *argv[]) {
               switch (parset.get<Config::state_model>(
                   "boundary.friction.state.model")) {
                 case Config::Dieterich:
-                  alpha[i] = state_update_dieterich(tau, V / L, alpha_old[i]);
+                  switch (
+                      parset.get<Config::scheme>("stateTimeSteppingScheme")) {
+                    case Config::ImplicitEuler:
+                      alpha[i] = state_update_dieterich_euler(tau, V / L,
+                                                              alpha_old[i]);
+                      break;
+                    case Config::Newmark:
+                      alpha[i] = state_update_dieterich_newmark(
+                          tau, V / L, alpha_old[i], alphad_old[i]);
+                      alphad[i] =
+                          2.0 / tau * (alpha[i] - alpha_old[i]) - alphad_old[i];
+                      break;
+                    default:
+                      assert(false); // Nothing else implemented
+                  }
                   break;
                 case Config::Ruina:
                   alpha[i] = state_update_ruina(tau, V * tau / L, alpha_old[i]);
@@ -430,6 +449,7 @@ int main(int argc, char *argv[]) {
       }
 
       alpha_old = alpha;
+      alphad_old = alphad;
 
       { // Write all kinds of data
         for (size_t i = 0; i < frictionalNodes.size(); ++i)
diff --git a/src/one-body-sample.parset b/src/one-body-sample.parset
index 64fa3a2b1df348f56e9be3ca418651030c437619..a6e3d7e76b5b4ba7c3a604d60a53530d12dc125f 100644
--- a/src/one-body-sample.parset
+++ b/src/one-body-sample.parset
@@ -11,6 +11,7 @@ printVelocitySteppingComparison = false
 enableTimer = false
 
 timeSteppingScheme = implicitEuler
+stateTimeSteppingScheme = implicitEuler
 
 [grid]
 refinements = 4