From cb2f87d3c7bf02822b711ec89e9944f8db62f5f5 Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Fri, 17 Apr 2009 14:04:25 +0000
Subject: [PATCH] beginning a global assembler for general geodesic fe problems

[[Imported from SVN: r4024]]
---
 src/geodesicfeassembler.hh | 133 +++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)
 create mode 100644 src/geodesicfeassembler.hh

diff --git a/src/geodesicfeassembler.hh b/src/geodesicfeassembler.hh
new file mode 100644
index 00000000..542ca535
--- /dev/null
+++ b/src/geodesicfeassembler.hh
@@ -0,0 +1,133 @@
+#ifndef GLOBAL_GEODESIC_FE_ASSEMBLER_HH
+#define GLOBAL_GEODESIC_FE_ASSEMBLER_HH
+
+#include <dune/istl/bcrsmatrix.hh>
+#include <dune/common/fmatrix.hh>
+#include <dune/istl/matrixindexset.hh>
+#include <dune/istl/matrix.hh>
+
+#include "localgeodesicfestiffness.hh"
+
+
+/** \brief A global FE assembler for problems involving functions that map into non-Euclidean spaces 
+ */
+template <class GridView, class TargetSpace>
+class GeodesicFEAssembler {
+    
+    typedef typename GridView::template Codim<0>::Entity EntityType;
+    typedef typename GridView::template Codim<0>::EntityPointer EntityPointer;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    
+    //! Dimension of the grid.
+    enum { gridDim = GridView::dimension };
+    
+    //! Dimension of a tangent space
+    enum { blocksize = TargetSpace::TangentVector::size };
+    
+    //!
+    typedef Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock;
+    
+    const GridView gridView_; 
+
+    const LocalGeodesicFEStiffness<GridView,TargetSpace>* localStiffness_;
+
+public:
+    
+    /** \brief Constructor for a given grid */
+    GeodesicFEAssembler(const GridView& gridView) : 
+        gridView_(gridView)
+    {}
+    
+    /** \brief Assemble the tangent stiffness matrix
+     */
+    void assembleMatrix(const std::vector<TargetSpace>& sol,
+                        Dune::BCRSMatrix<MatrixBlock>& matrix) const;
+    
+    /** \brief Assemble the gradient */
+    void assembleGradient(const std::vector<TargetSpace>& sol,
+                          Dune::BlockVector<Dune::FieldVector<double, blocksize> >& grad) const;
+
+    /** \brief Assemble the gradient using a finite difference approximation */
+    void assembleGradientFD(const std::vector<TargetSpace>& sol,
+                          Dune::BlockVector<Dune::FieldVector<double, blocksize> >& grad) const;
+    
+    /** \brief Compute the energy of a deformation state */
+    double computeEnergy(const std::vector<TargetSpace>& sol) const;
+    
+protected:
+    void getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const;
+    
+}; // end class
+
+
+
+template <class GridView, class TargetSpace>
+void GeodesicFEAssembler<GridView,TargetSpace>::
+getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const
+{
+    const typename GridView::IndexSet& indexSet = gridView_->indexSet();
+    
+    int n = gridView_->size(gridDim);
+    
+    nb.resize(n, n);
+    
+    ElementIterator it    = gridView_->template begin<0>();
+    ElementIterator endit = gridView_->template end<0>  ();
+    
+    for (; it!=endit; ++it) {
+        
+        for (int i=0; i<it->template count<gridDim>(); i++) {
+            
+            for (int j=0; j<it->template count<gridDim>(); j++) {
+                
+                int iIdx = indexSet.subIndex(*it,i,gridDim);
+                int jIdx = indexSet.subIndex(*it,j,gridDim);
+                
+                nb.add(iIdx, jIdx);
+                
+            }
+            
+        }
+        
+    }
+    
+}
+
+
+
+template <class GridView, class TargetSpace>
+double GeodesicFEAssembler<GridView, TargetSpace>::
+computeEnergy(const std::vector<TargetSpace>& sol) const
+{
+    double energy = 0;
+    
+    const typename GridView::IndexSet& indexSet = gridView_.indexSet();
+
+    if (sol.size()!=indexSet.size(gridDim))
+        DUNE_THROW(Dune::Exception, "Solution vector doesn't match the grid!");
+
+    std::vector<TargetSpace> localSolution;
+
+    ElementIterator it    = gridView_.template begin<0>();
+    ElementIterator endIt = gridView_.template end<0>();
+
+    // Loop over all elements
+    for (; it!=endIt; ++it) {
+
+        localSolution.resize(it->template count<gridDim>());
+
+        for (int i=0; i<it->template count<gridDim>(); i++)
+            localSolution[i]               = sol[indexSet.subIndex(*it,i,gridDim)];
+
+        energy += localStiffness_->energy(*it, localSolution);
+
+    }
+
+    return energy;
+
+}
+
+
+
+#endif
+
-- 
GitLab