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 : using std::abs, std::atan2;
125 :
126 : // inlet c=0 established in component
127 2104 : if (c == 0)
128 : {
129 1052 : ADReal alpha = _omega[0] / _omega_rated;
130 :
131 1052 : ADReal Q_in = (_rhouA[0] / _rhoA[0]) * _A[0];
132 :
133 1052 : ADReal nu = Q_in / _volumetric_rated;
134 :
135 : // Head and torque
136 1052 : ADReal x_p = atan2(alpha, nu);
137 1052 : const auto wt = _torque_hydraulic.value(x_p, ADPoint());
138 1052 : const auto wh = _head.value(x_p, ADPoint());
139 :
140 0 : const ADReal y = alpha * alpha + nu * nu;
141 :
142 1052 : const auto zt = wt * _torque_rated;
143 :
144 : // Real homologous_torque = -(alpha * alpha + nu * nu) * wt * _torque_rated;
145 1052 : const ADReal homologous_torque = -y * zt;
146 2104 : _hydraulic_torque = homologous_torque * ((_rhoA[0] / _A[0]) / _density_rated);
147 :
148 1052 : const auto zh = wh * _head_rated;
149 :
150 : // _pump_head = (alpha * alpha + nu * nu) * wh * _head_rated;
151 1052 : _pump_head = y * zh;
152 :
153 : // MoI
154 1052 : if (alpha < _speed_cr_I)
155 : {
156 1052 : _moment_of_inertia += _inertia_const;
157 : }
158 : else
159 : {
160 0 : _moment_of_inertia += _inertia_coeff[0] + _inertia_coeff[1] * abs(alpha) +
161 0 : _inertia_coeff[2] * alpha * alpha +
162 0 : _inertia_coeff[3] * abs(alpha * alpha * alpha);
163 : }
164 :
165 : // friction torque
166 : ADReal sign;
167 1052 : if (alpha > _transition_friction.rightEnd())
168 1052 : sign = -1;
169 0 : else if (alpha < _transition_friction.leftEnd())
170 0 : sign = 1;
171 : else
172 0 : sign = _transition_friction.value(alpha, 1, -1);
173 :
174 1052 : if (alpha < _speed_cr_fr)
175 : {
176 0 : _friction_torque = sign * _tau_fr_const;
177 : }
178 : else
179 : {
180 : _friction_torque =
181 2104 : sign * (_tau_fr_coeff[0] + _tau_fr_coeff[1] * abs(alpha) +
182 3156 : _tau_fr_coeff[2] * alpha * alpha + _tau_fr_coeff[3] * abs(alpha * alpha * alpha));
183 : }
184 :
185 : // compute momentum and energy source terms
186 : // a negative torque value results in a positive S_energy
187 1052 : const ADReal S_energy = -_hydraulic_torque * _omega[0];
188 :
189 : // a positive head value results in a positive S_momentum
190 2104 : const ADRealVectorValue S_momentum = (_rhoA[0] / _A[0]) * _g * _pump_head * _A_ref * _di_out;
191 :
192 1052 : _residual[VolumeJunction1Phase::RHOEV_INDEX] -= S_energy;
193 :
194 1052 : _residual[VolumeJunction1Phase::RHOUV_INDEX] -= S_momentum(0);
195 1052 : _residual[VolumeJunction1Phase::RHOVV_INDEX] -= S_momentum(1);
196 1052 : _residual[VolumeJunction1Phase::RHOWV_INDEX] -= S_momentum(2);
197 :
198 2104 : _torque += _hydraulic_torque + _friction_torque;
199 : }
200 2104 : }
201 :
202 : ADReal
203 737 : ADShaftConnectedPump1PhaseUserObject::getHydraulicTorque() const
204 : {
205 737 : return _hydraulic_torque;
206 : }
207 :
208 : ADReal
209 737 : ADShaftConnectedPump1PhaseUserObject::getFrictionTorque() const
210 : {
211 737 : return _friction_torque;
212 : }
213 :
214 : ADReal
215 737 : ADShaftConnectedPump1PhaseUserObject::getPumpHead() const
216 : {
217 737 : return _pump_head;
218 : }
219 :
220 : void
221 1562 : ADShaftConnectedPump1PhaseUserObject::finalize()
222 : {
223 1562 : ADVolumeJunction1PhaseUserObject::finalize();
224 1562 : ADShaftConnectableUserObjectInterface::finalize();
225 :
226 1562 : ADShaftConnectableUserObjectInterface::setupJunctionData(
227 1562 : ADVolumeJunctionBaseUserObject::_scalar_dofs);
228 3124 : ADShaftConnectableUserObjectInterface::setOmegaDofs(getScalarVar("omega", 0));
229 :
230 1562 : comm().sum(_hydraulic_torque);
231 1562 : comm().sum(_friction_torque);
232 1562 : comm().sum(_pump_head);
233 1562 : }
234 :
235 : void
236 306 : ADShaftConnectedPump1PhaseUserObject::threadJoin(const UserObject & uo)
237 : {
238 306 : ADVolumeJunction1PhaseUserObject::threadJoin(uo);
239 306 : ADShaftConnectableUserObjectInterface::threadJoin(uo);
240 :
241 : const auto & scpuo = static_cast<const ADShaftConnectedPump1PhaseUserObject &>(uo);
242 306 : _hydraulic_torque += scpuo._hydraulic_torque;
243 306 : _friction_torque += scpuo._friction_torque;
244 306 : _pump_head += scpuo._pump_head;
245 306 : }
|