From 85d3abe3c98348463ed104c27d5c95c1d38c7150 Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Sat, 19 Nov 2011 20:07:49 +0000
Subject: [PATCH] geodesicfefunctionadaptor can now handle spaces of higher
 than second order

[[Imported from SVN: r8240]]
---
 dune/gfe/geodesicfefunctionadaptor.hh | 41 ++++++++++++---------------
 harmonicmaps-eoc.cc                   | 15 ++++++----
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/dune/gfe/geodesicfefunctionadaptor.hh b/dune/gfe/geodesicfefunctionadaptor.hh
index 6a504d50..72f6cc00 100644
--- a/dune/gfe/geodesicfefunctionadaptor.hh
+++ b/dune/gfe/geodesicfefunctionadaptor.hh
@@ -4,8 +4,6 @@
 #include <vector>
 #include <map>
 
-#include <dune/fufem/functionspacebases/p2nodalbasis.hh>
-
 #include "localgeodesicfefunction.hh"
 
 template <class Basis, class TargetSpace>
@@ -118,10 +116,15 @@ struct CoordinateFunction
 
 
 /** \brief Refine a grid globally and prolong a given geodesic finite element function
+ * 
+ * \tparam order Interpolation order of the function space.  Kinda stupid that I
+ *  have to provide this by hand.  Will change...
  */
-template <class GridType>
-static void higherOrderGFEFunctionAdaptor(GridType& grid, std::vector<TargetSpace>& x)
+template <int order>
+static void higherOrderGFEFunctionAdaptor(Basis& basis,
+                                          typename Basis::GridView::Grid& grid, std::vector<TargetSpace>& x)
 {
+    typedef typename Basis::GridView::Grid GridType;
     const int dim = GridType::dimension;
 
     typedef typename GridType::template Codim<0>::LeafIterator ElementIterator;
@@ -135,25 +138,18 @@ static void higherOrderGFEFunctionAdaptor(GridType& grid, std::vector<TargetSpac
     typedef typename GridType::Traits::LocalIdSet::IdType IdType;
     std::map<IdType, std::vector<TargetSpace> > dofMap;
 
-    typedef P2NodalBasis<typename GridType::LeafGridView,double> P2Basis;
-    P2Basis p2Basis(grid.leafView());
-    
-    assert(x.size() == p2Basis.size());
+    assert(x.size() == basis.size());
     
     ElementIterator eIt    = grid.template leafbegin<0>();
     ElementIterator eEndIt = grid.template leafend<0>();
 
     for (; eIt!=eEndIt; ++eIt) {
 
-        const typename P2Basis::LocalFiniteElement& lfe = p2Basis.getLocalFiniteElement(*eIt);
+        const typename Basis::LocalFiniteElement& lfe = basis.getLocalFiniteElement(*eIt);
         std::vector<TargetSpace> coefficients(lfe.localCoefficients().size());
         
-        for (size_t i=0; i<lfe.localCoefficients().size(); i++) {
-            
-            unsigned int idx = p2Basis.index(*eIt, i);
-            coefficients[i] = x[idx];
-
-        }
+        for (size_t i=0; i<lfe.localCoefficients().size(); i++)
+            coefficients[i] = x[basis.index(*eIt, i)];
 
         IdType id = idSet.id(*eIt);
         dofMap.insert(std::make_pair(id, coefficients));
@@ -172,22 +168,21 @@ static void higherOrderGFEFunctionAdaptor(GridType& grid, std::vector<TargetSpac
     //   Restore and interpolate the data
     // /////////////////////////////////////////////////////
 
-    p2Basis.update(grid.leafView());
+    basis.update(grid.leafView());
     
-    x.resize(p2Basis.size());
+    x.resize(basis.size());
 
     for (eIt=grid.template leafbegin<0>(); eIt!=eEndIt; ++eIt) {
 
-        const typename P2Basis::LocalFiniteElement& lfe = p2Basis.getLocalFiniteElement(*eIt);
+        const typename Basis::LocalFiniteElement& lfe = basis.getLocalFiniteElement(*eIt);
 
-        std::auto_ptr<typename Dune::PQkLocalFiniteElementFactory<double,double,dim,2>::FiniteElementType> fatherLFE 
-            = std::auto_ptr<typename Dune::PQkLocalFiniteElementFactory<double,double,dim,2>::FiniteElementType>(Dune::PQkLocalFiniteElementFactory<double,double,dim,2>::create(eIt->type()));
+        std::auto_ptr<typename Dune::PQkLocalFiniteElementFactory<double,double,dim,order>::FiniteElementType> fatherLFE 
+            = std::auto_ptr<typename Dune::PQkLocalFiniteElementFactory<double,double,dim,order>::FiniteElementType>(Dune::PQkLocalFiniteElementFactory<double,double,dim,order>::create(eIt->father()->type()));
         
         // Set up a local gfe function on the father element
-        //std::vector<TargetSpace> coefficients(fatherLFE->localCoefficients().size());
         std::vector<TargetSpace> coefficients = dofMap[idSet.id(*eIt->father())];
         
-        LocalGeodesicFEFunction<dim,double,typename P2Basis::LocalFiniteElement,TargetSpace> fatherFunction(*fatherLFE, coefficients);
+        LocalGeodesicFEFunction<dim,double,typename Basis::LocalFiniteElement,TargetSpace> fatherFunction(*fatherLFE, coefficients);
 
         // The embedding of this element into the father geometry
         const typename GridType::template Codim<0>::LocalGeometry& geometryInFather = eIt->geometryInFather();
@@ -207,7 +202,7 @@ static void higherOrderGFEFunctionAdaptor(GridType& grid, std::vector<TargetSpac
 
         for (int i=0; i<lfe.localCoefficients().size(); i++) {
 
-            unsigned int idx = p2Basis.index(*eIt, i);
+            unsigned int idx = basis.index(*eIt, i);
 
             x[idx] = fatherFunction.evaluate(geometryInFather.global(lagrangeNodes[i]));
 
diff --git a/harmonicmaps-eoc.cc b/harmonicmaps-eoc.cc
index d48dff07..a3650329 100644
--- a/harmonicmaps-eoc.cc
+++ b/harmonicmaps-eoc.cc
@@ -223,8 +223,8 @@ int main (int argc, char *argv[]) try
 #else
     typedef P1NodalBasis<GridType::LeafGridView,double> FEBasis;
 #endif
-    FEBasis basis(referenceGrid->leafView());
-    OperatorAssembler<FEBasis,FEBasis> operatorAssembler(basis, basis);
+    FEBasis referenceBasis(referenceGrid->leafView());
+    OperatorAssembler<FEBasis,FEBasis> operatorAssembler(referenceBasis, referenceBasis);
 
     LaplaceAssembler<GridType, FEBasis::LocalFiniteElement, FEBasis::LocalFiniteElement> laplaceLocalAssembler;
     MassAssembler<GridType, FEBasis::LocalFiniteElement, FEBasis::LocalFiniteElement> massMatrixLocalAssembler;
@@ -277,12 +277,17 @@ int main (int argc, char *argv[]) try
 #endif
         
         // Prolong solution to the very finest grid
-        for (int j=i; j<numLevels; j++)
-#if defined THIRD_ORDER || defined SECOND_ORDER
-            higherOrderGFEFunctionAdaptor(*grid, solution);
+        for (int j=i; j<numLevels; j++) {
+            FEBasis basis(grid->leafView());
+#if defined THIRD_ORDER
+            GeodesicFEFunctionAdaptor<FEBasis,TargetSpace>::higherOrderGFEFunctionAdaptor<3>(basis, *grid, solution);
+#elif defined SECOND_ORDER
+            GeodesicFEFunctionAdaptor<FEBasis,TargetSpace>::higherOrderGFEFunctionAdaptor<2>(basis, *grid, solution);
 #else
             geodesicFEFunctionAdaptor(*grid, solution);
 #endif
+        }
+
         // Interpret TargetSpace as isometrically embedded into an R^m, because this is
         // how the corresponding Sobolev spaces are defined.
 
-- 
GitLab