From 9ce826f5164ad5a1cf4e424f34b527416a69460d Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Tue, 13 Mar 2012 15:47:11 +0000
Subject: [PATCH] Mh, seems to work.

---
 AMDiS/src/parallel/FeSpaceMapping.cc  |   7 +-
 AMDiS/src/parallel/FeSpaceMapping.h   |  15 ++-
 AMDiS/src/parallel/PetscSolverFeti.cc | 147 ++++++++++++--------------
 AMDiS/src/parallel/PetscSolverFeti.h  |   3 -
 4 files changed, 84 insertions(+), 88 deletions(-)

diff --git a/AMDiS/src/parallel/FeSpaceMapping.cc b/AMDiS/src/parallel/FeSpaceMapping.cc
index 0d582345..36d1d7f4 100644
--- a/AMDiS/src/parallel/FeSpaceMapping.cc
+++ b/AMDiS/src/parallel/FeSpaceMapping.cc
@@ -47,7 +47,8 @@ namespace AMDiS {
   void GlobalDofMap::addOffset(int offset)
   {
     for (map<DegreeOfFreedom, MultiIndex>::iterator it = dofMap.begin(); it != dofMap.end(); ++it)
-      it->second.local += offset;
+      it->second.global = it->second.local + offset;
+      //      it->second.local += offset;
   }
 
   void GlobalDofMap::computeNonLocalIndices()
@@ -60,7 +61,7 @@ namespace AMDiS {
     for (DofComm::Iterator it(*sendDofs, feSpace); !it.end(); it.nextRank())
       for (; !it.endDofIter(); it.nextDof())
 	if (dofMap.count(it.getDofIndex()) && !nonRankDofs.count(it.getDofIndex()))
-	  stdMpi.getSendData(it.getRank()).push_back(dofMap[it.getDofIndex()].local);
+	  stdMpi.getSendData(it.getRank()).push_back(dofMap[it.getDofIndex()].global);
 
     stdMpi.updateSendDataSize();
 
@@ -84,7 +85,7 @@ namespace AMDiS {
       int i = 0;
       for (; !it.endDofIter(); it.nextDof())
 	if (nonRankDofs.count(it.getDofIndex()))
-	  dofMap[it.getDofIndex()].local = stdMpi.getRecvData(it.getRank())[i++];
+	  dofMap[it.getDofIndex()].global = stdMpi.getRecvData(it.getRank())[i++];
     }
   }
 
diff --git a/AMDiS/src/parallel/FeSpaceMapping.h b/AMDiS/src/parallel/FeSpaceMapping.h
index 81ee57c0..b2832527 100644
--- a/AMDiS/src/parallel/FeSpaceMapping.h
+++ b/AMDiS/src/parallel/FeSpaceMapping.h
@@ -369,8 +369,10 @@ namespace AMDiS {
 	typedef map<DegreeOfFreedom, MultiIndex>::iterator ItType;
 	for (ItType it = dofMap.begin(); it != dofMap.end(); ++it) {
 	  if (data[feSpaces[i]].isRankDof(it->first)) {
-	    int globalMatIndex = 
-	      it->second.local - data[feSpaces[i]].rStartDofs + offset;
+ 	    int globalMatIndex = it->second.local + offset;
+
+// 	    int globalMatIndex = 
+// 	      it->second.local - data[feSpaces[i]].rStartDofs + offset;
 	    dofToMatIndex.add(i, it->first, globalMatIndex);
 	  }
 	}
@@ -400,9 +402,9 @@ namespace AMDiS {
 	stdMpi.startCommunication();
 	
 	{
-	  int counter = 0;
 	  for (DofComm::Iterator it(*recvDofs, feSpaces[i]); 
 	       !it.end(); it.nextRank()) {
+	    int counter = 0;
 	    for (; !it.endDofIter(); it.nextDof()) {
 	      if (dofMap.count(it.getDofIndex())) {
 		DegreeOfFreedom d = stdMpi.getRecvData(it.getRank())[counter++];
@@ -465,6 +467,13 @@ namespace AMDiS {
 	data[*it].setDofComm(pSend, pRecv);
     }
 
+    inline int getMatIndex(int ithComponent, DegreeOfFreedom d)
+    {
+      FUNCNAME("FeSpaceData::getMatIndex()");
+
+      return dofToMatIndex.get(ithComponent, d);
+    }
+
   private:
     MPI::Intracomm* mpiComm;
 
diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc
index 4fbe4262..6201c4f9 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.cc
+++ b/AMDiS/src/parallel/PetscSolverFeti.cc
@@ -181,7 +181,6 @@ namespace AMDiS {
 
   PetscSolverFeti::PetscSolverFeti()
     : PetscSolver(),
-      nComponents(-1),
       schurPrimalSolver(0)
   {
     FUNCNAME("PetscSolverFeti::PetscSolverFeti()");
@@ -408,8 +407,6 @@ namespace AMDiS {
   {
     FUNCNAME("PetscSolverFeti::createMatLagrange()");
 
-    const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
-
     // === Create distributed matrix for Lagrange constraints. ===
 
     MatCreateMPIAIJ(PETSC_COMM_WORLD,
@@ -425,35 +422,34 @@ namespace AMDiS {
     // === m == r, than the rank sets -1.0 for the corresponding           ===
     // === constraint.                                                     ===
 
-    map<DegreeOfFreedom, MultiIndex> &dualMap = dualDofMap[feSpace].getMap();
-    for (map<DegreeOfFreedom, MultiIndex>::iterator it = dualMap.begin(); it != dualMap.end(); ++it) {
-      TEST_EXIT_DBG(boundaryDofRanks.count(it->first))
-	("Should not happen!\n");
+    for (unsigned int k = 0; k < feSpaces.size(); k++) {
+      map<DegreeOfFreedom, MultiIndex> &dualMap = 
+	dualDofMap[feSpaces[k]].getMap();
 
-      // Global index of the first Lagrange constriant for this node.
-      int index = lagrangeMap[feSpace][it->first].local;
-      // Copy set of all ranks that contain this dual node.
-      vector<int> W(boundaryDofRanks[it->first].begin(), 
-		    boundaryDofRanks[it->first].end());
-      // Number of ranks that contain this dual node.
-      int degree = W.size();
-
-      for (int i = 0; i < degree; i++) {
-	for (int j = i + 1; j < degree; j++) {
-	  if (W[i] == mpiRank || W[j] == mpiRank) {
-	    // Set the constraint for all components of the system.
-	    for (int k = 0; k < nComponents; k++) {
-	      int rowIndex = index * nComponents + k;
-	      int colIndex = 
-		(localDofMap[feSpace].rStartDofs +
-		 localDofMap[feSpace][it->first].local) * nComponents + k;
+      for (map<DegreeOfFreedom, MultiIndex>::iterator it = dualMap.begin(); 
+	   it != dualMap.end(); ++it) {
+	TEST_EXIT_DBG(boundaryDofRanks.count(it->first))
+	  ("Should not happen!\n");
+	
+	// Global index of the first Lagrange constriant for this node.
+	int index = lagrangeMap.getMatIndex(k, it->first);
+	
+	// Copy set of all ranks that contain this dual node.
+	vector<int> W(boundaryDofRanks[it->first].begin(), 
+		      boundaryDofRanks[it->first].end());
+	// Number of ranks that contain this dual node.
+	int degree = W.size();
+	
+	for (int i = 0; i < degree; i++) {
+	  for (int j = i + 1; j < degree; j++) {
+	    if (W[i] == mpiRank || W[j] == mpiRank) {
+	      int colIndex = localDofMap.mapGlobal(it->first, k);
 	      double value = (W[i] == mpiRank ? 1.0 : -1.0);
-	      MatSetValue(mat_lagrange, rowIndex, colIndex, value, 
+	      MatSetValue(mat_lagrange, index, colIndex, value, 
 			  INSERT_VALUES);
 	    }
+	    index++;	      
 	  }
-
-	  index++;
 	}
       }
     }
@@ -767,8 +763,6 @@ namespace AMDiS {
   {
     FUNCNAME("PetscSolverFeti::recoverSolution()");
 
-    const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
-
     // === Get local part of the solution for B variables. ===
 
     PetscScalar *localSolB;
@@ -778,19 +772,25 @@ namespace AMDiS {
     // === Create scatter to get solutions of all primal nodes that are ===
     // === contained in rank's domain.                                  ===
     
+    vector<const FiniteElemSpace*> feSpaces = getFeSpaces(&vec);
+
     vector<PetscInt> globalIsIndex, localIsIndex;
     globalIsIndex.reserve(primalDofMap.getLocalDofs());
     localIsIndex.reserve(primalDofMap.getLocalDofs());
 
     {
-      int counter = 0;
-      for (map<DegreeOfFreedom, MultiIndex>::iterator it = primalDofMap[feSpace].getMap().begin();
-	   it != primalDofMap[feSpace].getMap().end(); ++it) {
-	for (int i = 0; i < nComponents; i++) {
-	  globalIsIndex.push_back(it->second.local * nComponents + i);
-	  localIsIndex.push_back(counter++);
+      int cnt = 0;
+      for (unsigned int i = 0; i < feSpaces.size(); i++) {
+	map<DegreeOfFreedom, MultiIndex>& dofMap = 
+	  primalDofMap[feSpaces[i]].getMap();
+	for (map<DegreeOfFreedom, MultiIndex>::iterator it = dofMap.begin();
+	     it != dofMap.end(); ++it) {
+	  globalIsIndex.push_back(primalDofMap.getMatIndex(i, it->first));
+	  localIsIndex.push_back(cnt++);
 	}
       }
+
+      TEST_EXIT_DBG(cnt == primalDofMap.getLocalDofs())("Should not happen!\n");
     }
     
     IS globalIs, localIs;
@@ -825,21 +825,19 @@ namespace AMDiS {
 
     // === And copy from PETSc local vectors to the DOF vectors. ===
 
-    for (int i = 0; i < nComponents; i++) {
+    int cnt = 0;
+    for (int i = 0; i < vec.getSize(); i++) {
       DOFVector<double>& dofVec = *(vec.getDOFVector(i));
 
-      for (map<DegreeOfFreedom, MultiIndex>::iterator it = localDofMap[feSpace].getMap().begin();
-	   it != localDofMap[feSpace].getMap().end(); ++it) {
+      for (map<DegreeOfFreedom, MultiIndex>::iterator it = localDofMap[feSpaces[i]].getMap().begin();
+	   it != localDofMap[feSpaces[i]].getMap().end(); ++it) {
 	int petscIndex = localDofMap.mapLocal(it->first, i);
 	dofVec[it->first] = localSolB[petscIndex];
       }
 
-      int counter = 0;
-      for (map<DegreeOfFreedom, MultiIndex>::iterator it = primalDofMap[feSpace].getMap().begin();
-	   it != primalDofMap[feSpace].getMap().end(); ++it) {
-	dofVec[it->first] = localSolPrimal[counter * nComponents + i];
-	counter++;
-      }
+      for (map<DegreeOfFreedom, MultiIndex>::iterator it = primalDofMap[feSpaces[i]].getMap().begin();
+	   it != primalDofMap[feSpaces[i]].getMap().end(); ++it)
+	dofVec[it->first] = localSolPrimal[cnt++];
     }
 
     VecRestoreArray(vec_sol_b, &localSolB);
@@ -852,13 +850,10 @@ namespace AMDiS {
   {
     FUNCNAME("PetscSolverFeti::fillPetscMatrix()");   
 
-    vector<const FiniteElemSpace*> feSpaces = getFeSpaces(mat);
-
-    const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
-    nComponents = mat->getSize();
-
     // === Create all sets and indices. ===
 
+    vector<const FiniteElemSpace*> feSpaces = getFeSpaces(mat);
+
     primalDofMap.init(mpiComm, feSpaces, true, true);
     dualDofMap.init(mpiComm, feSpaces, false, false);
     lagrangeMap.init(mpiComm, feSpaces, true, true);
@@ -943,6 +938,7 @@ namespace AMDiS {
     // === Traverse all sequentially created matrices and add the values to ===
     // === the global PETSc matrices.                                       ===
 
+    int nComponents = mat->getSize();
     for (int i = 0; i < nComponents; i++) {
       for (int j = 0; j < nComponents; j++) {
 	if (!(*mat)[i][j])
@@ -955,7 +951,7 @@ namespace AMDiS {
 	for (cursor_type cursor = begin<row>((*mat)[i][j]->getBaseMatrix()), 
 	       cend = end<row>((*mat)[i][j]->getBaseMatrix()); cursor != cend; ++cursor) {
 
-	  bool rowPrimal = isPrimal(feSpace, *cursor);
+	  bool rowPrimal = isPrimal(feSpaces[i], *cursor);
   
 	  cols.clear();
 	  colsOther.clear();
@@ -972,7 +968,7 @@ namespace AMDiS {
 	  for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); 
 	       icursor != icend; ++icursor) {
 
-	    bool colPrimal = primalDofMap[feSpace].isSet(col(*icursor));
+	    bool colPrimal = isPrimal(feSpaces[j], col(*icursor));
 
 	    if (colPrimal) {
 	      if (rowPrimal) {
@@ -996,29 +992,29 @@ namespace AMDiS {
 	    // === For preconditioner ===
 
 	    if (!rowPrimal && !colPrimal) {
-	      int rowIndex = localDofMap[feSpace][*cursor].local;
-	      int colIndex = localDofMap[feSpace][col(*icursor)].local;
+	      int rowIndex = localDofMap[feSpaces[i]][*cursor].local;
+	      int colIndex = localDofMap[feSpaces[j]][col(*icursor)].local;
 		
-	      if (rowIndex < nLocalInterior[feSpace]) {
-		if (colIndex < nLocalInterior[feSpace]) {
+	      if (rowIndex < nLocalInterior[feSpaces[i]]) {
+		if (colIndex < nLocalInterior[feSpaces[j]]) {
 		  int colIndex2 = localDofMap.mapLocal(col(*icursor), j);
 		  colsLocal.push_back(colIndex2);
 		  valuesLocal.push_back(value(*icursor));
 		} else {
 		  int colIndex2 = 
-		    (localDofMap[feSpace][col(*icursor)].local - nLocalInterior[feSpace]) *
+		    (localDofMap[feSpaces[j]][col(*icursor)].local - nLocalInterior[feSpaces[j]]) *
 		    nComponents + j;
 
 		  colsLocalOther.push_back(colIndex2);
 		  valuesLocalOther.push_back(value(*icursor));
 		}
 	      } else {
-		if (colIndex < nLocalInterior[feSpace]) {
+		if (colIndex < nLocalInterior[feSpaces[j]]) {
 		  int colIndex2 = localDofMap.mapLocal(col(*icursor), j);
 		  colsLocalOther.push_back(colIndex2);
 		  valuesLocalOther.push_back(value(*icursor));
 		} else {
-		  int colIndex2 = (localDofMap[feSpace][col(*icursor)].local - nLocalInterior[feSpace]) *
+		  int colIndex2 = (localDofMap[feSpaces[j]][col(*icursor)].local - nLocalInterior[feSpaces[j]]) *
 		    nComponents + j;
 
 		  colsLocal.push_back(colIndex2);
@@ -1034,11 +1030,9 @@ namespace AMDiS {
 	  // === Set matrix values. ===
 
 	  if (rowPrimal) {
-	    int rowIndex = 
-	      primalDofMap[feSpace][*cursor].local * nComponents + i;
-
+	    int rowIndex = primalDofMap.getMatIndex(i, *cursor);
 	    for (unsigned int k = 0; k < cols.size(); k++)
-	      cols[k] = primalDofMap[feSpace][cols[k]].local * nComponents + j;
+	      cols[k] = primalDofMap.getMatIndex(j, cols[k]);
 
 	    MatSetValues(mat_primal_primal, 1, &rowIndex, cols.size(),
 			 &(cols[0]), &(values[0]), ADD_VALUES);
@@ -1061,10 +1055,8 @@ namespace AMDiS {
 
 	    if (colsOther.size()) {
 	      int globalRowIndex = localDofMap.mapGlobal(*cursor, i);
-
 	      for (unsigned int k = 0; k < colsOther.size(); k++)
-		colsOther[k] = 
-		  primalDofMap[feSpace][colsOther[k]].local * nComponents + j;
+		colsOther[k] = primalDofMap.getMatIndex(j, colsOther[k]);
 
   	      MatSetValues(mat_b_primal, 1, &globalRowIndex, colsOther.size(),
   			   &(colsOther[0]), &(valuesOther[0]), ADD_VALUES);
@@ -1077,10 +1069,10 @@ namespace AMDiS {
 	    switch (fetiPreconditioner) {
 	    case FETI_DIRICHLET:
 	      {
-		int rowIndex = localDofMap[feSpace][*cursor].local;
+		int rowIndex = localDofMap[feSpaces[i]][*cursor].local;
 		
-		if (rowIndex < nLocalInterior[feSpace]) {
-		  int rowIndex2 = localDofMap[feSpace][*cursor].local * nComponents + i;
+		if (rowIndex < nLocalInterior[feSpaces[i]]) {
+		  int rowIndex2 = localDofMap[feSpaces[i]][*cursor].local * nComponents + i;
 		  
 		  MatSetValues(mat_interior_interior, 1, &rowIndex2, colsLocal.size(),
 			       &(colsLocal[0]), &(valuesLocal[0]), INSERT_VALUES);
@@ -1090,7 +1082,7 @@ namespace AMDiS {
 				 &(colsLocalOther[0]), &(valuesLocalOther[0]), INSERT_VALUES);
 		} else {
 		  int rowIndex2 = 
-		    (localDofMap[feSpace][*cursor].local - nLocalInterior[feSpace]) * nComponents + i;
+		    (localDofMap[feSpaces[i]][*cursor].local - nLocalInterior[feSpaces[i]]) * nComponents + i;
 		  
 		  MatSetValues(mat_duals_duals, 1, &rowIndex2, colsLocal.size(),
 			       &(colsLocal[0]), &(valuesLocal[0]), INSERT_VALUES);
@@ -1105,11 +1097,11 @@ namespace AMDiS {
 
 	    case FETI_LUMPED:
 	      {
-		int rowIndex = localDofMap[feSpace][*cursor].local;
+		int rowIndex = localDofMap[feSpaces[i]][*cursor].local;
 		
-		if (rowIndex >= nLocalInterior[feSpace]) {
+		if (rowIndex >= nLocalInterior[feSpaces[i]]) {
 		  int rowIndex2 = 
-		    (localDofMap[feSpace][*cursor].local - nLocalInterior[feSpace]) * nComponents + i;
+		    (localDofMap[feSpaces[i]][*cursor].local - nLocalInterior[feSpaces[i]]) * nComponents + i;
 		  
 		  MatSetValues(mat_duals_duals, 1, &rowIndex2, colsLocal.size(),
 			       &(colsLocal[0]), &(valuesLocal[0]), INSERT_VALUES);		
@@ -1187,8 +1179,6 @@ namespace AMDiS {
     FUNCNAME("PetscSolverFeti::fillPetscRhs()");
 
     vector<const FiniteElemSpace*> feSpaces = getFeSpaces(vec);
-    const FiniteElemSpace *feSpace = meshDistributor->getFeSpace(0);
-    int nComponents = vec->getSize();
 
     VecCreateMPI(PETSC_COMM_WORLD, 
 		 localDofMap.getRankDofs(), localDofMap.getOverallDofs(), &f_b);
@@ -1196,14 +1186,13 @@ namespace AMDiS {
 		 primalDofMap.getRankDofs(), primalDofMap.getOverallDofs(),
 		 &f_primal);
     
-    for (int i = 0; i < nComponents; i++) {
+    for (unsigned int i = 0; i < feSpaces.size(); i++) {
       DOFVector<double>::Iterator dofIt(vec->getDOFVector(i), USED_DOFS);
       for (dofIt.reset(); !dofIt.end(); ++dofIt) {
 	int index = dofIt.getDOFIndex();
-	if (isPrimal(feSpace, index)) {
-	  index = primalDofMap[feSpace][index].local * nComponents + i;
-	  double value = *dofIt;
-	  VecSetValues(f_primal, 1, &index, &value, ADD_VALUES);
+	if (isPrimal(feSpaces[i], index)) {
+	  index = primalDofMap.getMatIndex(i, index);
+	  VecSetValue(f_primal, index, *dofIt, ADD_VALUES);
 	} else {
 	  index = localDofMap.mapGlobal(index, i);
 	  VecSetValue(f_b, index, *dofIt, INSERT_VALUES);
diff --git a/AMDiS/src/parallel/PetscSolverFeti.h b/AMDiS/src/parallel/PetscSolverFeti.h
index b9d91767..a2dcadd2 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.h
+++ b/AMDiS/src/parallel/PetscSolverFeti.h
@@ -151,9 +151,6 @@ namespace AMDiS {
     }
 
   protected:
-    /// Number of components in the PDE to be solved.
-    int nComponents;
-
     /// Mapping from primal DOF indices to a global index of primals.
     FeSpaceData<GlobalDofMap> primalDofMap;
 
-- 
GitLab