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 171 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 176 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 184 of file NonlinearSolver.h.

References _linear_solver, and _maxiter.

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

◆ ~NonlinearSolver()

Definition at line 622 of file NonlinearSolver.cpp.

623{
624 if (_r_neq != nullptr)
625 {
627 }
628}
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 82 of file NonlinearSolver.cpp.

86{
88 {
89 return;
90 }
91
92 INFO("Calculate non-equilibrium initial residuum.");
93
97 _equation_system->getA(A);
99
100 // r_neq = A * x - rhs
103 MathLib::LinAlg::axpy(*_r_neq, -1.0, rhs); // res -= rhs
104
105 // Set the values of the selected entries of _r_neq, which are associated
106 // with the equations that do not need initial residual compensation, to
107 // zero.
108 const auto selected_global_indices =
109 _equation_system->getIndicesOfResiduumWithoutInitialCompensation();
110
113 _equation_system->setReleaseNodalForces(_r_neq, process_id);
114
116
119}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
std::size_t _rhs_id
ID of the right-hand side vector.
void finalizeAssembly(PETScMatrix &A)
Definition LinAlg.cpp:191
void matMult(PETScMatrix const &A, PETScVector const &x, PETScVector &y)
Definition LinAlg.cpp:142
void axpy(PETScVector &y, PetscScalar const a, PETScVector const &x)
Definition LinAlg.cpp:50

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 194 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 121 of file NonlinearSolver.cpp.

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

Referenced by calculateNonEquilibriumInitialResiduum(), and compensateNonEquilibriumInitialResiduum().

◆ _convergence_criterion

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

Definition at line 222 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 218 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 223 of file NonlinearSolver.h.

Referenced by NonlinearSolver(), and solve().

◆ _r_neq

non-equilibrium initial residuum.

Definition at line 225 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 230 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 227 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 228 of file NonlinearSolver.h.

Referenced by solve().


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