Commit d906fc98 authored by Thomas Witkowski's avatar Thomas Witkowski

Code refactoring, so added some no bugs.

parent a125580e
...@@ -10,57 +10,44 @@ ...@@ -10,57 +10,44 @@
namespace AMDiS { namespace AMDiS {
CoarseningManager* CoarseningManager::traversePtr = NULL;
/****************************************************************************/
/* sets the mark on all elements that have to be coarsend */
/****************************************************************************/
int CoarseningManager::coarsenMarkFunction(ElInfo *el_info)
{
el_info->getElement()->setMark(traversePtr->globalMark);
return 0;
}
/****************************************************************************/ /****************************************************************************/
/* tries to coarsen every element of mesh at least mark times */ /* tries to coarsen every element of mesh at least mark times */
/****************************************************************************/ /****************************************************************************/
Flag CoarseningManager::globalCoarsen(Mesh *aMesh, int mark) Flag CoarseningManager::globalCoarsen(Mesh *aMesh, int mark)
{ {
if (mark >= 0) return(0); if (mark >= 0)
globalMark = mark; return 0;
traversePtr = this;
aMesh->traverse(-1, Mesh::CALL_LEAF_EL, coarsenMarkFunction); TraverseStack stack;
return(coarsenMesh(aMesh)); ElInfo *elInfo = stack.traverseFirst(aMesh, -1, Mesh::CALL_LEAF_EL);
} while (elInfo) {
elInfo->getElement()->setMark(mark);
int CoarseningManager::spreadCoarsenMarkFunction(ElInfo* el_info) elInfo = stack.traverseNext(elInfo);
{
Element *el = el_info->getElement();
signed char mark;
if (el->getChild(0)) {
/****************************************************************************/
/* interior node of the tree */
/****************************************************************************/
mark = max(el->getChild(0)->getMark(), el->getChild(1)->getMark());
el->setMark(std::min(mark + 1, 0));
} else {
/****************************************************************************/
/* leaf node of the tree */
/****************************************************************************/
if (el->getMark() < 0)
el->setMark(el->getMark() - 1);
} }
return 0; return coarsenMesh(aMesh);
} }
void CoarseningManager::spreadCoarsenMark() void CoarseningManager::spreadCoarsenMark()
{ {
traversePtr = this; TraverseStack stack;
mesh->traverse(-1, Mesh::CALL_EVERY_EL_POSTORDER, spreadCoarsenMarkFunction); ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_POSTORDER);
while (elInfo) {
Element *el = elInfo->getElement();
if (el->getChild(0)) {
// interior node of the tree
signed char mark = max(el->getChild(0)->getMark(), el->getChild(1)->getMark());
el->setMark(std::min(mark + 1, 0));
} else {
// leaf node of the tree
if (el->getMark() < 0)
el->setMark(el->getMark() - 1);
}
elInfo = stack.traverseNext(elInfo);
}
} }
...@@ -69,17 +56,15 @@ namespace AMDiS { ...@@ -69,17 +56,15 @@ namespace AMDiS {
/* resets the element marks */ /* resets the element marks */
/****************************************************************************/ /****************************************************************************/
int CoarseningManager::cleanUpAfterCoarsenFunction(ElInfo *el_info)
{
Element *el = el_info->getElement();
el->setMark(max(el->getMark(), 0));
return 0;
}
void CoarseningManager::cleanUpAfterCoarsen() void CoarseningManager::cleanUpAfterCoarsen()
{ {
traversePtr = this; TraverseStack stack;
mesh->traverse(-1, Mesh::CALL_LEAF_EL, cleanUpAfterCoarsenFunction); ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
Element *el = elInfo->getElement();
el->setMark(max(el->getMark(), 0));
elInfo = stack.traverseNext(elInfo);
}
} }
/****************************************************************************/ /****************************************************************************/
......
...@@ -42,7 +42,6 @@ namespace AMDiS { ...@@ -42,7 +42,6 @@ namespace AMDiS {
CoarseningManager() CoarseningManager()
: mesh(NULL), : mesh(NULL),
stack(NULL), stack(NULL),
globalMark(0),
doMore(0) doMore(0)
{} {}
...@@ -92,15 +91,6 @@ namespace AMDiS { ...@@ -92,15 +91,6 @@ namespace AMDiS {
*/ */
void spreadCoarsenMark(); void spreadCoarsenMark();
/// Used while traversal in spreadCoarsenMark
static int spreadCoarsenMarkFunction(ElInfo* el_info);
/// Used while traversal in cleanUpAfterCoarsen
static int cleanUpAfterCoarsenFunction(ElInfo* el_info);
/// Sets the mark on all elements that have to be coarsend
static int coarsenMarkFunction(ElInfo *el_info);
/// Resets the element marks /// Resets the element marks
void cleanUpAfterCoarsen(); void cleanUpAfterCoarsen();
...@@ -111,18 +101,9 @@ namespace AMDiS { ...@@ -111,18 +101,9 @@ namespace AMDiS {
/// Used for non recursive mesh traversal. /// Used for non recursive mesh traversal.
TraverseStack *stack; TraverseStack *stack;
/// Used by globalCoarsen to remember the given mark value
int globalMark;
/// Spezifies whether the coarsening operation is still in progress /// Spezifies whether the coarsening operation is still in progress
bool doMore; bool doMore;
/** \brief
* Used while mesh traversal to have a pointer to this CoarseningManager
* from a static method
*/
static CoarseningManager* traversePtr;
/// Spezifies how many DOFVectors should restricted while coarsening /// Spezifies how many DOFVectors should restricted while coarsening
int callCoarseRestrict; int callCoarseRestrict;
......
...@@ -68,13 +68,6 @@ namespace AMDiS { ...@@ -68,13 +68,6 @@ namespace AMDiS {
double* max, double* max,
bool writeLeafData = false, bool writeLeafData = false,
int comp = 0); int comp = 0);
// methods for traversal
static int maxErrAtQpFct(ElInfo* elinfo);
static int H1ErrFct(ElInfo* elinfo);
static int L2ErrFct(ElInfo* elinfo);
static int relFct(ElInfo* elinfo);
public: public:
static T errUFct(const DimVec<double>& lambda); static T errUFct(const DimVec<double>& lambda);
...@@ -114,13 +107,6 @@ namespace AMDiS { ...@@ -114,13 +107,6 @@ namespace AMDiS {
static const AbstractFunction<WorldVector<T>, WorldVector<double> >* pGrdU; static const AbstractFunction<WorldVector<T>, WorldVector<double> >* pGrdU;
static const BasisFunction* basFct; static const BasisFunction* basFct;
static const DOFVector<T>* errUh; static const DOFVector<T>* errUh;
static double maxErr;
static double l2Err2;
static double l2Norm2;
static int relative;
static double relNorm2;
static double h1Err2;
static double h1Norm2;
static bool writeInLeafData; static bool writeInLeafData;
static int component; static int component;
}; };
...@@ -131,13 +117,6 @@ namespace AMDiS { ...@@ -131,13 +117,6 @@ namespace AMDiS {
template<typename T> const AbstractFunction<WorldVector<T>, WorldVector<double> >* Error<T>::pGrdU = NULL; template<typename T> const AbstractFunction<WorldVector<T>, WorldVector<double> >* Error<T>::pGrdU = NULL;
template<typename T> const BasisFunction* Error<T>::basFct = NULL; template<typename T> const BasisFunction* Error<T>::basFct = NULL;
template<typename T> const DOFVector<T>* Error<T>::errUh = NULL; template<typename T> const DOFVector<T>* Error<T>::errUh = NULL;
template<typename T> double Error<T>::maxErr = 0.0;
template<typename T> double Error<T>::l2Err2 = 0.0;
template<typename T> double Error<T>::l2Norm2 = 0.0;
template<typename T> int Error<T>::relative = 0;
template<typename T> double Error<T>::relNorm2 = 0.0;
template<typename T> double Error<T>::h1Err2 = 0.0;
template<typename T> double Error<T>::h1Norm2 = 0.0;
template<typename T> typename Error<T>::AbstrFctErrU Error<T>::errU; template<typename T> typename Error<T>::AbstrFctErrU Error<T>::errU;
template<typename T> typename Error<T>::AbstrFctGrdErrU Error<T>::grdErrU; template<typename T> typename Error<T>::AbstrFctGrdErrU Error<T>::grdErrU;
template<typename T> bool Error<T>::writeInLeafData = false; template<typename T> bool Error<T>::writeInLeafData = false;
......
#include "Mesh.h" #include "Mesh.h"
#include "Parametric.h" #include "Parametric.h"
#include "Quadrature.h" #include "Quadrature.h"
#include "Traverse.h"
namespace AMDiS { namespace AMDiS {
...@@ -20,150 +21,80 @@ namespace AMDiS { ...@@ -20,150 +21,80 @@ namespace AMDiS {
return ((*pGrdU)(x)); return ((*pGrdU)(x));
} }
template<typename T>
int Error<T>::maxErrAtQpFct(ElInfo* el_info)
{
double err = 0.0;
const double *u_vec, *uh_vec;
elinfo = el_info;
u_vec = quadFast->getQuadrature()->fAtQp(errU, NULL);
uh_vec = errUh->getVecAtQPs(el_info,
NULL,
quadFast,
NULL);
int numPoints = quadFast->getNumPoints();
for (int i = 0; i < numPoints; i++) {
err = u_vec[i] > uh_vec[i] ? u_vec[i] - uh_vec[i] : uh_vec[i] - u_vec[i];
maxErr = max(maxErr, err);
}
return;
}
template<typename T> template<typename T>
double Error<T>::maxErrAtQp(const AbstractFunction<T, WorldVector<double> >& u, double Error<T>::maxErrAtQp(const AbstractFunction<T, WorldVector<double> >& u,
const DOFVector<T>& uh, const DOFVector<T>& uh,
const Quadrature* q) const Quadrature* q)
{ {
FUNCNAME("Error<T>::maxErrAtQp()"); FUNCNAME("Error<T>::maxErrAtQp()");
const FiniteElemSpace *fe_space;
const FiniteElemSpace *fe_space;
if (!(pU = &u)) { if (!(pU = &u)) {
ERROR("no function u specified; doing nothing\n"); ERROR("no function u specified; doing nothing\n");
return(-1.0); return(-1.0);
} }
if (!(errUh = &uh) || !(fe_space = uh->getFESpace())) {
if (!(errUh = &uh) || !(fe_space = uh->getFESpace())) ERROR("no discrete function or no fe_space for it; doing nothing\n");
{ return(-1.0);
ERROR("no discrete function or no fe_space for it; doing nothing\n"); }
return(-1.0); if (!(basFct = fe_space->getBasisFcts())) {
} ERROR("no basis functions at discrete solution ; doing nothing\n");
return(-1.0);
if (!(basFct = fe_space->getBasisFcts())) }
{
ERROR("no basis functions at discrete solution ; doing nothing\n");
return(-1.0);
}
int dim = fe_space->getMesh()->getDim();
if (!q) if (!q)
q = Quadrature::provideQuadrature(dim, q = Quadrature::provideQuadrature(fe_space->getMesh()->getDim(),
2*fe_space->getBasisFcts()->getDegree() 2 * fe_space->getBasisFcts()->getDegree() - 2);
- 2);
quadFast = FastQuadrature::provideFastQuadrature(basFct, *q, INIT_PHI);
maxErr = 0.0; quadFast = FastQuadrature::provideFastQuadrature(basFct, *q, INIT_PHI);
double maxErr = 0.0;
fe_space->getMesh()->traverse(-1, TraverseStack stack;
Mesh::FILL_COORDS | ElInfo *elInfo = stack.traverseFirst(fe_space->getMesh(), -1,
Mesh::CALL_LEAF_EL, Mesh::FILL_COORDS | Mesh::CALL_LEAF_EL);
maxErrAtQpFct); while (elInfo) {
double err = 0.0;
return(maxErr); const double *u_vec, *uh_vec;
}
u_vec = quadFast->getQuadrature()->fAtQp(errU, NULL);
template<typename T> uh_vec = errUh->getVecAtQPs(elInfo, NULL, quadFast, NULL);
int Error<T>::H1ErrFct(ElInfo* el_info)
{ int nPoints = quadFast->getNumPoints();
int i, j; for (int i = 0; i < nPoints; i++) {
double err, err_2, h1_err_el, norm_el, norm2, det, exact; err = u_vec[i] > uh_vec[i] ? u_vec[i] - uh_vec[i] : uh_vec[i] - u_vec[i];
const WorldVector<double> *grdu_vec, *grduh_vec; maxErr = max(maxErr, err);
elinfo = el_info;
grdu_vec = quadFast->getQuadrature()->grdFAtQp(grdErrU, NULL);
det = el_info->getDet();
grduh_vec = errUh->getGrdAtQPs(elinfo, NULL, quadFast, NULL);
int numPoints = quadFast->getNumPoints();
int dow = Global::getGeo(WORLD);
for (h1_err_el = i = 0; i < numPoints; i++)
{
for (err_2 = j = 0; j < dow; j++)
{
err = grdu_vec[i][j] - grduh_vec[i][j];
err_2 += sqr(err);
}
h1_err_el += quadFast->getWeight(i)*err_2;
} }
exact = det*h1_err_el; elInfo = stack.traverseNext(elInfo);
h1Err2 += exact;
maxErr = max(maxErr, exact);
if (writeInLeafData)
el_info->getElement()->setEstimation(exact, component);
if (relative) {
for (norm_el = i = 0; i < numPoints; i++) {
for (norm2 = j = 0; j < dow; j++)
norm2 += sqr(grdu_vec[i][j]);
norm_el += quadFast->getWeight(i)*norm2;
}
h1Norm2 += det*norm_el;
} }
return 0; return maxErr;
} }
template<typename T> template<typename T>
double Error<T>::H1Err( double Error<T>::H1Err(const AbstractFunction<WorldVector<T>, WorldVector<double> > &grdU,
const AbstractFunction<WorldVector<T>, WorldVector<double> >& grdU, const DOFVector<T> &uh,
const DOFVector<T>& uh, int relErr,
int relErr, double* max,
double* max,
bool writeLeafData, bool writeLeafData,
int comp) int comp)
{ {
FUNCNAME("Error<T>::H1Err"); FUNCNAME("Error<T>::H1Err()");
const FiniteElemSpace *fe_space; const FiniteElemSpace *fe_space;
writeInLeafData = writeLeafData; writeInLeafData = writeLeafData;
component = comp; component = comp;
Quadrature *q = NULL; Quadrature *q = NULL;
pGrdU = &grdU; pGrdU = &grdU;
errUh = &uh; errUh = &uh;
if(!(fe_space = uh.getFESpace())) if (!(fe_space = uh.getFESpace())) {
{ ERROR("no fe_space for uh; doing nothing\n");
ERROR("no fe_space for uh; doing nothing\n"); return(0.0);
return(0.0); }
} if (!(basFct = fe_space->getBasisFcts())) {
ERROR("no basis functions at discrete solution ; doing nothing\n");
if (!(basFct = fe_space->getBasisFcts())) return(0.0);
{ }
ERROR("no basis functions at discrete solution ; doing nothing\n");
return(0.0);
}
int dim = fe_space->getMesh()->getDim(); int dim = fe_space->getMesh()->getDim();
int deg = grdU.getDegree(); int deg = grdU.getDegree();
...@@ -174,69 +105,74 @@ namespace AMDiS { ...@@ -174,69 +105,74 @@ namespace AMDiS {
*q, *q,
INIT_GRD_PHI); INIT_GRD_PHI);
relative = relErr; double relative = relErr;
double maxErr = 0.0, h1Err2 = 0.0, h1Norm2 = 0.0;
maxErr = h1Err2 = h1Norm2 = 0.0;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(fe_space->getMesh(), -1,
Mesh::FILL_COORDS |
Mesh::CALL_LEAF_EL |
Mesh::FILL_DET |
Mesh::FILL_GRD_LAMBDA);
while (elInfo) {
int i, j;
double err, err_2, h1_err_el, norm_el, norm2, det, exact;
const WorldVector<double> *grdu_vec, *grduh_vec;
grdu_vec = quadFast->getQuadrature()->grdFAtQp(grdErrU, NULL);
det = elInfo->getDet();
grduh_vec = errUh->getGrdAtQPs(elinfo, NULL, quadFast, NULL);
int nPoints = quadFast->getNumPoints();
int dow = Global::getGeo(WORLD);
for (h1_err_el = i = 0; i < nPoints; i++) {
for (err_2 = j = 0; j < dow; j++) {
err = grdu_vec[i][j] - grduh_vec[i][j];
err_2 += sqr(err);
}
h1_err_el += quadFast->getWeight(i)*err_2;
}
exact = det*h1_err_el;
h1Err2 += exact;
maxErr = std::max(maxErr, exact);
if (writeInLeafData)
elInfo->getElement()->setEstimation(exact, component);
if (relative) {
for (norm_el = i = 0; i < nPoints; i++) {
for (norm2 = j = 0; j < dow; j++)
norm2 += sqr(grdu_vec[i][j]);
norm_el += quadFast->getWeight(i)*norm2;
}
h1Norm2 += det*norm_el;
}
fe_space->getMesh()->traverse(-1, elInfo = stack.traverseNext(elInfo);
Mesh::FILL_COORDS | }
Mesh::CALL_LEAF_EL |
Mesh::FILL_DET |
Mesh::FILL_GRD_LAMBDA,
H1ErrFct);
if (relative) { if (relative) {
relNorm2 = h1Norm2 + 1.e-15; double relNorm2 = h1Norm2 + 1.e-15;
fe_space->getMesh()->traverse(-1, Mesh::CALL_LEAF_EL, relFct); elInfo = stack.traverseFirst(fe_space->getMesh(), -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
double exact = elInfo->getElement()->getEstimation(component) / relNorm2;
if (writeInLeafData)
elinfo->getElement()->setEstimation(exact, component);
elInfo = stack.traverseNext(elInfo);
}
h1Err2 /= relNorm2; h1Err2 /= relNorm2;
maxErr /= relNorm2; maxErr /= relNorm2;
} }
if (max) *max = maxErr; if (max)
*max = maxErr;
return(sqrt(h1Err2));
}
template<typename T>
int Error<T>::L2ErrFct(ElInfo* el_info)
{
int i;
double err, det, l2_err_el, norm_el, exact;
const double *u_vec, *uh_vec;
elinfo = el_info;
u_vec = quadFast->getQuadrature()->fAtQp(errU, NULL);
uh_vec = errUh->getVecAtQPs(el_info,
NULL,
quadFast,
NULL);
det = el_info->getDet();
int numPoints = quadFast->getNumPoints();
for (l2_err_el = i = 0; i < numPoints; i++) {
err = u_vec[i] - uh_vec[i];
l2_err_el += quadFast->getWeight(i)*sqr(err);
}
exact = det*l2_err_el;
l2Err2 += exact;
maxErr = max(maxErr, exact);
if (writeInLeafData) {
el_info->getElement()->setEstimation(exact, component);
}
if (relative) {
for (norm_el = i = 0; i < numPoints; i++)
norm_el += quadFast->getWeight(i)*sqr(u_vec[i]);
l2Norm2 += det*norm_el;
}
return 0; return sqrt(h1Err2);
} }
template<typename T> template<typename T>
...@@ -278,20 +214,58 @@ namespace AMDiS { ...@@ -278,20 +214,58 @@ namespace AMDiS {
q = Quadrature::provideQuadrature(dim, degree); q = Quadrature::provideQuadrature(dim, degree);
quadFast = FastQuadrature::provideFastQuadrature(basFct, *q, INIT_PHI);