From 479286fcb3fbb8d0b900edad2286ad934903be42 Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Thu, 17 Mar 2011 15:13:30 +0000
Subject: [PATCH] Added parallel field split preconditioner for the Schur
 complement approach, part II.

---
 AMDiS/src/Makefile.am             |  2 +
 AMDiS/src/Makefile.in             | 20 +++++++--
 AMDiS/src/parallel/PetscSolver.cc | 67 +++++--------------------------
 AMDiS/src/parallel/PetscSolver.h  |  1 +
 4 files changed, 28 insertions(+), 62 deletions(-)

diff --git a/AMDiS/src/Makefile.am b/AMDiS/src/Makefile.am
index 43a9d80c..5e008925 100644
--- a/AMDiS/src/Makefile.am
+++ b/AMDiS/src/Makefile.am
@@ -21,6 +21,7 @@ if USE_PARALLEL_DOMAIN_AMDIS
   parallel/ParallelProblemStatBase.cc \
   parallel/ParMetisPartitioner.cc \
   parallel/PetscSolver.cc \
+  parallel/PetscSolverSchur.cc \
   parallel/StdMpi.cc \
   parallel/ZoltanPartitioner.cc
   libamdis_la_CXXFLAGS += -DHAVE_PARALLEL_DOMAIN_AMDIS=1
@@ -247,6 +248,7 @@ parallel/ParallelDebug.h \
 parallel/ParallelProblemStatBase.h \
 parallel/ParMetisPartitioner.h \
 parallel/PetscSolver.h \
+parallel/PetscSolverSchur.h \
 parallel/StdMpi.h \
 parallel/ZoltanPartitioner.h \
 reinit/BoundaryElementDist.h \
diff --git a/AMDiS/src/Makefile.in b/AMDiS/src/Makefile.in
index 63a8be76..d69efeef 100644
--- a/AMDiS/src/Makefile.in
+++ b/AMDiS/src/Makefile.in
@@ -47,6 +47,7 @@ host_triplet = @host@
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@  parallel/ParallelProblemStatBase.cc \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@  parallel/ParMetisPartitioner.cc \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@  parallel/PetscSolver.cc \
+@USE_PARALLEL_DOMAIN_AMDIS_TRUE@  parallel/PetscSolverSchur.cc \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@  parallel/StdMpi.cc \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@  parallel/ZoltanPartitioner.cc
 
@@ -90,10 +91,11 @@ am__libamdis_la_SOURCES_DIST = parallel/ElementObjectData.cc \
 	parallel/MeshPartitioner.cc parallel/MpiHelper.cc \
 	parallel/ParallelDebug.cc parallel/ParallelProblemStatBase.cc \
 	parallel/ParMetisPartitioner.cc parallel/PetscSolver.cc \
-	parallel/StdMpi.cc parallel/ZoltanPartitioner.cc AdaptBase.cc \
-	AdaptInfo.cc AdaptInstationary.cc AdaptStationary.cc \
-	Assembler.cc BasisFunction.cc Boundary.cc BoundaryManager.cc \
-	Cholesky.cc CoarseningManager.cc CoarseningManager1d.cc \
+	parallel/PetscSolverSchur.cc parallel/StdMpi.cc \
+	parallel/ZoltanPartitioner.cc AdaptBase.cc AdaptInfo.cc \
+	AdaptInstationary.cc AdaptStationary.cc Assembler.cc \
+	BasisFunction.cc Boundary.cc BoundaryManager.cc Cholesky.cc \
+	CoarseningManager.cc CoarseningManager1d.cc \
 	CoarseningManager2d.cc CoarseningManager3d.cc \
 	ComponentTraverseInfo.cc CreatorMap.cc DOFAdmin.cc \
 	DOFIndexed.cc DOFMatrix.cc DOFVector.cc Debug.cc \
@@ -135,6 +137,7 @@ am__libamdis_la_SOURCES_DIST = parallel/ElementObjectData.cc \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@	libamdis_la-ParallelProblemStatBase.lo \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@	libamdis_la-ParMetisPartitioner.lo \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@	libamdis_la-PetscSolver.lo \
+@USE_PARALLEL_DOMAIN_AMDIS_TRUE@	libamdis_la-PetscSolverSchur.lo \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@	libamdis_la-StdMpi.lo \
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@	libamdis_la-ZoltanPartitioner.lo
 am__objects_2 = $(am__objects_1)
@@ -570,6 +573,7 @@ parallel/ParallelDebug.h \
 parallel/ParallelProblemStatBase.h \
 parallel/ParMetisPartitioner.h \
 parallel/PetscSolver.h \
+parallel/PetscSolverSchur.h \
 parallel/StdMpi.h \
 parallel/ZoltanPartitioner.h \
 reinit/BoundaryElementDist.h \
@@ -874,6 +878,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parametric.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PeriodicBC.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PetscSolver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PetscSolverSchur.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PngWriter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PovrayWriter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemImplicit.Plo@am__quote@
@@ -1029,6 +1034,13 @@ libamdis_la-PetscSolver.lo: parallel/PetscSolver.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-PetscSolver.lo `test -f 'parallel/PetscSolver.cc' || echo '$(srcdir)/'`parallel/PetscSolver.cc
 
+libamdis_la-PetscSolverSchur.lo: parallel/PetscSolverSchur.cc
+@am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-PetscSolverSchur.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-PetscSolverSchur.Tpo" -c -o libamdis_la-PetscSolverSchur.lo `test -f 'parallel/PetscSolverSchur.cc' || echo '$(srcdir)/'`parallel/PetscSolverSchur.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-PetscSolverSchur.Tpo" "$(DEPDIR)/libamdis_la-PetscSolverSchur.Plo"; else rm -f "$(DEPDIR)/libamdis_la-PetscSolverSchur.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='parallel/PetscSolverSchur.cc' object='libamdis_la-PetscSolverSchur.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-PetscSolverSchur.lo `test -f 'parallel/PetscSolverSchur.cc' || echo '$(srcdir)/'`parallel/PetscSolverSchur.cc
+
 libamdis_la-StdMpi.lo: parallel/StdMpi.cc
 @am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-StdMpi.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-StdMpi.Tpo" -c -o libamdis_la-StdMpi.lo `test -f 'parallel/StdMpi.cc' || echo '$(srcdir)/'`parallel/StdMpi.cc; \
 @am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-StdMpi.Tpo" "$(DEPDIR)/libamdis_la-StdMpi.Plo"; else rm -f "$(DEPDIR)/libamdis_la-StdMpi.Tpo"; exit 1; fi
diff --git a/AMDiS/src/parallel/PetscSolver.cc b/AMDiS/src/parallel/PetscSolver.cc
index b8e5463e..30ff7a35 100644
--- a/AMDiS/src/parallel/PetscSolver.cc
+++ b/AMDiS/src/parallel/PetscSolver.cc
@@ -108,9 +108,8 @@ namespace AMDiS {
 	  int colIndex = globalColDof * dispMult + dispAddCol;
 
 	  // Ignore all zero entries, expect it is a diagonal entry.
-	  //	  if (value(*icursor) == 0.0 && globalRowDof != globalColDof)
-// 	  if (value(*icursor) == 0.0 && rowIndex != colIndex)
-// 	    continue;
+ 	  if (value(*icursor) == 0.0 && rowIndex != colIndex)
+ 	    continue;
 
 	  if (!periodicCol) {
 	    // Calculate the exact position of the column index in the PETSc matrix.
@@ -182,8 +181,8 @@ namespace AMDiS {
 	  int globalColDof = meshDistributor->mapLocalToGlobal(col(*icursor));
 
 	  // Ignore all zero entries, expect it is a diagonal entry.
-// 	  if (value(*icursor) == 0.0 && globalRowDof != globalColDof)
-// 	    continue;
+ 	  if (value(*icursor) == 0.0 && globalRowDof != globalColDof)
+ 	    continue;
 
 
 	  // === Add all periodic associations of both, the row and the column ===
@@ -410,7 +409,7 @@ namespace AMDiS {
 	      int petscColIdx = 
 		meshDistributor->mapLocalToGlobal(col(*icursor)) * nComponents + j;
 	      
-	      //	      if (value(*icursor) != 0.0 || petscRowIdx == petscColIdx) {
+	      if (value(*icursor) != 0.0 || petscRowIdx == petscColIdx) {
 		// The row DOF is a rank DOF, if also the column is a rank DOF, 
 		// increment the d_nnz values for this row, otherwise the o_nnz value.
 		if (petscColIdx >= meshDistributor->getRstart() * nComponents && 
@@ -418,7 +417,7 @@ namespace AMDiS {
 		  d_nnz[localPetscRowIdx]++;
 		else
 		  o_nnz[localPetscRowIdx]++;
-		//	      }    
+	      }    
 	    }
 	  } else {
 	    // === The current row DOF is not a rank dof, i.e., it will be created ===
@@ -431,13 +430,13 @@ namespace AMDiS {
 	    
 	    for (icursor_type icursor = begin<nz>(cursor), 
 		   icend = end<nz>(cursor); icursor != icend; ++icursor) {
-	      //	      if (value(*icursor) != 0.0) {
+	      if (value(*icursor) != 0.0) {
 		int petscColIdx = 
 		  meshDistributor->mapLocalToGlobal(col(*icursor)) * nComponents + j;
 		
 		sendMatrixEntry[sendToRank].
 		  push_back(make_pair(petscRowIdx, petscColIdx));
-		//	      }
+	      }
 	    }
 	    
 	  } // if (isRankDof[*cursor]) ... else ...
@@ -603,55 +602,7 @@ namespace AMDiS {
 
     // Do not delete the solution vector, use it for the initial guess.
     //    KSPSetInitialGuessNonzero(solver, PETSC_TRUE);
-
-    
-    KSPCreate(PETSC_COMM_WORLD, &solver);
-    KSPGetPC(solver, &pc);
-    PCSetType(pc, PCFIELDSPLIT);
-
-#if 0
-    typedef map<int, DofContainer> RankToDofContainer;
-    typedef map<DegreeOfFreedom, bool> DofIndexToBool;
-
-    std::set<DegreeOfFreedom> boundaryDofsSet;
-    std::set<DegreeOfFreedom> boundaryLocalDofs;
-    RankToDofContainer& sendDofs = meshDistributor->getSendDofs();
-    for (RankToDofContainer::iterator rankIt = sendDofs.begin(); rankIt != sendDofs.end(); ++rankIt)
-      for (DofContainer::iterator dofIt = rankIt->second.begin(); dofIt != rankIt->second.end(); ++dofIt) {
-	boundaryLocalDofs.insert(**dofIt);
-
-	for (int i = 0; i < nComponents; i++)
-	  boundaryDofsSet.insert(meshDistributor->mapLocalToGlobal(**dofIt) * nComponents + i);
-      }
-
-    vector<DegreeOfFreedom> boundaryDofs(boundaryDofsSet.begin(), boundaryDofsSet.end());
-
-    std::set<DegreeOfFreedom> otherBoundaryLocalDofs;
-    RankToDofContainer& recvDofs = meshDistributor->getRecvDofs();
-    for (RankToDofContainer::iterator rankIt = recvDofs.begin(); rankIt != recvDofs.end(); ++rankIt)
-      for (DofContainer::iterator dofIt = rankIt->second.begin(); dofIt != rankIt->second.end(); ++dofIt)
-	otherBoundaryLocalDofs.insert(**dofIt);
-
-    std::set<DegreeOfFreedom> interiorDofsSet;
-    DofIndexToBool& isRankDof = meshDistributor->getIsRankDof();
-    for (DofIndexToBool::iterator dofIt = isRankDof.begin(); dofIt != isRankDof.end(); ++dofIt)
-      if (dofIt->second && 
-	  boundaryLocalDofs.count(dofIt->first) == 0 && 
-	  otherBoundaryLocalDofs.count(dofIt->first) == 0)
-	for (int i = 0; i < nComponents; i++)	    
-	  interiorDofsSet.insert(meshDistributor->mapLocalToGlobal(dofIt->first) * nComponents + i);
-
-    vector<DegreeOfFreedom> interiorDofs(interiorDofsSet.begin(), interiorDofsSet.end());
-
-    IS interiorIs;
-    ISCreateGeneral(PETSC_COMM_WORLD, interiorDofs.size(), &(interiorDofs[0]), PETSC_COPY_VALUES, &interiorIs);
-    PCFieldSplitSetIS(pc, "interior", interiorIs);
-
-    IS boundaryIs;
-    ISCreateGeneral(PETSC_COMM_WORLD, boundaryDofs.size(), &(boundaryDofs[0]), PETSC_COPY_VALUES, &boundaryIs);
-    PCFieldSplitSetIS(pc, "boundary", boundaryIs);
-#endif
-
+   
     // === Run PETSc. ===
 
     KSPSolve(solver, petscRhsVec, petscSolVec);
diff --git a/AMDiS/src/parallel/PetscSolver.h b/AMDiS/src/parallel/PetscSolver.h
index c2ab9bda..7aeecbc9 100644
--- a/AMDiS/src/parallel/PetscSolver.h
+++ b/AMDiS/src/parallel/PetscSolver.h
@@ -77,6 +77,7 @@ namespace AMDiS {
     /// Use PETSc to solve the linear system of equations
     void solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo);
 
+  private:
     /// Is used to create a PETSc solver and preconditioner object. This function may
     /// be overridden to create some special PETSc solver.
     virtual void providePetscSolver(KSP &solver, PC &pc);
-- 
GitLab