Commit 5f9656c6 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Added some documentation to parallel code.

parent 4354cab8
This diff is collapsed.
...@@ -31,138 +31,137 @@ ...@@ -31,138 +31,137 @@
#include "Global.h" #include "Global.h"
#include "Boundary.h" #include "Boundary.h"
#include "Serializer.h" #include "Serializer.h"
#include "FiniteElemSpace.h"
namespace AMDiS { namespace AMDiS {
using namespace std; using namespace std;
/// Just to templatize the typedef.
template<typename T> template<typename T>
struct PerBoundMap struct PerBoundMap {
{
typedef map<pair<T, T>, BoundaryType> type; typedef map<pair<T, T>, BoundaryType> type;
typedef typename type::iterator iterator; typedef typename type::iterator iterator;
}; };
/// Defines one element object. This may be either a vertex, edge or face.
struct ElementObjectData { struct ElementObjectData {
ElementObjectData(int a = -1, int b = 0, BoundaryType c = INTERIOR) ElementObjectData(int a = -1, int b = 0)
: elIndex(a), : elIndex(a),
ithObject(b), ithObject(b)
boundaryType(c)
{} {}
/// Index of the element this object is part of.
int elIndex; int elIndex;
/// Index of the object within the element.
int ithObject; int ithObject;
BoundaryType boundaryType; /// Write this element object to disk.
void serialize(ostream &out) const void serialize(ostream &out) const
{ {
SerUtil::serialize(out, elIndex); SerUtil::serialize(out, elIndex);
SerUtil::serialize(out, ithObject); SerUtil::serialize(out, ithObject);
SerUtil::serialize(out, boundaryType);
} }
/// Read this element object from disk.
void deserialize(istream &in) void deserialize(istream &in)
{ {
SerUtil::deserialize(in, elIndex); SerUtil::deserialize(in, elIndex);
SerUtil::deserialize(in, ithObject); SerUtil::deserialize(in, ithObject);
SerUtil::deserialize(in, boundaryType);
} }
/// Compare this element object with another one.
bool operator==(ElementObjectData& cmp) const bool operator==(ElementObjectData& cmp) const
{ {
return (elIndex == cmp.elIndex && return (elIndex == cmp.elIndex && ithObject == cmp.ithObject);
ithObject == cmp.ithObject &&
boundaryType == cmp.boundaryType);
} }
/// Define a strict order on element objects.
bool operator<(const ElementObjectData& rhs) const bool operator<(const ElementObjectData& rhs) const
{ {
return (elIndex < rhs.elIndex || return (elIndex < rhs.elIndex ||
(elIndex == rhs.elIndex && (elIndex == rhs.elIndex && ithObject < rhs.ithObject));
ithObject < rhs.ithObject));
} }
}; };
/** \brief
* This class is a database of element objects. An element object is either a
* vertex, edge or the face of a specific element. This database is used to store
* all objects of all elements of a mesh. The information is stored in a way that
* makes it possible to identify all elements, which have a given vertex, edge or
* face in common. If is is known which element is owned by which rank in parallel
* computations, it is thus possible to get all interior boundaries on object
* level. This is required, because two elements may share a common vertex without
* beging neighbours in the definition of AMDiS.
*/
class ElementObjects { class ElementObjects {
public: public:
ElementObjects() ElementObjects()
: iterGeoPos(CENTER) : feSpace(NULL),
mesh(NULL),
iterGeoPos(CENTER)
{} {}
void addVertex(Element *el, int ith, BoundaryType bound = INTERIOR) /// Set the finite element space that should be used for the database (especially
{ /// the mesh is of interest).
DegreeOfFreedom vertex = el->getDof(ith, 0); void setFeSpace(FiniteElemSpace *fe)
int elIndex = el->getIndex();
ElementObjectData elObj(elIndex, ith, bound);
vertexElements[vertex].push_back(elObj);
vertexLocalMap[elObj] = vertex;
}
void addEdge(Element *el, int ith, BoundaryType bound = INTERIOR)
{ {
DofEdge edge = el->getEdge(ith); feSpace = fe;
int elIndex = el->getIndex(); mesh = feSpace->getMesh();
ElementObjectData elObj(elIndex, ith, bound);
edgeElements[edge].push_back(elObj);
edgeLocalMap[elObj] = edge;
} }
void addFace(Element *el, int ith, BoundaryType bound = INTERIOR) /** \brief
{ * Adds an element to the object database. If the element is part of a periodic
DofFace face = el->getFace(ith); * boundary, all information about subobjects of the element on this boundary
int elIndex = el->getIndex(); * are collected.
ElementObjectData elObj(elIndex, ith, bound); *
* \param[in] elInfo ElInfo object of the element.
faceElements[face].push_back(elObj); */
faceLocalMap[elObj] = face; void addElement(ElInfo *elInfo);
}
/** \brief
void addElement(Element *el, BoundaryType bound = INTERIOR) * Creates final data of the periodic boundaries. Must be called after all
{ * elements of the mesh are added to the object database. Then this functions
for (int i = 0; i < el->getGeo(VERTEX); i++) * search for interectly connected vertices in periodic boundaries. This is only
addVertex(el, i); * the case, if there are more than one boundary conditions. Then, e.g., in 2D,
* all edges of a square are iterectly connected. In 3D, if the macro mesh is a
for (int i = 0; i < el->getGeo(EDGE); i++) * box, all eight vertex nodes and always four of the 12 edges are iterectly
addEdge(el, i); * connected.
*/
for (int i = 0; i < el->getGeo(FACE); i++) void createPeriodicData();
addFace(el, i);
}
/** \brief
void addPeriodicVertex(pair<DegreeOfFreedom, DegreeOfFreedom> perVertex, * Create for a filled object database the membership information for all element
BoundaryType bType) * objects. An object is owned by a rank, if the rank has the heighest rank
{ * number of all ranks where the object is part of.
periodicVertices[perVertex] = bType; *
} * \param[in] macroElementRankMap Maps to each macro element of the mesh the
* rank that owns this macro element.
void addPeriodicEdge(pair<DofEdge, DofEdge> perEdge, BoundaryType bType) */
{
periodicEdges[perEdge] = bType;
}
void addPeriodicFace(pair<DofFace, DofFace> perFace, BoundaryType bType)
{
periodicFaces[perFace] = bType;
}
void createRankData(map<int, int>& macroElementRankMap); void createRankData(map<int, int>& macroElementRankMap);
/** \brief
* Iterates over all elements for one geometrical index, i.e., over all vertices,
* edges or faces in the mesh. The function returns true, if the result is valid.
* Otherwise the iterator is at the end position.
*
* \param[in] pos Must be either VERTEX, EDGE or FACE and defines the elements
* that should be traversed.
*/
bool iterate(GeoIndex pos) bool iterate(GeoIndex pos)
{ {
// CENTER marks the variable "iterGeoPos" to be in an undefined state. I.e.,
// there is no iteration that is actually running.
if (iterGeoPos == CENTER) { if (iterGeoPos == CENTER) {
iterGeoPos = pos; iterGeoPos = pos;
switch (iterGeoPos) { switch (iterGeoPos) {
...@@ -221,6 +220,7 @@ namespace AMDiS { ...@@ -221,6 +220,7 @@ namespace AMDiS {
} }
/// Returns the data of the current iterator position.
map<int, ElementObjectData>& getIterateData() map<int, ElementObjectData>& getIterateData()
{ {
switch (iterGeoPos) { switch (iterGeoPos) {
...@@ -242,6 +242,7 @@ namespace AMDiS { ...@@ -242,6 +242,7 @@ namespace AMDiS {
} }
/// Returns the rank owner of the current iterator position.
int getIterateOwner() int getIterateOwner()
{ {
switch (iterGeoPos) { switch (iterGeoPos) {
...@@ -263,121 +264,220 @@ namespace AMDiS { ...@@ -263,121 +264,220 @@ namespace AMDiS {
} }
/// Returns the rank owner of a vertex DOF.
int getOwner(DegreeOfFreedom vertex) int getOwner(DegreeOfFreedom vertex)
{ {
return vertexOwner[vertex]; return vertexOwner[vertex];
} }
/// Returns the rank owner of an edge.
int getOwner(DofEdge edge) int getOwner(DofEdge edge)
{ {
return edgeOwner[edge]; return edgeOwner[edge];
} }
/// Returns the rank owner of an face.
int getOwner(DofFace face) int getOwner(DofFace face)
{ {
return faceOwner[face]; return faceOwner[face];
} }
/// Checks if a given vertex DOF is in a given rank.
int isInRank(DegreeOfFreedom vertex, int rank) int isInRank(DegreeOfFreedom vertex, int rank)
{ {
return (vertexInRank[vertex].count(rank)); return (vertexInRank[vertex].count(rank));
} }
/// Checks if a given edge is in a given rank.
int isInRank(DofEdge edge, int rank) int isInRank(DofEdge edge, int rank)
{ {
return (edgeInRank[edge].count(rank)); return (edgeInRank[edge].count(rank));
} }
/// Checks if a given face is in a given rank.
int isInRank(DofFace face, int rank) int isInRank(DofFace face, int rank)
{ {
return (faceInRank[face].count(rank)); return (faceInRank[face].count(rank));
} }
/// Returns a vector with all macro elements that have a given vertex DOF in common.
vector<ElementObjectData>& getElements(DegreeOfFreedom vertex) vector<ElementObjectData>& getElements(DegreeOfFreedom vertex)
{ {
return vertexElements[vertex]; return vertexElements[vertex];
} }
/// Returns a vector with all macro elements that have a given edge in common.
vector<ElementObjectData>& getElements(DofEdge edge) vector<ElementObjectData>& getElements(DofEdge edge)
{ {
return edgeElements[edge]; return edgeElements[edge];
} }
/// Returns a vector with all macro elements that have a given face in common.
vector<ElementObjectData>& getElements(DofFace face) vector<ElementObjectData>& getElements(DofFace face)
{ {
return faceElements[face]; return faceElements[face];
} }
/// Returns a map that maps to each rank all macro elements in this rank that
/// have a given vertex DOF in common.
map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex) map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex)
{ {
return vertexInRank[vertex]; return vertexInRank[vertex];
} }
/// Returns a map that maps to each rank all macro elements in this rank that
/// have a given edge in common.
map<int, ElementObjectData>& getElementsInRank(DofEdge edge) map<int, ElementObjectData>& getElementsInRank(DofEdge edge)
{ {
return edgeInRank[edge]; return edgeInRank[edge];
} }
/// Returns a map that maps to each rank all macro elements in this rank that
/// have a given face in common.
map<int, ElementObjectData>& getElementsInRank(DofFace face) map<int, ElementObjectData>& getElementsInRank(DofFace face)
{ {
return faceInRank[face]; return faceInRank[face];
} }
/// Returns to an element object data the appropriate vertex DOF.
DegreeOfFreedom getVertexLocalMap(ElementObjectData &data) DegreeOfFreedom getVertexLocalMap(ElementObjectData &data)
{ {
return vertexLocalMap[data]; return vertexLocalMap[data];
} }
/// Returns to an element object data the appropriate edge.
DofEdge getEdgeLocalMap(ElementObjectData &data) DofEdge getEdgeLocalMap(ElementObjectData &data)
{ {
return edgeLocalMap[data]; return edgeLocalMap[data];
} }
/// Returns to an element object data the appropriate face.
DofFace getFaceLocalMap(ElementObjectData &data) DofFace getFaceLocalMap(ElementObjectData &data)
{ {
return faceLocalMap[data]; return faceLocalMap[data];
} }
/// Write the element database to disk.
void serialize(ostream &out); void serialize(ostream &out);
/// Read the element database from disk.
void deserialize(istream &in); void deserialize(istream &in);
private: protected:
/// Adds the i-th DOF vertex of an element to the object database.
void addVertex(Element *el, int ith)
{
DegreeOfFreedom vertex = el->getDof(ith, 0);
int elIndex = el->getIndex();
ElementObjectData elObj(elIndex, ith);
vertexElements[vertex].push_back(elObj);
vertexLocalMap[elObj] = vertex;
}
/// Adds the i-th edge of an element to the object database.
void addEdge(Element *el, int ith)
{
DofEdge edge = el->getEdge(ith);
int elIndex = el->getIndex();
ElementObjectData elObj(elIndex, ith);
edgeElements[edge].push_back(elObj);
edgeLocalMap[elObj] = edge;
}
/// Adds the i-th face of an element to the object database.
void addFace(Element *el, int ith)
{
DofFace face = el->getFace(ith);
int elIndex = el->getIndex();
ElementObjectData elObj(elIndex, ith);
faceElements[face].push_back(elObj);
faceLocalMap[elObj] = face;
}
/// Some auxiliary function to write the element object database to disk.
void serialize(ostream &out, vector<ElementObjectData>& elVec); void serialize(ostream &out, vector<ElementObjectData>& elVec);
/// Some auxiliary function to read the element object database from disk.
void deserialize(istream &in, vector<ElementObjectData>& elVec); void deserialize(istream &in, vector<ElementObjectData>& elVec);
/// Some auxiliary function to write the element object database to disk.
void serialize(ostream &out, map<int, ElementObjectData>& data); void serialize(ostream &out, map<int, ElementObjectData>& data);
/// Some auxiliary function to read the element object database from disk.
void deserialize(istream &in, map<int, ElementObjectData>& data); void deserialize(istream &in, map<int, ElementObjectData>& data);
private: private:
/// The used FE space.
FiniteElemSpace *feSpace;
/// The mesh that is used to store all its element information in the database.
Mesh *mesh;
/// Maps to each vertex DOF all element objects that represent this vertex.
map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements; map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
/// Maps to each edge all element objects that represent this edge.
map<DofEdge, vector<ElementObjectData> > edgeElements; map<DofEdge, vector<ElementObjectData> > edgeElements;
map<DofFace, vector<ElementObjectData> > faceElements;
/// Maps to each face all element objects that represent this edge.
map<DofFace, vector<ElementObjectData> > faceElements;
/// Maps to an element object the corresponding vertex DOF.
map<ElementObjectData, DegreeOfFreedom> vertexLocalMap; map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
/// Maps to an element object the corresponding edge.
map<ElementObjectData, DofEdge> edgeLocalMap; map<ElementObjectData, DofEdge> edgeLocalMap;
/// Maps to an element object the corresponding face.
map<ElementObjectData, DofFace> faceLocalMap; map<ElementObjectData, DofFace> faceLocalMap;
/// Defines for all vertex DOFs the rank that ownes this vertex DOF.
map<DegreeOfFreedom, int> vertexOwner; map<DegreeOfFreedom, int> vertexOwner;
/// Defines for all edges the rank that ownes this edge.
map<DofEdge, int> edgeOwner; map<DofEdge, int> edgeOwner;
/// Defines for all faces the rank that ownes this face.
map<DofFace, int> faceOwner; map<DofFace, int> faceOwner;
/// Defines to each vertex DOF a map that maps to each rank number the element
/// objects that have this vertex DOF in common.
map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank; map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
/// Defines to each edge a map that maps to each rank number the element objects
/// that have this edge in common.
map<DofEdge, map<int, ElementObjectData> > edgeInRank; map<DofEdge, map<int, ElementObjectData> > edgeInRank;
/// Defines to each face a map that maps to each rank number the element objects
/// that have this face in common.
map<DofFace, map<int, ElementObjectData> > faceInRank; map<DofFace, map<int, ElementObjectData> > faceInRank;
/// Vertex iterator to iterate over \ref vertexInRank
map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter; map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
/// Edge iterator to iterate over \ref edgeInRank
map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter; map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
/// Face iterator to iterate over \ref faceInRank
map<DofFace, map<int, ElementObjectData> >::iterator faceIter; map<DofFace, map<int, ElementObjectData> >::iterator faceIter;
/// Defines the geometrical iteration index of the iterators. I.e., the value
/// is either VERTEX, EDGE or FACE and the corresponding element objects are
/// traversed. The value CENTER is used to define a not defined states of the
/// iterators, i.e., if no iteration is running.
GeoIndex iterGeoPos; GeoIndex iterGeoPos;
public: public:
...@@ -385,6 +485,12 @@ namespace AMDiS { ...@@ -385,6 +485,12 @@ namespace AMDiS {
PerBoundMap<DegreeOfFreedom>::type periodicVertices; PerBoundMap<DegreeOfFreedom>::type periodicVertices;
PerBoundMap<DofEdge>::type periodicEdges; PerBoundMap<DofEdge>::type periodicEdges;
PerBoundMap<DofFace>::type periodicFaces; PerBoundMap<DofFace>::type periodicFaces;
// Stores to each vertex all its periodic associations.
std::map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
// Stores to each edge all its periodic associations.
std::map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;
}; };