Documentation 6b54b78464
Loading...
Searching...
No Matches
CMultiGridIntegration.hpp
Go to the documentation of this file.
1/*!
2 * \file CMultiGridIntegration.hpp
3 * \brief Declaration of class for time integration using a multigrid method.
4 * \author F. Palacios, T. Economon
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
30/*!
31 * \class CMultiGridIntegration
32 * \ingroup Drivers
33 * \brief Class for time integration using a multigrid method.
34 * \author F. Palacios
35 */
36class CMultiGridIntegration final : public CIntegration {
37public:
38 /*!
39 * \brief Constructor of the class.
40 */
42
43 /*!
44 * \brief This subroutine calls the MultiGrid_Cycle and also prepare the multigrid levels and the monitoring.
45 * \param[in] geometry - Geometrical definition of the problem.
46 * \param[in] solver_container - Container vector with all the solutions.
47 * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved).
48 * \param[in] config - Definition of the particular problem.
49 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
50 * \param[in] Iteration - Current iteration.
51 */
52 void MultiGrid_Iteration(CGeometry ****geometry, CSolver *****solver_container,
53 CNumerics ******numerics_container, CConfig **config,
54 unsigned short RunTime_EqSystem, unsigned short iZone, unsigned short iInst) override;
55
56 /*!
57 * \brief Record CONV_FIELD on the active Full-MG level and decide whether it is done.
58 * \param[in] convFields - Name and log10 value of each monitored residual field.
59 * \param[in] config - Definition of the particular problem.
60 */
61 void MonitorFullMG_Startup(const vector<pair<string, passivedouble> >& convFields,
62 const CConfig *config) override;
63
64 bool GetFullMG_CFLRamp() const override { return mg_ramp_mesh0_active; }
65
66 unsigned long GetLevelStartIter() const override { return mg_ramp_level_start_iter; }
67
68private:
69 /*!
70 * \brief Perform a Full-Approximation Storage (FAS) Multigrid.
71 * \param[in] geometry - Geometrical definition of the problem.
72 * \param[in] solver_container - Container vector with all the solutions.
73 * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved).
74 * \param[in] config - Definition of the particular problem.
75 * \param[in] iMesh - Index of the mesh in multigrid computations.
76 * \param[in] mu - Variable for controlling the kind of multigrid algorithm.
77 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
78 * \param[in] Iteration - Current iteration.
79 */
80 void MultiGrid_Cycle(CGeometry ****geometry, CSolver *****solver_container,
81 CNumerics ******numerics_container, CConfig **config,
82 unsigned short iMesh, unsigned short mu, unsigned short RunTime_EqSystem,
83 unsigned short iZone, unsigned short iInst);
84
85 /*!
86 * \brief Compute the forcing term.
87 * \param[in] sol_fine - Pointer to the solution on the fine grid.
88 * \param[in] sol_coarse - Pointer to the solution on the coarse grid.
89 * \param[in] geo_fine - Geometrical definition of the fine grid.
90 * \param[in] geo_coarse - Geometrical definition of the coarse grid.
91 * \param[in] config - Definition of the particular problem.
92 */
93 void SetForcing_Term(CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine,
94 CGeometry *geo_coarse, CConfig *config, unsigned short iMesh);
95
96 /*!
97 * \brief Add the truncation error to the residual.
98 * \param[in] geometry - Geometrical definition of the problem.
99 * \param[in] flow - Flow solution.
100 */
101 void SetResidual_Term(CGeometry *geometry, CSolver *flow);
102
103 /*!
104 * \brief Set the value of the corrected fine grid solution.
105 * \param[out] sol_fine - Pointer to the solution on the fine grid.
106 * \param[in] geo_fine - Geometrical definition of the fine grid.
107 * \param[in] config - Definition of the particular problem.
108 */
109 void SetProlongated_Correction(CSolver *sol_fine, CGeometry *geo_fine, CConfig *config, unsigned short iMesh);
110
111 /*!
112 * \brief Compute the gradient in coarse grid using the fine grid information.
113 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
114 * \param[in] sol_fine - Pointer to the solution on the fine grid.
115 * \param[out] sol_coarse - Pointer to the solution on the coarse grid.
116 * \param[in] geo_fine - Geometrical definition of the fine grid.
117 * \param[in] geo_coarse - Geometrical definition of the coarse grid.
118 * \param[in] config - Definition of the particular problem.
119 */
120 void SetRestricted_Gradient(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse,
121 CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config);
122
123 /*!
124 * \brief Compute the non-dimensional parameters.
125 * \param[in] geometry - Geometrical definition of the problem.
126 * \param[in] solver_container - Container vector with all the solutions.
127 * \param[in] config - Definition of the particular problem.
128 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
129 * \param[in] Iteration - Current iteration.
130 * \param[in] monitor - value of the non-dimensional parameters for monitoring the convergence.
131 */
132 void NonDimensional_Parameters(CGeometry **geometry, CSolver ***solver_container, CNumerics ****numerics_container,
133 CConfig *config, unsigned short FinestMesh, unsigned short RunTime_EqSystem,
134 su2double *monitor);
135
136 /*!
137 * \brief Compute the fine solution from a coarse solution.
138 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
139 * \param[out] sol_fine - Pointer to the solution on the fine grid.
140 * \param[in] sol_coarse - Pointer to the solution on the coarse grid.
141 * \param[in] geo_fine - Geometrical definition of the fine grid.
142 * \param[in] geo_coarse - Geometrical definition of the coarse grid.
143 * \param[in] config - Definition of the particular problem.
144 */
145 void SetProlongated_Solution(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse,
146 CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config);
147
148
149 /*!
150 * \brief Apply post-smoothing iterations on the fine grid after prolongation.
151 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
152 * \param[in] solver_fine - Pointer to the solver on the fine grid.
153 * \param[in] numerics_fine - Description of the numerical method on the fine grid.
154 * \param[in] geometry_fine - Geometrical definition of the fine grid.
155 * \param[in] solver_container_fine - Container with all solvers on the fine grid.
156 * \param[in] config - Definition of the particular problem.
157 * \param[in] iMesh - Index of the mesh in multigrid computations.
158 * \param[in] iRKLimit - Number of Runge-Kutta steps.
159 */
160 void PostSmoothing(unsigned short RunTime_EqSystem, CSolver* solver_fine, CNumerics** numerics_fine,
161 CGeometry* geometry_fine, CSolver** solver_container_fine, CConfig *config,
162 unsigned short iMesh, unsigned short iRKLimit);
163
164 /*!
165 * \brief Apply pre-smoothing iterations on the fine grid before restriction.
166 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
167 * \param[in] geometry - Geometrical definition of the problem (all levels).
168 * \param[in] solver_container - Container vector with all the solutions.
169 * \param[in] config_container - Definition of the particular problems.
170 * \param[in] solver_fine - Pointer to the solver on the fine grid.
171 * \param[in] numerics_fine - Description of the numerical method on the fine grid.
172 * \param[in] geometry_fine - Geometrical definition of the fine grid.
173 * \param[in] solver_container_fine - Container with all solvers on the fine grid.
174 * \param[in] config - Definition of the particular problem.
175 * \param[in] iMesh - Index of the mesh in multigrid computations.
176 * \param[in] iZone - Index of the zone.
177 * \param[in] iRKLimit - Number of Runge-Kutta steps.
178 */
179 void PreSmoothing(unsigned short RunTime_EqSystem, CGeometry**** geometry, CSolver***** solver_container,
180 CConfig **config_container, CSolver* solver_fine, CNumerics** numerics_fine,
181 CGeometry* geometry_fine, CSolver** solver_container_fine, CConfig *config,
182 unsigned short iMesh, unsigned short iZone, unsigned short iRKLimit);
183
184 /*!
185 * \brief Compute the fine grid correction from the coarse solution.
186 * \param[out] sol_fine - Pointer to the solution on the fine grid.
187 * \param[in] sol_coarse - Pointer to the solution on the coarse grid.
188 * \param[in] geo_fine - Geometrical definition of the fine grid.
189 * \param[in] geo_coarse - Geometrical definition of the coarse grid.
190 * \param[in] config - Definition of the particular problem.
191 */
192 void GetProlongated_Correction(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse,
193 CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config);
194
195 /*!
196 * \brief Do an implicit smoothing of the prolongated correction.
197 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
198 * \param[in] solution - Container vector with all the solutions on the finest grid.
199 * \param[in] geometry - Geometrical definition of the problem.
200 * \param[in] val_nSmooth - Number of smoothing iterations.
201 * \param[in] val_smooth_coeff - Relaxation factor.
202 * \param[in] config - Definition of the particular problem.
203 */
204 void SmoothProlongated_Correction(unsigned short RunTime_EqSystem, CSolver *solver, CGeometry *geometry,
205 unsigned short val_nSmooth, su2double val_smooth_coeff, CConfig *config,
206 unsigned short iMesh);
207
208 /*!
209 * \brief Restrict solution from fine grid to a coarse grid.
210 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
211 * \param[in] sol_fine - Pointer to the solution on the fine grid.
212 * \param[out] sol_coarse - Pointer to the solution on the coarse grid.
213 * \param[in] geo_fine - Geometrical definition of the fine grid.
214 * \param[in] geo_coarse - Geometrical definition of the coarse grid.
215 * \param[in] config - Definition of the particular problem.
216 */
217 void SetRestricted_Solution(unsigned short RunTime_EqSystem, CSolver *sol_fine, CSolver *sol_coarse,
218 CGeometry *geo_fine, CGeometry *geo_coarse, CConfig *config);
219
220 /*!
221 * \brief Initialize the adjoint solution using the primal problem.
222 * \param[in] geometry - Geometrical definition of the problem.
223 * \param[in] solver_container - Container vector with all the solutions.
224 * \param[in] config - Definition of the particular problem.
225 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
226 * \param[in] Iteration - Current iteration.
227 */
228 void Adjoint_Setup(CGeometry ****geometry, CSolver *****solver_container, CConfig **config,
229 unsigned short RunTime_EqSystem, unsigned long Iteration, unsigned short iZone);
230
231 /*!
232 * \brief Adapt both restriction and prolongation damping factors from the global-trend signal.
233 * \param[in,out] config - Problem configuration.
234 * \param[in] crossCycleRatio - Current fine_d0 divided by the EMA of fine_d0.
235 */
236 void adaptDampingFactors(CConfig* config, passivedouble crossCycleRatio);
237
238 /*!
239 * \brief Set the CFL of every coarse multigrid level, ramping level i from the final CFL of
240 * level i+1 to its own target, which CFL_NUMBER and MG_CFL_SCALING determine.
241 *
242 * \param[in] geometry - Geometrical definition of the problem.
243 * \param[in,out] solver_container - Container vector with all the solutions.
244 * \param[in,out] config - Definition of the particular problem.
245 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
246 * \param[in] iZone - Zone index.
247 * \param[in] iInst - Instance index.
248 * \param[in] FinestMesh - Currently active finest mesh level.
249 * \param[in] FullMG - Whether the Full-MG cycle is active.
250 * \param[in] mesh0_ramp_window - Result of FullMG_Mesh0RampWindow, computed by the caller.
251 */
252 void SetCoarseGridCFL(CGeometry ****geometry, CSolver *****solver_container, CConfig **config,
253 unsigned short RunTime_EqSystem, unsigned short iZone, unsigned short iInst,
254 unsigned short FinestMesh, bool FullMG, bool mesh0_ramp_window);
255
256 /*!
257 * \brief Whether the finest grid has a Full-MG CFL ramp at all.
258 * \param[in] config - Definition of the particular problem.
259 * \param[in] FinestMesh - Currently active finest mesh level.
260 * \param[in] FullMG - Whether the Full-MG cycle is active.
261 */
262 bool FullMG_Mesh0HasRamp(const CConfig* config, unsigned short FinestMesh, bool FullMG) const {
263 return FullMG && (FinestMesh == MESH_0) && (config->GetMGOptions().MG_Startup_Iter > 0) &&
264 (mg_ramp_cfl_start > 0.0);
265 }
266
267 /*!
268 * \brief Whether the level-0 CFL is still climbing towards the configured number.
269 */
270 bool FullMG_Mesh0Ramping(const CConfig* config, unsigned short FinestMesh, bool FullMG) const {
271 return FullMG_Mesh0HasRamp(config, FinestMesh, FullMG) &&
272 ((config->GetInnerIter() - mg_ramp_level_start_iter) < config->GetMGOptions().MG_Startup_Iter);
273 }
274
275 /*!
276 * \brief The single iteration after the ramp, which writes the configured CFL back.
277 */
278 bool FullMG_Mesh0RampRestore(const CConfig* config, unsigned short FinestMesh, bool FullMG) const {
279 return FullMG_Mesh0HasRamp(config, FinestMesh, FullMG) &&
280 ((config->GetInnerIter() - mg_ramp_level_start_iter) == config->GetMGOptions().MG_Startup_Iter);
281 }
282
283 /*!
284 * \brief Whether the startup owns the level-0 CFL this iteration.
285 */
286 bool FullMG_Mesh0RampWindow(const CConfig* config, unsigned short FinestMesh, bool FullMG) const {
287 return FullMG_Mesh0Ramping(config, FinestMesh, FullMG) ||
288 FullMG_Mesh0RampRestore(config, FinestMesh, FullMG);
289 }
290
291 /*!
292 * \brief Interpolate a scalar solver's solution onto the newly activated Full-MG level.
293 * \param[in,out] sol_fine - Solver on the level being activated.
294 * \param[in] sol_coarse - Solver on the level handing over.
295 * \param[in] geo_fine - Geometry of the level being activated.
296 * \param[in] geo_coarse - Geometry of the level handing over.
297 * \param[in] config - Definition of the particular problem.
298 * \param[in] eddy_viscosity - Carry the eddy viscosity across as well.
299 */
300 void SetProlongated_ScalarSolution(CSolver *sol_fine, CSolver *sol_coarse, CGeometry *geo_fine,
301 CGeometry *geo_coarse, CConfig *config, bool eddy_viscosity);
302
303 /*!
304 * \brief Helper function for early-exit logic during pre/post-smoothing.
305 * \param[in] iSmooth - Current smoothing iteration index.
306 * \param[in] iMesh - Index of the mesh in multigrid computations.
307 * \param[in] defect - Current RMS defect value.
308 * \param[in] mgOpts - Reference to multigrid options.
309 * \param[in] stag_tol - Stagnation tolerance value.
310 * \param[in] early_exit - Whether early exit is enabled.
311 * \param[out] lastRMS - Array to store RMS values [start, end].
312 * \param[out] exitReason - Character for early exit reason ('T', 'S', 'A', or ' ').
313 * \param[out] worstStepRatio - Worst step-to-step ratio seen.
314 * \param[out] worstStep - Iteration number of worst step.
315 */
316 void prePostEarlyExit(unsigned short iSmooth, unsigned short iMesh,
317 passivedouble defect, const CMGOptions& mgOpts,
318 passivedouble stag_tol, bool early_exit,
319 passivedouble lastRMS[2], char& exitReason,
320 passivedouble& worstStepRatio, unsigned short& worstStep);
321
322 static constexpr int MAX_MG_LEVELS = 10;
323
324 /*--- Bounds the fixed-size stack buffers in the restriction and prolongation kernels,
325 * independently of the CSysMatrix limit of the same name. ---*/
326 static constexpr unsigned short MAXNVAR = 25;
327 static constexpr unsigned short MAXNDIM = 3;
328
329 /*--- Early-exit smoothing state (shared across OMP threads via master write + barrier). ---*/
330 bool mg_early_exit_flag = false; /*!< \brief Shared flag for early exit across OMP threads. */
331 passivedouble mg_initial_smooth_rms = 0.0; /*!< \brief Initial RMS residual before current smoothing phase (FAS). */
332 passivedouble mg_prev_smooth_rms = 0.0; /*!< \brief RMS residual from previous smoothing step; used for stagnation detection. */
333 passivedouble mg_fine_rms_ema = 0.0; /*!< \brief EMA of fine-grid pre-smooth RMS across cycles; cross-cycle trend signal. */
334 passivedouble last_crossCycleRatio = 1.0; /*!< \brief crossCycleRatio from the most recent cycle; stored for display only. */
335
336 /*--- Actual iteration counts per MG level, filled each cycle for the compact output summary. ---*/
337 unsigned short lastPreSmoothIters[MAX_MG_LEVELS+1] = {};
338 unsigned short lastPostSmoothIters[MAX_MG_LEVELS+1] = {};
339 unsigned short lastCorrecSmoothIters[MAX_MG_LEVELS+1] = {};
340 /*--- Early-exit reason per level: 'T'=threshold, 'S'=stagnation, ' '=ran to completion. ---*/
341 char lastPreSmoothExitReason[MAX_MG_LEVELS+1] = {};
342 char lastPostSmoothExitReason[MAX_MG_LEVELS+1] = {};
343
344 /*--- Per-level start/end RMS residual for adaptive damping. ---*/
345 passivedouble lastPreSmoothRMS[MAX_MG_LEVELS+1][2] = {};
346 passivedouble lastPostSmoothRMS[MAX_MG_LEVELS+1][2] = {};
347 passivedouble lastCorrecSmoothRMS[MAX_MG_LEVELS+1][2] = {};
348
349 /*--- Per-level worst step-to-step amplification seen inside a smoothing phase.
350 * step==0 means no intra-smoother ratio was available (fewer than 2 sweeps). ---*/
351 passivedouble lastPreSmoothWorstStepRatio[MAX_MG_LEVELS+1] = {};
352 passivedouble lastPostSmoothWorstStepRatio[MAX_MG_LEVELS+1] = {};
353 unsigned short lastPreSmoothWorstStep[MAX_MG_LEVELS+1] = {};
354 unsigned short lastPostSmoothWorstStep[MAX_MG_LEVELS+1] = {};
355
356 /*! \brief FinestMesh observed on the previous call; 0 also serves as the sentinel forcing a
357 * reset on the first call, since a FULL cycle starts at FinestMesh == nMGLevels > 0. */
358 unsigned short mg_ramp_last_FinestMesh = 0;
359 unsigned long mg_ramp_level_start_iter = 0; /*!< \brief InnerIter the active FMG level became active at. */
360 passivedouble mg_ramp_cfl_start = 0.0; /*!< \brief CFL the level below handed over; 0 before a promotion. */
361 bool mg_ramp_mesh0_active = false; /*!< \brief Whether the level-0 CFL ramp is still climbing. */
362
363 su2double mg_damp_restric_initial = -1.0; /*!< \brief MG_DAMP_RESTRICTION as configured; negative if not captured. */
364 su2double mg_damp_prolong_initial = 0.0; /*!< \brief MG_DAMP_PROLONGATION as configured. */
365
366 /*! \brief Why the active level was last promoted, for the report message. */
367 enum class MGStartupPromote { NONE, BUDGET, CONVERGENCE, STAGNATION };
368 MGStartupPromote mg_startup_promote_reason = MGStartupPromote::NONE;
369
370 vector<passivedouble> mg_startup_conv_start; /*!< \brief Field values when the active level became active. */
371 vector<passivedouble> mg_startup_conv_prev; /*!< \brief Field values on the previous iteration. */
372 unsigned long mg_startup_stall_count = 0; /*!< \brief Consecutive iterations without useful reduction. */
373
374};
Declaration of the main routines to orchestrate space and time integration.
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
unsigned long GetInnerIter(void) const
Get the current FSI iteration number.
Definition CConfig.hpp:3405
const CMGOptions & GetMGOptions() const
Get the multigrid options struct.
Definition CConfig.hpp:3900
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 multigrid method.
Definition CMultiGridIntegration.hpp:36
CMultiGridIntegration()
Constructor of the class.
Definition CMultiGridIntegration.cpp:75
bool GetFullMG_CFLRamp() const override
Whether the Full-MG startup is still ramping the CFL of the finest grid.
Definition CMultiGridIntegration.hpp:64
void MonitorFullMG_Startup(const vector< pair< string, passivedouble > > &convFields, const CConfig *config) override
Record CONV_FIELD on the active Full-MG level and decide whether it is done.
Definition CMultiGridIntegration.cpp:77
unsigned long GetLevelStartIter() const override
InnerIter at which the currently active Full-MG level became active.
Definition CMultiGridIntegration.hpp:66
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 subroutine calls the MultiGrid_Cycle and also prepare the multigrid levels and the monitoring.
Definition CMultiGridIntegration.cpp:243
Class for defining the numerical methods.
Definition CNumerics.hpp:48
Definition CSolver.hpp:71
double passivedouble
Definition code_config.hpp:129
passivedouble su2double
Definition code_config.hpp:181
@ NONE
Definition option_structure.hpp:282
const unsigned int MESH_0
Definition of the finest grid level.
Definition option_structure.hpp:88
Structure containing multigrid options.
Definition option_structure.hpp:1225
unsigned long MG_Startup_Iter
Iterations per mesh during FMG startup, and the length of each level's CFL ramp. 0 = no iteration bud...
Definition option_structure.hpp:1237