Line data Source code
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 "ADShaftConnectedPump1PhaseUserObject.h"
11 : #include "VolumeJunction1Phase.h"
12 : #include "MooseVariableScalar.h"
13 : #include "THMIndicesVACE.h"
14 : #include "Function.h"
15 : #include "metaphysicl/parallel_numberarray.h"
16 : #include "metaphysicl/parallel_dualnumber.h"
17 : #include "metaphysicl/parallel_semidynamicsparsenumberarray.h"
18 : #include "libmesh/parallel_algebra.h"
19 :
20 : registerMooseObject("ThermalHydraulicsApp", ADShaftConnectedPump1PhaseUserObject);
21 :
22 : InputParameters
23 92 : ADShaftConnectedPump1PhaseUserObject::validParams()
24 : {
25 92 : InputParameters params = ADVolumeJunction1PhaseUserObject::validParams();
26 92 : params += ADShaftConnectableUserObjectInterface::validParams();
27 :
28 184 : params.addParam<BoundaryName>("inlet", "Pump inlet");
29 184 : params.addParam<BoundaryName>("outlet", "Pump outlet");
30 184 : params.addRequiredParam<Point>("di_out", "Direction of connected outlet");
31 184 : params.addRequiredParam<Real>("gravity_magnitude", "Gravity constant, [m/s^2]");
32 184 : params.addRequiredParam<Real>("omega_rated", "Rated pump speed [rad/s]");
33 184 : params.addRequiredParam<Real>("volumetric_rated", "Rated pump volumetric flow rate [m^3/s]");
34 184 : params.addRequiredParam<Real>("head_rated", "Rated pump head [m]");
35 184 : params.addRequiredParam<Real>("torque_rated", "Rated pump torque [N-m]");
36 184 : params.addRequiredParam<Real>("density_rated", "Rated pump fluid density [kg/m^3]");
37 184 : params.addRequiredParam<Real>("speed_cr_fr", "Pump speed threshold for friction [-]");
38 184 : params.addRequiredParam<Real>("tau_fr_const", "Pump friction constant [N-m]");
39 184 : params.addRequiredParam<std::vector<Real>>("tau_fr_coeff", "Friction coefficients [N-m]");
40 184 : params.addRequiredParam<Real>("speed_cr_I", "Pump speed threshold for inertia [-]");
41 184 : params.addRequiredParam<Real>("inertia_const", "Pump inertia constant [kg-m^2]");
42 184 : params.addRequiredParam<std::vector<Real>>("inertia_coeff", "Pump inertia coefficients [kg-m^2]");
43 184 : params.addRequiredParam<FunctionName>("head", "Function to compute data for pump head [-]");
44 184 : params.addRequiredParam<FunctionName>("torque_hydraulic",
45 : "Function to compute data for pump torque [-]");
46 184 : params.addRequiredParam<std::string>("pump_name", "Name of the instance of this pump component");
47 184 : params.addParam<Real>(
48 : "transition_width",
49 184 : 1e-3,
50 : "Transition width for sign of the frictional torque at 0 speed over rated speed ratio.");
51 184 : params.addRequiredCoupledVar("omega", "Shaft rotational speed [rad/s]");
52 :
53 92 : params.addClassDescription(
54 : "Computes and caches flux and residual vectors for a 1-phase pump. Also computes pump torque "
55 : "and head which is passed to the connected shaft");
56 :
57 92 : return params;
58 0 : }
59 :
60 49 : ADShaftConnectedPump1PhaseUserObject::ADShaftConnectedPump1PhaseUserObject(
61 49 : const InputParameters & params)
62 : : ADVolumeJunction1PhaseUserObject(params),
63 : ADShaftConnectableUserObjectInterface(this),
64 :
65 49 : _di_out(getParam<Point>("di_out")),
66 98 : _g(getParam<Real>("gravity_magnitude")),
67 98 : _omega_rated(getParam<Real>("omega_rated")),
68 98 : _volumetric_rated(getParam<Real>("volumetric_rated")),
69 98 : _head_rated(getParam<Real>("head_rated")),
70 98 : _torque_rated(getParam<Real>("torque_rated")),
71 98 : _density_rated(getParam<Real>("density_rated")),
72 98 : _speed_cr_fr(getParam<Real>("speed_cr_fr")),
73 98 : _tau_fr_const(getParam<Real>("tau_fr_const")),
74 98 : _tau_fr_coeff(getParam<std::vector<Real>>("tau_fr_coeff")),
75 98 : _speed_cr_I(getParam<Real>("speed_cr_I")),
76 98 : _inertia_const(getParam<Real>("inertia_const")),
77 98 : _inertia_coeff(getParam<std::vector<Real>>("inertia_coeff")),
78 49 : _head(getFunction("head")),
79 49 : _torque_hydraulic(getFunction("torque_hydraulic")),
80 98 : _pump_name(getParam<std::string>("pump_name")),
81 49 : _omega(adCoupledScalarValue("omega")),
82 98 : _transition_width(getParam<Real>("transition_width")),
83 98 : _transition_friction(0, _transition_width)
84 : {
85 49 : }
86 :
87 : void
88 49 : ADShaftConnectedPump1PhaseUserObject::initialSetup()
89 : {
90 49 : ADVolumeJunction1PhaseUserObject::initialSetup();
91 :
92 49 : ADShaftConnectableUserObjectInterface::setupConnections(
93 49 : ADVolumeJunctionBaseUserObject::_n_connections, ADVolumeJunctionBaseUserObject::_n_flux_eq);
94 49 : }
95 :
96 : void
97 1868 : ADShaftConnectedPump1PhaseUserObject::initialize()
98 : {
99 1868 : ADVolumeJunction1PhaseUserObject::initialize();
100 1868 : ADShaftConnectableUserObjectInterface::initialize();
101 :
102 1868 : _hydraulic_torque = 0;
103 1868 : _friction_torque = 0;
104 1868 : _pump_head = 0;
105 1868 : }
106 :
107 : void
108 2104 : ADShaftConnectedPump1PhaseUserObject::execute()
109 : {
110 2104 : ADVolumeJunctionBaseUserObject::storeConnectionData();
111 2104 : ADShaftConnectableUserObjectInterface::setConnectionData(
112 2104 : ADVolumeJunctionBaseUserObject::_flow_channel_dofs);
113 :
114 2104 : const unsigned int c = getBoundaryIDIndex();
115 :
116 2104 : computeFluxesAndResiduals(c);
117 2104 : }
118 :
119 : void
120 2104 : ADShaftConnectedPump1PhaseUserObject::computeFluxesAndResiduals(const unsigned int & c)
121 : {
122 2104 : ADVolumeJunction1PhaseUserObject::computeFluxesAndResiduals(c);
123 :
124 : // inlet c=0 established in component
125 2104 : if (c == 0)
126 : {
127 1052 : ADReal alpha = _omega[0] / _omega_rated;
128 :
129 1052 : ADReal Q_in = (_rhouA[0] / _rhoA[0]) * _A[0];
130 :
131 1052 : ADReal nu = Q_in / _volumetric_rated;
132 :
133 : // Head and torque
134 1052 : ADReal x_p = std::atan2(alpha, nu);
135 1052 : const auto wt = _torque_hydraulic.value(x_p, ADPoint());
136 1052 : const auto wh = _head.value(x_p, ADPoint());
137 :
138 0 : const ADReal y = alpha * alpha + nu * nu;
139 :
140 1052 : const auto zt = wt * _torque_rated;
141 :
142 : // Real homologous_torque = -(alpha * alpha + nu * nu) * wt * _torque_rated;
143 1052 : const ADReal homologous_torque = -y * zt;
144 2104 : _hydraulic_torque = homologous_torque * ((_rhoA[0] / _A[0]) / _density_rated);
145 :
146 1052 : const auto zh = wh * _head_rated;
147 :
148 : // _pump_head = (alpha * alpha + nu * nu) * wh * _head_rated;
149 1052 : _pump_head = y * zh;
150 :
151 : // MoI
152 1052 : if (alpha < _speed_cr_I)
153 : {
154 1052 : _moment_of_inertia += _inertia_const;
155 : }
156 : else
157 : {
158 0 : _moment_of_inertia += _inertia_coeff[0] + _inertia_coeff[1] * std::abs(alpha) +
159 0 : _inertia_coeff[2] * alpha * alpha +
160 0 : _inertia_coeff[3] * std::abs(alpha * alpha * alpha);
161 : }
162 :
163 : // friction torque
164 : ADReal sign;
165 1052 : if (alpha > _transition_friction.rightEnd())
166 1052 : sign = -1;
167 0 : else if (alpha < _transition_friction.leftEnd())
168 0 : sign = 1;
169 : else
170 0 : sign = _transition_friction.value(alpha, 1, -1);
171 :
172 1052 : if (alpha < _speed_cr_fr)
173 : {
174 0 : _friction_torque = sign * _tau_fr_const;
175 : }
176 : else
177 : {
178 2104 : _friction_torque = sign * (_tau_fr_coeff[0] + _tau_fr_coeff[1] * std::abs(alpha) +
179 1052 : _tau_fr_coeff[2] * alpha * alpha +
180 2104 : _tau_fr_coeff[3] * std::abs(alpha * alpha * alpha));
181 : }
182 :
183 : // compute momentum and energy source terms
184 : // a negative torque value results in a positive S_energy
185 1052 : const ADReal S_energy = -_hydraulic_torque * _omega[0];
186 :
187 : // a positive head value results in a positive S_momentum
188 2104 : const ADRealVectorValue S_momentum = (_rhoA[0] / _A[0]) * _g * _pump_head * _A_ref * _di_out;
189 :
190 1052 : _residual[VolumeJunction1Phase::RHOEV_INDEX] -= S_energy;
191 :
192 1052 : _residual[VolumeJunction1Phase::RHOUV_INDEX] -= S_momentum(0);
193 1052 : _residual[VolumeJunction1Phase::RHOVV_INDEX] -= S_momentum(1);
194 1052 : _residual[VolumeJunction1Phase::RHOWV_INDEX] -= S_momentum(2);
195 :
196 2104 : _torque += _hydraulic_torque + _friction_torque;
197 : }
198 2104 : }
199 :
200 : ADReal
201 737 : ADShaftConnectedPump1PhaseUserObject::getHydraulicTorque() const
202 : {
203 737 : return _hydraulic_torque;
204 : }
205 :
206 : ADReal
207 737 : ADShaftConnectedPump1PhaseUserObject::getFrictionTorque() const
208 : {
209 737 : return _friction_torque;
210 : }
211 :
212 : ADReal
213 737 : ADShaftConnectedPump1PhaseUserObject::getPumpHead() const
214 : {
215 737 : return _pump_head;
216 : }
217 :
218 : void
219 1562 : ADShaftConnectedPump1PhaseUserObject::finalize()
220 : {
221 1562 : ADVolumeJunction1PhaseUserObject::finalize();
222 1562 : ADShaftConnectableUserObjectInterface::finalize();
223 :
224 1562 : ADShaftConnectableUserObjectInterface::setupJunctionData(
225 1562 : ADVolumeJunctionBaseUserObject::_scalar_dofs);
226 3124 : ADShaftConnectableUserObjectInterface::setOmegaDofs(getScalarVar("omega", 0));
227 :
228 1562 : comm().sum(_hydraulic_torque);
229 1562 : comm().sum(_friction_torque);
230 1562 : comm().sum(_pump_head);
231 1562 : }
232 :
233 : void
234 306 : ADShaftConnectedPump1PhaseUserObject::threadJoin(const UserObject & uo)
235 : {
236 306 : ADVolumeJunction1PhaseUserObject::threadJoin(uo);
237 306 : ADShaftConnectableUserObjectInterface::threadJoin(uo);
238 :
239 : const auto & scpuo = static_cast<const ADShaftConnectedPump1PhaseUserObject &>(uo);
240 306 : _hydraulic_torque += scpuo._hydraulic_torque;
241 306 : _friction_torque += scpuo._friction_torque;
242 306 : _pump_head += scpuo._pump_head;
243 306 : }
|