Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Aland, Sebastian
amdis
Commits
5f9656c6
Commit
5f9656c6
authored
Jan 07, 2011
by
Thomas Witkowski
Browse files
Added some documentation to parallel code.
parent
4354cab8
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
AMDiS/src/parallel/ElementObjectData.cc
View file @
5f9656c6
This diff is collapsed.
Click to expand it.
AMDiS/src/parallel/ElementObjectData.h
View file @
5f9656c6
...
...
@@ -31,138 +31,137 @@
#include "Global.h"
#include "Boundary.h"
#include "Serializer.h"
#include "FiniteElemSpace.h"
namespace
AMDiS
{
using
namespace
std
;
/// Just to templatize the typedef.
template
<
typename
T
>
struct
PerBoundMap
{
struct
PerBoundMap
{
typedef
map
<
pair
<
T
,
T
>
,
BoundaryType
>
type
;
typedef
typename
type
::
iterator
iterator
;
};
/// Defines one element object. This may be either a vertex, edge or face.
struct
ElementObjectData
{
ElementObjectData
(
int
a
=
-
1
,
int
b
=
0
,
BoundaryType
c
=
INTERIOR
)
ElementObjectData
(
int
a
=
-
1
,
int
b
=
0
)
:
elIndex
(
a
),
ithObject
(
b
),
boundaryType
(
c
)
ithObject
(
b
)
{}
/// Index of the element this object is part of.
int
elIndex
;
/// Index of the object within the element.
int
ithObject
;
BoundaryType
boundaryType
;
/// Write this element object to disk.
void
serialize
(
ostream
&
out
)
const
{
SerUtil
::
serialize
(
out
,
elIndex
);
SerUtil
::
serialize
(
out
,
ithObject
);
SerUtil
::
serialize
(
out
,
boundaryType
);
}
/// Read this element object from disk.
void
deserialize
(
istream
&
in
)
{
SerUtil
::
deserialize
(
in
,
elIndex
);
SerUtil
::
deserialize
(
in
,
ithObject
);
SerUtil
::
deserialize
(
in
,
boundaryType
);
}
/// Compare this element object with another one.
bool
operator
==
(
ElementObjectData
&
cmp
)
const
{
return
(
elIndex
==
cmp
.
elIndex
&&
ithObject
==
cmp
.
ithObject
&&
boundaryType
==
cmp
.
boundaryType
);
return
(
elIndex
==
cmp
.
elIndex
&&
ithObject
==
cmp
.
ithObject
);
}
/// Define a strict order on element objects.
bool
operator
<
(
const
ElementObjectData
&
rhs
)
const
{
return
(
elIndex
<
rhs
.
elIndex
||
(
elIndex
==
rhs
.
elIndex
&&
ithObject
<
rhs
.
ithObject
));
return
(
elIndex
<
rhs
.
elIndex
||
(
elIndex
==
rhs
.
elIndex
&&
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
{
public:
ElementObjects
()
:
iterGeoPos
(
CENTER
)
:
feSpace
(
NULL
),
mesh
(
NULL
),
iterGeoPos
(
CENTER
)
{}
void
addVertex
(
Element
*
el
,
int
ith
,
BoundaryType
bound
=
INTERIOR
)
{
DegreeOfFreedom
vertex
=
el
->
getDof
(
ith
,
0
);
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
)
/// Set the finite element space that should be used for the database (especially
/// the mesh is of interest).
void
setFeSpace
(
FiniteElemSpace
*
fe
)
{
DofEdge
edge
=
el
->
getEdge
(
ith
);
int
elIndex
=
el
->
getIndex
();
ElementObjectData
elObj
(
elIndex
,
ith
,
bound
);
edgeElements
[
edge
].
push_back
(
elObj
);
edgeLocalMap
[
elObj
]
=
edge
;
feSpace
=
fe
;
mesh
=
feSpace
->
getMesh
();
}
void
addFace
(
Element
*
el
,
int
ith
,
BoundaryType
bound
=
INTERIOR
)
{
DofFace
face
=
el
->
getFace
(
ith
);
int
elIndex
=
el
->
getIndex
();
ElementObjectData
elObj
(
elIndex
,
ith
,
bound
);
faceElements
[
face
].
push_back
(
elObj
);
faceLocalMap
[
elObj
]
=
face
;
}
void
addElement
(
Element
*
el
,
BoundaryType
bound
=
INTERIOR
)
{
for
(
int
i
=
0
;
i
<
el
->
getGeo
(
VERTEX
);
i
++
)
addVertex
(
el
,
i
);
for
(
int
i
=
0
;
i
<
el
->
getGeo
(
EDGE
);
i
++
)
addEdge
(
el
,
i
);
for
(
int
i
=
0
;
i
<
el
->
getGeo
(
FACE
);
i
++
)
addFace
(
el
,
i
);
}
void
addPeriodicVertex
(
pair
<
DegreeOfFreedom
,
DegreeOfFreedom
>
perVertex
,
BoundaryType
bType
)
{
periodicVertices
[
perVertex
]
=
bType
;
}
void
addPeriodicEdge
(
pair
<
DofEdge
,
DofEdge
>
perEdge
,
BoundaryType
bType
)
{
periodicEdges
[
perEdge
]
=
bType
;
}
void
addPeriodicFace
(
pair
<
DofFace
,
DofFace
>
perFace
,
BoundaryType
bType
)
{
periodicFaces
[
perFace
]
=
bType
;
}
/** \brief
* Adds an element to the object database. If the element is part of a periodic
* boundary, all information about subobjects of the element on this boundary
* are collected.
*
* \param[in] elInfo ElInfo object of the element.
*/
void
addElement
(
ElInfo
*
elInfo
);
/** \brief
* 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
* search for interectly connected vertices in periodic boundaries. This is only
* 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
* box, all eight vertex nodes and always four of the 12 edges are iterectly
* connected.
*/
void
createPeriodicData
();
/** \brief
* Create for a filled object database the membership information for all element
* 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.
*
* \param[in] macroElementRankMap Maps to each macro element of the mesh the
* rank that owns this macro element.
*/
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
)
{
// CENTER marks the variable "iterGeoPos" to be in an undefined state. I.e.,
// there is no iteration that is actually running.
if
(
iterGeoPos
==
CENTER
)
{
iterGeoPos
=
pos
;
switch
(
iterGeoPos
)
{
...
...
@@ -221,6 +220,7 @@ namespace AMDiS {
}
/// Returns the data of the current iterator position.
map
<
int
,
ElementObjectData
>&
getIterateData
()
{
switch
(
iterGeoPos
)
{
...
...
@@ -242,6 +242,7 @@ namespace AMDiS {
}
/// Returns the rank owner of the current iterator position.
int
getIterateOwner
()
{
switch
(
iterGeoPos
)
{
...
...
@@ -263,121 +264,220 @@ namespace AMDiS {
}
/// Returns the rank owner of a vertex DOF.
int
getOwner
(
DegreeOfFreedom
vertex
)
{
return
vertexOwner
[
vertex
];
}
/// Returns the rank owner of an edge.
int
getOwner
(
DofEdge
edge
)
{
return
edgeOwner
[
edge
];
}
/// Returns the rank owner of an face.
int
getOwner
(
DofFace
face
)
{
return
faceOwner
[
face
];
}
/// Checks if a given vertex DOF is in a given rank.
int
isInRank
(
DegreeOfFreedom
vertex
,
int
rank
)
{
return
(
vertexInRank
[
vertex
].
count
(
rank
));
}
/// Checks if a given edge is in a given rank.
int
isInRank
(
DofEdge
edge
,
int
rank
)
{
return
(
edgeInRank
[
edge
].
count
(
rank
));
}
/// Checks if a given face is in a given rank.
int
isInRank
(
DofFace
face
,
int
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
)
{
return
vertexElements
[
vertex
];
}
/// Returns a vector with all macro elements that have a given edge in common.
vector
<
ElementObjectData
>&
getElements
(
DofEdge
edge
)
{
return
edgeElements
[
edge
];
}
/// Returns a vector with all macro elements that have a given face in common.
vector
<
ElementObjectData
>&
getElements
(
DofFace
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
)
{
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
)
{
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
)
{
return
faceInRank
[
face
];
}
/// Returns to an element object data the appropriate vertex DOF.
DegreeOfFreedom
getVertexLocalMap
(
ElementObjectData
&
data
)
{
return
vertexLocalMap
[
data
];
}
/// Returns to an element object data the appropriate edge.
DofEdge
getEdgeLocalMap
(
ElementObjectData
&
data
)
{
return
edgeLocalMap
[
data
];
}
/// Returns to an element object data the appropriate face.
DofFace
getFaceLocalMap
(
ElementObjectData
&
data
)
{
return
faceLocalMap
[
data
];
}
/// Write the element database to disk.
void
serialize
(
ostream
&
out
);
/// Read the element database from disk.
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
);
/// Some auxiliary function to read the element object database from disk.
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
);
/// Some auxiliary function to read the element object database from disk.
void
deserialize
(
istream
&
in
,
map
<
int
,
ElementObjectData
>&
data
);
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
;
/// Maps to each edge all element objects that represent this edge.
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
;
/// Maps to an element object the corresponding edge.
map
<
ElementObjectData
,
DofEdge
>
edgeLocalMap
;
/// Maps to an element object the corresponding face.
map
<
ElementObjectData
,
DofFace
>
faceLocalMap
;
/// Defines for all vertex DOFs the rank that ownes this vertex DOF.
map
<
DegreeOfFreedom
,
int
>
vertexOwner
;
/// Defines for all edges the rank that ownes this edge.
map
<
DofEdge
,
int
>
edgeOwner
;
/// Defines for all faces the rank that ownes this face.
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
;
/// 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
;
/// 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
;
/// Vertex iterator to iterate over \ref vertexInRank
map
<
DegreeOfFreedom
,
map
<
int
,
ElementObjectData
>
>::
iterator
vertexIter
;
/// Edge iterator to iterate over \ref edgeInRank
map
<
DofEdge
,
map
<
int
,
ElementObjectData
>
>::
iterator
edgeIter
;
/// Face iterator to iterate over \ref faceInRank
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
;
public:
...
...
@@ -385,6 +485,12 @@ namespace AMDiS {
PerBoundMap
<
DegreeOfFreedom
>::
type
periodicVertices
;
PerBoundMap
<
DofEdge
>::
type
periodicEdges
;
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
;
};
}
...
...
AMDiS/src/parallel/MeshDistributor.cc
View file @
5f9656c6
...
...
@@ -103,6 +103,8 @@ namespace AMDiS {
TEST_EXIT
(
feSpace
)(
"No FE space has been defined for the mesh distributor!
\n
"
);
TEST_EXIT
(
mesh
)(
"No mesh has been defined for the mesh distributor!
\n
"
);
elObjects
.
setFeSpace
(
feSpace
);
// If the problem has been already read from a file, we need only to set
// isRankDofs to all matrices and rhs vector and to remove periodic
// boundary conditions (if there are some).
...
...
@@ -1265,9 +1267,7 @@ namespace AMDiS {
FUNCNAME
(
"MeshDistributor::createInteriorBoundaryInfo()"
);
createMeshElementData
();
createBoundaryData
();
}
...
...
@@ -1276,7 +1276,6 @@ namespace AMDiS {
FUNCNAME
(
"MeshDistributor::updateInteriorBoundaryInfo()"
);
elObjects
.
createRankData
(
partitionVec
);
createBoundaryData
();
}
...
...
@@ -1285,12 +1284,6 @@ namespace AMDiS {
{
FUNCNAME
(
"MeshDistributor::createMeshElementData()"
);
// 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
;
// === Fills macro element data structures. ===
...
...
@@ -1304,274 +1297,19 @@ namespace AMDiS {
Element
*
el
=
elInfo
->
getElement
();
macroElIndexMap
[
el
->
getIndex
()]
=
el
;
macroElIndexTypeMap
[
el
->
getIndex
()]
=
elInfo
->
getType
();
// === Add all sub object of the element to the variable elObjects. ===
elObjects
.
addElement
(
elInfo
);
elObjects
.
addElement
(
el
);
// === Get periodic boundary information. ===
switch
(
mesh
->
getDim
())
{
case
2
:
for
(
int
i
=
0
;
i
<
el
->
getGeo
(
EDGE
);
i
++
)
{
if
(
mesh
->
isPeriodicAssociation
(
elInfo
->
getBoundary
(
EDGE
,
i
)))
{
Element
*
neigh
=
elInfo
->
getNeighbour
(
i
);
DofEdge
edge1
=
el
->
getEdge
(
i
);
DofEdge
edge2
=
neigh
->
getEdge
(
elInfo
->
getOppVertex
(
i
));
BoundaryType
boundaryType
=
elInfo
->
getBoundary
(
EDGE
,
i
);
elObjects
.
addPeriodicEdge
(
std
::
make_pair
(
edge1
,
edge2
),
boundaryType
);
periodicEdgeAssoc
[
edge1
].
insert
(
edge2
);
elObjects
.
addPeriodicVertex
(
std
::
make_pair
(
edge1
.
first
,
edge2
.
first
),
boundaryType
);
elObjects
.
addPeriodicVertex
(
std
::
make_pair
(
edge1
.
second
,
edge2
.
second
),
boundaryType
);
periodicDofAssoc
[
edge1
.
first
].
insert
(
boundaryType
);
periodicDofAssoc
[
edge1
.
second
].
insert
(
boundaryType
);
TEST_EXIT_DBG
(
edge1
.
first
==
mesh
->
getPeriodicAssociations
(
boundaryType
)[
edge2
.
first
]
&&
edge1
.
second
==
mesh
->
getPeriodicAssociations
(
boundaryType
)[
edge2
.
second
])
(
"Should not happen!
\n
"
);
}
}
break
;
case
3
:
for
(
int
i
=
0
;
i
<
el
->
getGeo
(
FACE
);
i
++
)
{
if
(
mesh
->
isPeriodicAssociation
(
elInfo
->
getBoundary
(
FACE
,
i
)))
{
Element
*
neigh
=
elInfo
->
getNeighbour
(
i
);
DofFace
face1
=
el
->
getFace
(
i
);
DofFace
face2
=
neigh
->
getFace
(
elInfo
->
getOppVertex
(
i
));
BoundaryType
boundaryType
=
elInfo
->
getBoundary
(
FACE
,
i
);
elObjects
.
addPeriodicFace
(
std
::
make_pair
(
face1
,
face2
),
elInfo
->
getBoundary
(
i
));
elObjects
.
addPeriodicVertex
(
std
::
make_pair
(
face1
.
get
<
0
>
(),
face2
.
get
<
0
>
()),
boundaryType
);
elObjects
.
addPeriodicVertex
(
std
::
make_pair
(
face1
.
get
<
1
>
(),
face2
.
get
<
1
>
()),
boundaryType
);
elObjects
.
addPeriodicVertex
(
std
::
make_pair
(
face1
.
get
<
2
>
(),
face2
.
get
<
2
>
()),
boundaryType
);
periodicDofAssoc
[
face1
.
get
<
0
>
()].
insert
(
boundaryType
);
periodicDofAssoc
[
face1
.
get
<
1
>
()].
insert
(
boundaryType
);
periodicDofAssoc
[
face1
.
get
<
2
>
()].
insert
(
boundaryType
);
TEST_EXIT_DBG
(
face1
.
get
<
0
>
()
==
mesh
->
getPeriodicAssociations
(
boundaryType
)[
face2
.
get
<
0
>
()]
&&
face1
.
get
<
1
>
()
==
mesh
->
getPeriodicAssociations
(
boundaryType
)[
face2
.
get
<
1
>
()]
&&
face1
.
get
<
2
>
()
==
mesh
->
getPeriodicAssociations
(
boundaryType
)[
face2
.
get
<
2
>
()])
(
"Should not happen!
\n
"
);
DofEdge
elEdge1
=
std
::
make_pair
(
face1
.
get
<
0
>
(),
face1
.
get
<
1
>
());
DofEdge
elEdge2
=
std
::
make_pair
(
face1
.
get
<
0
>
(),
face1
.
get
<
2
>
());
DofEdge
elEdge3
=
std
::
make_pair
(
face1
.
get
<
1
>
(),
face1
.
get
<
2
>
());
DofEdge
neighEdge1
=
std
::
make_pair
(
face2
.
get
<
0
>
(),
face2
.
get
<
1
>
());
DofEdge
neighEdge2
=
std
::
make_pair
(
face2
.
get
<
0
>
(),
face2
.
get
<
2
>
());
DofEdge
neighEdge3
=
std
::
make_pair
(
face2
.
get
<
1
>
(),
face2
.
get
<
2
>
());
elObjects
.
addPeriodicEdge
(
std
::
make_pair
(
elEdge1
,
neighEdge1
),
boundaryType
);
elObjects
.
addPeriodicEdge
(
std
::
make_pair
(
elEdge2
,
neighEdge2
),
boundaryType
);
elObjects
.
addPeriodicEdge
(
std
::
make_pair
(
elEdge3
,
neighEdge3
),
boundaryType
);
periodicEdgeAssoc
[
elEdge1
].
insert
(
neighEdge1
);
periodicEdgeAssoc
[
elEdge2
].
insert
(
neighEdge2
);
periodicEdgeAssoc
[
elEdge3
].
insert
(
neighEdge3
);
}
}
break
;
}
elInfo
=
stack
.
traverseNext
(
elInfo
);
}
// === Create periodic data, if there are periodic boundary conditions. ===
elObjects
.
createPeriodicData
();
// === Create mesh element data for this rank. ===
// === Create mesh element data for this rank. ===
elObjects
.
createRankData
(
partitionVec
);
// === Search for interectly connected vertices in periodic boundaries. ===
if
(
elObjects
.
periodicVertices
.
size
()
>
0
)
{
// === Search for an unsed boundary index. ===
BoundaryType
newPeriodicBoundaryType
=
0
;