Commit 7c4c35f6 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Bugfix in element residual estimation, thanks to Katharina.

parent e2994995
...@@ -860,6 +860,7 @@ namespace AMDiS { ...@@ -860,6 +860,7 @@ namespace AMDiS {
solver->setMultipleRhs(true); solver->setMultipleRhs(true);
} }
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
MPI::COMM_WORLD.Barrier(); MPI::COMM_WORLD.Barrier();
INFO(info, 8)("buildAfterCoarsen needed %.5f seconds\n", INFO(info, 8)("buildAfterCoarsen needed %.5f seconds\n",
......
...@@ -304,16 +304,15 @@ namespace AMDiS { ...@@ -304,16 +304,15 @@ namespace AMDiS {
for (it = dofMat->getOperatorsBegin(), itfac = dofMat->getOperatorEstFactorBegin(); for (it = dofMat->getOperatorsBegin(), itfac = dofMat->getOperatorEstFactorBegin();
it != dofMat->getOperatorsEnd(); ++it, ++itfac) { it != dofMat->getOperatorsEnd(); ++it, ++itfac) {
if (*itfac == NULL || **itfac != 0.0) { if (*itfac == NULL || **itfac != 0.0) {
if (num_rows(uhQP) == 0 && (*it)->zeroOrderTerms()) { if ((*it)->zeroOrderTerms()) {
uhQP.change_dim(nPoints); uhQP.change_dim(nPoints);
uh[system]->getVecAtQPs(elInfo, NULL, quadFast[system], uhQP); uh[system]->getVecAtQPs(elInfo, NULL, quadFast[system], uhQP);
} }
if (num_rows(grdUhQp) == 0 && if ((*it)->firstOrderTermsGrdPsi() || (*it)->firstOrderTermsGrdPhi()) {
((*it)->firstOrderTermsGrdPsi() || (*it)->firstOrderTermsGrdPhi())) {
grdUhQp.change_dim(nPoints); grdUhQp.change_dim(nPoints);
uh[system]->getGrdAtQPs(elInfo, NULL, quadFast[system], grdUhQp); uh[system]->getGrdAtQPs(elInfo, NULL, quadFast[system], grdUhQp);
} }
if (num_rows(D2UhQp) == 0 && degree > 2 && (*it)->secondOrderTerms()) { if (degree > 2 && (*it)->secondOrderTerms()) {
D2UhQp.change_dim(nPoints); D2UhQp.change_dim(nPoints);
uh[system]->getD2AtQPs(elInfo, NULL, quadFast[system], D2UhQp); uh[system]->getD2AtQPs(elInfo, NULL, quadFast[system], D2UhQp);
} }
......
...@@ -41,6 +41,10 @@ namespace AMDiS { ...@@ -41,6 +41,10 @@ namespace AMDiS {
{ {
FUNCNAME("SimpleResidualEstimator::init()"); FUNCNAME("SimpleResidualEstimator::init()");
double kappa = 0.0;
Parameters::get("kappa", kappa);
kappa_inv = 1.0 / kappa;
// === Create data structures. === // === Create data structures. ===
basFcts = uh[0]->getFeSpace()->getBasisFcts(); basFcts = uh[0]->getFeSpace()->getBasisFcts();
...@@ -188,12 +192,12 @@ namespace AMDiS { ...@@ -188,12 +192,12 @@ namespace AMDiS {
for (it = dofMat->getOperatorsBegin(), itfac = dofMat->getOperatorEstFactorBegin(); for (it = dofMat->getOperatorsBegin(), itfac = dofMat->getOperatorEstFactorBegin();
it != dofMat->getOperatorsEnd(); ++it, ++itfac) { it != dofMat->getOperatorsEnd(); ++it, ++itfac) {
if (*itfac == NULL || **itfac != 0.0) { if (*itfac == NULL || **itfac != 0.0) {
if (num_rows(uhQP) == 0 && (*it)->zeroOrderTerms()) { if ((*it)->zeroOrderTerms()) {
uhQP.change_dim(nPoints); uhQP.change_dim(nPoints);
uh[0]->getVecAtQPs(elInfo, NULL, quadFast, uhQP); uh[0]->getVecAtQPs(elInfo, NULL, quadFast, uhQP);
} }
if (num_rows(D2UhQp) == 0 && degree > 2 && (*it)->secondOrderTerms()) { if (degree > 2 && (*it)->secondOrderTerms()) {
D2UhQp.change_dim(nPoints); D2UhQp.change_dim(nPoints);
uh[0]->getD2AtQPs(elInfo, NULL, quadFast, D2UhQp); uh[0]->getD2AtQPs(elInfo, NULL, quadFast, D2UhQp);
} }
...@@ -208,12 +212,14 @@ namespace AMDiS { ...@@ -208,12 +212,14 @@ namespace AMDiS {
double result = 0.0; double result = 0.0;
for (int iq = 0; iq < nPoints; iq++) for (int iq = 0; iq < nPoints; iq++)
result += quad->getWeight(iq) * riq[iq] * riq[iq]; result += quad->getWeight(iq) * riq[iq] * riq[iq];
double alpha0 = std::min(h2, kappa_inv);
if (norm == NO_NORM || norm == L2_NORM) if (norm == NO_NORM || norm == L2_NORM)
result = C0 * h2 * h2 * det * result; result = C0 * alpha0 * alpha0 * det * result;
else else
result = C0 * h2 * det * result; result = C0 * alpha0 * det * result;
return result; return result;
} }
...@@ -228,7 +234,6 @@ namespace AMDiS { ...@@ -228,7 +234,6 @@ namespace AMDiS {
Element *el = elInfo->getElement(); Element *el = elInfo->getElement();
const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
double det = elInfo->getDet(); double det = elInfo->getDet();
double h2 = h2_from_det(det, dim);
/// === Compute jump on all faces of the current element. === /// === Compute jump on all faces of the current element. ===
for (int face = 0; face < nNeighbours; face++) { for (int face = 0; face < nNeighbours; face++) {
...@@ -320,23 +325,29 @@ namespace AMDiS { ...@@ -320,23 +325,29 @@ namespace AMDiS {
val += surfaceQuad->getWeight(iq) * (jump[iq] * jump[iq]); val += surfaceQuad->getWeight(iq) * (jump[iq] * jump[iq]);
double d = 0.5 * (det + detNeigh); double d = 0.5 * (det + detNeigh);
double h2 = h2_from_det(d, dim);
double alpha0 = std::min(h2, kappa_inv);
if (norm == NO_NORM || norm == L2_NORM) if (norm == NO_NORM || norm == L2_NORM)
val *= C1 * h2_from_det(d, dim) * d; val *= C1 * alpha0 * d;
else else
val *= C1 * d; val *= C1 * d;
neigh->setEstimation(neigh->getEstimation(0) + val, 0); neigh->setEstimation(neigh->getEstimation(0) + val, 0);
result += val; result += val;
} // for face } // for face
double val = fh[0]->getBoundaryManager()->boundResidual(elInfo, matrix[0], uh[0]); /*
double val =
fh[0]->getBoundaryManager()->boundResidual(elInfo, matrix[0], uh[0]);
if (norm == NO_NORM || norm == L2_NORM) if (norm == NO_NORM || norm == L2_NORM)
val *= C1 * h2; val *= C1 * h2;
else else
val *= C1; val *= C1;
result += val; result += val;
*/
return result; return result;
} }
......
...@@ -193,6 +193,8 @@ namespace AMDiS { ...@@ -193,6 +193,8 @@ namespace AMDiS {
/// Maximal number of neighbours an element may have in the used dimension. /// Maximal number of neighbours an element may have in the used dimension.
int nNeighbours; int nNeighbours;
double kappa_inv;
}; };
} }
......
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