From fff0abd44ad9e9f703df33748b8c11d21cbd8897 Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Fri, 19 Aug 2011 13:15:32 +0000
Subject: [PATCH] New test cosseratenergytest

[[Imported from SVN: r7613]]
---
 test/Makefile.am           |   3 +
 test/cosseratenergytest.cc | 177 +++++++++++++++++++++++++++++++++++++
 2 files changed, 180 insertions(+)
 create mode 100644 test/cosseratenergytest.cc

diff --git a/test/Makefile.am b/test/Makefile.am
index f3d1c107..36a840cf 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -5,6 +5,7 @@ LDADD = $(UG_LDFLAGS) $(AMIRAMESH_LDFLAGS) $(UG_LIBS) $(AMIRAMESH_LIBS)
 AM_CPPFLAGS += $(UG_CPPFLAGS) $(AMIRAMESH_CPPFLAGS) -Wall
 
 check_PROGRAMS = averagedistanceassemblertest \
+                 cosseratenergytest \
                  fdcheck \
                  frameinvariancetest \
                  harmonicenergytest \
@@ -26,6 +27,8 @@ localgeodesicfestiffnesstest_SOURCES = localgeodesicfestiffnesstest.cc
 
 harmonicenergytest_SOURCES = harmonicenergytest.cc
 
+cosseratenergytest_SOURCES = cosseratenergytest.cc
+
 averagedistanceassemblertest_SOURCES = averagedistanceassemblertest.cc
 
 targetspacetest_SOURCES = targetspacetest.cc
diff --git a/test/cosseratenergytest.cc b/test/cosseratenergytest.cc
new file mode 100644
index 00000000..284bbe5d
--- /dev/null
+++ b/test/cosseratenergytest.cc
@@ -0,0 +1,177 @@
+#include "config.h"
+
+#include <dune/grid/uggrid.hh>
+
+#include <dune/gfe/rigidbodymotion.hh>
+
+#include <dune/gfe/cosseratenergystiffness.hh>
+
+#include "multiindex.hh"
+#include "valuefactory.hh"
+
+const int dim = 2;
+
+const double eps = 1e-4;
+
+typedef RigidBodyMotion<3> TargetSpace;
+
+using namespace Dune;
+
+#if 0
+template <class GridType>
+void testEnergy(const GridType* grid, const std::vector<TargetSpace>& coefficients) {
+
+    HarmonicEnergyLocalStiffness<typename GridType::LeafGridView,TargetSpace> assembler;
+    std::vector<TargetSpace> rotatedCoefficients(coefficients.size());
+
+    for (int i=0; i<10; i++) {
+
+        Rotation<3,double> rotation(FieldVector<double,3>(1), double(i));
+
+        FieldMatrix<double,3,3> matrix;
+        rotation.matrix(matrix);
+        for (size_t j=0; j<coefficients.size(); j++) {
+            FieldVector<double,3> tmp;
+            matrix.mv(coefficients[j].globalCoordinates(), tmp);
+            rotatedCoefficients[j] = tmp;
+        }
+
+        std::cout << "energy: " << assembler.energy(*grid->template leafbegin<0>(), 
+                                                    rotatedCoefficients) << std::endl;
+
+        std::vector<typename TargetSpace::EmbeddedTangentVector> rotatedGradient;
+        assembler.assembleEmbeddedGradient(*grid->template leafbegin<0>(),
+                                   rotatedCoefficients,
+                                   rotatedGradient);
+
+        for (size_t j=0; j<coefficients.size(); j++) {
+            FieldVector<double,3> tmp;
+            matrix.mtv(rotatedGradient[j], tmp);
+            std::cout << "gradient: " << tmp << std::endl;
+        }
+
+    }
+
+}
+#endif
+
+
+template <int domainDim>
+Tensor3<double,3,3,3> evaluateDerivativeFD(const LocalGeodesicFEFunction<domainDim,double,TargetSpace>& f,
+                          const Dune::FieldVector<double,domainDim>& local)
+{
+    Tensor3<double,3,3,3> result(0);
+
+    for (int i=0; i<domainDim; i++) {
+        
+        Dune::FieldVector<double, domainDim> forward  = local;
+        Dune::FieldVector<double, domainDim> backward = local;
+        
+        forward[i]  += eps;
+        backward[i] -= eps;
+
+        TargetSpace forwardValue = f.evaluate(forward);
+        TargetSpace backwardValue = f.evaluate(backward);
+        
+        FieldMatrix<double,3,3> forwardMatrix, backwardMatrix;
+        forwardValue.q.matrix(forwardMatrix);
+        backwardValue.q.matrix(backwardMatrix);
+        
+        FieldMatrix<double,3,3> fdDer = (forwardMatrix - backwardMatrix) / (2*eps);
+        
+        for (int j=0; j<3; j++)
+            for (int k=0; k<3; k++)
+                result[j][k][i] = fdDer[j][k];
+        
+    }
+
+    return result;
+
+}
+
+template <int domainDim>
+void testDerivativeOfRotationMatrix(const array<TargetSpace,dim+1>& corners)
+{
+    // Make local fe function to be tested
+    LocalGeodesicFEFunction<domainDim,double,TargetSpace> f(corners);
+
+    // A quadrature rule as a set of test points
+    int quadOrder = 3;
+    
+    const Dune::QuadratureRule<double, domainDim>& quad 
+        = Dune::QuadratureRules<double, domainDim>::rule(GeometryType(GeometryType::simplex,domainDim), quadOrder);
+    
+    for (size_t pt=0; pt<quad.size(); pt++) {
+        
+        const Dune::FieldVector<double,domainDim>& quadPos = quad[pt].position();
+
+        // evaluate actual derivative
+        Dune::FieldMatrix<double, TargetSpace::EmbeddedTangentVector::size, domainDim> derivative = f.evaluateDerivative(quadPos);
+
+        Tensor3<double,3,3,3> DR;
+        CosseratEnergyLocalStiffness<typename UGGrid<domainDim>::LeafGridView,3>::computeDR(f.evaluate(quadPos),derivative, DR);
+
+        //std::cout << "DR:\n" << DR << std::endl;
+
+        // evaluate fd approximation of derivative
+        Tensor3<double,3,3,3> DR_fd = evaluateDerivativeFD(f,quadPos);
+
+        double maxDiff = 0;
+        for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++)
+                for (int k=0; k<3; k++)
+                    maxDiff = std::max(maxDiff, std::abs(DR[i][j][k] - DR_fd[i][j][k]));
+        
+        if ( maxDiff > 100*eps ) {
+            std::cout << className(corners[0]) << ": Analytical gradient does not match fd approximation." << std::endl;
+            std::cout << "Analytical:\n " << DR << std::endl;
+            std::cout << "FD        :\n " << DR_fd << std::endl;
+            assert(false);
+        }
+
+    }
+}
+
+
+
+
+int main(int argc, char** argv)
+{
+    array<double,4> coords = {0,0,1,0};
+    UnitVector<4> uv(coords);
+    Rotation<3,double> ro(coords);
+
+    FieldVector<double,4> v(0);
+    v[1] = 1;
+    
+    UnitVector<4> uv_c = UnitVector<4>::exp(uv,v);
+    Rotation<3,double> ro_c = Rotation<3,double>::exp(ro,v);
+    
+    std::cout << "uv_c: " << uv_c << std::endl;
+    std::cout << "ro_c: " << ro_c << std::endl;
+    exit(0);
+    
+    const int domainDim = 2;
+    std::cout << " --- Testing Rotation<3>, domain dimension: " << domainDim << " ---" << std::endl;
+
+    std::vector<Rotation<3,double> > testPoints;
+    ValueFactory<Rotation<3,double> >::get(testPoints);
+    
+    int nTestPoints = testPoints.size();
+
+    // Set up elements of SO(3)
+    array<TargetSpace, domainDim+1> corners;
+
+    MultiIndex<domainDim+1> index(nTestPoints);
+    int numIndices = index.cycle();
+
+    for (int i=0; i<numIndices; i++, ++index) {
+        
+        for (int j=0; j<domainDim+1; j++)
+            corners[j].q = testPoints[index[j]];
+
+        testDerivativeOfRotationMatrix<2>(corners);
+                
+    }
+    
+}
-- 
GitLab