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

Generated by: LCOV version 1.14