https://mooseframework.inl.gov
Loading...
Searching...
No Matches
FVReconstructedPressureGradient.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
12#include "FEProblemBase.h"
13#include "FVUtils.h"
15#include "LinearSystem.h"
16#include "MooseMesh.h"
17#include "RhieChowMassFlux.h"
18#include "SystemBase.h"
19
20#include "libmesh/dense_matrix.h"
21#include "libmesh/dense_vector.h"
22#include "libmesh/elem.h"
23
24#include <cmath>
25
26using namespace libMesh;
27
29
32{
35 params.suppressParameter<MooseEnum>("limiter");
37 "Reconstructs and relaxes the pressure gradient used for Rhie-Chow momentum coupling.");
38 params.addParam<GradientMethodName>(
39 "base_gradient_method",
40 "green-gauss",
41 "Gradient method used before Rhie-Chow has computed reconstructed gradients.");
42 // A conservative 0.1 default damps pressure-velocity feedback with the standard SIMPLE
43 // relaxation settings; values near 1 can require retuning those settings to converge.
45 "gradient_relaxation",
46 0.1,
47 "0.0<gradient_relaxation<=1.0",
48 "Relaxation factor applied when updating the reconstructed pressure-coupling gradient.");
49 return params;
50}
51
53 : FVGradientMethod(params),
55 _base_gradient_method_name(getParam<GradientMethodName>("base_gradient_method")),
56 _gradient_relaxation(getParam<Real>("gradient_relaxation"))
57{
58}
59
60void
62 const LinearFVGradientReader & pressure_gradient)
63{
64 mooseAssert(&pressure_gradient.system() == &rc.pressureSystem(),
65 "First binding must use the pressure system owned by the RhieChowMassFlux.");
66
67 mooseAssert(pressure_gradient.variableNumber() == rc.pressureVariableNumber(),
68 "First binding must use the pressure variable registered on the RhieChowMassFlux.");
69
70 if (!_rhie_chow)
71 {
72 _rhie_chow = &rc;
73 _pressure_system = &pressure_gradient.system();
74 _pressure_variable_number = pressure_gradient.variableNumber();
75 _momentum_systems.reserve(rc.dimension());
77 for (const auto component : make_range(rc.dimension()))
78 {
79 _momentum_systems.push_back(&rc.momentumSystem(component));
81 }
82 return;
83 }
84
85 if (_rhie_chow != &rc)
86 mooseError("FVReconstructedPressureGradient '",
87 name(),
88 "' is already bound to RhieChowMassFlux '",
90 "' and cannot also be used by RhieChowMassFlux '",
91 rc.name(),
92 "'.");
93
94 if (_pressure_system != &pressure_gradient.system())
95 mooseError("FVReconstructedPressureGradient '",
96 name(),
97 "' is already bound to pressure system '",
99 "' and cannot also be used by pressure system '",
100 pressure_gradient.system().name(),
101 "'.");
102
103 if (_pressure_variable_number != pressure_gradient.variableNumber())
104 mooseError("FVReconstructedPressureGradient '",
105 name(),
106 "' is already bound to pressure variable number ",
108 " and cannot also be used by pressure variable number ",
109 pressure_gradient.variableNumber(),
110 ".");
111
112 if (_momentum_systems.size() != rc.dimension())
113 mooseError("FVReconstructedPressureGradient '",
114 name(),
115 "' cannot be reused with a different set of momentum systems.");
116
117 for (const auto component : make_range(rc.dimension()))
118 if (_momentum_systems[component] != &rc.momentumSystem(component))
119 mooseError("FVReconstructedPressureGradient '",
120 name(),
121 "' cannot be reused with a different set of momentum systems.");
122}
123
124void
126{
127 mooseAssert(_rhie_chow,
128 "FVReconstructedPressureGradient must be bound to one RhieChowMassFlux before it "
129 "is used.");
130
131 mooseAssert(_rhie_chow == &rc,
132 "FVReconstructedPressureGradient is bound to a single RhieChowMassFlux and cannot "
133 "be used by another.");
134}
135
136void
138{
139 checkFlowSystem(rc);
140
141 mooseAssert(_pressure_system == &rc.pressureSystem() &&
143 "FVReconstructedPressureGradient must be linked to the pressure field owned by its "
144 "bound RhieChowMassFlux.");
145
146 const auto & pressure_variable = rc.pressureSystem().getVariable(0, _pressure_variable_number);
147 if (pressure_variable.blockIDs() != rc.blockIDs())
148 mooseError("FVReconstructedPressureGradient '",
149 name(),
150 "' requires pressure variable '",
151 pressure_variable.name(),
152 "' and RhieChowMassFlux '",
153 rc.name(),
154 "' to have identical block restrictions. Pressure blocks: ",
155 Moose::stringify(pressure_variable.blockIDs()),
156 "; Rhie-Chow blocks: ",
158 ".");
159
160 mooseAssert(_momentum_systems.size() == rc.dimension() &&
162 "One momentum system and velocity-gradient field must be registered per spatial "
163 "component.");
164
165 for (const auto component : make_range(rc.dimension()))
166 {
167 mooseAssert(_momentum_systems[component] == &rc.momentumSystem(component),
168 "Momentum system linkage must match the RhieChowMassFlux for every spatial "
169 "component.");
170
171 const auto & velocity_variable = rc.velocityVariable(component);
172 if (velocity_variable.blockIDs() != rc.blockIDs())
173 mooseError("FVReconstructedPressureGradient '",
174 name(),
175 "' requires velocity variable '",
176 velocity_variable.name(),
177 "' and RhieChowMassFlux '",
178 rc.name(),
179 "' to have identical block restrictions. Velocity blocks: ",
180 Moose::stringify(velocity_variable.blockIDs()),
181 "; Rhie-Chow blocks: ",
183 ".");
184
185 [[maybe_unused]] const auto * const velocity_gradient = _velocity_gradient_fields[component];
186 mooseAssert(velocity_gradient &&
187 &velocity_gradient->system() == &rc.momentumSystem(component) &&
188 velocity_gradient->variableNumber() == rc.velocityVariable(component).number(),
189 "Velocity-gradient field linkage must match the RhieChowMassFlux for every "
190 "momentum component.");
191 }
192}
193
194void
196{
198 mooseError("FVReconstructedPressureGradient '",
199 name(),
200 "' cannot use itself as its base_gradient_method.");
201
202 if (_base_gradient_method_name == "green-gauss" &&
204 {
205 auto params = fe_problem.getMooseApp().getFactory().getValidParams("FVGreenGaussGradient");
206 fe_problem.addFVGradientMethod("FVGreenGaussGradient", _base_gradient_method_name, params);
207 }
208
211 "Unable to find base FVGradientMethod with name '", _base_gradient_method_name, "'.");
212
214}
215
216void
218 SystemBase & system,
219 GradientContainer & gradient,
220 const std::unordered_set<unsigned int> & variable_numbers) const
221{
222 // On a fresh run, FEProblemBase::initialSetup() calls copySolutionsBackwards() to initialize
223 // gradient time-state storage before SIMPLE or PIMPLE calls linkRhieChowUserObject(). That state
224 // initialization reaches this method with no linked Rhie-Chow pressure system, so seed the
225 // gradient history with the ordinary gradient until the executioner completes the linkage.
226 if (!_pressure_system)
227 {
228 mooseAssert(_base_gradient_method,
229 "resolveGradientMethodDependencies() must run before gradients are computed.");
230 _base_gradient_method->computeGradient(system, gradient, variable_numbers);
231 return;
232 }
233
234 mooseAssert(_pressure_system == &system,
235 "FVReconstructedPressureGradient can only compute gradients for the pressure "
236 "system it is bound to.");
237
238 mooseAssert(variable_numbers.size() == 1 && variable_numbers.count(_pressure_variable_number),
239 "FVReconstructedPressureGradient can only compute the pressure variable to which "
240 "it is bound.");
241
242 if (_coupling_pressure_gradient.empty())
243 {
244 // No flux-consistent pressure gradient exists before the first pressure corrector. Use the
245 // ordinary gradient for the initial momentum predictor instead of inventing coupling data.
246 mooseAssert(_base_gradient_method,
247 "resolveGradientMethodDependencies() must run before gradients are computed.");
248 _base_gradient_method->computeGradient(system, gradient, variable_numbers);
249 return;
250 }
251
252 mooseAssert(_coupling_pressure_gradient.size() == gradient.size(),
253 "Coupling and destination gradients must have equal component counts.");
254 for (const auto component : index_range(gradient))
255 {
256 mooseAssert(gradient[component]->type() == GHOSTED,
257 "Linear FV gradient storage must be ghosted.");
258 // Only the owned range needs to be copied here; the caller,
259 // FVGradientMethod::computeGradient(), unconditionally closes every component of gradient right
260 // after this call returns, which refreshes the ghosts needed by face interpolation from the
261 // now-matching owned entries.
262 *gradient[component] = *_coupling_pressure_gradient[component];
263 }
264}
265
266void
268 GradientContainer & destination)
269{
270 if (destination.empty())
271 {
272 destination.reserve(source.size());
273 for (const auto component : index_range(source))
274 destination.push_back(source[component]->clone());
275 return;
276 }
277
278 mooseAssert(source.size() == destination.size(),
279 "Source and destination gradients must have equal component counts.");
280 for (const auto component : index_range(source))
281 {
282 mooseAssert(
283 source[component]->size() == destination[component]->size() &&
284 source[component]->local_size() == destination[component]->local_size() &&
285 source[component]->first_local_index() == destination[component]->first_local_index() &&
286 source[component]->last_local_index() == destination[component]->last_local_index(),
287 "Source and destination gradient component vectors must have matching parallel "
288 "layouts.");
289 *destination[component] = *source[component];
290 }
291}
292
293void
323
324void
326{
327 checkFlowSystem(rc);
328 // A new time-step attempt starts from the last accepted coupling field. This keeps a converged
329 // momentum balance unchanged across time-step acceptance, rejection, restart, and recovery.
333}
334
335void
343
344void
346{
347 checkFlowSystem(rc);
349 const auto dimension = rc.dimension();
350
351 mooseAssert(_velocity_gradient_fields.size() == dimension,
352 "A velocity gradient field must be registered for every momentum component.");
353
354 // Freeze grad(u) before the pressure corrector changes the flux. The lagged field linearizes the
355 // Taylor correction from each cell center P to its face f without coupling reconstruction back
356 // to the velocity that it is currently computing.
359
360 for (const auto component : make_range(dimension))
361 copyGradient(_velocity_gradient_fields[component]->components(),
363}
364
367 const RhieChowMassFlux & rc,
368 const RealVectorValue & elem_gradient,
369 const FaceInfo & fi,
370 const bool elem_has_info,
371 const unsigned int velocity_component) const
372{
373 const auto dimension = rc.dimension();
374 const ElemInfo * const neighbor_info = elem_has_info ? fi.neighborInfo() : fi.elemInfo();
375 // At a domain boundary or the edge of the Rhie-Chow block restriction, use the owned cell's
376 // gradient (zero Hessian approximation). Otherwise interpolate the two lagged cell gradients to
377 // the face.
378 if (!neighbor_info || !rc.hasBlocks(neighbor_info->subdomain_id()))
379 return elem_gradient;
380
381 const auto & velocity = rc.velocityVariable(velocity_component);
382 const auto system_number = rc.momentumSystem(velocity_component).number();
383 RealVectorValue neighbor_gradient;
384 for (const auto direction : make_range(dimension))
385 neighbor_gradient(direction) =
386 (*_lagged_reconstruction_velocity_gradient[velocity_component][direction])(
387 neighbor_info->dofIndices()[system_number][velocity.number()]);
388
389 RealVectorValue face_gradient;
390 Moose::FV::interpolate(Moose::FV::InterpMethod::Average,
391 face_gradient,
392 elem_gradient,
393 neighbor_gradient,
394 fi,
395 elem_has_info);
396
397 return face_gradient;
398}
399
400void
402 const RhieChowMassFlux & rc,
403 const ElemInfo & elem_info,
404 const std::vector<RealVectorValue> & elem_velocity_gradients,
405 const FaceInfo * const fi,
406 const Point & surface_vector,
407 const bool elem_has_info,
408 DenseMatrix<Real> & matrix,
409 DenseVector<Real> & projection_rhs) const
410{
411 mooseAssert(fi, "FaceInfo must be available while reconstructing a cell.");
412
413 const Real surface_area = surface_vector.norm();
414 // An axisymmetric face on the symmetry axis has zero physical area and adds no projection
415 // equation.
416 if (surface_area == 0.0)
417 return;
418
419 const auto pressure_face_type =
421 // On one-sided pressure faces, RhieChow stores the flux outward from the pressure cell. On
422 // two-sided faces, it stores the flux relative to FaceInfo::normal(), so only the neighbor cell
423 // needs the opposite orientation.
424 const Real normal_alignment =
425 pressure_face_type == FaceInfo::VarFaceNeighbors::BOTH && !elem_has_info ? -1.0 : 1.0;
426 const Real face_flux = rc.getVolumetricFaceFlux(*fi);
427 mooseAssert(std::isfinite(face_flux), "Corrected face flux must be finite.");
428 Real face_normal_reconstructed_quantity = face_flux * normal_alignment;
429
430 // First-order expansion at the face gives
431 // u_f.n_f = u_P.n_f + ((grad u)_f d_Pf).n_f.
432 // Subtract the lagged Taylor term to obtain one face equation for the unknown cell velocity:
433 // u_P.n_f ~= u_f.n_f - ((grad u)_f d_Pf).n_f.
434 const Point d_pf = fi->faceCentroid() - elem_info.centroid();
435 Real gradient_flux_correction = 0.0;
436 for (const auto component : make_range(rc.dimension()))
437 {
438 const auto velocity_gradient = reconstructionVelocityGradient(
439 rc, elem_velocity_gradients[component], *fi, elem_has_info, component);
440 for ([[maybe_unused]] const auto direction : make_range(rc.dimension()))
441 mooseAssert(std::isfinite(velocity_gradient(direction)),
442 "Lagged velocity gradient must be finite.");
443
444 gradient_flux_correction += (velocity_gradient * d_pf) * surface_vector(component);
445 }
446
447 face_normal_reconstructed_quantity -= gradient_flux_correction / surface_area;
448
449 // Assemble the area-weighted least-squares projection of the corrected face equations:
450 // [sum_f |S_f| n_f n_f^T] u_P = sum_f |S_f| qhat_f n_f,
451 // where qhat_f is face_normal_reconstructed_quantity and S_f = |S_f| n_f.
452 for (const auto i : make_range(rc.dimension()))
453 {
454 projection_rhs(i) += face_normal_reconstructed_quantity * surface_vector(i);
455 for (const auto j : make_range(rc.dimension()))
456 matrix(i, j) += surface_vector(i) * surface_vector(j) / surface_area;
457 }
458}
459
462 const DenseVector<Real> & projection_rhs) const
463{
464 const auto dimension = projection_rhs.size();
465 DenseVector<Real> reconstructed_quantity(dimension);
466 if (dimension == 1)
467 reconstructed_quantity(0) = projection_rhs(0) / matrix(0, 0);
468 else
469 {
470 // A valid cell has face normals that span the spatial dimension, making this normal-equation
471 // matrix symmetric positive definite.
472 DenseMatrix<Real> solve_matrix(matrix);
473 solve_matrix.cholesky_solve(projection_rhs, reconstructed_quantity);
474 }
475
476 return reconstructed_quantity;
477}
478
479Real
481 const RhieChowMassFlux & rc,
482 const ElemInfo & elem_info,
483 const unsigned int component,
484 const Real reconstructed_velocity) const
485{
486 mooseAssert(std::isfinite(reconstructed_velocity),
487 "Reconstructed velocity component must be finite.");
488
489 const auto momentum_dof = elem_info.dofIndices()[rc.momentumSystem(component).number()][0];
490 const Real HbyA = (*rc.HbyAComponents()[component])(momentum_dof);
491 const Real Ainv = (*rc.AinvComponents()[component])(momentum_dof);
492 if (!std::isfinite(HbyA) || !std::isfinite(Ainv) || Ainv == 0.0)
493 mooseError("FVReconstructedPressureGradient '",
494 name(),
495 "' found invalid momentum-coupling data for component ",
496 component,
497 " of cell ID ",
498 elem_info.elem()->id(),
499 ": H/A = ",
500 HbyA,
501 " and 1/A = ",
502 Ainv,
503 ".");
504
505 // Invert the same diagonal momentum relation used by Rhie-Chow,
506 // u_P = -(H/A)_P - A_P^{-1} (grad p)_P,
507 // so the reconstructed pressure gradient produces the projected, flux-consistent u_P.
508 const Real reconstructed_gradient = (-reconstructed_velocity - HbyA) / Ainv;
509 mooseAssert(std::isfinite(reconstructed_gradient),
510 "Reconstructed pressure-gradient component must be finite.");
511
512 return reconstructed_gradient;
513}
514
515void
517{
518 checkFlowSystem(rc);
520
521 const auto dimension = rc.dimension();
522 const auto & base_pressure_gradient = rc.basePressureGradientComponents();
523 const auto face_flux_iteration = rc.faceMassFluxGeneration();
524
525 mooseAssert(base_pressure_gradient.size() == dimension,
526 "A base pressure-gradient component must exist for every spatial dimension.");
527
528 mooseAssert(face_flux_iteration != _last_reconstructed_face_flux_iteration,
529 "The current pressure corrector must produce a new face flux before "
530 "reconstruction.");
531
533 for (const auto component : make_range(dimension))
534 _reconstructed_pressure_gradient.push_back(base_pressure_gradient[component]->zero_clone());
535
536 // Zero the candidate so pressure DOFs not visited during this corrector cannot retain stale
537 // reconstructed values from an earlier cycle.
538 for (auto & pressure_gradient : _reconstructed_pressure_gradient)
539 pressure_gradient->zero();
540
541 const auto & mesh = rc.pressureSystem().feProblem().mesh();
542 const auto rz_radial_coord = mesh.getAxisymmetricRadialCoord();
543 std::vector<RealVectorValue> elem_velocity_gradients(dimension);
544
545 for (const auto & elem_info : mesh.elemInfoVector())
546 {
547 if (!rc.hasBlocks(elem_info->subdomain_id()))
548 continue;
549
550 const Elem & elem = *elem_info->elem();
551 DenseMatrix<Real> matrix(dimension, dimension);
552 DenseVector<Real> projection_rhs(dimension);
553 matrix.zero();
554 projection_rhs.zero();
555
556 for (const auto component : make_range(dimension))
557 {
558 const auto & velocity = rc.velocityVariable(component);
559 const auto system_number = rc.momentumSystem(component).number();
560 const auto velocity_dof = elem_info->dofIndices()[system_number][velocity.number()];
561 for (const auto direction : make_range(dimension))
562 {
563 const auto gradient =
564 (*_lagged_reconstruction_velocity_gradient[component][direction])(velocity_dof);
565 mooseAssert(std::isfinite(gradient), "Lagged velocity gradient must be finite.");
566 elem_velocity_gradients[component](direction) = gradient;
567 }
568 }
569
570 // The coordinate-system-aware surface vector S_f supplied by loopOverElemFaceInfo is outward
571 // from this cell, including the appropriate Cartesian or axisymmetric geometric weighting.
572 auto act = [&](const Elem &,
573 const Elem * const,
574 const FaceInfo * const fi,
575 const Point & surface_vector,
576 const Real,
577 const bool elem_has_info)
578 {
580 *elem_info,
581 elem_velocity_gradients,
582 fi,
583 surface_vector,
584 elem_has_info,
585 matrix,
586 projection_rhs);
587 };
588
590 elem, mesh, act, mesh.getCoordSystem(elem.subdomain_id()), rz_radial_coord);
591
592 const auto reconstructed_quantity = solveFaceProjection(matrix, projection_rhs);
593
594 const auto pressure_dof =
595 elem_info->dofIndices()[rc.pressureSystem().number()][_pressure_variable_number];
596 for (const auto component : make_range(dimension))
597 {
598 const auto reconstructed_gradient =
599 reconstructPressureGradient(rc, *elem_info, component, reconstructed_quantity(component));
600 _reconstructed_pressure_gradient[component]->set(pressure_dof, reconstructed_gradient);
601 }
602 }
603
604 for (auto & pressure_gradient : _reconstructed_pressure_gradient)
605 pressure_gradient->close();
606
607 _last_reconstructed_face_flux_iteration = face_flux_iteration;
608}
609
612{
613 checkFlowSystem(rc);
615 "No reconstructed pressure-gradient candidate is ready for the conservative "
616 "cell-velocity correction.");
618}
619
620void
622 const RhieChowMassFlux & rc,
623 const GradientView & base_gradient,
624 const GradientContainer & reconstructed_candidate)
625{
626 mooseAssert(!base_gradient.empty() && reconstructed_candidate.size() == base_gradient.size(),
627 "Base and reconstructed gradients must have equal nonzero component counts.");
628
629 if (_coupling_pressure_gradient.empty())
631
632 const auto & mesh = rc.pressureSystem().feProblem().mesh();
633 const auto pressure_system_number = rc.pressureSystem().number();
634 for (const auto component : index_range(_coupling_pressure_gradient))
635 {
636 for (const auto & elem_info : mesh.elemInfoVector())
637 {
638 if (!rc.hasBlocks(elem_info->subdomain_id()))
639 continue;
640
641 const auto pressure_dof =
642 elem_info->dofIndices()[pressure_system_number][_pressure_variable_number];
643 // Under-relax feedback to the next momentum predictor:
644 // g_coupling^{k+1} = (1-alpha) g_coupling^k + alpha g_reconstructed^k.
645 const auto updated_gradient =
646 (1.0 - _gradient_relaxation) * (*_coupling_pressure_gradient[component])(pressure_dof) +
647 _gradient_relaxation * (*reconstructed_candidate[component])(pressure_dof);
648 _coupling_pressure_gradient[component]->set(pressure_dof, updated_gradient);
649 }
650 _coupling_pressure_gradient[component]->close();
651 }
652}
653
654void
registerMooseObject("NavierStokesApp", FVReconstructedPressureGradient)
bool hasBlocks(const SubdomainName &name) const
virtual const std::set< SubdomainID > & blockIDs() const
SubdomainID subdomain_id() const
const Elem * elem() const
const std::vector< std::vector< dof_id_type > > & dofIndices() const
const Point & centroid() const
virtual void addFVGradientMethod(const std::string &method_type, const std::string &name, InputParameters &parameters)
FVGradientMethod & getFVGradientMethod(const GradientMethodName &name, const THREAD_ID tid=0)
bool hasFVGradientMethod(const GradientMethodName &name) const
virtual MooseMesh & mesh() override
static InputParameters validParams()
void computeGradient(SystemBase &system, GradientContainer &gradient, const std::unordered_set< unsigned int > &variable_numbers) const
Gradient method that reconstructs and relaxes the pressure gradient used for Rhie-Chow momentum-press...
void updateCouplingPressureGradient(const RhieChowMassFlux &rc, const GradientView &base_gradient, const GradientContainer &reconstructed_candidate)
Blend a reconstructed candidate into the persistent coupling pressure gradient.
void finalizeCouplingPressureGradient(const RhieChowMassFlux &rc, const GradientView &base_gradient)
Relax and publish the current candidate as the coupling pressure gradient.
LinearFVGradientReader::GradientContainer GradientView
std::vector< std::vector< std::unique_ptr< NumericVector< Number > > > > _lagged_reconstruction_velocity_gradient
Lagged velocity gradients indexed by velocity component and spatial direction.
void resolveGradientMethodDependencies(FEProblemBase &fe_problem) override
DenseVector< Real > solveFaceProjection(const DenseMatrix< Real > &matrix, const DenseVector< Real > &projection_rhs) const
Solve a cell's velocity-projection system.
void validateSetup(const RhieChowMassFlux &rc) const
Validate the one-time Rhie-Chow linkage and field layouts required by reconstruction.
Real reconstructPressureGradient(const RhieChowMassFlux &rc, const ElemInfo &elem_info, unsigned int component, Real reconstructed_velocity) const
Invert one diagonal momentum equation to recover a pressure-gradient component.
FVReconstructedPressureGradient(const InputParameters &params)
PressureGradientReconstructionState _reconstruction_state
Current position in the pressure-gradient reconstruction cycle.
void linkFlowSystem(RhieChowMassFlux &rc, const LinearFVGradientReader &pressure_gradient)
Link this stateful method to one Rhie-Chow flow-system configuration.
void transition(PressureGradientReconstructionEvent event)
Apply and validate one reconstruction-cycle transition.
void assembleFaceProjection(const RhieChowMassFlux &rc, const ElemInfo &elem_info, const std::vector< RealVectorValue > &elem_velocity_gradients, const FaceInfo *fi, const Point &surface_vector, bool elem_has_info, DenseMatrix< Real > &matrix, DenseVector< Real > &projection_rhs) const
Add one face's contribution to the area-weighted least-squares system that reconstructs the cell velo...
const GradientMethodName _base_gradient_method_name
Gradient method used before the reconstructed coupling pressure gradient exists.
GradientContainer _reconstructed_pressure_gradient
Reconstructed pressure-gradient candidate.
dof_id_type _last_reconstructed_face_flux_iteration
Corrected face-flux iteration used by the previous reconstruction.
RealVectorValue reconstructionVelocityGradient(const RhieChowMassFlux &rc, const RealVectorValue &elem_gradient, const FaceInfo &fi, bool elem_has_info, unsigned int velocity_component) const
Interpolate a lagged velocity-component gradient to a face.
void saveLaggedVelocityGradient(RhieChowMassFlux &rc)
Save the lagged cell velocity gradient used by the reconstruction.
const GradientContainer & reconstructedCandidate(const RhieChowMassFlux &rc) const
Get the conservative candidate produced by the current pressure corrector.
void copyGradient(const GradientView &source, GradientContainer &destination)
Copy gradient values while reusing compatible destination storage.
const FVGradientMethod * _base_gradient_method
Resolved method used before the reconstructed coupling pressure gradient exists.
void computeCandidateFromCorrectedFlux(const RhieChowMassFlux &rc)
Reconstruct the conservative pressure-gradient candidate from the corrected face flux.
void checkFlowSystem(const RhieChowMassFlux &rc) const
Check that a stateful operation is requested by the bound Rhie-Chow object.
void computeGradientWithoutLimiter(SystemBase &system, GradientContainer &gradient, const std::unordered_set< unsigned int > &variable_numbers) const override
GradientContainer _coupling_pressure_gradient
Persistent coupling pressure gradient.
PressureGradientReconstructionEvent
Operations that advance or reset the pressure-gradient reconstruction cycle.
@ Reset
Reset the cycle to require a new lagged velocity-gradient snapshot.
@ ReconstructCandidate
Record that a pressure-gradient candidate has been reconstructed.
@ PublishCandidate
Record that the reconstructed candidate has been published.
@ SaveLaggedVelocityGradient
Record that the lagged velocity-gradient snapshot has been saved.
std::vector< const SystemBase * > _momentum_systems
Momentum systems coupled through the owning Rhie-Chow object.
std::vector< const LinearFVGradientReader * > _velocity_gradient_fields
Ordinary gradient fields for the velocity components.
FVGradientMethod::GradientContainer GradientContainer
const Real _gradient_relaxation
Relaxation factor applied to reconstructed pressure gradients.
const SystemBase * _pressure_system
Pressure system that owns the reconstructed pressure variable.
const RhieChowMassFlux * _rhie_chow
Rhie-Chow object that owns this stateful reconstruction method.
unsigned int _pressure_variable_number
Pressure variable reconstructed by this method.
PressureGradientReconstructionState
Current stage of the pressure-gradient reconstruction cycle.
@ CandidateReady
The reconstructed candidate is available and ready to be published.
@ NeedLaggedVelocityGradient
The next reconstruction cycle requires a lagged velocity-gradient snapshot.
@ NeedCandidate
The lagged velocity gradient is available and a reconstructed candidate is required.
void resetForTimeStep(const RhieChowMassFlux &rc)
Prepare solver-iteration state for a new time-step attempt.
VarFaceNeighbors faceType(const std::pair< unsigned int, unsigned int > &var_sys) const
const ElemInfo * elemInfo() const
const ElemInfo * neighborInfo() const
const Point & faceCentroid() const
void suppressParameter(const std::string &name)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(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 GradientContainer & components() const
const SystemBase & system() const
unsigned int variableNumber() const
static InputParameters validParams()
Factory & getFactory()
const std::string & type() const
const std::string & name() const
void mooseError(Args &&... args) const
MooseApp & getMooseApp() const
const LinearFVGradientReader & requestCellGradients(unsigned int oldest_state=0)
unsigned int number() const
User object responsible for determining the face fluxes using the Rhie-Chow interpolation in a segreg...
MooseLinearVariableFVReal & velocityVariable(unsigned int component)
Velocity variable for one spatial component.
const LinearSystem & pressureSystem() const
Pressure linear system.
Real getVolumetricFaceFlux(const FaceInfo &fi) const
Get the volumetric face flux (used in advection terms)
const std::vector< std::unique_ptr< NumericVector< Number > > > & HbyAComponents() const
Get the momentum-layout H/A component vectors.
dof_id_type faceMassFluxGeneration() const
Producer counter for the conservative face mass flux: incremented every time computeFaceMassFlux() ru...
LinearSystem & momentumSystem(unsigned int component)
Momentum linear system for one spatial component.
unsigned int pressureVariableNumber() const
Variable number of the pressure variable reconstructed by this object.
const std::vector< NumericVector< Number > * > & basePressureGradientComponents() const
Get the base-pressure gradient component vectors used to seed reconstructed updates.
const std::vector< std::unique_ptr< NumericVector< Number > > > & AinvComponents() const
Get the momentum-layout 1/A component vectors.
const LinearFVGradientReader & pressureGradientField() const
Get the registered pressure gradient field used by compatible momentum pressure kernels.
unsigned int dimension() const
Number of spatial dimensions of the coupled momentum/pressure systems.
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
unsigned int number() const
FEProblemBase & feProblem()
virtual const std::string & name() const
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
virtual void zero() override final
virtual void zero() override final
virtual unsigned int size() const override final
dof_id_type id() const
subdomain_id_type subdomain_id() const
auto norm() const
MeshBase & mesh
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
void loopOverElemFaceInfo(const Elem &elem, const MooseMesh &mesh, ActionFunctor &act, const Moose::CoordinateSystemType coord_type, const unsigned int rz_radial_coord=libMesh::invalid_uint)
StateArg oldState()
std::string stringify(const T &t)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
auto index_range(const T &sizable)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)