https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LinearAssemblySegregatedSolve.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "FEProblem.h"
13#include "LinearSystem.h"
14#include "Executioner.h"
15
18{
20
21 params.addParam<std::vector<SolverSystemName>>(
22 "active_scalar_systems", {}, "The solver system for each active scalar advection equation.");
23
24 /*
25 * Parameters to control the solution of each scalar advection system
26 */
27 params.addParam<std::vector<Real>>("active_scalar_equation_relaxation",
28 std::vector<Real>(),
29 "The relaxation which should be used for the active scalar "
30 "equations. (=1 for no relaxation, "
31 "diagonal dominance will still be enforced)");
32
33 params.addParam<MultiMooseEnum>("active_scalar_petsc_options",
35 "Singleton PETSc options for the active scalar equation(s)");
37 "active_scalar_petsc_options_iname",
39 "Names of PETSc name/value pairs for the active scalar equation(s)");
40 params.addParam<std::vector<std::string>>(
41 "active_scalar_petsc_options_value",
42 "Values of PETSc name/value pairs (must correspond with \"petsc_options_iname\" for the "
43 "active scalar equation(s)");
44 params.addParam<std::vector<Real>>(
45 "active_scalar_absolute_tolerance",
46 std::vector<Real>(),
47 "The absolute tolerance(s) on the normalized residual(s) of the active scalar equation(s).");
48 params.addRangeCheckedParam<Real>("active_scalar_l_tol",
49 1e-5,
50 "0.0<=active_scalar_l_tol & active_scalar_l_tol<1.0",
51 "The relative tolerance on the normalized residual in the "
52 "linear solver of the active scalar equation(s).");
53 params.addRangeCheckedParam<Real>("active_scalar_l_abs_tol",
54 1e-10,
55 "0.0<active_scalar_l_abs_tol",
56 "The absolute tolerance on the normalized residual in the "
57 "linear solver of the active scalar equation(s).");
58 params.addParam<unsigned int>(
59 "active_scalar_l_max_its",
60 10000,
61 "The maximum allowed iterations in the linear solver of the turbulence equation.");
62
64 "active_scalar_systems active_scalar_equation_relaxation active_scalar_petsc_options "
65 "active_scalar_petsc_options_iname "
66 "active_scalar_petsc_options_value "
67 "active_scalar_absolute_tolerance "
68 "active_scalar_l_tol active_scalar_l_abs_tol active_scalar_l_max_its",
69 "Active Scalars Equations");
70
71 /*
72 * Flags to optionally skip solving subsets of the thermal-hydraulics system (useful when
73 * recovering a converged solution and only advancing scalar transport for example).
74 */
75 params.addParam<bool>(
76 "should_solve_momentum", true, "Whether we should solve the momentum predictor/corrector.");
77 params.addParam<bool>(
78 "should_solve_pressure", true, "Whether we should solve the pressure corrector.");
79 params.addParam<bool>(
80 "should_solve_energy", true, "Whether we should solve the fluid energy equation.");
81 params.addParam<bool>(
82 "should_solve_solid_energy", true, "Whether we should solve the solid energy equation.");
83 params.addParam<bool>("should_solve_turbulence",
84 true,
85 "Whether we should solve the turbulence surrogate equations.");
86 params.addParam<bool>(
87 "should_solve_passive_scalars", true, "Whether we should solve passive scalar equations.");
88 params.addParam<bool>(
89 "should_solve_active_scalars", true, "Whether we should solve active scalar equations.");
90 params.addParam<bool>("should_solve_pm_radiation",
91 true,
92 "Whether we should solve participating media radiation equations.");
93 params.addParamNamesToGroup("should_solve_momentum should_solve_pressure should_solve_energy "
94 "should_solve_solid_energy should_solve_turbulence "
95 "should_solve_passive_scalars should_solve_active_scalars",
96 "Solve control");
97
98 /*
99 * Parameter to amortize the (often dominant) pressure preconditioner setup cost. The pressure
100 * operator changes slowly between SIMPLE iterations, so its preconditioner can be reused for
101 * several iterations rather than rebuilt every solve.
102 */
103 const std::string recompute_frequency_explanation =
104 "The default of 1 rebuilds it on every solve. A value of N rebuilds it once every N solves "
105 "and "
106 "reuses it in between, which can substantially reduce the solve cost when the "
107 "preconditioner setup dominates (e.g. algebraic multigrid). Larger values trade more reuse "
108 "for a possibly staler preconditioner (more Krylov iterations); for solves where the "
109 "operator changes significantly between linear solves, prefer a smaller value.";
110 params.addRangeCheckedParam<unsigned int>(
111 "pressure_pc_recompute_frequency",
112 1,
113 "pressure_pc_recompute_frequency >= 1",
114 "How often (in pressure corrector solves) to recompute the pressure preconditioner. " +
115 recompute_frequency_explanation);
116 params.addParamNamesToGroup("pressure_pc_recompute_frequency", "Pressure Equation");
117 // Other preconditioner reuse
118 params.addRangeCheckedParam<unsigned int>(
119 "momentum_pc_recompute_frequency",
120 1,
121 "momentum_pc_recompute_frequency >= 1",
122 "How often (in SIMPLE iteration solves) to recompute the momentum preconditioner. " +
123 recompute_frequency_explanation);
124 params.addParamNamesToGroup("momentum_pc_recompute_frequency", "Momentum Equations");
125 params.addRangeCheckedParam<unsigned int>(
126 "energy_pc_recompute_frequency",
127 1,
128 "energy_pc_recompute_frequency >= 1",
129 "How often (in terms of CHT and SIMPLE iterations) to recompute the preconditioner. " +
130 recompute_frequency_explanation);
131 params.addParamNamesToGroup("energy_pc_recompute_frequency", "Energy Equation");
132 params.addRangeCheckedParam<unsigned int>("solid_energy_pc_recompute_frequency",
133 1,
134 "solid_energy_pc_recompute_frequency >= 1",
135 "How often (in terms of CHT solves nested within "
136 "SIMPLE solves) to recompute the preconditioner. " +
137 recompute_frequency_explanation);
138 params.addParamNamesToGroup("solid_energy_pc_recompute_frequency", "Solid Energy Equation");
139 params.addRangeCheckedParam<unsigned int>(
140 "passive_scalar_pc_recompute_frequency",
141 1,
142 "passive_scalar_pc_recompute_frequency >= 1",
143 "How often (in advection solves) to recompute the preconditioner. " +
144 recompute_frequency_explanation);
145 params.addParamNamesToGroup("passive_scalar_pc_recompute_frequency",
146 "Passive Scalars Advection Equation");
147 params.addRangeCheckedParam<unsigned int>(
148 "turbulence_pc_recompute_frequency",
149 1,
150 "turbulence_pc_recompute_frequency >= 1",
151 "How often (in advection solves) to recompute the preconditioner. " +
152 recompute_frequency_explanation);
153 params.addParamNamesToGroup("turbulence_pc_recompute_frequency", "Turbulence Equation");
154 params.addRangeCheckedParam<unsigned int>(
155 "active_scalar_pc_recompute_frequency",
156 1,
157 "active_scalar_pc_recompute_frequency >= 1",
158 "How often (in advection solves) to recompute the preconditioner. " +
159 recompute_frequency_explanation);
160 params.addParamNamesToGroup("active_scalar_pc_recompute_frequency", "Active Scalars Equation");
161
162 /*
163 * Parameters to control the conjugate heat transfer
164 */
166
167 return params;
168}
169
171 : SIMPLESolveBase(ex),
172 _momentum_pc_recompute_frequency(getParam<unsigned int>("momentum_pc_recompute_frequency")),
173 _momentum_pc_solve_counter(0),
174 _pressure_sys_number(_problem.linearSysNum(getParam<SolverSystemName>("pressure_system"))),
175 _pressure_system(_problem.getLinearSystem(_pressure_sys_number)),
176 _pressure_pc_recompute_frequency(getParam<unsigned int>("pressure_pc_recompute_frequency")),
177 _pressure_pc_solve_counter(0),
178 _energy_sys_number(_has_energy_system
179 ? _problem.linearSysNum(getParam<SolverSystemName>("energy_system"))
180 : libMesh::invalid_uint),
181 _energy_system(_has_energy_system ? &_problem.getLinearSystem(_energy_sys_number) : nullptr),
182 _energy_pc_recompute_frequency(getParam<unsigned int>("energy_pc_recompute_frequency")),
183 _energy_pc_solve_counter(0),
184 _solid_energy_sys_number(
185 _has_solid_energy_system
186 ? _problem.linearSysNum(getParam<SolverSystemName>("solid_energy_system"))
187 : libMesh::invalid_uint),
188 _solid_energy_system(
189 _has_solid_energy_system ? &_problem.getLinearSystem(_solid_energy_sys_number) : nullptr),
190 _solid_energy_pc_recompute_frequency(
191 getParam<unsigned int>("solid_energy_pc_recompute_frequency")),
192 _solid_energy_pc_solve_counter(0),
193 _passive_scalar_pc_recompute_frequency(
194 getParam<unsigned int>("passive_scalar_pc_recompute_frequency")),
195 _passive_scalar_pc_solve_counter(0),
196 _turbulence_pc_recompute_frequency(getParam<unsigned int>("turbulence_pc_recompute_frequency")),
197 _turbulence_pc_solve_counter(0),
198 _should_solve_momentum(getParam<bool>("should_solve_momentum")),
199 _should_solve_pressure(getParam<bool>("should_solve_pressure")),
200 _should_solve_energy(getParam<bool>("should_solve_energy")),
201 _should_solve_solid_energy(getParam<bool>("should_solve_solid_energy")),
202 _should_solve_turbulence(getParam<bool>("should_solve_turbulence")),
203 _should_solve_passive_scalars(getParam<bool>("should_solve_passive_scalars")),
204 _should_solve_active_scalars(getParam<bool>("should_solve_active_scalars")),
205 _should_solve_pm_radiation(getParam<bool>("should_solve_pm_radiation")),
206 _active_scalar_system_names(getParam<std::vector<SolverSystemName>>("active_scalar_systems")),
207 _has_active_scalar_systems(!_active_scalar_system_names.empty()),
208 _active_scalar_equation_relaxation(
209 getParam<std::vector<Real>>("active_scalar_equation_relaxation")),
210 _active_scalar_l_abs_tol(getParam<Real>("active_scalar_l_abs_tol")),
211 _active_scalar_absolute_tolerance(
212 getParam<std::vector<Real>>("active_scalar_absolute_tolerance")),
213 _active_scalar_pc_recompute_frequency(
214 getParam<unsigned int>("active_scalar_pc_recompute_frequency")),
215 _active_scalar_pc_solve_counter(0),
216 _cht(ex.parameters())
217{
219 paramError("should_solve_momentum",
220 "Pressure correction requires solving the momentum equations.");
222 paramError("should_solve_pressure",
223 "Solving momentum without a pressure corrector is not supported.");
225 paramError("should_solve_solid_energy",
226 "Solid energy solve cannot be enabled when the fluid energy solve is disabled.");
227
228 // We fetch the systems and their numbers for the momentum equations only if we solve them
230 for (auto system_i : index_range(_momentum_system_names))
231 {
234 _systems_to_solve.push_back(_momentum_systems.back());
235 }
236
239
242
245
246 // and for the turbulence surrogate equations
248 for (auto system_i : index_range(_turbulence_system_names))
249 {
252 _turbulence_systems.push_back(
254 }
255
256 // and for the passive scalar equations
258 for (auto system_i : index_range(_passive_scalar_system_names))
259 {
262 _passive_scalar_systems.push_back(
266 }
267
268 // and for the participating media radiation equations
270 for (auto system_i : index_range(_pm_radiation_system_names))
271 {
274 _pm_radiation_systems.push_back(
277 }
278
279 // and for the active scalar equations
281 for (auto system_i : index_range(_active_scalar_system_names))
282 {
285 _active_scalar_systems.push_back(
288
289 const auto & active_scalar_petsc_options =
290 getParam<MultiMooseEnum>("active_scalar_petsc_options");
291 const auto & active_scalar_petsc_pair_options = getParam<MooseEnumItem, std::string>(
292 "active_scalar_petsc_options_iname", "active_scalar_petsc_options_value");
294 active_scalar_petsc_options, "", *this, _active_scalar_petsc_options);
295 Moose::PetscSupport::addPetscPairsToPetscOptions(active_scalar_petsc_pair_options,
297 "",
298 *this,
300
302 getParam<Real>("active_scalar_l_tol");
304 getParam<Real>("active_scalar_l_abs_tol");
306 getParam<unsigned int>("active_scalar_l_max_its");
307 }
308
310 paramError("active_scalar_equation_relaxation",
311 "Should be the same size as the number of systems");
312
313 // We disable the prefix here for the time being, the segregated solvers use a different approach
314 // for setting the petsc parameters
315 for (auto & system : _systems_to_solve)
316 system->system().prefix_with_name(false);
317
318 // Link CHT objects, this will also do some error checking
319 // Make a copy for compatibility. These could change in the future
320 // Convert _pm_radiation_systems to std::vector<SystemBase *>
321 if (_cht.enabled())
322 {
324 paramError("should_solve_energy",
325 "Conjugate heat transfer requires solving the fluid energy equation.");
327 paramError("should_solve_solid_energy",
328 "Conjugate heat transfer requires solving the solid energy equation.");
329
330 std::vector<SystemBase *> pm_radiation_systems_base(_pm_radiation_systems.begin(),
332
333 _cht.linkEnergySystems(_solid_energy_system, _energy_system, pm_radiation_systems_base);
334 }
335}
336
337void
339{
341 return;
342
343 _rc_uo =
344 const_cast<RhieChowMassFlux *>(&getUserObject<RhieChowMassFlux>("rhie_chow_user_object"));
347
348 // Initialize the face velocities in the RC object
349 if (!_app.isRecovering())
352}
353
354std::vector<std::pair<unsigned int, Real>>
356{
357 // Temporary storage for the (flux-normalized) residuals from
358 // different momentum components
359 std::vector<std::pair<unsigned int, Real>> its_normalized_residuals;
360
361 LinearImplicitSystem & momentum_system_0 =
362 cast_ref<LinearImplicitSystem &>(_momentum_systems[0]->system());
363
364 libMesh::PetscLinearSolver<Real> & momentum_solver =
365 cast_ref<libMesh::PetscLinearSolver<Real> &>(*momentum_system_0.get_linear_solver());
366
367 // Solve the momentum equations.
368 // TO DO: These equations are VERY similar. If we can store the differences (things coming from
369 // BCs for example) separately, it is enough to construct one matrix.
370 for (const auto system_i : index_range(_momentum_systems))
371 {
373
374 // We will need the right hand side and the solution of the next component
375 LinearImplicitSystem & momentum_system =
376 cast_ref<LinearImplicitSystem &>(_momentum_systems[system_i]->system());
377
378 NumericVector<Number> & solution = *(momentum_system.solution);
379 NumericVector<Number> & rhs = *(momentum_system.rhs);
380 SparseMatrix<Number> & mmat = *(momentum_system.matrix);
381
382 auto diff_diagonal = solution.zero_clone();
383
384 // We assemble the matrix and the right hand side
385 _problem.computeLinearSystemSys(momentum_system, mmat, rhs, /*compute_grads*/ true);
386
387 // Still need to relax the right hand side with the same vector
389 NS::FV::relaxRightHandSide(rhs, solution, *diff_diagonal);
390
391 // The normalization factor depends on the right hand side so we need to recompute it for this
392 // component
393 Real norm_factor = NS::FV::computeNormalizationFactor(solution, mmat, rhs);
394
395 // Very important, for deciding the convergence, we need the unpreconditioned
396 // norms in the linear solve
397 LibmeshPetscCall(KSPSetNormType(momentum_solver.ksp(), KSP_NORM_UNPRECONDITIONED));
398 // Solve this component. We don't update the ghosted solution yet, that will come at the end
399 // of the corrector step. Also setting the linear tolerances and maximum iteration counts.
402
403 // We solve the equation
404 auto its_resid_pair = momentum_solver.solve(mmat, mmat, solution, rhs);
405 momentum_system.update();
406
407 // We will reuse the preconditioner for every momentum system
408 if (system_i == 0)
409 momentum_solver.reuse_preconditioner(true);
410
411 // Save the normalized residual
412 its_normalized_residuals.push_back(
413 std::make_pair(its_resid_pair.first, momentum_solver.get_initial_residual() / norm_factor));
414
415 if (_print_fields)
416 {
417 _console << " matrix when we solve " << std::endl;
418 mmat.print();
419 _console << " rhs when we solve " << std::endl;
420 rhs.print();
421 _console << " velocity solution component " << system_i << std::endl;
422 solution.print();
423 _console << "Norm factor " << norm_factor << std::endl;
424 _console << Moose::stringify(momentum_solver.get_initial_residual()) << std::endl;
425 }
426
427 // Printing residuals
428 _console << " Momentum equation:"
429 << (_momentum_systems.size() > 1
430 ? std::string(" Component ") + std::to_string(system_i + 1) + std::string(" ")
431 : std::string(" "))
432 << COLOR_GREEN << its_normalized_residuals[system_i].second << COLOR_DEFAULT
433 << " Linear its: " << its_normalized_residuals[system_i].first << std::endl;
434 }
435
436 // Each component's assembly computed its gradient before that component was solved. Solving the
437 // momentum systems does not refresh those fields, so they still contain the pre-solve velocity
438 // gradients required by the reconstructed pressure-gradient update.
441
442 for (const auto system_i : index_range(_momentum_systems))
443 {
444 LinearImplicitSystem & momentum_system =
445 cast_ref<LinearImplicitSystem &>(_momentum_systems[system_i]->system());
446 _momentum_systems[system_i]->setSolution(*(momentum_system.current_local_solution));
447 _momentum_systems[system_i]->copyPreviousSolutions(Moose::SolutionIterationType::Nonlinear);
448 }
449
450 // We reset this to ensure the preconditioner is computed again when we go to the momentum
451 // predictor, if the number of reuses has been met
452 momentum_solver.reuse_preconditioner(
455
456 return its_normalized_residuals;
457}
458
459void
468
469std::pair<unsigned int, Real>
471{
473
474 // We will need some members from the linear system
475 LinearImplicitSystem & pressure_system =
476 cast_ref<LinearImplicitSystem &>(_pressure_system.system());
477
478 // We will need the solution, the right hand side and the matrix
479 NumericVector<Number> & current_local_solution = *(pressure_system.current_local_solution);
480 NumericVector<Number> & solution = *(pressure_system.solution);
481 SparseMatrix<Number> & mmat = *(pressure_system.matrix);
482 NumericVector<Number> & rhs = *(pressure_system.rhs);
483
484 // Fetch the linear solver from the system
485 libMesh::PetscLinearSolver<Real> & pressure_solver =
486 cast_ref<libMesh::PetscLinearSolver<Real> &>(*pressure_system.get_linear_solver());
487
488 _problem.computeLinearSystemSys(pressure_system, mmat, rhs, false);
489
490 if (_print_fields)
491 {
492 _console << "Pressure matrix" << std::endl;
493 mmat.print();
494 }
495
496 // We compute the normalization factors based on the fluxes
497 Real norm_factor = NS::FV::computeNormalizationFactor(solution, mmat, rhs);
498
499 // We need the non-preconditioned norm to be consistent with the norm factor
500 LibmeshPetscCall(KSPSetNormType(pressure_solver.ksp(), KSP_NORM_UNPRECONDITIONED));
501
502 // Setting the linear tolerances and maximum iteration counts
505
506 if (_pin_pressure)
508 pressure_system.update();
509
510 // Optionally reuse the pressure preconditioner across SIMPLE iterations to amortize its setup
511 // cost. We rebuild it on the first solve and then once every _pressure_pc_recompute_frequency
512 // solves, reusing it in between. With the default frequency of 1 this rebuilds on every solve.
513 pressure_solver.reuse_preconditioner(
515
516 auto its_res_pair = pressure_solver.solve(mmat, mmat, solution, rhs);
517 pressure_system.update();
518
519 if (_print_fields)
520 {
521 _console << " rhs when we solve pressure " << std::endl;
522 rhs.print();
523 _console << " Pressure " << std::endl;
524 solution.print();
525 _console << "Norm factor " << norm_factor << std::endl;
526 }
527
528 _pressure_system.setSolution(current_local_solution);
529
530 const auto residuals =
531 std::make_pair(its_res_pair.first, pressure_solver.get_initial_residual() / norm_factor);
532
533 _console << " Pressure equation: " << COLOR_GREEN << residuals.second << COLOR_DEFAULT
534 << " Linear its: " << residuals.first << std::endl;
535
536 return residuals;
537}
538
539std::pair<unsigned int, Real>
541{
543
544 // We will need some members from the linear system
545 LinearImplicitSystem & system = cast_ref<LinearImplicitSystem &>(_solid_energy_system->system());
546
547 // We will need the solution, the right hand side and the matrix
548 NumericVector<Number> & current_local_solution = *(system.current_local_solution);
549 NumericVector<Number> & solution = *(system.solution);
550 SparseMatrix<Number> & mmat = *(system.matrix);
551 NumericVector<Number> & rhs = *(system.rhs);
552
553 // Fetch the linear solver from the system
555 cast_ref<libMesh::PetscLinearSolver<Real> &>(*system.get_linear_solver());
556
557 _problem.computeLinearSystemSys(system, mmat, rhs, false);
558
559 if (_print_fields)
560 {
561 _console << "Solid energy matrix" << std::endl;
562 mmat.print();
563 }
564
565 // We compute the normalization factors based on the fluxes
566 Real norm_factor = NS::FV::computeNormalizationFactor(solution, mmat, rhs);
567
568 // We need the non-preconditioned norm to be consistent with the norm factor
569 LibmeshPetscCall(KSPSetNormType(solver.ksp(), KSP_NORM_UNPRECONDITIONED));
570
571 // Setting the linear tolerances and maximum iteration counts
574
575 // Handle preconditioner reuse logic
579
580 auto its_res_pair = solver.solve(mmat, mmat, solution, rhs);
581 system.update();
582
583 if (_print_fields)
584 {
585 _console << " rhs when we solve solid energy " << std::endl;
586 rhs.print();
587 _console << " Solid energy " << std::endl;
588 solution.print();
589 _console << "Norm factor " << norm_factor << std::endl;
590 }
591
592 _solid_energy_system->setSolution(current_local_solution);
593
594 _solid_energy_system->copyPreviousSolutions(Moose::SolutionIterationType::Nonlinear);
595
596 const auto residuals =
597 std::make_pair(its_res_pair.first, solver.get_initial_residual() / norm_factor);
598
599 _console << " Solid energy equation: " << COLOR_GREEN << residuals.second << COLOR_DEFAULT
600 << " Linear its: " << residuals.first << std::endl;
601
602 return residuals;
603}
604
605std::pair<unsigned int, Real>
606LinearAssemblySegregatedSolve::correctVelocity(const bool recompute_face_mass_flux,
607 const SolverParams & solver_params)
608{
609 // Compute the coupling fields between the momentum and pressure equations using the pressure
610 // gradient captured before the current momentum predictor was assembled.
612
613 // We set the preconditioner/controllable parameters for the pressure equations through
614 // petsc options. Linear tolerances will be overridden within the solver.
616
617 // Solve the pressure corrector
618 const auto residuals = solvePressureCorrector();
619
620 // Compute the face velocity which is used in the advection terms. In certain
621 // segregated solver algorithms (like PISO) this is only done on the last iteration.
622 if (recompute_face_mass_flux)
624
625 // Reconstructed gradients use the unrelaxed pressure and its conservative face flux to form
626 // the candidate pressure gradient that corrects cell velocity exactly. Relaxed feedback is
627 // published below after the relaxed pressure solution has been computed. Here,
628 // mdot = [(rhoHbyA)_f - (rho/A)_f grad(p)_face] dot normal * S. Only the unrelaxed pressure
629 // makes div(mdot) = 0; using a relaxed pressure would leave a continuity residual.
631
632 auto & pressure_current_solution = *(_pressure_system.system().current_local_solution.get());
633 auto & pressure_old_solution = *(_pressure_system.solutionPreviousNewton());
634
635 // Relax the pressure update for the next momentum predictor
637 pressure_current_solution, pressure_old_solution, _pressure_variable_relaxation);
638
639 // Overwrite old solution
640 pressure_old_solution = pressure_current_solution;
641 _pressure_system.setSolution(pressure_current_solution);
642
643 // Refresh other registered pressure gradients from the relaxed pressure, then publish relaxed
644 // reconstructed coupling feedback for the next momentum predictor. Without reconstruction,
645 // preserve the existing update of cell velocity from the relaxed pressure gradient.
647
648 return residuals;
649}
650
651std::pair<unsigned int, Real>
653 LinearSystem & system,
654 const Real relaxation_factor,
655 libMesh::SolverConfiguration & solver_config,
656 const Real absolute_tol,
657 const bool reuse_pc,
658 const Real field_relaxation,
659 const Real min_value_limiter)
660{
662
663 // We will need some members from the implicit linear system
664 LinearImplicitSystem & li_system = cast_ref<LinearImplicitSystem &>(system.system());
665
666 // We will need the solution, the right hand side and the matrix
667 NumericVector<Number> & current_local_solution = *(li_system.current_local_solution);
668 NumericVector<Number> & solution = *(li_system.solution);
669 SparseMatrix<Number> & mmat = *(li_system.matrix);
670 NumericVector<Number> & rhs = *(li_system.rhs);
671
672 // We need a vector that stores the (diagonal_relaxed-original_diagonal) vector
673 auto diff_diagonal = solution.zero_clone();
674
675 // Fetch the linear solver from the system
676 libMesh::PetscLinearSolver<Real> & linear_solver =
677 cast_ref<libMesh::PetscLinearSolver<Real> &>(*li_system.get_linear_solver());
678
679 _problem.computeLinearSystemSys(li_system, mmat, rhs, true);
680
681 // Go and relax the system matrix and the right hand side
682 NS::FV::relaxMatrix(mmat, relaxation_factor, *diff_diagonal);
683 NS::FV::relaxRightHandSide(rhs, solution, *diff_diagonal);
684
685 if (_print_fields)
686 {
687 _console << system.name() << " system matrix" << std::endl;
688 mmat.print();
689 }
690
691 // We compute the normalization factors based on the fluxes
692 Real norm_factor = NS::FV::computeNormalizationFactor(solution, mmat, rhs);
693
694 // We need the non-preconditioned norm to be consistent with the norm factor
695 LibmeshPetscCall(KSPSetNormType(linear_solver.ksp(), KSP_NORM_UNPRECONDITIONED));
696
697 // Setting the linear tolerances and maximum iteration counts
698 solver_config.real_valued_data["abs_tol"] = absolute_tol * norm_factor;
699 linear_solver.set_solver_configuration(solver_config);
700
701 // Preconditioner reuse to reduce computational cost
702 linear_solver.reuse_preconditioner(reuse_pc);
703
704 // Solve the system and update current local solution
705 auto its_res_pair = linear_solver.solve(mmat, mmat, solution, rhs);
706 li_system.update();
707
708 if (_print_fields)
709 {
710 _console << " rhs when we solve " << system.name() << std::endl;
711 rhs.print();
712 _console << system.name() << " solution " << std::endl;
713 solution.print();
714 _console << " Norm factor " << norm_factor << std::endl;
715 }
716
717 // Limiting scalar solution
718 if (min_value_limiter != std::numeric_limits<Real>::min())
719 NS::FV::limitSolutionUpdate(current_local_solution, min_value_limiter);
720
721 // Relax the field update for the next momentum predictor
722 if (field_relaxation != 1.0)
723 {
724 auto & old_local_solution = *(system.solutionPreviousNewton());
725 NS::FV::relaxSolutionUpdate(current_local_solution, old_local_solution, field_relaxation);
726 }
727
728 system.setSolution(current_local_solution);
729
730 // Store the accepted, possibly field-relaxed solution.
731 // This must also occur when field_relaxation == 1.
732 system.copyPreviousSolutions(Moose::SolutionIterationType::Nonlinear);
733
734 const auto residuals =
735 std::make_pair(its_res_pair.first, linear_solver.get_initial_residual() / norm_factor);
736
737 _console << " Advected system: " << system.name() << " " << COLOR_GREEN << residuals.second
738 << COLOR_DEFAULT << " Linear its: " << residuals.first << std::endl;
739
740 return residuals;
741}
742
743bool
745{
746 // Do not solve if problem is set not to
747 if (!_problem.shouldSolve())
748 return true;
749
751
752 // Dummy solver parameter file which is needed for switching petsc options
753 SolverParams solver_params;
754 solver_params._type = Moose::SolveType::ST_LINEAR;
755 solver_params._line_search = Moose::LineSearchType::LS_NONE;
756
757 // Initialize the SIMPLE iteration counter
758 unsigned int simple_iteration_counter = 0;
759
760 // Reset all the PC solve counters for preconditioner re-use
768
769 // We set up the residual storage and the corresponding tolerances.
770 ResidualStorage residual_storage = setupResidualStorage();
771 auto & ns_residuals = residual_storage.ns_residuals;
772 auto & ns_abs_tols = residual_storage.ns_abs_tols;
773 const auto & momentum_indices = residual_storage.momentum_indices;
774 const auto pressure_index = residual_storage.pressure_index;
775 const auto energy_index = residual_storage.energy_index;
776 const auto solid_energy_index = residual_storage.solid_energy_index;
777 const auto & active_scalar_indices = residual_storage.active_scalar_indices;
778 const auto & turbulence_indices = residual_storage.turbulence_indices;
779 const auto & pm_radiation_indices = residual_storage.pm_radiation_indices;
780
781 bool converged = residual_storage.converged;
782
783 // Loop until converged or hit the maximum allowed iteration number
786
787 while (simple_iteration_counter < _num_iterations && !converged)
788 {
789 simple_iteration_counter++;
790
791 // We set the preconditioner/controllable parameters through petsc options. Linear
792 // tolerances will be overridden within the solver. In case of a segregated momentum
793 // solver, we assume that every velocity component uses the same preconditioner
796
797 // Initialize base and coupling pressure gradients. After this we reuse the last gradients
798 // until the pressure corrector finalizes a new coupling field.
799 if (_should_solve_pressure && simple_iteration_counter == 1)
801
802 // Capture the lagged velocity and coupling pressure gradients before momentum assembly.
805
806 _console << "Iteration " << simple_iteration_counter << " Initial residual norms:" << std::endl;
807
808 // Solve the momentum predictor step
810 {
811 auto momentum_residual = solveMomentumPredictor();
812 for (const auto system_i : index_range(momentum_residual))
813 ns_residuals[momentum_indices[system_i]] = momentum_residual[system_i];
814 }
815
816 // Now we correct the velocity, this function depends on the method, it differs for
817 // SIMPLE/PIMPLE, this returns the pressure errors
819 ns_residuals[pressure_index] = correctVelocity(true, solver_params);
820
821 // If we have an energy equation, solve it here.We assume the material properties in the
822 // Navier-Stokes equations depend on temperature, therefore we can not solve for temperature
823 // outside of the velocity-pressure loop
825 {
826 // If there is no CHT specified this will just do go once through this block
828 while (!_cht.converged())
829 {
830 if (_cht.enabled())
832
833 // We set the preconditioner/controllable parameters through petsc options. Linear
834 // tolerances will be overridden within the solver.
836 ns_residuals[energy_index] =
844
846 {
847 // We set the preconditioner/controllable parameters through petsc options. Linear
848 // tolerances will be overridden within the solver.
850 for (const auto i : index_range(_pm_radiation_system_names))
851 {
852 ns_residuals[pm_radiation_indices[i]] =
858 /*reuse_pc*/ false);
859 }
860 }
861
863 {
864 // For now we only update gradients if cht is needed, might change in the future
865 if (_cht.enabled())
866 {
869 }
870
871 // We set the preconditioner/controllable parameters through petsc options. Linear
872 // tolerances will be overridden within the solver.
874 ns_residuals[solid_energy_index] = solveSolidEnergy();
875
876 // For now we only update gradients if cht is needed, might change in the future
877 if (_cht.enabled())
879 }
880
881 if (_cht.enabled())
882 {
885 }
886
888 }
889 if (_cht.enabled())
891 }
892
893 // If we have active scalar equations, solve them here in case they depend on temperature
894 // or they affect the fluid properties such that they must be solved concurrently with
895 // pressure and velocity
897 {
899
900 // We set the preconditioner/controllable parameters through petsc options. Linear
901 // tolerances will be overridden within the solver.
903 for (const auto i : index_range(_active_scalar_system_names))
904 ns_residuals[active_scalar_indices[i]] = solveAdvectedSystem(
912 }
913
914 // If we have turbulence equations, solve them here.
915 // The turbulent viscosity depends on the value of the turbulence surrogate variables
917 {
918 // We set the preconditioner/controllable parameters through petsc options. Linear
919 // tolerances will be overridden within the solver.
921 for (const auto i : index_range(_turbulence_system_names))
922 {
923 ns_residuals[turbulence_indices[i]] = solveAdvectedSystem(
932 }
934 }
935
937
938 converged = NS::FV::converged(ns_residuals, ns_abs_tols);
939 }
940
941 // If we have passive scalar equations, solve them here. We assume the material properties in
942 // the Navier-Stokes equations do not depend on passive scalars, as they are passive, therefore
943 // we solve outside of the velocity-pressure loop
945 (converged || _continue_on_max_its))
946 {
947 // The reason why we need more than one iteration is due to the matrix relaxation
948 // which can be used to stabilize the equations
949 bool passive_scalar_converged = false;
950 unsigned int ps_iteration_counter = 0;
951
952 _console << "Passive scalar iteration " << ps_iteration_counter
953 << " Initial residual norms:" << std::endl;
954
955 while (ps_iteration_counter < _num_iterations && !passive_scalar_converged)
956 {
957 ps_iteration_counter++;
958 std::vector<std::pair<unsigned int, Real>> scalar_residuals(
959 _passive_scalar_system_names.size(), std::make_pair(0, 1.0));
960 std::vector<Real> scalar_abs_tols;
961 for (const auto scalar_tol : _passive_scalar_absolute_tolerance)
962 scalar_abs_tols.push_back(scalar_tol);
963
964 // We set the preconditioner/controllable parameters through petsc options. Linear
965 // tolerances will be overridden within the solver.
967 for (const auto i : index_range(_passive_scalar_system_names))
968 scalar_residuals[i] = solveAdvectedSystem(
976
977 passive_scalar_converged = NS::FV::converged(scalar_residuals, scalar_abs_tols);
978 }
979
980 // Both flow and scalars must converge
981 converged = passive_scalar_converged && converged;
982 }
983
984 converged = _continue_on_max_its ? true : converged;
985
986 return converged;
987}
988
991{
992 ResidualStorage storage;
993
994 // Residual store: position in this vector defines the ordering used by NS::FV::converged()
995 // Each entry holds (linear its, normalized residual) for one system
997 for (const auto system_i : index_range(_momentum_systems))
998 {
999 storage.momentum_indices.push_back(storage.ns_residuals.size());
1000 storage.ns_residuals.push_back(std::make_pair(0, 1.0));
1001
1002 const auto abs_tol = _momentum_absolute_tolerance.size() == 1
1004 : _momentum_absolute_tolerance[system_i];
1005 storage.ns_abs_tols.push_back(abs_tol);
1006 }
1007
1009 {
1010 storage.pressure_index = storage.ns_residuals.size();
1011 storage.ns_residuals.push_back(std::make_pair(0, 1.0));
1012 storage.ns_abs_tols.push_back(_pressure_absolute_tolerance);
1013 }
1014
1016 {
1017 storage.energy_index = storage.ns_residuals.size();
1018 storage.ns_residuals.push_back(std::make_pair(0, 1.0));
1019 storage.ns_abs_tols.push_back(_energy_absolute_tolerance);
1020 }
1021
1023 {
1024 storage.solid_energy_index = storage.ns_residuals.size();
1025 storage.ns_residuals.push_back(std::make_pair(0, 1.0));
1027 }
1028
1030 for (const auto i : index_range(_active_scalar_system_names))
1031 {
1032 storage.active_scalar_indices.push_back(storage.ns_residuals.size());
1033 storage.ns_residuals.push_back(std::make_pair(0, 1.0));
1034 storage.ns_abs_tols.push_back(_active_scalar_absolute_tolerance[i]);
1035 }
1036
1038 for (const auto i : index_range(_turbulence_system_names))
1039 {
1040 storage.turbulence_indices.push_back(storage.ns_residuals.size());
1041 storage.ns_residuals.push_back(std::make_pair(0, 1.0));
1042 storage.ns_abs_tols.push_back(_turbulence_absolute_tolerance[i]);
1043 }
1044
1046 for (const auto i : index_range(_pm_radiation_system_names))
1047 {
1048 storage.pm_radiation_indices.push_back(storage.ns_residuals.size());
1049 storage.ns_residuals.push_back(std::make_pair(0, 1.0));
1050 storage.ns_abs_tols.push_back(_pm_radiation_absolute_tolerance[i]);
1051 }
1052
1053 storage.converged = storage.ns_residuals.empty();
1054 return storage;
1055}
const ExecFlagType EXEC_NONLINEAR
void ErrorVector unsigned int
const ConsoleStream _console
virtual void computeLinearSystemSys(libMesh::LinearImplicitSystem &sys, libMesh::SparseMatrix< libMesh::Number > &system_matrix, NumericVector< libMesh::Number > &rhs, const bool compute_gradients=true)
bool shouldSolve() const
LinearSystem & getLinearSystem(unsigned int sys_num)
void setCurrentLinearSystem(unsigned int sys_num)
unsigned int linearSysNum(const LinearSystemName &linear_sys_name) const override
virtual MooseMesh & mesh() override
virtual void execute(const ExecFlagType &exec_type)
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const unsigned int _energy_sys_number
The number of the system corresponding to the energy equation.
std::pair< unsigned int, Real > solveSolidEnergy()
Solve an equation which contains the solid energy conservation.
virtual std::pair< unsigned int, Real > correctVelocity(const bool recompute_face_mass_flux, const SolverParams &solver_params)
Computes new velocity field based on computed pressure gradients.
unsigned int _turbulence_pc_solve_counter
Number of turbulence equations solves performed without recomputing the preconditioner.
unsigned int _energy_pc_solve_counter
Number of energy solves performed without recomputing the preconditioner.
std::pair< unsigned int, Real > solveAdvectedSystem(const unsigned int system_num, LinearSystem &system, const Real relaxation_factor, libMesh::SolverConfiguration &solver_config, const Real abs_tol, const bool reuse_pc, const Real field_relaxation=1.0, const Real min_value_limiter=std::numeric_limits< Real >::min())
Solve an equation which contains an advection term that depends on the solution of the segregated Nav...
const unsigned int _energy_pc_recompute_frequency
How often to recompute the energy equation preconditioner.
SIMPLESolverConfiguration _active_scalar_linear_control
Options for the linear solver of the active scalar equation(s)
ResidualStorage setupResidualStorage() const
Build residual/tolerance vectors and associated indices for all enabled systems.
const unsigned int _solid_energy_sys_number
The number of the system corresponding to the solid energy equation.
std::vector< LinearSystem * > _systems_to_solve
Shortcut to every linear system that we solve for here.
unsigned int _solid_energy_pc_solve_counter
Number of solid energy solves performed without recomputing the preconditioner.
const unsigned int _momentum_pc_recompute_frequency
How often to recompute the momentum equations preconditioner.
const Real _active_scalar_l_abs_tol
Absolute linear tolerance for the active scalar equation(s).
LinearSystem * _energy_system
Pointer to the linear system corresponding to the fluid energy equation.
NS::FV::CHTHandler _cht
********************** Conjugate heat transfer variables ************** //
LinearSystem * _solid_energy_system
Pointer to the linear system corresponding to the solid energy equation.
std::vector< unsigned int > _momentum_system_numbers
The number(s) of the system(s) corresponding to the momentum equation(s)
std::vector< LinearSystem * > _turbulence_systems
Pointer(s) to the system(s) corresponding to the turbulence equation(s)
virtual bool solve() override
Performs the momentum pressure coupling.
std::vector< LinearSystem * > _momentum_systems
Pointer(s) to the system(s) corresponding to the momentum equation(s)
std::vector< LinearSystem * > _pm_radiation_systems
Pointer(s) to the system(s) corresponding to the participting media radiation equation(s)
Moose::PetscSupport::PetscOptions _active_scalar_petsc_options
Options which hold the petsc settings for the active scalar equation(s)
RhieChowMassFlux * _rc_uo
Pointer to the segregated RhieChow interpolation object.
const unsigned int _pressure_pc_recompute_frequency
How often (in pressure corrector solves) to recompute the pressure preconditioner.
virtual std::vector< std::pair< unsigned int, Real > > solveMomentumPredictor() override
Solve a momentum predictor step with a fixed pressure field.
unsigned int _momentum_pc_solve_counter
Number of momentum equations solves performed without recomputing the preconditioner.
const std::vector< Real > _active_scalar_equation_relaxation
The user-defined relaxation parameter(s) for the active scalar equation(s)
std::vector< LinearSystem * > _active_scalar_systems
Pointer(s) to the system(s) corresponding to the active scalar equation(s)
unsigned int _active_scalar_pc_solve_counter
Number of active scalar solves performed without recomputing the preconditioner.
unsigned int _pressure_pc_solve_counter
Number of pressure corrector solves performed without recomputing the preconditioner.
const unsigned int _active_scalar_pc_recompute_frequency
How often to recompute the active scalar equations preconditioner.
const unsigned int _turbulence_pc_recompute_frequency
How often to recompute the turbulence equations preconditioner.
virtual void linkRhieChowUserObject() override
Fetch the Rhie Chow user object that is reponsible for determining face velocities and mass flux.
LinearSystem & _pressure_system
Reference to the linear system corresponding to the pressure equation.
const std::vector< Real > _active_scalar_absolute_tolerance
The user-defined absolute tolerance for determining the convergence in active scalars.
const bool _has_active_scalar_systems
Boolean for easy check if a active scalar systems shall be solved or not.
const unsigned int _solid_energy_pc_recompute_frequency
How often to recompute the solid energy equation preconditioner.
const std::vector< SolverSystemName > & _active_scalar_system_names
The names of the active scalar systems.
unsigned int _passive_scalar_pc_solve_counter
Number of passive scalar solves performed without recomputing the preconditioner.
const unsigned int _passive_scalar_pc_recompute_frequency
How often to recompute the passive scalar equations preconditioner.
const unsigned int _pressure_sys_number
The number of the system corresponding to the pressure equation.
std::vector< unsigned int > _active_scalar_system_numbers
virtual std::pair< unsigned int, Real > solvePressureCorrector() override
Solve a pressure corrector step.
const bool _should_solve_momentum
Flags controlling which systems are actively solved (can be used with restart to freeze flow)
std::vector< LinearSystem * > _passive_scalar_systems
Pointer(s) to the system(s) corresponding to the passive scalar equation(s)
virtual System & system() override
void computeGradients()
bool isRecovering() const
void paramError(const std::string &param, Args... args) const
virtual unsigned int dimension() const
MooseApp & _app
void sumIntegratedFluxes()
Sum the integrated fluxes over all processors.
Definition CHTHandler.C:585
void printIntegratedFluxes() const
Print the integrated heat fluxes.
Definition CHTHandler.C:598
void resetCHTConvergence()
Reset the convergence data.
Definition CHTHandler.h:188
void resetIntegratedFluxes()
Reset the heat fluxes to 0.
Definition CHTHandler.C:614
void initializeCHTCouplingFields()
Initialize the coupling fields for the conjugate heat transfer routines.
Definition CHTHandler.C:436
void deduceCHTBoundaryCoupling()
Run error checks and make sure everything works.
Definition CHTHandler.C:144
bool converged() const
Check if CHT iteration converged.
Definition CHTHandler.C:625
void setupConjugateHeatTransferContainers()
Set up the boundary condition pairs, functor maps, and every other necessary structure for the conjug...
Definition CHTHandler.C:351
virtual bool enabled() const override final
Check if CHT treatment is needed.
Definition CHTHandler.h:182
static InputParameters validParams()
Definition CHTHandler.C:26
void updateCHTBoundaryCouplingFields(const NS::CHTSide side)
Update the coupling fields for.
Definition CHTHandler.C:465
void linkEnergySystems(SystemBase *solid_energy_system, SystemBase *fluid_energy_system, std::vector< SystemBase * > pm_radiation_systems)
Link energy systems.
Definition CHTHandler.C:129
void incrementCHTIterators()
Increment CHT iterators in the loop.
Definition CHTHandler.h:194
User object responsible for determining the face fluxes using the Rhie-Chow interpolation in a segreg...
void linkMomentumPressureSystems(const std::vector< LinearSystem * > &momentum_systems, LinearSystem &pressure_system, const std::vector< unsigned int > &momentum_system_numbers)
Update the momentum system-related information.
void initFaceMassFlux()
Initialize the container for face velocities.
void finalizePressureCorrector()
After pressure relaxation, refresh every registered pressure gradient and publish relaxed reconstruct...
void finalizeMomentumPredictor()
Capture the lagged velocity gradients computed while assembling the momentum predictor.
void computeFaceMassFlux()
Update the values of the face velocities in the containers.
void computeHbyA(const bool verbose)
Computes the inverse of the diagonal (1/A) of the system matrix plus the H/A components for the press...
void initPressureGradient()
Compute every registered pressure gradient once, before the first momentum predictor of a SIMPLE iter...
void initCouplingField()
Initialize the coupling fields (HbyA and Ainv)
void preparePressureRelaxation()
Before pressure relaxation, form the conservative reconstructed candidate from the corrected face flu...
void prepareMomentumPredictor()
Snapshot the fields read by the next momentum predictor.
Solve class serving as a base class for the two SIMPLE solvers that operate with different assembly a...
const std::vector< Real > _turbulence_equation_relaxation
The user-defined relaxation parameter(s) for the turbulence equation(s)
const Real _momentum_equation_relaxation
The user-defined relaxation parameter for the momentum equation.
const bool _has_energy_system
Boolean for easy check if a fluid energy system shall be solved or not.
std::vector< unsigned int > _pm_radiation_system_numbers
dof_id_type _pressure_pin_dof
The dof ID where the pressure needs to be pinned.
const bool _has_turbulence_systems
Boolean for easy check if a turbulence scalar systems shall be solved or not.
SIMPLESolverConfiguration _pm_radiation_linear_control
Options for the linear solver of the participating media radiation equation(s)
std::vector< unsigned int > _turbulence_system_numbers
const std::vector< SolverSystemName > & _passive_scalar_system_names
The names of the passive scalar systems.
const std::vector< Real > _pm_radiation_absolute_tolerance
The user-defined absolute tolerance for determining the convergence in participating media radiation.
std::vector< unsigned int > _passive_scalar_system_numbers
Moose::PetscSupport::PetscOptions _turbulence_petsc_options
Options which hold the petsc settings for the turbulence equation(s)
const bool _has_pm_radiation_systems
Boolean for easy check if participating media radiation systems shall be solved or not.
const Real _pressure_absolute_tolerance
The user-defined absolute tolerance for determining the convergence in pressure.
const std::vector< SolverSystemName > & _turbulence_system_names
The names of the turbulence systems.
const Real _turbulence_l_abs_tol
Absolute linear tolerance for the turbulence equation(s).
const std::vector< Real > _passive_scalar_equation_relaxation
The user-defined relaxation parameter(s) for the passive scalar equation(s)
const Real _pressure_l_abs_tol
Absolute linear tolerance for the pressure equation.
const Real _passive_scalar_l_abs_tol
Absolute linear tolerance for the passive scalar equation(s).
const bool _has_solid_energy_system
Boolean for easy check if a solid energy system shall be solved or not.
Moose::PetscSupport::PetscOptions _passive_scalar_petsc_options
Options which hold the petsc settings for the passive scalar equation(s)
SIMPLESolverConfiguration _pressure_linear_control
Options for the linear solver of the pressure equation.
static InputParameters validParams()
std::vector< Real > _turbulence_field_relaxation
The user-defined relaxation parameter(s) for the turbulence field(s)
const std::vector< Real > _turbulence_absolute_tolerance
The user-defined absolute tolerance for determining the convergence turbulence variables.
const std::vector< Real > _momentum_absolute_tolerance
The user-defined absolute tolerance(s) for determining the convergence in momentum.
SIMPLESolverConfiguration _solid_energy_linear_control
Options for the linear solver of the energy equation.
const bool _has_passive_scalar_systems
Boolean for easy check if a passive scalar systems shall be solved or not.
std::vector< Real > _turbulence_field_min_limit
The user-defined lower limit for turbulent quantities e.g. k, eps/omega, etc..
Moose::PetscSupport::PetscOptions _pm_radiation_petsc_options
Options which hold the petsc settings for the participating media radiation equation(s)
const std::vector< SolverSystemName > & _pm_radiation_system_names
The names of the participating media radiation systems.
const Real _pm_radiation_l_abs_tol
Absolute linear tolerance for the participating media radiation equation(s).
const Real _pressure_variable_relaxation
The user-defined relaxation parameter for the pressure variable.
const Real _momentum_l_abs_tol
Absolute linear tolerance for the momentum equation(s).
Moose::PetscSupport::PetscOptions _momentum_petsc_options
Options which hold the petsc settings for the momentum equation.
SIMPLESolverConfiguration _energy_linear_control
Options for the linear solver of the energy equation.
const Real _energy_l_abs_tol
Absolute linear tolerance for the energy equations.
const Real _pressure_pin_value
The value we want to enforce for pressure.
Moose::PetscSupport::PetscOptions _solid_energy_petsc_options
Options which hold the petsc settings for the fluid energy equation.
Moose::PetscSupport::PetscOptions _pressure_petsc_options
Options which hold the petsc settings for the pressure equation.
const bool _continue_on_max_its
If solve should continue if maximum number of iterations is hit.
const Real _energy_absolute_tolerance
The user-defined absolute tolerance for determining the convergence in energy.
const unsigned int _num_iterations
The maximum number of momentum-pressure iterations.
const std::vector< Real > _passive_scalar_absolute_tolerance
The user-defined absolute tolerance for determining the convergence in passive scalars.
SIMPLESolverConfiguration _turbulence_linear_control
Options for the linear solver of the turbulence equation(s)
const std::vector< SolverSystemName > & _momentum_system_names
The names of the momentum systems.
const Real _energy_equation_relaxation
The user-defined relaxation parameter for the energy equation.
SIMPLESolverConfiguration _momentum_linear_control
Options for the linear solver of the momentum equation.
SIMPLESolverConfiguration _passive_scalar_linear_control
Options for the linear solver of the passive scalar equation(s)
const Real _solid_energy_l_abs_tol
Absolute linear tolerance for the energy equations.
const bool _pin_pressure
If the pressure needs to be pinned.
Moose::PetscSupport::PetscOptions _energy_petsc_options
Options which hold the petsc settings for the fluid energy equation.
const std::vector< Real > _pm_radiation_equation_relaxation
The user-defined relaxation parameter(s) for the participating media radiation equation(s)
const Real _energy_field_relaxation
The user-defined relaxation parameter(s) for the energy field.
const bool _print_fields
Debug parameter which allows printing the coupling and solution vectors/matrices.
const Real _solid_energy_absolute_tolerance
The user-defined absolute tolerance for determining the convergence in solid energy.
FEProblemBase & _problem
Moose::LineSearchType _line_search
Moose::SolveType _type
void setSolution(const NumericVector< Number > &soln)
void copyPreviousSolutions(const Moose::SolutionIterationType iteration_type)
virtual const NumericVector< Number > * solutionPreviousNewton() const
virtual const std::string & name() const
void set_solver_configuration(SolverConfiguration &solver_configuration)
virtual void reuse_preconditioner(bool)
virtual std::pair< unsigned int, Real > solve(SparseMatrix< T > &matrix_in, NumericVector< T > &solution_in, NumericVector< T > &rhs_in, const std::optional< double > tol=std::nullopt, const std::optional< unsigned int > m_its=std::nullopt) override
std::map< std::string, int > int_valued_data
std::map< std::string, Real > real_valued_data
void petscSetOptions(const PetscOptions &po, const SolverParams &solver_params, FEProblemBase *const problem=nullptr)
MultiMooseEnum getCommonPetscFlags()
MultiMooseEnum getCommonPetscKeys()
void addPetscFlagsToPetscOptions(const MultiMooseEnum &petsc_flags, std::string prefix, const ParallelParamObject &param_object, PetscOptions &petsc_options)
void addPetscPairsToPetscOptions(const std::vector< std::pair< MooseEnumItem, std::string > > &petsc_pair_options, const unsigned int mesh_dimension, std::string prefix, const ParallelParamObject &param_object, PetscOptions &petsc_options)
std::string stringify(const T &t)
Real computeNormalizationFactor(const NumericVector< Number > &solution, const SparseMatrix< Number > &mat, const NumericVector< Number > &rhs)
Compute a normalization factor which is applied to the linear residual to determine convergence.
bool converged(const std::vector< std::pair< unsigned int, Real > > &residuals, const std::vector< Real > &abs_tolerances)
Based on the residuals, determine if the iterative process converged or not.
void relaxMatrix(SparseMatrix< Number > &matrix_in, const Real relaxation_parameter, NumericVector< Number > &diff_diagonal)
Relax the matrix to ensure diagonal dominance, we hold onto the difference in diagonals for later use...
void constrainSystem(SparseMatrix< Number > &mx, NumericVector< Number > &rhs, const Real desired_value, const dof_id_type dof_id)
Implicitly constrain the system by adding a factor*(u-u_desired) to it at a desired dof value.
void relaxSolutionUpdate(NumericVector< Number > &vec_new, const NumericVector< Number > &vec_old, const Real relaxation_factor)
Relax the update on a solution field using the following approach: $u = u_{old}+\lambda (u - u_{old})...
void limitSolutionUpdate(NumericVector< Number > &solution, const Real min_limit=std::numeric_limits< Real >::epsilon(), const Real max_limit=1e10)
Limit a solution to its minimum and maximum bounds: $u = min(max(u, min_limit), max_limit)$.
void relaxRightHandSide(NumericVector< Number > &rhs_in, const NumericVector< Number > &solution_in, const NumericVector< Number > &diff_diagonal)
Relax the right hand side of an equation, this needs to be called once and the system matrix has been...
@ SOLID
Definition NS.h:200
@ FLUID
Definition NS.h:201
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
Aggregated storage for residuals, tolerances, and indices used in convergence checks.
std::vector< std::size_t > active_scalar_indices
Indices of active scalar equations in ns_residuals.
std::size_t pressure_index
Index of the pressure equation in ns_residuals.
std::vector< std::size_t > turbulence_indices
Indices of turbulence surrogate equations in ns_residuals.
std::size_t energy_index
Index of the energy equation in ns_residuals.
std::vector< std::pair< unsigned int, Real > > ns_residuals
(linear iterations, normalized residual) entries in the order used by NS::FV::converged()
bool converged
This will be an initial indicator if we have something to solve.
std::vector< std::size_t > pm_radiation_indices
Indices of participating media radiation equations in ns_residuals.
std::vector< std::size_t > momentum_indices
Indices of momentum equations in ns_residuals.
std::vector< Real > ns_abs_tols
Absolute tolerances matching ns_residuals.
std::size_t solid_energy_index
Index of the solid energy equation in ns_residuals.