From 6c98a63a0eca1d0abbc700bdd5a43bbf2d0737f9 Mon Sep 17 00:00:00 2001 From: Christoph Lehmann <christoph.lehmann@ufz.de> Date: Sat, 16 Sep 2023 11:18:13 +0200 Subject: [PATCH] [NL] Picard: Linear solver computes only if necessary --- NumLib/ODESolver/NonlinearSolver.cpp | 73 ++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/NumLib/ODESolver/NonlinearSolver.cpp b/NumLib/ODESolver/NonlinearSolver.cpp index 29b4e69ffeb..1e57a38f1ea 100644 --- a/NumLib/ODESolver/NonlinearSolver.cpp +++ b/NumLib/ODESolver/NonlinearSolver.cpp @@ -24,6 +24,67 @@ namespace NumLib { +namespace detail +{ +#if !defined(USE_PETSC) && !defined(USE_LIS) +bool solvePicard(GlobalLinearSolver& linear_solver, GlobalMatrix& A, + GlobalVector& rhs, GlobalVector& x, + bool const compute_necessary) +{ + BaseLib::RunTime time_linear_solver; + time_linear_solver.start(); + + if (compute_necessary) + { + if (!linear_solver.compute(A)) + { + ERR("Picard: The linear solver failed in the compute() step."); + return false; + } + } + + bool const iteration_succeeded = linear_solver.solve(rhs, x); + + INFO("[time] Linear solver took {:g} s.", time_linear_solver.elapsed()); + + if (iteration_succeeded) + { + return true; + } + + ERR("Picard: The linear solver failed in the solve() step."); + return false; +} +#else +bool solvePicard(GlobalLinearSolver& linear_solver, GlobalMatrix& A, + GlobalVector& rhs, GlobalVector& x, + bool const compute_necessary) +{ + if (!compute_necessary) + { + WARN( + "The performance optimization to skip the linear solver compute() " + "step is not implemented for PETSc or LIS linear solvers."); + } + + BaseLib::RunTime time_linear_solver; + time_linear_solver.start(); + + bool const iteration_succeeded = linear_solver.solve(A, rhs, x); + + INFO("[time] Linear solver took {:g} s.", time_linear_solver.elapsed()); + + if (iteration_succeeded) + { + return true; + } + + ERR("Picard: The linear solver failed in the solve() step."); + return false; +} +#endif +} // namespace detail + void NonlinearSolver<NonlinearSolverTag::Picard>:: calculateNonEquilibriumInitialResiduum( std::vector<GlobalVector*> const& x, @@ -128,17 +189,11 @@ NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Picard>::solve( _convergence_criterion->checkResidual(res); } - BaseLib::RunTime time_linear_solver; - time_linear_solver.start(); bool iteration_succeeded = - _linear_solver.solve(A, rhs, *x_new[process_id]); - INFO("[time] Linear solver took {:g} s.", time_linear_solver.elapsed()); + detail::solvePicard(_linear_solver, A, rhs, x_new_process, + sys.linearSolverNeedsToCompute()); - if (!iteration_succeeded) - { - ERR("Picard: The linear solver failed."); - } - else + if (iteration_succeeded) { if (postIterationCallback) { -- GitLab