diff --git a/dune/tectonic/globallaursennonlinearity.hh b/dune/tectonic/globallaursennonlinearity.hh
index 4b24e83c1a7c6e96ca0c955c76507086eedb16f1..6d9d1ddcc023d59b561940acc1fa39f2a1c477fc 100644
--- a/dune/tectonic/globallaursennonlinearity.hh
+++ b/dune/tectonic/globallaursennonlinearity.hh
@@ -7,6 +7,7 @@
 
 #include <dune/common/fvector.hh>
 
+#include "localnonlinearity.hh"
 #include "globalnonlinearity.hh"
 #include "nicefunction.hh"
 
@@ -33,11 +34,15 @@ class GlobalLaursenNonlinearity : public Dune::GlobalNonlinearity<dim> {
 
     sigma_n [id + mu id] = sigma_n (1 + mu) id
   */
-  virtual Dune::NiceFunction *restriction(int i) const {
+  virtual shared_ptr<LocalNonlinearity<dim> const> restriction(int i) const {
     double coefficient = nodalIntegrals[i][0];
     coefficient *= normalStress[i];
     coefficient *= 1 + mu[i];
-    return new OuterFunctionType(coefficient);
+
+    shared_ptr<NiceFunction const> const func(
+        new OuterFunctionType(coefficient));
+    return shared_ptr<LocalNonlinearity<dim> const>(
+        new LocalNonlinearity<dim>(func));
   }
 
 private:
diff --git a/dune/tectonic/globalnonlinearity.hh b/dune/tectonic/globalnonlinearity.hh
index 7915f9ae636d09c4ff3de0bb973842b2e02e4f62..15d15da8a19bed63f2e835e519e8b85353feafef 100644
--- a/dune/tectonic/globalnonlinearity.hh
+++ b/dune/tectonic/globalnonlinearity.hh
@@ -6,14 +6,15 @@
 #include <dune/common/fvector.hh>
 
 #include "nicefunction.hh"
+#include "localnonlinearity.hh"
 
 namespace Dune {
 template <int dim> class GlobalNonlinearity {
 public:
   /*
-    Return a restriction of the outer function to the i'th node. If
+    Return a restriction of the outer function to the i'th node.
   */
-  virtual NiceFunction* restriction(int i) const = 0;
+  virtual shared_ptr<LocalNonlinearity<dim> const> restriction(int i) const = 0;
 };
 }
 #endif
diff --git a/dune/tectonic/globalruinanonlinearity.hh b/dune/tectonic/globalruinanonlinearity.hh
index a2b2cb68dbb7c19a746a46917bc6991cb27df5df..249be621e63271a939615082aff8cd55f7ea23a9 100644
--- a/dune/tectonic/globalruinanonlinearity.hh
+++ b/dune/tectonic/globalruinanonlinearity.hh
@@ -22,20 +22,25 @@ class GlobalRuinaNonlinearity : public Dune::GlobalNonlinearity<dim> {
         a(a),
         mu(mu),
         eta(eta),
-        normalStress(normalStress) {}
+        normalStress(normalStress),
+        trivialNonlinearity(new LocalNonlinearity<dim>(
+            shared_ptr<NiceFunction const>(new TrivialFunction))) {}
 
   /*
     Return a restriction of the outer function to the i'th node.
   */
-  virtual Dune::NiceFunction *restriction(int i) const {
+  virtual shared_ptr<LocalNonlinearity<dim> const> restriction(int i) const {
     if (nodalIntegrals[i][0] == 0)
-      return new Dune::TrivialFunction();
-    else
-      return new Dune::RuinaFunction(nodalIntegrals[i][0], a[i], mu[i], eta[i],
-                                     normalStress[i]);
+      return trivialNonlinearity;
+
+    shared_ptr<NiceFunction const> const func(new Dune::RuinaFunction(
+        nodalIntegrals[i][0], a[i], mu[i], eta[i], normalStress[i]));
+    return shared_ptr<LocalNonlinearity<dim>>(new LocalNonlinearity<dim>(func));
   }
 
 private:
+  shared_ptr<LocalNonlinearity<dim> const> const trivialNonlinearity;
+
   std::vector<Dune::FieldVector<double, 1>> nodalIntegrals;
   std::vector<double> a;
   std::vector<double> mu;
diff --git a/dune/tectonic/localnonlinearity.hh b/dune/tectonic/localnonlinearity.hh
index fbdd63257359a3df461d7396b48a6c8841be9f1e..0d5b5b78c5d45745f81f4b33254b2b13b6924ba6 100644
--- a/dune/tectonic/localnonlinearity.hh
+++ b/dune/tectonic/localnonlinearity.hh
@@ -18,7 +18,7 @@ template <int dimension> class LocalNonlinearity {
   typedef FieldVector<double, dimension> VectorType;
   typedef FieldMatrix<double, dimension, dimension> MatrixType;
 
-  LocalNonlinearity(Dune::shared_ptr<NiceFunction> &func) : func_(func) {}
+  LocalNonlinearity(Dune::shared_ptr<NiceFunction const> func) : func_(func) {}
 
   double operator()(VectorType const x) const {
     double ret;
@@ -63,7 +63,7 @@ template <int dimension> class LocalNonlinearity {
   }
 
 private:
-  Dune::shared_ptr<NiceFunction> &func_;
+  Dune::shared_ptr<NiceFunction const> const func_;
 };
 }
 #endif
diff --git a/dune/tectonic/myblockproblem.hh b/dune/tectonic/myblockproblem.hh
index dd085f9a4825519a51217b1361fc2843dacb65dd..cb96d7d0a7f6aa98fc5a8e6b6e097de31ca12d0b 100644
--- a/dune/tectonic/myblockproblem.hh
+++ b/dune/tectonic/myblockproblem.hh
@@ -9,7 +9,6 @@
 #include <dune/tnnmg/problem-classes/onedconvexfunction.hh>
 
 #include "localnonlinearity.hh"
-#include "nicefunction.hh"
 #include "samplefunctional.hh"
 
 /** \brief Base class for problems where each block can be solved with a
@@ -118,8 +117,7 @@ class MyBlockProblem<MyConvexProblemTypeTEMPLATE>::IterateObject {
       }
       assert(localA != NULL);
 
-      Dune::shared_ptr<Dune::NiceFunction> f(problem.phi.restriction(m));
-      Dune::LocalNonlinearity<block_size> const phi(f);
+      auto phi = problem.phi.restriction(m);
       Dune::SampleFunctional<block_size> localJ(*localA, localb, phi,
                                                 ignore_component);
 
diff --git a/dune/tectonic/samplefunctional.hh b/dune/tectonic/samplefunctional.hh
index f5de28a3311d9d2b60932987df095cce11f15f48..d042d9e7edaffa673707932d52b68689946671f6 100644
--- a/dune/tectonic/samplefunctional.hh
+++ b/dune/tectonic/samplefunctional.hh
@@ -24,15 +24,15 @@ template <int dim> class SampleFunctional {
   typedef LocalNonlinearity<dim> NonlinearityType;
 
   SampleFunctional(SmallMatrix const &A, SmallVector const &b,
-                   NonlinearityType const &phi, int ignore = dim)
+                   shared_ptr<NonlinearityType const> phi, int ignore = dim)
       : A(A), b(b), phi(phi), ignore(ignore) {}
 
   double operator()(SmallVector const &v) const {
     SmallVector y;
-    A.mv(v, y);            //      Av
-    y /= 2;                //  1/2 Av
-    y -= b;                //  1/2 Av - b
-    return y * v + phi(v); // <1/2 Av - b,v> + H(|v|)
+    A.mv(v, y);             //      Av
+    y /= 2;                 //  1/2 Av
+    y -= b;                 //  1/2 Av - b
+    return y * v + *phi(v); // <1/2 Av - b,v> + H(|v|)
   }
 
   bool descentDirection(SmallVector const x, SmallVector &ret) const {
@@ -44,7 +44,7 @@ template <int dim> class SampleFunctional {
       smoothGradient(x, d);
 
       Interval<double> D;
-      phi.directionalSubDiff(x, d, D);
+      phi->directionalSubDiff(x, d, D);
       double const nonlinearDecline = D[1];
       double const smoothDecline = -(d * d);
       double const combinedDecline = smoothDecline + nonlinearDecline;
@@ -94,7 +94,7 @@ template <int dim> class SampleFunctional {
 
   SmallMatrix const &A;
   SmallVector const &b;
-  NonlinearityType const &phi;
+  shared_ptr<NonlinearityType const> const phi;
   int const ignore;
 
 private:
@@ -107,7 +107,7 @@ template <int dim> class SampleFunctional {
   }
 
   void upperGradient(SmallVector const &x, SmallVector &y) const {
-    phi.upperGradient(x, y);
+    phi->upperGradient(x, y);
     SmallVector z;
     smoothGradient(x, z);
     y += z;
@@ -116,7 +116,7 @@ template <int dim> class SampleFunctional {
   }
 
   void lowerGradient(SmallVector const &x, SmallVector &y) const {
-    phi.lowerGradient(x, y);
+    phi->lowerGradient(x, y);
     SmallVector z;
     smoothGradient(x, z);
     y += z;
@@ -156,7 +156,7 @@ void minimise(Functional const J, typename Functional::SmallVector &x,
       return;
 
     typedef typename Functional::NonlinearityType LocalNonlinearityType;
-    LocalNonlinearityType phi = J.phi;
+    LocalNonlinearityType phi = *J.phi; // copy, see below
     if (linesearchp) {
       // {{{ Construct a restriction of J to the line x + t * descDir