Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer,
es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Die Konten der externen Nutzer:innen sind ü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. The accounts of external users can be accessed via the "Standard" tab.
The administrators

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

Work on pdd

parent deafc91a
......@@ -14,7 +14,6 @@
#include "BoundaryCondition.h"
#include "BoundaryManager.h"
#include "Assembler.h"
#include "Utilities.h"
namespace AMDiS {
......
......@@ -276,6 +276,10 @@ namespace AMDiS {
void ParallelDomainProblemBase::createInteriorBoundaryInfo(std::vector<const DegreeOfFreedom*>& rankDOFs,
std::map<const DegreeOfFreedom*, int>& boundaryDOFs)
{
FUNCNAME("ParallelDomainProblemBase::createInteriorBoundaryInfo()");
// === First, create all the information about the interior boundaries. ===
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH);
while (elInfo) {
......@@ -323,20 +327,86 @@ namespace AMDiS {
/// === And add the part of the interior boundary. ===
AtomicBoundary& bound =
interiorBoundary.getNewAtomicBoundary(ranksBoundary ? mpiRank :
partitionVec[elInfo->getNeighbour(i)->getIndex()]);
(ranksBoundary ?
myIntBoundary.getNewAtomicBoundary(partitionVec[elInfo->getNeighbour(i)->getIndex()]) :
otherIntBoundary.getNewAtomicBoundary(partitionVec[elInfo->getNeighbour(i)->getIndex()]));
bound.rankObject.el = element;
bound.rankObject.subObjAtBoundary = EDGE;
bound.rankObject.ithObjAtBoundary = i;
bound.neighbourObject.el = elInfo->getNeighbour(i);
bound.neighbourObject.subObjAtBoundary = EDGE;
bound.neighbourObject.ithObjAtBoundary = -1;
std::cout << "ADD IN " << mpiRank << ": " << element->getIndex() << " " << elInfo->getNeighbour(i)->getIndex() << std::endl;
}
}
}
elInfo = stack.traverseNext(elInfo);
}
// === Once we have this information, we must care about their order. Eventually ===
// === all the boundaries have to be in the same order on both ranks (because ===
// === each boundary is shared by exactly two ranks). ===
std::vector<int*> sendBuffers;
std::vector<int*> recvBuffers;
for (std::map<int, std::vector<AtomicBoundary> >::iterator rankIt = myIntBoundary.boundary.begin();
rankIt != myIntBoundary.boundary.end();
++rankIt) {
int* buffer = new int[rankIt->second.size()];
for (int i = 0; i < static_cast<int>(rankIt->second.size()); i++)
buffer[i] = (rankIt->second)[i].rankObject.el->getIndex();
sendBuffers.push_back(buffer);
mpiComm.Isend(buffer, rankIt->second.size(), MPI_INT, rankIt->first, 0);
}
for (std::map<int, std::vector<AtomicBoundary> >::iterator rankIt = otherIntBoundary.boundary.begin();
rankIt != otherIntBoundary.boundary.end();
++rankIt) {
int *buffer = new int[rankIt->second.size()];
recvBuffers.push_back(buffer);
mpiComm.Irecv(buffer, rankIt->second.size(), MPI_INT, rankIt->first, 0);
}
mpiComm.Barrier();
int i = 0;
for (std::map<int, std::vector<AtomicBoundary> >::iterator rankIt = otherIntBoundary.boundary.begin();
rankIt != otherIntBoundary.boundary.end();
++rankIt) {
// === We have received from rank "rankIt->first" the ordered list of element ===
// === indices. We now have to sort the corresponding list in this rank to ===
// === get the same order. ===
for (int j = 0; j < static_cast<int>(rankIt->second.size()); j++) {
// If the expected object is not at place, search for it.
if ((rankIt->second)[j].neighbourObject.el->getIndex() != recvBuffers[i][j]) {
int k = j + 1;
for (; k < static_cast<int>(rankIt->second.size()); k++)
if ((rankIt->second)[k].neighbourObject.el->getIndex() == recvBuffers[i][j])
break;
// The element must always be found, because the list is just in another order.
TEST_EXIT(k < rankIt->second.size())("Should never happen!\n");
// Swap the current with the found element.
AtomicBoundary tmpBound = (rankIt->second)[k];
(rankIt->second)[k] = (rankIt->second)[j];
(rankIt->second)[j] = tmpBound;
}
}
delete [] recvBuffers[i++];
}
for (int i = 0; i < static_cast<int>(sendBuffers.size()); i++)
delete [] sendBuffers[i];
}
......@@ -527,8 +597,10 @@ namespace AMDiS {
void ParallelDomainProblemBase::updateLocalGlobalNumbering(int& nRankDOFs,
int& nOverallDOFs)
{
FUNCNAME("ParallelDomainProblemBase::updateLocalGlobalNumbering()");
std::set<const DegreeOfFreedom*> rankDOFs;
std::set<const DegreeOfFreedom*> boundaryDOFs;
std::map<const DegreeOfFreedom*, int> boundaryDOFs;
/// === Get all DOFs in ranks partition. ===
......@@ -545,20 +617,105 @@ namespace AMDiS {
}
// === Traverse on interior boundaries and move all not ranked owned DOFs from
// rankDOFs to boundaryDOFs === //
// === Traverse on interior boundaries and move all not ranked owned DOFs from ===
// === rankDOFs to boundaryDOFs ===
for (std::map<int, std::vector<AtomicBoundary> >::iterator it =
interiorBoundary.boundary.begin();
it != interiorBoundary.boundary.end();
myIntBoundary.boundary.begin();
it != myIntBoundary.boundary.end();
++it) {
for (int i = 0; i < it->second.size(); i++) {
for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin();
boundIt != it->second.end();
++boundIt) {
const DegreeOfFreedom *dof1 = NULL;
const DegreeOfFreedom *dof2 = NULL;
switch (boundIt->rankObject.ithObjAtBoundary) {
case 0:
dof1 = boundIt->rankObject.el->getDOF(1);
dof2 = boundIt->rankObject.el->getDOF(2);
break;
case 1:
dof1 = boundIt->rankObject.el->getDOF(0);
dof2 = boundIt->rankObject.el->getDOF(2);
break;
case 2:
dof1 = boundIt->rankObject.el->getDOF(0);
dof2 = boundIt->rankObject.el->getDOF(1);
break;
default:
ERROR_EXIT("Should never happen!\n");
}
std::vector<const DegreeOfFreedom*> boundDOFs;
addAllDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary,
boundDOFs);
}
}
}
void ParallelDomainProblemBase::addAllDOFs(Element *el, int ithEdge,
std::vector<const DegreeOfFreedom*>& dofs,
bool addVertices)
{
FUNCNAME("ParallelDomainProblemBase::addAllDOFs()");
const DegreeOfFreedom* boundDOF1 = NULL;
const DegreeOfFreedom* boundDOF2 = NULL;
if (addVertices) {
switch (ithEdge) {
case 0:
boundDOF1 = el->getDOF(1);
boundDOF2 = el->getDOF(2);
break;
case 1:
boundDOF1 = el->getDOF(0);
boundDOF2 = el->getDOF(2);
break;
case 2:
boundDOF1 = el->getDOF(0);
boundDOF2 = el->getDOF(1);
break;
default:
ERROR_EXIT("Should never happen!\n");
}
dofs.push_back(boundDOF1);
}
switch (ithEdge) {
case 0:
if (el->getSecondChild() && el->getSecondChild()->getFirstChild()) {
addAllDOFs(el->getSecondChild()->getFirstChild(), 0, dofs, false);
dofs.push_back(el->getSecondChild()->getFirstChild()->getDOF(2));
addAllDOFs(el->getSecondChild()->getSecondChild(), 1, dofs, false);
}
break;
case 1:
if (el->getFirstChild() && el->getFirstChild()->getFirstChild()) {
addAllDOFs(el->getFirstChild()->getFirstChild(), 0, dofs, false);
dofs.push_back(el->getFirstChild()->getFirstChild()->getDOF(2));
addAllDOFs(el->getFirstChild()->getSecondChild(), 1, dofs, false);
}
break;
case 2:
if (el->getFirstChild()) {
addAllDOFs(el->getFirstChild(), 0, dofs, false);
dofs.push_back(el->getFirstChild()->getDOF(2));
addAllDOFs(el->getSecondChild(), 1, dofs, false);
}
break;
default:
ERROR_EXIT("Should never happen!\n");
}
if (addVertices)
dofs.push_back(boundDOF2);
}
void ParallelDomainProblemBase::createDOFMemberInfo(
std::map<const DegreeOfFreedom*, std::set<int> >& partitionDOFs,
std::vector<const DegreeOfFreedom*>& rankDOFs,
......
......@@ -137,9 +137,15 @@ namespace AMDiS {
void updateLocalGlobalNumbering(int& nRankDOFs, int& nOverallDOFs);
void addAllDOFs(Element *el, int ithEdge,
std::vector<const DegreeOfFreedom*>& dofs,
bool addVertices = true);
/** \brief
* This function traverses the whole mesh, i.e. before it is really partitioned,
* and collects information about which DOF corresponds to which rank.
* and collects information about which DOF corresponds to which rank. Can only
* be used, if \ref partitionVec is set correctly. This is only the case, when
* the macro mesh is partitioned.
*
* @param[out] partionDOFs Stores to each DOF pointer the set of ranks the DOF is
* part of.
......@@ -215,10 +221,20 @@ namespace AMDiS {
int nRankDOFs;
/** \brief
* Defines the interioir boundaries of the domain that result from partitioning
* the whole mesh.
* Defines the interior boundaries of the domain that result from partitioning
* the whole mesh. Contains only the boundaries, which are owned by the rank, i.e.,
* the object gives for every neighbour rank i the boundaries this rank owns and
* shares with rank i.
*/
InteriorBoundary myIntBoundary;
/** \brief
* Defines the interior boundaries of the domain that result from partitioning
* the whole mesh. Contains only the boundaries, which are not owned by the rank,
* i.e., the object gives for every neighbour rank i the boundaries that are
* owned by rank i and are shared with this rank.
*/
InteriorBoundary interiorBoundary;
InteriorBoundary otherIntBoundary;
/** \brief
* This map contains for each rank the list of dofs the current rank must send
......
......@@ -51,7 +51,8 @@ namespace AMDiS {
/** \brief
* Returns a new UmfPackSolver object.
*/
OEMSolver* create() {
OEMSolver* create()
{
return new UmfPackSolver(this->name);
}
};
......@@ -67,7 +68,11 @@ namespace AMDiS {
}
/// Destructor
~UmfPackSolver() { if (solver) delete solver;}
~UmfPackSolver()
{
if (solver)
delete solver;
}
/// Solves the system directly
int solveSystem(const DOFMatrix::base_matrix_type& A,
......
// ============================================================================
// == ==
// == AMDiS - Adaptive multidimensional simulations ==
// == ==
// ============================================================================
// == ==
// == crystal growth group ==
// == ==
// == Stiftung caesar ==
// == Ludwig-Erhard-Allee 2 ==
// == 53175 Bonn ==
// == germany ==
// == ==
// ============================================================================
// == ==
// == http://www.caesar.de/cg/AMDiS ==
// == ==
// ============================================================================
/** \file Utilities.h */
#ifndef AMDIS_UTILITIES_H
#define AMDIS_UTILITIES_H
#include <vector>
#include <algorithm>
template <typename T>
std::vector<T> inline invert_reorder(const std::vector<T>& v)
{
T my_max= *std::max_element(v.begin(), v.end()) + 1;
std::vector<T> u(my_max, T(-1));
for (int i= 0; i < v.size(); i++)
if (v[i] >= 0) {
assert(u[v[i]] == -1); // check double insertion
u[v[i]]= T(i);
}
assert(find(u.begin(), u.end(), T(-1)) == u.end()); // check if all entries are set
return u;
}
#endif // AMDIS_UTILITIES_H
......@@ -29,18 +29,10 @@
#include "Flag.h"
#include "Mesh.h"
#include "DataCollector.h"
#include "AMDiS_fwd.h"
namespace AMDiS {
class DOFAdmin;
class ElInfo;
template<typename T> class DOFVector;
// ============================================================================
// ===== class ValueWriter ====================================================
// ============================================================================
/** \ingroup Output
* \brief
* ValueWriter is a static class which writes the values of a DOFVector
......@@ -53,9 +45,7 @@ namespace AMDiS {
class ValueWriter
{
public:
/** \brief
* Writes DOFVector values to values->feSpace->mesh.
*/
/// Writes DOFVector values to values->feSpace->mesh.
static void writeValues(DataCollector *dc,
const std::string filename,
double time = 0.0,
......@@ -64,34 +54,22 @@ namespace AMDiS {
bool (*writeElem)(ElInfo*) = NULL);
protected:
/** \brief
* File to which the values should be written
*/
/// File to which the values should be written
static FILE *valueFile;
/** \brief
* Global interpolation point indexing
*/
/// Global interpolation point indexing
static DOFVector<int> *interpPointInd;
/** \brief
* list of coords for each dof
*/
/// list of coords for each dof
static DOFVector< std::list<WorldVector<double> > > *dofCoords;
/** \brief
* DOFAdmin of values
*/
/// DOFAdmin of values
static const DOFAdmin *admin;
/** \brief
* Pointer to have a global access to values
*/
/// Pointer to have a global access to values
static DOFVector<double> *valueVec;
/** \brief
* Total number of interpolation points.
*/
/// Total number of interpolation points.
static int ni;
};
......
......@@ -26,35 +26,27 @@
namespace AMDiS {
/** \brief
* Stores coordinates and output index for one vertex.
*/
/// Stores coordinates and output index for one vertex.
class VertexInfo
{
public:
/** \brief
* Coordinates for this vertex.
*/
/// Coordinates for this vertex.
WorldVector<double> coords;
/** \brief
* Index for the output file.
*/
/// Index for the output file.
int outputIndex;
/** \brief
* Used to check, whether coords are already stored for a given dof.
*/
bool operator==(const WorldVector<double>& c) {
/// Used to check, whether coords are already stored for a given dof.
bool operator==(const WorldVector<double>& c)
{
return (c == coords);
};
}
/** \brief
* Used to check, whether coords are already stored for a given dof.
*/
bool operator!=(const WorldVector<double>& c) {
/// Used to check, whether coords are already stored for a given dof.
bool operator!=(const WorldVector<double>& c)
{
return (c != coords);
};
}
};
}
......
......@@ -21,24 +21,27 @@ namespace AMDiS {
~VertexVector();
const DOFAdmin *getAdmin() { return admin; };
const DOFAdmin *getAdmin()
{
return admin;
}
void resize(int size) {
int i, oldSize = static_cast<int>(vec.size());
void resize(int size)
{
int oldSize = static_cast<int>(vec.size());
vec.resize(size);
for(i = oldSize; i < size; i++) {
for (int i = oldSize; i < size; i++)
vec[i] = i;
}
}
void set(DegreeOfFreedom val);
void compressDOFContainer(int size, std::vector<DegreeOfFreedom> &newDOF) {
void compressDOFContainer(int size, std::vector<DegreeOfFreedom> &newDOF)
{
DOFContainer::compressDOFContainer(size, newDOF);
int totalSize = getAdmin()->getSize();
for(int i = size; i < totalSize; i++) {
for(int i = size; i < totalSize; i++)
vec[i] = i;
}
}
protected:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment