LCOV - code coverage report
Current view: top level - src/userobjects - ADVolumeJunction1PhaseUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #30301 (3b550b) with base 2ad78d Lines: 102 126 81.0 %
Date: 2025-07-30 13:02:48 Functions: 4 4 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 "ADVolumeJunction1PhaseUserObject.h"
      11             : #include "SinglePhaseFluidProperties.h"
      12             : #include "THMIndicesVACE.h"
      13             : #include "VolumeJunction1Phase.h"
      14             : #include "ADNumericalFlux3EqnBase.h"
      15             : #include "Numerics.h"
      16             : #include "THMUtils.h"
      17             : #include "metaphysicl/parallel_numberarray.h"
      18             : #include "metaphysicl/parallel_dualnumber.h"
      19             : #include "metaphysicl/parallel_semidynamicsparsenumberarray.h"
      20             : #include "libmesh/parallel_algebra.h"
      21             : 
      22             : registerMooseObject("ThermalHydraulicsApp", ADVolumeJunction1PhaseUserObject);
      23             : 
      24             : InputParameters
      25        2372 : ADVolumeJunction1PhaseUserObject::validParams()
      26             : {
      27        2372 :   InputParameters params = ADVolumeJunctionBaseUserObject::validParams();
      28             : 
      29        4744 :   params.addRequiredCoupledVar("A", "Cross-sectional area of connected flow channels");
      30        4744 :   params.addRequiredCoupledVar("rhoA", "rho*A of the connected flow channels");
      31        4744 :   params.addRequiredCoupledVar("rhouA", "rhou*A of the connected flow channels");
      32        4744 :   params.addRequiredCoupledVar("rhoEA", "rhoE*A of the connected flow channels");
      33             : 
      34        4744 :   params.addRequiredCoupledVar("rhoV", "rho*V of the junction");
      35        4744 :   params.addRequiredCoupledVar("rhouV", "rho*u*V of the junction");
      36        4744 :   params.addRequiredCoupledVar("rhovV", "rho*v*V of the junction");
      37        4744 :   params.addRequiredCoupledVar("rhowV", "rho*w*V of the junction");
      38        4744 :   params.addRequiredCoupledVar("rhoEV", "rho*E*V of the junction");
      39             : 
      40        4744 :   params.addRequiredParam<UserObjectName>("fp", "Fluid properties user object name");
      41             : 
      42        4744 :   params.addRequiredParam<Real>("K", "Form loss coefficient [-]");
      43        4744 :   params.addRequiredParam<Real>("A_ref", "Reference area [m^2]");
      44             : 
      45        4744 :   params.addParam<bool>("apply_velocity_scaling",
      46        4744 :                         false,
      47             :                         "Set to true to apply the scaling to the normal velocity. See "
      48             :                         "documentation for more information.");
      49             : 
      50        4744 :   params.addClassDescription(
      51             :       "Computes and caches flux and residual vectors for a 1-phase volume junction");
      52             : 
      53        4744 :   params.declareControllable("K");
      54        2372 :   return params;
      55           0 : }
      56             : 
      57        1298 : ADVolumeJunction1PhaseUserObject::ADVolumeJunction1PhaseUserObject(const InputParameters & params)
      58             :   : ADVolumeJunctionBaseUserObject(params),
      59             : 
      60        1298 :     _A(adCoupledValue("A")),
      61        1298 :     _rhoA(adCoupledValue("rhoA")),
      62        1298 :     _rhouA(adCoupledValue("rhouA")),
      63        1298 :     _rhoEA(adCoupledValue("rhoEA")),
      64             : 
      65        2596 :     _K(getParam<Real>("K")),
      66        2596 :     _A_ref(getParam<Real>("A_ref")),
      67             : 
      68        2596 :     _apply_velocity_scaling(getParam<bool>("apply_velocity_scaling")),
      69             : 
      70        2596 :     _fp(getUserObject<SinglePhaseFluidProperties>("fp"))
      71             : {
      72        1298 :   _flow_variable_names.resize(THMVACE1D::N_FLUX_OUTPUTS);
      73             :   _flow_variable_names[THMVACE1D::RHOA] = "rhoA";
      74             :   _flow_variable_names[THMVACE1D::RHOUA] = "rhouA";
      75             :   _flow_variable_names[THMVACE1D::RHOEA] = "rhoEA";
      76             : 
      77        1298 :   _scalar_variable_names.resize(VolumeJunction1Phase::N_EQ);
      78             :   _scalar_variable_names[VolumeJunction1Phase::RHOV_INDEX] = "rhoV";
      79             :   _scalar_variable_names[VolumeJunction1Phase::RHOUV_INDEX] = "rhouV";
      80             :   _scalar_variable_names[VolumeJunction1Phase::RHOVV_INDEX] = "rhovV";
      81             :   _scalar_variable_names[VolumeJunction1Phase::RHOWV_INDEX] = "rhowV";
      82             :   _scalar_variable_names[VolumeJunction1Phase::RHOEV_INDEX] = "rhoEV";
      83             : 
      84        1298 :   _junction_var_values.resize(VolumeJunction1Phase::N_EQ);
      85        1298 :   _junction_var_values[VolumeJunction1Phase::RHOV_INDEX] = &coupledJunctionValue("rhoV");
      86        1298 :   _junction_var_values[VolumeJunction1Phase::RHOUV_INDEX] = &coupledJunctionValue("rhouV");
      87        1298 :   _junction_var_values[VolumeJunction1Phase::RHOVV_INDEX] = &coupledJunctionValue("rhovV");
      88        1298 :   _junction_var_values[VolumeJunction1Phase::RHOWV_INDEX] = &coupledJunctionValue("rhowV");
      89        1298 :   _junction_var_values[VolumeJunction1Phase::RHOEV_INDEX] = &coupledJunctionValue("rhoEV");
      90             : 
      91        1298 :   _numerical_flux_uo.resize(_n_connections);
      92        4174 :   for (std::size_t i = 0; i < _n_connections; i++)
      93        2876 :     _numerical_flux_uo[i] = &getUserObjectByName<ADNumericalFlux3EqnBase>(_numerical_flux_names[i]);
      94        1298 : }
      95             : 
      96             : void
      97      136247 : ADVolumeJunction1PhaseUserObject::computeFluxesAndResiduals(const unsigned int & c)
      98             : {
      99      136247 :   const Real din = _normal[c];
     100      136247 :   const RealVectorValue di = _dir[0];
     101             :   const RealVectorValue ni = di * din;
     102             :   const RealVectorValue nJi = -ni;
     103      136247 :   const Real nJi_dot_di = -din;
     104             : 
     105             :   RealVectorValue t1, t2;
     106      136247 :   THM::computeOrthogonalDirections(nJi, t1, t2);
     107             : 
     108      136247 :   std::vector<ADReal> Ui(THMVACE3D::N_FLUX_INPUTS, 0.);
     109      136247 :   Ui[THMVACE3D::RHOA] = _rhoA[0];
     110      272494 :   Ui[THMVACE3D::RHOUA] = _rhouA[0] * di(0);
     111      136247 :   Ui[THMVACE3D::RHOVA] = _rhouA[0] * di(1);
     112      136247 :   Ui[THMVACE3D::RHOWA] = _rhouA[0] * di(2);
     113      136247 :   Ui[THMVACE3D::RHOEA] = _rhoEA[0];
     114      136247 :   Ui[THMVACE3D::AREA] = _A[0];
     115             : 
     116             :   const auto & rhoV = _cached_junction_var_values[VolumeJunction1Phase::RHOV_INDEX];
     117             :   const auto & rhouV = _cached_junction_var_values[VolumeJunction1Phase::RHOUV_INDEX];
     118             :   const auto & rhovV = _cached_junction_var_values[VolumeJunction1Phase::RHOVV_INDEX];
     119             :   const auto & rhowV = _cached_junction_var_values[VolumeJunction1Phase::RHOWV_INDEX];
     120             :   const auto & rhoEV = _cached_junction_var_values[VolumeJunction1Phase::RHOEV_INDEX];
     121             : 
     122      136247 :   const ADReal rhoJ = rhoV / _volume;
     123      272494 :   const ADReal vJ = 1.0 / rhoJ;
     124           0 :   const ADRealVectorValue uvecJ(rhouV / rhoV, rhovV / rhoV, rhowV / rhoV);
     125      272494 :   const ADReal eJ = rhoEV / rhoV - 0.5 * uvecJ * uvecJ;
     126      136247 :   const ADReal pJ = _fp.p_from_v_e(vJ, eJ);
     127             : 
     128      136247 :   std::vector<ADReal> UJi(THMVACE3D::N_FLUX_INPUTS, 0.);
     129      272494 :   UJi[THMVACE3D::RHOA] = rhoV / _volume * _A[0];
     130      136247 :   if (_apply_velocity_scaling)
     131             :   {
     132           0 :     const ADReal unJ = uvecJ * nJi;
     133           0 :     const ADReal ut1J = uvecJ * t1;
     134           0 :     const ADReal ut2J = uvecJ * t2;
     135           0 :     const ADReal uni = _rhouA[0] / _rhoA[0] * nJi_dot_di;
     136             : 
     137           0 :     const ADReal rhoi = _rhoA[0] / _A[0];
     138           0 :     const ADReal vi = 1.0 / rhoi;
     139           0 :     const ADReal ei = _rhoEA[0] / _rhoA[0] - 0.5 * uni * uni;
     140           0 :     const ADReal ci = _fp.c_from_v_e(vi, ei);
     141           0 :     const ADReal cJ = _fp.c_from_v_e(vJ, eJ);
     142           0 :     const ADReal cmax = std::max(ci, cJ);
     143             : 
     144           0 :     const ADReal uni_sign = (uni > 0) - (uni < 0);
     145           0 :     const ADReal factor = 0.5 * (1.0 - uni_sign) * std::min(std::abs(uni - unJ) / cmax, 1.0);
     146             : 
     147           0 :     const ADReal unJ_mod = uni - factor * (uni - unJ);
     148           0 :     const ADRealVectorValue uvecJ_mod = unJ_mod * nJi + ut1J * t1 + ut2J * t2;
     149           0 :     const ADReal EJ_mod = eJ + 0.5 * uvecJ_mod * uvecJ_mod;
     150             : 
     151           0 :     UJi[THMVACE3D::RHOUA] = rhoJ * uvecJ_mod(0) * _A[0];
     152           0 :     UJi[THMVACE3D::RHOVA] = rhoJ * uvecJ_mod(1) * _A[0];
     153           0 :     UJi[THMVACE3D::RHOWA] = rhoJ * uvecJ_mod(2) * _A[0];
     154           0 :     UJi[THMVACE3D::RHOEA] = rhoJ * EJ_mod * _A[0];
     155             :   }
     156             :   else
     157             :   {
     158      272494 :     UJi[THMVACE3D::RHOUA] = rhouV / _volume * _A[0];
     159      272494 :     UJi[THMVACE3D::RHOVA] = rhovV / _volume * _A[0];
     160      272494 :     UJi[THMVACE3D::RHOWA] = rhowV / _volume * _A[0];
     161      272494 :     UJi[THMVACE3D::RHOEA] = rhoEV / _volume * _A[0];
     162             :   }
     163      136247 :   UJi[THMVACE3D::AREA] = _A[0];
     164             : 
     165             :   const auto flux_3d =
     166      136247 :       _numerical_flux_uo[c]->getFlux3D(_current_side, _current_elem->id(), UJi, Ui, nJi, t1, t2);
     167             : 
     168      136247 :   _flux[c].resize(THMVACE1D::N_FLUX_OUTPUTS);
     169      136247 :   _flux[c][THMVACE1D::MASS] = flux_3d[THMVACE3D::MASS] * nJi_dot_di;
     170      136247 :   _flux[c][THMVACE1D::MOMENTUM] = flux_3d[THMVACE3D::MOM_NORM];
     171      136247 :   _flux[c][THMVACE1D::ENERGY] = flux_3d[THMVACE3D::ENERGY] * nJi_dot_di;
     172             : 
     173      136247 :   if (c == 0 && std::abs(_K) > 1e-10)
     174             :   {
     175        3798 :     const ADReal vel_in = _rhouA[0] / _rhoA[0];
     176        3798 :     const ADReal v_in = THM::v_from_rhoA_A(_rhoA[0], _A[0]);
     177        3798 :     const ADReal rhouA2 = _rhouA[0] * _rhouA[0];
     178       11394 :     const ADReal e_in = _rhoEA[0] / _rhoA[0] - 0.5 * rhouA2 / (_rhoA[0] * _rhoA[0]);
     179        3798 :     const ADReal p_in = _fp.p_from_v_e(v_in, e_in);
     180        3798 :     const ADReal s0_in = _fp.s_from_v_e(v_in, e_in);
     181        3798 :     const ADReal T_in = _fp.T_from_v_e(v_in, e_in);
     182        3798 :     const ADReal h_in = _fp.h_from_p_T(p_in, T_in);
     183             :     const ADReal velin2 = vel_in * vel_in;
     184        3798 :     const ADReal h0_in = h_in + 0.5 * velin2;
     185        3798 :     const ADReal p0_in = _fp.p_from_h_s(h0_in, s0_in);
     186             :     ADReal S_loss;
     187        3798 :     if (_A_ref == 0)
     188       10449 :       S_loss = _K * (p0_in - p_in) * _A[0];
     189             :     else
     190         630 :       S_loss = _K * (p0_in - p_in) * _A_ref;
     191        3798 :     if (THM::isInlet(vel_in, _normal[c]))
     192             :     {
     193           0 :       _residual[VolumeJunction1Phase::RHOUV_INDEX] -= ni(0) * S_loss;
     194           0 :       _residual[VolumeJunction1Phase::RHOVV_INDEX] -= ni(1) * S_loss;
     195           0 :       _residual[VolumeJunction1Phase::RHOWV_INDEX] -= ni(2) * S_loss;
     196             :     }
     197             :     else
     198             :     {
     199        3798 :       _residual[VolumeJunction1Phase::RHOUV_INDEX] += ni(0) * S_loss;
     200        3798 :       _residual[VolumeJunction1Phase::RHOVV_INDEX] += ni(1) * S_loss;
     201        3798 :       _residual[VolumeJunction1Phase::RHOWV_INDEX] += ni(2) * S_loss;
     202             :     }
     203        7596 :     _residual[VolumeJunction1Phase::RHOEV_INDEX] += S_loss * std::abs(vel_in);
     204             :   }
     205             : 
     206      136247 :   const ADRealVectorValue flux_mom_n = flux_3d[THMVACE3D::MOM_NORM] * nJi +
     207      136247 :                                        flux_3d[THMVACE3D::MOM_TAN1] * t1 +
     208      136247 :                                        flux_3d[THMVACE3D::MOM_TAN2] * t2;
     209             :   const RealVectorValue ex(1, 0, 0);
     210             :   const RealVectorValue ey(0, 1, 0);
     211             :   const RealVectorValue ez(0, 0, 1);
     212             : 
     213      136247 :   _residual[VolumeJunction1Phase::RHOV_INDEX] -= -flux_3d[THMVACE3D::RHOA];
     214      408741 :   _residual[VolumeJunction1Phase::RHOUV_INDEX] -= -flux_mom_n * ex - pJ * ni(0) * _A[0];
     215      408741 :   _residual[VolumeJunction1Phase::RHOVV_INDEX] -= -flux_mom_n * ey - pJ * ni(1) * _A[0];
     216      408741 :   _residual[VolumeJunction1Phase::RHOWV_INDEX] -= -flux_mom_n * ez - pJ * ni(2) * _A[0];
     217      136247 :   _residual[VolumeJunction1Phase::RHOEV_INDEX] -= -flux_3d[THMVACE3D::RHOEA];
     218      136247 : }
     219             : 
     220             : void
     221       73760 : ADVolumeJunction1PhaseUserObject::finalize()
     222             : {
     223       73760 :   ADVolumeJunctionBaseUserObject::finalize();
     224      442560 :   for (unsigned int i = 0; i < _n_scalar_eq; i++)
     225      368800 :     comm().sum(_residual[i]);
     226       73760 : }

Generated by: LCOV version 1.14