From 92f468303351fc2c2c3438d07fbd40c099c38f67 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Tue, 23 Jun 2009 15:16:27 +0000 Subject: [PATCH] Periodic boundary condition work for higher elements. --- AMDiS/src/ElInfo2d.cc | 99 +++++++++++++++++++++++++++++++--------- AMDiS/src/PeriodicBC.cc | 23 ++-------- AMDiS/src/ProblemScal.cc | 6 +-- AMDiS/src/TimedObject.h | 39 ++++++++-------- 4 files changed, 103 insertions(+), 64 deletions(-) diff --git a/AMDiS/src/ElInfo2d.cc b/AMDiS/src/ElInfo2d.cc index 6f1accf3..fbd38c3f 100644 --- a/AMDiS/src/ElInfo2d.cc +++ b/AMDiS/src/ElInfo2d.cc @@ -77,31 +77,82 @@ namespace AMDiS { Element *nb = const_cast<Element*>(neighbour_[i]); int edgeNo = oppVertex_[i] = mel->getOppVertex(i); - if (nb->getFirstChild() && (edgeNo != 2)) { // make nb nearest el. + + + if (nb->getFirstChild() && (edgeNo != 2)) { + + // Search for the next neighbour. In many cases, the neighbour element + // may be refinemed in a way, such that there is no new vertex on the + // common edge. This situation is shown in the following picture: + // + // /|\ + // / | \ + // / | \ + // /\ | \ + // / \ | \ + // / \| \ + // ------------- + // + // nb el + // + // Note that we know (because of the last if statement), that the + // neighbour element has children and the common edge is not the + // refinement edge, which has always the number 2, of our element. + + if (edgeNo == 0) { + // The situation is as follows: + // + // ------- + // \ /|\ + // \ / | \ + // \/ | \ + // \ | \ + // \ | \ + // \| \ + // ------- + // + // nb el + // That means, the edge 0 of the same level neighbour is the common + // edge, i.e., the direct neighbour is the second child of the same + // level neighbour. + nb = neighbour_[i] = nb->getSecondChild(); } else { + // The situation is as shown in the picture above. So the next + // neighbour is the first child of the same level neighbour element. nb = neighbour_[i] = nb->getFirstChild(); } + // In both cases the opp vertex number is 2, as one can see in the + // pictures above. oppVertex_[i] = 2; if (fill_opp_coords) { if (nb->isNewCoordSet()) { oppCoord_[i] = *(nb->getNewCoord()); } else { - oppCoord_[i] = (macroNeighbour->coord[0] + macroNeighbour->coord[1]) * 0.5; - } + // In both cases, that are shown in the pictures above, the opp + // vertex of the neighbour edge is the midpoint of the vertex 0 + // and vertex 1 of the same level neighbour element. + oppCoord_[i] = (macroNeighbour->coord[0] + + macroNeighbour->coord[1]) * 0.5; + } switch (i) { case 0: - if (*(macroNeighbour->getElement()->getDOF(2)) == *(element_->getDOF(2))) { + // The common edge is the edge 0 of this element. + + switch (edgeNo) { + case 1: neighbourCoord_[i][0] = macroNeighbour->coord[2]; neighbourCoord_[i][1] = macroNeighbour->coord[0]; - } else if (*(macroNeighbour->getElement()->getDOF(2)) == *(element_->getDOF(1))) { + break; + case 0: neighbourCoord_[i][0] = macroNeighbour->coord[1]; neighbourCoord_[i][1] = macroNeighbour->coord[2]; - } else { + break; + default: ERROR_EXIT("Should not happen!\n"); } @@ -109,13 +160,17 @@ namespace AMDiS { break; case 1: - if (*(macroNeighbour->getElement()->getDOF(2)) == *(element_->getDOF(2))) { + // The commonedge is the edge 1 of this element. + switch (edgeNo) { + case 0: neighbourCoord_[i][0] = macroNeighbour->coord[1]; neighbourCoord_[i][1] = macroNeighbour->coord[2]; - } else if (*(macroNeighbour->getElement()->getDOF(2)) == *(element_->getDOF(0))) { + break; + case 1: neighbourCoord_[i][0] = macroNeighbour->coord[2]; neighbourCoord_[i][1] = macroNeighbour->coord[0]; - } else { + break; + default: ERROR_EXIT("Should not happen!\n"); } @@ -123,15 +178,10 @@ namespace AMDiS { break; case 2: - if (*(macroNeighbour->getElement()->getDOF(2)) == *(element_->getDOF(0))) { - neighbourCoord_[i][0] = macroNeighbour->coord[2]; - neighbourCoord_[i][1] = macroNeighbour->coord[1]; - } else if (*(macroNeighbour->getElement()->getDOF(2)) == *(element_->getDOF(1))) { - neighbourCoord_[i][0] = macroNeighbour->coord[0]; - neighbourCoord_[i][1] = macroNeighbour->coord[2]; - } else { - ERROR_EXIT("Should not happen!\n"); - } + // I've deleted here some code, be I think that this case is not + // possible. If an error occurs in this line, please check AMDiS + // revision <= 476 at the same position. + ERROR_EXIT("Should not happen!\n"); break; default: @@ -146,17 +196,24 @@ namespace AMDiS { } else { std::cout << " Neighbour " << j << ": not existing" << std::endl; } - std::cout << " OppVertex " << j << ": " << static_cast<int>(mel->getOppVertex(j)) << std::endl; - std::cout << std::endl; + std::cout << " OppVertex " << j << ": " + << static_cast<int>(mel->getOppVertex(j)) + << std::endl << std::endl; } ERROR_EXIT("should not happen!\n"); break; } } } else { + + // In this case, we know that the common edge is the refinement edge. + // This makes everything much more simpler, because we know that the + // next neighbour is equal to the samel level neighbour. If the same + // level neighbour would be refinement, also this element must to be + // refinement, because they share the refinement edge. + if (fill_opp_coords) { oppCoord_[i] = macroNeighbour->coord[edgeNo]; - neighbourCoord_[i] = macroNeighbour->coord; } } diff --git a/AMDiS/src/PeriodicBC.cc b/AMDiS/src/PeriodicBC.cc index f63282ef..a252749d 100644 --- a/AMDiS/src/PeriodicBC.cc +++ b/AMDiS/src/PeriodicBC.cc @@ -205,32 +205,19 @@ namespace AMDiS { masterMatrix_ = NULL; } - matrix->print(); - using namespace mtl; DOFAdmin* admin = rowFESpace->getAdmin(); std::vector<int> dofMap(admin->getUsedSize()); - for (int i = 0; i < admin->getUsedSize(); i++) { + for (int i = 0; i < admin->getUsedSize(); i++) dofMap[i] = (*associated)[i]; - std::cout << "map " << i << " to " << dofMap[i] << std::endl; - } // Compute reorder matrix (newRow and newCol yields transposed!!!) matrix::traits::reorder<>::type R= matrix::reorder(dofMap); - DOFMatrix::base_matrix_type &A= matrix->getBaseMatrix(), B, D, E, TR; - - A*= 0.5; - // Half of entries with decreased row index + half of the strict lower origing - B= strict_upper(R) * A + strict_lower(A); - // Add half of entries with same row and decreased column index + half of increased columns - // Remark regarding column permutation: trans(strict_upper(trans(X))) == strict_lower(X) - // B+= bands(trans(R), 0, 1) * (A * strict_lower(R) + lower(A)); -> make this work one day!!! - TR= trans(R); - D= bands(TR, 0, 1); - E= A * strict_lower(R) + lower(A); - B+= D * E; - swap(A, B); + DOFMatrix::base_matrix_type &A= matrix->getBaseMatrix(), C; + + C = R * A * trans(R) + A; + A = 0.5 * C; } void PeriodicBC::exitVector(DOFVectorBase<double>* vector) diff --git a/AMDiS/src/ProblemScal.cc b/AMDiS/src/ProblemScal.cc index 4583f070..c71a268e 100644 --- a/AMDiS/src/ProblemScal.cc +++ b/AMDiS/src/ProblemScal.cc @@ -586,6 +586,8 @@ namespace AMDiS { systemMatrix->removeRowsWithDBC(systemMatrix->getApplyDBCs()); + systemMatrix->finishInsertion(); + // TODO: ExitMatrix should be called after finishInsertion! if (systemMatrix->getBoundaryManager()) systemMatrix->getBoundaryManager()->exitMatrix(systemMatrix); @@ -594,8 +596,6 @@ namespace AMDiS { if (solution->getBoundaryManager()) solution->getBoundaryManager()->exitVector(solution); - systemMatrix->finishInsertion(); - INFO(info, 8)("buildAfterCoarsen needed %.5f seconds\n", TIME_USED(first,clock())); #ifdef HAVE_PARALLEL_DOMAIN_AMDIS @@ -606,8 +606,6 @@ namespace AMDiS { #endif createPrecon(); - - systemMatrix->print(); } void ProblemScal::writeResidualMesh(AdaptInfo *adaptInfo, const std::string name) diff --git a/AMDiS/src/TimedObject.h b/AMDiS/src/TimedObject.h index df73b4f4..7731144b 100644 --- a/AMDiS/src/TimedObject.h +++ b/AMDiS/src/TimedObject.h @@ -24,10 +24,6 @@ namespace AMDiS { - // =========================================================================== - // ===== class TimedObject =================================================== - // =========================================================================== - /** \brief * This class can be used as base class for time dependent objects where * different objects refer to the same time. Herefore a pointer to @@ -37,24 +33,25 @@ namespace AMDiS { class TimedObject { public: - /** \brief - * Constructor. - */ - TimedObject() : timePtr(NULL) {}; - - /** \brief - * Sets the time pointer. - */ - inline void setTimePtr(double *timePtr_) { timePtr = timePtr_; }; - - /** \brief - * Returns the time pointer. - */ - inline double *getTimePtr() { return timePtr; }; + /// Constructor. + TimedObject() + : timePtr(NULL) + {} + + /// Sets the time pointer. + inline void setTimePtr(double *timePtr_) + { + timePtr = timePtr_; + } + + /// Returns the time pointer. + inline double *getTimePtr() + { + return timePtr; + } + protected: - /** \brief - * Pointer to the externally managed time value. - */ + /// Pointer to the externally managed time value. double *timePtr; }; -- GitLab