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

* Exact error computation

parent b6628156
...@@ -188,7 +188,7 @@ namespace AMDiS { ...@@ -188,7 +188,7 @@ namespace AMDiS {
// for all elements ... // for all elements ...
for (int i = 0; i < nComponents; i++) { for (int i = 0; i < nComponents; i++) {
elInfo = stack.traverseFirst(componentMeshes_[i], -1, elInfo = stack.traverseFirst(componentMeshes[i], -1,
Mesh::CALL_LEAF_EL | Mesh::CALL_LEAF_EL |
Mesh::FILL_BOUND | Mesh::FILL_BOUND |
Mesh::FILL_COORDS | Mesh::FILL_COORDS |
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "RobinBC.h" #include "RobinBC.h"
#include "PeriodicBC.h" #include "PeriodicBC.h"
#include "Lagrange.h" #include "Lagrange.h"
#include "Flag.h"
namespace AMDiS { namespace AMDiS {
...@@ -45,7 +46,7 @@ namespace AMDiS { ...@@ -45,7 +46,7 @@ namespace AMDiS {
adoptFlag.isSet(INIT_SYSTEM) || adoptFlag.isSet(INIT_SYSTEM) ||
adoptFlag.isSet(INIT_FE_SPACE))) { adoptFlag.isSet(INIT_FE_SPACE))) {
meshes_ = adoptProblem->getMeshes(); meshes_ = adoptProblem->getMeshes();
componentMeshes_ = adoptProblem->componentMeshes_; componentMeshes = adoptProblem->componentMeshes;
refinementManager_ = adoptProblem->refinementManager_; refinementManager_ = adoptProblem->refinementManager_;
coarseningManager_ = adoptProblem->coarseningManager_; coarseningManager_ = adoptProblem->coarseningManager_;
} }
...@@ -180,7 +181,7 @@ namespace AMDiS { ...@@ -180,7 +181,7 @@ namespace AMDiS {
{ {
FUNCNAME("ProblemVec::createMesh()"); FUNCNAME("ProblemVec::createMesh()");
componentMeshes_.resize(nComponents); componentMeshes.resize(nComponents);
std::map<int, Mesh*> meshForRefinementSet; std::map<int, Mesh*> meshForRefinementSet;
char number[3]; char number[3];
...@@ -203,7 +204,7 @@ namespace AMDiS { ...@@ -203,7 +204,7 @@ namespace AMDiS {
meshForRefinementSet[refSet] = newMesh; meshForRefinementSet[refSet] = newMesh;
meshes_.push_back(newMesh); meshes_.push_back(newMesh);
} }
componentMeshes_[i] = meshForRefinementSet[refSet]; componentMeshes[i] = meshForRefinementSet[refSet];
} }
switch(dim) { switch(dim) {
case 1: case 1:
...@@ -243,17 +244,17 @@ namespace AMDiS { ...@@ -243,17 +244,17 @@ namespace AMDiS {
TEST_EXIT(componentSpaces[i] == NULL)("feSpace already created\n"); TEST_EXIT(componentSpaces[i] == NULL)("feSpace already created\n");
if (feSpaceMap[std::pair<Mesh*, int>(componentMeshes_[i], degree)] == NULL) { if (feSpaceMap[std::pair<Mesh*, int>(componentMeshes[i], degree)] == NULL) {
FiniteElemSpace *newFESpace = FiniteElemSpace *newFESpace =
FiniteElemSpace::provideFESpace(NULL, FiniteElemSpace::provideFESpace(NULL,
Lagrange::getLagrange(dim, degree), Lagrange::getLagrange(dim, degree),
componentMeshes_[i], componentMeshes[i],
name_ + "->feSpace"); name_ + "->feSpace");
feSpaceMap[std::pair<Mesh*, int>(componentMeshes_[i], degree)] = newFESpace; feSpaceMap[std::pair<Mesh*, int>(componentMeshes[i], degree)] = newFESpace;
feSpaces.push_back(newFESpace); feSpaces.push_back(newFESpace);
} }
componentSpaces[i] = componentSpaces[i] =
feSpaceMap[std::pair<Mesh*, int>(componentMeshes_[i], degree)]; feSpaceMap[std::pair<Mesh*, int>(componentMeshes[i], degree)];
} }
// create dof admin for vertex dofs if neccessary // create dof admin for vertex dofs if neccessary
...@@ -459,14 +460,14 @@ namespace AMDiS { ...@@ -459,14 +460,14 @@ namespace AMDiS {
std::vector< DOFVector<double>* > solutionList(nComponents); std::vector< DOFVector<double>* > solutionList(nComponents);
for (int i = 0; i < nComponents; i++) { for (int i = 0; i < nComponents; i++) {
TEST_EXIT(componentMeshes_[0] == componentMeshes_[i]) TEST_EXIT(componentMeshes[0] == componentMeshes[i])
("All Meshes have to be equal to write a vector file.\n"); ("All Meshes have to be equal to write a vector file.\n");
solutionList[i] = solution_->getDOFVector(i); solutionList[i] = solution_->getDOFVector(i);
} }
fileWriters_.push_back(NEW FileWriter(numberedName, fileWriters_.push_back(NEW FileWriter(numberedName,
componentMeshes_[0], componentMeshes[0],
solutionList)); solutionList));
} }
...@@ -481,7 +482,7 @@ namespace AMDiS { ...@@ -481,7 +482,7 @@ namespace AMDiS {
if (filename != "") { if (filename != "") {
fileWriters_.push_back(NEW FileWriter(numberedName, fileWriters_.push_back(NEW FileWriter(numberedName,
componentMeshes_[i], componentMeshes[i],
solution_->getDOFVector(i))); solution_->getDOFVector(i)));
} }
} }
...@@ -549,18 +550,7 @@ namespace AMDiS { ...@@ -549,18 +550,7 @@ namespace AMDiS {
#endif #endif
if (computeExactError) { if (computeExactError) {
for (int i = 0; i < nComponents; i++) { computeError(adaptInfo);
DOFVector<double> *tmp = NEW DOFVector<double>(componentSpaces[i], "tmp");
tmp->interpol(exactSolutionFcts[i]);
// double t = max(abs(tmp->max()), abs(tmp->min()));
double t = tmp->absMax();
*tmp -= *(solution_->getDOFVector(i));
double l2Error = tmp->L2Norm();
double maxError = tmp->absMax() / t;
MSG("L2 error = %.8e\n", l2Error);
MSG("L-inf error = %.8e\n", maxError);
DELETE tmp;
}
} else { } else {
for (int i = 0; i < nComponents; i++) { for (int i = 0; i < nComponents; i++) {
Estimator *scalEstimator = estimator_[i]; Estimator *scalEstimator = estimator_[i];
...@@ -600,7 +590,7 @@ namespace AMDiS { ...@@ -600,7 +590,7 @@ namespace AMDiS {
Flag markFlag = 0; Flag markFlag = 0;
for (int i = 0; i < nComponents; i++) { for (int i = 0; i < nComponents; i++) {
if (marker[i]) { if (marker[i]) {
markFlag |= marker[i]->markMesh(adaptInfo, componentMeshes_[i]); markFlag |= marker[i]->markMesh(adaptInfo, componentMeshes[i]);
} else { } else {
WARNING("no marker for component %d\n", i); WARNING("no marker for component %d\n", i);
} }
...@@ -745,7 +735,7 @@ namespace AMDiS { ...@@ -745,7 +735,7 @@ namespace AMDiS {
} }
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); ElInfo *elInfo = stack.traverseFirst(componentMeshes[i], -1, assembleFlag);
while (elInfo) { while (elInfo) {
if (useGetBound_) { if (useGetBound_) {
...@@ -787,7 +777,7 @@ namespace AMDiS { ...@@ -787,7 +777,7 @@ namespace AMDiS {
solution_->getDOFVector(i)->getBoundaryManager()->initVector(solution_->getDOFVector(i)); solution_->getDOFVector(i)->getBoundaryManager()->initVector(solution_->getDOFVector(i));
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); ElInfo *elInfo = stack.traverseFirst(componentMeshes[i], -1, assembleFlag);
while (elInfo) { while (elInfo) {
if (rhs_->getDOFVector(i)->getBoundaryManager()) if (rhs_->getDOFVector(i)->getBoundaryManager())
rhs_->getDOFVector(i)->getBoundaryManager()-> rhs_->getDOFVector(i)->getBoundaryManager()->
...@@ -1018,5 +1008,61 @@ namespace AMDiS { ...@@ -1018,5 +1008,61 @@ namespace AMDiS {
solution_->deserialize(in); solution_->deserialize(in);
} }
void ProblemVec::computeError(AdaptInfo *adaptInfo)
{
FUNCNAME("ProblemVec::computeError()");
for (int i = 0; i < nComponents; i++) {
TEST_EXIT(exactSolutionFcts[i])("No solution function given!\n");
// Compute the difference between exact and computed solution
DOFVector<double> *tmp = NEW DOFVector<double>(componentSpaces[i], "tmp");
tmp->interpol(exactSolutionFcts[i]);
double solMax = tmp->absMax();
*tmp -= *(solution_->getDOFVector(i));
MSG("L2 error = %.8e\n", tmp->L2Norm());
MSG("L-inf error = %.8e\n", tmp->absMax() / solMax);
adaptInfo->setEstSum(tmp->absMax() / solMax, i);
adaptInfo->setEstMax(tmp->absMax() / solMax, i);
// To set element estimates, compute a vector with the difference
// between exact and computed solution for each DOF.
DOFVector<double> *sol = NEW DOFVector<double>(componentSpaces[i], "tmp");
sol->interpol(exactSolutionFcts[i]);
DOFVector<double>::Iterator it1(sol, USED_DOFS);
DOFVector<double>::Iterator it2(tmp, USED_DOFS);
for (it1.reset(), it2.reset(); !it1.end(); ++it1, ++it2) {
if ((abs(*it1) <= DBL_TOL) || (abs(*it2) <= DBL_TOL)) {
*it2 = 0.0;
} else {
*it2 = abs(*it2 / *it1);
}
}
// Compute estimate for every mesh element
Vector<DegreeOfFreedom> locInd(componentSpaces[i]->getBasisFcts()->getNumber());
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(componentMeshes[i], -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
componentSpaces[i]->getBasisFcts()->getLocalIndicesVec(elInfo->getElement(),
componentSpaces[i]->getAdmin(),
&locInd);
double estimate = 0.0;
for (int j = 0; j < componentSpaces[i]->getBasisFcts()->getNumber(); j++) {
estimate += (*tmp)[locInd[j]];
}
elInfo->getElement()->setEstimation(estimate, i);
elInfo->getElement()->setMark(0);
elInfo = stack.traverseNext(elInfo);
}
DELETE tmp;
DELETE sol;
}
}
} }
...@@ -322,9 +322,9 @@ namespace AMDiS { ...@@ -322,9 +322,9 @@ namespace AMDiS {
*/ */
inline Mesh* getMesh(int comp) { inline Mesh* getMesh(int comp) {
FUNCNAME("ProblemVec::getMesh()"); FUNCNAME("ProblemVec::getMesh()");
TEST_EXIT(comp < static_cast<int>(componentMeshes_.size()) && comp >= 0) TEST_EXIT(comp < static_cast<int>(componentMeshes.size()) && comp >= 0)
("invalid component number\n"); ("invalid component number\n");
return componentMeshes_[comp]; return componentMeshes[comp];
}; };
/** \brief /** \brief
...@@ -523,6 +523,13 @@ namespace AMDiS { ...@@ -523,6 +523,13 @@ namespace AMDiS {
return fileWriters_; return fileWriters_;
}; };
protected:
/** \brief
* If the exact solution is known, the problem can compute the exact
* error instead of the error estimation. This is done in this function.
*/
void computeError(AdaptInfo *adaptInfo);
protected: protected:
/** \brief /** \brief
* Name of this problem. * Name of this problem.
...@@ -552,7 +559,7 @@ namespace AMDiS { ...@@ -552,7 +559,7 @@ namespace AMDiS {
/** \brief /** \brief
* Pointer to the meshes for the different problem components * Pointer to the meshes for the different problem components
*/ */
std::vector<Mesh*> componentMeshes_; std::vector<Mesh*> componentMeshes;
/** \brief /** \brief
* Responsible for element marking. * Responsible for element marking.
......
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