LCOV - code coverage report
Current view: top level - src/userobjects - ADShaftConnectedPump1PhaseUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #30301 (3b550b) with base 2ad78d Lines: 120 129 93.0 %
Date: 2025-07-30 13:02:48 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.14