Commit 566d2c61 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

First update of parallel AMDiS with mixed finite elements. Not tested, and there ARE BUGS.

parent 15d34568
...@@ -150,7 +150,7 @@ namespace AMDiS { ...@@ -150,7 +150,7 @@ namespace AMDiS {
return name; return name;
} }
/// Returns \ref nDof[i], i.e., the number of dofs for the position i. /// Returns \ref nDof[i], i.e., the number of DOFs for the position i.
inline const int getNumberOfDofs(int i) const inline const int getNumberOfDofs(int i) const
{ {
return nDof[i]; return nDof[i];
......
...@@ -492,7 +492,10 @@ namespace AMDiS { ...@@ -492,7 +492,10 @@ namespace AMDiS {
int nnzPerRow; int nnzPerRow;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
std::map<DegreeOfFreedom, bool> *rankDofs; /// Stores for the DOFs of the row FE spaces whether they are owned by the
/// rank or not. This is used to ensure that Dirichlet BC is handled
/// correctly in parallel computations.
std::map<DegreeOfFreedom, bool> *rankDofs;
#endif #endif
/// Inserter object: implemented as pointer, allocated and deallocated as needed /// Inserter object: implemented as pointer, allocated and deallocated as needed
......
...@@ -25,7 +25,8 @@ namespace AMDiS { ...@@ -25,7 +25,8 @@ namespace AMDiS {
namespace debug { namespace debug {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
void writeLocalElementDofs(int rank, int elIdx, FiniteElemSpace *feSpace) void writeLocalElementDofs(int rank, int elIdx,
const FiniteElemSpace *feSpace)
{ {
using boost::lexical_cast; using boost::lexical_cast;
...@@ -37,7 +38,8 @@ namespace AMDiS { ...@@ -37,7 +38,8 @@ namespace AMDiS {
} }
void writeDofMesh(int rank, DegreeOfFreedom dof, FiniteElemSpace *feSpace) void writeDofMesh(int rank, DegreeOfFreedom dof,
const FiniteElemSpace *feSpace)
{ {
using boost::lexical_cast; using boost::lexical_cast;
...@@ -50,7 +52,7 @@ namespace AMDiS { ...@@ -50,7 +52,7 @@ namespace AMDiS {
} }
void writeMesh(FiniteElemSpace *feSpace, int rank, std::string filename) void writeMesh(const FiniteElemSpace *feSpace, int rank, std::string filename)
{ {
using boost::lexical_cast; using boost::lexical_cast;
...@@ -64,7 +66,7 @@ namespace AMDiS { ...@@ -64,7 +66,7 @@ namespace AMDiS {
#endif #endif
void writeDofIndexMesh(FiniteElemSpace *feSpace) void writeDofIndexMesh(const FiniteElemSpace *feSpace)
{ {
DOFVector<double> tmp(feSpace, "tmp"); DOFVector<double> tmp(feSpace, "tmp");
DOFIterator<double> it(&tmp, USED_DOFS); DOFIterator<double> it(&tmp, USED_DOFS);
...@@ -74,7 +76,7 @@ namespace AMDiS { ...@@ -74,7 +76,7 @@ namespace AMDiS {
} }
void colorEdgeInMesh(FiniteElemSpace *feSpace, void colorEdgeInMesh(const FiniteElemSpace *feSpace,
Element *el, Element *el,
int localEdgeNo, int localEdgeNo,
std::string filename) std::string filename)
...@@ -190,7 +192,8 @@ namespace AMDiS { ...@@ -190,7 +192,8 @@ namespace AMDiS {
} }
Element* getDofIndexElement(FiniteElemSpace *feSpace, DegreeOfFreedom dof) Element* getDofIndexElement(const FiniteElemSpace *feSpace,
DegreeOfFreedom dof)
{ {
const BasisFunction* basFcts = feSpace->getBasisFcts(); const BasisFunction* basFcts = feSpace->getBasisFcts();
int nBasFcts = basFcts->getNumber(); int nBasFcts = basFcts->getNumber();
...@@ -322,7 +325,7 @@ namespace AMDiS { ...@@ -322,7 +325,7 @@ namespace AMDiS {
} }
void printInfoByDof(FiniteElemSpace *feSpace, DegreeOfFreedom dof) void printInfoByDof(const FiniteElemSpace *feSpace, DegreeOfFreedom dof)
{ {
FUNCNAME("debug::printInfoByDof()"); FUNCNAME("debug::printInfoByDof()");
...@@ -387,7 +390,7 @@ namespace AMDiS { ...@@ -387,7 +390,7 @@ namespace AMDiS {
} }
void printAllDofCoords(FiniteElemSpace *feSpace) void printAllDofCoords(const FiniteElemSpace *feSpace)
{ {
FUNCNAME("printAllDofCoords()"); FUNCNAME("printAllDofCoords()");
...@@ -405,7 +408,8 @@ namespace AMDiS { ...@@ -405,7 +408,8 @@ namespace AMDiS {
} }
void getAllDofs(FiniteElemSpace *feSpace, std::set<const DegreeOfFreedom*>& dofs) void getAllDofs(const FiniteElemSpace *feSpace,
std::set<const DegreeOfFreedom*>& dofs)
{ {
FUNCNAME("getAllDofs()"); FUNCNAME("getAllDofs()");
...@@ -793,7 +797,7 @@ namespace AMDiS { ...@@ -793,7 +797,7 @@ namespace AMDiS {
} }
void testDofsByCoords(FiniteElemSpace *feSpace, void testDofsByCoords(const FiniteElemSpace *feSpace,
DofContainer &dofs0, DofContainer &dofs1) DofContainer &dofs0, DofContainer &dofs1)
{ {
FUNCNAME("debug::testDofsByCoords()"); FUNCNAME("debug::testDofsByCoords()");
......
...@@ -41,9 +41,13 @@ namespace AMDiS { ...@@ -41,9 +41,13 @@ namespace AMDiS {
typedef std::map<int, DofContainer> ElementIdxToDofs; typedef std::map<int, DofContainer> ElementIdxToDofs;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
void writeLocalElementDofs(int rank, int elIdx, FiniteElemSpace *feSpace); void writeLocalElementDofs(int rank,
int elIdx,
const FiniteElemSpace *feSpace);
void writeMesh(FiniteElemSpace *feSpace, int rank, std::string filename); void writeMesh(const FiniteElemSpace *feSpace,
int rank,
std::string filename);
/** \brief /** \brief
* Writes a vtu file with the mesh, where all DOFs are set to zero, and only * Writes a vtu file with the mesh, where all DOFs are set to zero, and only
...@@ -55,7 +59,9 @@ namespace AMDiS { ...@@ -55,7 +59,9 @@ namespace AMDiS {
* \param[in] dof Defines the DOF, which value is set to one in the mesh file. * \param[in] dof Defines the DOF, which value is set to one in the mesh file.
* \param[in] feSpace The FE space to be used. * \param[in] feSpace The FE space to be used.
*/ */
void writeDofMesh(int rank, DegreeOfFreedom dof, FiniteElemSpace *feSpace); void writeDofMesh(int rank,
DegreeOfFreedom dof,
const FiniteElemSpace *feSpace);
#endif #endif
/** \brief /** \brief
...@@ -64,9 +70,9 @@ namespace AMDiS { ...@@ -64,9 +70,9 @@ namespace AMDiS {
* *
* \param[in] feSpace The FE space to be used. * \param[in] feSpace The FE space to be used.
*/ */
void writeDofIndexMesh(FiniteElemSpace *feSpace); void writeDofIndexMesh(const FiniteElemSpace *feSpace);
void colorEdgeInMesh(FiniteElemSpace *feSpace, void colorEdgeInMesh(const FiniteElemSpace *feSpace,
Element *el, Element *el,
int localEdgeNo, int localEdgeNo,
std::string filename); std::string filename);
...@@ -92,7 +98,8 @@ namespace AMDiS { ...@@ -92,7 +98,8 @@ namespace AMDiS {
Mesh *mesh, Mesh *mesh,
int elIndex); int elIndex);
Element* getDofIndexElement(FiniteElemSpace *feSpace, DegreeOfFreedom dof); Element* getDofIndexElement(const FiniteElemSpace *feSpace,
DegreeOfFreedom dof);
Element* getLevel0ParentElement(Mesh *mesh, Element *el); Element* getLevel0ParentElement(Mesh *mesh, Element *el);
...@@ -108,13 +115,14 @@ namespace AMDiS { ...@@ -108,13 +115,14 @@ namespace AMDiS {
void printElementCoords(const FiniteElemSpace *feSpace, Element *el); void printElementCoords(const FiniteElemSpace *feSpace, Element *el);
void printInfoByDof(FiniteElemSpace *feSpace, DegreeOfFreedom dof); void printInfoByDof(const FiniteElemSpace *feSpace, DegreeOfFreedom dof);
void printMatValuesStatistics(Matrix<DOFMatrix*> *mat); void printMatValuesStatistics(Matrix<DOFMatrix*> *mat);
void printAllDofCoords(FiniteElemSpace *feSpace); void printAllDofCoords(const FiniteElemSpace *feSpace);
void getAllDofs(FiniteElemSpace *feSpace, std::set<const DegreeOfFreedom*>& dofs); void getAllDofs(const FiniteElemSpace *feSpace,
std::set<const DegreeOfFreedom*>& dofs);
/** \brief /** \brief
* Creates a text file storing the value of a sparse matrix. Each line of the file * Creates a text file storing the value of a sparse matrix. Each line of the file
...@@ -200,7 +208,7 @@ namespace AMDiS { ...@@ -200,7 +208,7 @@ namespace AMDiS {
const DegreeOfFreedom* dof3, const DegreeOfFreedom* dof3,
DofContainer &vec); DofContainer &vec);
void testDofsByCoords(FiniteElemSpace *feSpace, void testDofsByCoords(const FiniteElemSpace *feSpace,
DofContainer &dofs0, DofContainer &dofs1); DofContainer &dofs0, DofContainer &dofs1);
} }
......
...@@ -625,7 +625,7 @@ namespace AMDiS { ...@@ -625,7 +625,7 @@ namespace AMDiS {
} }
void Element::getAllDofs(FiniteElemSpace* feSpace, void Element::getAllDofs(const FiniteElemSpace* feSpace,
BoundaryObject bound, BoundaryObject bound,
DofContainer& dofs) DofContainer& dofs)
{ {
......
...@@ -421,7 +421,7 @@ namespace AMDiS { ...@@ -421,7 +421,7 @@ namespace AMDiS {
* which all vertex dofs are assembled. * which all vertex dofs are assembled.
* \param[out] dofs List of dofs, where the result is stored. * \param[out] dofs List of dofs, where the result is stored.
*/ */
virtual void getNodeDofs(FiniteElemSpace* feSpace, virtual void getNodeDofs(const FiniteElemSpace* feSpace,
BoundaryObject bound, BoundaryObject bound,
DofContainer& dofs) const = 0; DofContainer& dofs) const = 0;
...@@ -436,11 +436,11 @@ namespace AMDiS { ...@@ -436,11 +436,11 @@ namespace AMDiS {
* all non vertex dofs are assembled. * all non vertex dofs are assembled.
* \param[out] dofs All dofs are put to this dof list. * \param[out] dofs All dofs are put to this dof list.
*/ */
virtual void getHigherOrderDofs(FiniteElemSpace* feSpace, virtual void getHigherOrderDofs(const FiniteElemSpace* feSpace,
BoundaryObject bound, BoundaryObject bound,
DofContainer& dofs) const = 0; DofContainer& dofs) const = 0;
void getAllDofs(FiniteElemSpace* feSpace, void getAllDofs(const FiniteElemSpace* feSpace,
BoundaryObject bound, BoundaryObject bound,
DofContainer& dofs); DofContainer& dofs);
......
...@@ -36,14 +36,15 @@ namespace AMDiS { ...@@ -36,14 +36,15 @@ namespace AMDiS {
// Get geo index of vertices in the given dimension. // Get geo index of vertices in the given dimension.
posIndex = INDEX_OF_DIM(pos, dim); posIndex = INDEX_OF_DIM(pos, dim);
// Get number of dofs per vertex (should be one in all cases). // Get number of DOFs per vertex (should be one in all cases).
nDofs = admin->getNumberOfDofs(posIndex); nDofs = admin->getNumberOfDofs(posIndex);
TEST_EXIT_DBG(nDofs != 0)("Mh, I've to think about this situation!\n"); TEST_EXIT_DBG(nDofs != 0)("Mh, I've to think about this situation!\n");
// Calculate displacement. Is used if there is more than one dof admin on the mesh. // Calculate displacement. Is used if there is more than one DOF admin
// on the mesh.
n0 = admin->getNumberOfPreDofs(posIndex); n0 = admin->getNumberOfPreDofs(posIndex);
// Get first dof index position for vertices. // Get first DOF index position for vertices.
node0 = mesh->getNode(posIndex); node0 = mesh->getNode(posIndex);
// Get number of vertices in this dimension. // Get number of vertices in this dimension.
nElements = Global::getGeo(posIndex, mesh->getDim()); nElements = Global::getGeo(posIndex, mesh->getDim());
...@@ -55,11 +56,11 @@ namespace AMDiS { ...@@ -55,11 +56,11 @@ namespace AMDiS {
bool ElementDofIterator::next() bool ElementDofIterator::next()
{ {
// First iterate over the dofs of one element (vertex, edge, face). // First iterate over the DOFs of one element (vertex, edge, face).
dofPos++; dofPos++;
if (dofPos >= nDofs) { if (dofPos >= nDofs) {
// We are finished with all dofs of on element. Go to the next one. // We are finished with all DOFs of on element. Go to the next one.
dofPos = 0; dofPos = 0;
elementPos++; elementPos++;
...@@ -72,33 +73,35 @@ namespace AMDiS { ...@@ -72,33 +73,35 @@ namespace AMDiS {
return false; return false;
// Increase position, i.e., go from vertices to edges to faces and search // Increase position, i.e., go from vertices to edges to faces and search
// for the next position with dofs. // for the next position with DOFs.
do { do {
pos++; pos++;
// Get geo index posistion. // Get geo index posistion.
posIndex = INDEX_OF_DIM(pos, dim); posIndex = INDEX_OF_DIM(pos, dim);
// Get number of dofs in this position. // Get number of DOFs in this position.
nDofs = admin->getNumberOfDofs(posIndex); nDofs = admin->getNumberOfDofs(posIndex);
} while (nDofs == 0 && pos < dim); } while (nDofs == 0 && pos < dim);
if (nDofs > 0 && pos <= dim) { if (nDofs > 0 && pos <= dim) {
// We have found on more position with dofs. // We have found on more position with DOFs.
// Get number of elements in this position, i.e, the number of vertices,. // Get number of elements in this position, i.e, the number of
// edges and faces in the given dimension. // vertices, edges and faces in the given dimension.
nElements = Global::getGeo(posIndex, dim); nElements = Global::getGeo(posIndex, dim);
// Calculate displacement. Is used if there is more than one dof admin on the mesh. // Calculate displacement. Is used if there is more than one DOF
// admin on the mesh.
n0 = admin->getNumberOfPreDofs(posIndex); n0 = admin->getNumberOfPreDofs(posIndex);
// Get first dof index position for the geo index position. // Get first DOF index position for the geo index position.
node0 = mesh->getNode(posIndex); node0 = mesh->getNode(posIndex);
if (inOrder) if (inOrder)
orderPosition = basisFcts->orderOfPositionIndices(element, posIndex, 0); orderPosition =
basisFcts->orderOfPositionIndices(element, posIndex, 0);
} else { } else {
// That's all, we jave traversed all dofs of the mesh element. // That's all, we jave traversed all DOFs of the mesh element.
return false; return false;
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
namespace AMDiS { namespace AMDiS {
/** \brief /** \brief
* This class implements an iterator to iterate over all dofs of one element * This class implements an iterator to iterate over all DOFs of one element
* independet of dimension and the degree of basis functions. * independet of dimension and the degree of basis functions.
* *
* Should be used in the following way: * Should be used in the following way:
...@@ -57,12 +57,12 @@ namespace AMDiS { ...@@ -57,12 +57,12 @@ namespace AMDiS {
/// Start a new traverse with the given element. /// Start a new traverse with the given element.
void reset(const Element* el); void reset(const Element* el);
/// Go to next dof. Returns false, if there is dof anymore. /// Go to next DOF. Returns false, if there is no DOF anymore.
bool next(); bool next();
bool nextStrict(); bool nextStrict();
/// Returns the dof index of the current dof. /// Returns the DOF index of the current DOF.
inline DegreeOfFreedom getDof() inline DegreeOfFreedom getDof()
{ {
if (inOrder) if (inOrder)
...@@ -71,7 +71,7 @@ namespace AMDiS { ...@@ -71,7 +71,7 @@ namespace AMDiS {
return dofs[node0 + elementPos][n0 + dofPos]; return dofs[node0 + elementPos][n0 + dofPos];
} }
/// Returns a pointer to the current dof. /// Returns a pointer to the current DOF.
inline const DegreeOfFreedom* getDofPtr() inline const DegreeOfFreedom* getDofPtr()
{ {
if (inOrder) if (inOrder)
...@@ -80,13 +80,22 @@ namespace AMDiS { ...@@ -80,13 +80,22 @@ namespace AMDiS {
return &dofs[node0 + elementPos][n0 + dofPos]; return &dofs[node0 + elementPos][n0 + dofPos];
} }
/// Returns \ref pos, the current position (vertex, edge, face) of the traverse. /// Returns a pointer to the starting position of the current DOF
/// array. Makes only sence, if \ref nextStrict() is used for traverse.
inline const DegreeOfFreedom* getStartDof()
{
return dofs[node0 + elementPos];
}
/// Returns \ref pos, the current position (vertex, edge, face) of
/// the traverse.
inline int getCurrentPos() inline int getCurrentPos()
{ {
return pos; return pos;
} }
/// Returns \ref elementPos, the number of vertex, edge or face that is traversed. /// Returns \ref elementPos, the number of vertex, edge or face that
/// is traversed.
inline int getCurrentElementPos() inline int getCurrentElementPos()
{ {
return elementPos; return elementPos;
...@@ -99,12 +108,12 @@ namespace AMDiS { ...@@ -99,12 +108,12 @@ namespace AMDiS {
protected: protected:
/// The dof admin for which dofs should be traversed. /// The DOF admin for which DOFs should be traversed.
const DOFAdmin* admin; const DOFAdmin* admin;
const BasisFunction* basisFcts; const BasisFunction* basisFcts;
/// Pointer to the dofs that should be traversed. /// Pointer to the DOFs that should be traversed.
const DegreeOfFreedom **dofs; const DegreeOfFreedom **dofs;
/// Mesh on which the element is defined. /// Mesh on which the element is defined.
...@@ -126,32 +135,28 @@ namespace AMDiS { ...@@ -126,32 +135,28 @@ namespace AMDiS {
GeoIndex posIndex; GeoIndex posIndex;
/** \brief /** \brief
* Number of dofs at the current traverse position. Examples: independent of * Number of DOFs at the current traverse position. Examples: independent of
* dimension and degree of basis functions there is only one dof per vertex. * dimension and degree of basis functions there is only one DOF per vertex.
* But in 2d and with 3rd degree lagrange basis functions there are two * But in 2D and with 3rd degree lagrange basis functions there are two
* dofs per edge. * DOFs per edge.
*/ */
int nDofs; int nDofs;
/** \brief /// Displacement of DOF indices. Used if more than one DOF admin is defined
* Displacement of dof indices. Used of more than one dof admin is defined /// on the mesh.
* on the mesh.
*/
int n0; int n0;
/// Dof index of the first dof at this geo index position. /// DOF index of the first DOF at this geo index position.
int node0; int node0;
/** \brief /// Number of elements in the current geo position. Examples: 3 vertices in
* Number of elements in the current geo position. Examples: 3 vertices in 2d, /// 2d, 1 face in 2d, 4 faces in 3d, etc.
* 1 face in 2d, 4 faces in 3d, etc.
*/
int nElements; int nElements;
/// Current element, i.e., ith vertex, edge or face, that is traversed. /// Current element, i.e., ith vertex, edge or face, that is traversed.
int elementPos; int elementPos;
/// Currrent dof that is traversed on the current element; /// Currrent DOF that is traversed on the current element;
int dofPos; int dofPos;
}; };
} }
......
...@@ -173,13 +173,13 @@ namespace AMDiS { ...@@ -173,13 +173,13 @@ namespace AMDiS {
return "Line"; return "Line";
} }
void getNodeDofs(FiniteElemSpace*, BoundaryObject, DofContainer&) const void getNodeDofs(const FiniteElemSpace*, BoundaryObject, DofContainer&) const
{ {
FUNCNAME("Line::getNodeDofs()"); FUNCNAME("Line::getNodeDofs()");
ERROR_EXIT("Not yet implemented!\n"); ERROR_EXIT("Not yet implemented!\n");
} }
void getHigherOrderDofs(FiniteElemSpace*, BoundaryObject, DofContainer&) const void getHigherOrderDofs(const FiniteElemSpace*, BoundaryObject, DofContainer&) const
{ {
FUNCNAME("Line::getHigherOrderDofs()"); FUNCNAME("Line::getHigherOrderDofs()");
ERROR_EXIT("Not yet implemented!\n"); ERROR_EXIT("Not yet implemented!\n");
......
...@@ -271,21 +271,32 @@ namespace AMDiS { ...@@ -271,21 +271,32 @@ namespace AMDiS {