LCOV - code coverage report
Current view: top level - src/userobjects - ADGateValve1PhaseUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #30301 (3b550b) with base 2ad78d Lines: 109 110 99.1 %
Date: 2025-07-30 13:02:48 Functions: 7 7 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 "ADGateValve1PhaseUserObject.h"
      11             : #include "THMIndicesVACE.h"
      12             : #include "ADNumericalFlux3EqnBase.h"
      13             : #include "Function.h"
      14             : #include "Numerics.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", ADGateValve1PhaseUserObject);
      21             : 
      22             : const std::vector<std::pair<std::string, unsigned int>>
      23             :     ADGateValve1PhaseUserObject::_varname_eq_index_pairs{
      24             :         std::pair<std::string, unsigned int>("rhoA", THMVACE1D::MASS),
      25             :         std::pair<std::string, unsigned int>("rhouA", THMVACE1D::MOMENTUM),
      26             :         std::pair<std::string, unsigned int>("rhoEA", THMVACE1D::ENERGY)};
      27             : 
      28             : InputParameters
      29         166 : ADGateValve1PhaseUserObject::validParams()
      30             : {
      31         166 :   InputParameters params = ADFlowJunctionUserObject::validParams();
      32             : 
      33         332 :   params.addRequiredParam<Real>("open_area_fraction",
      34             :                                 "Fraction of possible flow area that is open");
      35         332 :   params.addParam<Real>("open_area_fraction_min", 1e-10, "Minimum open area fraction");
      36             : 
      37         332 :   params.addRequiredCoupledVar("A", "Cross-sectional area of connected flow channels");
      38         332 :   params.addRequiredCoupledVar("rhoA", "rho*A of the connected flow channels");
      39         332 :   params.addRequiredCoupledVar("rhouA", "rhou*A of the connected flow channels");
      40         332 :   params.addRequiredCoupledVar("rhoEA", "rhoE*A of the connected flow channels");
      41             : 
      42         332 :   params.addRequiredParam<UserObjectName>("numerical_flux", "Numerical flux user object name");
      43             : 
      44         332 :   params.addRequiredParam<std::string>("component_name", "Name of the associated component");
      45             : 
      46         332 :   params.addClassDescription("Gate valve user object for 1-phase flow");
      47             : 
      48         332 :   params.declareControllable("open_area_fraction");
      49             : 
      50         166 :   return params;
      51           0 : }
      52             : 
      53          90 : ADGateValve1PhaseUserObject::ADGateValve1PhaseUserObject(const InputParameters & params)
      54             :   : ADFlowJunctionUserObject(params),
      55             : 
      56          90 :     _f_open(getParam<Real>("open_area_fraction")),
      57         180 :     _f_open_min(getParam<Real>("open_area_fraction_min")),
      58             : 
      59          90 :     _A(adCoupledValue("A")),
      60          90 :     _rhoA(adCoupledValue("rhoA")),
      61          90 :     _rhouA(adCoupledValue("rhouA")),
      62          90 :     _rhoEA(adCoupledValue("rhoEA")),
      63             : 
      64          90 :     _rhoA_jvar(coupled("rhoA")),
      65          90 :     _rhouA_jvar(coupled("rhouA")),
      66          90 :     _rhoEA_jvar(coupled("rhoEA")),
      67             : 
      68         180 :     _p(getADMaterialProperty<Real>("p")),
      69             : 
      70          90 :     _numerical_flux(getUserObject<ADNumericalFlux3EqnBase>("numerical_flux")),
      71             : 
      72         180 :     _component_name(getParam<std::string>("component_name")),
      73             : 
      74         180 :     _dir(getMaterialProperty<RealVectorValue>("direction")),
      75             : 
      76          90 :     _solutions(_n_connections),
      77          90 :     _fluxes(_n_connections, std::vector<ADReal>(THMVACE1D::N_FLUX_OUTPUTS, 0)),
      78          90 :     _dof_indices(_n_connections, std::vector<dof_id_type>(THMVACE1D::N_FLUX_OUTPUTS, 0)),
      79             : 
      80          90 :     _stored_p(_n_connections),
      81             : 
      82          90 :     _elem_ids(_n_connections),
      83          90 :     _local_side_ids(_n_connections),
      84             : 
      85          90 :     _areas(_n_connections),
      86         180 :     _directions(_n_connections)
      87             : {
      88          90 : }
      89             : 
      90             : void
      91       10382 : ADGateValve1PhaseUserObject::initialize()
      92             : {
      93             :   _connection_indices.clear();
      94             : 
      95       10382 :   std::vector<ADReal> zero(THMVACE1D::N_FLUX_INPUTS, ADReal(0.));
      96       31146 :   for (auto & s : _solutions)
      97       20764 :     s = zero;
      98       41528 :   for (unsigned int i = 0; i < THMVACE1D::N_FLUX_OUTPUTS; i++)
      99             :   {
     100       31146 :     _fluxes[0][i] = 0;
     101       31146 :     _fluxes[1][i] = 0;
     102             :   }
     103       10382 : }
     104             : 
     105             : void
     106        9892 : ADGateValve1PhaseUserObject::execute()
     107             : {
     108             :   // Get connection index
     109        9892 :   const unsigned int c = getBoundaryIDIndex();
     110        9892 :   _connection_indices.push_back(c);
     111             : 
     112             :   // Store DoF indices
     113       39568 :   for (const auto & varname_eq_index_pair : _varname_eq_index_pairs)
     114             :   {
     115       29676 :     MooseVariable * var = getVar(varname_eq_index_pair.first, 0);
     116             :     auto && dofs = var->dofIndices();
     117             :     mooseAssert(dofs.size() == 1, "There should be only one DoF index.");
     118       29676 :     _dof_indices[c][varname_eq_index_pair.second] = dofs[0];
     119             :   }
     120             : 
     121             :   // Store solution vector for connection
     122        9892 :   std::vector<ADReal> U(THMVACE1D::N_FLUX_INPUTS, ADReal(0.));
     123        9892 :   U[THMVACE1D::RHOA] = _rhoA[0];
     124        9892 :   U[THMVACE1D::RHOUA] = _rhouA[0];
     125        9892 :   U[THMVACE1D::RHOEA] = _rhoEA[0];
     126        9892 :   U[THMVACE1D::AREA] = _A[0];
     127        9892 :   _solutions[c] = U;
     128             : 
     129             :   // Store element ID and local side ID for connection
     130        9892 :   _elem_ids[c] = _current_elem->id();
     131        9892 :   _local_side_ids[c] = _current_side;
     132             : 
     133             :   // Store direction and area of channel at junction (used for error-checking)
     134        9892 :   _areas[c] = _A[0];
     135        9892 :   _directions[c] = _dir[0];
     136             : 
     137        9892 :   _stored_p[c] = _p[0];
     138        9892 : }
     139             : 
     140             : void
     141        1934 : ADGateValve1PhaseUserObject::threadJoin(const UserObject & uo)
     142             : {
     143             :   const auto & junction_uo = static_cast<const ADGateValve1PhaseUserObject &>(uo);
     144             : 
     145             :   // Store the data computed/retrieved in the other threads
     146        4109 :   for (unsigned int i = 0; i < junction_uo._connection_indices.size(); i++)
     147             :   {
     148        2175 :     const unsigned int c = junction_uo._connection_indices[i];
     149             : 
     150        2175 :     _dof_indices[c] = junction_uo._dof_indices[c];
     151        2175 :     _solutions[c] = junction_uo._solutions[c];
     152        2175 :     _elem_ids[c] = junction_uo._elem_ids[c];
     153        2175 :     _local_side_ids[c] = junction_uo._local_side_ids[c];
     154        2175 :     _areas[c] = junction_uo._areas[c];
     155        2175 :     _directions[c] = junction_uo._directions[c];
     156        2175 :     _stored_p[c] = junction_uo._stored_p[c];
     157             :   }
     158        1934 : }
     159             : 
     160             : void
     161        8448 : ADGateValve1PhaseUserObject::finalize()
     162             : {
     163             :   // Check direction compatibility
     164        8448 :   if (!THM::areParallelVectors(_directions[0], _directions[1]))
     165           2 :     mooseError(_component_name, ": The connected channels must be parallel at the junction.");
     166             : 
     167       25338 :   for (unsigned int i = 0; i < _n_connections; i++)
     168             :   {
     169       16892 :     processor_id_type owner_proc = _processor_ids[i];
     170       16892 :     comm().broadcast(_elem_ids[i], owner_proc, true);
     171       16892 :     comm().broadcast(_local_side_ids[i], owner_proc, true);
     172       16892 :     comm().broadcast(_solutions[i], owner_proc, true);
     173       16892 :     comm().broadcast(_directions[i], owner_proc, true);
     174       16892 :     comm().broadcast(_areas[i], owner_proc, true);
     175       16892 :     comm().broadcast(_stored_p[i], owner_proc, true);
     176             :   }
     177             : 
     178        8446 :   const Real & n1_dot_d1 = _normal[0];
     179        8446 :   const Real d1_dot_d2 = _directions[0] * _directions[1];
     180             : 
     181             :   const ADReal & A1 = _areas[0];
     182             :   const ADReal & A2 = _areas[1];
     183        8446 :   const ADReal A = std::min(A1, A2);
     184        8446 :   const ADReal A_flow = _f_open * A;
     185             : 
     186        8446 :   if (_f_open > _f_open_min)
     187             :   {
     188             :     // compute flow contribution
     189        4196 :     std::vector<ADReal> U_flow1 = _solutions[0];
     190        4196 :     std::vector<ADReal> U_flow2 = _solutions[1];
     191        4196 :     U_flow1[THMVACE1D::AREA] = A_flow;
     192        4196 :     U_flow2[THMVACE1D::AREA] = A_flow;
     193       16784 :     for (unsigned int i = 0; i < THMVACE1D::N_FLUX_OUTPUTS; i++)
     194             :     {
     195       12588 :       U_flow1[i] *= A_flow / A1;
     196       12588 :       U_flow2[i] *= A_flow / A2;
     197             :     }
     198        4196 :     U_flow2[THMVACE1D::RHOUA] *= d1_dot_d2;
     199             : 
     200        4196 :     _fluxes[0] = _numerical_flux.getFlux(
     201        4196 :         _local_side_ids[0], _elem_ids[0], true, U_flow1, U_flow2, n1_dot_d1);
     202             : 
     203        4196 :     _fluxes[1] = _numerical_flux.getFlux(
     204        4196 :         _local_side_ids[0], _elem_ids[0], false, U_flow1, U_flow2, n1_dot_d1);
     205        4196 :     _fluxes[1][THMVACE1D::RHOA] *= d1_dot_d2;
     206        4196 :     _fluxes[1][THMVACE1D::RHOEA] *= d1_dot_d2;
     207             :   }
     208             : 
     209             :   // compute wall contribution
     210       25338 :   for (unsigned int c = 0; c < _n_connections; c++)
     211             :   {
     212       16892 :     const ADReal A_wall = _areas[c] - A_flow;
     213       16892 :     _fluxes[c][THMVACE1D::RHOUA] += _stored_p[c] * A_wall;
     214             :   }
     215        8446 : }
     216             : 
     217             : const std::vector<ADReal> &
     218       29460 : ADGateValve1PhaseUserObject::getFlux(const unsigned int & connection_index) const
     219             : {
     220             :   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     221             : 
     222       29460 :   return _fluxes[connection_index];
     223             : }

Generated by: LCOV version 1.14