Commit 531be06c authored by Thomas Witkowski's avatar Thomas Witkowski

Some large changes in code, seems to work....

parent fe752c0c
...@@ -98,6 +98,7 @@ namespace AMDiS { ...@@ -98,6 +98,7 @@ namespace AMDiS {
class VertexVector; class VertexVector;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
class ElementObjectDatabase;
class FeSpaceDofMap; class FeSpaceDofMap;
class MeshLevelData; class MeshLevelData;
#endif #endif
......
...@@ -10,15 +10,45 @@ ...@@ -10,15 +10,45 @@
// See also license.opensource.txt in the distribution. // See also license.opensource.txt in the distribution.
#include "DofComm.h" #include "parallel/DofComm.h"
#include "parallel/InteriorBoundary.h"
#include "FiniteElemSpace.h"
namespace AMDiS { namespace AMDiS {
using namespace std; using namespace std;
void DofComm::removeEmpty() int DofComm::getNumberDofs(int level, const FiniteElemSpace *feSpace)
{ {
FUNCNAME("DofComm::removeEmpty()"); FUNCNAME("DofComm::getNumberDofs()");
TEST_EXIT_DBG(level < data.size())("Should not happen!\n");
DofContainerSet dofs;
for (DataIter rankIt = data[level].begin();
rankIt != data[level].end(); ++rankIt)
for (FeMapIter feIt = rankIt->second.begin();
feIt != rankIt->second.end(); ++feIt)
if (feIt->first == feSpace)
dofs.insert(feIt->second.begin(), feIt->second.end());
return static_cast<int>(dofs.size());
}
void DofComm::create(RankToBoundMap &boundary)
{
// === Fill data. ===
for (unsigned int i = 0; i < feSpaces.size(); i++)
for (int level = 0; level < nLevel; level++)
for (InteriorBoundary::iterator it(boundary, level); !it.end(); ++it)
it->rankObj.el->getAllDofs(feSpaces[i], it->rankObj,
data[level][it.getRank()][feSpaces[i]]);
// === Remove empty data containers. ===
for (unsigned int i = 0; i < data.size(); i++) { for (unsigned int i = 0; i < data.size(); i++) {
DataIter dit = data[i].begin(); DataIter dit = data[i].begin();
...@@ -42,25 +72,6 @@ namespace AMDiS { ...@@ -42,25 +72,6 @@ namespace AMDiS {
} }
int DofComm::getNumberDofs(int level, const FiniteElemSpace *feSpace)
{
FUNCNAME("DofComm::getNumberDofs()");
TEST_EXIT_DBG(level < data.size())("Should not happen!\n");
DofContainerSet dofs;
for (DataIter rankIt = data[level].begin();
rankIt != data[level].end(); ++rankIt)
for (FeMapIter feIt = rankIt->second.begin();
feIt != rankIt->second.end(); ++feIt)
if (feIt->first == feSpace)
dofs.insert(feIt->second.begin(), feIt->second.end());
return static_cast<int>(dofs.size());
}
bool DofComm::Iterator::setNextFeMap() bool DofComm::Iterator::setNextFeMap()
{ {
FUNCNAME("DofComm::Iterator::setNextFeMap()"); FUNCNAME("DofComm::Iterator::setNextFeMap()");
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define AMDIS_DOF_COMM_H #define AMDIS_DOF_COMM_H
#include <map> #include <map>
#include "parallel/ParallelTypes.h"
#include "FiniteElemSpace.h" #include "FiniteElemSpace.h"
#include "Global.h" #include "Global.h"
...@@ -52,12 +53,13 @@ namespace AMDiS { ...@@ -52,12 +53,13 @@ namespace AMDiS {
return data[level][rank][feSpace]; return data[level][rank][feSpace];
} }
void removeEmpty(); void init(int n, vector<const FiniteElemSpace*> &fe)
void init(int nLevels = 1)
{ {
nLevel = n;
feSpaces = fe;
data.clear(); data.clear();
data.resize(nLevels); data.resize(nLevel);
} }
DataType& getData(int level = 0) DataType& getData(int level = 0)
...@@ -67,9 +69,15 @@ namespace AMDiS { ...@@ -67,9 +69,15 @@ namespace AMDiS {
int getNumberDofs(int level, const FiniteElemSpace *feSpace); int getNumberDofs(int level, const FiniteElemSpace *feSpace);
void create(RankToBoundMap &boundary);
protected: protected:
LevelDataType data; LevelDataType data;
int nLevel;
vector<const FiniteElemSpace*> feSpaces;
friend class Iterator; friend class Iterator;
public: public:
......
...@@ -15,6 +15,49 @@ ...@@ -15,6 +15,49 @@
namespace AMDiS { namespace AMDiS {
void ElementObjectDatabase::create()
{
// === Fills macro element data structures. ===
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1,
Mesh::CALL_LEAF_EL |
Mesh::FILL_NEIGH |
Mesh::FILL_BOUND);
while (elInfo) {
TEST_EXIT_DBG(elInfo->getLevel() == 0)("Should not happen!\n");
Element *el = elInfo->getElement();
macroElIndexMap.insert(make_pair(el->getIndex(), el));
macroElIndexTypeMap.insert(make_pair(el->getIndex(), elInfo->getType()));
// Add all sub object of the element to the variable elObjDb.
addElement(elInfo);
elInfo = stack.traverseNext(elInfo);
}
// Create periodic data, if there are periodic boundary conditions.
createPeriodicData();
// Create data about the reverse modes of neighbouring elements.
createReverseModeData();
}
void ElementObjectDatabase::createMacroElementInfo(vector<MacroElement*> &mel)
{
macroElIndexMap.clear();
macroElIndexTypeMap.clear();
for (vector<MacroElement*>::iterator it = mel.begin();
it != mel.end(); ++it) {
macroElIndexMap.insert(make_pair((*it)->getIndex(), (*it)->getElement()));
macroElIndexTypeMap.insert(make_pair((*it)->getIndex(), (*it)->getElType()));
}
}
void ElementObjectDatabase::addElement(ElInfo *elInfo) void ElementObjectDatabase::addElement(ElInfo *elInfo)
{ {
FUNCNAME("ElementObjectDatabase::addElement()"); FUNCNAME("ElementObjectDatabase::addElement()");
...@@ -128,7 +171,7 @@ namespace AMDiS { ...@@ -128,7 +171,7 @@ namespace AMDiS {
} }
void ElementObjectDatabase::createPeriodicData(const FiniteElemSpace *feSpace) void ElementObjectDatabase::createPeriodicData()
{ {
FUNCNAME("ElementObjectDatabase::createPeriodicData()"); FUNCNAME("ElementObjectDatabase::createPeriodicData()");
...@@ -223,9 +266,9 @@ namespace AMDiS { ...@@ -223,9 +266,9 @@ namespace AMDiS {
("Should not happen!\n"); ("Should not happen!\n");
periodicVertices[make_pair(dof0, dof3)] = periodicVertices[make_pair(dof0, dof3)] =
provideConnectedPeriodicBoundary(feSpace->getAdmin(), type0, type1); provideConnectedPeriodicBoundary(type0, type1);
periodicVertices[make_pair(dof3, dof0)] = periodicVertices[make_pair(dof3, dof0)] =
provideConnectedPeriodicBoundary(feSpace->getAdmin(), type0, type1); provideConnectedPeriodicBoundary(type0, type1);
for (unsigned int j = i + 1; j < multPeriodicDof2.size(); j++) for (unsigned int j = i + 1; j < multPeriodicDof2.size(); j++)
if (multPeriodicDof2[j] == dof3) if (multPeriodicDof2[j] == dof3)
...@@ -244,7 +287,7 @@ namespace AMDiS { ...@@ -244,7 +287,7 @@ namespace AMDiS {
make_pair(multPeriodicDof3[j], multPeriodicDof3[i]); make_pair(multPeriodicDof3[j], multPeriodicDof3[i]);
if (periodicVertices.count(perDofs0) == 0) { if (periodicVertices.count(perDofs0) == 0) {
BoundaryType b = getNewBoundaryType(feSpace->getAdmin()); BoundaryType b = getNewBoundaryType();
periodicVertices[perDofs0] = b; periodicVertices[perDofs0] = b;
periodicVertices[perDofs1] = b; periodicVertices[perDofs1] = b;
} }
...@@ -275,8 +318,7 @@ namespace AMDiS { ...@@ -275,8 +318,7 @@ namespace AMDiS {
BoundaryType type0 = periodicEdges[make_pair(edge0, edge1)]; BoundaryType type0 = periodicEdges[make_pair(edge0, edge1)];
BoundaryType type1 = periodicEdges[make_pair(edge0, edge2)]; BoundaryType type1 = periodicEdges[make_pair(edge0, edge2)];
BoundaryType type2 = BoundaryType type2 = provideConnectedPeriodicBoundary(type0, type1);
provideConnectedPeriodicBoundary(feSpace->getAdmin(), type0, type1);
periodicEdges[perEdge0] = type2; periodicEdges[perEdge0] = type2;
periodicEdges[perEdge1] = type2; periodicEdges[perEdge1] = type2;
...@@ -321,7 +363,7 @@ namespace AMDiS { ...@@ -321,7 +363,7 @@ namespace AMDiS {
} }
BoundaryType ElementObjectDatabase::getNewBoundaryType(DOFAdmin *admin) BoundaryType ElementObjectDatabase::getNewBoundaryType()
{ {
FUNCNAME("ElementObjectDatabase::getNewBoundaryType()"); FUNCNAME("ElementObjectDatabase::getNewBoundaryType()");
...@@ -334,15 +376,14 @@ namespace AMDiS { ...@@ -334,15 +376,14 @@ namespace AMDiS {
newPeriodicBoundaryType--; newPeriodicBoundaryType--;
mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = mesh->getPeriodicAssociations()[newPeriodicBoundaryType] =
new VertexVector(admin, ""); new VertexVector(feSpace->getAdmin(), "");
return newPeriodicBoundaryType; return newPeriodicBoundaryType;
} }
BoundaryType BoundaryType
ElementObjectDatabase::provideConnectedPeriodicBoundary(DOFAdmin *admin, ElementObjectDatabase::provideConnectedPeriodicBoundary(BoundaryType b0,
BoundaryType b0,
BoundaryType b1) BoundaryType b1)
{ {
FUNCNAME("ElementObjectDatabase::provideConnectedPeriodicBoundary()"); FUNCNAME("ElementObjectDatabase::provideConnectedPeriodicBoundary()");
...@@ -351,13 +392,13 @@ namespace AMDiS { ...@@ -351,13 +392,13 @@ namespace AMDiS {
(b0 <= b1 ? make_pair(b0, b1) : make_pair(b1, b0)); (b0 <= b1 ? make_pair(b0, b1) : make_pair(b1, b0));
if (bConnMap.count(bConn) == 0) { if (bConnMap.count(bConn) == 0) {
BoundaryType newPeriodicBoundaryType = getNewBoundaryType(admin); BoundaryType newPeriodicBoundaryType = getNewBoundaryType();
VertexVector &vecB0 = mesh->getPeriodicAssociations(b0); VertexVector &vecB0 = mesh->getPeriodicAssociations(b0);
VertexVector &vecB1 = mesh->getPeriodicAssociations(b1); VertexVector &vecB1 = mesh->getPeriodicAssociations(b1);
VertexVector &vecC = mesh->getPeriodicAssociations(newPeriodicBoundaryType); VertexVector &vecC = mesh->getPeriodicAssociations(newPeriodicBoundaryType);
DOFIteratorBase it(const_cast<DOFAdmin*>(admin), USED_DOFS); DOFIteratorBase it(const_cast<DOFAdmin*>(feSpace->getAdmin()), USED_DOFS);
for (it.reset(); !it.end(); ++it) { for (it.reset(); !it.end(); ++it) {
if (!it.isDofFree()) { if (!it.isDofFree()) {
...@@ -478,9 +519,7 @@ namespace AMDiS { ...@@ -478,9 +519,7 @@ namespace AMDiS {
} }
void ElementObjectDatabase::createReverseModeData(const FiniteElemSpace* feSpace, void ElementObjectDatabase::createReverseModeData()
map<int, Element*> &elIndexMap,
map<int, int> &elIndexTypeMap)
{ {
FUNCNAME("ElementObjectDatabase::createReverseModeData()"); FUNCNAME("ElementObjectDatabase::createReverseModeData()");
...@@ -498,13 +537,13 @@ namespace AMDiS { ...@@ -498,13 +537,13 @@ namespace AMDiS {
vector<ElementObjectData>& els = edgeIt->second; vector<ElementObjectData>& els = edgeIt->second;
for (unsigned int i = 0; i < els.size(); i++) { for (unsigned int i = 0; i < els.size(); i++) {
BoundaryObject obj0(elIndexMap[els[i].elIndex], BoundaryObject obj0(macroElIndexMap[els[i].elIndex],
elIndexTypeMap[els[i].elIndex], macroElIndexTypeMap[els[i].elIndex],
EDGE, els[i].ithObject); EDGE, els[i].ithObject);
for (unsigned int j = i + 1; j < els.size(); j++) { for (unsigned int j = i + 1; j < els.size(); j++) {
BoundaryObject obj1(elIndexMap[els[j].elIndex], BoundaryObject obj1(macroElIndexMap[els[j].elIndex],
elIndexTypeMap[els[j].elIndex], macroElIndexTypeMap[els[j].elIndex],
EDGE, els[j].ithObject); EDGE, els[j].ithObject);
bool reverseMode = bool reverseMode =
...@@ -522,13 +561,13 @@ namespace AMDiS { ...@@ -522,13 +561,13 @@ namespace AMDiS {
vector<ElementObjectData>& els = faceIt->second; vector<ElementObjectData>& els = faceIt->second;
for (unsigned int i = 0; i < els.size(); i++) { for (unsigned int i = 0; i < els.size(); i++) {
BoundaryObject obj0(elIndexMap[els[i].elIndex], BoundaryObject obj0(macroElIndexMap[els[i].elIndex],
elIndexTypeMap[els[i].elIndex], macroElIndexTypeMap[els[i].elIndex],
FACE, els[i].ithObject); FACE, els[i].ithObject);
for (unsigned int j = i + 1; j < els.size(); j++) { for (unsigned int j = i + 1; j < els.size(); j++) {
BoundaryObject obj1(elIndexMap[els[j].elIndex], BoundaryObject obj1(macroElIndexMap[els[j].elIndex],
elIndexTypeMap[els[j].elIndex], macroElIndexTypeMap[els[j].elIndex],
FACE, els[j].ithObject); FACE, els[j].ithObject);
bool reverseMode = bool reverseMode =
...@@ -549,13 +588,13 @@ namespace AMDiS { ...@@ -549,13 +588,13 @@ namespace AMDiS {
vector<ElementObjectData> &edges1 = edgeElements[edgeIt->first.second]; vector<ElementObjectData> &edges1 = edgeElements[edgeIt->first.second];
for (unsigned int i = 0; i < edges0.size(); i++) { for (unsigned int i = 0; i < edges0.size(); i++) {
BoundaryObject obj0(elIndexMap[edges0[i].elIndex], BoundaryObject obj0(macroElIndexMap[edges0[i].elIndex],
elIndexTypeMap[edges0[i].elIndex], macroElIndexTypeMap[edges0[i].elIndex],
EDGE, edges0[i].ithObject); EDGE, edges0[i].ithObject);
for (unsigned int j = 0; j < edges1.size(); j++) { for (unsigned int j = 0; j < edges1.size(); j++) {
BoundaryObject obj1(elIndexMap[edges1[j].elIndex], BoundaryObject obj1(macroElIndexMap[edges1[j].elIndex],
elIndexTypeMap[edges1[j].elIndex], macroElIndexTypeMap[edges1[j].elIndex],
EDGE, edges1[j].ithObject); EDGE, edges1[j].ithObject);
bool reverseMode = bool reverseMode =
...@@ -575,11 +614,11 @@ namespace AMDiS { ...@@ -575,11 +614,11 @@ namespace AMDiS {
TEST_EXIT_DBG(faces0.size() == faces1.size() == 1)("Should not happen!\n"); TEST_EXIT_DBG(faces0.size() == faces1.size() == 1)("Should not happen!\n");
BoundaryObject obj0(elIndexMap[faces0[0].elIndex], BoundaryObject obj0(macroElIndexMap[faces0[0].elIndex],
elIndexTypeMap[faces0[0].elIndex], macroElIndexTypeMap[faces0[0].elIndex],
FACE, faces0[0].ithObject); FACE, faces0[0].ithObject);
BoundaryObject obj1(elIndexMap[faces1[0].elIndex], BoundaryObject obj1(macroElIndexMap[faces1[0].elIndex],
elIndexTypeMap[faces1[0].elIndex], macroElIndexTypeMap[faces1[0].elIndex],
FACE, faces1[0].ithObject); FACE, faces1[0].ithObject);
bool reverseMode = bool reverseMode =
......
...@@ -103,39 +103,25 @@ namespace AMDiS { ...@@ -103,39 +103,25 @@ namespace AMDiS {
class ElementObjectDatabase { class ElementObjectDatabase {
public: public:
ElementObjectDatabase() ElementObjectDatabase()
: mesh(NULL), : feSpace(NULL),
mesh(NULL),
iterGeoPos(CENTER) iterGeoPos(CENTER)
{} {}
void setFeSpace(const FiniteElemSpace *fe)
/// Set the mesh that should be used for the database.
void setMesh(Mesh *m)
{ {
mesh = m; feSpace = fe;
mesh = feSpace->getMesh();
}
Mesh* getMesh()
{
return mesh;
} }
void create();
/** \brief void createMacroElementInfo(vector<MacroElement*> &mel);
* 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 indirectly 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
* indirectly connected.
*/
void createPeriodicData(const FiniteElemSpace *feSpace);
/** \brief /** \brief
* Create for a filled object database the membership information for all * Create for a filled object database the membership information for all
...@@ -149,22 +135,6 @@ namespace AMDiS { ...@@ -149,22 +135,6 @@ namespace AMDiS {
MeshLevelData& levelData); MeshLevelData& levelData);
/** \brief
* Creates on all boundaries the reverse mode flag.
*
* \param[in] feSpace An arbitrary FE space defined on the mesh.
* Is used to get the orientation of the DOFs on
* elements.
* \param[in] elIndexMap Maps an element index to the pointer to the
* element.
* \param[in] elIndexTypeMap Maps an element index to its type id (only
* relevant in 3D).
*/
void createReverseModeData(const FiniteElemSpace* feSpace,
map<int, Element*> &elIndexMap,
map<int, int> &elIndexTypeMap);
/** \brief /** \brief
* Iterates over all elements for one geometrical index, i.e., over all * 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 * vertices, edges or faces in the mesh. The function returns true, if the
...@@ -480,6 +450,16 @@ namespace AMDiS { ...@@ -480,6 +450,16 @@ namespace AMDiS {
return (t >= smallestPeriodicBcType); return (t >= smallestPeriodicBcType);
} }
inline Element* getElementPtr(int index)
{
return macroElIndexMap[index];
}
inline int getElementType(int index)
{
return macroElIndexTypeMap[index];
}
/// Write the element database to disk. /// Write the element database to disk.
void serialize(ostream &out); void serialize(ostream &out);
...@@ -487,6 +467,15 @@ namespace AMDiS { ...@@ -487,6 +467,15 @@ namespace AMDiS {
void deserialize(istream &in); void deserialize(istream &in);
protected: protected:
/** \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);
/// Adds the i-th DOF vertex of an element to the object database. /// Adds the i-th DOF vertex of an element to the object database.
void addVertex(Element *el, int ith) void addVertex(Element *el, int ith)
{ {
...@@ -520,10 +509,24 @@ namespace AMDiS { ...@@ -520,10 +509,24 @@ namespace AMDiS {
faceLocalMap[elObj] = face; faceLocalMap[elObj] = face;
} }
BoundaryType getNewBoundaryType(DOFAdmin *admin); /** \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 indirectly 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
* indirectly connected.
*/
void createPeriodicData();
BoundaryType provideConnectedPeriodicBoundary(DOFAdmin *admin, /// Creates on all boundaries the reverse mode flag.
BoundaryType b0, void createReverseModeData();
BoundaryType getNewBoundaryType();
BoundaryType provideConnectedPeriodicBoundary(BoundaryType b0,
BoundaryType b1); BoundaryType b1);
/// Some auxiliary function to write the element object database to disk.