https://mooseframework.inl.gov
ADShaftConnectedCompressor1PhaseUserObject.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 "VolumeJunction1Phase.h"
13 #include "MooseVariableScalar.h"
14 #include "THMIndicesVACE.h"
15 #include "Function.h"
16 #include "Numerics.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 {
29 
30  params.addParam<BoundaryName>("inlet", "Compressor inlet");
31  params.addParam<BoundaryName>("outlet", "Compressor outlet");
32  params.addRequiredParam<Point>("di_out", "Direction of connected outlet");
33  params.addRequiredParam<bool>("treat_as_turbine", "Treat the compressor as a turbine?");
34  params.addRequiredParam<Real>("omega_rated", "Rated compressor speed [rad/s]");
35  params.addRequiredParam<Real>("mdot_rated", "Rated compressor mass flow rate [kg/s]");
36  params.addRequiredParam<Real>("rho0_rated",
37  "Rated compressor inlet stagnation fluid density [kg/m^3]");
38  params.addRequiredParam<Real>("c0_rated", "Rated compressor inlet stagnation sound speed [m/s]");
39  params.addRequiredParam<Real>("speed_cr_fr", "Compressor speed threshold for friction [-]");
40  params.addRequiredParam<Real>("tau_fr_const", "Compressor friction constant [N-m]");
41  params.addRequiredParam<std::vector<Real>>("tau_fr_coeff", "Friction coefficients [N-m]");
42  params.addRequiredParam<Real>("speed_cr_I", "Compressor speed threshold for inertia [-]");
43  params.addRequiredParam<Real>("inertia_const", "Compressor inertia constant [kg-m^2]");
44  params.addRequiredParam<std::vector<Real>>("inertia_coeff",
45  "Compressor inertia coefficients [kg-m^2]");
46  params.addRequiredParam<std::vector<Real>>(
47  "speeds",
48  "Relative corrected speeds. Order of speeds needs correspond to the "
49  "orders of `Rp_functions` and `eff_functions` [-]");
50  params.addRequiredParam<std::vector<FunctionName>>(
51  "Rp_functions",
52  "Functions of pressure ratio versus relative corrected flow. Each function is for a "
53  "different, constant relative corrected speed. The order of function names should correspond "
54  "to the order of speeds in the `speeds` parameter [-]");
55  params.addRequiredParam<std::vector<FunctionName>>(
56  "eff_functions",
57  "Functions of adiabatic efficiency versus relative corrected flow. Each function is for a "
58  "different, constant relative corrected speed. The order of function names should correspond "
59  "to the order of speeds in the `speeds` parameter [-]");
60  params.addRequiredParam<Real>("min_pressure_ratio", "Minimum pressure ratio");
61  params.addRequiredParam<Real>("max_pressure_ratio", "Maximum pressure ratio");
62  params.addRequiredParam<std::string>("compressor_name",
63  "Name of the instance of this compressor component");
64  params.addRequiredCoupledVar("omega", "Shaft rotational speed [rad/s]");
65 
66  params.addClassDescription("Computes and caches flux and residual vectors for a 1-phase "
67  "compressor. Also computes compressor torque "
68  "and delta_p which is passed to the connected shaft");
69 
70  return params;
71 }
72 
74  const InputParameters & params)
77 
78  _di_out(getParam<Point>("di_out")),
79  _treat_as_turbine(getParam<bool>("treat_as_turbine")),
80  _omega_rated(getParam<Real>("omega_rated")),
81  _mdot_rated(getParam<Real>("mdot_rated")),
82  _rho0_rated(getParam<Real>("rho0_rated")),
83  _c0_rated(getParam<Real>("c0_rated")),
84  _speed_cr_fr(getParam<Real>("speed_cr_fr")),
85  _tau_fr_const(getParam<Real>("tau_fr_const")),
86  _tau_fr_coeff(getParam<std::vector<Real>>("tau_fr_coeff")),
87  _speed_cr_I(getParam<Real>("speed_cr_I")),
88  _inertia_const(getParam<Real>("inertia_const")),
89  _inertia_coeff(getParam<std::vector<Real>>("inertia_coeff")),
90  _speeds(getParam<std::vector<Real>>("speeds")),
91  _Rp_function_names(getParam<std::vector<FunctionName>>("Rp_functions")),
92  _eff_function_names(getParam<std::vector<FunctionName>>("eff_functions")),
93  _n_speeds(_speeds.size()),
94  _Rp_functions(_n_speeds),
95  _eff_functions(_n_speeds),
96  _Rp_min(getParam<Real>("min_pressure_ratio")),
97  _Rp_max(getParam<Real>("max_pressure_ratio")),
98  _compressor_name(getParam<std::string>("compressor_name")),
99  _omega(adCoupledScalarValue("omega"))
100 {
101  if (_n_speeds != _Rp_function_names.size() || _n_speeds != _eff_function_names.size())
102  mooseError("The number of entries of speeds needs to equal the number of entries of "
103  "Rp_functions and eff_functions");
104 
105  // Store functions and check to make sure there is no self-reference.
106  for (unsigned int i = 0; i < _n_speeds; i++)
107  {
108  if (_Rp_function_names[i] == name() || _eff_function_names[i] == name())
109  mooseError(name(), ": This function cannot use its own name in the 'functions' parameter.");
110 
113  }
114 }
115 
116 void
118 {
120 
123 }
124 
125 void
127 {
130 
131  _isentropic_torque = 0;
133  _friction_torque = 0;
134  _delta_p = 0;
135  _Rp = 0;
136  _eff = 0;
137  _flow_rel_corr = 0;
138  _speed_rel_corr = 0;
139 }
140 
141 void
143 {
147 
148  const unsigned int c = getBoundaryIDIndex();
149 
151 }
152 
153 void
155 {
157 
158  using std::isinf, std::min, std::max, std::abs, std::isnan;
159 
160  // inlet c=0 established in component
161  if (c == 0)
162  {
163  const ADReal rhoA_in = _rhoA[0];
164  const ADReal rhouA_in = _rhouA[0];
165  const ADReal rhoEA_in = _rhoEA[0];
166  const ADReal e_in = THM::e_from_arhoA_arhouA_arhoEA(rhoA_in, rhouA_in, rhoEA_in);
167  const ADReal v_in = _A[0] / rhoA_in;
168  const ADReal p_in = _fp.p_from_v_e(v_in, e_in);
169  const ADReal vel_in = rhouA_in / rhoA_in;
170 
171  // static entropy is equal to stagnation entropy by definition of the stagnation state
172  const ADReal s_in = _fp.s_from_v_e(v_in, e_in);
173  const ADReal s_out = s_in;
174 
175  // isentropic: dH/m = Vdp/m
176  // h0, T0, and c0 are constant for adiabatic flows
177  const ADReal h0_in = e_in + p_in * v_in + 0.5 * vel_in * vel_in;
178  const ADReal p0_in = _fp.p_from_h_s(h0_in, s_in);
179  const ADReal rho0_in = _fp.rho_from_p_s(p0_in, s_in);
180  const ADReal v0_in = 1.0 / rho0_in;
181  const ADReal e0_in = _fp.e_from_p_rho(p0_in, rho0_in);
182  const ADReal c0_in = _fp.c_from_v_e(v0_in, e0_in);
183  const ADReal flow_A = rhouA_in * _rho0_rated * _c0_rated;
184 
185  const ADReal flow_B = _mdot_rated * rho0_in * c0_in;
186  _flow_rel_corr = flow_A / flow_B;
187  _speed_rel_corr = (_omega[0] / _omega_rated) * (_c0_rated / c0_in);
188 
189  // If _speed_rel_corr == _speeds[0], then the lower index x1 is determined to be -1
190  if (_speed_rel_corr == _speeds[0])
191  {
192  _Rp = _Rp_functions[0]->value(_flow_rel_corr, ADPoint());
193  _eff = _eff_functions[0]->value(_flow_rel_corr, ADPoint());
194  }
195  else if (isnan(_speed_rel_corr)) // NaN; unguarded, gives segmentation fault
196  {
197  _Rp = std::nan("");
198  _eff = std::nan("");
199  }
200  else // linear interpolation/extrapolation
201  {
202  unsigned int x1, x2;
203  if (_speed_rel_corr < _speeds[0]) // extrapolation past minimum
204  {
205  x1 = 0;
206  x2 = 1;
207  }
208  else if (_speed_rel_corr > _speeds.back()) // extrapolation past maximum
209  {
210  x1 = _n_speeds - 1;
211  x2 = x1 - 1;
212  }
213  else // interpolation
214  {
215  auto x1_iter = std::lower_bound(_speeds.begin(), _speeds.end(), _speed_rel_corr);
216  auto x2_iter = std::upper_bound(_speeds.begin(), _speeds.end(), _speed_rel_corr);
217 
218  x1 = (x1_iter - _speeds.begin()) - 1; // _speeds index for entry <= _speed_rel_corr
219  x2 = (x2_iter - _speeds.begin()); // _speeds index for entry > _speed_rel_corr
220  }
221 
222  const Real x1_spd = _speeds[x1];
223  const Real x2_spd = _speeds[x2];
224 
225  const ADReal y1_Rp = _Rp_functions[x1]->value(_flow_rel_corr, ADPoint());
226  const ADReal y2_Rp = _Rp_functions[x2]->value(_flow_rel_corr, ADPoint());
227  const ADReal Rp_m = (y2_Rp - y1_Rp) / (x2_spd - x1_spd);
228  _Rp = y1_Rp + (_speed_rel_corr - x1_spd) * Rp_m;
229 
230  const ADReal y1_eff = _eff_functions[x1]->value(_flow_rel_corr, ADPoint());
231  const ADReal y2_eff = _eff_functions[x2]->value(_flow_rel_corr, ADPoint());
232  const ADReal eff_m = (y2_eff - y1_eff) / (x2_spd - x1_spd);
233  _eff = y1_eff + (_speed_rel_corr - x1_spd) * eff_m;
234  }
235 
236  // Apply bounds
237  _Rp = max(_Rp_min, min(_Rp_max, _Rp));
238 
239  // Invert if treating as turbine
240  ADReal Rp_comp, eff_comp;
241  if (_treat_as_turbine)
242  {
243  Rp_comp = 1.0 / _Rp;
244  eff_comp = 1.0 / _eff;
245  }
246  else
247  {
248  Rp_comp = _Rp;
249  eff_comp = _eff;
250  }
251 
252  const ADReal p0_out = p0_in * Rp_comp;
253  const ADReal rho0_out_isen = _fp.rho_from_p_s(p0_out, s_out);
254 
255  const ADReal e0_out_isen = _fp.e_from_p_rho(p0_out, rho0_out_isen);
256 
257  _delta_p = p0_in * (Rp_comp - 1.0);
258 
259  if (MooseUtils::absoluteFuzzyEqual(_omega[0], 0.0))
260  {
261  _isentropic_torque = 0.0;
262  _dissipation_torque = 0.0;
263  }
264  else
265  {
266  const ADReal h0_out_isen = THM::h_from_e_p_rho(e0_out_isen, p0_out, rho0_out_isen);
267  _isentropic_torque = -(rhouA_in / _omega[0]) * (h0_out_isen - h0_in); // tau_isen
268 
269  const ADReal g_x = h0_out_isen - h0_in + h0_in * eff_comp;
270  const ADReal h0_out = g_x / eff_comp;
271 
272  _dissipation_torque = -(rhouA_in / _omega[0]) * (h0_out - h0_out_isen);
273  }
274 
275  const ADReal alpha = _omega[0] / _omega_rated;
276 
277  if (alpha < _speed_cr_I)
278  {
280  }
281  else
282  {
284  _inertia_coeff[2] * alpha * alpha +
285  _inertia_coeff[3] * abs(alpha * alpha * alpha);
286  }
287 
288  // friction torque
289  Real sign;
290  if (_omega[0] >= 0)
291  sign = -1;
292  else
293  sign = 1;
294  if (alpha < _speed_cr_fr)
295  {
297  }
298  else
299  {
301  sign * (_tau_fr_coeff[0] + _tau_fr_coeff[1] * abs(alpha) +
303  }
304 
306 
307  // compute momentum and energy source terms
308  // a negative torque value results in a positive S_energy
309  const ADReal S_energy = -(_isentropic_torque + _dissipation_torque) * _omega[0];
310 
311  const ADRealVectorValue S_momentum = _delta_p * _A_ref * _di_out;
312 
314 
318  }
319 }
320 
321 ADReal
323 {
324  return _isentropic_torque;
325 }
326 
327 ADReal
329 {
330  return _dissipation_torque;
331 }
332 
333 ADReal
335 {
336  return _friction_torque;
337 }
338 
339 ADReal
341 {
342  return _delta_p;
343 }
344 
345 ADReal
347 {
348  return _Rp;
349 }
350 
351 ADReal
353 {
354  return _eff;
355 }
356 ADReal
358 {
359  return _flow_rel_corr;
360 }
361 ADReal
363 {
364  return _speed_rel_corr;
365 }
366 
367 void
369 {
372 
376 
380  comm().sum(_delta_p);
381  comm().sum(_Rp);
382  comm().sum(_eff);
385 }
386 
387 void
389 {
392 
393  const auto & scpuo = static_cast<const ADShaftConnectedCompressor1PhaseUserObject &>(uo);
394  _isentropic_torque += scpuo._isentropic_torque;
395  _dissipation_torque += scpuo._dissipation_torque;
396  _friction_torque += scpuo._friction_torque;
397  _delta_p += scpuo._delta_p;
398  _Rp += scpuo._Rp;
399  _eff += scpuo._eff;
400  _flow_rel_corr += scpuo._flow_rel_corr;
401  _speed_rel_corr += scpuo._speed_rel_corr;
402 }
const ADVariableValue & _rhoA
rho*A of the connected flow channels
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
const std::vector< Real > & _speeds
Compressor speeds which correspond to Rp and eff function order.
std::vector< std::vector< dof_id_type > > _flow_channel_dofs
Degrees of freedom for flow channel variables, for each connection.
void e_from_arhoA_arhouA_arhoEA(Real arhoA, Real arhouA, Real arhoEA, Real &e, Real &de_darhoA, Real &de_darhouA, Real &de_darhoEA)
Computes specific internal energy and its derivatives from alpha*rho*A, alpha*rho*u*A, and alpha*rho*E*A.
Definition: Numerics.C:147
const bool _treat_as_turbine
Treat the compressor as a turbine?
std::vector< const Function * > _Rp_functions
Pressure ratio functions.
ADReal getDissipationTorque() const
Dissipation torque computed in the 1-phase shaft-connected compressor.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
unsigned int getBoundaryIDIndex()
Gets the index of the currently executing boundary within the vector of boundary IDs given to this Si...
const Real & _c0_rated
Rated compressor inlet stagnation sound speed.
const SinglePhaseFluidProperties & _fp
Single-phase fluid properties user object.
const std::vector< FunctionName > & _eff_function_names
Names of the adiabatic efficiency functions.
const std::vector< FunctionName > & _Rp_function_names
Names of the pressure ratio functions.
const Parallel::Communicator & comm() const
virtual void computeFluxesAndResiduals(const unsigned int &c) override
Computes and stores the fluxes, the scalar residuals, and their Jacobians.
unsigned int _n_flux_eq
Number of flow channel flux components.
registerMooseObject("ThermalHydraulicsApp", ADShaftConnectedCompressor1PhaseUserObject)
const unsigned int _n_connections
Number of connected flow channels.
DualNumber< Real, DNDerivativeType, true > ADReal
std::vector< const Function * > _eff_functions
Adiabatic efficiency functions.
void addRequiredParam(const std::string &name, const std::string &doc_string)
auto max(const L &left, const R &right)
std::vector< ADReal > _residual
Cached scalar residual vector.
virtual void setOmegaDofs(const MooseVariableScalar *omega_var)
ADReal getFrictionTorque() const
Friction torque computed in the 1-phase shaft-connected compressor.
const std::vector< Real > & _inertia_coeff
Compressor inertia coefficients.
virtual void threadJoin(const UserObject &uo) override
const std::string & name() const
ADReal getIsentropicTorque() const
Isentropic torque computed in the 1-phase shaft-connected compressor.
virtual void storeConnectionData()
Stores data (connection index, face shape functions, DoFs associated with flow channel variables) rel...
T sign(T x)
const std::vector< Real > & _tau_fr_coeff
Compressor friction coefficients.
const ADVariableValue & _rhoEA
rho*E*A of the connected flow channels
const MooseVariableScalar * getScalarVar(const std::string &var_name, unsigned int comp) const
virtual void setupJunctionData(std::vector< dof_id_type > &scalar_dofs)
Stores data associated with a junction component.
ADReal getRelativeCorrectedSpeed() const
Gets the elative corrected shaft speed.
Computes and caches flux and residual vectors for a 1-phase volume junction.
const Real & _speed_cr_I
Compressor speed threshold for inertia.
ADReal getRelativeCorrectedMassFlowRate() const
Gets the relative corrected mass flow rate.
const Real & _rho0_rated
Rated compressor inlet stagnation fluid density.
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
std::vector< dof_id_type > _scalar_dofs
Degrees of freedom for scalar variables.
Interface class for user objects that are connected to a shaft.
const ADVariableValue & _A
Cross-sectional area of connected flow channels.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void setConnectionData(const std::vector< std::vector< dof_id_type >> &flow_channel_dofs)
Stores data computed by a volume-junction-like object associated with the conection.
const Function & getFunctionByName(const FunctionName &name) const
static const std::string alpha
Definition: NS.h:134
const Real & _mdot_rated
Rated compressor mass flow rate.
Computes and caches flux and residual vectors for a 1-phase compressor.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
ADReal getCompressorDeltaP() const
Compressor head computed in the 1-phase shaft-connected compressor.
virtual void setupConnections(unsigned int n_connections, unsigned int n_flow_eq)
void h_from_e_p_rho(Real e, Real p, Real rho, Real &h, Real &dh_de, Real &dh_dp, Real &dh_drho)
Computes specific enthalpy and its derivatives from specific internal energy, pressure, and density.
Definition: Numerics.C:220
const Real & _speed_cr_fr
Compressor speed threshold for friction.
auto min(const L &left, const R &right)
const ADVariableValue & _rhouA
rho*u*A of the connected flow channels
virtual void computeFluxesAndResiduals(const unsigned int &c) override
Computes and stores the fluxes, the scalar residuals, and their Jacobians.