Commit e8e207b4 authored by Thomas Witkowski's avatar Thomas Witkowski

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];
return componentData.find(feSpace)->second;
}
/// Returns DOF mapping for a given FE space.
ComponentDofMap& operator[](const FiniteElemSpace *feSpace)
{
ERROR_EXIT("FE Space acces is not possible for component wise defined DOF mappings\n");
TEST_EXIT_DBG(componentData.count(feSpace))("No data for FE space!\n");;
return componentData.find(feSpace)->second;
}
/// Checks whether the DOF mapping is defined for a specific
/// component number.
bool isDefinedFor(int compNumber) const
{
const FiniteElemSpace *feSpace = componentSpaces[compNumber];
return static_cast<bool>(componentData.count(feSpace));
}
/// Return data iterator.
ComponentIterator& getIteratorData()
{