From 7590982d53b46d1c66d6fe00b9c164b173ba3bd9 Mon Sep 17 00:00:00 2001
From: Oliver Sander <oliver.sander@tu-dresden.de>
Date: Wed, 31 Jan 2024 10:29:54 +0100
Subject: [PATCH] Make interface of class LocalDensity a bit more general

Currently, Cosserat materials are hard-wired in the interface.
This patch changes the interface a little bit towards being
more general.
---
 dune/gfe/assemblers/localintegralenergy.hh | 12 ++++++------
 dune/gfe/densities/bulkcosseratdensity.hh  | 12 +++++++-----
 dune/gfe/densities/localdensity.hh         | 19 +++++++++----------
 test/cosseratcontinuumtest.cc              |  2 +-
 4 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/dune/gfe/assemblers/localintegralenergy.hh b/dune/gfe/assemblers/localintegralenergy.hh
index 23c8dd8d..f2de0036 100644
--- a/dune/gfe/assemblers/localintegralenergy.hh
+++ b/dune/gfe/assemblers/localintegralenergy.hh
@@ -38,6 +38,10 @@ namespace Dune::GFE {
 
     constexpr static int gridDim = GridView::dimension;
 
+    static_assert(sizeof...(TargetSpaces) == 2, "LocalGeodesicIntegralEnergy needs two TargetSpaces!");
+    using TargetSpaceDeformation = typename std::tuple_element<0, std::tuple<TargetSpaces...> >::type;
+    using TargetSpaceRotation = typename std::tuple_element<1, std::tuple<TargetSpaces...> >::type;
+
   public:
 
     /** \brief Constructor with a Dune::Elasticity::LocalDensity
@@ -48,7 +52,7 @@ namespace Dune::GFE {
 
     /** \brief Constructor with a Dune::GFE::LocalDensity
      */
-    LocalIntegralEnergy(const std::shared_ptr<GFE::LocalDensity<gridDim,RT,DT> >& ld)
+    LocalIntegralEnergy(const std::shared_ptr<GFE::LocalDensity<FieldVector<DT,gridDim>,ProductManifold<TargetSpaces...> > >& ld)
       : localDensityGFE_(ld)
     {}
 
@@ -60,10 +64,6 @@ namespace Dune::GFE {
     {
       const auto& element = localView.element();
 
-      static_assert(sizeof...(TargetSpaces) > 1, "LocalGeodesicIntegralEnergy needs at least two TargetSpace!");
-
-      using TargetSpaceDeformation = typename std::tuple_element<0, std::tuple<TargetSpaces...> >::type;
-      using TargetSpaceRotation = typename std::tuple_element<1, std::tuple<TargetSpaces...> >::type;
 
       const std::vector<TargetSpaceDeformation>& localDeformationConfiguration = std::get<0>(std::forward_as_tuple(localSolutions ...));
       const std::vector<TargetSpaceRotation>& localOrientationConfiguration = std::get<1>(std::forward_as_tuple(localSolutions ...));
@@ -142,7 +142,7 @@ namespace Dune::GFE {
 
   protected:
     const std::shared_ptr<Elasticity::LocalDensity<gridDim,RT,DT> > localDensityElasticity_ = nullptr;
-    const std::shared_ptr<GFE::LocalDensity<gridDim,RT,DT> > localDensityGFE_ = nullptr;
+    const std::shared_ptr<GFE::LocalDensity<FieldVector<DT,gridDim>,ProductManifold<TargetSpaces...> > > localDensityGFE_ = nullptr;
   };
 
 }  // namespace Dune::GFE
diff --git a/dune/gfe/densities/bulkcosseratdensity.hh b/dune/gfe/densities/bulkcosseratdensity.hh
index 9f4cddbd..5a1ce6f8 100644
--- a/dune/gfe/densities/bulkcosseratdensity.hh
+++ b/dune/gfe/densities/bulkcosseratdensity.hh
@@ -9,16 +9,18 @@
 #include <dune/gfe/cosseratstrain.hh>
 #include <dune/gfe/linearalgebra.hh>
 #include <dune/gfe/densities/localdensity.hh>
+#include <dune/gfe/spaces/productmanifold.hh>
 
 namespace Dune::GFE {
 
-  template<class field_type = double, class ctype = double>
+  template<class Position, class field_type>
   class BulkCosseratDensity final
-    : public GFE::LocalDensity<3,field_type,ctype>
+    : public GFE::LocalDensity<Position, GFE::ProductManifold<RealTuple<field_type,3>,Rotation<field_type,3> > >
   {
   private:
-    // gridDim = 3 - this can be hardwired here, because BulkCosseratDensity only works for 3d->3d problems
-    static const int gridDim = 3;
+    // BulkCosseratDensity only works for 3d->3d problems
+    static_assert(Position::size()==3);
+    static const int gridDim = Position::size();
     static const int embeddedDim = Rotation<field_type,gridDim>::embeddedDim;
     using OrientationDerivativeType = FieldMatrix<field_type, embeddedDim, gridDim>;
 
@@ -116,7 +118,7 @@ namespace Dune::GFE {
      * \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,
+    field_type operator() (const Position& x,
                            const RealTuple<field_type,gridDim>& deformationValue,
                            const FieldMatrix<field_type,gridDim,gridDim>& deformationDerivative,
                            const Rotation<field_type,gridDim>& orientationValue,
diff --git a/dune/gfe/densities/localdensity.hh b/dune/gfe/densities/localdensity.hh
index 8f29d58d..80df27fc 100644
--- a/dune/gfe/densities/localdensity.hh
+++ b/dune/gfe/densities/localdensity.hh
@@ -9,14 +9,13 @@ 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
+   * \tparam Position The evaluation point in the integration domain
+   * \tparam TargetSpace Type for the function value
    */
-  template<int dim, class field_type = double, class ctype = double>
+  template<class Position, class TargetSpace>
   class LocalDensity
   {
-  private:
-    static const int embeddedDim = Rotation<field_type,dim>::embeddedDim;
+    using field_type = typename TargetSpace::field_type;
   public:
 
     /** \brief Evaluation with the current position, the deformation function, the deformation gradient, the rotation and the rotation gradient
@@ -27,11 +26,11 @@ namespace Dune::GFE {
      * \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;
+    virtual field_type operator() (const Position& x,
+                                   const RealTuple<field_type,3>& deformation,
+                                   const FieldMatrix<field_type,3,3>& gradient,
+                                   const Rotation<field_type,3>& rotation,
+                                   const FieldMatrix<field_type, 4, 3>& rotationGradient) const = 0;
 
   };
 
diff --git a/test/cosseratcontinuumtest.cc b/test/cosseratcontinuumtest.cc
index 54f8dd91..2680242d 100644
--- a/test/cosseratcontinuumtest.cc
+++ b/test/cosseratcontinuumtest.cc
@@ -202,7 +202,7 @@ int main (int argc, char *argv[])
 
   GFE::SumEnergy<CompositeBasis, RealTuple<adouble,dim>,Rotation<adouble,dim> > sumEnergy;
   auto neumannEnergy = std::make_shared<GFE::NeumannEnergy<CompositeBasis, RealTuple<adouble,dim>, Rotation<adouble,dim> > >(neumannBoundary,neumannFunction);
-  auto bulkCosseratDensity = std::make_shared<GFE::BulkCosseratDensity<adouble,double> >(parameters);
+  auto bulkCosseratDensity = std::make_shared<GFE::BulkCosseratDensity<FieldVector<double,dim>,adouble> >(parameters);
   auto bulkCosseratEnergy = std::make_shared<GFE::LocalIntegralEnergy<CompositeBasis, RealTuple<adouble,dim>, Rotation<adouble,dim> > >(bulkCosseratDensity);
   sumEnergy.addLocalEnergy(bulkCosseratEnergy);
   sumEnergy.addLocalEnergy(neumannEnergy);
-- 
GitLab