https://mooseframework.inl.gov
ADVolumeJunction1PhaseUserObject.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 
12 #include "THMIndicesVACE.h"
13 #include "VolumeJunction1Phase.h"
15 #include "Numerics.h"
16 #include "THMUtils.h"
17 #include "metaphysicl/parallel_numberarray.h"
18 #include "metaphysicl/parallel_dualnumber.h"
19 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h"
20 #include "libmesh/parallel_algebra.h"
21 
23 
26 {
28 
29  params.addRequiredCoupledVar("A", "Cross-sectional area of connected flow channels");
30  params.addRequiredCoupledVar("rhoA", "rho*A of the connected flow channels");
31  params.addRequiredCoupledVar("rhouA", "rhou*A of the connected flow channels");
32  params.addRequiredCoupledVar("rhoEA", "rhoE*A of the connected flow channels");
33 
34  params.addRequiredCoupledVar("rhoV", "rho*V of the junction");
35  params.addRequiredCoupledVar("rhouV", "rho*u*V of the junction");
36  params.addRequiredCoupledVar("rhovV", "rho*v*V of the junction");
37  params.addRequiredCoupledVar("rhowV", "rho*w*V of the junction");
38  params.addRequiredCoupledVar("rhoEV", "rho*E*V of the junction");
39 
40  params.addRequiredParam<UserObjectName>("fp", "Fluid properties user object name");
41 
42  params.addRequiredParam<Real>("K", "Form loss coefficient [-]");
43  params.addRequiredParam<Real>("A_ref", "Reference area [m^2]");
44 
45  params.addParam<bool>("apply_velocity_scaling",
46  false,
47  "Set to true to apply the scaling to the normal velocity. See "
48  "documentation for more information.");
49 
50  params.addClassDescription(
51  "Computes and caches flux and residual vectors for a 1-phase volume junction");
52 
53  params.declareControllable("K");
54  return params;
55 }
56 
59 
60  _A(adCoupledValue("A")),
61  _rhoA(adCoupledValue("rhoA")),
62  _rhouA(adCoupledValue("rhouA")),
63  _rhoEA(adCoupledValue("rhoEA")),
64 
65  _K(getParam<Real>("K")),
66  _A_ref(getParam<Real>("A_ref")),
67 
68  _apply_velocity_scaling(getParam<bool>("apply_velocity_scaling")),
69 
70  _fp(getUserObject<SinglePhaseFluidProperties>("fp"))
71 {
76 
83 
90 
92  for (std::size_t i = 0; i < _n_connections; i++)
93  _numerical_flux_uo[i] = &getUserObjectByName<ADNumericalFlux3EqnBase>(_numerical_flux_names[i]);
94 }
95 
96 void
98 {
99  const Real din = _normal[c];
100  const RealVectorValue di = _dir[0];
101  const RealVectorValue ni = di * din;
102  const RealVectorValue nJi = -ni;
103  const Real nJi_dot_di = -din;
104 
105  RealVectorValue t1, t2;
107 
108  std::vector<ADReal> Ui(THMVACE3D::N_FLUX_INPUTS, 0.);
109  Ui[THMVACE3D::RHOA] = _rhoA[0];
110  Ui[THMVACE3D::RHOUA] = _rhouA[0] * di(0);
111  Ui[THMVACE3D::RHOVA] = _rhouA[0] * di(1);
112  Ui[THMVACE3D::RHOWA] = _rhouA[0] * di(2);
113  Ui[THMVACE3D::RHOEA] = _rhoEA[0];
114  Ui[THMVACE3D::AREA] = _A[0];
115 
121 
122  const ADReal rhoJ = rhoV / _volume;
123  const ADReal vJ = 1.0 / rhoJ;
124  const ADRealVectorValue uvecJ(rhouV / rhoV, rhovV / rhoV, rhowV / rhoV);
125  const ADReal eJ = rhoEV / rhoV - 0.5 * uvecJ * uvecJ;
126  const ADReal pJ = _fp.p_from_v_e(vJ, eJ);
127 
128  std::vector<ADReal> UJi(THMVACE3D::N_FLUX_INPUTS, 0.);
129  UJi[THMVACE3D::RHOA] = rhoV / _volume * _A[0];
131  {
132  const ADReal unJ = uvecJ * nJi;
133  const ADReal ut1J = uvecJ * t1;
134  const ADReal ut2J = uvecJ * t2;
135  const ADReal uni = _rhouA[0] / _rhoA[0] * nJi_dot_di;
136 
137  const ADReal rhoi = _rhoA[0] / _A[0];
138  const ADReal vi = 1.0 / rhoi;
139  const ADReal ei = _rhoEA[0] / _rhoA[0] - 0.5 * uni * uni;
140  const ADReal ci = _fp.c_from_v_e(vi, ei);
141  const ADReal cJ = _fp.c_from_v_e(vJ, eJ);
142  const ADReal cmax = std::max(ci, cJ);
143 
144  const ADReal uni_sign = (uni > 0) - (uni < 0);
145  const ADReal factor = 0.5 * (1.0 - uni_sign) * std::min(std::abs(uni - unJ) / cmax, 1.0);
146 
147  const ADReal unJ_mod = uni - factor * (uni - unJ);
148  const ADRealVectorValue uvecJ_mod = unJ_mod * nJi + ut1J * t1 + ut2J * t2;
149  const ADReal EJ_mod = eJ + 0.5 * uvecJ_mod * uvecJ_mod;
150 
151  UJi[THMVACE3D::RHOUA] = rhoJ * uvecJ_mod(0) * _A[0];
152  UJi[THMVACE3D::RHOVA] = rhoJ * uvecJ_mod(1) * _A[0];
153  UJi[THMVACE3D::RHOWA] = rhoJ * uvecJ_mod(2) * _A[0];
154  UJi[THMVACE3D::RHOEA] = rhoJ * EJ_mod * _A[0];
155  }
156  else
157  {
158  UJi[THMVACE3D::RHOUA] = rhouV / _volume * _A[0];
159  UJi[THMVACE3D::RHOVA] = rhovV / _volume * _A[0];
160  UJi[THMVACE3D::RHOWA] = rhowV / _volume * _A[0];
161  UJi[THMVACE3D::RHOEA] = rhoEV / _volume * _A[0];
162  }
163  UJi[THMVACE3D::AREA] = _A[0];
164 
165  const auto flux_3d =
166  _numerical_flux_uo[c]->getFlux3D(_current_side, _current_elem->id(), UJi, Ui, nJi, t1, t2);
167 
169  _flux[c][THMVACE1D::MASS] = flux_3d[THMVACE3D::MASS] * nJi_dot_di;
171  _flux[c][THMVACE1D::ENERGY] = flux_3d[THMVACE3D::ENERGY] * nJi_dot_di;
172 
173  if (c == 0 && std::abs(_K) > 1e-10)
174  {
175  const ADReal vel_in = _rhouA[0] / _rhoA[0];
176  const ADReal v_in = THM::v_from_rhoA_A(_rhoA[0], _A[0]);
177  const ADReal rhouA2 = _rhouA[0] * _rhouA[0];
178  const ADReal e_in = _rhoEA[0] / _rhoA[0] - 0.5 * rhouA2 / (_rhoA[0] * _rhoA[0]);
179  const ADReal p_in = _fp.p_from_v_e(v_in, e_in);
180  const ADReal s0_in = _fp.s_from_v_e(v_in, e_in);
181  const ADReal T_in = _fp.T_from_v_e(v_in, e_in);
182  const ADReal h_in = _fp.h_from_p_T(p_in, T_in);
183  const ADReal velin2 = vel_in * vel_in;
184  const ADReal h0_in = h_in + 0.5 * velin2;
185  const ADReal p0_in = _fp.p_from_h_s(h0_in, s0_in);
186  ADReal S_loss;
187  if (_A_ref == 0)
188  S_loss = _K * (p0_in - p_in) * _A[0];
189  else
190  S_loss = _K * (p0_in - p_in) * _A_ref;
191  if (THM::isInlet(vel_in, _normal[c]))
192  {
193  _residual[VolumeJunction1Phase::RHOUV_INDEX] -= ni(0) * S_loss;
194  _residual[VolumeJunction1Phase::RHOVV_INDEX] -= ni(1) * S_loss;
195  _residual[VolumeJunction1Phase::RHOWV_INDEX] -= ni(2) * S_loss;
196  }
197  else
198  {
199  _residual[VolumeJunction1Phase::RHOUV_INDEX] += ni(0) * S_loss;
200  _residual[VolumeJunction1Phase::RHOVV_INDEX] += ni(1) * S_loss;
201  _residual[VolumeJunction1Phase::RHOWV_INDEX] += ni(2) * S_loss;
202  }
203  _residual[VolumeJunction1Phase::RHOEV_INDEX] += S_loss * std::abs(vel_in);
204  }
205 
206  const ADRealVectorValue flux_mom_n = flux_3d[THMVACE3D::MOM_NORM] * nJi +
207  flux_3d[THMVACE3D::MOM_TAN1] * t1 +
208  flux_3d[THMVACE3D::MOM_TAN2] * t2;
209  const RealVectorValue ex(1, 0, 0);
210  const RealVectorValue ey(0, 1, 0);
211  const RealVectorValue ez(0, 0, 1);
212 
214  _residual[VolumeJunction1Phase::RHOUV_INDEX] -= -flux_mom_n * ex - pJ * ni(0) * _A[0];
215  _residual[VolumeJunction1Phase::RHOVV_INDEX] -= -flux_mom_n * ey - pJ * ni(1) * _A[0];
216  _residual[VolumeJunction1Phase::RHOWV_INDEX] -= -flux_mom_n * ez - pJ * ni(2) * _A[0];
218 }
219 
220 void
222 {
224  for (unsigned int i = 0; i < _n_scalar_eq; i++)
225  comm().sum(_residual[i]);
226 }
const ADVariableValue & _rhoA
rho*A of the connected flow channels
std::vector< std::vector< ADReal > > _flux
Cached flux vector for each connection.
const unsigned int & _current_side
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void v_from_rhoA_A(Real rhoA, Real A, Real &v, Real &dv_drhoA)
Computes specific volume and its derivatives from rho*A, and area.
Definition: Numerics.C:100
std::vector< std::string > _scalar_variable_names
Vector of coupled variable names for each scalar variable.
const SinglePhaseFluidProperties & _fp
Single-phase fluid properties user object.
const Parallel::Communicator & comm() const
virtual void finalize() override
virtual void computeFluxesAndResiduals(const unsigned int &c) override
Computes and stores the fluxes, the scalar residuals, and their Jacobians.
unsigned int _n_scalar_eq
Number of scalar residual components.
const unsigned int _n_connections
Number of connected flow channels.
const std::vector< UserObjectName > & _numerical_flux_names
Names of numerical flux user objects for each connected flow channel.
void addRequiredParam(const std::string &name, const std::string &doc_string)
std::vector< ADReal > _residual
Cached scalar residual vector.
const Real & _volume
Volume of the junction.
std::vector< const ADNumericalFlux3EqnBase * > _numerical_flux_uo
Vector of numerical flux user objects for each connected flow channel.
std::vector< const ADVariableValue * > _junction_var_values
ADVolumeJunction1PhaseUserObject(const InputParameters &params)
std::vector< std::string > _flow_variable_names
Vector of coupled variable names for each flow variable.
const MaterialProperty< RealVectorValue > & _dir
Direction of the element connected to the junction.
static const unsigned int N_EQ
Number of equations for the junction.
const ADVariableValue & _rhoEA
rho*E*A of the connected flow channels
Common class for single phase fluid properties.
Base class for computing and caching flux and residual vectors for a volume junction.
Computes and caches flux and residual vectors for a 1-phase volume junction.
const Real & _K
Form loss coefficient.
static const unsigned int N_FLUX_OUTPUTS
Number of numerical flux function outputs for 1D.
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void computeOrthogonalDirections(const RealVectorValue &n_unnormalized, RealVectorValue &t1, RealVectorValue &t2)
Computes two unit vectors orthogonal to the given vector.
Definition: THMUtils.C:22
const ADVariableValue & _A
Cross-sectional area of connected flow channels.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool isInlet(Real vel, Real normal)
Determine if inlet boundary condition should be applied.
Definition: Numerics.C:235
void addClassDescription(const std::string &doc_string)
const std::vector< Real > & _normal
Flow channel outward normals or junction inward normals.
registerMooseObject("ThermalHydraulicsApp", ADVolumeJunction1PhaseUserObject)
const Elem *const & _current_elem
const bool _apply_velocity_scaling
Apply velocity scaling?
const ADVariableValue & _rhouA
rho*u*A of the connected flow channels
void declareControllable(const std::string &name, std::set< ExecFlagType > execute_flags={})
const ADVariableValue & coupledJunctionValue(const std::string &var_name, unsigned int i=0) const
Gets an AD junction variable value.
static const unsigned int N_FLUX_INPUTS
Number of numerical flux function inputs for 3D.