LCOV - code coverage report
Current view: top level - src/interfaces - ScalarCoupleable.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 99787a Lines: 141 185 76.2 %
Date: 2025-10-14 20:01:24 Functions: 19 28 67.9 %
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 "ScalarCoupleable.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "FEProblem.h"
      14             : #include "MooseVariableFEBase.h"
      15             : #include "MooseVariableScalar.h"
      16             : #include "Problem.h"
      17             : #include "SubProblem.h"
      18             : 
      19      490545 : ScalarCoupleable::ScalarCoupleable(const MooseObject * moose_object)
      20      490545 :   : _sc_fe_problem(
      21     1962180 :         *moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
      22      981090 :     _sc_tid(moose_object->parameters().isParamValid("_tid")
      23      490545 :                 ? moose_object->parameters().get<THREAD_ID>("_tid")
      24             :                 : 0),
      25      490545 :     _real_zero(_sc_fe_problem._real_zero[_sc_tid]),
      26      490545 :     _scalar_zero(_sc_fe_problem._scalar_zero[_sc_tid]),
      27      490545 :     _point_zero(_sc_fe_problem._point_zero[_sc_tid]),
      28      490545 :     _sc_parameters(moose_object->parameters()),
      29      490545 :     _sc_name(_sc_parameters.getObjectName()),
      30      490545 :     _sc_is_implicit(_sc_parameters.have_parameter<bool>("implicit")
      31      490545 :                         ? _sc_parameters.get<bool>("implicit")
      32      490545 :                         : true)
      33             : {
      34     1962180 :   SubProblem & problem = *_sc_parameters.getCheckedPointerParam<SubProblem *>("_subproblem");
      35             : 
      36             :   // Coupling
      37      490545 :   for (std::set<std::string>::const_iterator iter = _sc_parameters.coupledVarsBegin();
      38      787663 :        iter != _sc_parameters.coupledVarsEnd();
      39      297118 :        ++iter)
      40             :   {
      41      297118 :     std::string name = *iter;
      42      297118 :     if (_sc_parameters.getVecMooseType(*iter) != std::vector<std::string>())
      43             :     {
      44       75430 :       std::vector<std::string> vars = _sc_parameters.getVecMooseType(*iter);
      45      166839 :       for (const auto & coupled_var_name : vars)
      46             :       {
      47       91409 :         if (problem.hasScalarVariable(coupled_var_name))
      48             :         {
      49        2088 :           MooseVariableScalar * scalar_var = &problem.getScalarVariable(_sc_tid, coupled_var_name);
      50        2088 :           _coupled_scalar_vars[name].push_back(scalar_var);
      51        2088 :           _coupled_moose_scalar_vars.push_back(scalar_var);
      52             :         }
      53       89321 :         else if (problem.hasVariable(coupled_var_name))
      54             :         {
      55             :           MooseVariableFEBase * moose_var =
      56       89321 :               &problem.getVariable(_sc_tid,
      57             :                                    coupled_var_name,
      58             :                                    Moose::VarKindType::VAR_ANY,
      59       89321 :                                    Moose::VarFieldType::VAR_FIELD_ANY);
      60       89321 :           _sc_coupled_vars[name].push_back(moose_var);
      61             :         }
      62             :         else
      63           0 :           mooseError(_sc_name, ": Coupled variable '", coupled_var_name, "' was not found");
      64             :       }
      65       75430 :     }
      66      297118 :   }
      67      490545 : }
      68             : 
      69             : #ifdef MOOSE_KOKKOS_ENABLED
      70      200105 : ScalarCoupleable::ScalarCoupleable(const ScalarCoupleable & object,
      71      200105 :                                    const Moose::Kokkos::FunctorCopy &)
      72      200105 :   : _sc_fe_problem(object._sc_fe_problem),
      73      200105 :     _sc_tid(object._sc_tid),
      74      200105 :     _real_zero(object._real_zero),
      75      200105 :     _scalar_zero(object._scalar_zero),
      76      200105 :     _point_zero(object._point_zero),
      77      200105 :     _sc_parameters(object._sc_parameters),
      78      200105 :     _sc_name(object._sc_name),
      79      200105 :     _sc_is_implicit(object._sc_is_implicit)
      80             : {
      81      200105 : }
      82             : #endif
      83             : 
      84             : bool
      85        2241 : ScalarCoupleable::isCoupledScalar(const std::string & var_name_in, unsigned int i) const
      86             : {
      87        2241 :   const auto var_name = _sc_parameters.checkForRename(var_name_in);
      88             : 
      89        2241 :   auto it = _coupled_scalar_vars.find(var_name);
      90        2241 :   if (it != _coupled_scalar_vars.end())
      91        1774 :     return (i < it->second.size());
      92             :   else
      93             :   {
      94             :     // Make sure the user originally requested this value in the InputParameter syntax
      95         467 :     if (!_sc_parameters.hasCoupledValue(var_name))
      96           0 :       mooseError(_sc_name,
      97             :                  ": The coupled scalar variable \"",
      98             :                  var_name,
      99             :                  "\" was never added to this object's "
     100             :                  "InputParameters, please double-check "
     101             :                  "your spelling");
     102             : 
     103         467 :     return false;
     104             :   }
     105        2241 : }
     106             : 
     107             : unsigned int
     108         805 : ScalarCoupleable::coupledScalar(const std::string & var_name, const unsigned int comp) const
     109             : {
     110         805 :   checkVar(var_name);
     111         801 :   return getScalarVar(var_name, comp)->number();
     112             : }
     113             : 
     114             : Order
     115         126 : ScalarCoupleable::coupledScalarOrder(const std::string & var_name, const unsigned int comp) const
     116             : {
     117         126 :   checkVar(var_name);
     118         126 :   if (!isCoupledScalar(var_name, comp))
     119          28 :     return _sc_fe_problem.getMaxScalarOrder();
     120             : 
     121          98 :   return getScalarVar(var_name, comp)->order();
     122             : }
     123             : 
     124             : const VariableValue *
     125          28 : ScalarCoupleable::getDefaultValue(const std::string & var_name) const
     126             : {
     127          28 :   auto default_value_it = _default_value.find(var_name);
     128          28 :   if (default_value_it == _default_value.end())
     129             :   {
     130           0 :     auto value = std::make_unique<VariableValue>(_sc_fe_problem.getMaxScalarOrder(),
     131          28 :                                                  _sc_parameters.defaultCoupledValue(var_name));
     132          28 :     default_value_it = _default_value.insert(std::make_pair(var_name, std::move(value))).first;
     133          28 :   }
     134             : 
     135          56 :   return default_value_it->second.get();
     136             : }
     137             : 
     138             : const VariableValue &
     139        1112 : ScalarCoupleable::coupledScalarValue(const std::string & var_name, const unsigned int comp) const
     140             : {
     141        1112 :   checkVar(var_name);
     142        1112 :   if (!isCoupledScalar(var_name, comp))
     143          28 :     return *getDefaultValue(var_name);
     144             : 
     145        1084 :   auto var = getScalarVar(var_name, comp);
     146        1084 :   return _sc_is_implicit ? var->sln() : var->slnOld();
     147             : }
     148             : 
     149             : const ADVariableValue &
     150         295 : ScalarCoupleable::adCoupledScalarValue(const std::string & var_name, const unsigned int comp) const
     151             : {
     152         295 :   checkVar(var_name);
     153         295 :   if (!isCoupledScalar(var_name, comp))
     154           0 :     return *getADDefaultValue(var_name);
     155             : 
     156         295 :   auto var = getScalarVar(var_name, comp);
     157             : 
     158         295 :   if (_sc_is_implicit)
     159         295 :     return var->adSln();
     160             :   else
     161           0 :     mooseError("adCoupledValue for non-implicit calculations is not currently supported. Use "
     162             :                "coupledValue instead for non-implicit");
     163             : }
     164             : 
     165             : template <>
     166             : const GenericVariableValue<false> &
     167           0 : ScalarCoupleable::coupledGenericScalarValue<false>(const std::string & var_name,
     168             :                                                    const unsigned int comp) const
     169             : {
     170           0 :   return coupledScalarValue(var_name, comp);
     171             : }
     172             : 
     173             : template <>
     174             : const GenericVariableValue<true> &
     175           0 : ScalarCoupleable::coupledGenericScalarValue<true>(const std::string & var_name,
     176             :                                                   const unsigned int comp) const
     177             : {
     178           0 :   return adCoupledScalarValue(var_name, comp);
     179             : }
     180             : 
     181             : const ADVariableValue *
     182           0 : ScalarCoupleable::getADDefaultValue(const std::string & var_name) const
     183             : {
     184           0 :   auto default_value_it = _dual_default_value.find(var_name);
     185           0 :   if (default_value_it == _dual_default_value.end())
     186             :   {
     187           0 :     auto value = std::make_unique<ADVariableValue>(_sc_fe_problem.getMaxScalarOrder(),
     188           0 :                                                    _sc_parameters.defaultCoupledValue(var_name));
     189           0 :     default_value_it = _dual_default_value.insert(std::make_pair(var_name, std::move(value))).first;
     190           0 :   }
     191             : 
     192           0 :   return default_value_it->second.get();
     193             : }
     194             : 
     195             : const VariableValue &
     196          40 : ScalarCoupleable::coupledVectorTagScalarValue(const std::string & var_name,
     197             :                                               TagID tag,
     198             :                                               const unsigned int comp) const
     199             : {
     200          40 :   checkVar(var_name);
     201          40 :   if (!isCoupledScalar(var_name, comp))
     202           0 :     return *getDefaultValue(var_name);
     203             : 
     204          40 :   if (!_sc_fe_problem.vectorTagExists(tag))
     205           0 :     mooseError("Attempting to couple to vector tag scalar with ID ",
     206             :                tag,
     207             :                "in ",
     208           0 :                _sc_name,
     209             :                ", but a vector tag with that ID does not exist");
     210             : 
     211          40 :   _sc_coupleable_vector_tags.insert(tag);
     212             : 
     213          40 :   return getScalarVar(var_name, comp)->vectorTagSln(tag);
     214             : }
     215             : 
     216             : const VariableValue &
     217          20 : ScalarCoupleable::coupledMatrixTagScalarValue(const std::string & var_name,
     218             :                                               TagID tag,
     219             :                                               const unsigned int comp) const
     220             : {
     221          20 :   checkVar(var_name);
     222          20 :   if (!isCoupledScalar(var_name, comp))
     223           0 :     return *getDefaultValue(var_name);
     224             : 
     225          20 :   _sc_coupleable_matrix_tags.insert(tag);
     226             : 
     227          20 :   return getScalarVar(var_name, comp)->matrixTagSln(tag);
     228             : }
     229             : 
     230             : const VariableValue &
     231          32 : ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, const unsigned int comp) const
     232             : {
     233          32 :   checkVar(var_name);
     234          32 :   if (!isCoupledScalar(var_name, comp))
     235           0 :     return *getDefaultValue(var_name);
     236             : 
     237          32 :   validateExecutionerType(var_name, "coupledScalarValueOld");
     238          28 :   auto var = getScalarVar(var_name, comp);
     239          28 :   return _sc_is_implicit ? var->slnOld() : var->slnOlder();
     240             : }
     241             : 
     242             : const VariableValue &
     243          28 : ScalarCoupleable::coupledScalarValueOlder(const std::string & var_name,
     244             :                                           const unsigned int comp) const
     245             : {
     246          28 :   checkVar(var_name);
     247          28 :   if (!isCoupledScalar(var_name, comp))
     248           0 :     return *getDefaultValue(var_name);
     249             : 
     250          28 :   validateExecutionerType(var_name, "coupledScalarValueOlder");
     251          28 :   auto var = getScalarVar(var_name, comp);
     252          28 :   if (_sc_is_implicit)
     253          28 :     return var->slnOlder();
     254             :   else
     255           0 :     mooseError("Older values not available for explicit schemes");
     256             : }
     257             : 
     258             : const VariableValue &
     259          75 : ScalarCoupleable::coupledScalarDot(const std::string & var_name, const unsigned int comp) const
     260             : {
     261          75 :   checkVar(var_name);
     262          75 :   validateExecutionerType(var_name, "coupledScalarDot");
     263          71 :   return getScalarVar(var_name, comp)->uDot();
     264             : }
     265             : 
     266             : const ADVariableValue &
     267          13 : ScalarCoupleable::adCoupledScalarDot(const std::string & var_name, const unsigned int comp) const
     268             : {
     269          13 :   checkVar(var_name);
     270          13 :   validateExecutionerType(var_name, "adCoupledScalarDot");
     271          13 :   return getScalarVar(var_name, comp)->adUDot();
     272             : }
     273             : 
     274             : const VariableValue &
     275           0 : ScalarCoupleable::coupledScalarDotDot(const std::string & var_name, const unsigned int comp) const
     276             : {
     277           0 :   checkVar(var_name);
     278           0 :   validateExecutionerType(var_name, "coupledScalarDotDot");
     279           0 :   return getScalarVar(var_name, comp)->uDotDot();
     280             : }
     281             : 
     282             : const VariableValue &
     283           0 : ScalarCoupleable::coupledScalarDotOld(const std::string & var_name, const unsigned int comp) const
     284             : {
     285           0 :   checkVar(var_name);
     286           0 :   validateExecutionerType(var_name, "coupledScalarDotOld");
     287           0 :   return getScalarVar(var_name, comp)->uDotOld();
     288             : }
     289             : 
     290             : const VariableValue &
     291           0 : ScalarCoupleable::coupledScalarDotDotOld(const std::string & var_name,
     292             :                                          const unsigned int comp) const
     293             : {
     294           0 :   checkVar(var_name);
     295           0 :   validateExecutionerType(var_name, "coupledScalarDotDotOld");
     296           0 :   return getScalarVar(var_name, comp)->uDotDotOld();
     297             : }
     298             : const VariableValue &
     299          71 : ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, const unsigned int comp) const
     300             : {
     301          71 :   checkVar(var_name);
     302          71 :   validateExecutionerType(var_name, "coupledScalarDotDu");
     303          71 :   return getScalarVar(var_name, comp)->duDotDu();
     304             : }
     305             : 
     306             : const VariableValue &
     307           0 : ScalarCoupleable::coupledScalarDotDotDu(const std::string & var_name, const unsigned int comp) const
     308             : {
     309           0 :   checkVar(var_name);
     310           0 :   validateExecutionerType(var_name, "coupledScalarDotDotDu");
     311           0 :   return getScalarVar(var_name, comp)->duDotDotDu();
     312             : }
     313             : 
     314             : void
     315        2617 : ScalarCoupleable::checkVar(const std::string & var_name_in) const
     316             : {
     317        2617 :   const auto var_name = _sc_parameters.checkForRename(var_name_in);
     318             : 
     319        2617 :   auto it = _sc_coupled_vars.find(var_name);
     320        2617 :   if (it != _sc_coupled_vars.end())
     321             :   {
     322           4 :     std::string cvars;
     323           8 :     for (auto jt : it->second)
     324           4 :       cvars += " " + jt->name();
     325           4 :     mooseError(_sc_name,
     326             :                ": Trying to couple a field variable where scalar variable is expected, '",
     327             :                var_name,
     328             :                " =",
     329             :                cvars,
     330             :                "'");
     331           0 :   }
     332             :   // NOTE: non-existent variables are handled in the constructor
     333        2613 : }
     334             : 
     335             : const MooseVariableScalar *
     336        4079 : ScalarCoupleable::getScalarVar(const std::string & var_name_in, const unsigned int comp) const
     337             : {
     338        4079 :   const auto var_name = _sc_parameters.checkForRename(var_name_in);
     339             : 
     340        4079 :   const auto it = _coupled_scalar_vars.find(var_name);
     341        4079 :   if (it != _coupled_scalar_vars.end())
     342             :   {
     343        4079 :     const auto & entry = it->second;
     344        4079 :     if (comp < entry.size())
     345        8158 :       return entry[comp];
     346             :     else
     347           0 :       mooseError(_sc_name, ": Trying to get a non-existent component of variable '", var_name, "'");
     348             :   }
     349             :   else
     350           0 :     mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
     351        4079 : }
     352             : 
     353             : void
     354         219 : ScalarCoupleable::validateExecutionerType(const std::string & name,
     355             :                                           const std::string & fn_name) const
     356             : {
     357         219 :   if (!_sc_fe_problem.isTransient())
     358           8 :     mooseError(_sc_name,
     359             :                ": Calling '",
     360             :                fn_name,
     361             :                "' on variable \"",
     362             :                name,
     363             :                "\" when using a \"Steady\" executioner is not allowed. This value is available "
     364             :                "only in transient simulations.");
     365         211 : }
     366             : 
     367             : unsigned int
     368         177 : ScalarCoupleable::coupledScalarComponents(const std::string & var_name_in) const
     369             : {
     370         177 :   const auto var_name = _sc_parameters.checkForRename(var_name_in);
     371             : 
     372         177 :   const auto it = _coupled_scalar_vars.find(var_name);
     373         177 :   if (it != _coupled_scalar_vars.end())
     374         354 :     return it->second.size();
     375             : 
     376           0 :   mooseError(_sc_name, ": Trying to get a non-existent variable '", var_name, "'");
     377         177 : }

Generated by: LCOV version 1.14