Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist ü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. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

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

SimpleResidualEstimator ready and documented.

parent 97be72e8
......@@ -92,7 +92,6 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
${SOURCE_DIR}/Element.cc
${SOURCE_DIR}/ElementData.cc
${SOURCE_DIR}/ElementDofIterator.cc
${SOURCE_DIR}/Estimator.cc
${SOURCE_DIR}/FiniteElemSpace.cc
${SOURCE_DIR}/FirstOrderAssembler.cc
${SOURCE_DIR}/FirstOrderTerm.cc
......@@ -123,12 +122,10 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
${SOURCE_DIR}/Quadrature.cc
${SOURCE_DIR}/RCNeighbourList.cc
${SOURCE_DIR}/Recovery.cc
${SOURCE_DIR}/RecoveryEstimator.cc
${SOURCE_DIR}/RefinementManager.cc
${SOURCE_DIR}/RefinementManager1d.cc
${SOURCE_DIR}/RefinementManager2d.cc
${SOURCE_DIR}/RefinementManager3d.cc
${SOURCE_DIR}/ResidualEstimator.cc
${SOURCE_DIR}/RobinBC.cc
${SOURCE_DIR}/ScalableQuadrature.cc
${SOURCE_DIR}/SecondOrderAssembler.cc
......@@ -147,6 +144,10 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
${SOURCE_DIR}/VertexVector.cc
${SOURCE_DIR}/ZeroOrderAssembler.cc
${SOURCE_DIR}/ZeroOrderTerm.cc
${SOURCE_DIR}/est/Estimator.cc
${SOURCE_DIR}/est/RecoveryEstimator.cc
${SOURCE_DIR}/est/ResidualEstimator.cc
${SOURCE_DIR}/est/SimpleResidualEstimator.cc
${SOURCE_DIR}/io/ArhReader.cc
${SOURCE_DIR}/io/ArhWriter.cc
${SOURCE_DIR}/io/DataCollector.cc
......@@ -345,6 +346,11 @@ INSTALL(FILES ${HEADERS}
DESTINATION include/amdis/nonlin/)
list(APPEND deb_add_dirs "include/amdis/nonlin")
FILE(GLOB HEADERS "${SOURCE_DIR}/est/*.h")
INSTALL(FILES ${HEADERS}
DESTINATION include/amdis/est/)
list(APPEND deb_add_dirs "include/amdis/est")
FILE(GLOB HEADERS "${SOURCE_DIR}/time/*.h")
INSTALL(FILES ${HEADERS}
DESTINATION include/amdis/time/)
......
......@@ -59,7 +59,6 @@
#include "Element.h"
#include "ElementDofIterator.h"
#include "Error.h"
#include "Estimator.h"
#include "FiniteElemSpace.h"
#include "FirstOrderTerm.h"
#include "FixVec.h"
......@@ -112,6 +111,8 @@
#include "VertexVector.h"
#include "ZeroOrderTerm.h"
#include "est/Estimator.h"
#include "io/ArhReader.h"
#include "io/ArhWriter.h"
#include "io/FileWriter.h"
......
......@@ -12,7 +12,7 @@
#include "AdaptInstationary.h"
#include "Initfile.h"
#include "Estimator.h"
#include "est/Estimator.h"
#include "ProblemIterationInterface.h"
#include "ProblemTimeInterface.h"
#include "Serializer.h"
......
......@@ -12,7 +12,7 @@
#include "AdaptStationary.h"
#include "Initfile.h"
#include "Estimator.h"
#include "est/Estimator.h"
#include "ProblemIterationInterface.h"
#include <math.h>
......
......@@ -315,8 +315,8 @@ namespace AMDiS {
FUNCNAME("Assembler::matVecAssemble()");
Element *el = elInfo->getElement();
ElementVector uhOldLoc(operat->uhOld->getFeSpace() == rowFeSpace ? nRow : nCol);
ElementVector uhOldLoc(operat->uhOld->getFeSpace() == rowFeSpace ?
nRow : nCol);
operat->uhOld->getLocalVector(el, uhOldLoc);
if (el != lastMatEl) {
......
......@@ -17,14 +17,15 @@
#include "ITL_Preconditioner.h"
#include "MatrixVector.h"
#include "SystemVector.h"
#include "Estimator.h"
#include "RecoveryEstimator.h"
#include "ResidualEstimator.h"
#include "est/Estimator.h"
#include "LeafData.h"
#include "SurfaceRegion_ED.h"
#include "ElementRegion_ED.h"
#include "DOFMatrix.h"
#include "UmfPackSolver.h"
#include "est/RecoveryEstimator.h"
#include "est/ResidualEstimator.h"
#include "est/SimpleResidualEstimator.h"
#include "time/RosenbrockMethod.h"
#include "nonlin/NonLinSolver.h"
......@@ -102,6 +103,9 @@ namespace AMDiS {
creator = new ResidualEstimator::Creator;
addCreator("residual", creator);
creator = new SimpleResidualEstimator::Creator;
addCreator("simple-residual", creator);
creator = new RecoveryEstimator::Creator;
addCreator("recovery", creator);
}
......
......@@ -57,9 +57,11 @@ namespace AMDiS {
dimOfWorld = Global::getGeo(WORLD);
}
ElInfo::~ElInfo()
{}
void ElInfo::coordToWorld(const DimVec<double>& l,
WorldVector<double>& w) const
......@@ -80,12 +82,14 @@ namespace AMDiS {
}
}
double ElInfo::calcDet() const
{
testFlag(Mesh::FILL_COORDS);
return calcDet(coord);
}
double ElInfo::calcDet(const FixVec<WorldVector<double>, VERTEX> &coords) const
{
FUNCNAME("ElInfo::calcDet()");
......@@ -114,10 +118,8 @@ namespace AMDiS {
det = norm(&e1);
} else {
det = (coords[1][0] - coords[0][0]) * (coords[2][1] - coords[0][1]) -
(coords[1][1] - coords[0][1]) * (coords[2][0] - coords[0][0]);
}
break;
case 3:
......
......@@ -735,13 +735,13 @@ namespace AMDiS {
vectorProduct(elementNormal, e0, normal);
}
double det = norm(&normal);
double detn = norm(&normal);
TEST_EXIT_DBG(det > 1.e-30)("det = 0 on face %d\n", side);
TEST_EXIT_DBG(detn > 1.e-30)("det = 0 on face %d\n", side);
normal *= 1.0 / det;
normal *= 1.0 / detn;
return det;
return detn;
}
......@@ -762,13 +762,13 @@ namespace AMDiS {
vectorProduct(e0, e1, elementNormal);
double det = norm(&elementNormal);
double detn = norm(&elementNormal);
TEST_EXIT_DBG(det > 1.e-30)("det = 0");
TEST_EXIT_DBG(detn > 1.e-30)("det = 0");
elementNormal *= 1.0 / det;
elementNormal *= 1.0 / detn;
return det;
return detn;
}
......
......@@ -16,8 +16,8 @@
#include "ProblemInstat.h"
#include "AdaptStationary.h"
#include "AdaptInstationary.h"
#include "Estimator.h"
#include "StandardProblemIteration.h"
#include "est/Estimator.h"
#include "io/FileWriter.h"
namespace AMDiS {
......
......@@ -14,14 +14,12 @@
#include <boost/lexical_cast.hpp>
#include "ProblemStat.h"
#include "RecoveryEstimator.h"
#include "Serializer.h"
#include "AbstractFunction.h"
#include "Operator.h"
#include "SystemVector.h"
#include "DOFMatrix.h"
#include "FiniteElemSpace.h"
#include "Estimator.h"
#include "Marker.h"
#include "AdaptInfo.h"
#include "io/FileWriter.h"
......@@ -35,6 +33,7 @@
#include "PeriodicBC.h"
#include "Lagrange.h"
#include "Flag.h"
#include "est/Estimator.h"
#include "io/VtkWriter.h"
#include "io/ValueReader.h"
#include "ProblemStatDbg.h"
......@@ -791,6 +790,8 @@ namespace AMDiS {
nnz += matrix->getBaseMatrix().nnz();
}
// And now assemble boundary conditions on the vectors
assembleBoundaryConditions(rhs->getDOFVector(i),
solution->getDOFVector(i),
......
......@@ -11,11 +11,12 @@
#include "RobinBC.h"
#include "Estimator.h"
#include "Assembler.h"
#include "DOFVector.h"
#include "DOFMatrix.h"
#include "SurfaceOperator.h"
#include "est/Estimator.h"
#include <math.h>
namespace AMDiS {
......
......@@ -10,8 +10,8 @@
// See also license.opensource.txt in the distribution.
#include "Estimator.h"
#include "Assembler.h"
#include "est/Estimator.h"
template<typename T>
void RobinBC<T>::fillLocalBC(DOFVector<T>* vector,
......
......@@ -132,7 +132,8 @@ namespace AMDiS {
}
/// Implements SecondOrderTerm::getLALt().
inline void getLALt(const ElInfo *elInfo, vector<mtl::dense2D<double> > &LALt) const
inline void getLALt(const ElInfo *elInfo,
vector<mtl::dense2D<double> > &LALt) const
{
const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
const int nPoints = static_cast<int>(LALt.size());
......
......@@ -52,16 +52,16 @@ namespace AMDiS {
}
const FixVec<int, WORLD>& Triangle::sortFaceIndices(int face,
FixVec<int,WORLD> *vec) const
FixVec<int, WORLD> *vec) const
{
static MatrixOfFixVecs<FixVec<int,WORLD> > *sorted_2d = NULL;
static MatrixOfFixVecs<FixVec<int, WORLD> > *sorted_2d = NULL;
int no = 0;
FixVec<int,WORLD> *val = NULL;
FixVec<int, WORLD> *val = NULL;
const int *vof = vertexOfEdge[face];
if (NULL == sorted_2d) {
sorted_2d = new MatrixOfFixVecs<FixVec<int,WORLD> >(2, 3, 2, NO_INIT);
sorted_2d = new MatrixOfFixVecs<FixVec<int, WORLD> >(2, 3, 2, NO_INIT);
(*sorted_2d)[1][0][1] = (*sorted_2d)[1][1][0] =
(*sorted_2d)[2][0][0] = (*sorted_2d)[2][1][1] = 0;
......@@ -83,7 +83,7 @@ namespace AMDiS {
val = &((*sorted_2d)[face][no]);
}
return *(const_cast<const FixVec<int,WORLD>* >(val));
return *(const_cast<const FixVec<int, WORLD>* >(val));
}
......
......@@ -95,7 +95,7 @@ namespace AMDiS {
bool hasSide(Element* sideElem) const;
/// implements Element::sortFaceIndices
const FixVec<int,WORLD>& sortFaceIndices(int face, FixVec<int,WORLD> *vec) const;
const FixVec<int, WORLD>& sortFaceIndices(int face, FixVec<int, WORLD> *vec) const;
/// implements Element::isLine. Returns false because this element is a Triangle
inline bool isLine() const
......
......@@ -536,8 +536,10 @@ namespace AMDiS {
(*it)->evalSecondOrder(nPoints, uhIq, grdUhIq, D2UhIq, result, -factor);
if (grdUhIq) {
(*it)->evalFirstOrderGrdPsi(nPoints, uhIq, grdUhIq, D2UhIq, result, factor);
(*it)->evalFirstOrderGrdPhi(nPoints, uhIq, grdUhIq, D2UhIq, result, factor);
(*it)->evalFirstOrderGrdPsi(nPoints, uhIq, grdUhIq, D2UhIq,
result, factor);
(*it)->evalFirstOrderGrdPhi(nPoints, uhIq, grdUhIq, D2UhIq,
result, factor);
}
if (num_rows(uhIq) > 0)
......
......@@ -59,7 +59,7 @@ namespace AMDiS {
* \ingroup Estimator
*
* \brief
* Estimator for scalar problems.
* Residual estimator.
*/
class ResidualEstimator : public Estimator
{
......@@ -88,8 +88,8 @@ namespace AMDiS {
virtual void init(double timestep);
/** \brief
* Estimates the error on an element. For more information about the parameter,
* see the description \ref Estimator::estimateElement.
* Estimates the error on an element. For more information about the
* parameter, see the description \ref Estimator::estimateElement.
*/
virtual void estimateElement(ElInfo *elInfo, DualElInfo *dualElInfo = NULL);
......
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
#include "est/SimpleResidualEstimator.h"
#include "Operator.h"
#include "DOFMatrix.h"
#include "DOFVector.h"
#include "Assembler.h"
#include "Traverse.h"
#include "Initfile.h"
namespace AMDiS {
SimpleResidualEstimator::SimpleResidualEstimator(std::string name)
: Estimator(name, 0),
C0(0.0),
C1(0.0)
{
FUNCNAME("SimpleResidualEstimator::SimpleResidualEstimator()");
// === Read parameters C0 and C1 from init file. ===
Parameters::get(name + "->C0", C0);
Parameters::get(name + "->C1", C1);
C0 = C0 > 1.e-25 ? sqr(C0) : 0.0;
C1 = C1 > 1.e-25 ? sqr(C1) : 0.0;
}
void SimpleResidualEstimator::init(double)
{
FUNCNAME("SimpleResidualEstimator::init()");
// === Create data structures. ===
basFcts = uh[0]->getFeSpace()->getBasisFcts();
dim = mesh->getDim();
degree = basFcts->getDegree() * 2;
quad = Quadrature::provideQuadrature(dim, degree);
nPoints = quad->getNumPoints();
Flag flag = INIT_PHI;
if (degree > 2)
flag |= INIT_D2_PHI;
quadFast = FastQuadrature::provideFastQuadrature(basFcts, *quad, flag);
uhEl.change_dim(basFcts->getNumber());
uhNeigh.change_dim(basFcts->getNumber());
riq.change_dim(nPoints);
D2uhqp = NULL;
// === Clear error indicators and mark elements for jumpRes. ===
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
elInfo->getElement()->setEstimation(0.0, 0);
elInfo->getElement()->setMark(1);
elInfo = stack.traverseNext(elInfo);
}
est_sum = 0.0;
est_max = 0.0;
traverseFlag =
Mesh::FILL_NEIGH |
Mesh::FILL_COORDS |
Mesh::FILL_OPP_COORDS |
Mesh::FILL_BOUND |
Mesh::FILL_GRD_LAMBDA |
Mesh::FILL_DET |
Mesh::CALL_LEAF_EL;
neighInfo = mesh->createNewElInfo();
// === Prepare date for computing jump residual. ===
if (C1 > 0.0 && dim > 1) {
surfaceQuad = Quadrature::provideQuadrature(dim - 1, degree);
nPointsSurface = surfaceQuad->getNumPoints();
grdUhEl.resize(nPointsSurface);
grdUhNeigh.resize(nPointsSurface);
jump.resize(nPointsSurface);
localJump.resize(nPointsSurface);
nNeighbours = Global::getGeo(NEIGH, dim);
lambdaNeigh = new DimVec<WorldVector<double> >(dim, NO_INIT);
lambda = new DimVec<double>(dim, NO_INIT);
}
}
void SimpleResidualEstimator::exit(bool output)
{
FUNCNAME("SimpleResidualEstimator::exit()");
// === Calculate the root of the estimations and make output. ===
est_sum = sqrt(est_sum);
if (output)
MSG("estimate = %.8e\n", est_sum);
/// === Delete data structures. ===
if (D2uhqp != NULL)
delete [] D2uhqp;
if (C1 && (dim > 1)) {
delete lambdaNeigh;
delete lambda;
}
delete neighInfo;
}
void SimpleResidualEstimator::estimateElement(ElInfo *elInfo, DualElInfo *)
{
FUNCNAME("SimpleResidualEstimator::estimateElement()");
TEST_EXIT(matrix[0])("Should not happen!\n");
// Get pointer to element object.
Element *el = elInfo->getElement();
// Get error estimation of this element.
double est_el = el->getEstimation(0);
// Shortcut for the system matrix.
DOFMatrix *dofMat = const_cast<DOFMatrix*>(matrix[0]);
// Shortcut for the right hand side DOF vector
DOFVector<double> *dofVec = const_cast<DOFVector<double>*>(fh[0]);
// === Init assembler ===
std::vector<Operator*>::iterator it;
std::vector<double*>::iterator itfac;
// Matrix assembler are only initialized with the corresponding multiply
// factors are != 0
for (it = dofMat->getOperatorsBegin(), itfac = dofMat->getOperatorEstFactorBegin();
it != dofMat->getOperatorsEnd(); ++it, ++itfac)
if (*itfac == NULL || **itfac != 0.0)
(*it)->getAssembler()->initElement(elInfo, NULL, quad);
// Vector assembler are only initialized if C0 is set. Note that the jump
// residual (thus C1) does not contain the right hand side.
if (C0 > 0.0)
for (it = dofVec->getOperatorsBegin(); it != dofVec->getOperatorsEnd(); ++it)
(*it)->getAssembler()->initElement(elInfo, NULL, quad);
// === Compute element residuals and time error estimation. ===
if (C0 > 0.0)
est_el += computeElementResidual(elInfo);
// === Compute jump residuals. ===
if (C1 > 0.0 && dim > 1)
est_el += computeJumpResidual(elInfo);
// === Update global residual variables. ===
el->setEstimation(est_el, 0);
el->setMark(0);
est_sum += est_el;
est_max = std::max(est_max, est_el);
}
double SimpleResidualEstimator::computeElementResidual(ElInfo *elInfo)
{
FUNCNAME("SimpleResidualEstimator::computeElementResidual()");
double det = elInfo->getDet();
double h2 = h2_from_det(det, dim);
riq = 0.0;
DOFMatrix *dofMat = const_cast<DOFMatrix*>(matrix[0]);
DOFVector<double> *dofVec = const_cast<DOFVector<double>*>(fh[0]);
// === If there is a valid left hand side operator get the solution ===
// === vector or its derivations on the quadrature points of the ===
// === element. ===
std::vector<Operator*>::iterator it;
std::vector<double*>::iterator itfac;
for (it = dofMat->getOperatorsBegin(), itfac = dofMat->getOperatorEstFactorBegin();
it != dofMat->getOperatorsEnd(); ++it, ++itfac) {
if (*itfac == NULL || **itfac != 0.0) {
if (num_rows(uhQP) == 0 && (*it)->zeroOrderTerms()) {
uhQP.change_dim(nPoints);
uh[0]->getVecAtQPs(elInfo, NULL, quadFast, uhQP);
}
if (D2uhqp == NULL && degree > 2 && (*it)->secondOrderTerms()) {
D2uhqp = new WorldMatrix<double>[nPoints];
uh[0]->getD2AtQPs(elInfo, NULL, quadFast, D2uhqp);
}
}
}
// === Compute the element residual and store it in irq. ===
r(elInfo, nPoints, uhQP, D2uhqp, dofMat, dofVec, quad, riq);
// === Add integral over r square. ===
double result = 0.0;
for (int iq = 0; iq < nPoints; iq++)
result += quad->getWeight(iq) * riq[iq] * riq[iq];
if (norm == NO_NORM || norm == L2_NORM)
result = C0 * h2 * h2 * det * result;
else
result = C0 * h2 * det * result;
return result;
}
double SimpleResidualEstimator::computeJumpResidual(ElInfo *elInfo)
{
FUNCNAME("SimpleResidualEstimator::computeJumpResidual()");
// === Init temporary variables. ===
double result = 0.0;
int dow = Global::getGeo(WORLD);
Element *el = elInfo->getElement();
const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
double det = elInfo->getDet();
double h2 = h2_from_det(det, dim);
/// === Compute jump on all faces of the current element. ===
for (int face = 0; face < nNeighbours; face++) {
// Pointer to neighbouring element.
Element *neigh = const_cast<Element*>(elInfo->getNeighbour(face));
// If there is no neighbour, or we have already visited this pair,
// then continue with next one.
if (!(neigh && neigh->getMark()))
continue;
// === The next lines are only to set all information about the ===
// === neighbouring element. ===
int oppV = elInfo->getOppVertex(face);
el->sortFaceIndices(face, &faceIndEl);
neigh->sortFaceIndices(oppV, &faceIndNeigh);