Processing math: 100%
OGS
NumLib::NonlinearSolver< NonlinearSolverTag::Picard > Class Referencefinal

Detailed Description

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

Definition at line 178 of file NonlinearSolver.h.

#include <NonlinearSolver.h>

Inheritance diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Picard >:
[legend]
Collaboration diagram for NumLib::NonlinearSolver< NonlinearSolverTag::Picard >:
[legend]

Public Types

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

Public Member Functions

 NonlinearSolver (GlobalLinearSolver &linear_solver, const int maxiter)
 
 ~NonlinearSolver ()
 
void setEquationSystem (System &eq, ConvergenceCriterion &conv_crit)
 
void calculateNonEquilibriumInitialResiduum (std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id) override
 
NonlinearSolverStatus solve (std::vector< GlobalVector * > &x, std::vector< GlobalVector * > const &x_prev, std::function< void(int, bool, std::vector< GlobalVector * > const &)> const &postIterationCallback, int const process_id) override
 
void compensateNonEquilibriumInitialResiduum (bool const value)
 
- 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
 
GlobalVector_r_neq = nullptr
 non-equilibrium initial residuum.
 
std::size_t _A_id = 0u
 ID of the A matrix.
 
std::size_t _rhs_id = 0u
 ID of the right-hand side vector.
 
std::size_t _x_new_id = 0u
 
std::size_t _r_neq_id = 0u
 
bool _compensate_non_equilibrium_initial_residuum = false
 

Member Typedef Documentation

◆ System

Type of the nonlinear equation system to be solved.

Definition at line 183 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 191 of file NonlinearSolver.h.

193 : _linear_solver(linear_solver), _maxiter(maxiter)
194 {
195 }
const int _maxiter
maximum number of iterations

◆ ~NonlinearSolver()

Member Function Documentation

◆ calculateNonEquilibriumInitialResiduum()

void NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::calculateNonEquilibriumInitialResiduum ( std::vector< GlobalVector * > const & x,
std::vector< GlobalVector * > const & x_prev,
int const process_id )
overridevirtual

Implements NumLib::NonlinearSolverBase.

Definition at line 89 of file NonlinearSolver.cpp.

93{
95 {
96 return;
97 }
98
99 INFO("Calculate non-equilibrium initial residuum.");
100
103 _equation_system->assemble(x, x_prev, process_id);
105 _equation_system->getRhs(*x_prev[process_id], rhs);
106
107 // r_neq = A * x - rhs
109 MathLib::LinAlg::matMult(A, *x[process_id], *_r_neq);
110 MathLib::LinAlg::axpy(*_r_neq, -1.0, rhs); // res -= rhs
111
112 // Set the values of the selected entries of _r_neq, which are associated
113 // with the equations that do not need initial residual compensation, to
114 // zero.
115 const auto selected_global_indices =
117
118 std::vector<double> zero_entries(selected_global_indices.size(), 0.0);
119 _r_neq->set(selected_global_indices, zero_entries);
120
122
125}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void set(IndexType rowId, double v)
set entry
Definition EigenVector.h:74
virtual void releaseMatrix(GlobalMatrix const &A)=0
virtual GlobalMatrix & getMatrix(std::size_t &id)=0
Get an uninitialized matrix with the given id.
std::size_t _rhs_id
ID of the right-hand side vector.
GlobalVector * _r_neq
non-equilibrium initial residuum.
virtual void getA(GlobalMatrix &A) const =0
virtual std::vector< GlobalIndexType > getIndicesOfResiduumWithoutInitialCompensation() const =0
virtual void assemble(std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id)=0
virtual void getRhs(GlobalVector const &x_prev, GlobalVector &rhs) const =0
virtual GlobalVector & getVector(std::size_t &id)=0
Get an uninitialized vector with the given id.
virtual void releaseVector(GlobalVector const &x)=0
void finalizeAssembly(PETScMatrix &A)
Definition LinAlg.cpp:198
void matMult(PETScMatrix const &A, PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:149
void axpy(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:57
static NUMLIB_EXPORT MatrixProvider & provider
static NUMLIB_EXPORT VectorProvider & provider

References MathLib::LinAlg::axpy(), MathLib::LinAlg::finalizeAssembly(), NumLib::MatrixProvider::getMatrix(), NumLib::VectorProvider::getVector(), INFO(), MathLib::LinAlg::matMult(), NumLib::GlobalMatrixProvider::provider, NumLib::GlobalVectorProvider::provider, NumLib::MatrixProvider::releaseMatrix(), and NumLib::VectorProvider::releaseVector().

◆ compensateNonEquilibriumInitialResiduum()

void NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::compensateNonEquilibriumInitialResiduum ( bool const value)
inline

Definition at line 219 of file NonlinearSolver.h.

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

202 {
203 _equation_system = &eq;
204 _convergence_criterion = &conv_crit;
205 }

◆ solve()

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

Assemble and solve the equation system.

Parameters
xin: the initial guess, out: the solution.
x_prevprevious time step 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 127 of file NonlinearSolver.cpp.

133{
134 namespace LinAlg = MathLib::LinAlg;
135 auto& sys = *_equation_system;
136
139
140 std::vector<GlobalVector*> x_new{x};
141 x_new[process_id] =
143 LinAlg::copy(*x[process_id], *x_new[process_id]); // set initial guess
144
145 bool error_norms_met = false;
146
148
149 int iteration = 1;
150 for (; iteration <= _maxiter; ++iteration, _convergence_criterion->reset())
151 {
152 BaseLib::RunTime timer_dirichlet;
153 double time_dirichlet = 0.0;
154
155 BaseLib::RunTime time_iteration;
156 time_iteration.start();
157
158 INFO("Iteration #{:d} started.", iteration);
159 timer_dirichlet.start();
160 auto& x_new_process = *x_new[process_id];
162 sys.computeKnownSolutions(x_new_process, process_id);
163 sys.applyKnownSolutions(x_new_process);
164 time_dirichlet += timer_dirichlet.elapsed();
165
166 sys.preIteration(iteration, x_new_process);
167
168 BaseLib::RunTime time_assembly;
169 time_assembly.start();
170 sys.assemble(x_new, x_prev, process_id);
171 sys.getA(A);
172 sys.getRhs(*x_prev[process_id], rhs);
173
174 // Normalize the linear equation system, if required
175 if (sys.requiresNormalization() &&
177 {
178 sys.getAandRhsNormalized(A, rhs);
179 WARN(
180 "The equation system is rectangular, but the current linear "
181 "solver only supports square systems. "
182 "The system will be normalized, which lead to a squared "
183 "condition number and potential numerical issues. "
184 "It is recommended to use a solver that supports rectangular "
185 "equation systems for better numerical stability.");
186 }
187
188 INFO("[time] Assembly took {:g} s.", time_assembly.elapsed());
189
190 // Subtract non-equilibrium initial residuum if set
191 if (_r_neq != nullptr)
192 {
193 LinAlg::axpy(rhs, -1, *_r_neq);
194 }
195
196 timer_dirichlet.start();
197 sys.applyKnownSolutionsPicard(A, rhs, x_new_process);
198 time_dirichlet += timer_dirichlet.elapsed();
199 INFO("[time] Applying Dirichlet BCs took {:g} s.", time_dirichlet);
200
201 if (!sys.isLinear() && _convergence_criterion->hasResidualCheck())
202 {
203 GlobalVector res;
204 LinAlg::matMult(A, x_new_process, res); // res = A * x_new
205 LinAlg::axpy(res, -1.0, rhs); // res -= rhs
207 }
208
209 bool iteration_succeeded =
210 detail::solvePicard(_linear_solver, A, rhs, x_new_process,
211 sys.linearSolverNeedsToCompute());
212
213 if (iteration_succeeded)
214 {
215 if (postIterationCallback)
216 {
217 postIterationCallback(iteration, error_norms_met, x_new);
218 }
219
220 switch (sys.postIteration(x_new_process))
221 {
223 // Don't copy here. The old x might still be used further
224 // below. Although currently it is not.
225 break;
227 ERR("Picard: The postIteration() hook reported a "
228 "non-recoverable error.");
229 iteration_succeeded = false;
230 // Copy new solution to x.
231 // Thereby the failed solution can be used by the caller for
232 // debugging purposes.
233 LinAlg::copy(x_new_process, *x[process_id]);
234 break;
236 INFO(
237 "Picard: The postIteration() hook decided that this "
238 "iteration has to be repeated.");
240 *x[process_id],
241 x_new_process); // throw the iteration result away
242 continue;
243 }
244 }
245
246 if (!iteration_succeeded)
247 {
248 // Don't compute error norms, break here.
249 error_norms_met = false;
250 break;
251 }
252
253 if (sys.isLinear())
254 {
255 error_norms_met = true;
256 }
257 else
258 {
260 {
261 GlobalVector minus_delta_x(*x[process_id]);
262 LinAlg::axpy(minus_delta_x, -1.0,
263 x_new_process); // minus_delta_x = x - x_new
264 _convergence_criterion->checkDeltaX(minus_delta_x,
265 x_new_process);
266 }
267
268 error_norms_met = _convergence_criterion->isSatisfied();
269 }
270
271 // Update x s.t. in the next iteration we will compute the right delta x
272 LinAlg::copy(x_new_process, *x[process_id]);
273
274 INFO("[time] Iteration #{:d} took {:g} s.", iteration,
275 time_iteration.elapsed());
276
277 if (error_norms_met)
278 {
279 break;
280 }
281
282 // Avoid increment of the 'iteration' if the error norms are not met,
283 // but maximum number of iterations is reached.
284 if (iteration >= _maxiter)
285 {
286 break;
287 }
288 }
289
290 if (iteration > _maxiter)
291 {
292 ERR("Picard: Could not solve the given nonlinear system within {:d} "
293 "iterations",
294 _maxiter);
295 }
296
300
301 return {error_norms_met, iteration};
302}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
Count the running time.
Definition RunTime.h:29
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:42
void start()
Start the timer.
Definition RunTime.h:32
bool canSolveRectangular() const
Get, if the solver can handle rectangular equation systems.
Global vector based on Eigen vector.
Definition EigenVector.h:26
virtual void checkResidual(GlobalVector const &residual)=0
Check if the residual satisfies the convergence criterion.
virtual bool hasResidualCheck() const =0
virtual bool isSatisfied() const
Tell if the convergence criterion is satisfied.
virtual void checkDeltaX(GlobalVector const &minus_delta_x, GlobalVector const &x)=0
virtual bool hasDeltaXCheck() const =0
void copy(PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:37
void setLocalAccessibleVector(PETScVector const &x)
Definition LinAlg.cpp:27
bool solvePicard(GlobalLinearSolver &linear_solver, GlobalMatrix &A, GlobalVector &rhs, GlobalVector &x, MathLib::LinearSolverBehaviour const linear_solver_behaviour)

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

Member Data Documentation

◆ _A_id

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

ID of the A matrix.

Definition at line 233 of file NonlinearSolver.h.

◆ _compensate_non_equilibrium_initial_residuum

bool NumLib::NonlinearSolver< NonlinearSolverTag::Picard >::_compensate_non_equilibrium_initial_residuum = false
private

Definition at line 242 of file NonlinearSolver.h.

◆ _convergence_criterion

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

Definition at line 229 of file NonlinearSolver.h.

◆ _equation_system

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

Definition at line 226 of file NonlinearSolver.h.

◆ _linear_solver

Definition at line 225 of file NonlinearSolver.h.

◆ _maxiter

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

maximum number of iterations

Definition at line 230 of file NonlinearSolver.h.

◆ _r_neq

non-equilibrium initial residuum.

Definition at line 232 of file NonlinearSolver.h.

◆ _r_neq_id

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

ID of the non-equilibrium initial residuum vector.

Definition at line 237 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 234 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 235 of file NonlinearSolver.h.


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