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