diff --git a/AMDiS/src/BoundaryCondition.h b/AMDiS/src/BoundaryCondition.h index 34626153b8d5012a41a93ddbae26dbce7a334de2..d07e2d6385a3ff761630d0115bd856b42853ea5f 100644 --- a/AMDiS/src/BoundaryCondition.h +++ b/AMDiS/src/BoundaryCondition.h @@ -56,23 +56,30 @@ namespace AMDiS { rowFESpace(rowFESpace_), colFESpace(colFESpace_) { - if(!colFESpace) colFESpace = rowFESpace; + if (!colFESpace) + colFESpace = rowFESpace; }; /** \brief * Returns \ref boundaryType. */ - inline BoundaryType getBoundaryType() { return boundaryType; }; + inline BoundaryType getBoundaryType() { + return boundaryType; + }; /** \brief * Returns \ref rowFESpace. */ - inline const FiniteElemSpace *getRowFESpace() { return rowFESpace; }; + inline const FiniteElemSpace *getRowFESpace() { + return rowFESpace; + }; /** \brief * Returns \ref rowFESpace. */ - inline const FiniteElemSpace *getColFESpace() { return colFESpace; }; + inline const FiniteElemSpace *getColFESpace() { + return colFESpace; + }; virtual void initMatrix(DOFMatrix*) {}; @@ -120,7 +127,9 @@ namespace AMDiS { * Returns whether the condition must be treated as dirichlet condition * while assemblage. */ - virtual bool isDirichlet() { return false; }; + virtual bool isDirichlet() { + return false; + }; protected: /** \brief diff --git a/AMDiS/src/BoundaryManager.cc b/AMDiS/src/BoundaryManager.cc index b28f95d0af510a36e941bc70b37a888982e3f22f..0a515bbd9397038754c5f75047fe486165989906 100644 --- a/AMDiS/src/BoundaryManager.cc +++ b/AMDiS/src/BoundaryManager.cc @@ -104,43 +104,20 @@ namespace AMDiS { } } - // void BoundaryManager::fillGlobalBoundVector(DOFVectorBase<BoundaryType> *bound) - // { - // int i; - // const BasisFunction *basFcts = bound->getFESpace()->getBasisFcts(); - // int numBasFcts = basFcts->getNumber(); - // TraverseStack stack; - // ElInfo *elInfo = stack.traverseFirst(bound->getFESpace()->getMesh(), - // -1, - // Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND); - // while(elInfo) { - // const DegreeOfFreedom *localIndices = - // basFcts->getLocalIndices(elInfo->getElement(), - // bound->getFESpace()->getAdmin(), - // NULL); - - // for(i = 0; i < numBasFcts; i++) { - // (*bound)[localIndices[i]] = elInfo->getBoundary(i); - // } - - // elInfo = stack.traverseNext(elInfo); - // } - // } - void BoundaryManager::initMatrix(DOFMatrix *matrix) { ::std::map<BoundaryType, BoundaryCondition*>::iterator it; - for(it = localBCs.begin(); it != localBCs.end(); ++it) { - if((*it).second) { - if(!(*it).second->isDirichlet()) { + for (it = localBCs.begin(); it != localBCs.end(); ++it) { + if ((*it).second) { + if (!(*it).second->isDirichlet()) { (*it).second->initMatrix(matrix); } } } - for(it = localBCs.begin(); it != localBCs.end(); ++it) { - if((*it).second) { - if((*it).second->isDirichlet()) { + for (it = localBCs.begin(); it != localBCs.end(); ++it) { + if ((*it).second) { + if ((*it).second->isDirichlet()) { (*it).second->initMatrix(matrix); } } @@ -150,9 +127,9 @@ namespace AMDiS { void BoundaryManager::exitMatrix(DOFMatrix *matrix) { ::std::map<BoundaryType, BoundaryCondition*>::iterator it; - for(it = localBCs.begin(); it != localBCs.end(); ++it) { - if((*it).second) { - if(!(*it).second->isDirichlet()) { + for (it = localBCs.begin(); it != localBCs.end(); ++it) { + if ((*it).second) { + if (!(*it).second->isDirichlet()) { (*it).second->exitMatrix(matrix); } } diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc index 5ee8198366286bccd511de35b3add3f367c347d3..af868e410538632da3aa12337a9acc6930a38266 100644 --- a/AMDiS/src/DOFMatrix.cc +++ b/AMDiS/src/DOFMatrix.cc @@ -125,9 +125,8 @@ namespace AMDiS { void DOFMatrix::clear() { - int i; - - for (i=0; i<static_cast<int>(matrix.size()); i++) { + int mSize = static_cast<int>(matrix.size()); + for (int i = 0; i < mSize; i++) { matrix[i].resize(0); } return; diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc index d92c48adb7b17a9dd2722ed9739940463b5e1897..89e17255465b8e4f336d6a7d8ebbd75e8a248bf0 100644 --- a/AMDiS/src/ProblemVec.cc +++ b/AMDiS/src/ProblemVec.cc @@ -669,8 +669,13 @@ namespace AMDiS { rhs_->getDOFVector(i)->set(0.0); for (int j = 0; j < numComponents_; j++) { - if ((*systemMatrix_)[i][j]) - (*systemMatrix_)[i][j]->clear(); + if ((*systemMatrix_)[i][j]) { + // The matrix should not be deleted, if it was assembled before + // and it is marked to be assembled only once. + if (!(assembleMatrixOnlyOnce_[i][j] && assembledMatrix_[i][j])) { + (*systemMatrix_)[i][j]->clear(); + } + } } } @@ -680,12 +685,34 @@ namespace AMDiS { for (int i = 0; i < numComponents_; i++) { for (int j = 0; j < numComponents_; j++) { + // Only if this variable is true, the current matrix will be assembled. + bool assembleMatrix = true; + // The DOFMatrix which should be assembled (or not, if assembleMatrix + // will be set to false). DOFMatrix *matrix = (*systemMatrix_)[i][j]; + // If the matrix was assembled before and it is marked to be assembled + // only once, it will not be assembled. + if (assembleMatrixOnlyOnce_[i][j] && assembledMatrix_[i][j]) { + assembleMatrix = false; + } + // If there is no DOFMatrix (e.g. if it is completly 0), do not assemble. + if (!matrix) { + assembleMatrix = false; + } + + // If the matrix should not be assembled, the rhs vector has to be considered. + // This will be only done, if i == j. So, if both is not true, we can jump + // to the next matrix. + if (!assembleMatrix && i != j) { + continue; + } + + if (componentMeshes_[i] != componentMeshes_[j]) { ERROR_EXIT("not yet\n"); } else { - if (matrix && matrix->getBoundaryManager()) + if (assembleMatrix && matrix->getBoundaryManager()) matrix->getBoundaryManager()->initMatrix(matrix); elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); @@ -694,7 +721,7 @@ namespace AMDiS { useGetBound_ ? componentSpaces_[i]->getBasisFcts()->getBound(elInfo, NULL) : NULL; - if (matrix) { + if (assembleMatrix) { matrix->assemble(1.0, elInfo, bound); if (matrix->getBoundaryManager()) { matrix-> @@ -708,14 +735,16 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } - if (matrix && matrix->getBoundaryManager()) + if (assembleMatrix && matrix->getBoundaryManager()) matrix->getBoundaryManager()->exitMatrix(matrix); } + + assembledMatrix_[i][j] = true; } // fill boundary conditions if (rhs_->getDOFVector(i)->getBoundaryManager()) - rhs_->getDOFVector(i)->getBoundaryManager()->initVector(rhs_->getDOFVector(i)); + rhs_->getDOFVector(i)->getBoundaryManager()->initVector(rhs_->getDOFVector(i)); if (solution_->getDOFVector(i)->getBoundaryManager()) solution_->getDOFVector(i)->getBoundaryManager()->initVector(solution_->getDOFVector(i)); @@ -734,6 +763,12 @@ namespace AMDiS { if (solution_->getDOFVector(i)->getBoundaryManager()) solution_->getDOFVector(i)->getBoundaryManager()->exitVector(solution_->getDOFVector(i)); } + + for (int i = 0; i < numComponents_; i++) { + // ::std::cout << "Vector: " << i << ::std::endl; + // rhs_->getDOFVector(i)->print(); + } + INFO(info_, 8)("buildAfterCoarsen needed %.5f seconds\n", TIME_USED(first,clock())); diff --git a/AMDiS/src/ProblemVec.h b/AMDiS/src/ProblemVec.h index dfc649e6dd59e4ea93ade77e70d77efd4b6ea7af..11222f5b529434820e0f036c788d3d84cd34cdec 100644 --- a/AMDiS/src/ProblemVec.h +++ b/AMDiS/src/ProblemVec.h @@ -74,8 +74,20 @@ namespace AMDiS { { GET_PARAMETER(0, name_ + "->components", "%d", &numComponents_); TEST_EXIT(numComponents_ > 0)("components not set!\n"); + estimator_.resize(numComponents_, NULL); marker_.resize(numComponents_, NULL); + + assembleMatrixOnlyOnce_.resize(numComponents_); + assembledMatrix_.resize(numComponents_); + for (int i = 0; i < numComponents_; i++) { + assembleMatrixOnlyOnce_[i].resize(numComponents_); + assembledMatrix_[i].resize(numComponents_); + for (int j = 0; j < numComponents_; j++) { + assembleMatrixOnlyOnce_[i][j] = false; + assembledMatrix_[i][j] = false; + } + } }; /** \brief @@ -450,6 +462,10 @@ namespace AMDiS { rightPrecon_ = p; }; + inline void setAssembleMatrixOnlyOnce(int i, int j, bool value = true) { + assembleMatrixOnlyOnce_[i][j] = value; + } + /** \} */ // ===== Serializable implementation ===== @@ -529,6 +545,23 @@ namespace AMDiS { */ Matrix<DOFMatrix*> *systemMatrix_; + /** \brief + * Some DOFMatrices of the systemMatrix may be assembled only once (for + * example if they are independent of the time or older solutions). If + * [i][j] of this field is set to true, the corresponding DOFMatrix will + * be assembled only once. All other matrices will be assembled at every + * time step. + */ + ::std::vector< ::std::vector< bool > > assembleMatrixOnlyOnce_; + + /** \brief + * If [i][j] of this field is set to true, the corresponding DOFMatrix of + * the systemMatrix_ has been assembled at least once. This field is used + * to determine, if assembling of a matrix can be ommitted, if it is set + * to be assembled only once. + */ + ::std::vector< ::std::vector< bool > > assembledMatrix_; + /** \brief * Matrix-vector multiplication */