Documentation 6b54b78464
Loading...
Searching...
No Matches
CNewtonIntegration.hpp
Go to the documentation of this file.
1/*!
2 * \file CNewtonIntegration.hpp
3 * \brief Newton-Krylov integration.
4 * \author P. Gomes
5 * \version 8.5.0 "Harrier"
6 *
7 * SU2 Project Website: https://su2code.github.io
8 *
9 * The SU2 Project is maintained by the SU2 Foundation
10 * (http://su2foundation.org)
11 *
12 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
13 *
14 * SU2 is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * SU2 is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28#include "CIntegration.hpp"
29#include "../../../Common/include/parallelization/omp_structure.hpp"
30#include "../../../Common/include/linear_algebra/CPreconditioner.hpp"
31#include "../../../Common/include/linear_algebra/CMatrixVectorProduct.hpp"
32#include "../../../Common/include/linear_algebra/CSysSolve.hpp"
33
34#ifdef HAVE_OMP
35#ifdef HAVE_OMP_SIMD
36#define CNEWTON_PARFOR SU2_OMP_FOR_(simd schedule(static,omp_chunk_size) SU2_NOWAIT)
37#else
38#define CNEWTON_PARFOR SU2_OMP_FOR_(schedule(static,omp_chunk_size) SU2_NOWAIT)
39#endif
40#define END_CNEWTON_PARFOR END_SU2_OMP_FOR
41#else
42#define CNEWTON_PARFOR SU2_OMP_SIMD
43#define END_CNEWTON_PARFOR
44#endif
45
46/*!
47 * \class CNewtonIntegration
48 * \ingroup Drivers
49 * \brief Class for time integration using a Newton-Krylov method, based
50 * on matrix-free products with the true Jacobian via finite differences.
51 * \author P. Gomes
52 */
53class CNewtonIntegration final : public CIntegration {
54public:
55#ifdef CODI_FORWARD_TYPE
56 using Scalar = su2double;
57 using MixedScalar = su2double;
58#else
59 /*--- No point having single precision matrix-free products. ---*/
61 /*--- The block preconditioners may still use single precision. ---*/
63#endif
64
65private:
66 /*--- Residual evaluation modes, explicit for products, default to allow preconditioners to be built. ---*/
67 enum class ResEvalType {EXPLICIT, DEFAULT};
68
69 bool setup = false;
70 bool autoRelaxation = false;
71 bool useDeflation = false;
72 Scalar finDiffStepND = 0.0;
73 Scalar finDiffStep = 0.0; /*!< \brief Based on RMS(solution), used in matrix-free products. */
74 Scalar nkRelaxation = 1.0;
75 unsigned long omp_chunk_size; /*!< \brief Chunk size used in light point loops. */
76
77 /*--- Number of iterations and tolerance for the linear preconditioner,
78 * 0 iterations forces "weak" preconditioning, i.e. not iterative. ---*/
79 unsigned short precondIters = 0;
80 su2double precondTol = 0.0;
81
82 /*--- For a number of iterations, or before a certain residual drop,
83 * use the quasi-Newton approach instead of Newton-Krylov. If both
84 * criteria are zero, or the solver does not provide a linear
85 * preconditioner, there is no startup phase. ---*/
86 bool startupPeriod = false;
87 unsigned short startupIters = 0, iter = 0;
88 su2double startupResidual = 0.0;
89 su2double firstResidual = -20.0;
90
91 /*--- Relax (increase) the tolerance for NK solves by a factor, until a
92 * certain drop in residuals, to reduce the cost of early iterations. ---*/
93 unsigned short tolRelaxFactor = 0;
94 su2double fullTolResidual = 0.0;
95
96 CConfig* config = nullptr;
97 CSolver** solvers = nullptr;
98 CGeometry* geometry = nullptr;
99 CNumerics*** numerics = nullptr;
100
101 /*--- Residual and linear solver. ---*/
102 CSysVector<Scalar> LinSysRes, LinSysResRelax;
103 CSysSolve<Scalar> LinSolver;
104 const CSysVector<Scalar>* LinSysRes0 = nullptr;
105
106 /*--- If possible the solution vector of the solver is re-used, otherwise this temporary is used. ---*/
107 CSysVector<Scalar> LinSysSol;
108
109 template<class T, su2enable_if<std::is_same<T,Scalar>::value> = 0>
110 inline CSysVector<Scalar>& GetSolutionVec(CSysVector<T>& x) { return x; }
111
112 template<class T, su2enable_if<std::is_same<T,Scalar>::value> = 0>
113 inline void SetSolutionResult(CSysVector<T>&) const { }
114
115 template<class T, su2enable_if<!std::is_same<T,Scalar>::value> = 0>
116 inline CSysVector<Scalar>& GetSolutionVec(CSysVector<T>&) {
117 LinSysSol = Scalar(0.0);
118 return LinSysSol;
119 }
120
121 template<class T, su2enable_if<!std::is_same<T,Scalar>::value> = 0>
122 inline void SetSolutionResult(CSysVector<T>& x) const {
124 for (auto i = 0ul; i < x.GetLocSize(); ++i) x[i] = LinSysSol[i];
126 }
127
128 /*--- Preconditioner objects for each active solver. ---*/
129 CPreconditioner<MixedScalar>* preconditioner = nullptr;
130
131 /*--- If mixed precision is used, these temporaries are used to interface with the preconditioner. ---*/
132 mutable CSysVector<MixedScalar> precondIn, precondOut;
133
134 template<class T, su2enable_if<!std::is_same<T,MixedScalar>::value> = 0>
135 inline unsigned long Preconditioner_impl(const CSysVector<T>& u, CSysVector<T>& v,
136 unsigned long iters, Scalar& eps) const {
138 for (auto i = 0ul; i < u.GetLocSize(); ++i) precondIn[i] = u[i];
140
141 iters = Preconditioner_impl(precondIn, precondOut, iters, eps);
142
144 for (auto i = 0ul; i < u.GetLocSize(); ++i) v[i] = precondOut[i];
147
148 return iters;
149 }
150
151 /*--- Otherwise they are not needed. ---*/
152 template<class T, su2enable_if<std::is_same<T,MixedScalar>::value> = 0>
153 inline unsigned long Preconditioner_impl(const CSysVector<T>& u, CSysVector<T>& v,
154 unsigned long iters, Scalar& eps) const {
155 /*--- Unlike the matrix-free outer product this is a CSysMatrix operation, it can run on the
156 * device. The outer Krylov vectors are host resident, hence the transfers. ---*/
157 unsigned long nIters = 0;
158 ApplyPreconditionerOnDevice(u, v, config->GetCUDA(), [&] { nIters = PreconditionerApply(u, v, iters, eps); });
159 return nIters;
160 }
161
162 /*!
163 * \brief The preconditioner on its own, or a nested solve with the approximate Jacobian.
164 */
165 inline unsigned long PreconditionerApply(const CSysVector<MixedScalar>& u, CSysVector<MixedScalar>& v,
166 unsigned long iters, Scalar& eps) const {
167 const auto inner_solver = config->GetKind_Linear_Solver_Inner();
168
169 if (iters == 0 || (iters == 1 && inner_solver == LINEAR_SOLVER_INNER::SMOOTHER)) {
170 (*preconditioner)(u, v);
171 return 0;
172 }
173 auto product = CSysMatrixVectorProduct<MixedScalar>(solvers[FLOW_SOL]->Jacobian, geometry, config);
174 v = MixedScalar(0.0);
175 MixedScalar eps_t = eps;
176 switch (inner_solver) {
178 iters = solvers[FLOW_SOL]->System.FGMRES_LinSolver(u, v, product, *preconditioner, eps, iters, eps_t, false, config);
179 break;
181 iters = solvers[FLOW_SOL]->System.BCGSTAB_LinSolver(u, v, product, *preconditioner, eps, iters, eps_t, false, config);
182 break;
184 iters = solvers[FLOW_SOL]->System.Smoother_LinSolver(u, v, product, *preconditioner, 0, iters, eps_t, false, config);
185 break;
186 }
187 eps = eps_t;
188 return iters;
189 }
190
191 /*!
192 * \brief Gather solver info, etc..
193 */
194 void Setup();
195
196 /*!
197 * \brief Increment the solution, x := x+mag*dir.
198 */
199 void PerturbSolution(const CSysVector<Scalar>& direction, Scalar magnitude);
200
201 /*!
202 * \brief Evaluate the nonlinear residual of the solver, which should be capable of alternating
203 * between implicit and explicit iterations to save time during matrix-free products.
204 */
205 void ComputeResiduals(ResEvalType type);
206
207 /*!
208 * \brief Compute the step size for finite differences.
209 */
210 void ComputeFinDiffStep();
211
212public:
213 /*!
214 * \brief Constructor.
215 */
217
218 /*!
219 * \brief Destructor.
220 */
222
223 /*!
224 * \brief This class overrides this method to make it a drop-in replacement for CMultigridIntegration.
225 * \param[in] geometry - Geometrical definition of the problem.
226 * \param[in] solver_container - Container vector with all the solutions.
227 * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved).
228 * \param[in] config - Definition of the particular problem.
229 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
230 * \param[in] iZone - Current zone.
231 * \param[in] iInst - Current instance.
232 */
233 void MultiGrid_Iteration(CGeometry ****geometry, CSolver *****solver_container,
234 CNumerics ******numerics_container, CConfig **config,
235 unsigned short RunTime_EqSystem, unsigned short iZone, unsigned short iInst) override;
236
237 /*!
238 * \brief Implementation of matrix-vector product with the real Jacobian of the nonlinear residuals.
239 */
241
242 /*!
243 * \brief Wrapper for the preconditioner.
244 */
246
247};
248
249#undef CNEWTON_PARFOR
250#undef END_CNEWTON_PARFOR
Declaration of the main routines to orchestrate space and time integration.
CNewtonIntegration::Scalar Scalar
Definition CNewtonIntegration.cpp:31
#define CNEWTON_PARFOR
Definition CNewtonIntegration.hpp:42
#define END_CNEWTON_PARFOR
Definition CNewtonIntegration.hpp:43
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
bool GetCUDA(void) const
Get information about GPU support.
Definition CConfig.hpp:6698
LINEAR_SOLVER_INNER GetKind_Linear_Solver_Inner(void) const
Get the inner linear solver used in nested Krylov linear solvers.
Definition CConfig.hpp:4389
Parent class for defining the geometry of the problem (complete geometry, multigrid agglomerated geom...
Definition CGeometry.hpp:75
Main class for doing the space integration, time integration, and monitoring of a system of Partial D...
Definition CIntegration.hpp:47
Class for time integration using a Newton-Krylov method, based on matrix-free products with the true ...
Definition CNewtonIntegration.hpp:53
CNewtonIntegration()=default
Constructor.
su2mixedfloat MixedScalar
Definition CNewtonIntegration.hpp:62
void MultiGrid_Iteration(CGeometry ****geometry, CSolver *****solver_container, CNumerics ******numerics_container, CConfig **config, unsigned short RunTime_EqSystem, unsigned short iZone, unsigned short iInst) override
This class overrides this method to make it a drop-in replacement for CMultigridIntegration.
Definition CNewtonIntegration.cpp:181
void Preconditioner(const CSysVector< Scalar > &u, CSysVector< Scalar > &v) const
Wrapper for the preconditioner.
Definition CNewtonIntegration.cpp:377
~CNewtonIntegration()
Destructor.
Definition CNewtonIntegration.cpp:62
passivedouble Scalar
Definition CNewtonIntegration.hpp:60
void MatrixFreeProduct(const CSysVector< Scalar > &u, CSysVector< Scalar > &v)
Implementation of matrix-vector product with the real Jacobian of the nonlinear residuals.
Definition CNewtonIntegration.cpp:344
Class for defining the numerical methods.
Definition CNumerics.hpp:48
Abstract base class for defining a preconditioning operation.
Definition CPreconditioner.hpp:103
Definition CSolver.hpp:71
CSysSolve< su2mixedfloat > System
Linear solver/smoother.
Definition CSolver.hpp:202
Specialization of matrix-vector product that uses CSysMatrix class.
Definition CMatrixVectorProduct.hpp:70
Class for solving linear systems using classical and Krylov-subspace iterative methods.
Definition CSysSolve.hpp:86
unsigned long Smoother_LinSolver(const VectorType &b, VectorType &x, const ProductType &mat_vec, const PrecondType &precond, ScalarType tol, unsigned long m, ScalarType &residual, bool monitoring, const CConfig *config) const
Generic smoother (modified Richardson iteration with preconditioner)
Definition CSysSolve.cpp:1248
unsigned long BCGSTAB_LinSolver(const VectorType &b, VectorType &x, const ProductType &mat_vec, const PrecondType &precond, ScalarType tol, unsigned long m, ScalarType &residual, bool monitoring, const CConfig *config) const
Biconjugate Gradient Stabilized Method (BCGSTAB)
Definition CSysSolve.cpp:1059
unsigned long FGMRES_LinSolver(const VectorType &b, VectorType &x, const ProductType &mat_vec, const PrecondType &precond, ScalarType tol, unsigned long m, ScalarType &residual, bool monitoring, const CConfig *config) const
Flexible Generalized Minimal Residual method.
Definition CSysSolve.cpp:421
Class for holding and manipulating vectors needed by linear solvers.
Definition CSysVector.hpp:195
unsigned long GetLocSize() const
return the number of local elements in the CSysVector
Definition CSysVector.hpp:420
double passivedouble
Definition code_config.hpp:129
passivedouble su2mixedfloat
Definition code_config.hpp:189
passivedouble su2double
Definition code_config.hpp:181
void ApplyPreconditionerOnDevice(const CSysVector< ScalarType > &u, CSysVector< ScalarType > &v, bool useCuda, Apply &&apply)
Mirror of ApplyPreconditionerOnHost: applies a device preconditioner to host vectors.
Definition CPreconditioner.hpp:75
#define SU2_OMP_BARRIER
Definition omp_structure.hpp:142
@ FLOW_SOL
Position of the mean flow solution in the solver container array.
Definition option_structure.hpp:577
@ BCGSTAB
Use BCGSTAB as the preconditioning linear solver.
@ SMOOTHER
Iterative smoother.
@ NONE
Do not use a nested linear solver.
@ DEFAULT
Kind of transition correlation model (Menter-Langtry if SST, MALAN if SA).