From ec239f4ea7369a25118869fe7d3ccda60b77d78e Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Thu, 4 Sep 2008 07:29:47 +0000
Subject: [PATCH] * This and that

---
 AMDiS/compositeFEM/src/SubElementAssembler.cc |   4 +-
 AMDiS/compositeFEM/src/SubElementAssembler.h  |   4 +-
 AMDiS/src/DOFMatrix.cc                        |  18 +-
 AMDiS/src/DOFMatrix.h                         |  23 ++-
 AMDiS/src/ProblemVec.cc                       | 157 +++++++++++++-----
 AMDiS/src/ProblemVec.h                        |  11 ++
 6 files changed, 162 insertions(+), 55 deletions(-)

diff --git a/AMDiS/compositeFEM/src/SubElementAssembler.cc b/AMDiS/compositeFEM/src/SubElementAssembler.cc
index 883f8c47..95f495f5 100644
--- a/AMDiS/compositeFEM/src/SubElementAssembler.cc
+++ b/AMDiS/compositeFEM/src/SubElementAssembler.cc
@@ -74,8 +74,6 @@ namespace AMDiS {
 						const ElInfo *elInfo, 
 						ElementVector *userVec)
   {
-    double corrFactor;
-
     /** 
      * Manipulate the quadratures of the SubAssemblers for subelement.
      */
@@ -88,7 +86,7 @@ namespace AMDiS {
      * determinant of element has been used instead of the determinant of subelement. Thus
      * the result must be corrected with respect to subelement.
      */
-    corrFactor = subElInfo->getDet() / fabs(elInfo->getDet());
+    double corrFactor = subElInfo->getDet() / fabs(elInfo->getDet());
     for (int i = 0; i < nRow; i++) {
       (*userVec)[i] *= corrFactor;
     }
diff --git a/AMDiS/compositeFEM/src/SubElementAssembler.h b/AMDiS/compositeFEM/src/SubElementAssembler.h
index e5697592..991b4b18 100644
--- a/AMDiS/compositeFEM/src/SubElementAssembler.h
+++ b/AMDiS/compositeFEM/src/SubElementAssembler.h
@@ -57,8 +57,8 @@ namespace AMDiS {
     MEMORY_MANAGED(SubElementAssembler);
 
     SubElementAssembler(Operator *op, 
-			const FiniteElemSpace *rowFESpace_,
-			const FiniteElemSpace *colFESpace_=NULL);
+			const FiniteElemSpace *rowFESpace,
+			const FiniteElemSpace *colFESpace = NULL);
 
     virtual ~SubElementAssembler()
     {
diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc
index 7a5c8f8a..aac17249 100644
--- a/AMDiS/src/DOFMatrix.cc
+++ b/AMDiS/src/DOFMatrix.cc
@@ -40,7 +40,7 @@ namespace AMDiS {
     }
 
     if (rowFESpace && rowFESpace->getAdmin())
-      (const_cast<DOFAdmin*>( rowFESpace->getAdmin()))->addDOFIndexed(this);
+      (const_cast<DOFAdmin*>(rowFESpace->getAdmin()))->addDOFIndexed(this);
 
     boundaryManager = NEW BoundaryManager;
     elementMatrix = NEW ElementMatrix(rowFESpace->getBasisFcts()->getNumber(),
@@ -284,9 +284,12 @@ namespace AMDiS {
   {
     int j;
 
-    for (j=0; j<static_cast<int>(matrix[a].size());j++) 
-      if (b==matrix[a][j].col) break;
-    if (j!=static_cast<int>(matrix[a].size())) matrix[a][j].col=c;
+    for (j = 0; j<static_cast<int>(matrix[a].size());j++) 
+      if (b == matrix[a][j].col) 
+	break;
+
+    if (j != static_cast<int>(matrix[a].size())) 
+      matrix[a][j].col = c;
   }
 
   void DOFMatrix::addSparseDOFEntry(double sign, int irow, 
@@ -386,12 +389,13 @@ namespace AMDiS {
       }
     }
     int usedSize = rowFESpace->getAdmin()->getUsedSize();
-    for(i=0; i < usedSize; i++) {
+    for (i = 0; i < usedSize; i++) {
       row = reinterpret_cast< std::vector<MatEntry>*>(&(matrix[i])); 
       int rowSize = static_cast<int>(row->size());
-      for (j=0; j < rowSize; j++) {
+      for (j = 0; j < rowSize; j++) {
 	col = (*row)[j].col;
-	if (entryUsed(i,j)) (*row)[j].col = newDOF[col];
+	if (entryUsed(i,j)) 
+	  (*row)[j].col = newDOF[col];
       }    
     }
   }
diff --git a/AMDiS/src/DOFMatrix.h b/AMDiS/src/DOFMatrix.h
index c331b2c7..deb7a3ac 100644
--- a/AMDiS/src/DOFMatrix.h
+++ b/AMDiS/src/DOFMatrix.h
@@ -211,7 +211,7 @@ namespace AMDiS {
      */
     DOFMatrix(const FiniteElemSpace* rowFESpace,
 	      const FiniteElemSpace* colFESpace,
-	      std::string n="");
+	      std::string n = "");
 
     /** \brief
      * Copy-Constructor
@@ -267,18 +267,22 @@ namespace AMDiS {
      * Returns true if matrix[a][b] has entry \ref NO_MORE_ENTRIES
      */
     inline bool noMoreEntries(DegreeOfFreedom a,int b) const {
-      return  (NO_MORE_ENTRIES==((matrix[a])[b]).col);
+      return (NO_MORE_ENTRIES == ((matrix[a])[b]).col);
     };
 
     /** \brief
      * Returns \ref coupleMatrix.
      */
-    inline bool isCoupleMatrix() { return coupleMatrix; };
+    inline bool isCoupleMatrix() { 
+      return coupleMatrix; 
+    };
 
     /** \brief
      * Returns \ref coupleMatrix.
      */
-    inline void setCoupleMatrix(bool c) { coupleMatrix = c; };
+    inline void setCoupleMatrix(bool c) { 
+      coupleMatrix = c; 
+    };
 
     /** \brief
      * Matrix-matrix multiplication.
@@ -437,6 +441,14 @@ namespace AMDiS {
       return matrix.size();
     };
 
+    /** \brief
+     * Returns the number of used rows (equal to number of used DOFs in
+     * the row FE space).
+     */
+    inline int getUsedSize() const {
+      return rowFESpace->getAdmin()->getUsedSize();
+    };
+
     /** \brief
      * Returns number of cols. For that, the function iteratos over all
      * rows and searchs for the entry with the highest col number.
@@ -453,7 +465,8 @@ namespace AMDiS {
 	}
       }
 
-      return max;
+      // Add one to the maximum value, because the indeces start with 0.
+      return max + 1;
     };
 
     /** \brief
diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc
index ea9ad47a..3ce3acd3 100644
--- a/AMDiS/src/ProblemVec.cc
+++ b/AMDiS/src/ProblemVec.cc
@@ -12,6 +12,7 @@
 #include "FileWriter.h"
 #include "CoarseningManager.h"
 #include "RefinementManager.h"
+#include "DualTraverse.h"
 #include "Mesh.h"
 #include "OEMSolver.h"
 #include "Preconditioner.h"
@@ -271,8 +272,6 @@ namespace AMDiS {
   {
     FUNCNAME("ProblemVec::createMatricesAndVectors()");
 
-    int i;
-
     // === create vectors and system matrix ===
 
     systemMatrix_ = NEW Matrix<DOFMatrix*>(nComponents, nComponents);
@@ -282,7 +281,7 @@ namespace AMDiS {
 
     char number[10];
     std::string numberedName;
-    for (i = 0; i < nComponents; i++) {
+    for (int i = 0; i < nComponents; i++) {
       (*systemMatrix_)[i][i] = NEW DOFMatrix(componentSpaces[i], 
 					     componentSpaces[i], "A_ii");
       (*systemMatrix_)[i][i]->setCoupleMatrix(false);
@@ -700,8 +699,6 @@ namespace AMDiS {
 #pragma omp parallel for 
 #endif
     for (i = 0; i < nComponents; i++) {
-      const BasisFunction *basisFcts = componentSpaces[i]->getBasisFcts();
-
       for (int j = 0; j < nComponents; j++) {
 	// Only if this variable is true, the current matrix will be assembled.	
 	bool assembleMatrix = true;
@@ -729,43 +726,21 @@ namespace AMDiS {
 	if (assembleMatrix && matrix->getBoundaryManager())
 	  matrix->getBoundaryManager()->initMatrix(matrix);
 
-	BoundaryType *bound = NULL;
-	if (useGetBound_) {
-	  bound = GET_MEMORY(BoundaryType, basisFcts->getNumber());
-	}
-	
-	TraverseStack stack;
-	ElInfo *elInfo = stack.traverseFirst(componentMeshes[i], -1, assembleFlag);
-	
-	while (elInfo) {
-	  if (useGetBound_) {
-	    basisFcts->getBound(elInfo, bound);
-	  }
-	  
-	  if (assembleMatrix) {
-	    matrix->assemble(1.0, elInfo, bound);
-	    
-	    if (matrix->getBoundaryManager()) {
-	      matrix->
-		getBoundaryManager()->
-		fillBoundaryConditions(elInfo, matrix);
-	    }		      
-	  }
-	  
-	  if (i == j) {
-	    rhs_->getDOFVector(i)->assemble(1.0, elInfo, bound);
-	  }
-	  
-	  elInfo = stack.traverseNext(elInfo);
+	if (componentSpaces[i] == componentSpaces[j]) {
+	  assembleOnOneMesh(componentSpaces[i],
+			    assembleFlag,
+			    assembleMatrix ? matrix : NULL,
+			    (i == j) ? rhs_->getDOFVector(i) : NULL);
+	} else {
+	  assembleOnDifMeshes(componentSpaces[i], componentSpaces[j],
+			      assembleFlag,
+			      assembleMatrix ? matrix : NULL,
+			      (i == j) ? rhs_->getDOFVector(i) : NULL);	  
 	}
-	
+
 	if (assembleMatrix && matrix->getBoundaryManager())
 	  matrix->getBoundaryManager()->exitMatrix(matrix);	  
 	
-	if (useGetBound_) {
-	  FREE_MEMORY(bound, BoundaryType, basisFcts->getNumber());
-	}	  
-	
 	assembledMatrix_[i][j] = true;
       }
 
@@ -956,6 +931,112 @@ namespace AMDiS {
 	addBoundaryCondition(periodic);
   }
 
+  void ProblemVec::assembleOnOneMesh(FiniteElemSpace *feSpace, Flag assembleFlag,
+				     DOFMatrix *matrix, DOFVector<double> *vector)
+  {
+    Mesh *mesh = feSpace->getMesh();
+    const BasisFunction *basisFcts = feSpace->getBasisFcts();
+
+    BoundaryType *bound = NULL;
+    if (useGetBound_) {
+      bound = GET_MEMORY(BoundaryType, basisFcts->getNumber());
+    }
+
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, assembleFlag);
+    
+    while (elInfo) {
+      if (useGetBound_) {
+	basisFcts->getBound(elInfo, bound);
+      }
+      
+      if (matrix) {
+	matrix->assemble(1.0, elInfo, bound);
+	
+	if (matrix->getBoundaryManager()) {
+	  matrix->getBoundaryManager()->
+	    fillBoundaryConditions(elInfo, matrix);
+	}		      
+      }
+      
+      if (vector) {
+	vector->assemble(1.0, elInfo, bound);
+      }
+      
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+    if (useGetBound_) {
+      FREE_MEMORY(bound, BoundaryType, basisFcts->getNumber());
+    }	     
+  }
+
+  void ProblemVec::assembleOnDifMeshes(FiniteElemSpace *rowFeSpace, FiniteElemSpace *colFeSpace,
+				       Flag assembleFlag,
+				       DOFMatrix *matrix, DOFVector<double> *vector)
+  {
+    Mesh *rowMesh = rowFeSpace->getMesh();
+    Mesh *colMesh = colFeSpace->getMesh();
+
+    const BasisFunction *basisFcts = rowFeSpace->getBasisFcts();
+    BoundaryType *bound = NULL;
+    if (useGetBound_) {
+      bound = GET_MEMORY(BoundaryType, basisFcts->getNumber());
+    }
+
+    DualTraverse dualTraverse;
+    ElInfo *rowElInfo, *colElInfo;
+    ElInfo *largeElInfo, *smallElInfo;
+
+    bool cont = dualTraverse.traverseFirst(rowMesh, colMesh, -1, -1,
+					   assembleFlag, assembleFlag,
+					   &rowElInfo, &colElInfo,
+					   &smallElInfo, &largeElInfo);
+    while (cont) {
+      Element *rowElem = rowElInfo->getElement();
+      Element *colElem = colElInfo->getElement();
+
+      if (rowElInfo->getLevel() != colElInfo->getLevel()) {
+	if (smallElInfo == rowElInfo) 
+	  std::cout << "Row = small\n";
+	else
+	  std::cout << "Row = large\n";
+
+	if (largeElInfo == colElInfo) 
+	  std::cout << "Col = large\n";
+	else
+	  std::cout << "Col = small\n";
+
+
+	ERROR_EXIT("KOMMT GLEICH!\n");
+      }
+
+      if (useGetBound_) {
+	basisFcts->getBound(rowElInfo, bound);
+      }
+      
+      if (matrix) {
+	matrix->assemble(1.0, rowElInfo, bound);
+	
+	if (matrix->getBoundaryManager()) {
+	  matrix->getBoundaryManager()->
+	    fillBoundaryConditions(rowElInfo, matrix);
+	}		      
+      }
+      
+      if (vector) {
+	vector->assemble(1.0, rowElInfo, bound);
+      }
+
+      cont = dualTraverse.traverseNext(&rowElInfo, &colElInfo,
+				       &smallElInfo, &largeElInfo);
+    }
+
+    if (useGetBound_) {
+      FREE_MEMORY(bound, BoundaryType, basisFcts->getNumber());
+    }
+  }
+
   void ProblemVec::writeResidualMesh(AdaptInfo *adaptInfo, const std::string name)
   {
     FUNCNAME("ProblemVec::writeResidualMesh()");
diff --git a/AMDiS/src/ProblemVec.h b/AMDiS/src/ProblemVec.h
index 6dca6598..6d510825 100644
--- a/AMDiS/src/ProblemVec.h
+++ b/AMDiS/src/ProblemVec.h
@@ -289,6 +289,17 @@ namespace AMDiS {
     inline void allowFirstRefinement() {
       allowFirstRef_ = true;
     }; 
+
+    /** \brief
+     * This function assembles a DOFMatrix and a DOFVector for the case,
+     * the meshes from row and col FE-space are equal.
+     */
+    void assembleOnOneMesh(FiniteElemSpace *feSpace, Flag assembleFlag,
+			   DOFMatrix *matrix, DOFVector<double> *vector);
+
+    void assembleOnDifMeshes(FiniteElemSpace *rowFeSpace, FiniteElemSpace *colFeSpace,
+			     Flag assembleFlag,
+			     DOFMatrix *matrix, DOFVector<double> *vector);
   
     // ===== getting-methods ======================================================
 
-- 
GitLab