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 {
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
......
......@@ -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);
}
}
......
......@@ -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;
......
......@@ -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()));
......
......@@ -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
*/
......
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