https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PCNSFVKT.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
10#include "PCNSFVKT.h"
11#include "NS.h"
13#include "Limiter.h"
14
15using namespace Moose::FV;
16
17registerMooseObject("NavierStokesApp", PCNSFVKT);
18
21{
23 params.addClassDescription("Computes the residual of advective term using finite volume method.");
24 params.addRequiredParam<UserObjectName>(NS::fluid, "Fluid userobject");
25 MooseEnum eqn("mass momentum energy scalar");
26 params.addRequiredParam<MooseEnum>("eqn", eqn, "The equation you're solving.");
27 MooseEnum momentum_component("x=0 y=1 z=2");
28 params.addParam<MooseEnum>("momentum_component",
29 momentum_component,
30 "The component of the momentum equation that this kernel applies to.");
31 params.addParam<MooseEnum>(
32 "limiter", moose_limiter_type, "The limiter to apply during interpolation.");
33 params.set<unsigned short>("ghost_layers") = 2;
34 params.addParam<bool>(
35 "knp_for_omega",
36 true,
37 "Whether to use the Kurganov, Noelle, and Petrova method to compute the omega parameter for "
38 "stabilization. If false, then the Kurganov-Tadmor method will be used.");
39 return params;
40}
41
43 : FVQpFluxKernel(params),
44 _fluid(getUserObject<SinglePhaseFluidProperties>(NS::fluid)),
45
46 _sup_vel_x_elem(getADMaterialProperty<Real>(NS::superficial_velocity_x)),
47 _sup_vel_x_neighbor(getNeighborADMaterialProperty<Real>(NS::superficial_velocity_x)),
48 _grad_sup_vel_x_elem(
49 getADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_x))),
50 _grad_sup_vel_x_neighbor(
51 getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_x))),
52 _sup_vel_y_elem(getADMaterialProperty<Real>(NS::superficial_velocity_y)),
53 _sup_vel_y_neighbor(getNeighborADMaterialProperty<Real>(NS::superficial_velocity_y)),
54 _grad_sup_vel_y_elem(
55 getADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_y))),
56 _grad_sup_vel_y_neighbor(
57 getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_y))),
58 _sup_vel_z_elem(getADMaterialProperty<Real>(NS::superficial_velocity_z)),
59 _sup_vel_z_neighbor(getNeighborADMaterialProperty<Real>(NS::superficial_velocity_z)),
60 _grad_sup_vel_z_elem(
61 getADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_z))),
62 _grad_sup_vel_z_neighbor(
63 getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::superficial_velocity_z))),
64
65 _T_fluid_elem(getADMaterialProperty<Real>(NS::T_fluid)),
66 _T_fluid_neighbor(getNeighborADMaterialProperty<Real>(NS::T_fluid)),
67 _grad_T_fluid_elem(getADMaterialProperty<RealVectorValue>(NS::grad(NS::T_fluid))),
68 _grad_T_fluid_neighbor(getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::T_fluid))),
69 _pressure_elem(getADMaterialProperty<Real>(NS::pressure)),
70 _pressure_neighbor(getNeighborADMaterialProperty<Real>(NS::pressure)),
71 _grad_pressure_elem(getADMaterialProperty<RealVectorValue>(NS::grad(NS::pressure))),
72 _grad_pressure_neighbor(getNeighborADMaterialProperty<RealVectorValue>(NS::grad(NS::pressure))),
73 _eps_elem(getMaterialProperty<Real>(NS::porosity)),
74 _eps_neighbor(getNeighborMaterialProperty<Real>(NS::porosity)),
75 _eqn(getParam<MooseEnum>("eqn")),
76 _index(getParam<MooseEnum>("momentum_component")),
77 _scalar_elem(_u_elem),
78 _scalar_neighbor(_u_neighbor),
79 _grad_scalar_elem((_eqn == "scalar") ? &_var.adGradSln() : nullptr),
80 _grad_scalar_neighbor((_eqn == "scalar") ? &_var.adGradSlnNeighbor() : nullptr),
81 _limiter(Limiter<ADReal>::build(LimiterType(int(getParam<MooseEnum>("limiter"))))),
82 _knp_for_omega(getParam<bool>("knp_for_omega"))
83{
84 if ((_eqn == "momentum") && !isParamValid("momentum_component"))
85 paramError("eqn",
86 "If 'momentum' is specified for 'eqn', then you must provide a parameter "
87 "value for 'momentum_component'");
88}
89
90std::pair<ADReal, ADReal>
92 const ADReal & u_neighbor_normal,
93 const ADReal & c_elem,
94 const ADReal & c_neighbor) const
95{
96 // Equations from Greenshields sans multiplication by area (which will be done in
97 // computeResidual/Jacobian
98 const auto psi_elem =
99 std::max({c_elem + u_elem_normal, c_neighbor + u_neighbor_normal, ADReal(0)});
100 const auto psi_neighbor =
101 std::max({c_elem - u_elem_normal, c_neighbor - u_neighbor_normal, ADReal(0)});
102 auto alpha = _knp_for_omega ? psi_elem / (psi_elem + psi_neighbor) : ADReal(0.5);
103 auto omega = _knp_for_omega ? alpha * (1 - alpha) * (psi_elem + psi_neighbor)
104 : alpha * std::max(psi_elem, psi_neighbor);
105
106 // Do this to avoid new nonzero mallocs
107 const auto dummy_quant = 0 * (c_elem + u_elem_normal + c_neighbor + u_neighbor_normal);
108
109 alpha += dummy_quant;
110 omega += dummy_quant;
111 return std::make_pair(std::move(alpha), std::move(omega));
112}
113
114ADReal
116 const ADReal & omega,
117 const ADReal & sup_vel_elem_normal,
118 const ADReal & sup_vel_neighbor_normal,
119 const ADReal & adv_quant_elem,
120 const ADReal & adv_quant_neighbor)
121{
122 return alpha * (sup_vel_elem_normal * adv_quant_elem) +
123 (1 - alpha) * sup_vel_neighbor_normal * adv_quant_neighbor -
124 omega * (adv_quant_neighbor - adv_quant_elem);
125}
126
127ADReal
129{
130 // Perform primitive interpolations
131 const auto pressure_elem = interpolate(*_limiter,
135 *_face_info,
136 /*elem_is_up=*/true);
137 const auto pressure_neighbor = interpolate(*_limiter,
141 *_face_info,
142 /*elem_is_up=*/false);
143 const auto T_fluid_elem = interpolate(*_limiter,
147 *_face_info,
148 /*elem_is_up=*/true);
149 const auto T_fluid_neighbor = interpolate(*_limiter,
153 *_face_info,
154 /*elem_is_up=*/false);
155 const auto sup_vel_x_elem = interpolate(*_limiter,
159 *_face_info,
160 /*elem_is_up=*/true);
161 const auto sup_vel_x_neighbor = interpolate(*_limiter,
165 *_face_info,
166 /*elem_is_up=*/false);
167 const auto sup_vel_y_elem = interpolate(*_limiter,
171 *_face_info,
172 /*elem_is_up=*/true);
173 const auto sup_vel_y_neighbor = interpolate(*_limiter,
177 *_face_info,
178 /*elem_is_up=*/false);
179 const auto sup_vel_z_elem = interpolate(*_limiter,
183 *_face_info,
184 /*elem_is_up=*/true);
185 const auto sup_vel_z_neighbor = interpolate(*_limiter,
189 *_face_info,
190 /*elem_is_up=*/false);
191
192 const auto sup_vel_elem = VectorValue<ADReal>(sup_vel_x_elem, sup_vel_y_elem, sup_vel_z_elem);
193 const auto u_elem = sup_vel_elem / _eps_elem[_qp];
194 const auto rho_elem = _fluid.rho_from_p_T(pressure_elem, T_fluid_elem);
195 const auto specific_volume_elem = 1. / rho_elem;
196 const auto e_elem = _fluid.e_from_T_v(T_fluid_elem, specific_volume_elem);
197 const auto sup_vel_neighbor =
198 VectorValue<ADReal>(sup_vel_x_neighbor, sup_vel_y_neighbor, sup_vel_z_neighbor);
199 const auto u_neighbor = sup_vel_neighbor / _eps_neighbor[_qp];
200 const auto rho_neighbor = _fluid.rho_from_p_T(pressure_neighbor, T_fluid_neighbor);
201 const auto specific_volume_neighbor = 1. / rho_neighbor;
202 const auto e_neighbor = _fluid.e_from_T_v(T_fluid_neighbor, specific_volume_neighbor);
203
204 const auto c_elem = _fluid.c_from_v_e(specific_volume_elem, e_elem);
205 const auto c_neighbor = _fluid.c_from_v_e(specific_volume_neighbor, e_neighbor);
206
207 const auto sup_vel_elem_normal = sup_vel_elem * _face_info->normal();
208 const auto sup_vel_neighbor_normal = sup_vel_neighbor * _face_info->normal();
209 const auto u_elem_normal = u_elem * _face_info->normal();
210 const auto u_neighbor_normal = u_neighbor * _face_info->normal();
211
212 const auto pr = computeAlphaAndOmega(u_elem_normal, u_neighbor_normal, c_elem, c_neighbor);
213 const auto & alpha = pr.first;
214 const auto & omega = pr.second;
215
216 if (_eqn == "mass")
217 return computeFaceFlux(
218 alpha, omega, sup_vel_elem_normal, sup_vel_neighbor_normal, rho_elem, rho_neighbor);
219 else if (_eqn == "momentum")
220 {
221 const auto rhou_elem = u_elem(_index) * rho_elem;
222 const auto rhou_neighbor = u_neighbor(_index) * rho_neighbor;
223 return computeFaceFlux(alpha,
224 omega,
225 sup_vel_elem_normal,
226 sup_vel_neighbor_normal,
227 rhou_elem,
228 rhou_neighbor) +
229 _face_info->normal()(_index) * (alpha * _eps_elem[_qp] * pressure_elem +
230 (1 - alpha) * _eps_neighbor[_qp] * pressure_neighbor);
231 }
232 else if (_eqn == "energy")
233 {
234 const auto ht_elem = e_elem + 0.5 * u_elem * u_elem + pressure_elem / rho_elem;
235 const auto ht_neighbor =
236 e_neighbor + 0.5 * u_neighbor * u_neighbor + pressure_neighbor / rho_neighbor;
237 const auto rho_ht_elem = rho_elem * ht_elem;
238 const auto rho_ht_neighbor = rho_neighbor * ht_neighbor;
239 return computeFaceFlux(
240 alpha, omega, sup_vel_elem_normal, sup_vel_neighbor_normal, rho_ht_elem, rho_ht_neighbor);
241 }
242 else if (_eqn == "scalar")
243 {
244 const auto scalar_elem = interpolate(*_limiter,
248 *_face_info,
249 true);
250 const auto scalar_neighbor = interpolate(*_limiter,
254 *_face_info,
255 false);
256 const auto rhos_elem = rho_elem * scalar_elem;
257 const auto rhos_neighbor = rho_neighbor * scalar_neighbor;
258 return computeFaceFlux(
259 alpha, omega, sup_vel_elem_normal, sup_vel_neighbor_normal, rhos_elem, rhos_neighbor);
260 }
261 else
262 mooseError("Unrecognized enum type ", _eqn);
263}
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("NavierStokesApp", PCNSFVKT)
void ErrorVector unsigned int
const FaceInfo * _face_info
const unsigned int _qp
static InputParameters validParams()
const Point & normal() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
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)
T & set(const std::string &name, bool quiet_mode=false)
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
Implements the centered Kurganov-Tadmor discretization of advective fluxes.
Definition PCNSFVKT.h:30
const MaterialProperty< Real > & _eps_elem
porosity left == elem, right == neighbor
Definition PCNSFVKT.h:81
const ADMaterialProperty< RealVectorValue > & _grad_T_fluid_elem
Definition PCNSFVKT.h:69
const ADMaterialProperty< Real > & _T_fluid_elem
fluid temperature left == elem, right == neighbor
Definition PCNSFVKT.h:67
const ADMaterialProperty< Real > & _sup_vel_y_neighbor
Definition PCNSFVKT.h:57
const ADMaterialProperty< RealVectorValue > & _grad_pressure_elem
Definition PCNSFVKT.h:76
const ADMaterialProperty< RealVectorValue > & _grad_T_fluid_neighbor
Definition PCNSFVKT.h:70
static ADReal computeFaceFlux(const ADReal &alpha, const ADReal &omega, const ADReal &sup_vel_elem_normal, const ADReal &sup_vel_neighbor_normal, const ADReal &adv_quant_elem, const ADReal &adv_quant_neighbor)
Definition PCNSFVKT.C:115
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_x_elem
Definition PCNSFVKT.h:54
const SinglePhaseFluidProperties & _fluid
fluid properties
Definition PCNSFVKT.h:49
static InputParameters validParams()
Definition PCNSFVKT.C:20
PCNSFVKT(const InputParameters &params)
Definition PCNSFVKT.C:42
const unsigned int _index
When solving the momentum equation, the momentum component we are solving for.
Definition PCNSFVKT.h:89
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_z_neighbor
Definition PCNSFVKT.h:63
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_z_elem
Definition PCNSFVKT.h:62
const ADMaterialProperty< Real > & _sup_vel_x_elem
superficial velocities left == elem, right == neighbor
Definition PCNSFVKT.h:52
const ADVariableValue & _scalar_elem
passive scalar values left == elem, right == neighbor
Definition PCNSFVKT.h:92
const ADVariableGradient *const _grad_scalar_neighbor
Definition PCNSFVKT.h:95
const ADMaterialProperty< Real > & _sup_vel_y_elem
Definition PCNSFVKT.h:56
const ADMaterialProperty< Real > & _sup_vel_z_elem
Definition PCNSFVKT.h:60
std::unique_ptr< Moose::FV::Limiter< ADReal > > _limiter
The slope limiter we will apply when interpolating from cell centroids to faces.
Definition PCNSFVKT.h:99
const ADMaterialProperty< RealVectorValue > & _grad_pressure_neighbor
Definition PCNSFVKT.h:77
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_y_elem
Definition PCNSFVKT.h:58
const bool _knp_for_omega
Whether to use the Kurganov, Noelle, and Petrova method to compute the omega parameter for stabilizat...
Definition PCNSFVKT.h:103
const ADMaterialProperty< Real > & _sup_vel_x_neighbor
Definition PCNSFVKT.h:53
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_x_neighbor
Definition PCNSFVKT.h:55
std::pair< ADReal, ADReal > computeAlphaAndOmega(const ADReal &u_elem_normal, const ADReal &u_neighbor_normal, const ADReal &c_elem, const ADReal &c_neighbor) const
Definition PCNSFVKT.C:91
const ADMaterialProperty< Real > & _pressure_elem
pressure left == elem, right == neighbor
Definition PCNSFVKT.h:74
const MaterialProperty< Real > & _eps_neighbor
Definition PCNSFVKT.h:82
virtual ADReal computeQpResidual() override
Definition PCNSFVKT.C:128
const ADMaterialProperty< Real > & _sup_vel_z_neighbor
Definition PCNSFVKT.h:61
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_y_neighbor
Definition PCNSFVKT.h:59
const MooseEnum _eqn
The equation we are solving, e.g. mass, momentum, fluid energy, or passive scalar.
Definition PCNSFVKT.h:86
const ADVariableValue & _scalar_neighbor
Definition PCNSFVKT.h:93
const ADVariableGradient *const _grad_scalar_elem
Definition PCNSFVKT.h:94
const ADMaterialProperty< Real > & _pressure_neighbor
Definition PCNSFVKT.h:75
const ADMaterialProperty< Real > & _T_fluid_neighbor
Definition PCNSFVKT.h:68
Common class for single phase fluid properties.
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
const MooseEnum moose_limiter_type
static const std::string fluid
Definition NS.h:88