Skip to content
Snippets Groups Projects
Commit cfa53135 authored by Andreas Lauser's avatar Andreas Lauser
Browse files

partial reassemble: only update the solution if the DOF gets reassembled

also make the MpNc model respect absolute convergence criteria. IMHO
an unweighted absolute criterion is pretty useless in most contexts,
though. that's because the criterion is about the amount of
conservation quantities that get lost per second but a losing or
gaining a joule of energy is much less of a problem than losing or
gaining a kilogram of mass...

git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@7442 2fb0f335-1f38-0410-981e-8018bf24f1b0
parent 6dc7978e
No related branches found
No related tags found
No related merge requests found
...@@ -201,13 +201,13 @@ public: ...@@ -201,13 +201,13 @@ public:
const SolutionVector &uLastIter, const SolutionVector &uLastIter,
const SolutionVector &deltaU) const SolutionVector &deltaU)
{ {
this->writeConvergence_(uLastIter, deltaU); if (this->enableRelativeCriterion_ || this->enablePartialReassemble_)
this->newtonUpdateRelError(uLastIter, deltaU); this->newtonUpdateRelError(uLastIter, deltaU);
// compute the vertex and element colors for partial // compute the vertex and element colors for partial
// reassembly // reassembly
if (enablePartialReassemble) { if (enablePartialReassemble) {
Scalar minReasmTol = 0.5*this->tolerance_; Scalar minReasmTol = 0.01*this->tolerance_;
Scalar reassembleTol = Dumux::geometricMean(this->error_, minReasmTol); Scalar reassembleTol = Dumux::geometricMean(this->error_, minReasmTol);
reassembleTol = std::max(reassembleTol, minReasmTol); reassembleTol = std::max(reassembleTol, minReasmTol);
...@@ -215,28 +215,32 @@ public: ...@@ -215,28 +215,32 @@ public:
this->model_().jacobianAssembler().computeColors(reassembleTol); this->model_().jacobianAssembler().computeColors(reassembleTol);
} }
this->writeConvergence_(uLastIter, deltaU);
if (GET_PROP_VALUE(TypeTag, NewtonUseLineSearch)) { if (GET_PROP_VALUE(TypeTag, NewtonUseLineSearch)) {
lineSearchUpdate_(uCurrentIter, uLastIter, deltaU); lineSearchUpdate_(uCurrentIter, uLastIter, deltaU);
} }
else { else {
Scalar lambda = 1.0; for (int i = 0; i < uLastIter.size(); ++i) {
/* if (this->model_().jacobianAssembler().vertexColor(i) != JacobianAssembler::Red)
if (this->error_ > 10) { continue;
// Do a "poor man's line search"
lambda /= std::sqrt((this->numSteps_ + 1)*this->error_/10); uCurrentIter[i] = uLastIter[i];
lambda = std::max(0.2, lambda); uCurrentIter[i] -= deltaU[i];
} }
*/
if (this->numSteps_ < 2 && enableChop_) {
uCurrentIter = deltaU;
uCurrentIter *= - lambda;
uCurrentIter += uLastIter;
if (this->numSteps_ < 4 && enableChop_) {
// put crash barriers along the update path at the // put crash barriers along the update path at the
// beginning... // beginning...
NewtonChop::chop(uCurrentIter, uLastIter); NewtonChop::chop(uCurrentIter, uLastIter);
} }
if (this->enableAbsoluteCriterion_)
{
SolutionVector tmp(uLastIter);
this->absoluteError_ = this->method().model().globalResidual(tmp, uCurrentIter);
this->absoluteError_ /= this->initialAbsoluteError_;
}
} }
} }
......
...@@ -115,6 +115,9 @@ NEW_PROP_TAG(NewtonTargetSteps); ...@@ -115,6 +115,9 @@ NEW_PROP_TAG(NewtonTargetSteps);
//! Number of maximum iterations for the Newton method. //! Number of maximum iterations for the Newton method.
NEW_PROP_TAG(NewtonMaxSteps); NEW_PROP_TAG(NewtonMaxSteps);
//! The assembler for the Jacobian matrix
NEW_PROP_TAG(JacobianAssembler);
// set default values // set default values
SET_TYPE_PROP(NewtonMethod, NewtonController, Dumux::NewtonController<TypeTag>); SET_TYPE_PROP(NewtonMethod, NewtonController, Dumux::NewtonController<TypeTag>);
SET_BOOL_PROP(NewtonMethod, NewtonWriteConvergence, false); SET_BOOL_PROP(NewtonMethod, NewtonWriteConvergence, false);
...@@ -149,6 +152,7 @@ class NewtonController ...@@ -149,6 +152,7 @@ class NewtonController
typedef typename GET_PROP_TYPE(TypeTag, Model) Model; typedef typename GET_PROP_TYPE(TypeTag, Model) Model;
typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) NewtonMethod; typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) NewtonMethod;
typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) JacobianMatrix; typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) JacobianMatrix;
typedef typename GET_PROP_TYPE(TypeTag, JacobianAssembler) JacobianAssembler;
typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager;
typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper;
...@@ -444,30 +448,33 @@ public: ...@@ -444,30 +448,33 @@ public:
const SolutionVector &uLastIter, const SolutionVector &uLastIter,
const SolutionVector &deltaU) const SolutionVector &deltaU)
{ {
writeConvergence_(uLastIter, deltaU);
if (enableRelativeCriterion_ || enablePartialReassemble_) if (enableRelativeCriterion_ || enablePartialReassemble_)
newtonUpdateRelError(uLastIter, deltaU); newtonUpdateRelError(uLastIter, deltaU);
// compute the vertex and element colors for partial reassembly // compute the vertex and element colors for partial reassembly
if (enablePartialReassemble_) { if (enablePartialReassemble_) {
Scalar minReasmTol, tmp, reassembleTol; Scalar minReasmTol = 0.01*tolerance_;
minReasmTol = 0.1*tolerance_; Scalar reassembleTol = Dumux::geometricMean(error_, minReasmTol);
tmp = Dumux::geometricMean(error_, minReasmTol);
reassembleTol = Dumux::geometricMean(error_, tmp);
reassembleTol = std::max(reassembleTol, minReasmTol); reassembleTol = std::max(reassembleTol, minReasmTol);
this->model_().jacobianAssembler().updateDiscrepancy(uLastIter, deltaU); this->model_().jacobianAssembler().updateDiscrepancy(uLastIter, deltaU);
this->model_().jacobianAssembler().computeColors(reassembleTol); this->model_().jacobianAssembler().computeColors(reassembleTol);
} }
writeConvergence_(uLastIter, deltaU);
if (useLineSearch_) if (useLineSearch_)
{ {
lineSearchUpdate_(uCurrentIter, uLastIter, deltaU); lineSearchUpdate_(uCurrentIter, uLastIter, deltaU);
} }
else { else {
uCurrentIter = uLastIter; for (int i = 0; i < uLastIter.size(); ++i) {
uCurrentIter -= deltaU; if (this->model_().jacobianAssembler().vertexColor(i) != JacobianAssembler::Red)
continue;
uCurrentIter[i] = uLastIter[i];
uCurrentIter[i] -= deltaU[i];
}
if (enableAbsoluteCriterion_) if (enableAbsoluteCriterion_)
{ {
SolutionVector tmp(uLastIter); SolutionVector tmp(uLastIter);
...@@ -712,7 +719,6 @@ protected: ...@@ -712,7 +719,6 @@ protected:
// the linear solver // the linear solver
LinearSolver linearSolver_; LinearSolver linearSolver_;
private:
bool enablePartialReassemble_; bool enablePartialReassemble_;
bool enableJacobianRecycling_; bool enableJacobianRecycling_;
bool useLineSearch_; bool useLineSearch_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment