From ecbb27791f67c1971510debb3aecd0ff0524c932 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Fri, 29 Aug 2008 11:20:33 +0000 Subject: [PATCH] * Exact error computation --- AMDiS/src/ProblemNonLin.cc | 2 +- AMDiS/src/ProblemVec.cc | 96 ++++++++++++++++++++++++++++---------- AMDiS/src/ProblemVec.h | 13 ++++-- 3 files changed, 82 insertions(+), 29 deletions(-) diff --git a/AMDiS/src/ProblemNonLin.cc b/AMDiS/src/ProblemNonLin.cc index 5f4bb972..6a8309da 100644 --- a/AMDiS/src/ProblemNonLin.cc +++ b/AMDiS/src/ProblemNonLin.cc @@ -188,7 +188,7 @@ namespace AMDiS { // for all elements ... for (int i = 0; i < nComponents; i++) { - elInfo = stack.traverseFirst(componentMeshes_[i], -1, + elInfo = stack.traverseFirst(componentMeshes[i], -1, Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS | diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc index 36104a09..ea9ad47a 100644 --- a/AMDiS/src/ProblemVec.cc +++ b/AMDiS/src/ProblemVec.cc @@ -20,6 +20,7 @@ #include "RobinBC.h" #include "PeriodicBC.h" #include "Lagrange.h" +#include "Flag.h" namespace AMDiS { @@ -45,7 +46,7 @@ namespace AMDiS { adoptFlag.isSet(INIT_SYSTEM) || adoptFlag.isSet(INIT_FE_SPACE))) { meshes_ = adoptProblem->getMeshes(); - componentMeshes_ = adoptProblem->componentMeshes_; + componentMeshes = adoptProblem->componentMeshes; refinementManager_ = adoptProblem->refinementManager_; coarseningManager_ = adoptProblem->coarseningManager_; } @@ -180,7 +181,7 @@ namespace AMDiS { { FUNCNAME("ProblemVec::createMesh()"); - componentMeshes_.resize(nComponents); + componentMeshes.resize(nComponents); std::map<int, Mesh*> meshForRefinementSet; char number[3]; @@ -203,7 +204,7 @@ namespace AMDiS { meshForRefinementSet[refSet] = newMesh; meshes_.push_back(newMesh); } - componentMeshes_[i] = meshForRefinementSet[refSet]; + componentMeshes[i] = meshForRefinementSet[refSet]; } switch(dim) { case 1: @@ -243,17 +244,17 @@ namespace AMDiS { 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::provideFESpace(NULL, Lagrange::getLagrange(dim, degree), - componentMeshes_[i], + componentMeshes[i], name_ + "->feSpace"); - feSpaceMap[std::pair<Mesh*, int>(componentMeshes_[i], degree)] = newFESpace; + feSpaceMap[std::pair<Mesh*, int>(componentMeshes[i], degree)] = newFESpace; feSpaces.push_back(newFESpace); } 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 @@ -459,14 +460,14 @@ namespace AMDiS { std::vector< DOFVector<double>* > solutionList(nComponents); 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"); solutionList[i] = solution_->getDOFVector(i); } fileWriters_.push_back(NEW FileWriter(numberedName, - componentMeshes_[0], + componentMeshes[0], solutionList)); } @@ -481,7 +482,7 @@ namespace AMDiS { if (filename != "") { fileWriters_.push_back(NEW FileWriter(numberedName, - componentMeshes_[i], + componentMeshes[i], solution_->getDOFVector(i))); } } @@ -549,18 +550,7 @@ namespace AMDiS { #endif if (computeExactError) { - for (int i = 0; i < nComponents; i++) { - 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; - } + computeError(adaptInfo); } else { for (int i = 0; i < nComponents; i++) { Estimator *scalEstimator = estimator_[i]; @@ -600,7 +590,7 @@ namespace AMDiS { Flag markFlag = 0; for (int i = 0; i < nComponents; i++) { if (marker[i]) { - markFlag |= marker[i]->markMesh(adaptInfo, componentMeshes_[i]); + markFlag |= marker[i]->markMesh(adaptInfo, componentMeshes[i]); } else { WARNING("no marker for component %d\n", i); } @@ -745,7 +735,7 @@ namespace AMDiS { } TraverseStack stack; - ElInfo *elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); + ElInfo *elInfo = stack.traverseFirst(componentMeshes[i], -1, assembleFlag); while (elInfo) { if (useGetBound_) { @@ -787,7 +777,7 @@ namespace AMDiS { solution_->getDOFVector(i)->getBoundaryManager()->initVector(solution_->getDOFVector(i)); TraverseStack stack; - ElInfo *elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); + ElInfo *elInfo = stack.traverseFirst(componentMeshes[i], -1, assembleFlag); while (elInfo) { if (rhs_->getDOFVector(i)->getBoundaryManager()) rhs_->getDOFVector(i)->getBoundaryManager()-> @@ -1018,5 +1008,61 @@ namespace AMDiS { 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; + } + } } diff --git a/AMDiS/src/ProblemVec.h b/AMDiS/src/ProblemVec.h index 39a27af8..6dca6598 100644 --- a/AMDiS/src/ProblemVec.h +++ b/AMDiS/src/ProblemVec.h @@ -322,9 +322,9 @@ namespace AMDiS { */ inline Mesh* getMesh(int comp) { 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"); - return componentMeshes_[comp]; + return componentMeshes[comp]; }; /** \brief @@ -523,6 +523,13 @@ namespace AMDiS { 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: /** \brief * Name of this problem. @@ -552,7 +559,7 @@ namespace AMDiS { /** \brief * Pointer to the meshes for the different problem components */ - std::vector<Mesh*> componentMeshes_; + std::vector<Mesh*> componentMeshes; /** \brief * Responsible for element marking. -- GitLab