Commit 1f9daa76 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Added some parallel debuging test for periodic boundary conditions.

parent d5e4c931
...@@ -367,7 +367,7 @@ namespace AMDiS { ...@@ -367,7 +367,7 @@ namespace AMDiS {
/// Sets \ref timestepNumber. /// Sets \ref timestepNumber.
inline void setTimestepNumber(int num) inline void setTimestepNumber(int num)
{ {
timestepNumber = AMDiS::min(nTimesteps,num); timestepNumber = std::min(nTimesteps, num);
} }
/// Returns \ref nTimesteps. /// Returns \ref nTimesteps.
...@@ -379,7 +379,7 @@ namespace AMDiS { ...@@ -379,7 +379,7 @@ namespace AMDiS {
/// Sets \ref nTimesteps. /// Sets \ref nTimesteps.
inline void setNumberOfTimesteps(int num) inline void setNumberOfTimesteps(int num)
{ {
nTimesteps = AMDiS::max(0,num); nTimesteps = std::max(0, num);
} }
/// Increments \ref timestepNumber by 1; /// Increments \ref timestepNumber by 1;
......
...@@ -43,4 +43,4 @@ namespace AMDiS { ...@@ -43,4 +43,4 @@ namespace AMDiS {
} }
#endif // _Boundary_H_ #endif
...@@ -45,7 +45,7 @@ namespace AMDiS { ...@@ -45,7 +45,7 @@ namespace AMDiS {
if (el->getChild(0)) { if (el->getChild(0)) {
// interior node of the tree // interior node of the tree
int mark = max(el->getChild(0)->getMark(), el->getChild(1)->getMark()); int mark = std::max(el->getChild(0)->getMark(), el->getChild(1)->getMark());
el->setMark(std::min(mark + 1, 0)); el->setMark(std::min(mark + 1, 0));
} else { } else {
// leaf node of the tree // leaf node of the tree
...@@ -63,7 +63,7 @@ namespace AMDiS { ...@@ -63,7 +63,7 @@ namespace AMDiS {
ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
while (elInfo) { while (elInfo) {
Element *el = elInfo->getElement(); Element *el = elInfo->getElement();
el->setMark(max(el->getMark(), 0)); el->setMark(std::max(el->getMark(), 0));
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
} }
......
...@@ -57,7 +57,7 @@ namespace AMDiS { ...@@ -57,7 +57,7 @@ namespace AMDiS {
int mark0 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>(parent->getChild(0)))); int mark0 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>(parent->getChild(0))));
int mark1 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1)))); int mark1 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1))));
mark = max(mark0, mark1); mark = std::max(mark0, mark1);
child[0] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(0))); child[0] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(0)));
child[1] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1))); child[1] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1)));
......
...@@ -167,7 +167,7 @@ namespace AMDiS { ...@@ -167,7 +167,7 @@ namespace AMDiS {
usedCount++; usedCount++;
if (holeCount > 0) if (holeCount > 0)
holeCount--; holeCount--;
sizeUsed = max(sizeUsed, dof + 1); sizeUsed = std::max(sizeUsed, dof + 1);
return dof; return dof;
} }
...@@ -182,7 +182,7 @@ namespace AMDiS { ...@@ -182,7 +182,7 @@ namespace AMDiS {
if (old > minsize) if (old > minsize)
return; return;
int newval = max(minsize, static_cast<int>((dofFree.size() + sizeIncrement))); int newval = std::max(minsize, static_cast<int>((dofFree.size() + sizeIncrement)));
size = newval; size = newval;
...@@ -324,7 +324,7 @@ namespace AMDiS { ...@@ -324,7 +324,7 @@ namespace AMDiS {
for (std::list<DOFContainer*>::iterator dc = dofContainerList.begin(); for (std::list<DOFContainer*>::iterator dc = dofContainerList.begin();
dc != dofContainerList.end(); ++dc) dc != dofContainerList.end(); ++dc)
(*dc)->compressDofContainer(n, newDofIndex); (*dc)->compressDofContainer(n, newDofIndex);
} }
......
...@@ -173,7 +173,7 @@ namespace AMDiS { ...@@ -173,7 +173,7 @@ namespace AMDiS {
} }
/// Dereferntiation of the \ref dofFreeIterator /// Dereferntiation of the \ref dofFreeIterator
virtual bool isDOFFree() virtual bool isDofFree()
{ {
return *dofFreeIterator; return *dofFreeIterator;
} }
......
...@@ -77,7 +77,7 @@ namespace AMDiS { ...@@ -77,7 +77,7 @@ namespace AMDiS {
for (int i = 0; i < nPoints; i++) { for (int i = 0; i < nPoints; i++) {
err = u_vec[i] > uh_vec[i] ? u_vec[i] - uh_vec[i] : uh_vec[i] - u_vec[i]; err = u_vec[i] > uh_vec[i] ? u_vec[i] - uh_vec[i] : uh_vec[i] - u_vec[i];
maxErr = max(maxErr, err); maxErr = std::max(maxErr, err);
} }
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
......
...@@ -117,17 +117,6 @@ namespace AMDiS { ...@@ -117,17 +117,6 @@ namespace AMDiS {
// ===== some simple template functions ====================================== // ===== some simple template functions ======================================
/// template<typename T> T max(T a,T b ) {return ((a) > (b) ? (a) : (b));}
template<typename T,typename S> inline T max(T a,S b )
{
return ((a) > (b) ? (a) : (b));
}
template<typename T> inline T min(T a,T b)
{
return ((a) < (b)) ? (a) : (b);
}
template<typename T> inline T abs(T a) template<typename T> inline T abs(T a)
{ {
return ((a) >= 0 ? (a) : -(a)); return ((a) >= 0 ? (a) : -(a));
......
...@@ -42,15 +42,17 @@ namespace AMDiS { ...@@ -42,15 +42,17 @@ namespace AMDiS {
return 0; return 0;
} }
inline double Phi1ToR(double p1, double eps) { inline double Phi1ToR(double p1, double eps)
double x = max(-1.0 + numeric_limits< double >::epsilon(), {
min(1.0 - numeric_limits< double >::epsilon(), p1)); double x = std::max(-1.0 + numeric_limits<double>::epsilon(),
std::min(1.0 - numeric_limits<double>::epsilon(), p1));
return eps / 3.0 * log((1 + x) / (1 - x)) * 0.5; return eps / 3.0 * log((1 + x) / (1 - x)) * 0.5;
} }
inline double Phi2ToR(double p2, double eps) { inline double Phi2ToR(double p2, double eps)
double x = max(-1.0 + numeric_limits< double >::epsilon(), {
min(1.0 - numeric_limits< double >::epsilon(), 1 + 2 * p2)); double x = std::max(-1.0 + numeric_limits<double>::epsilon(),
std::min(1.0 - numeric_limits<double>::epsilon(), 1 + 2 * p2));
return eps / 3.0 * log( (1 + x) / (1 - x) ); return eps / 3.0 * log( (1 + x) / (1 - x) );
} }
......
...@@ -102,9 +102,12 @@ namespace AMDiS { ...@@ -102,9 +102,12 @@ namespace AMDiS {
changeIndex(0), changeIndex(0),
final_lambda(dimension, DEFAULT_VALUE, 0.0) final_lambda(dimension, DEFAULT_VALUE, 0.0)
{ {
FUNCNAME("Mesh::Mesh()"); FUNCNAME("Mesh::Mesh()");
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
nParallelPreRefinements = 0;
#endif
// set default element prototype // set default element prototype
switch(dim) { switch(dim) {
case 1: case 1:
...@@ -1248,42 +1251,41 @@ namespace AMDiS { ...@@ -1248,42 +1251,41 @@ namespace AMDiS {
// nMacroElements * 2^gr >= nProcs * 10 // nMacroElements * 2^gr >= nProcs * 10
// => gr = log_2(nProcs * 10 / nMacroElements) // => gr = log_2(nProcs * 10 / nMacroElements)
double tmp = 10.0 * MPI::COMM_WORLD.Get_size() / nMacroElements; double scale = 10.0 * MPI::COMM_WORLD.Get_size() / nMacroElements;
int nrRefine = ceil(log(tmp) / log(2)); nParallelPreRefinements = static_cast<int>(std::max(0.0, ceil(log(scale) / log(2))));
if (nrRefine < 0)
nrRefine = 0;
if (dim == 3) { if (dim == 3) {
int newElType = (elType + nrRefine) % 3; int newElType = (elType + nParallelPreRefinements) % 3;
switch (newElType) { switch (newElType) {
case 1: case 1:
if (nrRefine > 0) if (nParallelPreRefinements > 0)
nrRefine--; nParallelPreRefinements--;
else else
nrRefine = 2; nParallelPreRefinements = 2;
break; break;
case 2: case 2:
nrRefine++; nParallelPreRefinements++;
break; break;
} }
TEST_EXIT((elType + nrRefine) % 3 == 0)("This should not happen!\n"); TEST_EXIT((elType + nParallelPreRefinements) % 3 == 0)
("This should not happen!\n");
} }
// === Check if number of pre refinements is set ini init file. === // === Check if number of pre refinements is set ini init file. ===
int nPreRefine = 0; int tmp = 0;
GET_PARAMETER(0, "parallel->pre refine", "%d", &nPreRefine); GET_PARAMETER(0, "parallel->pre refine", "%d", &tmp);
if (nPreRefine != 0) { if (tmp != 0) {
MSG("Calculated %d pre refines to be useful, but %d are set in init file!\n", MSG("Calculated %d pre refines to be useful, but %d are set in init file!\n",
nrRefine, nPreRefine); nParallelPreRefinements, tmp);
nrRefine = nPreRefine; nParallelPreRefinements = tmp;
} }
// === If we do not need to refine the mesh, return back. === // === If we do not need to refine the mesh, return back. ===
if (nrRefine == 0) if (nParallelPreRefinements == 0)
return; return;
...@@ -1323,7 +1325,7 @@ namespace AMDiS { ...@@ -1323,7 +1325,7 @@ namespace AMDiS {
else else
refManager = new RefinementManager3d(); refManager = new RefinementManager3d();
refManager->globalRefine(&testMesh, nrRefine); refManager->globalRefine(&testMesh, nParallelPreRefinements);
delete refManager; delete refManager;
Lagrange* basFcts = Lagrange::getLagrange(dim, 1); Lagrange* basFcts = Lagrange::getLagrange(dim, 1);
...@@ -1348,21 +1350,20 @@ namespace AMDiS { ...@@ -1348,21 +1350,20 @@ namespace AMDiS {
int globalRefinements = 0; int globalRefinements = 0;
GET_PARAMETER(0, name + "->global refinements", "%d", &globalRefinements); GET_PARAMETER(0, name + "->global refinements", "%d", &globalRefinements);
if (globalRefinements < nrRefine) if (globalRefinements < nParallelPreRefinements)
globalRefinements = 0; globalRefinements = 0;
else else
globalRefinements -= nrRefine; globalRefinements -= nParallelPreRefinements;
std::stringstream oss; std::stringstream oss;
oss << globalRefinements; oss << globalRefinements;
ADD_PARAMETER(0, name + "->global refinements", oss.str().c_str()); ADD_PARAMETER(0, name + "->global refinements", oss.str().c_str());
// === Print a note to the screen that another mesh file will be used. === // === Print a note to the screen that another mesh file will be used. ===
MSG("The macro mesh file \"%s\" was refined %d times and stored to file \"%s\".\n", MSG("The macro mesh file \"%s\" was refined %d times and stored to file \"%s\".\n",
macroFilename.c_str(), nrRefine, newMacroFilename.str().c_str()); macroFilename.c_str(), nParallelPreRefinements, newMacroFilename.str().c_str());
macroFilename = newMacroFilename.str(); macroFilename = newMacroFilename.str();
if (periodicFilename != "") if (periodicFilename != "")
......
...@@ -608,6 +608,21 @@ namespace AMDiS { ...@@ -608,6 +608,21 @@ namespace AMDiS {
/// ///
void deleteMeshStructure(); void deleteMeshStructure();
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
/// In parallel computations the level of all macro elements is equal to the number
/// of global pre refinements, \ref nParallelPreRefinements.
inline int getMacroElementLevel()
{
return nParallelPreRefinements;
}
#else
/// In sequentiel computations the level of all macro elements is always 0.
inline int getMacroElementLevel()
{
return 0;
}
#endif
public: public:
/// ///
static const Flag FILL_NOTHING; static const Flag FILL_NOTHING;
...@@ -702,6 +717,12 @@ namespace AMDiS { ...@@ -702,6 +717,12 @@ namespace AMDiS {
void checkParallelMacroFile(std::string &macroFilename, void checkParallelMacroFile(std::string &macroFilename,
std::string &periodicFilename, std::string &periodicFilename,
int check); int check);
/// Returns \ref nParallelPreRefinements
int getParallelPreRefinements() const
{
return nParallelPreRefinements;
}
#endif #endif
protected: protected:
...@@ -855,6 +876,13 @@ namespace AMDiS { ...@@ -855,6 +876,13 @@ namespace AMDiS {
*/ */
long changeIndex; long changeIndex;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
/// In parallel computations the mesh may be globally prerefined to achieve a fine
/// enought starting mesh for the given number of ranks. The value of the variable
/// will be defined in function \ref checkParallelMacroFile.
int nParallelPreRefinements;
#endif
protected: protected:
/// for findElement-Fcts /// for findElement-Fcts
DimVec<double> final_lambda; DimVec<double> final_lambda;
......
...@@ -53,7 +53,7 @@ namespace AMDiS { ...@@ -53,7 +53,7 @@ namespace AMDiS {
for (int i = 0; i < static_cast<int>(terms->size()); i++) { for (int i = 0; i < static_cast<int>(terms->size()); i++) {
OperatorTerm *term = (*terms)[i]; OperatorTerm *term = (*terms)[i];
maxTermDegree = max(maxTermDegree, term->degree); maxTermDegree = std::max(maxTermDegree, term->degree);
} }
return psiDegree + phiDegree - order + maxTermDegree; return psiDegree + phiDegree - order + maxTermDegree;
......
...@@ -50,7 +50,7 @@ namespace AMDiS { ...@@ -50,7 +50,7 @@ namespace AMDiS {
if (Parameters::singlett->paramInfo) { if (Parameters::singlett->paramInfo) {
if (Parameters::singlett->paramInfo > 1) if (Parameters::singlett->paramInfo > 1)
info = max(info, Parameters::singlett->paramInfo - 1); info = std::max(info, Parameters::singlett->paramInfo - 1);
} else { } else {
info = 0; info = 0;
} }
......
...@@ -41,7 +41,7 @@ namespace AMDiS { ...@@ -41,7 +41,7 @@ namespace AMDiS {
child[0] = dynamic_cast<Line*>(mesh->createNewElement(el)); child[0] = dynamic_cast<Line*>(mesh->createNewElement(el));
child[1] = dynamic_cast<Line*>(mesh->createNewElement(el)); child[1] = dynamic_cast<Line*>(mesh->createNewElement(el));
int mark = max(0, el->getMark() - 1); int mark = std::max(0, el->getMark() - 1);
child[0]->setMark(mark); child[0]->setMark(mark);
child[1]->setMark(mark); child[1]->setMark(mark);
el->setMark(0); el->setMark(0);
......
...@@ -257,7 +257,7 @@ namespace AMDiS { ...@@ -257,7 +257,7 @@ namespace AMDiS {
child[0] = dynamic_cast<Triangle*>(mesh->createNewElement(el)); child[0] = dynamic_cast<Triangle*>(mesh->createNewElement(el));
child[1] = dynamic_cast<Triangle*>(mesh->createNewElement(el)); child[1] = dynamic_cast<Triangle*>(mesh->createNewElement(el));
int newMark = max(0, el->getMark() - 1); int newMark = std::max(0, el->getMark() - 1);
child[0]->setMark(newMark); child[0]->setMark(newMark);
child[1]->setMark(newMark); child[1]->setMark(newMark);
el->setMark(0); el->setMark(0);
...@@ -334,7 +334,7 @@ namespace AMDiS { ...@@ -334,7 +334,7 @@ namespace AMDiS {
int opp_vertex = (*elInfo)->getOppVertex(2); int opp_vertex = (*elInfo)->getOppVertex(2);
ElInfo *neigh_info = stack->traverseNeighbour2d(*elInfo, 2); ElInfo *neigh_info = stack->traverseNeighbour2d(*elInfo, 2);
neigh_info->getElement()->setMark(max(neigh_info->getElement()->getMark(), 1)); neigh_info->getElement()->setMark(std::max(neigh_info->getElement()->getMark(), 1));
neigh_info = refineFunction(neigh_info); neigh_info = refineFunction(neigh_info);
// === Now go back to the original element and refine the patch. === // === Now go back to the original element and refine the patch. ===
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "DOFVector.h" #include "DOFVector.h"
#include "PeriodicBC.h" #include "PeriodicBC.h"
#include "VertexVector.h" #include "VertexVector.h"
#include "Debug.h"
namespace AMDiS { namespace AMDiS {
...@@ -41,7 +42,7 @@ namespace AMDiS { ...@@ -41,7 +42,7 @@ namespace AMDiS {
child[0] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el)); child[0] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el));
child[1] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el)); child[1] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el));
int mark = max(0, el->getMark() - 1); int mark = std::max(0, el->getMark() - 1);
child[0]->setMark(mark); child[0]->setMark(mark);
child[1]->setMark(mark); child[1]->setMark(mark);
el->setMark(0); el->setMark(0);
...@@ -249,6 +250,8 @@ namespace AMDiS { ...@@ -249,6 +250,8 @@ namespace AMDiS {
int RefinementManager3d::newCoordsFct(ElInfo *el_info) int RefinementManager3d::newCoordsFct(ElInfo *el_info)
{ {
FUNCNAME("RefinementManager3d::newCoordsFct()");
Element *el = el_info->getElement(); Element *el = el_info->getElement();
DegreeOfFreedom *edge[2]; DegreeOfFreedom *edge[2];
ElInfo *elinfo = el_info; ElInfo *elinfo = el_info;
...@@ -474,7 +477,7 @@ namespace AMDiS { ...@@ -474,7 +477,7 @@ namespace AMDiS {
// Only 0 can be a compatible commen refinement edge. Thus, neigh has not // Only 0 can be a compatible commen refinement edge. Thus, neigh has not
// a compatible refinement edge. Refine it first. // a compatible refinement edge. Refine it first.
neigh->setMark(max(neigh->getMark(), 1)); neigh->setMark(std::max(neigh->getMark(), 1));
neighInfo = refineFunction(neighInfo); neighInfo = refineFunction(neighInfo);
......
...@@ -256,7 +256,7 @@ namespace AMDiS { ...@@ -256,7 +256,7 @@ namespace AMDiS {
el->setEstimation(est_el, row); el->setEstimation(est_el, row);
el->setMark(0); el->setMark(0);
est_sum += est_el; est_sum += est_el;
est_max = max(est_max, est_el); est_max = std::max(est_max, est_el);
} }
...@@ -295,7 +295,7 @@ namespace AMDiS { ...@@ -295,7 +295,7 @@ namespace AMDiS {
} }
double v = C3 * det * result; double v = C3 * det * result;
est_t_sum += v; est_t_sum += v;
est_t_max = max(est_t_max, v); est_t_max = std::max(est_t_max, v);
} }
} }
} }
......
...@@ -274,7 +274,7 @@ namespace AMDiS { ...@@ -274,7 +274,7 @@ namespace AMDiS {
DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0]; DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0];
DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0]; DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0];
DofEdge edge = std::make_pair(min(dof0, dof1), max(dof0, dof1)); DofEdge edge = std::make_pair(std::min(dof0, dof1), std::max(dof0, dof1));
return edge; return edge;
} }
......
...@@ -178,7 +178,7 @@ namespace AMDiS { ...@@ -178,7 +178,7 @@ namespace AMDiS {
DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0]; DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0];
DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0]; DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0];
DofEdge edge = std::make_pair(min(dof0, dof1), max(dof0, dof1)); DofEdge edge = std::make_pair(std::min(dof0, dof1), std::max(dof0, dof1));
return edge; return edge;
} }
......
...@@ -26,29 +26,33 @@ namespace AMDiS { ...@@ -26,29 +26,33 @@ namespace AMDiS {
const_cast<DOFAdmin*>(admin)->addDOFContainer(this); const_cast<DOFAdmin*>(admin)->addDOFContainer(this);
} }