From 7bd09e85e5fca0c396a8a0fdb8626ae3358fa981 Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Wed, 24 Jun 2015 12:40:17 +0000
Subject: [PATCH] Error in MeshDistributer corrected due to the use of
 non-initialized dofComm that is replaced by dofComms

---
 AMDiS/src/Bubble.cc                   |  2 +-
 AMDiS/src/ProblemStat.cc              |  2 +-
 AMDiS/src/ProblemStat.h               |  5 +--
 AMDiS/src/RefinementManager3d.cc      |  1 +
 AMDiS/src/io/PovrayWriter.cc          |  3 --
 AMDiS/src/parallel/DofComm.h          |  2 +-
 AMDiS/src/parallel/MeshDistributor.cc |  1 +
 AMDiS/src/parallel/MeshDistributor.h  | 51 +++++++++++++++++++++------
 AMDiS/src/parallel/PetscSolverFeti.cc | 15 ++++----
 demo/init/ball.dat.2d                 |  4 +--
 demo/init/ball.dat.3d                 |  2 +-
 demo/macro/macro.ball.2d              |  6 ++--
 12 files changed, 63 insertions(+), 31 deletions(-)

diff --git a/AMDiS/src/Bubble.cc b/AMDiS/src/Bubble.cc
index af2694c3..dfb376a2 100644
--- a/AMDiS/src/Bubble.cc
+++ b/AMDiS/src/Bubble.cc
@@ -773,7 +773,7 @@ namespace AMDiS {
   // list = informations about element and the neighbours
   // n = number of neighbours
   // Calculation of the values can be traced in the documentation
-  // TODO: maybe the implementation is wrong!
+  // NOTE: maybe the implementation is wrong!
   void Bubble::coarseRestr3_2d(DOFIndexed<double> *drv, 
 			       RCNeighbourList *list, 
 			       int n, BasisFunction* basFct)
diff --git a/AMDiS/src/ProblemStat.cc b/AMDiS/src/ProblemStat.cc
index deeeffa0..acc13752 100644
--- a/AMDiS/src/ProblemStat.cc
+++ b/AMDiS/src/ProblemStat.cc
@@ -621,7 +621,7 @@ namespace AMDiS {
 	for (int j = 0; j < nComponents; j++)
 	  estimator[i]->addSystem((*systemMatrix)[i][j], 
 				  solution->getDOFVector(j), 
-				  rhs->getDOFVector(j));      // TODO: hier eventuell (i) statt (j) ???
+				  rhs->getDOFVector(i));      // NOTE: hier eventuell (i) statt (j) ??? --> corrected
     }
   }
 
diff --git a/AMDiS/src/ProblemStat.h b/AMDiS/src/ProblemStat.h
index 6f995384..e60244d0 100644
--- a/AMDiS/src/ProblemStat.h
+++ b/AMDiS/src/ProblemStat.h
@@ -147,12 +147,13 @@ namespace AMDiS {
     void dualAssemble(AdaptInfo *adaptInfo, Flag flag, 
 		      bool asmMatrix = true, bool asmVector = true);
 
-    /// Implementation of ProblemStatBase::getNumComponents(), TODO: Wrong!!
-    virtual int getNumComponents() 
+    /// Returns nr of components \ref nComponents
+    virtual int getNumComponents()
     { 
       return nComponents; 
     }
     
+    /// Returns nr of additional components \ref nAddComponents
     virtual int getNumAddComponents()
     {
       return nAddComponents;
diff --git a/AMDiS/src/RefinementManager3d.cc b/AMDiS/src/RefinementManager3d.cc
index 176b173d..6b338b2b 100644
--- a/AMDiS/src/RefinementManager3d.cc
+++ b/AMDiS/src/RefinementManager3d.cc
@@ -396,6 +396,7 @@ namespace AMDiS {
     if (bound) {
       mesh->incrementNumberOfEdges(n_neigh + 2);
       mesh->incrementNumberOfFaces(2 * n_neigh + 1);
+      newCoords = true; // added to allow BOUNDARY_PROJECTION
     } else {
       mesh->incrementNumberOfEdges(n_neigh + 1);
       mesh->incrementNumberOfFaces(2 * n_neigh);
diff --git a/AMDiS/src/io/PovrayWriter.cc b/AMDiS/src/io/PovrayWriter.cc
index 957128fe..eee7d5bb 100644
--- a/AMDiS/src/io/PovrayWriter.cc
+++ b/AMDiS/src/io/PovrayWriter.cc
@@ -184,9 +184,6 @@ namespace AMDiS { namespace io {
     writeTestStuff(out, *dataCollector);
     writeMesh2(out, *dataCollector);
 
-    // TODO: remove
-    //tryMeshTraversal(out);
-
     out.close();
   }
 
diff --git a/AMDiS/src/parallel/DofComm.h b/AMDiS/src/parallel/DofComm.h
index c5fb2aff..51c59cc9 100644
--- a/AMDiS/src/parallel/DofComm.h
+++ b/AMDiS/src/parallel/DofComm.h
@@ -86,7 +86,7 @@ namespace AMDiS { namespace Parallel {
 
   protected:
     /// This map contains for each rank the list of DOFs the current rank must 
-    /// end to exchange solution DOFs at the interior boundaries.
+    /// send to exchange solution DOFs at the interior boundaries.
     DataType sendDofs;
 
     /// This map contains on each rank the list of DOFs from which the current 
diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc
index f6e7b2a6..8f35318d 100644
--- a/AMDiS/src/parallel/MeshDistributor.cc
+++ b/AMDiS/src/parallel/MeshDistributor.cc
@@ -1015,6 +1015,7 @@ namespace AMDiS { namespace Parallel {
 					   DofContainer& dofs)
   {
     DofContainerSet dofSet;
+    MultiLevelDofComm& dofComm = dofComms[feSpace->getMesh()];
     for (DofComm::Iterator it(dofComm[level].getSendDofs(), feSpace); 
 	 !it.end(); it.nextRank())
       dofSet.insert(it.getDofs().begin(), it.getDofs().end());
diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h
index 157dbb78..9665e5ae 100644
--- a/AMDiS/src/parallel/MeshDistributor.h
+++ b/AMDiS/src/parallel/MeshDistributor.h
@@ -177,10 +177,10 @@ namespace AMDiS { namespace Parallel {
       return periodicMap;
     }
 
-    DofComm& getDofComm(int level)
-    {
-      return dofComm[level];
-    }
+//     DofComm& getDofComm(int level)
+//     {
+//       return dofComm[level];
+//     }
     
     DofComm& getDofComm(Mesh* mesh, int level)
     {
@@ -245,10 +245,12 @@ namespace AMDiS { namespace Parallel {
     /// Works quite similar to the function \ref synchVector, but instead the 
     /// values of subdomain vectors are combined along the boundaries, by a
     /// binary functor. 
+    // minorRank => majorRank
     template<typename T, typename Operator>
     void synchVector(DOFVector<T> &vec, Operator op)
     {
       const FiniteElemSpace *fe = vec.getFeSpace();
+      MultiLevelDofComm& dofComm = dofComms[fe->getMesh()];
 
       int nLevels = levelData.getNumberOfLevels();
       for (int level = nLevels - 1; level >= 0; level--) {
@@ -277,8 +279,7 @@ namespace AMDiS { namespace Parallel {
 	    op(vec[it.getDofIndex()],
 	       stdMpi.getRecvData(it.getRank())[it.getDofCounter()]);
       }
-      if (!boost::is_same<Operator, functors::assign<T> >::value)
-	synchVector(vec);
+      synchVector(vec);
     }
     
     /** \brief
@@ -291,10 +292,41 @@ namespace AMDiS { namespace Parallel {
      * solved, or after the DOFVector is set by some user defined functions, 
      * e.g., initial solution functions.
      */    
+     // majorRank => minorRank
     template<typename T>
     void synchVector(DOFVector<T> &vec) 
     {
-      synchVector(vec, functors::assign<T>());
+      const FiniteElemSpace *fe = vec.getFeSpace();
+      MultiLevelDofComm& dofComm = dofComms[fe->getMesh()];
+
+      int nLevels = levelData.getNumberOfLevels();
+      for (int level = nLevels - 1; level >= 0; level--) {
+	StdMpi<std::vector<T> > stdMpi(levelData.getMpiComm(level));
+
+	for (DofComm::Iterator it(dofComm[level].getSendDofs(), fe); 
+	     !it.end(); it.nextRank()) {
+
+	  std::vector<T> dofs;
+	  dofs.reserve(it.getDofs().size());
+	  
+	  for (; !it.endDofIter(); it.nextDof())
+	    dofs.push_back(vec[it.getDofIndex()]);
+	  
+	  stdMpi.send(it.getRank(), dofs);
+	}
+	
+	for (DofComm::Iterator it(dofComm[level].getRecvDofs()); 
+	     !it.end(); it.nextRank())
+	  stdMpi.recv(it.getRank());
+	
+	stdMpi.startCommunication();
+	
+	for (DofComm::Iterator it(dofComm[level].getRecvDofs(), fe); 
+	     !it.end(); it.nextRank())
+	  for (; !it.endDofIter(); it.nextDof())
+	    vec[it.getDofIndex()] = 
+	      stdMpi.getRecvData(it.getRank())[it.getDofCounter()];
+      }
     }
    
     /// Works in the same way as the function above defined for DOFVectors. Due
@@ -304,10 +336,12 @@ namespace AMDiS { namespace Parallel {
     
     /// Works quite similar to the function \ref synchVector, but instead the 
     /// values of subdomain vectors are add along the boundaries.
+    // minorRank => majorRank
     template<typename T>
     void synchAddVector(DOFVector<T> &vec)
     {
       const FiniteElemSpace *fe = vec.getFeSpace();
+      MultiLevelDofComm& dofComm = dofComms[fe->getMesh()];
 
       int nLevels = levelData.getNumberOfLevels();
       for (int level = nLevels - 1; level >= 0; level--) {
@@ -621,9 +655,6 @@ namespace AMDiS { namespace Parallel {
     /// Defines the interior boundaries of the domain that result from 
     /// partitioning the whole mesh. 
     MultiLevelInteriorBoundary intBoundary;
-
-    /// Dof communicator object // TODO: to be deleted
-    MultiLevelDofComm dofComm;
     
     /// Dof communicator objects for each mesh
     std::map<Mesh*, MultiLevelDofComm> dofComms;
diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc
index e3b52fbe..1edcf370 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.cc
+++ b/AMDiS/src/parallel/PetscSolverFeti.cc
@@ -474,6 +474,7 @@ namespace AMDiS { namespace Parallel {
       return;
 
     const FiniteElemSpace *feSpace = componentSpaces[component];
+    Mesh* mesh = feSpace->getMesh();
     boundaryDofRanks[feSpace].clear();
 
     // Stores for all rank owned communication DOFs, if the counterpart is
@@ -484,7 +485,7 @@ namespace AMDiS { namespace Parallel {
     if (not subDomainIsLocal) {
       StdMpi<vector<int> > stdMpi(domainComm);
 
-      for (DofComm::Iterator it(meshDistributor->getDofComm(meshLevel).getRecvDofs(), feSpace);
+      for (DofComm::Iterator it(meshDistributor->getDofComm(mesh, meshLevel).getRecvDofs(), feSpace);
 	   !it.end(); it.nextRank()) {
 
 	vector<int> dofs;
@@ -500,13 +501,13 @@ namespace AMDiS { namespace Parallel {
 	stdMpi.send(it.getRank(), dofs);
       }	     
 
-      for (DofComm::Iterator it(meshDistributor->getDofComm(meshLevel).getSendDofs(), feSpace);
+      for (DofComm::Iterator it(meshDistributor->getDofComm(mesh, meshLevel).getSendDofs(), feSpace);
 	   !it.end(); it.nextRank())
 	stdMpi.recv(it.getRank());
 
       stdMpi.startCommunication();
 
-      for (DofComm::Iterator it(meshDistributor->getDofComm(meshLevel).getSendDofs(), feSpace); 
+      for (DofComm::Iterator it(meshDistributor->getDofComm(mesh, meshLevel).getSendDofs(), feSpace); 
 	   !it.end(); it.nextRank())
 	for (; !it.endDofIter(); it.nextDof())
 	  if (!isPrimal(component, it.getDofIndex()) &&
@@ -522,7 +523,7 @@ namespace AMDiS { namespace Parallel {
     // === of ranks that contain this node (denoted by W(x_j)).         ===
 
     int mpiRank = domainComm.Get_rank();
-    for (DofComm::Iterator it(meshDistributor->getDofComm(meshLevel).getSendDofs(), feSpace); 
+    for (DofComm::Iterator it(meshDistributor->getDofComm(mesh, meshLevel).getSendDofs(), feSpace); 
 	 !it.end(); it.nextRank()) {
       for (; !it.endDofIter(); it.nextDof()) {
 	if (!isPrimal(component, it.getDofIndex())) {
@@ -544,7 +545,7 @@ namespace AMDiS { namespace Parallel {
 
     StdMpi<vector<std::set<int> > > stdMpi(meshDistributor->getMpiComm(meshLevel));
 
-    for (DofComm::Iterator it(meshDistributor->getDofComm(meshLevel).getSendDofs(), feSpace);
+    for (DofComm::Iterator it(meshDistributor->getDofComm(mesh, meshLevel).getSendDofs(), feSpace);
 	 !it.end(); it.nextRank())
       for (; !it.endDofIter(); it.nextDof())
 	if (!isPrimal(component, it.getDofIndex()))
@@ -553,7 +554,7 @@ namespace AMDiS { namespace Parallel {
 
     stdMpi.updateSendDataSize();
 
-    for (DofComm::Iterator it(meshDistributor->getDofComm(meshLevel).getRecvDofs(), feSpace); 
+    for (DofComm::Iterator it(meshDistributor->getDofComm(mesh, meshLevel).getRecvDofs(), feSpace); 
 	 !it.end(); it.nextRank()) {
       bool recvFromRank = false;
       for (; !it.endDofIter(); it.nextDof()) {
@@ -571,7 +572,7 @@ namespace AMDiS { namespace Parallel {
 
     stdMpi.startCommunication();
 
-    for (DofComm::Iterator it(meshDistributor->getDofComm(meshLevel).getRecvDofs(), feSpace); 
+    for (DofComm::Iterator it(meshDistributor->getDofComm(mesh, meshLevel).getRecvDofs(), feSpace); 
 	 !it.end(); it.nextRank()) {
       int i = 0;
       for (; !it.endDofIter(); it.nextDof()) {
diff --git a/demo/init/ball.dat.2d b/demo/init/ball.dat.2d
index e9354fab..19cc55e0 100644
--- a/demo/init/ball.dat.2d
+++ b/demo/init/ball.dat.2d
@@ -1,14 +1,14 @@
 dimension of world:             2
 
 ballMesh->macro file name:    ./macro/macro.ball.2d
-ballMesh->global refinements: 3
+ballMesh->global refinements: 5
 
 ball->mesh:                   ballMesh
 ball->dim:                    2
 ball->components:             1
 ball->polynomial degree[0]:   1
 
-ball->space->components:      1
+ball->components:             1
 
 ball->solver:                 cg
 ball->solver->max iteration:  1000
diff --git a/demo/init/ball.dat.3d b/demo/init/ball.dat.3d
index 70426ef4..6b67201b 100644
--- a/demo/init/ball.dat.3d
+++ b/demo/init/ball.dat.3d
@@ -8,7 +8,7 @@ ball->dim:                    3
 ball->components:             1
 ball->polynomial degree[0]:   1
 
-ball->space->components:      1
+ball->components:             1
 
 ball->solver:                 cg
 ball->solver->max iteration:  1000
diff --git a/demo/macro/macro.ball.2d b/demo/macro/macro.ball.2d
index 54f1448e..b38d705e 100644
--- a/demo/macro/macro.ball.2d
+++ b/demo/macro/macro.ball.2d
@@ -31,6 +31,6 @@ element neighbours:
 
 projections:
  0 0 1
- 0 0 0
- 0 0 0
- 0 0 0
+ 0 0 1
+ 0 0 1
+ 0 0 1
-- 
GitLab