https://mooseframework.inl.gov
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 
15 using namespace Moose::FV;
16 
17 registerMooseObject("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  : FVFluxKernel(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 
90 std::pair<ADReal, ADReal>
91 PCNSFVKT::computeAlphaAndOmega(const ADReal & u_elem_normal,
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 
114 ADReal
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 
127 ADReal
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,
245  _scalar_elem[_qp],
247  &(*_grad_scalar_elem)[_qp],
248  *_face_info,
249  true);
250  const auto scalar_neighbor = interpolate(*_limiter,
252  _scalar_elem[_qp],
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 }
const SinglePhaseFluidProperties & _fluid
fluid properties
Definition: PCNSFVKT.h:49
const unsigned int _index
When solving the momentum equation, the momentum component we are solving for.
Definition: PCNSFVKT.h:89
static InputParameters validParams()
Definition: PCNSFVKT.C:20
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const ADMaterialProperty< RealVectorValue > & _grad_T_fluid_elem
Definition: PCNSFVKT.h:69
const ADVariableGradient *const _grad_scalar_neighbor
Definition: PCNSFVKT.h:95
const FaceInfo * _face_info
T & set(const std::string &name, bool quiet_mode=false)
const MooseEnum _eqn
The equation we are solving, e.g. mass, momentum, fluid energy, or passive scalar.
Definition: PCNSFVKT.h:86
static const std::string fluid
Definition: NS.h:87
const ADMaterialProperty< Real > & _pressure_elem
pressure left == elem, right == neighbor
Definition: PCNSFVKT.h:74
const MaterialProperty< Real > & _eps_neighbor
Definition: PCNSFVKT.h:82
const ADMaterialProperty< Real > & _sup_vel_x_elem
superficial velocities left == elem, right == neighbor
Definition: PCNSFVKT.h:52
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_z_elem
Definition: PCNSFVKT.h:62
void addRequiredParam(const std::string &name, const std::string &doc_string)
const ADMaterialProperty< Real > & _sup_vel_y_neighbor
Definition: PCNSFVKT.h:57
bool isParamValid(const std::string &name) const
static const std::string porosity
Definition: NS.h:104
virtual ADReal computeQpResidual() override
Definition: PCNSFVKT.C:128
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 bool _knp_for_omega
Whether to use the Kurganov, Noelle, and Petrova method to compute the omega parameter for stabilizat...
Definition: PCNSFVKT.h:103
static InputParameters validParams()
const ADMaterialProperty< Real > & _sup_vel_y_elem
Definition: PCNSFVKT.h:56
const ADMaterialProperty< Real > & _sup_vel_z_neighbor
Definition: PCNSFVKT.h:61
static const std::string T_fluid
Definition: NS.h:106
registerMooseObject("NavierStokesApp", PCNSFVKT)
const ADVariableGradient *const _grad_scalar_elem
Definition: PCNSFVKT.h:94
const MooseEnum moose_limiter_type
static const std::string superficial_velocity_y
Definition: NS.h:51
const unsigned int _qp
const ADMaterialProperty< Real > & _T_fluid_neighbor
Definition: PCNSFVKT.h:68
LimiterType
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_sup_vel_y_neighbor
Definition: PCNSFVKT.h:59
Common class for single phase fluid properties.
const Point & normal() const
void paramError(const std::string &param, Args... args) const
const ADMaterialProperty< Real > & _pressure_neighbor
Definition: PCNSFVKT.h:75
std::string grad(const std::string &var)
Definition: NS.h:91
const MaterialProperty< Real > & _eps_elem
porosity left == elem, right == neighbor
Definition: PCNSFVKT.h:81
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_x_elem
Definition: PCNSFVKT.h:54
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string alpha
Definition: NS.h:134
static const std::string pressure
Definition: NS.h:56
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_x_neighbor
Definition: PCNSFVKT.h:55
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
const ADMaterialProperty< RealVectorValue > & _grad_pressure_neighbor
Definition: PCNSFVKT.h:77
const ADMaterialProperty< RealVectorValue > & _grad_pressure_elem
Definition: PCNSFVKT.h:76
Implements the centered Kurganov-Tadmor discretization of advective fluxes.
Definition: PCNSFVKT.h:29
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_z_neighbor
Definition: PCNSFVKT.h:63
const ADVariableValue & _scalar_elem
passive scalar values left == elem, right == neighbor
Definition: PCNSFVKT.h:92
const ADMaterialProperty< RealVectorValue > & _grad_T_fluid_neighbor
Definition: PCNSFVKT.h:70
const ADMaterialProperty< Real > & _T_fluid_elem
fluid temperature left == elem, right == neighbor
Definition: PCNSFVKT.h:67
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
const ADMaterialProperty< Real > & _sup_vel_z_elem
Definition: PCNSFVKT.h:60
const ADMaterialProperty< Real > & _sup_vel_x_neighbor
Definition: PCNSFVKT.h:53
const ADMaterialProperty< RealVectorValue > & _grad_sup_vel_y_elem
Definition: PCNSFVKT.h:58
void ErrorVector unsigned int
static const std::string superficial_velocity_z
Definition: NS.h:52
PCNSFVKT(const InputParameters &params)
Definition: PCNSFVKT.C:42
const ADVariableValue & _scalar_neighbor
Definition: PCNSFVKT.h:93
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
static const std::string superficial_velocity_x
Definition: NS.h:50