Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

Commit e8e207b4 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Code refactoring, add comments, dirichlet rows in FETI-DP defined per component.

parent a276473c
......@@ -1687,6 +1687,7 @@ namespace AMDiS {
MSG("| number of levels: %d\n", nLevels);
MSG("| number of FE spaces: %d\n", uniqueFeSpaces.size());
for (unsigned int i = 0; i < uniqueFeSpaces.size(); i++) {
MSG("| FE space = %d (pointer adr %p):\n", i, uniqueFeSpaces[i]);
MSG("| nRankDofs = %d\n", dofMap[uniqueFeSpaces[i]].nRankDofs);
......
......@@ -42,8 +42,7 @@ namespace AMDiS {
: levelData(ld),
dofComm(NULL),
feSpace(NULL),
needGlobalMapping(false),
isNonLocal(false)
globalMapping(false)
{
clear();
}
......@@ -80,11 +79,9 @@ namespace AMDiS {
// === If required, compute also the global indices. ===
if (needGlobalMapping) {
computeGlobalMapping();
if (isNonLocal)
computeNonLocalIndices();
if (globalMapping) {
computeGlobalMapping();
computeNonLocalIndices();
}
}
......@@ -170,67 +167,50 @@ namespace AMDiS {
}
void ComponentDataEqFeSpace::init(vector<const FiniteElemSpace*> &f0,
vector<const FiniteElemSpace*> &f1,
bool isNonLocal,
MeshLevelData &levelData)
void FeSpaceData::init(vector<const FiniteElemSpace*> &f0,
vector<const FiniteElemSpace*> &f1,
bool globalMapping,
MeshLevelData &levelData)
{
feSpaces = f0;
feSpacesUnique = f1;
for (vector<const FiniteElemSpace*>::iterator it = feSpacesUnique.begin();
it != feSpacesUnique.end(); ++it) {
addFeSpace(*it, levelData);
componentData[*it].setNeedGlobalMapping(isNonLocal);
componentData[*it].setNonLocal(isNonLocal);
componentSpaces = f0;
feSpaces = f1;
for (vector<const FiniteElemSpace*>::iterator it = feSpaces.begin();
it != feSpaces.end(); ++it) {
if (componentData.count(*it))
componentData.find(*it)->second.clear();
else
componentData.insert(make_pair(*it, ComponentDofMap(&levelData)));
componentData[*it].setFeSpace(*it);
componentData[*it].setGlobalMapping(globalMapping);
}
}
void ComponentDataEqFeSpace::addFeSpace(const FiniteElemSpace* feSpace,
MeshLevelData &levelData)
void ComponentData::init(vector<const FiniteElemSpace*> &f0,
vector<const FiniteElemSpace*> &f1,
bool globalMapping,
MeshLevelData &levelData)
{
if (componentData.count(feSpace))
componentData.find(feSpace)->second.clear();
else
componentData.insert(make_pair(feSpace, ComponentDofMap(&levelData)));
componentData.find(feSpace)->second.setFeSpace(feSpace);
}
void ComponentDataDiffFeSpace::init(vector<const FiniteElemSpace*> &f0,
vector<const FiniteElemSpace*> &f1,
bool isNonLocal,
MeshLevelData &levelData)
{
feSpaces = f0;
feSpacesUnique = f1;
for (unsigned int component = 0; component < feSpaces.size(); component++) {
addComponent(component, feSpaces[component], levelData);
componentData[component].setNeedGlobalMapping(isNonLocal);
componentData[component].setNonLocal(isNonLocal);
componentSpaces = f0;
feSpaces = f1;
for (unsigned int component = 0; component < componentSpaces.size(); component++) {
if (componentData.count(component))
componentData.find(component)->second.clear();
else
componentData.insert(make_pair(component, ComponentDofMap(&levelData)));
componentData[component].setFeSpace(componentSpaces[component]);
componentData[component].setGlobalMapping(globalMapping);
}
}
void ComponentDataDiffFeSpace::addComponent(unsigned int component,
const FiniteElemSpace* feSpace,
MeshLevelData &levelData)
{
if (componentData.count(component))
componentData.find(component)->second.clear();
else
componentData.insert(make_pair(component, ComponentDofMap(&levelData)));
componentData.find(component)->second.setFeSpace(feSpace);
}
ParallelDofMapping::ParallelDofMapping(DofMappingMode mode)
: levelData(NULL),
dofComm(NULL),
isNonLocal(true),
globalMapping(true),
needMatIndexFromGlobal(false),
nRankDofs(1),
nLocalDofs(1),
......@@ -239,10 +219,10 @@ namespace AMDiS {
{
switch (mode) {
case COMPONENT_WISE:
data = new ComponentDataDiffFeSpace();
data = new ComponentData();
break;
case FESPACE_WISE:
data = new ComponentDataEqFeSpace();
data = new FeSpaceData();
break;
}
......@@ -261,9 +241,10 @@ namespace AMDiS {
FUNCNAME("ParallelDofMapping::init()");
levelData = &ldata;
isNonLocal = b;
globalMapping = b;
componentSpaces = fe;
data->init(fe, uniqueFe, isNonLocal, ldata);
data->init(fe, uniqueFe, globalMapping, ldata);
}
......@@ -386,29 +367,28 @@ namespace AMDiS {
// === Create the matrix indices for all component FE spaces. ===
vector<const FiniteElemSpace*> &feSpaces = data->getFeSpaces();
for (unsigned int i = 0; i < feSpaces.size(); i++) {
for (unsigned int component = 0; component < componentSpaces.size();
component++) {
// Traverse all DOFs of the FE space and create for all rank owned DOFs
// a matrix index.
DofMap& dofMap = (*data)[i].getMap();
DofMap& dofMap = (*data)[component].getMap();
for (DofMap::iterator it = dofMap.begin(); it != dofMap.end(); ++it) {
if ((*data)[i].isRankDof(it->first)) {
if ((*data)[component].isRankDof(it->first)) {
int globalMatIndex = it->second.local + offset;
if (globalIndex)
dofToMatIndex.add(i, it->second.global, globalMatIndex);
dofToMatIndex.add(component, it->second.global, globalMatIndex);
else
dofToMatIndex.add(i, it->first, globalMatIndex);
dofToMatIndex.add(component, it->first, globalMatIndex);
}
}
// Increase the offset for the next FE space by the number of DOFs owned
// by the rank in the current FE space.
offset += (*data)[i].nRankDofs;
offset += (*data)[component].nRankDofs;
// If there are no non local DOFs, continue with the next FE space.
if (!isNonLocal)
if (!globalMapping)
continue;
TEST_EXIT_DBG(dofComm != NULL)("No communicator given!\n");
......@@ -417,16 +397,17 @@ namespace AMDiS {
// === interior boundaries. ===
StdMpi<vector<DegreeOfFreedom> > stdMpi(mpiComm);
for (DofComm::Iterator it(dofComm->getSendDofs(), 0, feSpaces[i]);
for (DofComm::Iterator it(dofComm->getSendDofs(), 0, componentSpaces[component]);
!it.end(); it.nextRank()) {
vector<DegreeOfFreedom> sendGlobalDofs;
for (; !it.endDofIter(); it.nextDof())
if (dofMap.count(it.getDofIndex()))
if (globalIndex)
sendGlobalDofs.push_back(dofToMatIndex.get(i, dofMap[it.getDofIndex()].global));
sendGlobalDofs.push_back(dofToMatIndex.get(component,
dofMap[it.getDofIndex()].global));
else
sendGlobalDofs.push_back(dofToMatIndex.get(i, it.getDofIndex()));
sendGlobalDofs.push_back(dofToMatIndex.get(component, it.getDofIndex()));
int rank = it.getRank();
if (meshLevel > 0)
......@@ -435,7 +416,7 @@ namespace AMDiS {
stdMpi.send(rank, sendGlobalDofs);
}
for (DofComm::Iterator it(dofComm->getRecvDofs(), 0, feSpaces[i]);
for (DofComm::Iterator it(dofComm->getRecvDofs(), 0, componentSpaces[component]);
!it.end(); it.nextRank()) {
int rank = it.getRank();
if (meshLevel > 0)
......@@ -446,7 +427,7 @@ namespace AMDiS {
stdMpi.startCommunication();
for (DofComm::Iterator it(dofComm->getRecvDofs(), 0, feSpaces[i]);
for (DofComm::Iterator it(dofComm->getRecvDofs(), 0, componentSpaces[component]);
!it.end(); it.nextRank()) {
int rank = it.getRank();
if (meshLevel > 0)
......@@ -457,9 +438,9 @@ namespace AMDiS {
if (dofMap.count(it.getDofIndex())) {
DegreeOfFreedom d = stdMpi.getRecvData(rank)[counter++];
if (globalIndex)
dofToMatIndex.add(i, dofMap[it.getDofIndex()].global, d);
dofToMatIndex.add(component, dofMap[it.getDofIndex()].global, d);
else
dofToMatIndex.add(i, it.getDofIndex(), d);
dofToMatIndex.add(component, it.getDofIndex(), d);
}
}
}
......@@ -469,7 +450,7 @@ namespace AMDiS {
stdMpi.clear();
for (DofComm::Iterator it(dofComm->getPeriodicDofs(), 0, feSpaces[i]);
for (DofComm::Iterator it(dofComm->getPeriodicDofs(), 0, componentSpaces[component]);
!it.end(); it.nextRank()) {
vector<DegreeOfFreedom> sendGlobalDofs;
......@@ -477,9 +458,10 @@ namespace AMDiS {
if (dofMap.count(it.getDofIndex())) {
if (globalIndex) {
sendGlobalDofs.push_back(dofMap[it.getDofIndex()].global);
sendGlobalDofs.push_back(dofToMatIndex.get(i, dofMap[it.getDofIndex()].global));
sendGlobalDofs.push_back(dofToMatIndex.get(component,
dofMap[it.getDofIndex()].global));
} else {
sendGlobalDofs.push_back(dofToMatIndex.get(i, it.getDofIndex()));
sendGlobalDofs.push_back(dofToMatIndex.get(component, it.getDofIndex()));
}
}
......@@ -493,7 +475,7 @@ namespace AMDiS {
stdMpi.startCommunication();
for (DofComm::Iterator it(dofComm->getPeriodicDofs(), 0, feSpaces[i]);
for (DofComm::Iterator it(dofComm->getPeriodicDofs(), 0, componentSpaces[component]);
!it.end(); it.nextRank()) {
int rank = it.getRank();
......@@ -508,12 +490,13 @@ namespace AMDiS {
TEST_EXIT_DBG(counter + 2 <= stdMpi.getRecvData(it.getRank()).size())
("Should not happen!\n");
dofToMatIndex.add(i,
dofToMatIndex.add(component,
stdMpi.getRecvData(it.getRank())[counter],
stdMpi.getRecvData(it.getRank())[counter + 1]);
counter += 2;
} else {
dofToMatIndex.add(i, it.getDofIndex(),
dofToMatIndex.add(component,
it.getDofIndex(),
stdMpi.getRecvData(it.getRank())[counter++]);
}
}
......
......@@ -222,17 +222,10 @@ namespace AMDiS {
feSpace = fe;
}
/// Informs the mapping whether the mapping will include DOFs that are not
/// owned by the rank.
void setNonLocal(bool b)
{
isNonLocal = b;
}
/// Informs the mapping whether a global index must be computed.
void setNeedGlobalMapping(bool b)
void setGlobalMapping(bool b)
{
needGlobalMapping = b;
globalMapping = b;
}
/// Sets the DOF communicator.
......@@ -276,12 +269,7 @@ namespace AMDiS {
boost::container::flat_set<DegreeOfFreedom> nonRankDofs;
/// If true, a global index mapping will be computed for all DOFs.
bool needGlobalMapping;
/// Is true if there are DOFs in at least one subdomain that are not owned
/// by the rank. If the value is false, each rank contains only DOFs that
/// are also owned by this rank.
bool isNonLocal;
bool globalMapping;
public:
///
......@@ -289,6 +277,8 @@ namespace AMDiS {
};
/// Abstract iterator interface to access containrs containing values of
/// type \ref ComponentDofMap.
class ComponentIterator {
public:
virtual ComponentDofMap& operator*() = 0;
......@@ -303,240 +293,249 @@ namespace AMDiS {
};
/// Abstract interface to acces DOF mapping data for each component. Allows
/// to hide specific implementations, which allow, e.g., to efficiently map
/// all components having the same FE space to the same DOF mapping.
class ComponentDataInterface
{
public:
/// Access via component number
virtual ComponentDofMap& operator[](int compNumber) = 0;
/// Acess via FE space pointer
virtual ComponentDofMap& operator[](const FiniteElemSpace *feSpace) = 0;
/// Checks whether the DOF mapping is defined for a specific
/// component number.
virtual bool isDefinedFor(int compNumber) const = 0;
/// Returns iterator which iterates over all DOF mappings.
virtual ComponentIterator& getIteratorData() = 0;
/// Returns iterator which iterates over the DOF mappings of all
/// components. If the data is defined for each FE space and more than
/// one commponent is defined on the same FE space, the iterative will
/// also iterative multple times over the same DOF mapping object.
virtual ComponentIterator& getIteratorComponent() = 0;
virtual void init(vector<const FiniteElemSpace*> &f0,
vector<const FiniteElemSpace*> &f1,
bool isNonLocal,
/** \brief
* Initialization of the object.
*
* \param[in] componentSpaces Set of the FE spaces for each component.
* \param[in] feSpaces Set of all different FE spaces.
* \param[in] globalMapping Mapping is parallel (true) or only
* local (false).
* \param[in] levelData Data for multi level method.
*/
virtual void init(vector<const FiniteElemSpace*> &componentSpaces,
vector<const FiniteElemSpace*> &feSpaces,
bool globalMapping,
MeshLevelData &levelData) = 0;
vector<const FiniteElemSpace*>& getFeSpaces()
{
return feSpaces;
}
protected:
/// The FE spaces for all components.
vector<const FiniteElemSpace*> feSpaces;
vector<const FiniteElemSpace*> componentSpaces;
/// The set of all FE spaces. It uniquly contains all different FE spaces
/// from \ref feSpaces.
vector<const FiniteElemSpace*> feSpacesUnique;
vector<const FiniteElemSpace*> feSpaces;
};
class ComponentDataEqFeSpace : public ComponentDataInterface
/// This class concretizes the interface class \ref ComponentDataInterface. A
/// DOF mapping is implemented for each component.
class ComponentData : public ComponentDataInterface
{
public:
ComponentDataEqFeSpace()
: iterData(this),
iterComponent(this)
ComponentData()
: iter(this)
{}
/// Returns DOF mapping for a given component number.
ComponentDofMap& operator[](int compNumber)
{
const FiniteElemSpace *feSpace = feSpaces[compNumber];
return componentData.find(feSpace)->second;
}
TEST_EXIT_DBG(componentData.count(compNumber))
("No data for component %d!\n", compNumber);
ComponentDofMap& operator[](const FiniteElemSpace *feSpace)
{
TEST_EXIT_DBG(componentData.count(feSpace))("No data for FE space!\n");;
return componentData.find(feSpace)->second;
return componentData.find(compNumber)->second;
}
bool isDefinedFor(int compNumber) const
/// Just to implement the corresponding virtual function in \ref
/// ComponentDataInterface. Of course it does not work as we have data for
/// each component. Thus there may be different mappings for the same
/// FE space.
ComponentDofMap& operator[](const FiniteElemSpace *feSpace)
{
const FiniteElemSpace *feSpace = feSpaces[compNumber];
return static_cast<bool>(componentData.count(feSpace));
ERROR_EXIT("FE Space acces is not possible for component wise defined DOF mappings\n");
}
/// Return data iterator.
ComponentIterator& getIteratorData()
{
iterData.reset();
return iterData;
iter.reset();
return iter;
}
/// Return component iterator.
ComponentIterator& getIteratorComponent()
{
iterComponent.reset();
return iterComponent;
iter.reset();
return iter;
}
/// Checks whether the DOF mapping is defined for a specific
/// component number.
bool isDefinedFor(int compNumber) const
{
return (static_cast<unsigned int>(compNumber) < componentData.size());
}
/// Initialization
void init(vector<const FiniteElemSpace*> &f0,
vector<const FiniteElemSpace*> &f1,
bool isNonLocal,
bool globalMapping,
MeshLevelData &levelData);
protected:
void addFeSpace(const FiniteElemSpace* feSpace,
MeshLevelData &levelData);
class IteratorData : public ComponentIterator {
/// Iterator class to iterate over all parallel DOF mappings.
class Iterator : public ComponentIterator {
public:
IteratorData(ComponentDataEqFeSpace *d)
: data(d)
Iterator(ComponentData *d)
: data(d),
componentCounter(-1)
{}
ComponentDofMap& operator*()
{
(*data)[*it];
(*data)[componentCounter];
}
ComponentDofMap* operator->()
{
&((*data)[*it]);
&((*data)[componentCounter]);
}
bool end()
{
return (it == data->feSpacesUnique.end());
return (it == data->componentSpaces.end());
}
void next()
{
++it;
++componentCounter;
if (it == data->componentSpaces.end())
componentCounter = -1;
}
void reset()
{
it = data->feSpacesUnique.begin();
it = data->componentSpaces.begin();
componentCounter = 0;
}
protected:
ComponentDataEqFeSpace *data;
/// Pointer to data class over which the iterator must iterate.
ComponentData *data;
/// Internal iterator of the internal data from \ref ComponentData.
vector<const FiniteElemSpace*>::iterator it;
};
class IteratorComponent : public ComponentIterator {
public:
IteratorComponent(ComponentDataEqFeSpace *d)
: data(d)
{}
ComponentDofMap& operator*()
{
(*data)[*it];
}
ComponentDofMap* operator->()
{
&((*data)[*it]);
}
bool end()
{
return (it == data->feSpaces.end());
}
void next()
{
++it;
}
void reset()
{
it = data->feSpaces.begin();
}
/// Component number of current iteration.
int componentCounter;
};
protected:
ComponentDataEqFeSpace *data;
vector<const FiniteElemSpace*>::iterator it;
};
/// Data mapping from component numbers to DOF mapping objects.
map<unsigned int, ComponentDofMap> componentData;
map<const FiniteElemSpace*, ComponentDofMap> componentData;
/// Iterator object.
Iterator iter;
IteratorData iterData;
IteratorComponent iterComponent;
friend class IteratorData;
friend class IteratorComponent;
friend class Iterator;
};
class ComponentDataDiffFeSpace : public ComponentDataInterface
/// This class concretizes the interface class \ref ComponentDataInterface. A
/// DOF mapping is implemented for each finite element space. Thus, different
/// components sharing the same FE space are handled by the same DOF mapping.
class FeSpaceData : public ComponentDataInterface
{
public:
ComponentDataDiffFeSpace()
: iter(this)
FeSpaceData()
: iterData(this),
iterComponent(this)
{}
/// Returns DOF mapping for a given component number.
ComponentDofMap& operator[](int compNumber)
{
TEST_EXIT_DBG(componentData.count(compNumber))("No data for component %d!\n", compNumber);
return componentData.find(compNumber)->second;
const FiniteElemSpace *feSpace = componentSpaces[compNumber];