LCOV - code coverage report
Current view: top level - src/userobjects - ADVolumeJunctionBaseUserObject.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #32971 (54bef8) with base c6cf66 Lines: 81 104 77.9 %
Date: 2026-05-29 20:41:18 Functions: 11 13 84.6 %
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 "ADVolumeJunctionBaseUserObject.h"
      11             : #include "MooseVariableScalar.h"
      12             : #include "FEProblemBase.h"
      13             : #include "metaphysicl/parallel_numberarray.h"
      14             : #include "metaphysicl/parallel_dualnumber.h"
      15             : #include "metaphysicl/parallel_semidynamicsparsenumberarray.h"
      16             : #include "libmesh/parallel_algebra.h"
      17             : 
      18             : InputParameters
      19        1205 : ADVolumeJunctionBaseUserObject::validParams()
      20             : {
      21        1205 :   InputParameters params = ADFlowJunctionUserObject::validParams();
      22             : 
      23        2410 :   params.addParam<bool>(
      24        2410 :       "use_scalar_variables", true, "True if the junction variables are scalar variables");
      25        2410 :   params.addParam<subdomain_id_type>(
      26             :       "junction_subdomain_id",
      27             :       libMesh::invalid_uint,
      28             :       "Junction subdomain ID (required if 'use_scalar_variables' is 'false')");
      29             : 
      30        2410 :   params.addRequiredParam<Real>("volume", "Volume of the junction");
      31        2410 :   params.addRequiredParam<std::vector<UserObjectName>>(
      32             :       "numerical_flux_names",
      33             :       "The names of the user objects that compute the numerical flux at each flow channel.");
      34        1205 :   params.addClassDescription("User object to compute fluxes and residuals for a volume junction");
      35        1205 :   return params;
      36           0 : }
      37             : 
      38         641 : ADVolumeJunctionBaseUserObject::ADVolumeJunctionBaseUserObject(const InputParameters & params)
      39             :   : ADFlowJunctionUserObject(params),
      40         641 :     _use_scalar_variables(getParam<bool>("use_scalar_variables")),
      41        1282 :     _junction_subdomain_id(getParam<subdomain_id_type>("junction_subdomain_id")),
      42        1282 :     _volume(getParam<Real>("volume")),
      43        1923 :     _numerical_flux_names(getParam<std::vector<UserObjectName>>("numerical_flux_names"))
      44             : {
      45         641 :   if (_numerical_flux_names.size() != _n_connections)
      46           0 :     mooseError(name(),
      47             :                ": The number of supplied numerical flux objects '",
      48           0 :                _numerical_flux_names.size(),
      49             :                "' does not match the number of connections '",
      50           0 :                _n_connections,
      51             :                "'.");
      52             : 
      53        2564 :   if (!_use_scalar_variables && !isParamSetByUser("junction_subdomain_id"))
      54           0 :     mooseError("If 'use_scalar_variables' is set to false, 'junction_subdomain_id' is required.");
      55         641 : }
      56             : 
      57             : void
      58         592 : ADVolumeJunctionBaseUserObject::initialSetup()
      59             : {
      60         592 :   _n_flux_eq = _flow_variable_names.size();
      61         592 :   _n_scalar_eq = _scalar_variable_names.size();
      62             : 
      63         592 :   _scalar_dofs.resize(_n_scalar_eq);
      64         592 :   _cached_junction_var_values.resize(_n_scalar_eq);
      65         592 :   _flow_channel_dofs.resize(_n_connections);
      66         592 :   _residual.resize(_n_scalar_eq);
      67         592 : }
      68             : 
      69             : void
      70       46056 : ADVolumeJunctionBaseUserObject::initialize()
      71             : {
      72       46056 :   _flux.assign(_n_connections, std::vector<ADReal>(_n_flux_eq, 0.0));
      73      276336 :   for (auto & i : _residual)
      74             :   {
      75      230280 :     i.value() = 0;
      76      230280 :     i.derivatives() = DNDerivativeType();
      77             :   }
      78       46056 :   _connection_indices.clear();
      79             : 
      80       46056 :   auto junction_vars = getJunctionVariables();
      81             : 
      82             :   // Cache the junction variable values and get their dof indices
      83       46056 :   if (!_use_scalar_variables)
      84             :   {
      85      276336 :     for (unsigned int i = 0; i < _n_scalar_eq; i++)
      86             :     {
      87      230280 :       _cached_junction_var_values[i] = 0;
      88      230280 :       _scalar_dofs[i] = 0;
      89             :     }
      90             : 
      91     1475895 :     for (const Elem * elem : *_mesh.getActiveLocalElementRange())
      92             :     {
      93     1429839 :       if (elem->subdomain_id() == _junction_subdomain_id)
      94             :       {
      95             :         // Reinitialize the element
      96       34699 :         _fe_problem.setCurrentSubdomainID(elem, _tid);
      97       34699 :         _fe_problem.prepare(elem, _tid);
      98       34699 :         _fe_problem.reinitElem(elem, _tid);
      99             : 
     100             :         // Cache the junction variable values and Dof indices
     101      208194 :         for (unsigned int i = 0; i < _n_scalar_eq; i++)
     102             :         {
     103      173495 :           _cached_junction_var_values[i] = (*_junction_var_values[i])[0];
     104             : 
     105      173495 :           auto && dofs = junction_vars[i]->dofIndices();
     106             :           mooseAssert(dofs.size() == 1,
     107             :                       "There should be exactly 1 coupled DoF index for the variable '" +
     108             :                           junction_vars[i]->name() + "'.");
     109      173495 :           _scalar_dofs[i] = dofs[0];
     110             :         }
     111             :       }
     112             :     }
     113             : 
     114       46056 :     comm().sum(_cached_junction_var_values);
     115       46056 :     comm().sum(_scalar_dofs);
     116             :   }
     117             :   else
     118             :   {
     119           0 :     for (unsigned int i = 0; i < _junction_var_values.size(); i++)
     120           0 :       _cached_junction_var_values[i] = (*_junction_var_values[i])[0];
     121             : 
     122           0 :     for (unsigned int i = 0; i < _n_scalar_eq; i++)
     123             :     {
     124           0 :       auto && dofs = junction_vars[i]->dofIndices();
     125             :       mooseAssert(dofs.size() == 1,
     126             :                   "There should be exactly 1 coupled DoF index for the variable '" +
     127             :                       junction_vars[i]->name() + "'.");
     128           0 :       _scalar_dofs[i] = dofs[0];
     129             :     }
     130             :   }
     131       46056 : }
     132             : 
     133             : void
     134       66856 : ADVolumeJunctionBaseUserObject::storeConnectionData()
     135             : {
     136             :   // Get the connection index
     137       66856 :   const unsigned int c = getBoundaryIDIndex();
     138       66856 :   _connection_indices.push_back(c);
     139             : 
     140             :   // Get flow channel Dofs and basic function values
     141       66856 :   _flow_channel_dofs[c].clear();
     142      267424 :   for (unsigned int j = 0; j < _n_flux_eq; j++)
     143             :   {
     144      200568 :     MooseVariable * var = getVar(_flow_variable_names[j], 0);
     145             : 
     146             :     auto && dofs = var->dofIndices();
     147      401136 :     for (unsigned int k = 0; k < dofs.size(); k++)
     148      200568 :       _flow_channel_dofs[c].push_back(dofs[k]);
     149             :   }
     150       66856 : }
     151             : 
     152             : void
     153       61442 : ADVolumeJunctionBaseUserObject::execute()
     154             : {
     155       61442 :   storeConnectionData();
     156             : 
     157       61442 :   const unsigned int c = getBoundaryIDIndex();
     158       61442 :   computeFluxesAndResiduals(c);
     159       61440 : }
     160             : 
     161             : void
     162        5791 : ADVolumeJunctionBaseUserObject::threadJoin(const UserObject & uo)
     163             : {
     164             :   const auto & volume_junction_uo = static_cast<const ADVolumeJunctionBaseUserObject &>(uo);
     165             : 
     166             :   // Store the data computed/retrieved in the other threads
     167       11297 :   for (unsigned int i = 0; i < volume_junction_uo._connection_indices.size(); i++)
     168             :   {
     169        5506 :     const unsigned int c = volume_junction_uo._connection_indices[i];
     170             : 
     171        5506 :     _flux[c] = volume_junction_uo._flux[c];
     172        5506 :     _flow_channel_dofs[c] = volume_junction_uo._flow_channel_dofs[c];
     173             :   }
     174             : 
     175             :   // Add the scalar residuals from the other threads
     176       34746 :   for (unsigned int i = 0; i < _n_scalar_eq; i++)
     177       28955 :     _residual[i] += volume_junction_uo._residual[i];
     178        5791 : }
     179             : 
     180             : const std::vector<ADReal> &
     181      142475 : ADVolumeJunctionBaseUserObject::getResidual() const
     182             : {
     183             :   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     184             : 
     185      142475 :   return _residual;
     186             : }
     187             : 
     188             : const std::vector<ADReal> &
     189      198286 : ADVolumeJunctionBaseUserObject::getFlux(const unsigned int & connection_index) const
     190             : {
     191             :   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     192             : 
     193      198286 :   checkValidConnectionIndex(connection_index);
     194      198286 :   return _flux[connection_index];
     195             : }
     196             : 
     197             : std::vector<const MooseVariableBase *>
     198           0 : ADVolumeJunctionBaseUserObject::getFlowChannelVariables() const
     199             : {
     200             :   // TODO: This default implementation should be deleted and made pure virtual
     201             :   // after apps update.
     202           0 :   std::vector<const MooseVariableBase *> vars(_flow_variable_names.size());
     203           0 :   for (const auto i : index_range(_flow_variable_names))
     204           0 :     vars[i] = getVar(_flow_variable_names[i], 0);
     205           0 :   return vars;
     206           0 : }
     207             : 
     208             : std::vector<const MooseVariableBase *>
     209           0 : ADVolumeJunctionBaseUserObject::getJunctionVariables() const
     210             : {
     211           0 :   std::vector<const MooseVariableBase *> vars(_scalar_variable_names.size());
     212           0 :   for (unsigned int i = 0; i < _scalar_variable_names.size(); i++)
     213           0 :     vars[i] = getJunctionVar(_scalar_variable_names[i], 0);
     214           0 :   return vars;
     215           0 : }
     216             : 
     217             : const MooseVariableBase *
     218      230280 : ADVolumeJunctionBaseUserObject::getJunctionVar(const std::string & var_name, unsigned int i) const
     219             : {
     220             :   const MooseVariableBase * var;
     221      230280 :   if (_use_scalar_variables)
     222           0 :     var = getScalarVar(var_name, i);
     223             :   else
     224      230280 :     var = getVar(var_name, i);
     225      230280 :   return var;
     226             : }
     227             : 
     228             : const ADVariableValue &
     229        3205 : ADVolumeJunctionBaseUserObject::coupledJunctionValue(const std::string & var_name,
     230             :                                                      unsigned int i) const
     231             : {
     232        3205 :   return _use_scalar_variables ? adCoupledScalarValue(var_name, i) : adCoupledValue(var_name, i);
     233             : }

Generated by: LCOV version 1.14