From f466f865308a0b0784caadd41d9c338dfc58019b Mon Sep 17 00:00:00 2001
From: Oliver Sander <oliver.sander@tu-dresden.de>
Date: Fri, 30 Aug 2019 12:52:19 +0200
Subject: [PATCH] WIP

---
 dune/elasticity/assemblers/feassembler.hh     |   2 +-
 dune/elasticity/common/trustregionsolver.cc   |  70 ++++++++++++
 dune/elasticity/common/trustregionsolver.hh   |   2 +
 dune/elasticity/materials/burkholderenergy.hh |  99 +++++++++++++++++
 .../materials/burkholderstarenergy.hh         | 102 ++++++++++++++++++
 dune/elasticity/materials/cosh2energy.hh      |  96 +++++++++++++++++
 dune/elasticity/materials/dacorognaenergy.hh  |  97 +++++++++++++++++
 dune/elasticity/materials/neffmagicenergy.hh  |  27 ++++-
 dune/elasticity/materials/neffw2energy.hh     | 102 ++++++++++++++++++
 .../quasiconvexity-circle-burkholder.parset   |  81 ++++++++++++++
 problems/quasiconvexity-circle-cosh2.parset   |  75 +++++++++++++
 .../quasiconvexity-circle-dacorogna.parset    |  84 +++++++++++++++
 .../quasiconvexity-circle-expacosh.parset     |  15 ++-
 problems/quasiconvexity-circle-magic.parset   |  84 +++++++++++++++
 problems/quasiconvexity-circle-w2.parset      |  85 +++++++++++++++
 src/CMakeLists.txt                            |   2 +
 src/finite-strain-elasticity.cc               |   2 +
 src/quasiconvexity-test.cc                    |  90 ++++++++++++++--
 18 files changed, 1100 insertions(+), 15 deletions(-)
 create mode 100644 dune/elasticity/materials/burkholderenergy.hh
 create mode 100644 dune/elasticity/materials/burkholderstarenergy.hh
 create mode 100644 dune/elasticity/materials/cosh2energy.hh
 create mode 100644 dune/elasticity/materials/dacorognaenergy.hh
 create mode 100644 dune/elasticity/materials/neffw2energy.hh
 create mode 100644 problems/quasiconvexity-circle-burkholder.parset
 create mode 100644 problems/quasiconvexity-circle-cosh2.parset
 create mode 100644 problems/quasiconvexity-circle-dacorogna.parset
 create mode 100644 problems/quasiconvexity-circle-magic.parset
 create mode 100644 problems/quasiconvexity-circle-w2.parset

diff --git a/dune/elasticity/assemblers/feassembler.hh b/dune/elasticity/assemblers/feassembler.hh
index 0486478..0ce8dbb 100644
--- a/dune/elasticity/assemblers/feassembler.hh
+++ b/dune/elasticity/assemblers/feassembler.hh
@@ -70,7 +70,7 @@ getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const
 
     nb.resize(n, n);
 
-    for (const auto& element : elements(basis_.getGridView(), Dune::Partitions::interior))
+    for (const auto& element : elements(basis_.getGridView()/*, Dune::Partitions::interior*/))
     {
         const typename Basis::LocalFiniteElement& lfe = basis_.getLocalFiniteElement(element);
 
diff --git a/dune/elasticity/common/trustregionsolver.cc b/dune/elasticity/common/trustregionsolver.cc
index 5d16bf1..7b39adb 100644
--- a/dune/elasticity/common/trustregionsolver.cc
+++ b/dune/elasticity/common/trustregionsolver.cc
@@ -98,6 +98,7 @@ setup(const typename BasisType::GridView::Grid& grid,
 
     auto mmgStep = std::make_shared< MonotoneMGStep<MatrixType, CorrectionType> >();
 
+    mmgStep->setVerbosity(NumProc::REDUCED);
     mmgStep->setMGType(mu, nu1, nu2);
     mmgStep->ignoreNodes_ = &dirichletNodes;
     mmgStep->setBaseSolver(baseSolver);
@@ -288,6 +289,54 @@ void TrustRegionSolver<BasisType,VectorType>::solve()
                                                    i==0    // assemble occupation pattern only for the first call
                                                    );
 
+
+
+            ////////////////////////////////////////////////////////////////////
+            //  Try to determine the largest negative eigen value
+            ////////////////////////////////////////////////////////////////////
+#if 0
+            double upperBoundForEV = 1e4;
+            auto A = *hessianMatrix_;
+            for (std::size_t j=0; j<A.N(); j++)
+            {
+              A[i][i][0][0] -= upperBoundForEV;
+              A[i][i][1][1] -= upperBoundForEV;
+            }
+
+            // If the upper bound has been large enough, A is negative definite
+            CorrectionType eigenVector(rhs.size());
+            std::fill(eigenVector.begin(), eigenVector.end(), 1.0);
+
+            for (int j=0; j<1e6; j++)
+            {
+              if ( (j%1000)==0)
+                std::cout << "power iteration: " <<j << std::endl;
+              CorrectionType nextEV(eigenVector.size());
+
+              A.mv(eigenVector,nextEV);
+              nextEV /= nextEV.two_norm();
+
+              eigenVector = nextEV;
+
+              // Compute the currect approximation to the eigen value
+              CorrectionType tmp(eigenVector.size());
+              A.mv(eigenVector,tmp);
+
+              double eigenValue = (eigenVector * tmp) / eigenVector.two_norm2();
+
+              //std::cout << "eigen value: " << (-eigenValue + upperBoundForEV) << std::endl;
+//               std::cout << "eigen value: " << eigenValue << std::endl;
+            }
+
+            CorrectionType tmp(eigenVector.size());
+            hessianMatrix_->mv(eigenVector,tmp);
+
+            std::cout << "real eigen value: " << ((eigenVector * tmp) / eigenVector.two_norm2()) << std::endl;
+#endif
+
+            ///////////////////////////////////////////////////////////////////
+            //  Continue with the actual computation
+            ///////////////////////////////////////////////////////////////////
             rhs *= -1;        // The right hand side is the _negative_ gradient
 
             // Compute gradient norm to monitor convergence
@@ -482,6 +531,27 @@ void TrustRegionSolver<BasisType,VectorType>::solve()
         for (size_t j=0; j<newIterate.size(); j++)
             newIterate[j] += corr[j];
 
+        // Write newIterate to a file, so we can see whether it is worth waiting for the end of
+        // the simulation
+        using namespace Dune::Functions::BasisFactory;
+        auto powerBasis = makeBasis(
+          grid_->leafGridView(),
+          power<2>(
+            lagrange<1>(),
+            blockedInterleaved()
+        ));
+
+        SolutionType identity;
+        Dune::Functions::interpolate(powerBasis, identity, [](Dune::FieldVector<double,2> x){ return x; });
+
+
+        auto displacement = newIterate;
+        displacement -= identity;
+        auto displacementFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<Dune::FieldVector<double,2>>(basis, displacement);
+        Dune::VTKWriter<typename BasisType::GridView> vtkWriter(grid_->leafGridView());
+        vtkWriter.addVertexData(displacementFunction, Dune::VTK::FieldInfo("displacement", Dune::VTK::FieldInfo::Type::vector, 2));
+        vtkWriter.write(iterateNamePrefix_ + "tr-iterate-" + std::to_string(i));
+
         double energy    = assembler_->computeEnergy(newIterate);
         energy = grid_->comm().sum(energy);
 
diff --git a/dune/elasticity/common/trustregionsolver.hh b/dune/elasticity/common/trustregionsolver.hh
index 1b87165..2039d9f 100644
--- a/dune/elasticity/common/trustregionsolver.hh
+++ b/dune/elasticity/common/trustregionsolver.hh
@@ -99,6 +99,8 @@ public:
 
     SolutionType getSol() const {return x_;}
 
+    std::string iterateNamePrefix_;
+
 protected:
 
     /** \brief The grid */
diff --git a/dune/elasticity/materials/burkholderenergy.hh b/dune/elasticity/materials/burkholderenergy.hh
new file mode 100644
index 0000000..1f63ffc
--- /dev/null
+++ b/dune/elasticity/materials/burkholderenergy.hh
@@ -0,0 +1,99 @@
+#ifndef DUNE_ELASTICITY_MATERIALS_BURKHOLDERENERGY_HH
+#define DUNE_ELASTICITY_MATERIALS_BURKHOLDERENERGY_HH
+
+#include <dune/common/fmatrix.hh>
+#include <dune/common/parametertree.hh>
+
+#include <dune/geometry/quadraturerules.hh>
+
+#include <dune/elasticity/assemblers/localfestiffness.hh>
+
+namespace Dune::Elasticity {
+
+template<class GridView, class LocalFiniteElement, class field_type=double>
+class BurkholderEnergy
+  : public LocalFEStiffness<GridView,
+                            LocalFiniteElement,
+                            std::vector<Dune::FieldVector<field_type,GridView::dimension> > >
+{
+  // grid types
+  typedef typename GridView::Grid::ctype DT;
+  typedef typename GridView::template Codim<0>::Entity Entity;
+
+  // some other sizes
+  enum {gridDim=GridView::dimension};
+  enum {dim=GridView::dimension};
+
+public:
+
+  /** \brief Constructor with a set of material parameters
+   * \param parameters The material parameters
+   */
+  BurkholderEnergy(const Dune::ParameterTree& parameters)
+  {
+    p_ = parameters.template get<double>("p");
+  }
+
+  /** \brief Assemble the energy for a single element */
+  field_type energy (const Entity& e,
+                     const LocalFiniteElement& localFiniteElement,
+                     const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const;
+  double p_;
+
+};
+
+template <class GridView, class LocalFiniteElement, class field_type>
+field_type
+BurkholderEnergy<GridView, LocalFiniteElement, field_type>::
+energy(const Entity& element,
+       const LocalFiniteElement& localFiniteElement,
+       const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const
+{
+  assert(element.type() == localFiniteElement.type());
+
+  field_type energy = 0;
+
+  // store gradients of shape functions and base functions
+  std::vector<Dune::FieldMatrix<DT,1,gridDim> > referenceGradients(localFiniteElement.size());
+  std::vector<Dune::FieldVector<DT,gridDim> > gradients(localFiniteElement.size());
+
+  int quadOrder = (element.type().isSimplex()) ? localFiniteElement.localBasis().order()
+                                               : localFiniteElement.localBasis().order() * gridDim;
+
+  const auto& quad = Dune::QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+
+  for (const auto& qp : quad)
+  {
+    const DT integrationElement = element.geometry().integrationElement(qp.position());
+
+    const auto jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(qp.position());
+
+    // get gradients of shape functions
+    localFiniteElement.localBasis().evaluateJacobian(qp.position(), referenceGradients);
+
+    // compute gradients of base functions
+    for (size_t i=0; i<gradients.size(); ++i)
+      jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]);
+
+    Dune::FieldMatrix<field_type,gridDim,gridDim> derivative(0);
+    for (size_t i=0; i<gradients.size(); i++)
+      for (int j=0; j<gridDim; j++)
+        derivative[j].axpy(localConfiguration[i][j], gradients[i]);
+
+    auto det = derivative.determinant();
+    auto normSquared = derivative.frobenius_norm2();
+
+    auto lambdaMaxSquared = 0.5 * (normSquared + std::sqrt(normSquared*normSquared - 4*det*det));
+    auto lambdaMax = std::sqrt(lambdaMaxSquared);
+
+    auto energyDensity = 0.5 * p_ * det * std::pow(lambdaMax,p_-2) + 0.5*(2-p_) * std::pow(lambdaMax,p_);
+
+    energy -= qp.weight() * integrationElement * energyDensity;
+  }
+
+  return energy;
+}
+
+}  // namespace Dune::Elasticity
+
+#endif   //#ifndef DUNE_ELASTICITY_MATERIALS_BURKHOLDERENERGY_HH
diff --git a/dune/elasticity/materials/burkholderstarenergy.hh b/dune/elasticity/materials/burkholderstarenergy.hh
new file mode 100644
index 0000000..efa2cc9
--- /dev/null
+++ b/dune/elasticity/materials/burkholderstarenergy.hh
@@ -0,0 +1,102 @@
+#ifndef DUNE_ELASTICITY_MATERIALS_NEFFMAGICENERGY_HH
+#define DUNE_ELASTICITY_MATERIALS_NEFFMAGICENERGY_HH
+
+#include <dune/common/fmatrix.hh>
+#include <dune/common/parametertree.hh>
+
+#include <dune/geometry/quadraturerules.hh>
+
+#include <dune/elasticity/assemblers/localfestiffness.hh>
+
+namespace Dune::Elasticity {
+
+template<class GridView, class LocalFiniteElement, class field_type=double>
+class NeffMagicEnergy
+  : public LocalFEStiffness<GridView,
+                            LocalFiniteElement,
+                            std::vector<Dune::FieldVector<field_type,GridView::dimension> > >
+{
+  // grid types
+  typedef typename GridView::Grid::ctype DT;
+  typedef typename GridView::template Codim<0>::Entity Entity;
+
+  // some other sizes
+  enum {gridDim=GridView::dimension};
+  enum {dim=GridView::dimension};
+
+public:
+
+  /** \brief Constructor with a set of material parameters
+   * \param parameters The material parameters
+   */
+  NeffMagicEnergy(const Dune::ParameterTree& parameters)
+  {
+    c_ = 1.0;
+    if (parameters.hasKey("c"))
+      c_ = parameters.template get<double>("c");
+  }
+
+  /** \brief Assemble the energy for a single element */
+  field_type energy (const Entity& e,
+                     const LocalFiniteElement& localFiniteElement,
+                     const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const;
+  double c_;
+
+};
+
+template <class GridView, class LocalFiniteElement, class field_type>
+field_type
+NeffMagicEnergy<GridView, LocalFiniteElement, field_type>::
+energy(const Entity& element,
+       const LocalFiniteElement& localFiniteElement,
+       const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const
+{
+  assert(element.type() == localFiniteElement.type());
+
+  field_type energy = 0;
+
+  // store gradients of shape functions and base functions
+  std::vector<Dune::FieldMatrix<DT,1,gridDim> > referenceGradients(localFiniteElement.size());
+  std::vector<Dune::FieldVector<DT,gridDim> > gradients(localFiniteElement.size());
+
+  int quadOrder = (element.type().isSimplex()) ? localFiniteElement.localBasis().order()
+                                               : localFiniteElement.localBasis().order() * gridDim;
+
+  const auto& quad = Dune::QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+
+  for (const auto& qp : quad)
+  {
+    const DT integrationElement = element.geometry().integrationElement(qp.position());
+
+    const auto jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(qp.position());
+
+    // get gradients of shape functions
+    localFiniteElement.localBasis().evaluateJacobian(qp.position(), referenceGradients);
+
+    // compute gradients of base functions
+    for (size_t i=0; i<gradients.size(); ++i)
+      jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]);
+
+    Dune::FieldMatrix<field_type,gridDim,gridDim> derivative(0);
+    for (size_t i=0; i<gradients.size(); i++)
+      for (int j=0; j<gridDim; j++)
+        derivative[j].axpy(localConfiguration[i][j], gradients[i]);
+
+    auto det = derivative.determinant();
+    auto normSquared = derivative.frobenius_norm2();
+
+    auto K = normSquared / (2*det);
+
+    using std::acosh;
+
+    auto energyDensity = K + std::sqrt(K*K-1) - acosh(K) + c_*log(det);
+
+    energy += qp.weight() * integrationElement * energyDensity;
+  }
+
+  return energy;
+}
+
+}  // namespace Dune::Elasticity
+
+#endif   //#ifndef DUNE_ELASTICITY_MATERIALS_EXPACOSHENERGY_HH
diff --git a/dune/elasticity/materials/cosh2energy.hh b/dune/elasticity/materials/cosh2energy.hh
new file mode 100644
index 0000000..43e17fb
--- /dev/null
+++ b/dune/elasticity/materials/cosh2energy.hh
@@ -0,0 +1,96 @@
+#ifndef DUNE_ELASTICITY_MATERIALS_COSH2ENERGY_HH
+#define DUNE_ELASTICITY_MATERIALS_COSH2ENERGY_HH
+
+#include <dune/common/fmatrix.hh>
+#include <dune/common/fmatrixev.hh>
+
+#include <dune/geometry/quadraturerules.hh>
+
+#include <dune/elasticity/assemblers/localfestiffness.hh>
+
+namespace Dune {
+
+template<class GridView, class LocalFiniteElement, class field_type=double>
+class CosH2Energy
+  : public LocalFEStiffness<GridView,
+                            LocalFiniteElement,
+                            std::vector<Dune::FieldVector<field_type,GridView::dimension> > >
+{
+  // grid types
+  typedef typename GridView::Grid::ctype DT;
+  typedef typename GridView::template Codim<0>::Entity Entity;
+
+  // some other sizes
+  enum {gridDim=GridView::dimension};
+  enum {dim=GridView::dimension};
+
+public:
+
+  /** \brief Constructor with a set of material parameters
+   * \param parameters The material parameters
+   */
+  CosH2Energy(const Dune::ParameterTree& parameters)
+  {}
+
+  /** \brief Assemble the energy for a single element */
+  field_type energy (const Entity& e,
+                     const LocalFiniteElement& localFiniteElement,
+                     const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const;
+};
+
+template <class GridView, class LocalFiniteElement, class field_type>
+field_type
+CosH2Energy<GridView, LocalFiniteElement, field_type>::
+energy(const Entity& element,
+       const LocalFiniteElement& localFiniteElement,
+       const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const
+{
+  assert(element.type() == localFiniteElement.type());
+
+  field_type energy = 0;
+
+  // store gradients of shape functions and base functions
+  std::vector<Dune::FieldMatrix<DT,1,gridDim> > referenceGradients(localFiniteElement.size());
+  std::vector<Dune::FieldVector<DT,gridDim> > gradients(localFiniteElement.size());
+
+  int quadOrder = (element.type().isSimplex()) ? localFiniteElement.localBasis().order()
+                                               : localFiniteElement.localBasis().order() * gridDim;
+
+  const auto& quad = Dune::QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+
+  for (const auto& qp : quad)
+  {
+    const DT integrationElement = element.geometry().integrationElement(qp.position());
+
+    const auto jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(qp.position());
+
+    // get gradients of shape functions
+    localFiniteElement.localBasis().evaluateJacobian(qp.position(), referenceGradients);
+
+    // compute gradients of base functions
+    for (size_t i=0; i<gradients.size(); ++i)
+      jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]);
+
+    Dune::FieldMatrix<field_type,gridDim,gridDim> derivative(0);
+    for (size_t i=0; i<gradients.size(); i++)
+      for (int j=0; j<gridDim; j++)
+        derivative[j].axpy(localConfiguration[i][j], gradients[i]);
+
+    auto det = derivative.determinant();
+    auto normSquared = derivative.frobenius_norm2();
+
+    auto K = normSquared / (2*det);
+
+    using std::cosh;
+
+    auto energyDensity = cosh(K-2)-1;
+
+    energy += qp.weight() * integrationElement * energyDensity;
+  }
+
+  return energy;
+}
+
+}  // namespace Dune
+
+#endif   //#ifndef DUNE_ELASTICITY_MATERIALS_COSH2ENERGY_HH
diff --git a/dune/elasticity/materials/dacorognaenergy.hh b/dune/elasticity/materials/dacorognaenergy.hh
new file mode 100644
index 0000000..b1632e8
--- /dev/null
+++ b/dune/elasticity/materials/dacorognaenergy.hh
@@ -0,0 +1,97 @@
+#ifndef DUNE_ELASTICITY_MATERIALS_DACOROGNAENERGY_HH
+#define DUNE_ELASTICITY_MATERIALS_DACOROGNAENERGY_HH
+
+#include <dune/common/fmatrix.hh>
+#include <dune/common/parametertree.hh>
+
+#include <dune/geometry/quadraturerules.hh>
+
+#include <dune/elasticity/assemblers/localfestiffness.hh>
+
+namespace Dune::Elasticity {
+
+template<class GridView, class LocalFiniteElement, class field_type=double>
+class DacorognaEnergy
+  : public LocalFEStiffness<GridView,
+                            LocalFiniteElement,
+                            std::vector<Dune::FieldVector<field_type,GridView::dimension> > >
+{
+  // grid types
+  typedef typename GridView::Grid::ctype DT;
+  typedef typename GridView::template Codim<0>::Entity Entity;
+
+  // some other sizes
+  enum {gridDim=GridView::dimension};
+  enum {dim=GridView::dimension};
+
+public:
+
+  /** \brief Constructor with a set of material parameters
+   * \param parameters The material parameters
+   */
+  DacorognaEnergy(const Dune::ParameterTree& parameters)
+  {
+    gamma_ = parameters.template get<double>("gamma");
+  }
+
+  /** \brief Assemble the energy for a single element */
+  field_type energy (const Entity& e,
+                     const LocalFiniteElement& localFiniteElement,
+                     const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const;
+
+  double gamma_;
+
+};
+
+template <class GridView, class LocalFiniteElement, class field_type>
+field_type
+DacorognaEnergy<GridView, LocalFiniteElement, field_type>::
+energy(const Entity& element,
+       const LocalFiniteElement& localFiniteElement,
+       const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const
+{
+  assert(element.type() == localFiniteElement.type());
+
+  field_type energy = 0;
+
+  // store gradients of shape functions and base functions
+  std::vector<Dune::FieldMatrix<DT,1,gridDim> > referenceGradients(localFiniteElement.size());
+  std::vector<Dune::FieldVector<DT,gridDim> > gradients(localFiniteElement.size());
+
+  int quadOrder = (element.type().isSimplex()) ? localFiniteElement.localBasis().order()
+                                               : localFiniteElement.localBasis().order() * gridDim;
+
+  const auto& quad = Dune::QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+
+  for (const auto& qp : quad)
+  {
+    const DT integrationElement = element.geometry().integrationElement(qp.position());
+
+    const auto jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(qp.position());
+
+    // get gradients of shape functions
+    localFiniteElement.localBasis().evaluateJacobian(qp.position(), referenceGradients);
+
+    // compute gradients of base functions
+    for (size_t i=0; i<gradients.size(); ++i)
+      jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]);
+
+    Dune::FieldMatrix<field_type,gridDim,gridDim> derivative(0);
+    for (size_t i=0; i<gradients.size(); i++)
+      for (int j=0; j<gridDim; j++)
+        derivative[j].axpy(localConfiguration[i][j], gradients[i]);
+
+    auto det = derivative.determinant();
+    auto normSquared = derivative.frobenius_norm2();
+
+    auto energyDensity = normSquared * ( normSquared - gamma_ * det);
+
+    energy += qp.weight() * integrationElement * energyDensity;
+  }
+
+  return energy;
+}
+
+}  // namespace Dune::Elasticity
+
+#endif   //#ifndef DUNE_ELASTICITY_MATERIALS_DACOROGNAENERGY_HH
diff --git a/dune/elasticity/materials/neffmagicenergy.hh b/dune/elasticity/materials/neffmagicenergy.hh
index 4c09fa2..a06450e 100644
--- a/dune/elasticity/materials/neffmagicenergy.hh
+++ b/dune/elasticity/materials/neffmagicenergy.hh
@@ -30,12 +30,31 @@ public:
    * \param parameters The material parameters
    */
   NeffMagicEnergy(const Dune::ParameterTree& parameters)
-  {}
+  {
+    c_ = 1.0;
+    if (parameters.hasKey("c"))
+      c_ = parameters.template get<double>("c");
+  }
 
   /** \brief Assemble the energy for a single element */
   field_type energy (const Entity& e,
                      const LocalFiniteElement& localFiniteElement,
                      const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const;
+
+
+  double c(const Dune::FieldVector<double,dim>& x) const
+  {
+#if 0  // Three circles
+    bool inCircle0 = (x-FieldVector<double,dim>{-0.5,0}).two_norm() <0.2;
+    bool inCircle1 = (x-FieldVector<double,dim>{0.3535,0.3535}).two_norm() <0.2;
+    bool inCircle2 = (x-FieldVector<double,dim>{0.3535,-0.3535}).two_norm() <0.2;
+
+    return (inCircle0 or inCircle1 or inCircle2) ? c_ : 1;
+#endif
+    return (x.two_norm() < 0.9) ? 1 : c_;
+  }
+  double c_;
+
 };
 
 template <class GridView, class LocalFiniteElement, class field_type>
@@ -83,7 +102,9 @@ energy(const Entity& element,
 
     using std::acosh;
 
-    auto energyDensity = K + std::sqrt(K*K-1) - acosh(K) + log(det);
+    auto worldPos = element.geometry().global(qp.position());
+
+    auto energyDensity = K + std::sqrt(K*K-1) - acosh(K) + c(worldPos)*log(det);
 
     energy += qp.weight() * integrationElement * energyDensity;
   }
@@ -93,4 +114,4 @@ energy(const Entity& element,
 
 }  // namespace Dune::Elasticity
 
-#endif   //#ifndef DUNE_ELASTICITY_MATERIALS_EXPACOSHENERGY_HH
+#endif   //#ifndef DUNE_ELASTICITY_MATERIALS_NEFFMAGICENERGY_HH
diff --git a/dune/elasticity/materials/neffw2energy.hh b/dune/elasticity/materials/neffw2energy.hh
new file mode 100644
index 0000000..5b5f850
--- /dev/null
+++ b/dune/elasticity/materials/neffw2energy.hh
@@ -0,0 +1,102 @@
+#ifndef DUNE_ELASTICITY_MATERIALS_NEFFW2ENERGY_HH
+#define DUNE_ELASTICITY_MATERIALS_NEFFW2ENERGY_HH
+
+#include <dune/common/fmatrix.hh>
+#include <dune/common/parametertree.hh>
+
+#include <dune/geometry/quadraturerules.hh>
+
+#include <dune/elasticity/assemblers/localfestiffness.hh>
+
+namespace Dune::Elasticity {
+
+template<class GridView, class LocalFiniteElement, class field_type=double>
+class NeffW2Energy
+  : public LocalFEStiffness<GridView,
+                            LocalFiniteElement,
+                            std::vector<Dune::FieldVector<field_type,GridView::dimension> > >
+{
+  // grid types
+  typedef typename GridView::Grid::ctype DT;
+  typedef typename GridView::template Codim<0>::Entity Entity;
+
+  // some other sizes
+  enum {gridDim=GridView::dimension};
+  enum {dim=GridView::dimension};
+
+public:
+
+  /** \brief Constructor with a set of material parameters
+   * \param parameters The material parameters
+   */
+  NeffW2Energy(const Dune::ParameterTree& parameters)
+  {
+    c_ = 1.0;
+    if (parameters.hasKey("c"))
+      c_ = parameters.template get<double>("c");
+  }
+
+  /** \brief Assemble the energy for a single element */
+  field_type energy (const Entity& e,
+                     const LocalFiniteElement& localFiniteElement,
+                     const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const;
+  double c_;
+
+};
+
+template <class GridView, class LocalFiniteElement, class field_type>
+field_type
+NeffW2Energy<GridView, LocalFiniteElement, field_type>::
+energy(const Entity& element,
+       const LocalFiniteElement& localFiniteElement,
+       const std::vector<Dune::FieldVector<field_type, gridDim> >& localConfiguration) const
+{
+  assert(element.type() == localFiniteElement.type());
+
+  field_type energy = 0;
+
+  // store gradients of shape functions and base functions
+  std::vector<Dune::FieldMatrix<DT,1,gridDim> > referenceGradients(localFiniteElement.size());
+  std::vector<Dune::FieldVector<DT,gridDim> > gradients(localFiniteElement.size());
+
+  int quadOrder = (element.type().isSimplex()) ? localFiniteElement.localBasis().order()
+                                               : localFiniteElement.localBasis().order() * gridDim;
+
+  const auto& quad = Dune::QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+
+  for (const auto& qp : quad)
+  {
+    const DT integrationElement = element.geometry().integrationElement(qp.position());
+
+    const auto jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(qp.position());
+
+    // get gradients of shape functions
+    localFiniteElement.localBasis().evaluateJacobian(qp.position(), referenceGradients);
+
+    // compute gradients of base functions
+    for (size_t i=0; i<gradients.size(); ++i)
+      jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]);
+
+    Dune::FieldMatrix<field_type,gridDim,gridDim> derivative(0);
+    for (size_t i=0; i<gradients.size(); i++)
+      for (int j=0; j<gridDim; j++)
+        derivative[j].axpy(localConfiguration[i][j], gradients[i]);
+
+    auto det = derivative.determinant();
+    auto normSquared = derivative.frobenius_norm2();
+
+    auto K = normSquared / (2*det);
+
+    using std::acosh;
+
+    auto energyDensity = K + acosh(K) - c_*log(det);
+
+    energy += qp.weight() * integrationElement * energyDensity;
+  }
+
+  return energy;
+}
+
+}  // namespace Dune::Elasticity
+
+#endif   //#ifndef DUNE_ELASTICITY_MATERIALS_NEFFW2ENERGY_HH
diff --git a/problems/quasiconvexity-circle-burkholder.parset b/problems/quasiconvexity-circle-burkholder.parset
new file mode 100644
index 0000000..6050295
--- /dev/null
+++ b/problems/quasiconvexity-circle-burkholder.parset
@@ -0,0 +1,81 @@
+#############################################
+#  Grid parameters
+#############################################
+
+structuredGrid = false
+path = /home/sander/dune/dune-elasticity/grids/
+gridFile = circle2ndorder.msh
+
+#structuredGrid = true
+#lower = 0 0
+#upper = 1 1
+#elements = 2 2
+
+# Number of grid levels
+numLevels = 8
+
+#############################################
+#  Solver parameters
+#############################################
+
+# Number of homotopy steps for the Dirichlet boundary conditions
+numHomotopySteps = 1
+
+# Tolerance of the trust region solver
+tolerance = 1e-6
+
+# Max number of steps of the trust region solver
+maxTrustRegionSteps = 200
+
+# Initial trust-region radius
+initialTrustRegionRadius = 0.01
+
+# Number of multigrid iterations per trust-region step
+numIt = 200
+
+# Number of presmoothing steps
+nu1 = 3
+
+# Number of postsmoothing steps
+nu2 = 3
+
+# Number of coarse grid corrections
+mu = 1
+
+# Number of base solver iterations
+baseIt = 100
+
+# Tolerance of the multigrid solver
+mgTolerance = 1e-7
+
+# Tolerance of the base grid solver
+baseTolerance = 1e-8
+
+############################
+#   Material parameters
+############################
+
+energy = burkholder
+
+[materialParameters]
+
+p = 3
+
+[]
+
+#############################################
+#  Boundary values
+#############################################
+
+problem = neff-quasiconvexity
+
+###  Python predicate specifying all Dirichlet grid vertices
+# x is the vertex coordinate
+dirichletVerticesPredicate = "True"
+dirichletValues = affine
+
+# Initial deformation is (x[0] * sqrt(x0), x[1] / sqrt(x0))
+x0 = 3
+
+# Setting initialIterateFile overrides the x0 parameter
+#initialIterateFile = quasiconvexity-test-result-1.075-x0_1.1_8levels.data
diff --git a/problems/quasiconvexity-circle-cosh2.parset b/problems/quasiconvexity-circle-cosh2.parset
new file mode 100644
index 0000000..124a58a
--- /dev/null
+++ b/problems/quasiconvexity-circle-cosh2.parset
@@ -0,0 +1,75 @@
+#############################################
+#  Grid parameters
+#############################################
+
+structuredGrid = false
+sphereGrid = true
+#path = /home/sander/dune/dune-elasticity/grids/
+#gridFile = circle2ndorder.msh
+
+# Number of grid levels
+numLevels = 9
+
+#############################################
+#  Solver parameters
+#############################################
+
+# Number of homotopy steps for the Dirichlet boundary conditions
+numHomotopySteps = 1
+
+# Tolerance of the trust region solver
+tolerance = 1e-6
+
+# Max number of steps of the trust region solver
+maxTrustRegionSteps = 10000
+
+# Initial trust-region radius
+initialTrustRegionRadius = 0.01
+
+# Number of multigrid iterations per trust-region step
+numIt = 500
+
+# Number of presmoothing steps
+nu1 = 3
+
+# Number of postsmoothing steps
+nu2 = 3
+
+# Number of coarse grid corrections
+mu = 1
+
+# Number of base solver iterations
+baseIt = 100
+
+# Tolerance of the multigrid solver
+mgTolerance = 1e-7
+
+# Tolerance of the base grid solver
+baseTolerance = 1e-8
+
+############################
+#   Material parameters
+############################
+
+energy = cosh2
+
+[materialParameters]
+
+[]
+
+#############################################
+#  Boundary values
+#############################################
+
+problem = neff-quasiconvexity
+
+###  Python predicate specifying all Dirichlet grid vertices
+# x is the vertex coordinate
+dirichletVerticesPredicate = "True"
+#dirichletValues = affine
+
+# Initial deformation is (x[0] * sqrt(x0), x[1] / sqrt(x0))
+x0 = 1
+# Setting initialIterateFile overrides the x0 parameter
+#initialIterateFile = experiment-6.data
+#oldX0 = 10
diff --git a/problems/quasiconvexity-circle-dacorogna.parset b/problems/quasiconvexity-circle-dacorogna.parset
new file mode 100644
index 0000000..27abad9
--- /dev/null
+++ b/problems/quasiconvexity-circle-dacorogna.parset
@@ -0,0 +1,84 @@
+#############################################
+#  Grid parameters
+#############################################
+
+structuredGrid = false
+path = /home/sander/dune/dune-elasticity/grids/
+gridFile = circle2ndorder.msh
+
+#structuredGrid = true
+#lower = 0 0
+#upper = 1 1
+#elements = 2 2
+
+# Number of grid levels
+numLevels = 6
+
+#############################################
+#  Solver parameters
+#############################################
+
+# Number of homotopy steps for the Dirichlet boundary conditions
+numHomotopySteps = 1
+
+# Tolerance of the trust region solver
+tolerance = 1e-6
+
+# Max number of steps of the trust region solver
+maxTrustRegionSteps = 200
+
+# Initial trust-region radius
+initialTrustRegionRadius = 0.01
+
+# Number of multigrid iterations per trust-region step
+numIt = 200
+
+# Number of presmoothing steps
+nu1 = 3
+
+# Number of postsmoothing steps
+nu2 = 3
+
+# Number of coarse grid corrections
+mu = 1
+
+# Number of base solver iterations
+baseIt = 100
+
+# Tolerance of the multigrid solver
+mgTolerance = 1e-7
+
+# Tolerance of the base grid solver
+baseTolerance = 1e-8
+
+############################
+#   Material parameters
+############################
+
+energy = dacorogna
+
+[materialParameters]
+
+gamma = 2.31
+
+[]
+
+#############################################
+#  Boundary values
+#############################################
+
+problem = neff-quasiconvexity
+
+###  Python predicate specifying all Dirichlet grid vertices
+# x is the vertex coordinate
+dirichletVerticesPredicate = "True"
+dirichletValues = affine
+
+# Initial deformation is (x[0] * sqrt(x0), x[1] / sqrt(x0))
+x0 = 1.75
+
+# Initial iterate given as a Python function
+#initialIteratePython = one-circle
+
+# Setting initialIterateFile overrides the x0 parameter
+#initialIterateFile = quasiconvexity-test-result-1.075-x0_1.1_8levels.data
diff --git a/problems/quasiconvexity-circle-expacosh.parset b/problems/quasiconvexity-circle-expacosh.parset
index 3d68068..26f7a26 100644
--- a/problems/quasiconvexity-circle-expacosh.parset
+++ b/problems/quasiconvexity-circle-expacosh.parset
@@ -6,8 +6,13 @@ structuredGrid = false
 path = /home/sander/dune/dune-elasticity/grids/
 gridFile = circle2ndorder.msh
 
+#structuredGrid = true
+#lower = 0 0
+#upper = 1 1
+#elements = 2 2
+
 # Number of grid levels
-numLevels = 7
+numLevels = 6
 
 #############################################
 #  Solver parameters
@@ -72,7 +77,9 @@ dirichletVerticesPredicate = "True"
 dirichletValues = affine
 
 # Initial deformation is (x[0] * sqrt(x0), x[1] / sqrt(x0))
-x0 = 4.38
+#x0 = 4.38
+x0 = 12.0186
+
 # Setting initialIterateFile overrides the x0 parameter
-initialIterateFile = experiment-6.data
-oldX0 = 10
+#initialIterateFile = experiment-6.data
+#oldX0 = 10
diff --git a/problems/quasiconvexity-circle-magic.parset b/problems/quasiconvexity-circle-magic.parset
new file mode 100644
index 0000000..6e45ab9
--- /dev/null
+++ b/problems/quasiconvexity-circle-magic.parset
@@ -0,0 +1,84 @@
+#############################################
+#  Grid parameters
+#############################################
+
+structuredGrid = false
+path = /home/sander/dune/dune-elasticity/grids/
+gridFile = circle2ndorder.msh
+
+#structuredGrid = true
+#lower = 0 0
+#upper = 1 1
+#elements = 2 2
+
+# Number of grid levels
+numLevels = 6
+
+#############################################
+#  Solver parameters
+#############################################
+
+# Number of homotopy steps for the Dirichlet boundary conditions
+numHomotopySteps = 1
+
+# Tolerance of the trust region solver
+tolerance = 1e-6
+
+# Max number of steps of the trust region solver
+maxTrustRegionSteps = 200
+
+# Initial trust-region radius
+initialTrustRegionRadius = 0.01
+
+# Number of multigrid iterations per trust-region step
+numIt = 200
+
+# Number of presmoothing steps
+nu1 = 3
+
+# Number of postsmoothing steps
+nu2 = 3
+
+# Number of coarse grid corrections
+mu = 1
+
+# Number of base solver iterations
+baseIt = 100
+
+# Tolerance of the multigrid solver
+mgTolerance = 1e-7
+
+# Tolerance of the base grid solver
+baseTolerance = 1e-8
+
+############################
+#   Material parameters
+############################
+
+energy = magic
+
+[materialParameters]
+
+c = 2
+
+[]
+
+#############################################
+#  Boundary values
+#############################################
+
+problem = neff-quasiconvexity
+
+###  Python predicate specifying all Dirichlet grid vertices
+# x is the vertex coordinate
+dirichletVerticesPredicate = "True"
+dirichletValues = affine
+
+# Initial deformation is (x[0] * sqrt(x0), x[1] / sqrt(x0))
+x0 = 2
+
+# Initial iterate given as a Python function
+#initialIteratePython = one-circle
+
+# Setting initialIterateFile overrides the x0 parameter
+#initialIterateFile = quasiconvexity-test-result-1.075-x0_1.1_8levels.data
diff --git a/problems/quasiconvexity-circle-w2.parset b/problems/quasiconvexity-circle-w2.parset
new file mode 100644
index 0000000..232b3f4
--- /dev/null
+++ b/problems/quasiconvexity-circle-w2.parset
@@ -0,0 +1,85 @@
+#############################################
+#  Grid parameters
+#############################################
+
+structuredGrid = false
+path = /home/sander/dune/dune-elasticity/grids/
+gridFile = circle2ndorder.msh
+
+#structuredGrid = true
+#lower = 0 0
+#upper = 1 1
+#elements = 2 2
+
+# Number of grid levels
+numLevels = 6
+
+#############################################
+#  Solver parameters
+#############################################
+
+# Number of homotopy steps for the Dirichlet boundary conditions
+numHomotopySteps = 1
+
+# Tolerance of the trust region solver
+tolerance = 1e-6
+
+# Max number of steps of the trust region solver
+maxTrustRegionSteps = 200
+
+# Initial trust-region radius
+initialTrustRegionRadius = 0.01
+
+# Number of multigrid iterations per trust-region step
+numIt = 200
+
+# Number of presmoothing steps
+nu1 = 3
+
+# Number of postsmoothing steps
+nu2 = 3
+
+# Number of coarse grid corrections
+mu = 1
+
+# Number of base solver iterations
+baseIt = 100
+
+# Tolerance of the multigrid solver
+mgTolerance = 1e-7
+
+# Tolerance of the base grid solver
+baseTolerance = 1e-8
+
+############################
+#   Material parameters
+############################
+
+energy = w2
+
+[materialParameters]
+
+#c = 1.075
+c = 0.5
+
+[]
+
+#############################################
+#  Boundary values
+#############################################
+
+problem = neff-quasiconvexity
+
+###  Python predicate specifying all Dirichlet grid vertices
+# x is the vertex coordinate
+dirichletVerticesPredicate = "True"
+dirichletValues = affine
+
+# Initial deformation is (x[0] * sqrt(x0), x[1] / sqrt(x0))
+x0 = 10
+
+# Initial iterate given as a Python function
+#initialIteratePython = one-circle
+
+# Setting initialIterateFile overrides the x0 parameter
+#initialIterateFile = quasiconvexity-test-result-1.075-x0_1.1_8levels.data
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fffab1a..9b5395f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,6 +10,8 @@ if(ADOLC_FOUND AND IPOPT_FOUND AND PYTHONLIBS_FOUND AND dune-uggrid_FOUND)
     add_dune_pythonlibs_flags(${_program})
     add_dune_ug_flags(${_program})
     add_dune_mpi_flags(${_program})
+    add_dune_superlu_flags(${_program})
+    target_compile_options(${_program} PRIVATE "-fpermissive" -O3 -funroll-loops -DNDEBUG)
 #    target_compile_options(${_program} PRIVATE "-fpermissive")
   endforeach()
 
diff --git a/src/finite-strain-elasticity.cc b/src/finite-strain-elasticity.cc
index 519a98d..696d2f7 100644
--- a/src/finite-strain-elasticity.cc
+++ b/src/finite-strain-elasticity.cc
@@ -91,6 +91,8 @@ int main (int argc, char *argv[]) try
 
   // parse data file
   ParameterTree parameterSet;
+  if (argc < 2)
+    DUNE_THROW(Exception, "Usage: ./finite-strain-elasticity <parameter file>");
 
   ParameterTreeParser::readINITree(argv[1], parameterSet);
 
diff --git a/src/quasiconvexity-test.cc b/src/quasiconvexity-test.cc
index 91459e7..300a0ce 100644
--- a/src/quasiconvexity-test.cc
+++ b/src/quasiconvexity-test.cc
@@ -1,5 +1,7 @@
 #include <config.h>
 
+#undef HAVE_DUNE_PARMG
+
 // Includes for the ADOL-C automatic differentiation library
 // Need to come before (almost) all others.
 #include <adolc/adouble.h>
@@ -26,6 +28,7 @@
 #include <dune/fufem/boundarypatch.hh>
 #include <dune/fufem/functiontools/boundarydofs.hh>
 #include <dune/fufem/functionspacebases/dunefunctionsbasis.hh>
+#include <dune/fufem/functionspacebases/periodicbasis.hh>
 #include <dune/fufem/dunepython.hh>
 
 #include <dune/solvers/solvers/iterativesolver.hh>
@@ -35,12 +38,15 @@
 #include <dune/elasticity/assemblers/localadolcstiffness.hh>
 #include <dune/elasticity/assemblers/feassembler.hh>
 #include <dune/elasticity/materials/neffenergy.hh>
+#include <dune/elasticity/materials/burkholderenergy.hh>
 #include <dune/elasticity/materials/coshenergy.hh>
+#include <dune/elasticity/materials/dacorognaenergy.hh>
 #include <dune/elasticity/materials/expacoshenergy.hh>
 #include <dune/elasticity/materials/nefflogenergy.hh>
 #include <dune/elasticity/materials/nefflogenergy2.hh>
 #include <dune/elasticity/materials/neffmagicenergy.hh>
 #include <dune/elasticity/materials/neffreducedenergy.hh>
+#include <dune/elasticity/materials/neffw2energy.hh>
 
 // grid dimension
 const int dim = 2;
@@ -70,6 +76,8 @@ int main (int argc, char *argv[]) try
 
   // parse data file
   ParameterTree parameterSet;
+  if (argc < 2)
+    DUNE_THROW(Exception, "Usage: ./quasiconvexity-text <parameter file>");
 
   ParameterTreeParser::readINITree(argv[1], parameterSet);
 
@@ -129,9 +137,46 @@ int main (int argc, char *argv[]) try
 #endif
 
   // FE basis spanning the FE space that we are working in
-  typedef Dune::Functions::LagrangeBasis<GridView, order> FEBasis;
+//   typedef Dune::Functions::LagrangeBasis<GridView, order> FEBasis;
+//   FEBasis feBasis(gridView);
+  using FEBasis = Fufem::PeriodicBasis<GridView>;
   FEBasis feBasis(gridView);
 
+  bool periodicY = false;
+  if (periodicY)
+  {
+    if (order!=1)
+      DUNE_THROW(NotImplemented, "Periodic boundary conditions are only implemented for order 1!");
+
+    std::map<double,std::size_t> bottomMap, topMap;
+
+    for (const auto& vertex : vertices(gridView))
+    {
+      auto p = vertex.geometry().corner(0);
+      auto idx = gridView.indexSet().index(vertex);
+
+      if (p[1] < 1e-9)
+        bottomMap.insert(std::make_pair(p[0], idx));
+      if (p[1] > 1 - 1e-9)
+        topMap.insert(std::make_pair(p[0], idx));
+
+    }
+
+    if (topMap.size() != bottomMap.size())
+      DUNE_THROW(Exception, "Bottom and top vertex lists do not have the same size");
+
+    auto bottomIt = bottomMap.begin();
+    auto topIt = topMap.begin();
+
+    while (bottomIt != bottomMap.end())
+    {
+      feBasis.preBasis().unifyIndexPair({bottomIt->second}, {topIt->second});
+      ++bottomIt;
+      ++topIt;
+    }
+    feBasis.preBasis().initializeIndices();
+  }
+
   // /////////////////////////////////////////
   //   Read Dirichlet values
   // /////////////////////////////////////////
@@ -186,6 +231,17 @@ int main (int argc, char *argv[]) try
 
   Dune::Functions::interpolate(powerBasis, x, initialDeformation);
 
+  if (parameterSet.hasKey("initialIteratePython"))
+  {
+    // The python class that implements the Dirichlet values
+    Python::Module initialIterateModule = Python::import(parameterSet.get<std::string>("initialIteratePython"));
+
+    auto f = Python::Callable(initialIterateModule.get("initialIterate"));
+    PythonFunction<FieldVector<double,dim>, FieldVector<double,dim> > initialIteratePython(f);
+
+    Dune::Functions::interpolate(powerBasis, x, initialIteratePython);
+  }
+
   if (parameterSet.hasKey("initialIterateFile"))
   {
     std::ifstream inFile(parameterSet.get<std::string>("initialIterateFile"), std::ios_base::binary);
@@ -277,6 +333,21 @@ int main (int argc, char *argv[]) try
                                                                    FEBasis::LocalView::Tree::FiniteElement,
                                                                    adouble> >(materialParameters);
 
+    if (parameterSet.get<std::string>("energy") == "burkholder")
+      elasticEnergy = std::make_shared<Elasticity::BurkholderEnergy<GridView,
+                                                                    FEBasis::LocalView::Tree::FiniteElement,
+                                                                    adouble> >(materialParameters);
+
+    if (parameterSet.get<std::string>("energy") == "w2")
+      elasticEnergy = std::make_shared<Elasticity::NeffW2Energy<GridView,
+                                                                FEBasis::LocalView::Tree::FiniteElement,
+                                                                adouble> >(materialParameters);
+
+    if (parameterSet.get<std::string>("energy") == "dacorogna")
+      elasticEnergy = std::make_shared<Elasticity::DacorognaEnergy<GridView,
+                                                                FEBasis::LocalView::Tree::FiniteElement,
+                                                                adouble> >(materialParameters);
+
     if(!elasticEnergy)
       DUNE_THROW(Exception, "Error: Selected energy not available!");
 
@@ -328,9 +399,9 @@ int main (int argc, char *argv[]) try
 #else
 //     lambda = std::string("lambda x: (") + parameterSet.get<std::string>("initialDeformation") + std::string(")");
 //     PythonFunction<FieldVector<double,dim>, FieldVector<double,dim> > dirichletValues(Python::evaluate(lambda));
-    Python::Module module = Python::import(parameterSet.get<std::string>("dirichletValues"));
-    auto dirichletValues = Python::makeFunction<FieldVector<double,dim>(const FieldVector<double,dim>&)>(module.get("f"));
-    Dune::Functions::interpolate(powerBasis, x, dirichletValues, dirichletDofs);
+//     Python::Module module = Python::import(parameterSet.get<std::string>("dirichletValues"));
+//     auto dirichletValues = Python::makeFunction<FieldVector<double,dim>(const FieldVector<double,dim>&)>(module.get("f"));
+//     Dune::Functions::interpolate(powerBasis, x, dirichletValues, dirichletDofs);
 #endif
 
     //::Functions::interpolate(fufemFEBasis, x, dirichletValues, dirichletDofs);
@@ -339,6 +410,7 @@ int main (int argc, char *argv[]) try
     //   Solve!
     // /////////////////////////////////////////////////////
 
+    solver.iterateNamePrefix_ = "stage1-";
     solver.setInitialIterate(x);
     solver.solve();
 
@@ -348,6 +420,7 @@ int main (int argc, char *argv[]) try
     //   Output result
     /////////////////////////////////
 
+#if 0
     std::cout << "Total energy: " << assembler.computeEnergy(x) << std::endl;
 
     elasticEnergy = std::make_shared<NeffLogEnergy2<GridView,
@@ -363,7 +436,7 @@ int main (int argc, char *argv[]) try
     localADOLCStiffness.localEnergy_ = elasticEnergy.get();
 
     std::cout << "Energy part 2: " << assembler.computeEnergy(x) << std::endl;
-
+#endif
     // Compute the displacement
     auto displacement = x;
     displacement -= identity;
@@ -463,12 +536,14 @@ int main (int argc, char *argv[]) try
   MatrixVector::Generic::writeBinary(outFile, x);
   outFile.close();
 
+  exit(0);
+
   //////////////////////////////////////////////////////////////////////////////////
   //  Use the solution as initial iterate for the 'real' energy
   //////////////////////////////////////////////////////////////////////////////////
 
   ParameterTree neffMaterialParameters;
-  neffMaterialParameters["scaling"] = "1.15";
+  neffMaterialParameters["c"] = "1";
 
   // Careful: The following code computes the initial iterate given by the Python file,
   // and *assumes* that that file describes the homogeneous deformation!
@@ -478,7 +553,7 @@ int main (int argc, char *argv[]) try
   std::shared_ptr<LocalFEStiffness<GridView,
                                    FEBasis::LocalView::Tree::FiniteElement,
                                    std::vector<Dune::FieldVector<adouble, dim> > > >
-    energy = std::make_shared<NeffEnergy<GridView,
+    energy = std::make_shared<Elasticity::NeffW2Energy<GridView,
                               FEBasis::LocalView::Tree::FiniteElement,
                               adouble> >(neffMaterialParameters);
 
@@ -510,6 +585,7 @@ int main (int argc, char *argv[]) try
                baseTolerance
               );
 
+  solver.iterateNamePrefix_ = "stage2-";
   solver.setInitialIterate(x);
   solver.solve();
 
-- 
GitLab