OGS 6.1.0-1721-g6382411ad
NumLib::NonlinearSolver< NonlinearSolverTag::Picard > Class Template Referencefinal

Detailed Description

template<>
class NumLib::NonlinearSolver< NonlinearSolverTag::Picard >

Find a solution to a nonlinear equation using the Picard fixpoint iteration method.

Definition at line 142 of file NonlinearSolver.h.

#include <NonlinearSolver.h>

Inheritance diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Picard >:
Collaboration diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Picard >:

Public Types

using System = NonlinearSystem< NonlinearSolverTag::Picard >
 Type of the nonlinear equation system to be solved. More...
 

Public Member Functions

 NonlinearSolver (GlobalLinearSolver &linear_solver, const int maxiter)
 
void setEquationSystem (System &eq, ConvergenceCriterion &conv_crit)
 
void assemble (GlobalVector const &x) const override
 
NonlinearSolverStatus solve (GlobalVector &x, std::function< void(int, GlobalVector const &)> const &postIterationCallback) override
 
- Public Member Functions inherited from NumLib::NonlinearSolverBase
virtual ~NonlinearSolverBase ()=default
 

Private Attributes

GlobalLinearSolver & _linear_solver
 
System_equation_system = nullptr
 
ConvergenceCriterion_convergence_criterion = nullptr
 
const int _maxiter
 maximum number of iterations More...
 
std::size_t _A_id = 0u
 ID of the $ A $ matrix. More...
 
std::size_t _rhs_id = 0u
 ID of the right-hand side vector. More...
 
std::size_t _x_new_id = 0u
 

Member Typedef Documentation

◆ System

Type of the nonlinear equation system to be solved.

Definition at line 147 of file NonlinearSolver.h.

Constructor & Destructor Documentation

◆ NonlinearSolver()

NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::NonlinearSolver ( GlobalLinearSolver &  linear_solver,
const int  maxiter 
)
inlineexplicit

Constructs a new instance.

Parameters
linear_solverthe linear solver used by this nonlinear solver.
maxiterthe maximum number of iterations used to solve the equation.

Definition at line 155 of file NonlinearSolver.h.

157  : _linear_solver(linear_solver), _maxiter(maxiter)
158  {
159  }
const int _maxiter
maximum number of iterations

Member Function Documentation

◆ assemble()

void NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::assemble ( GlobalVector const &  x) const
overridevirtual

Only assemble the equation system.

Note
This method is needed to preload CrankNicolson time discretization scheme. It is not used for the general solver steps; in those only the solve() method is needed.
Parameters
xthe state at which the equation system will be assembled.

Implements NumLib::NonlinearSolverBase.

Definition at line 23 of file NonlinearSolver.cpp.

◆ setEquationSystem()

void NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::setEquationSystem ( System eq,
ConvergenceCriterion conv_crit 
)
inline

Set the nonlinear equation system that will be solved. TODO doc

Definition at line 163 of file NonlinearSolver.h.

◆ solve()

NonlinearSolverStatus NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::solve ( GlobalVector &  x,
std::function< void(int, GlobalVector const &)> const &  postIterationCallback 
)
overridevirtual

Assemble and solve the equation system.

Parameters
xin: the initial guess, out: the solution.
postIterationCallbackcalled after each iteration if set.
Return values
trueif the equation system could be solved
falseotherwise

Implements NumLib::NonlinearSolverBase.

Definition at line 29 of file NonlinearSolver.cpp.

References MathLib::LinAlg::axpy(), MathLib::LinAlg::copy(), BaseLib::RunTime::elapsed(), NumLib::FAILURE, NumLib::MatrixProvider::getMatrix(), NumLib::VectorProvider::getVector(), MathLib::LinAlg::matMult(), NumLib::GlobalVectorProvider::provider, NumLib::GlobalMatrixProvider::provider, NumLib::MatrixProvider::releaseMatrix(), NumLib::VectorProvider::releaseVector(), NumLib::REPEAT_ITERATION, BaseLib::RunTime::start(), and NumLib::SUCCESS.

33 {
34  namespace LinAlg = MathLib::LinAlg;
35  auto& sys = *_equation_system;
36 
37  auto& A =
40  _rhs_id);
42 
43  bool error_norms_met = false;
44 
45  LinAlg::copy(x, x_new); // set initial guess
46 
48 
49  int iteration = 1;
50  for (; iteration <= _maxiter;
51  ++iteration, _convergence_criterion->reset())
52  {
53  BaseLib::RunTime timer_dirichlet;
54  double time_dirichlet = 0.0;
55 
56  BaseLib::RunTime time_iteration;
57  time_iteration.start();
58 
59  timer_dirichlet.start();
60  sys.computeKnownSolutions(x_new);
61  sys.applyKnownSolutions(x_new);
62  time_dirichlet += timer_dirichlet.elapsed();
63 
64  sys.preIteration(iteration, x_new);
65 
66  BaseLib::RunTime time_assembly;
67  time_assembly.start();
68  sys.assemble(x_new);
69  sys.getA(A);
70  sys.getRhs(rhs);
71  INFO("[time] Assembly took %g s.", time_assembly.elapsed());
72 
73  timer_dirichlet.start();
74  sys.applyKnownSolutionsPicard(A, rhs, x_new);
75  time_dirichlet += timer_dirichlet.elapsed();
76  INFO("[time] Applying Dirichlet BCs took %g s.", time_dirichlet);
77 
78  if (!sys.isLinear() && _convergence_criterion->hasResidualCheck()) {
79  GlobalVector res;
80  LinAlg::matMult(A, x_new, res); // res = A * x_new
81  LinAlg::axpy(res, -1.0, rhs); // res -= rhs
83  }
84 
85  BaseLib::RunTime time_linear_solver;
86  time_linear_solver.start();
87  bool iteration_succeeded = _linear_solver.solve(A, rhs, x_new);
88  INFO("[time] Linear solver took %g s.", time_linear_solver.elapsed());
89 
90  if (!iteration_succeeded)
91  {
92  ERR("Picard: The linear solver failed.");
93  }
94  else
95  {
96  if (postIterationCallback)
97  postIterationCallback(iteration, x_new);
98 
99  switch (sys.postIteration(x_new))
100  {
102  // Don't copy here. The old x might still be used further
103  // below. Although currently it is not.
104  break;
106  ERR("Picard: The postIteration() hook reported a "
107  "non-recoverable error.");
108  iteration_succeeded = false;
109  // Copy new solution to x.
110  // Thereby the failed solution can be used by the caller for
111  // debugging purposes.
112  LinAlg::copy(x_new, x);
113  break;
115  INFO(
116  "Picard: The postIteration() hook decided that this "
117  "iteration has to be repeated.");
118  LinAlg::copy(x, x_new); // throw the iteration result away
119  continue;
120  }
121  }
122 
123  if (!iteration_succeeded)
124  {
125  // Don't compute error norms, break here.
126  error_norms_met = false;
127  break;
128  }
129 
130  if (sys.isLinear()) {
131  error_norms_met = true;
132  } else {
134  GlobalVector minus_delta_x(x);
135  LinAlg::axpy(minus_delta_x, -1.0,
136  x_new); // minus_delta_x = x - x_new
137  _convergence_criterion->checkDeltaX(minus_delta_x, x_new);
138  }
139 
140  error_norms_met = _convergence_criterion->isSatisfied();
141  }
142 
143  // Update x s.t. in the next iteration we will compute the right delta x
144  LinAlg::copy(x_new, x);
145 
146  INFO("[time] Iteration #%u took %g s.", iteration,
147  time_iteration.elapsed());
148 
149  if (error_norms_met)
150  break;
151 
152  // Avoid increment of the 'iteration' if the error norms are not met,
153  // but maximum number of iterations is reached.
154  if (iteration >= _maxiter)
155  break;
156  }
157 
158  if (iteration > _maxiter)
159  {
160  ERR("Picard: Could not solve the given nonlinear system within %u "
161  "iterations",
162  _maxiter);
163  }
164 
168 
169  return {error_norms_met, iteration};
170 }
void matMult(Matrix const &A, Vector const &x, Vector &y)
Definition: LinAlg.h:113
virtual void releaseMatrix(GlobalMatrix const &A)=0
const int _maxiter
maximum number of iterations
virtual GlobalVector & getVector()=0
Get an uninitialized vector.
std::size_t _rhs_id
ID of the right-hand side vector.
static NUMLIB_EXPORT MatrixProvider & provider
virtual bool hasResidualCheck() const =0
static NUMLIB_EXPORT VectorProvider & provider
virtual void checkDeltaX(GlobalVector const &minus_delta_x, GlobalVector const &x)=0
virtual GlobalMatrix & getMatrix()=0
Get an uninitialized matrix.
Count the running time.
Definition: RunTime.h:32
void start()
Start the timer.
Definition: RunTime.h:36
virtual bool hasDeltaXCheck() const =0
virtual void releaseVector(GlobalVector const &x)=0
virtual bool isSatisfied() const
Tell if the convergence criterion is satisfied.
void axpy(MatrixOrVector &y, double const a, MatrixOrVector const &x)
Computes .
Definition: LinAlg.h:57
void copy(MatrixOrVector const &x, MatrixOrVector &y)
Copies x to y.
Definition: LinAlg.h:36
virtual void checkResidual(GlobalVector const &residual)=0
Check if the residual satisfies the convergence criterion.
double elapsed() const
Get the elapsed time after started.
Definition: RunTime.h:52

Member Data Documentation

◆ _A_id

std::size_t NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_A_id = 0u
private

ID of the $ A $ matrix.

Definition at line 184 of file NonlinearSolver.h.

◆ _convergence_criterion

ConvergenceCriterion* NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_convergence_criterion = nullptr
private

Definition at line 181 of file NonlinearSolver.h.

◆ _equation_system

System* NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_equation_system = nullptr
private

Definition at line 178 of file NonlinearSolver.h.

◆ _linear_solver

GlobalLinearSolver& NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_linear_solver
private

Definition at line 177 of file NonlinearSolver.h.

◆ _maxiter

const int NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_maxiter
private

maximum number of iterations

Definition at line 182 of file NonlinearSolver.h.

◆ _rhs_id

std::size_t NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_rhs_id = 0u
private

ID of the right-hand side vector.

Definition at line 185 of file NonlinearSolver.h.

◆ _x_new_id

std::size_t NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_x_new_id = 0u
private

ID of the vector storing the solution of the linearized equation.

Definition at line 186 of file NonlinearSolver.h.


The documentation for this class was generated from the following files: