Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
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  // inlet c=0 established in component
159  if (c == 0)
160  {
161  const ADReal rhoA_in = _rhoA[0];
162  const ADReal rhouA_in = _rhouA[0];
163  const ADReal rhoEA_in = _rhoEA[0];
164  const ADReal e_in = THM::e_from_arhoA_arhouA_arhoEA(rhoA_in, rhouA_in, rhoEA_in);
165  const ADReal v_in = _A[0] / rhoA_in;
166  const ADReal p_in = _fp.p_from_v_e(v_in, e_in);
167  const ADReal vel_in = rhouA_in / rhoA_in;
168 
169  // static entropy is equal to stagnation entropy by definition of the stagnation state
170  const ADReal s_in = _fp.s_from_v_e(v_in, e_in);
171  const ADReal s_out = s_in;
172 
173  // isentropic: dH/m = Vdp/m
174  // h0, T0, and c0 are constant for adiabatic flows
175  const ADReal h0_in = e_in + p_in * v_in + 0.5 * vel_in * vel_in;
176  const ADReal p0_in = _fp.p_from_h_s(h0_in, s_in);
177  const ADReal rho0_in = _fp.rho_from_p_s(p0_in, s_in);
178  const ADReal v0_in = 1.0 / rho0_in;
179  const ADReal e0_in = _fp.e_from_p_rho(p0_in, rho0_in);
180  const ADReal c0_in = _fp.c_from_v_e(v0_in, e0_in);
181  const ADReal flow_A = rhouA_in * _rho0_rated * _c0_rated;
182 
183  const ADReal flow_B = _mdot_rated * rho0_in * c0_in;
184  _flow_rel_corr = flow_A / flow_B;
185  _speed_rel_corr = (_omega[0] / _omega_rated) * (_c0_rated / c0_in);
186 
187  // If _speed_rel_corr == _speeds[0], then the lower index x1 is determined to be -1
188  if (_speed_rel_corr == _speeds[0])
189  {
190  _Rp = _Rp_functions[0]->value(_flow_rel_corr, ADPoint());
191  _eff = _eff_functions[0]->value(_flow_rel_corr, ADPoint());
192  }
193  else if (std::isnan(_speed_rel_corr)) // NaN; unguarded, gives segmentation fault
194  {
195  _Rp = std::nan("");
196  _eff = std::nan("");
197  }
198  else // linear interpolation/extrapolation
199  {
200  unsigned int x1, x2;
201  if (_speed_rel_corr < _speeds[0]) // extrapolation past minimum
202  {
203  x1 = 0;
204  x2 = 1;
205  }
206  else if (_speed_rel_corr > _speeds.back()) // extrapolation past maximum
207  {
208  x1 = _n_speeds - 1;
209  x2 = x1 - 1;
210  }
211  else // interpolation
212  {
213  auto x1_iter = std::lower_bound(_speeds.begin(), _speeds.end(), _speed_rel_corr);
214  auto x2_iter = std::upper_bound(_speeds.begin(), _speeds.end(), _speed_rel_corr);
215 
216  x1 = (x1_iter - _speeds.begin()) - 1; // _speeds index for entry <= _speed_rel_corr
217  x2 = (x2_iter - _speeds.begin()); // _speeds index for entry > _speed_rel_corr
218  }
219 
220  const Real x1_spd = _speeds[x1];
221  const Real x2_spd = _speeds[x2];
222 
223  const ADReal y1_Rp = _Rp_functions[x1]->value(_flow_rel_corr, ADPoint());
224  const ADReal y2_Rp = _Rp_functions[x2]->value(_flow_rel_corr, ADPoint());
225  const ADReal Rp_m = (y2_Rp - y1_Rp) / (x2_spd - x1_spd);
226  _Rp = y1_Rp + (_speed_rel_corr - x1_spd) * Rp_m;
227 
228  const ADReal y1_eff = _eff_functions[x1]->value(_flow_rel_corr, ADPoint());
229  const ADReal y2_eff = _eff_functions[x2]->value(_flow_rel_corr, ADPoint());
230  const ADReal eff_m = (y2_eff - y1_eff) / (x2_spd - x1_spd);
231  _eff = y1_eff + (_speed_rel_corr - x1_spd) * eff_m;
232  }
233 
234  // Apply bounds
235  _Rp = std::max(_Rp_min, std::min(_Rp_max, _Rp));
236 
237  // Invert if treating as turbine
238  ADReal Rp_comp, eff_comp;
239  if (_treat_as_turbine)
240  {
241  Rp_comp = 1.0 / _Rp;
242  eff_comp = 1.0 / _eff;
243  }
244  else
245  {
246  Rp_comp = _Rp;
247  eff_comp = _eff;
248  }
249 
250  const ADReal p0_out = p0_in * Rp_comp;
251  const ADReal rho0_out_isen = _fp.rho_from_p_s(p0_out, s_out);
252 
253  const ADReal e0_out_isen = _fp.e_from_p_rho(p0_out, rho0_out_isen);
254 
255  _delta_p = p0_in * (Rp_comp - 1.0);
256 
258  {
259  _isentropic_torque = 0.0;
260  _dissipation_torque = 0.0;
261  }
262  else
263  {
264  const ADReal h0_out_isen = THM::h_from_e_p_rho(e0_out_isen, p0_out, rho0_out_isen);
265  _isentropic_torque = -(rhouA_in / _omega[0]) * (h0_out_isen - h0_in); // tau_isen
266 
267  const ADReal g_x = h0_out_isen - h0_in + h0_in * eff_comp;
268  const ADReal h0_out = g_x / eff_comp;
269 
270  _dissipation_torque = -(rhouA_in / _omega[0]) * (h0_out - h0_out_isen);
271  }
272 
273  const ADReal alpha = _omega[0] / _omega_rated;
274 
275  if (alpha < _speed_cr_I)
276  {
278  }
279  else
280  {
281  _moment_of_inertia += _inertia_coeff[0] + _inertia_coeff[1] * std::abs(alpha) +
282  _inertia_coeff[2] * alpha * alpha +
283  _inertia_coeff[3] * std::abs(alpha * alpha * alpha);
284  }
285 
286  // friction torque
287  Real sign;
288  if (_omega[0] >= 0)
289  sign = -1;
290  else
291  sign = 1;
292  if (alpha < _speed_cr_fr)
293  {
295  }
296  else
297  {
298  _friction_torque = sign * (_tau_fr_coeff[0] + _tau_fr_coeff[1] * std::abs(alpha) +
299  _tau_fr_coeff[2] * alpha * alpha +
300  _tau_fr_coeff[3] * std::abs(alpha * alpha * alpha));
301  }
302 
304 
305  // compute momentum and energy source terms
306  // a negative torque value results in a positive S_energy
307  const ADReal S_energy = -(_isentropic_torque + _dissipation_torque) * _omega[0];
308 
309  const ADRealVectorValue S_momentum = _delta_p * _A_ref * _di_out;
310 
312 
316  }
317 }
318 
319 ADReal
321 {
322  return _isentropic_torque;
323 }
324 
325 ADReal
327 {
328  return _dissipation_torque;
329 }
330 
331 ADReal
333 {
334  return _friction_torque;
335 }
336 
337 ADReal
339 {
340  return _delta_p;
341 }
342 
343 ADReal
345 {
346  return _Rp;
347 }
348 
349 ADReal
351 {
352  return _eff;
353 }
354 ADReal
356 {
357  return _flow_rel_corr;
358 }
359 ADReal
361 {
362  return _speed_rel_corr;
363 }
364 
365 void
367 {
370 
374 
378  comm().sum(_delta_p);
379  comm().sum(_Rp);
380  comm().sum(_eff);
383 }
384 
385 void
387 {
390 
391  const auto & scpuo = static_cast<const ADShaftConnectedCompressor1PhaseUserObject &>(uo);
392  _isentropic_torque += scpuo._isentropic_torque;
393  _dissipation_torque += scpuo._dissipation_torque;
394  _friction_torque += scpuo._friction_torque;
395  _delta_p += scpuo._delta_p;
396  _Rp += scpuo._Rp;
397  _eff += scpuo._eff;
398  _flow_rel_corr += scpuo._flow_rel_corr;
399  _speed_rel_corr += scpuo._speed_rel_corr;
400 }
const ADVariableValue & _rhoA
rho*A of the connected flow channels
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?
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
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
virtual const std::string & name() const
std::vector< const Function * > _eff_functions
Adiabatic efficiency functions.
void addRequiredParam(const std::string &name, const std::string &doc_string)
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
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.
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.