From df922afd6194367612bdeb5719960c6b09135393 Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Thu, 22 May 2014 19:33:20 +0000
Subject: [PATCH] Use the new CosseratStrain object, but without any
 optimizations yet

The CosseratStrain object is a 3x3 matrix, where the last column
is (0,0,1)^T.  This special structure allows to use specially tuned
matrix methods (e.g., the determinant), which I intent to do in the
future.

[[Imported from SVN: r9752]]
---
 dune/gfe/cosseratenergystiffness.hh | 41 ++++------------
 dune/gfe/cosseratstrain.hh          | 76 +++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 31 deletions(-)
 create mode 100644 dune/gfe/cosseratstrain.hh

diff --git a/dune/gfe/cosseratenergystiffness.hh b/dune/gfe/cosseratenergystiffness.hh
index 6998469b..a51ccd85 100644
--- a/dune/gfe/cosseratenergystiffness.hh
+++ b/dune/gfe/cosseratenergystiffness.hh
@@ -13,6 +13,7 @@
 #include <dune/gfe/rigidbodymotion.hh>
 #include <dune/gfe/tensor3.hh>
 #include <dune/gfe/orthogonalmatrix.hh>
+#include <dune/gfe/cosseratstrain.hh>
 
 #define DONT_USE_CURL
 
@@ -149,7 +150,7 @@ public:
     /** \brief The energy \f$ W_{mp}(\overline{U}) \f$, as written in
      * the first equation of (4.4) in Neff's paper
      */
-    RT quadraticMembraneEnergy(const Dune::FieldMatrix<field_type,3,3>& U) const
+    RT quadraticMembraneEnergy(const Dune::GFE::CosseratStrain<field_type,3,gridDim>& U) const
     {
         Dune::FieldMatrix<field_type,3,3> UMinus1 = U;
         for (int i=0; i<dim; i++)
@@ -163,7 +164,7 @@ public:
     /** \brief The energy \f$ W_{mp}(\overline{U}) \f$, as written in
      * the second equation of (4.4) in Neff's paper
      */
-    RT longQuadraticMembraneEnergy(const Dune::FieldMatrix<field_type,3,3>& U) const
+    RT longQuadraticMembraneEnergy(const Dune::GFE::CosseratStrain<field_type,3,gridDim>& U) const
     {
         RT result = 0;
 
@@ -171,7 +172,7 @@ public:
         Dune::FieldMatrix<field_type,dim-1,dim-1> sym2x2;
         for (int i=0; i<dim-1; i++)
             for (int j=0; j<dim-1; j++)
-                sym2x2[i][j] = 0.5 * (U[i][j] + U[j][i]) - (i==j);
+                sym2x2[i][j] = 0.5 * (U.matrix()[i][j] + U.matrix()[j][i]) - (i==j);
 
         result += mu_ * sym2x2.frobenius_norm2();
 
@@ -179,13 +180,13 @@ public:
         Dune::FieldMatrix<field_type,dim-1,dim-1> skew2x2;
         for (int i=0; i<dim-1; i++)
             for (int j=0; j<dim-1; j++)
-                skew2x2[i][j] = 0.5 * (U[i][j] - U[j][i]);
+                skew2x2[i][j] = 0.5 * (U.matrix()[i][j] - U.matrix()[j][i]);
 
         result += mu_c_ * skew2x2.frobenius_norm2();
 
 
         // classical transverse shear energy
-        result += kappa_ * (mu_ + mu_c_)/2 * (U[2][0]*U[2][0] + U[2][1]*U[2][1]);
+        result += kappa_ * (mu_ + mu_c_)/2 * (U.matrix()[2][0]*U.matrix()[2][0] + U.matrix()[2][1]*U.matrix()[2][1]);
 
         // elongational stretch energy
         result += mu_*lambda_ / (2*mu_ + lambda_) * traceSquared(sym2x2);
@@ -195,9 +196,9 @@ public:
 
     /** \brief Energy for large-deformation problems (private communication by Patrizio Neff)
      */
-    RT nonquadraticMembraneEnergy(const Dune::FieldMatrix<field_type,3,3>& U) const
+    RT nonquadraticMembraneEnergy(const Dune::GFE::CosseratStrain<field_type,3,gridDim>& U) const
     {
-        Dune::FieldMatrix<field_type,3,3> UMinus1 = U;
+        Dune::FieldMatrix<field_type,3,3> UMinus1 = U.matrix();
         for (int i=0; i<dim; i++)
             UMinus1[i][i] -= 1;
 
@@ -312,29 +313,7 @@ energy(const Entity& element,
         Dune::FieldMatrix<field_type,dim,dim> R;
         value.q.matrix(R);
 
-        /* Compute F, the deformation gradient.
-           In the continuum case this is
-           \f$ \hat{F} = \nabla m  \f$
-           In the case of a shell it is
-          \f$ \hat{F} = (\nabla m | \overline{R}_3) \f$
-        */
-        Dune::FieldMatrix<field_type,dim,dim> F;
-        for (int i=0; i<dim; i++)
-            for (int j=0; j<gridDim; j++)
-                F[i][j] = derivative[i][j];
-
-        for (int i=0; i<dim; i++)
-            for (int j=gridDim; j<dim; j++)
-                F[i][j] = R[i][j];
-
-        // U = R^T F
-        Dune::FieldMatrix<field_type,dim,dim> U;
-        for (int i=0; i<dim; i++)
-            for (int j=0; j<dim; j++) {
-                U[i][j] = 0;
-                for (int k=0; k<dim; k++)
-                    U[i][j] += R[k][i] * F[k][j];
-            }
+        Dune::GFE::CosseratStrain<field_type,dim,gridDim> U(derivative,R);
 
         //////////////////////////////////////////////////////////
         //  Compute the derivative of the rotation
@@ -347,7 +326,7 @@ energy(const Entity& element,
         // Add the local energy density
         if (gridDim==2) {
 #ifdef QUADRATIC_MEMBRANE_ENERGY
-            //energy += weight * thickness_ * quadraticMembraneEnergy(U);
+            //energy += weight * thickness_ * quadraticMembraneEnergy(U.matrix());
             energy += weight * thickness_ * longQuadraticMembraneEnergy(U);
 #else
             energy += weight * thickness_ * nonquadraticMembraneEnergy(U);
diff --git a/dune/gfe/cosseratstrain.hh b/dune/gfe/cosseratstrain.hh
new file mode 100644
index 00000000..cc72745d
--- /dev/null
+++ b/dune/gfe/cosseratstrain.hh
@@ -0,0 +1,76 @@
+#ifndef DUNE_GFE_COSSERATSTRAIN_HH
+#define DUNE_GFE_COSSERATSTRAIN_HH
+
+#include <dune/common/fmatrix.hh>
+
+namespace Dune {
+
+  namespace GFE {
+
+    /** \brief Strain tensor of a Cosserat material
+     *
+     * Mathematically, this object is a dimworld x dimworld matrix.
+     * However, the last dimworld-dim columns consists of the corresponding
+     * columns of the identity matrix.  Knowing this allows more efficient
+     * implementations of several frequently occurring operations.
+     *
+     * \tparam T Type used for real numbers
+     * \tparam dimworld Dimension of the world space
+     * \tparam dim Dimension of the domain
+     */
+    template <class T, int dimworld, int dim>
+    class CosseratStrain
+    {
+    public:
+      /** \brief Compute strain from the deformation gradient and the microrotation
+       *
+       * \param R The microrotation
+       */
+      CosseratStrain(const FieldMatrix<T,dimworld+4,dim>& deformationGradient,
+                     const FieldMatrix<T,dimworld,dimworld>& R)
+      {
+        /* Compute F, the deformation gradient.
+           In the continuum case (domain dimension == world dimension) this is
+           \f$ \hat{F} = \nabla m  \f$
+           In the case of a shell it is
+          \f$ \hat{F} = (\nabla m | \overline{R}_3) \f$
+        */
+        FieldMatrix<T,dimworld,dimworld> F;
+        for (int i=0; i<dimworld; i++)
+            for (int j=0; j<dim; j++)
+                F[i][j] = deformationGradient[i][j];
+
+        for (int i=0; i<dimworld; i++)
+            for (int j=dim; j<dimworld; j++)
+                F[i][j] = R[i][j];
+
+        // U = R^T F
+        for (int i=0; i<dimworld; i++)
+            for (int j=0; j<dimworld; j++) {
+                data_[i][j] = 0;
+                for (int k=0; k<dimworld; k++)
+                    data_[i][j] += R[k][i] * F[k][j];
+            }
+
+      }
+
+      T determinant() const
+      {
+        return data_.determinant();
+      }
+
+      /** \brief Temporary: get the raw matrix data */
+      const FieldMatrix<T,dimworld,dimworld>& matrix() const
+      {
+        return data_;
+      }
+
+    private:
+      FieldMatrix<T,dimworld,dimworld> data_;
+    };
+
+  }   // namespace GFE
+
+}  // namespace Dune
+
+#endif   // DUNE_GFE_COSSERATSTRAIN_HH
\ No newline at end of file
-- 
GitLab