Commit a167a0e3 authored by's avatar
Browse files

Reintroduce the TNNMGStep class for the new implementation

It is basically a combination of AcceleratedNonlinearGSStep and
TNNMGAcceleration, but I think it makes the code easier to understand,
even though it does not get shorter.

In addition, the new TNNMGStep class takes nonlinear smoother in form
of a shared_ptr to a dune-solvers IterationStep again.  I don't see
why we need static polymorphism here.
parent 123df6dc
Pipeline #5038 failed with stage
in 9 seconds
......@@ -11,6 +11,153 @@
#include "dune/solvers/iterationsteps/iterationstep.hh"
#include "dune/solvers/iterationsteps/lineariterationstep.hh"
namespace Dune {
namespace TNNMG {
* \brief One iteration of the TNNMG method
* \tparam F Functional to minimize
* \tparam BV Bit-vector type for marking ignored components
template<class F, class BV, class Linearization,
class LinearSolver,
class DefectProjection,
class LineSearchSolver>
class TNNMGStep :
public IterationStep<typename F::Vector, BV>
using Base = IterationStep<typename F::Vector, BV>;
using Vector = typename F::Vector;
using BitVector = typename Base::BitVector;
using Functional = F;
/** \brief Constructor
* \param linearSolver This is a callback used to solve the constrained linearized system
* \param projection This is a callback used to compute a projection into a defect-admissible set
* \param lineSolver This is a callback used to minimize a directional restriction of the functional
* for computing a damping parameter
TNNMGStep(const Functional& f,
Vector& x,
std::shared_ptr<IterationStep<Vector,BitVector> > nonlinearSmoother,
const LinearSolver& linearSolver,
const DefectProjection& projection,
const LineSearchSolver& lineSolver)
: Base(x),
//! destructor
using Base::getIterate;
void preprocess() override
void setPreSmoothingSteps(std::size_t i)
preSmoothingSteps_ = i;
* \brief Do one TNNMG step
void iterate() override
const auto& f = *f_;
const auto& ignore = (*this->ignoreNodes_);
auto& x = *getIterate();
// Nonlinear presmoothing
for (std::size_t i=0; i<preSmoothingSteps_; ++i)
// Compute constraint/truncated linearization
if (not linearization_)
linearization_ = std::make_shared<Linearization>(f, ignore);
auto&& A = linearization_->hessian();
auto&& r = linearization_->negativeGradient();
// Compute inexact solution of the linearized problem
Solvers::resizeInitializeZero(correction_, x);
Solvers::resizeInitializeZero(constrainedCorrection_, r);
linearSolver_(constrainedCorrection_, A, r);
linearization_->extendCorrection(constrainedCorrection_, correction_);
// Project onto admissible set
projection_(f, x, correction_);
// Line search
auto fv = directionalRestriction(f, x, correction_);
dampingFactor_ = 0;
lineSolver_(dampingFactor_, fv, false);
if (std::isnan(dampingFactor_))
dampingFactor_ = 0;
correction_ *= dampingFactor_;
x += correction_;
* \brief Export the last computed damping factor
double lastDampingFactor() const
return dampingFactor_;
* \brief Export the last used linearization
const Linearization& linearization() const
return *linearization_;
const Functional* f_;
std::shared_ptr<IterationStep<Vector,BitVector> > nonlinearSmoother_;
std::size_t preSmoothingSteps_;
std::shared_ptr<Linearization> linearization_;
LinearSolver linearSolver_;
typename Linearization::ConstrainedVector constrainedCorrection_;
Vector correction_;
DefectProjection projection_;
LineSearchSolver lineSolver_;
double dampingFactor_;
} // end namespace TNNMG
} // end namespace Dune
template<class TNNMGProblemTypeTEMPLATE, class NonlinearSmootherType>
class TruncatedNonsmoothNewtonMultigrid : public IterationStep<typename TNNMGProblemTypeTEMPLATE::VectorType>
......@@ -198,5 +345,6 @@ class TruncatedNonsmoothNewtonMultigrid : public IterationStep<typename TNNMGPro
mutable std::ostringstream outStream_;
Supports Markdown
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