From ba3f98b2c21bae8c40e5f2d42d36a7fad389e445 Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Sun, 21 Oct 2012 17:50:58 +0000
Subject: [PATCH] Implemented iterator interface for ParallelDOFMapping.

---
 AMDiS/src/parallel/ParallelDofMapping.cc |  59 +++++++++-
 AMDiS/src/parallel/ParallelDofMapping.h  | 139 ++++++++++++++---------
 2 files changed, 143 insertions(+), 55 deletions(-)

diff --git a/AMDiS/src/parallel/ParallelDofMapping.cc b/AMDiS/src/parallel/ParallelDofMapping.cc
index d4f24f10..6638d45d 100644
--- a/AMDiS/src/parallel/ParallelDofMapping.cc
+++ b/AMDiS/src/parallel/ParallelDofMapping.cc
@@ -170,6 +170,63 @@ namespace AMDiS {
   }
 
 
+  void ComponentDataEqFeSpace::init(vector<const FiniteElemSpace*> &f0,
+				    vector<const FiniteElemSpace*> &f1,
+				    bool isNonLocal,
+				    MeshLevelData &levelData)
+  {
+    feSpaces = f1;
+    feSpacesUnique = f0;
+    for (vector<const FiniteElemSpace*>::iterator it = feSpacesUnique.begin();
+     	 it != feSpacesUnique.end(); ++it) {
+      addFeSpace(*it, levelData);
+      componentData[*it].setNeedGlobalMapping(isNonLocal);
+      componentData[*it].setNonLocal(isNonLocal);
+    }
+  }
+
+
+  void ComponentDataEqFeSpace::addFeSpace(const FiniteElemSpace* feSpace,
+					  MeshLevelData &levelData)
+  {
+    if (componentData.count(feSpace))
+      componentData.find(feSpace)->second.clear();
+    else
+      componentData.insert(make_pair(feSpace, ComponentDofMap(&levelData)));
+    
+    componentData.find(feSpace)->second.setFeSpace(feSpace);    
+  }
+
+
+  void ComponentDataDiffFeSpace::init(vector<const FiniteElemSpace*> &f0,
+				      vector<const FiniteElemSpace*> &f1,
+				      bool isNonLocal,
+				      MeshLevelData &levelData)
+  {
+    feSpaces = f1;
+    feSpacesUnique = f0;
+
+    for (unsigned int component = 0; component < feSpaces.size(); component++) {
+      addComponent(component, feSpaces[component], levelData);
+      componentData[component].setNeedGlobalMapping(isNonLocal);
+      componentData[component].setNonLocal(isNonLocal);
+    }    
+  }
+
+
+  void ComponentDataDiffFeSpace::addComponent(unsigned int component,
+					      const FiniteElemSpace* feSpace,
+					      MeshLevelData &levelData)
+  {
+    if (componentData.count(component)) 
+      componentData.find(component)->second.clear();
+    else
+      componentData.insert(make_pair(component, ComponentDofMap(&levelData)));
+
+    componentData.find(component)->second.setFeSpace(feSpace);
+  }
+
+
   void ParallelDofMapping::init(MeshLevelData &ldata,
 				vector<const FiniteElemSpace*> &fe,
 				vector<const FiniteElemSpace*> &uniqueFe,
@@ -180,7 +237,7 @@ namespace AMDiS {
     levelData = &ldata;
     isNonLocal = b;
 
-    data->init(fe, uniqueFe, isNonLocal);   
+    data->init(fe, uniqueFe, isNonLocal, ldata);
   }
 
 
diff --git a/AMDiS/src/parallel/ParallelDofMapping.h b/AMDiS/src/parallel/ParallelDofMapping.h
index 3a86c89a..c1704515 100644
--- a/AMDiS/src/parallel/ParallelDofMapping.h
+++ b/AMDiS/src/parallel/ParallelDofMapping.h
@@ -94,7 +94,6 @@ namespace AMDiS {
   private:
     /// The mapping data. For each system component there is a specific map that
     /// maps global DOF indices to global matrix indices.
-    //    map<int, map<DegreeOfFreedom, int> > data;
     map<int, boost::container::flat_map<DegreeOfFreedom, int> > data;
   };
 
@@ -291,6 +290,7 @@ namespace AMDiS {
     int nRankDofs, nLocalDofs, nOverallDofs, rStartDofs;
   };
 
+
   class ComponentIterator {
   public:
     virtual ComponentDofMap& operator*() = 0;
@@ -304,6 +304,7 @@ namespace AMDiS {
     virtual void reset() = 0;
   };
 
+
   class ComponentDataInterface
   {
   public:
@@ -319,7 +320,8 @@ namespace AMDiS {
 
     virtual void init(vector<const FiniteElemSpace*> &f0,
 		      vector<const FiniteElemSpace*> &f1,
-		      bool isNonLocal) = 0;
+		      bool isNonLocal,
+		      MeshLevelData &levelData) = 0;
 
     vector<const FiniteElemSpace*>& getFeSpaces()
     {
@@ -339,6 +341,11 @@ namespace AMDiS {
   class ComponentDataEqFeSpace : ComponentDataInterface
   {
   public:
+    ComponentDataEqFeSpace()
+      : iterData(this),
+	iterComponent(this)
+    {}
+
     ComponentDofMap& operator[](int compNumber)
     {
       const FiniteElemSpace *feSpace = feSpaces[compNumber];
@@ -372,78 +379,87 @@ namespace AMDiS {
 
     void init(vector<const FiniteElemSpace*> &f0,
 	      vector<const FiniteElemSpace*> &f1,
-	      bool isNonLocal)
-    {
-    // === Init the mapping for all different FE spaces. ===
+	      bool isNonLocal,
+	      MeshLevelData &levelData);
 
-    // for (vector<const FiniteElemSpace*>::iterator it = feSpacesUnique.begin();
-    // 	 it != feSpacesUnique.end(); ++it) {
-    //   addFeSpace(*it);
-    //   data[*it].setNeedGlobalMapping(isNonLocal);
-    //   data[*it].setNonLocal(isNonLocal);
-    // }
-
-  // void ParallelDofMapping::addFeSpace(const FiniteElemSpace* feSpace)
-  // {
-  //   FUNCNAME("ParallelDofMapping::addFeSpace()");
-    
-  //   if (data.count(feSpace))
-  //     data.find(feSpace)->second.clear();
-  //   else
-  //     data.insert(make_pair(feSpace, ComponentDofMap(levelData)));
-    
-  //   data.find(feSpace)->second.setFeSpace(feSpace);
-  // }    
 
-    }
+  protected:
 
+    void addFeSpace(const FiniteElemSpace* feSpace,
+		    MeshLevelData &levelData);
 
-  protected:
     class IteratorData : public ComponentIterator {
     public:
+      IteratorData(ComponentDataEqFeSpace *d)
+	: data(d)
+      {}
+
       ComponentDofMap& operator*()
       {
+	(*data)[*it];
       }
 
       ComponentDofMap* operator->()
       {
+	&((*data)[*it]);
       }
 
       bool end()
       {
+	return (it != data->feSpacesUnique.end());
       }
 
       void next()
       {
+	++it;
       }
 
       void reset()
       {
+	it = data->feSpacesUnique.begin();
       }
+
+    protected:
+      ComponentDataEqFeSpace *data;
+
+      vector<const FiniteElemSpace*>::iterator it;
     };
 
     class IteratorComponent : public ComponentIterator {
     public:
+      IteratorComponent(ComponentDataEqFeSpace *d)
+	: data(d)
+      {}
+
       ComponentDofMap& operator*()
       {
+	(*data)[*it];
       }
 
       ComponentDofMap* operator->()
       {
+	&((*data)[*it]);
       }
 
-      
       bool end()
       {
+	return (it != data->feSpaces.end());
       }
 
       void next()
       {
+	++it;
       }
 
       void reset()
       {
+	it = data->feSpaces.begin();
       }
+
+    protected:
+      ComponentDataEqFeSpace *data;
+
+      vector<const FiniteElemSpace*>::iterator it;
     };
     
 
@@ -452,12 +468,20 @@ namespace AMDiS {
     IteratorData iterData;
 
     IteratorComponent iterComponent;
+
+    friend class IteratorData;
+    
+    friend class IteratorComponent;
   };
 
 
   class ComponentDataDiffFeSpace : ComponentDataInterface
   {
   public:
+    ComponentDataDiffFeSpace()
+      : iter(this)
+    {}
+
     ComponentDofMap& operator[](int compNumber)
     {
       TEST_EXIT_DBG(componentData.count(compNumber))("No data for component %d!\n", compNumber);
@@ -472,14 +496,14 @@ namespace AMDiS {
     
     ComponentIterator& getIteratorData()
     {
-      iterData.reset();
-      return iterData;
+      iter.reset();
+      return iter;
     }
     
     ComponentIterator& getIteratorComponent()
     {
-      iterComponent.reset();
-      return iterComponent;
+      iter.reset();
+      return iter;
     }
 
     bool isDefinedFor(int compNumber) const
@@ -487,60 +511,67 @@ namespace AMDiS {
       return (static_cast<unsigned int>(compNumber) < componentData.size());
     }
 
+    void init(vector<const FiniteElemSpace*> &f0,
+	      vector<const FiniteElemSpace*> &f1,
+	      bool isNonLocal,
+	      MeshLevelData &levelData);
+
   protected:
-    class IteratorData : public ComponentIterator {
+    void addComponent(unsigned int component,
+		      const FiniteElemSpace* feSpace,
+		      MeshLevelData &levelData);
+
+    class Iterator : public ComponentIterator {
     public:
+      Iterator(ComponentDataDiffFeSpace *d)
+	: data(d),
+	  componentCounter(-1)
+      {}
+
       ComponentDofMap& operator*()
       {
+	(*data)[componentCounter];
       }
 
       ComponentDofMap* operator->()
       {
+	&((*data)[componentCounter]);
       }
 
 
       bool end()
       {
+	return (it != data->feSpaces.end());
       }
 
       void next()
       {
-      }
-
-      void reset()
-      {
-      }
-    };
+	++it;
+	++componentCounter;
 
-    class IteratorComponent : public ComponentIterator {
-    public:
-      ComponentDofMap& operator*()
-      {
+	if (it == data->feSpaces.end())
+	  componentCounter = -1;
       }
 
-      ComponentDofMap* operator->()
+      void reset()
       {
+	it = data->feSpaces.begin();
+	componentCounter = 0;
       }
 
-      
-      bool end()
-      {
-      }
+    protected:
+      ComponentDataDiffFeSpace *data;
 
-      void next()
-      {
-      }
+      vector<const FiniteElemSpace*>::iterator it;
 
-      void reset()
-      {
-      }
+      int componentCounter;
     };
 
     map<unsigned int, ComponentDofMap> componentData;
 
-    IteratorData iterData;
+    Iterator iter;
 
-    IteratorComponent iterComponent;
+    friend class Iterator;
   };
 
 
-- 
GitLab