OGS 6.2.1-499-g3b941532c.dirty.20191012113459
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 148 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 (std::vector< GlobalVector *> const &x, int const process_id) const override
 
NonlinearSolverStatus solve (std::vector< GlobalVector *> &x, std::function< void(int, GlobalVector const &)> const &postIterationCallback, int const process_id) 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 153 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 161 of file NonlinearSolver.h.

163  : _linear_solver(linear_solver), _maxiter(maxiter)
164  {
165  }
const int _maxiter
maximum number of iterations

Member Function Documentation

◆ assemble()

void NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::assemble ( std::vector< GlobalVector *> const &  x,
int const  process_id 
) 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.
process_idthe process' id which will be assembled.

Implements NumLib::NonlinearSolverBase.

Definition at line 24 of file NonlinearSolver.cpp.

26 {
27  _equation_system->assemble(x, process_id);
28 }
virtual void assemble(std::vector< GlobalVector *> const &x, int const process_id)=0

◆ 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 169 of file NonlinearSolver.h.

◆ solve()

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

Assemble and solve the equation system.

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

Implements NumLib::NonlinearSolverBase.

Definition at line 30 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.

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

Member Data Documentation

◆ _A_id

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

ID of the $ A $ matrix.

Definition at line 192 of file NonlinearSolver.h.

◆ _convergence_criterion

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

Definition at line 189 of file NonlinearSolver.h.

◆ _equation_system

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

Definition at line 186 of file NonlinearSolver.h.

◆ _linear_solver

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

Definition at line 185 of file NonlinearSolver.h.

◆ _maxiter

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

maximum number of iterations

Definition at line 190 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 193 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 194 of file NonlinearSolver.h.


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