LCOV - code coverage report
Current view: top level - src/userobjects - ADShaftConnectedPump1PhaseUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #32971 (54bef8) with base c6cf66 Lines: 119 128 93.0 %
Date: 2026-05-29 20:41:18 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          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 : }

Generated by: LCOV version 1.14