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 7513d640 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Periodic BC implemented by Siqi Ling added to this branch

parent a877b6da
...@@ -1128,24 +1128,13 @@ namespace AMDiS { ...@@ -1128,24 +1128,13 @@ namespace AMDiS {
// === Write periodic associations. === // === Write periodic associations. ===
int mapSize = periodicAssociations.size(); int mapSize = periodicAssociations.size();
SerUtil::serialize(out, mapSize); SerUtil::serialize(out, mapSize);
for (map<BoundaryType, VertexVector*>::iterator it = periodicAssociations.begin(); for (map<BoundaryType, std::vector<VertexVector*> >::iterator it = periodicAssociations.begin();
it != periodicAssociations.end(); ++it) { it != periodicAssociations.end(); ++it) {
BoundaryType b = it->first; BoundaryType b = it->first;
// Check which DOFAdmin is used for the current VertexVector we want to serialize.
int ithAdmin = -1;
for (int i = 0; i < static_cast<int>(admin.size()); i++) {
if (admin[i] == it->second->getAdmin()) {
ithAdmin = i;
break;
}
}
TEST_EXIT(ithAdmin >= 0)
("No DOFAdmin found for serialization of periodic associations!\n");
SerUtil::serialize(out, b); SerUtil::serialize(out, b);
SerUtil::serialize(out, ithAdmin); for (int i = 0; i < size; i++)
it->second->serialize(out); (it->second)[i]->serialize(out);
} }
serializedDOFs.clear(); serializedDOFs.clear();
...@@ -1278,7 +1267,7 @@ namespace AMDiS { ...@@ -1278,7 +1267,7 @@ namespace AMDiS {
VertexVector *tmpvec = new VertexVector(admin[ithAdmin], ""); VertexVector *tmpvec = new VertexVector(admin[ithAdmin], "");
tmpvec->deserialize(in); tmpvec->deserialize(in);
periodicAssociations[b] = tmpvec; periodicAssociations[b].push_back(tmpvec);
} }
} }
...@@ -1514,24 +1503,41 @@ namespace AMDiS { ...@@ -1514,24 +1503,41 @@ namespace AMDiS {
#endif #endif
bool Mesh::associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2) VertexVector& Mesh::getPeriodicAssociations(BoundaryType b, const DOFAdmin* admin)
{
FUNCNAME_DBG("Mesh::getPeriodicAssociations()");
TEST_EXIT_DBG(periodicAssociations.count(b) == 1)
("There are no periodic assoications for boundary type %d!\n", b);
return admin ? (*(periodicAssociations[b][getAdminIndex(admin)])) : (*(periodicAssociations[b][0]));
}
bool Mesh::associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2, int iadmin)
{ {
map<BoundaryType, VertexVector*>::iterator it; FUNCNAME_DBG("Mesh::associated()");
map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); TEST_EXIT_DBG(iadmin < admin.size())("Wrong DOF admin index\n");
map<BoundaryType, std::vector<VertexVector*> >::iterator it;
map<BoundaryType, std::vector<VertexVector*> >::iterator end = periodicAssociations.end();
for (it = periodicAssociations.begin(); it != end; ++it) for (it = periodicAssociations.begin(); it != end; ++it)
if ((*(it->second))[dof1] == dof2) if ((*(it->second)[iadmin])[dof1] == dof2)
return true; return true;
return false; return false;
} }
bool Mesh::indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2) bool Mesh::indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2, int iadmin)
{ {
FUNCNAME_DBG("Mesh::indirectlyAssociated()");
TEST_EXIT_DBG(iadmin < admin.size())("Wrong DOF admin index\n");
vector<DegreeOfFreedom> associatedToDOF1; vector<DegreeOfFreedom> associatedToDOF1;
map<BoundaryType, VertexVector*>::iterator it; map<BoundaryType, std::vector<VertexVector*> >::iterator it;
map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); map<BoundaryType, std::vector<VertexVector*> >::iterator end = periodicAssociations.end();
DegreeOfFreedom dof, assDOF; DegreeOfFreedom dof, assDOF;
associatedToDOF1.push_back(dof1); associatedToDOF1.push_back(dof1);
...@@ -1539,7 +1545,7 @@ namespace AMDiS { ...@@ -1539,7 +1545,7 @@ namespace AMDiS {
int size = static_cast<int>(associatedToDOF1.size()); int size = static_cast<int>(associatedToDOF1.size());
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
dof = associatedToDOF1[i]; dof = associatedToDOF1[i];
assDOF = (*(it->second))[dof]; assDOF = (*(it->second)[iadmin])[dof];
if (assDOF == dof2) { if (assDOF == dof2) {
return true; return true;
} else { } else {
......
...@@ -192,6 +192,18 @@ namespace AMDiS { ...@@ -192,6 +192,18 @@ namespace AMDiS {
return *(admin[i]); return *(admin[i]);
} }
/// Returns the index of a given DOFMadmin pointer in the admin vector
inline int getAdminIndex(const DOFAdmin* dofAdmin) const
{
size_t i = 0;
for (; i < admin.size(); i++)
if (admin[i] == dofAdmin)
break;
TEST_EXIT_DBG(i < admin.size())("Wrong DOF admin index: %d\n", i);
return i;
}
/// Creates a DOFAdmin with name lname. nDof specifies how many DOFs /// Creates a DOFAdmin with name lname. nDof specifies how many DOFs
/// are needed at the different positions (see \ref DOFAdmin::nrDOF). /// are needed at the different positions (see \ref DOFAdmin::nrDOF).
/// A pointer to the created DOFAdmin is returned. /// A pointer to the created DOFAdmin is returned.
...@@ -549,25 +561,24 @@ namespace AMDiS { ...@@ -549,25 +561,24 @@ namespace AMDiS {
} }
/// ///
inline std::map<BoundaryType, VertexVector*>& getPeriodicAssociations() inline std::map<BoundaryType, std::vector<VertexVector*> >& getPeriodicAssociations()
{ {
return periodicAssociations; return periodicAssociations;
} }
/// Returns the periodic association for a specific boundary type. /// Returns the periodic association for a specific boundary type.
inline VertexVector& getPeriodicAssociations(BoundaryType b) VertexVector& getPeriodicAssociations(BoundaryType b, const DOFAdmin* admin = NULL);
{
FUNCNAME_DBG("Mesh::getPeriodicAssociations()");
TEST_EXIT_DBG(periodicAssociations.count(b) == 1)
("There are no periodic assoications for boundary type %d!\n", b);
return (*(periodicAssociations[b]));
}
inline void setPeriodicAssociations(BoundaryType b, VertexVector* vec) inline void setPeriodicAssociations(BoundaryType b, VertexVector* vec)
{ {
periodicAssociations[b] = vec; std::map<BoundaryType, std::vector<VertexVector*> >::iterator lb = periodicAssociations.lower_bound(b);
if (lb != periodicAssociations.end() && !periodicAssociations.key_comp()(b, lb->first)) {
lb->second.push_back(vec);
} else {
std::vector<VertexVector*> v;
v.push_back(vec);
periodicAssociations.insert(lb, std::make_pair(b, v));
}
} }
...@@ -579,10 +590,20 @@ namespace AMDiS { ...@@ -579,10 +590,20 @@ namespace AMDiS {
} }
/// ///
bool associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2); bool associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2, int iadmin = 0);
inline bool associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2, const DOFAdmin* dofAdmin)
{
return associated(dof1, dof2, getAdminIndex(dofAdmin));
}
/// ///
bool indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2); bool indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2, int iadmin = 0);
inline bool indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2, const DOFAdmin* dofAdmin)
{
return indirectlyAssociated(dof1, dof2, getAdminIndex(dofAdmin));
}
/// Returns \macroFileInfo /// Returns \macroFileInfo
inline MacroInfo* getMacroFileInfo() inline MacroInfo* getMacroFileInfo()
...@@ -854,7 +875,7 @@ namespace AMDiS { ...@@ -854,7 +875,7 @@ namespace AMDiS {
bool initialized; bool initialized;
/// Map of managed periodic vertex associations. /// Map of managed periodic vertex associations.
std::map<BoundaryType, VertexVector*> periodicAssociations; std::map<BoundaryType, std::vector<VertexVector*> > periodicAssociations;
/// If the mesh has been created by reading a macro file, here the information /// If the mesh has been created by reading a macro file, here the information
/// are stored about the content of the file. /// are stored about the content of the file.
......
...@@ -106,9 +106,10 @@ namespace AMDiS { ...@@ -106,9 +106,10 @@ namespace AMDiS {
} }
PeriodicBC::PeriodicBC(BoundaryType type, const FiniteElemSpace *rowSpace) PeriodicBC::PeriodicBC(BoundaryType type, const FiniteElemSpace *rowSpace, bool diagonal)
: BoundaryCondition(type, rowSpace, NULL), : BoundaryCondition(type, rowSpace, NULL),
masterMatrix(NULL) masterMatrix(NULL),
isDiagonal(diagonal)
{ {
if (rowFeSpace->getMesh()->getDim() > 1) if (rowFeSpace->getMesh()->getDim() > 1)
periodicDOFMapping = periodicDOFMapping =
...@@ -129,7 +130,7 @@ namespace AMDiS { ...@@ -129,7 +130,7 @@ namespace AMDiS {
if (!masterMatrix) { if (!masterMatrix) {
masterMatrix = matrix; masterMatrix = matrix;
Mesh *mesh = matrix->getRowFeSpace()->getMesh(); Mesh *mesh = matrix->getRowFeSpace()->getMesh();
associated = mesh->getPeriodicAssociations()[boundaryType]; associated = &(mesh->getPeriodicAssociations(boundaryType, rowFeSpace->getAdmin()));
TEST_EXIT(associated) TEST_EXIT(associated)
("No associations for periodic boundary condition %d!\n", boundaryType); ("No associations for periodic boundary condition %d!\n", boundaryType);
...@@ -153,6 +154,7 @@ namespace AMDiS { ...@@ -153,6 +154,7 @@ namespace AMDiS {
return; return;
DOFAdmin *admin = rowFeSpace->getAdmin(); DOFAdmin *admin = rowFeSpace->getAdmin();
int iadmin = rowFeSpace->getMesh()->getAdminIndex(admin);
FixVec<int, WORLD> elFace(dim, NO_INIT); FixVec<int, WORLD> elFace(dim, NO_INIT);
FixVec<int, WORLD> neighFace(dim, NO_INIT); FixVec<int, WORLD> neighFace(dim, NO_INIT);
DimVec<int> vertexPermutation(dim, NO_INIT); DimVec<int> vertexPermutation(dim, NO_INIT);
...@@ -186,7 +188,7 @@ namespace AMDiS { ...@@ -186,7 +188,7 @@ namespace AMDiS {
int j = 0; int j = 0;
for (; j < dim + 1; j++) for (; j < dim + 1; j++)
if (neigh->getDof(j, 0) == periodicDOF) if (neigh->getDof(j, iadmin) == periodicDOF)
break; break;
vertexPermutation[i] = j; vertexPermutation[i] = j;
...@@ -213,42 +215,71 @@ namespace AMDiS { ...@@ -213,42 +215,71 @@ namespace AMDiS {
FUNCNAME("PeriodicBC::exitMatrix()"); FUNCNAME("PeriodicBC::exitMatrix()");
TEST_EXIT(matrix)("No matrix\n"); TEST_EXIT(matrix)("No matrix\n");
TEST_EXIT(associated)("No associated vector!\n"); TEST_EXIT(associated)("No associated vector!\n");
if (matrix == masterMatrix) if (matrix == masterMatrix)
masterMatrix = NULL; masterMatrix = NULL;
using namespace mtl; using namespace mtl;
typedef DOFMatrix::base_matrix_type Matrix;
typedef mtl::traits::range_generator<mtl::tag::row, Matrix>::type c_type;
typedef mtl::traits::range_generator<mtl::tag::nz, c_type>::type ic_type;
DOFAdmin* admin = rowFeSpace->getAdmin(); DOFAdmin* admin = rowFeSpace->getAdmin();
std::vector<int> dofMap(admin->getUsedSize()); int adminSize = admin->getUsedSize();
for (int i = 0; i < admin->getUsedSize(); i++) Matrix &A= matrix->getBaseMatrix();
dofMap[i] = (*associated)[i];
mtl::traits::col<Matrix>::type c(A);
mtl::traits::value<Matrix>::type v(A);
std::vector<std::vector<std::pair<DegreeOfFreedom, double> > > row_values;
row_values.resize(adminSize);
// Compute reorder matrix (newRow and newCol yields transposed!!!) for (DegreeOfFreedom i = 0; i < adminSize; i++) {
matrix::traits::reorder<>::type R= matrix::reorder(dofMap); if (i < (*associated)[i]) {
DOFMatrix::base_matrix_type &A= matrix->getBaseMatrix(), C; c_type cursor(begin<mtl::tag::row>(A) + i);
C = R * A * trans(R) + A; for (ic_type icursor(begin<mtl::tag::nz>(cursor)), icend(end<mtl::tag::nz>(cursor));
A = 0.5 * C; icursor != icend; ++icursor) {
row_values[i].push_back(std::make_pair(c(*icursor), v(*icursor)));
v(*icursor, 0.0);
}
}
}
matrix::inserter<Matrix, update_plus<double> > ins(A);
if (isDiagonal) {
for (DegreeOfFreedom i = 0; i < adminSize; i++) {
if (i < (*associated)[i]) {
ins[i][i] << 1.0;
ins[i][(*associated)[i]] << -1.0;
}
}
}
for (DegreeOfFreedom i = 0; i < adminSize; i++) {
if (i < (*associated)[i]) {
for (size_t j = 0; j < row_values[i].size(); j++)
ins[(*associated)[i]][row_values[i][j].first] << row_values[i][j].second;
}
}
} }
void PeriodicBC::exitVector(DOFVectorBase<double>* vector) void PeriodicBC::exitVector(DOFVectorBase<double>* vector)
{ {
FUNCNAME("PeriodicBC::exitVector()");
TEST_EXIT(rowFeSpace == vector->getFeSpace())("Should not happen.\n");
DOFIterator<double> vecIt(vector, USED_DOFS); DOFIterator<double> vecIt(vector, USED_DOFS);
Mesh *mesh = vector->getFeSpace()->getMesh(); Mesh *mesh = vector->getFeSpace()->getMesh();
VertexVector *associated = mesh->getPeriodicAssociations()[boundaryType]; VertexVector *associated = &(mesh->getPeriodicAssociations(boundaryType, rowFeSpace->getAdmin()));
for (vecIt.reset(); !vecIt.end(); ++vecIt) { for (vecIt.reset(); !vecIt.end(); ++vecIt) {
DegreeOfFreedom dof = vecIt.getDOFIndex(); DegreeOfFreedom dof = vecIt.getDOFIndex();
DegreeOfFreedom newDOF = (*associated)[dof]; DegreeOfFreedom newDOF = (*associated)[dof];
if (dof < newDOF) { if (dof < newDOF) {
double entry = ((*vector)[dof] + (*vector)[newDOF]) * 0.5; (*vector)[newDOF] += (*vector)[dof];
(*vector)[dof] = entry; (*vector)[dof] = 0.0;
(*vector)[newDOF] = entry;
} }
} }
} }
......
...@@ -88,7 +88,7 @@ namespace AMDiS { ...@@ -88,7 +88,7 @@ namespace AMDiS {
{ {
public: public:
/// Constructor. /// Constructor.
PeriodicBC(BoundaryType type, const FiniteElemSpace *rowFeSpace); PeriodicBC(BoundaryType type, const FiniteElemSpace *rowFeSpace, bool diagonal);
~PeriodicBC(); ~PeriodicBC();
...@@ -116,6 +116,8 @@ namespace AMDiS { ...@@ -116,6 +116,8 @@ namespace AMDiS {
PeriodicDOFMapping *periodicDOFMapping; PeriodicDOFMapping *periodicDOFMapping;
DOFMatrix *masterMatrix; DOFMatrix *masterMatrix;
bool isDiagonal;
}; };
} }
......
...@@ -1549,7 +1549,7 @@ namespace AMDiS { ...@@ -1549,7 +1549,7 @@ namespace AMDiS {
void ProblemStatSeq::addPeriodicBC(BoundaryType type, int row, int col) void ProblemStatSeq::addPeriodicBC(BoundaryType type, int row, int col)
{ {
boundaryConditionSet = true; boundaryConditionSet = true;
PeriodicBC *periodic = new PeriodicBC(type, componentSpaces[row]); PeriodicBC *periodic = new PeriodicBC(type, componentSpaces[row], row == col);
if (systemMatrix && (*systemMatrix)[row][col]) if (systemMatrix && (*systemMatrix)[row][col])
(*systemMatrix)[row][col]->getBoundaryManager()->addBoundaryCondition(periodic); (*systemMatrix)[row][col]->getBoundaryManager()->addBoundaryCondition(periodic);
......
...@@ -74,9 +74,9 @@ namespace AMDiS { ...@@ -74,9 +74,9 @@ namespace AMDiS {
DegreeOfFreedom *last_edge[2] = {NULL, NULL}; DegreeOfFreedom *last_edge[2] = {NULL, NULL};
int n_neigh_periodic; int n_neigh_periodic;
DegreeOfFreedom newDOF = -1; DegreeOfFreedom *newDOF = NULL;
DegreeOfFreedom lastNewDOF = -1; DegreeOfFreedom *lastNewDOF = NULL;
DegreeOfFreedom firstNewDOF = -1; DegreeOfFreedom *firstNewDOF = NULL;
RCNeighbourList periodicList; RCNeighbourList periodicList;
...@@ -87,23 +87,25 @@ namespace AMDiS { ...@@ -87,23 +87,25 @@ namespace AMDiS {
newDOF = refinePatch(edge, periodicList, n_neigh_periodic, bound); newDOF = refinePatch(edge, periodicList, n_neigh_periodic, bound);
if (firstNewDOF == -1) if (firstNewDOF == NULL)
firstNewDOF = newDOF; firstNewDOF = newDOF;
if (lastNewDOF != -1) { if (lastNewDOF != NULL) {
for (std::map<int, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); for (std::map<int, std::vector<VertexVector*> >::iterator it = mesh->getPeriodicAssociations().begin();
it != mesh->getPeriodicAssociations().end(); ++it) { it != mesh->getPeriodicAssociations().end(); ++it) {
if (it->second) { if (!it->second.empty()) {
if (((*(it->second))[edge[0][0]] == last_edge[0][0] && for (size_t iadmin = 0; iadmin < mesh->getNumberOfDOFAdmin(); iadmin++) {
(*(it->second))[edge[1][0]] == last_edge[1][0]) || if (((*(it->second)[iadmin])[edge[0][iadmin]] == last_edge[0][iadmin] &&
((*(it->second))[edge[0][0]] == last_edge[1][0] && (*(it->second)[iadmin])[edge[1][iadmin]] == last_edge[1][iadmin]) ||
(*(it->second))[edge[1][0]] == last_edge[0][0])) { ((*(it->second[iadmin]))[edge[0][iadmin]] == last_edge[1][iadmin] &&
(*(it->second))[lastNewDOF] = newDOF; (*(it->second)[iadmin])[edge[1][iadmin]] == last_edge[0][iadmin])) {
(*(it->second))[newDOF] = lastNewDOF; (*(it->second)[iadmin])[lastNewDOF[iadmin]] = newDOF[iadmin];
} (*(it->second)[iadmin])[newDOF[iadmin]] = lastNewDOF[iadmin];
}
}
} }
} // for
} // if
} // for
} // if lastNewDOF
lastNewDOF = newDOF; lastNewDOF = newDOF;
last_edge[0] = edge[0]; last_edge[0] = edge[0];
...@@ -114,19 +116,21 @@ namespace AMDiS { ...@@ -114,19 +116,21 @@ namespace AMDiS {
} }
if (lastNewDOF != firstNewDOF) { if (lastNewDOF != firstNewDOF) {
for (std::map<int, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); for (std::map<int, std::vector<VertexVector*> >::iterator it = mesh->getPeriodicAssociations().begin();
it != mesh->getPeriodicAssociations().end(); ++it) { it != mesh->getPeriodicAssociations().end(); ++it) {
if (it->second) { if (!it->second.empty()) {
if (((*(it->second))[first_edge[0][0]] == last_edge[0][0] && for (size_t iadmin = 0; iadmin < mesh->getNumberOfDOFAdmin(); iadmin++) {
(*(it->second))[first_edge[1][0]] == last_edge[1][0]) || if (((*(it->second)[iadmin])[first_edge[0][iadmin]] == last_edge[0][iadmin] &&
((*(it->second))[first_edge[0][0]] == last_edge[1][0] && (*(it->second)[iadmin])[first_edge[1][iadmin]] == last_edge[1][iadmin]) ||
(*(it->second))[first_edge[1][0]] == last_edge[0][0])) { ((*(it->second)[iadmin])[first_edge[0][iadmin]] == last_edge[1][iadmin] &&
(*(it->second))[lastNewDOF] = firstNewDOF; (*(it->second)[iadmin])[first_edge[1][iadmin]] == last_edge[0][iadmin])) {
(*(it->second))[firstNewDOF] = lastNewDOF; (*(it->second)[iadmin])[lastNewDOF[iadmin]] = firstNewDOF[iadmin];
} (*(it->second)[iadmin])[firstNewDOF[iadmin]] = lastNewDOF[iadmin];
}
}
} }
} // for
} // if
} // for
} // if !=
return elInfo; return elInfo;
} }
...@@ -175,7 +179,7 @@ namespace AMDiS { ...@@ -175,7 +179,7 @@ namespace AMDiS {
} }
DegreeOfFreedom RefinementManager2d::refinePatch(DegreeOfFreedom *edge[2], DegreeOfFreedom* RefinementManager2d::refinePatch(DegreeOfFreedom *edge[2],
RCNeighbourList &refineList, RCNeighbourList &refineList,
int n_neigh, bool bound) int n_neigh, bool bound)
{ {
...@@ -242,7 +246,7 @@ namespace AMDiS { ...@@ -242,7 +246,7 @@ namespace AMDiS {
refineList.removeDOFParents(n_neigh); refineList.removeDOFParents(n_neigh);
} }
return dof[0][0]; return dof[0];
} }
......
...@@ -61,7 +61,7 @@ namespace AMDiS { ...@@ -61,7 +61,7 @@ namespace AMDiS {
RCNeighbourList &refineList, int *n_neigh); RCNeighbourList &refineList, int *n_neigh);
/// Refines all elements in the patch. /// Refines all elements in the patch.
DegreeOfFreedom refinePatch(DegreeOfFreedom *edge[2], DegreeOfFreedom* refinePatch(DegreeOfFreedom *edge[2],
RCNeighbourList &refineList, RCNeighbourList &refineList,
int n_neigh, bool bound); int n_neigh, bool bound);
......
...@@ -330,7 +330,7 @@ namespace AMDiS { ...@@ -330,7 +330,7 @@ namespace AMDiS {
} }
DegreeOfFreedom RefinementManager3d::refinePatch(DegreeOfFreedom *edge[2], DegreeOfFreedom* RefinementManager3d::refinePatch(DegreeOfFreedom *edge[2],
RCNeighbourList &refineList, RCNeighbourList &refineList,
int n_neigh, bool bound) int n_neigh, bool bound)