diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6fcba5884adfb23cf36fa7bb1828b9ffc1749741..7571ab5ea1df78681bf8c6d17f2be3cb48d2e705 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
 # Master
 
+- All files that implement densities have been put into the
+  `densities` subdirectory.
+
 - All files that implement assemblers have been moved to the
   `assemblers` subdirectory.
   
diff --git a/dune/gfe/CMakeLists.txt b/dune/gfe/CMakeLists.txt
index 45eb2012a4ef1af90ac7a192f2cb7bbdb5a92b33..e33e3ecd021aa5a259ab3fea28dc9fa8a1f213e2 100644
--- a/dune/gfe/CMakeLists.txt
+++ b/dune/gfe/CMakeLists.txt
@@ -2,4 +2,5 @@
 install(FILES gfe.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/gfe)
 
 add_subdirectory("spaces")
-add_subdirectory("assemblers")
\ No newline at end of file
+add_subdirectory("assemblers")
+add_subdirectory("densities")
\ No newline at end of file
diff --git a/dune/gfe/densities/CMakeLists.txt b/dune/gfe/densities/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..00314da6b927245830c71f5a819da9c1dd53d762
--- /dev/null
+++ b/dune/gfe/densities/CMakeLists.txt
@@ -0,0 +1,5 @@
+#install headers
+install(FILES
+        bulkcosseratdensity.hh
+        localdensity.hh
+        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/gfe/densities)
diff --git a/dune/gfe/densities/bulkcosseratdensity.hh b/dune/gfe/densities/bulkcosseratdensity.hh
new file mode 100644
index 0000000000000000000000000000000000000000..17edd65f0e9f802a1b35fedc28ed8b789409c0c5
--- /dev/null
+++ b/dune/gfe/densities/bulkcosseratdensity.hh
@@ -0,0 +1,178 @@
+#ifndef DUNE_GFE_DENSITIES_BULKCOSSERATDENSITY_HH
+#define DUNE_GFE_DENSITIES_BULKCOSSERATDENSITY_HH
+
+#define DONT_USE_CURL
+#define CURVATURE_WITH_WRYNESS
+
+#include <dune/common/fmatrix.hh>
+
+#include <dune/gfe/densities/localdensity.hh>
+
+namespace Dune::GFE {
+
+template<class field_type = double, class ctype = double>
+class BulkCosseratDensity final
+    : public GFE::LocalDensity<3,field_type,ctype>
+{
+private:
+  // gridDim = 3 - this can be hardwired here, because BulkCosseratDensity only works for 3d->3d problems
+  static const int gridDim = 3;
+  static const int embeddedDim = Rotation<field_type,gridDim>::embeddedDim;
+  using OrientationDerivativeType = FieldMatrix<field_type, embeddedDim, gridDim>;
+
+  static FieldMatrix<field_type,gridDim,gridDim> curl(const Tensor3<field_type,gridDim,gridDim,gridDim>& DR)
+  {
+      FieldMatrix<field_type,gridDim,gridDim> result;
+
+      for (int i=0; i<gridDim; i++) {
+          result[i][0] = DR[i][2][1] - DR[i][1][2];
+          result[i][1] = DR[i][0][2] - DR[i][2][0];
+          result[i][2] = DR[i][1][0] - DR[i][0][1];
+      }
+
+      return result;
+  }
+
+public:
+
+  /** \brief Constructor with a set of material parameters
+  * \param parameters The material parameters
+  */
+  BulkCosseratDensity(const ParameterTree& parameters)
+  {
+    mu_ = parameters.template get<double>("mu");
+    lambda_ = parameters.template get<double>("lambda");
+
+    // Cosserat couple modulus
+    mu_c_ = parameters.template get<double>("mu_c");
+
+    // Length scale parameter
+    L_c_ = parameters.template get<double>("L_c");
+
+    // Curvature exponent
+    q_ = parameters.template get<double>("q");
+
+    // Curvature parameters
+    b1_ = parameters.template get<double>("b1");
+    b2_ = parameters.template get<double>("b2");
+    b3_ = parameters.template get<double>("b3");
+  }
+
+  /** \brief The energy \f$ W_{mp}(\overline{U}) \f$, as written in
+   * the first equation of (4.4) in Neff's paper from 2006: A geometrically exact planar Cosserat shell model with microstructure: Existence of minimizers for zero Cosserat couple modulus
+   * OR: the equation (2.27) of 2019: Refined dimensional reduction for isotropic elastic Cosserat shells with initial curvature
+   */
+  field_type quadraticEnergy(const GFE::CosseratStrain<field_type,3,gridDim>& U) const
+  {
+      FieldMatrix<field_type,3,3> UMinus1 = U.matrix();
+      for (int i=0; i<gridDim; i++)
+          UMinus1[i][i] -= 1;
+
+      return mu_ * GFE::sym(UMinus1).frobenius_norm2()
+              + mu_c_ * GFE::skew(UMinus1).frobenius_norm2()
+#ifdef QUADRATIC_2006
+              + (mu_*lambda_)/(2*mu_ + lambda_) * GFE::traceSquared(UMinus1); // GFE::traceSquared(UMinus1) = GFE::traceSquared(GFE::sym(UMinus1))
+#else
+              + lambda_/2 * GFE::traceSquared(UMinus1); // GFE::traceSquared(UMinus1) = GFE::traceSquared(GFE::sym(UMinus1))
+#endif
+  }
+
+  field_type curvatureWithWryness(const FieldMatrix<field_type,gridDim,gridDim>& R, const Tensor3<field_type,3,3,3>& DR) const
+  {
+      // construct Wryness tensor \Gamma as in "Refined dimensional reduction for isotropic elastic Cosserat shells with initial curvature"
+      FieldMatrix<field_type,3,3> dRx1(0); //Derivative of R with respect to x1
+      FieldMatrix<field_type,3,3> dRx2(0); //Derivative of R with respect to x2
+      FieldMatrix<field_type,3,3> dRx3(0); //Derivative of R with respect to x3
+      for (int i=0; i<3; i++)
+          for (int j=0; j<3; j++) {
+              dRx1[i][j] = DR[i][j][0];
+              dRx2[i][j] = DR[i][j][1];
+              dRx3[i][j] = DR[i][j][2];
+          }
+
+      FieldMatrix<field_type,3,3> wryness(0);
+
+      auto axialVectorx1 = SkewMatrix<field_type,3>(transpose(R)*dRx1).axial();
+      auto axialVectorx2 = SkewMatrix<field_type,3>(transpose(R)*dRx2).axial();
+      auto axialVectorx3 = SkewMatrix<field_type,3>(transpose(R)*dRx3).axial();
+      for (int i=0; i<3; i++) {
+          wryness[i][0] = axialVectorx1[i];
+          wryness[i][1] = axialVectorx2[i];
+          wryness[i][2] = axialVectorx3[i];
+      }
+
+      // The choice for the Frobenius norm here is b1=b2=1 and b3 = 1/3
+      return mu_ * L_c_ * L_c_ * (b1_ * GFE::dev(GFE::sym(wryness)).frobenius_norm2()
+              + b2_ * GFE::skew(wryness).frobenius_norm2() + b3_ * GFE::traceSquared(wryness));
+  }
+
+  /** \brief Evaluation with the current position, the deformation value and its derivative, the orientation value and its derivative
+  *
+  * \param x The current position
+  * \param deformationValue The deformation at the current position
+  * \param deformationDerivative The derivative of the deformation at the current position
+  * \param orientationValue The orientation at the current position
+  * \param orientationDerivative The derivative of the orientation at the current position
+  */
+  field_type operator() (const FieldVector<ctype,gridDim>& x,
+                         const RealTuple<field_type,gridDim>& deformationValue,
+                         const FieldMatrix<field_type,gridDim,gridDim>& deformationDerivative,
+                         const Rotation<field_type,gridDim>& orientationValue,
+                         const OrientationDerivativeType& orientationDerivative) const
+  {
+    field_type strainEnergyDensity = 0;
+    /////////////////////////////////////////////////////////
+    // compute U, the Cosserat strain
+    /////////////////////////////////////////////////////////
+
+    FieldMatrix<field_type,gridDim,gridDim> R;
+    orientationValue.matrix(R);
+
+    GFE::CosseratStrain<field_type,gridDim,gridDim> U(deformationDerivative,R);
+
+    /////////////////////////////////////////////////////////////////////
+    //  Transfer the derivative of the rotation into matrix coordinates
+    ////////////////////////////////////////////////////////////////////
+
+    Tensor3<field_type,3,3,gridDim> DR = orientationValue.quaternionTangentToMatrixTangent(orientationDerivative);
+    strainEnergyDensity = quadraticEnergy(U);
+
+    #ifdef CURVATURE_WITH_WRYNESS
+    strainEnergyDensity += curvatureWithWryness(R,DR);
+    #else
+    
+    #ifdef DONT_USE_CURL
+    auto argument = DR;
+    #else
+    auto argument = curl(DR);
+    #endif
+
+    auto norm = (b1_ * GFE::dev(GFE::sym(argument)).frobenius_norm2()
+              + b2_ * GFE::skew(argument).frobenius_norm2() + b3_ * GFE::traceSquared(argument));
+
+    strainEnergyDensity += mu_ * std::pow(L_c_ * L_c_ * norm,q_/2.0);
+    #endif
+
+    return strainEnergyDensity;
+  }
+
+  /** \brief Lame constants */
+  double mu_, lambda_;
+
+  /** \brief Cosserat couple modulus, preferably 0 */
+  double mu_c_;
+
+  /** \brief Length scale parameter */
+  double L_c_;
+
+  /** \brief Curvature exponent */
+  double q_;
+
+  /** \brief Curvature parameters */
+  double b1_, b2_, b3_;
+
+};
+
+} // namespace GFE
+
+#endif   //#ifndef DUNE_GFE_BULKCOSSERATDENSITY_HH
diff --git a/dune/gfe/densities/localdensity.hh b/dune/gfe/densities/localdensity.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c1c11262dc6b14be87a50c057b12fd4070ac2f37
--- /dev/null
+++ b/dune/gfe/densities/localdensity.hh
@@ -0,0 +1,40 @@
+#ifndef DUNE_GFE_DENSITIES_LOCALDENSITY_HH
+#define DUNE_GFE_DENSITIES_LOCALDENSITY_HH
+
+#include <dune/common/fmatrix.hh>
+#include <dune/gfe/spaces/realtuple.hh>
+#include <dune/gfe/spaces/rotation.hh>
+
+namespace Dune::GFE {
+
+/** \brief A base class for energy densities to be evaluated in an integral energy
+ *
+ * \tparam field_type type of the gradient entries
+ * \tparam ctype type of the coordinates
+ */
+template<int dim, class field_type = double, class ctype = double>
+class LocalDensity
+{
+private:
+  static const int embeddedDim = Rotation<field_type,dim>::embeddedDim;
+public:
+
+  /** \brief Evaluation with the current position, the deformation function, the deformation gradient, the rotation and the rotation gradient
+   *
+   * \param x The current position
+   * \param deformationValue The deformation at the current position
+   * \param deformationDerivative The derivative of the deformation at the current position
+   * \param orientationValue The orientation at the current position
+   * \param orientationDerivative The derivative of the orientation at the current position
+   */
+  virtual field_type operator() (const FieldVector<ctype,dim>& x,
+                                 const RealTuple<field_type,dim>& deformation,
+                                 const FieldMatrix<field_type,dim,dim>& gradient,
+                                 const Rotation<field_type,dim>& rotation,
+                                 const FieldMatrix<field_type, embeddedDim, dim>& rotationGradient) const = 0;
+
+};
+
+}  // namespace Dune::GFE
+
+#endif  // DUNE_GFE_DENSITIES_LOCALDENSITY_HH