Commit b3f8ed4c authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

* It is now possible to define a matrix to be assembled only once.

parent 73542a30
...@@ -56,23 +56,30 @@ namespace AMDiS { ...@@ -56,23 +56,30 @@ namespace AMDiS {
rowFESpace(rowFESpace_), rowFESpace(rowFESpace_),
colFESpace(colFESpace_) colFESpace(colFESpace_)
{ {
if(!colFESpace) colFESpace = rowFESpace; if (!colFESpace)
colFESpace = rowFESpace;
}; };
/** \brief /** \brief
* Returns \ref boundaryType. * Returns \ref boundaryType.
*/ */
inline BoundaryType getBoundaryType() { return boundaryType; }; inline BoundaryType getBoundaryType() {
return boundaryType;
};
/** \brief /** \brief
* Returns \ref rowFESpace. * Returns \ref rowFESpace.
*/ */
inline const FiniteElemSpace *getRowFESpace() { return rowFESpace; }; inline const FiniteElemSpace *getRowFESpace() {
return rowFESpace;
};
/** \brief /** \brief
* Returns \ref rowFESpace. * Returns \ref rowFESpace.
*/ */
inline const FiniteElemSpace *getColFESpace() { return colFESpace; }; inline const FiniteElemSpace *getColFESpace() {
return colFESpace;
};
virtual void initMatrix(DOFMatrix*) {}; virtual void initMatrix(DOFMatrix*) {};
...@@ -120,7 +127,9 @@ namespace AMDiS { ...@@ -120,7 +127,9 @@ namespace AMDiS {
* Returns whether the condition must be treated as dirichlet condition * Returns whether the condition must be treated as dirichlet condition
* while assemblage. * while assemblage.
*/ */
virtual bool isDirichlet() { return false; }; virtual bool isDirichlet() {
return false;
};
protected: protected:
/** \brief /** \brief
......
...@@ -104,43 +104,20 @@ namespace AMDiS { ...@@ -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) void BoundaryManager::initMatrix(DOFMatrix *matrix)
{ {
::std::map<BoundaryType, BoundaryCondition*>::iterator it; ::std::map<BoundaryType, BoundaryCondition*>::iterator it;
for(it = localBCs.begin(); it != localBCs.end(); ++it) { for (it = localBCs.begin(); it != localBCs.end(); ++it) {
if((*it).second) { if ((*it).second) {
if(!(*it).second->isDirichlet()) { if (!(*it).second->isDirichlet()) {
(*it).second->initMatrix(matrix); (*it).second->initMatrix(matrix);
} }
} }
} }
for(it = localBCs.begin(); it != localBCs.end(); ++it) { for (it = localBCs.begin(); it != localBCs.end(); ++it) {
if((*it).second) { if ((*it).second) {
if((*it).second->isDirichlet()) { if ((*it).second->isDirichlet()) {
(*it).second->initMatrix(matrix); (*it).second->initMatrix(matrix);
} }
} }
...@@ -150,9 +127,9 @@ namespace AMDiS { ...@@ -150,9 +127,9 @@ namespace AMDiS {
void BoundaryManager::exitMatrix(DOFMatrix *matrix) void BoundaryManager::exitMatrix(DOFMatrix *matrix)
{ {
::std::map<BoundaryType, BoundaryCondition*>::iterator it; ::std::map<BoundaryType, BoundaryCondition*>::iterator it;
for(it = localBCs.begin(); it != localBCs.end(); ++it) { for (it = localBCs.begin(); it != localBCs.end(); ++it) {
if((*it).second) { if ((*it).second) {
if(!(*it).second->isDirichlet()) { if (!(*it).second->isDirichlet()) {
(*it).second->exitMatrix(matrix); (*it).second->exitMatrix(matrix);
} }
} }
......
...@@ -125,9 +125,8 @@ namespace AMDiS { ...@@ -125,9 +125,8 @@ namespace AMDiS {
void DOFMatrix::clear() void DOFMatrix::clear()
{ {
int i; int mSize = static_cast<int>(matrix.size());
for (int i = 0; i < mSize; i++) {
for (i=0; i<static_cast<int>(matrix.size()); i++) {
matrix[i].resize(0); matrix[i].resize(0);
} }
return; return;
......
...@@ -669,8 +669,13 @@ namespace AMDiS { ...@@ -669,8 +669,13 @@ namespace AMDiS {
rhs_->getDOFVector(i)->set(0.0); rhs_->getDOFVector(i)->set(0.0);
for (int j = 0; j < numComponents_; j++) { for (int j = 0; j < numComponents_; j++) {
if ((*systemMatrix_)[i][j]) if ((*systemMatrix_)[i][j]) {
(*systemMatrix_)[i][j]->clear(); // 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 { ...@@ -680,12 +685,34 @@ namespace AMDiS {
for (int i = 0; i < numComponents_; i++) { for (int i = 0; i < numComponents_; i++) {
for (int j = 0; j < numComponents_; j++) { 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]; 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]) { if (componentMeshes_[i] != componentMeshes_[j]) {
ERROR_EXIT("not yet\n"); ERROR_EXIT("not yet\n");
} else { } else {
if (matrix && matrix->getBoundaryManager()) if (assembleMatrix && matrix->getBoundaryManager())
matrix->getBoundaryManager()->initMatrix(matrix); matrix->getBoundaryManager()->initMatrix(matrix);
elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag);
...@@ -694,7 +721,7 @@ namespace AMDiS { ...@@ -694,7 +721,7 @@ namespace AMDiS {
useGetBound_ ? useGetBound_ ?
componentSpaces_[i]->getBasisFcts()->getBound(elInfo, NULL) : componentSpaces_[i]->getBasisFcts()->getBound(elInfo, NULL) :
NULL; NULL;
if (matrix) { if (assembleMatrix) {
matrix->assemble(1.0, elInfo, bound); matrix->assemble(1.0, elInfo, bound);
if (matrix->getBoundaryManager()) { if (matrix->getBoundaryManager()) {
matrix-> matrix->
...@@ -708,14 +735,16 @@ namespace AMDiS { ...@@ -708,14 +735,16 @@ namespace AMDiS {
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
if (matrix && matrix->getBoundaryManager()) if (assembleMatrix && matrix->getBoundaryManager())
matrix->getBoundaryManager()->exitMatrix(matrix); matrix->getBoundaryManager()->exitMatrix(matrix);
} }
assembledMatrix_[i][j] = true;
} }
// fill boundary conditions // fill boundary conditions
if (rhs_->getDOFVector(i)->getBoundaryManager()) 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()) if (solution_->getDOFVector(i)->getBoundaryManager())
solution_->getDOFVector(i)->getBoundaryManager()->initVector(solution_->getDOFVector(i)); solution_->getDOFVector(i)->getBoundaryManager()->initVector(solution_->getDOFVector(i));
...@@ -734,6 +763,12 @@ namespace AMDiS { ...@@ -734,6 +763,12 @@ namespace AMDiS {
if (solution_->getDOFVector(i)->getBoundaryManager()) if (solution_->getDOFVector(i)->getBoundaryManager())
solution_->getDOFVector(i)->getBoundaryManager()->exitVector(solution_->getDOFVector(i)); 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", INFO(info_, 8)("buildAfterCoarsen needed %.5f seconds\n",
TIME_USED(first,clock())); TIME_USED(first,clock()));
......
...@@ -74,8 +74,20 @@ namespace AMDiS { ...@@ -74,8 +74,20 @@ namespace AMDiS {
{ {
GET_PARAMETER(0, name_ + "->components", "%d", &numComponents_); GET_PARAMETER(0, name_ + "->components", "%d", &numComponents_);
TEST_EXIT(numComponents_ > 0)("components not set!\n"); TEST_EXIT(numComponents_ > 0)("components not set!\n");
estimator_.resize(numComponents_, NULL); estimator_.resize(numComponents_, NULL);
marker_.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 /** \brief
...@@ -450,6 +462,10 @@ namespace AMDiS { ...@@ -450,6 +462,10 @@ namespace AMDiS {
rightPrecon_ = p; rightPrecon_ = p;
}; };
inline void setAssembleMatrixOnlyOnce(int i, int j, bool value = true) {
assembleMatrixOnlyOnce_[i][j] = value;
}
/** \} */ /** \} */
// ===== Serializable implementation ===== // ===== Serializable implementation =====
...@@ -529,6 +545,23 @@ namespace AMDiS { ...@@ -529,6 +545,23 @@ namespace AMDiS {
*/ */
Matrix<DOFMatrix*> *systemMatrix_; 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 /** \brief
* Matrix-vector multiplication * Matrix-vector multiplication
*/ */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment