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.

References _linear_solver, and _maxiter.

Referenced by ~NonlinearSolver(), calculateNonEquilibriumInitialResiduum(), and solve().

◆ ~NonlinearSolver()

Definition at line 629 of file NonlinearSolver.cpp.

630{
631 if (_r_neq != nullptr)
632 {
634 }
635}
GlobalVector * _r_neq
non-equilibrium initial residuum.

References NonlinearSolver(), _r_neq, and NumLib::GlobalVectorProvider::provider.

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);
104 _equation_system->getA(A);
106
107 // r_neq = A * x - rhs
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 =
116 _equation_system->getIndicesOfResiduumWithoutInitialCompensation();
117
120 _equation_system->setReleaseNodalForces(_r_neq, process_id);
121
123
126}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:36
std::size_t _rhs_id
ID of the right-hand side vector.
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

References NonlinearSolver(), _A_id, _compensate_non_equilibrium_initial_residuum, _equation_system, _r_neq, _r_neq_id, _rhs_id, MathLib::LinAlg::axpy(), MathLib::LinAlg::finalizeAssembly(), INFO(), MathLib::LinAlg::matMult(), NumLib::GlobalMatrixProvider::provider, and NumLib::GlobalVectorProvider::provider.

◆ compensateNonEquilibriumInitialResiduum()

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

◆ 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.

References _convergence_criterion, and _equation_system.

◆ 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 128 of file NonlinearSolver.cpp.

134{
135 namespace LinAlg = MathLib::LinAlg;
136 auto& sys = *_equation_system;
137
140
144 LinAlg::copy(*x[process_id], *x_new[process_id]); // set initial guess
145
146 bool error_norms_met = false;
147
148 _convergence_criterion->preFirstIteration();
149
150 int iteration = 1;
151 for (; iteration <= _maxiter; ++iteration, _convergence_criterion->reset())
152 {
154 double time_dirichlet = 0.0;
155
157 time_iteration.start();
158
159 INFO("Iteration #{:d} started.", iteration);
160 timer_dirichlet.start();
163 sys.computeKnownSolutions(x_new_process, process_id);
164 sys.applyKnownSolutions(x_new_process);
165 time_dirichlet += timer_dirichlet.elapsed();
166
167 sys.preIteration(iteration, x_new_process);
168
170 time_assembly.start();
171 sys.assemble(x_new, x_prev, process_id);
172 sys.getA(A);
173 sys.getRhs(*x_prev[process_id], rhs);
174
175 // Normalize the linear equation system, if required
176 if (sys.requiresNormalization() &&
177 !_linear_solver.canSolveRectangular())
178 {
179 sys.getAandRhsNormalized(A, rhs);
180 WARN(
181 "The equation system is rectangular, but the current linear "
182 "solver only supports square systems. "
183 "The system will be normalized, which lead to a squared "
184 "condition number and potential numerical issues. "
185 "It is recommended to use a solver that supports rectangular "
186 "equation systems for better numerical stability.");
187 }
188
189 INFO("[time] Assembly took {:g} s.", time_assembly.elapsed());
190
191 // Subtract non-equilibrium initial residuum if set
192 if (_r_neq != nullptr)
193 {
194 LinAlg::axpy(rhs, -1, *_r_neq);
195 }
196
197 auto const solver_needs_to_compute = sys.linearSolverNeedsToCompute();
198 bool const solver_will_compute =
200
201 timer_dirichlet.start();
202 sys.applyKnownSolutionsPicard(
208 time_dirichlet += timer_dirichlet.elapsed();
209 INFO("[time] Applying Dirichlet BCs took {:g} s.", time_dirichlet);
210
211 if (!sys.isLinear() && _convergence_criterion->hasResidualCheck())
212 {
214 {
215 // !solver_will_compute means that the Dirichlet BC application
216 // is incomplete (i.e., A not properly modified) and the
217 // computed residual is wrong.
218 OGS_FATAL(
219 "Logic error. The solver skips the compute step for a "
220 "non-linear equation system.");
221 }
223 LinAlg::matMult(A, x_new_process, res); // res = A * x_new
224 LinAlg::axpy(res, -1.0, rhs); // res -= rhs
225 _convergence_criterion->checkResidual(res);
226 }
227
230
232 {
234 {
236 }
237
238 switch (sys.postIteration(x_new_process))
239 {
241 // Don't copy here. The old x might still be used further
242 // below. Although currently it is not.
243 break;
245 ERR("Picard: The postIteration() hook reported a "
246 "non-recoverable error.");
247 iteration_succeeded = false;
248 // Copy new solution to x.
249 // Thereby the failed solution can be used by the caller for
250 // debugging purposes.
252 break;
254 INFO(
255 "Picard: The postIteration() hook decided that this "
256 "iteration has to be repeated.");
258 *x[process_id],
259 x_new_process); // throw the iteration result away
260 continue;
261 }
262 }
263
265 {
266 // Don't compute error norms, break here.
267 error_norms_met = false;
268 break;
269 }
270
271 if (sys.isLinear())
272 {
273 error_norms_met = true;
274 }
275 else
276 {
277 if (_convergence_criterion->hasDeltaXCheck())
278 {
281 x_new_process); // minus_delta_x = x - x_new
284 }
285
287 }
288
289 // Update x s.t. in the next iteration we will compute the right delta x
291
292 INFO("[time] Iteration #{:d} took {:g} s.", iteration,
293 time_iteration.elapsed());
294
295 if (error_norms_met)
296 {
297 break;
298 }
299
300 // Avoid increment of the 'iteration' if the error norms are not met,
301 // but maximum number of iterations is reached.
302 if (iteration >= _maxiter)
303 {
304 break;
305 }
306 }
307
308 if (iteration > _maxiter)
309 {
310 ERR("Picard: Could not solve the given nonlinear system within {:d} "
311 "iterations",
312 _maxiter);
313 }
314
318
319 return {error_norms_met, iteration};
320}
#define OGS_FATAL(...)
Definition Error.h:26
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:48
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:42
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 NonlinearSolver(), _A_id, _convergence_criterion, _equation_system, _linear_solver, _maxiter, _r_neq, _rhs_id, _x_new_id, MathLib::LinAlg::axpy(), MathLib::COMPLETE_MATRIX_UPDATE, MathLib::LinAlg::copy(), BaseLib::RunTime::elapsed(), ERR(), NumLib::FAILURE, INFO(), MathLib::LinAlg::matMult(), OGS_FATAL, NumLib::GlobalMatrixProvider::provider, NumLib::GlobalVectorProvider::provider, 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.

Referenced by calculateNonEquilibriumInitialResiduum(), and solve().

◆ _compensate_non_equilibrium_initial_residuum

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

Enables computation of the non-equilibrium initial residuum \( r_{\rm neq} \) before the first time step. The forces are zero if the external forces are in equilibrium with the initial state/initial conditions. During the simulation the new residuum reads \( \tilde r = r - r_{\rm neq} \).

Definition at line 242 of file NonlinearSolver.h.

Referenced by calculateNonEquilibriumInitialResiduum(), and compensateNonEquilibriumInitialResiduum().

◆ _convergence_criterion

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

Definition at line 229 of file NonlinearSolver.h.

Referenced by setEquationSystem(), and solve().

◆ _equation_system

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

◆ _linear_solver

Definition at line 225 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _maxiter

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

maximum number of iterations

Definition at line 230 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _r_neq

non-equilibrium initial residuum.

Definition at line 232 of file NonlinearSolver.h.

Referenced by ~NonlinearSolver(), calculateNonEquilibriumInitialResiduum(), and solve().

◆ _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.

Referenced by calculateNonEquilibriumInitialResiduum().

◆ _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.

Referenced by calculateNonEquilibriumInitialResiduum(), and solve().

◆ _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.

Referenced by solve().


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