LCOV - code coverage report
Current view: top level - src/interfaces - Coupleable.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 99787a Lines: 792 1438 55.1 %
Date: 2025-10-14 20:01:24 Functions: 138 244 56.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 "Coupleable.h"
      11             : #include "Problem.h"
      12             : #include "SubProblem.h"
      13             : #include "FEProblem.h"
      14             : #include "MooseVariableScalar.h"
      15             : #include "MooseVariableFE.h"
      16             : #include "InputParameters.h"
      17             : #include "MooseObject.h"
      18             : #include "SystemBase.h"
      19             : #include "AuxiliarySystem.h"
      20             : 
      21             : #include "AuxKernel.h"
      22             : #include "ElementUserObject.h"
      23             : #include "NodalUserObject.h"
      24             : #include "NodeFaceConstraint.h"
      25             : #include "NodeElemConstraintBase.h"
      26             : 
      27      393314 : Coupleable::Coupleable(const MooseObject * moose_object, bool nodal, bool is_fv)
      28      786628 :   : _c_parameters(moose_object->parameters()),
      29      393314 :     _c_name(moose_object->name()),
      30      393314 :     _c_type(moose_object->type()),
      31     1573256 :     _c_fe_problem(*_c_parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
      32      786628 :     _c_sys(_c_parameters.isParamValid("_sys") ? _c_parameters.get<SystemBase *>("_sys") : nullptr),
      33      393314 :     _new_to_deprecated_coupled_vars(_c_parameters.getNewToDeprecatedVarMap()),
      34      393314 :     _c_nodal(nodal),
      35      393314 :     _c_is_implicit(_c_parameters.have_parameter<bool>("implicit")
      36      393314 :                        ? _c_parameters.get<bool>("implicit")
      37             :                        : true),
      38      393314 :     _c_allow_element_to_nodal_coupling(
      39      393314 :         _c_parameters.have_parameter<bool>("_allow_nodal_to_elemental_coupling")
      40      393314 :             ? _c_parameters.get<bool>("_allow_nodal_to_elemental_coupling")
      41             :             : false),
      42      393314 :     _c_tid(_c_parameters.get<THREAD_ID>("_tid")),
      43      393314 :     _zero(_c_fe_problem._zero[_c_tid]),
      44      393314 :     _phi_zero(_c_fe_problem._phi_zero[_c_tid]),
      45      393314 :     _ad_zero(_c_fe_problem._ad_zero[_c_tid]),
      46      393314 :     _grad_zero(_c_fe_problem._grad_zero[_c_tid]),
      47      393314 :     _ad_grad_zero(_c_fe_problem._ad_grad_zero[_c_tid]),
      48      393314 :     _grad_phi_zero(_c_fe_problem._grad_phi_zero[_c_tid]),
      49      393314 :     _second_zero(_c_fe_problem._second_zero[_c_tid]),
      50      393314 :     _ad_second_zero(_c_fe_problem._ad_second_zero[_c_tid]),
      51      393314 :     _second_phi_zero(_c_fe_problem._second_phi_zero[_c_tid]),
      52      393314 :     _vector_zero(_c_fe_problem._vector_zero[_c_tid]),
      53      393314 :     _vector_curl_zero(_c_fe_problem._vector_curl_zero[_c_tid]),
      54      393314 :     _coupleable_neighbor(_c_parameters.have_parameter<bool>("_neighbor")
      55      393314 :                              ? _c_parameters.get<bool>("_neighbor")
      56             :                              : false),
      57      393314 :     _coupleable_max_qps(Moose::constMaxQpsPerElem),
      58      393314 :     _is_fv(is_fv),
      59      393314 :     _obj(moose_object),
      60     3933140 :     _writable_coupled_variables(libMesh::n_threads())
      61             : {
      62     1573256 :   SubProblem & problem = *_c_parameters.getCheckedPointerParam<SubProblem *>("_subproblem");
      63      393314 :   _obj->getMooseApp().registerInterfaceObject(*this);
      64             : 
      65      393314 :   unsigned int optional_var_index_counter = 0;
      66             : 
      67             :   // Coupling
      68      688928 :   for (auto iter = _c_parameters.coupledVarsBegin(); iter != _c_parameters.coupledVarsEnd(); ++iter)
      69             :   {
      70      295622 :     std::string name = *iter;
      71             : 
      72      295622 :     std::vector<std::string> vars = _c_parameters.getVecMooseType(name);
      73      295622 :     if (vars.size() > 0)
      74             :     {
      75      164201 :       for (const auto & coupled_var_name : vars)
      76             :       {
      77       89872 :         if (problem.hasVariable(coupled_var_name))
      78             :         {
      79             :           MooseVariableFieldBase * moose_var =
      80       88281 :               &problem.getVariable(_c_tid,
      81             :                                    coupled_var_name,
      82             :                                    Moose::VarKindType::VAR_ANY,
      83       88281 :                                    Moose::VarFieldType::VAR_FIELD_ANY);
      84       88281 :           _coupled_vars[name].push_back(moose_var);
      85       88281 :           _coupled_moose_vars.push_back(moose_var);
      86       88281 :           if (auto * tmp_var = dynamic_cast<MooseVariable *>(moose_var))
      87       81174 :             _coupled_standard_moose_vars.push_back(tmp_var);
      88        7107 :           else if (auto * tmp_var = dynamic_cast<VectorMooseVariable *>(moose_var))
      89        1118 :             _coupled_vector_moose_vars.push_back(tmp_var);
      90        5989 :           else if (auto * tmp_var = dynamic_cast<ArrayMooseVariable *>(moose_var))
      91        1579 :             _coupled_array_moose_vars.push_back(tmp_var);
      92        4410 :           else if (auto * tmp_var = dynamic_cast<MooseVariableFV<Real> *>(moose_var))
      93             :           {
      94             :             // We are using a finite volume variable through add*CoupledVar as opposed to getFunctor
      95             :             // so we can be reasonably confident that the variable values will be obtained using
      96             :             // traditional pre-evaluation and quadrature point indexing
      97        4056 :             tmp_var->requireQpComputations();
      98        4056 :             _coupled_fv_moose_vars.push_back(tmp_var);
      99             :           }
     100         354 :           else if (auto * tmp_var = dynamic_cast<MooseLinearVariableFV<Real> *>(moose_var))
     101         354 :             _coupled_fv_moose_vars.push_back(tmp_var);
     102             :           else
     103           0 :             _obj->paramError(name, "provided c++ type for variable parameter is not supported");
     104             :         }
     105        1591 :         else if (problem.hasScalarVariable(coupled_var_name))
     106             :         {
     107             :           MooseVariableScalar * moose_scalar_var =
     108        1583 :               &problem.getScalarVariable(_c_tid, coupled_var_name);
     109        1583 :           _c_coupled_scalar_vars[name].push_back(moose_scalar_var);
     110             :         }
     111             :         else
     112           8 :           _obj->paramError(name, "coupled variable '", coupled_var_name, "' was not found");
     113             :       }
     114             :     }
     115             :     else // This means it was optional coupling.  Let's assign a unique id to this variable
     116             :     {
     117      221285 :       _optional_var_index[name].assign(_c_parameters.numberDefaultCoupledValues(name), 0);
     118      443273 :       for (unsigned int j = 0; j < _optional_var_index[name].size(); ++j)
     119      221988 :         _optional_var_index[name][j] =
     120      221988 :             std::numeric_limits<unsigned int>::max() - optional_var_index_counter;
     121      221285 :       ++optional_var_index_counter;
     122             :     }
     123      295614 :   }
     124      786620 : }
     125             : 
     126             : #ifdef MOOSE_KOKKOS_ENABLED
     127      200105 : Coupleable::Coupleable(const Coupleable & object, const Moose::Kokkos::FunctorCopy &)
     128      200105 :   : _c_parameters(object._c_parameters),
     129      200105 :     _c_name(object._c_name),
     130      200105 :     _c_type(object._c_type),
     131      200105 :     _c_fe_problem(object._c_fe_problem),
     132      200105 :     _c_sys(object._c_sys),
     133      200105 :     _new_to_deprecated_coupled_vars(object._new_to_deprecated_coupled_vars),
     134      200105 :     _c_nodal(object._c_nodal),
     135      200105 :     _c_is_implicit(object._c_is_implicit),
     136      200105 :     _c_allow_element_to_nodal_coupling(object._c_allow_element_to_nodal_coupling),
     137      200105 :     _c_tid(object._c_tid),
     138      200105 :     _zero(object._zero),
     139      200105 :     _phi_zero(object._phi_zero),
     140      200105 :     _ad_zero(object._ad_zero),
     141      200105 :     _grad_zero(object._grad_zero),
     142      200105 :     _ad_grad_zero(object._ad_grad_zero),
     143      200105 :     _grad_phi_zero(object._grad_phi_zero),
     144      200105 :     _second_zero(object._second_zero),
     145      200105 :     _ad_second_zero(object._ad_second_zero),
     146      200105 :     _second_phi_zero(object._second_phi_zero),
     147      200105 :     _vector_zero(object._vector_zero),
     148      200105 :     _vector_curl_zero(object._vector_curl_zero),
     149      200105 :     _coupleable_neighbor(object._coupleable_neighbor),
     150      200105 :     _coupleable_max_qps(object._coupleable_max_qps),
     151      200105 :     _is_fv(object._is_fv),
     152      200105 :     _obj(object._obj),
     153     1000525 :     _writable_coupled_variables(object._writable_coupled_variables)
     154             : {
     155      400210 : }
     156             : #endif
     157             : 
     158             : bool
     159      300983 : Coupleable::isCoupled(const std::string & var_name_in, unsigned int i) const
     160             : {
     161      300983 :   const auto var_name = _c_parameters.checkForRename(var_name_in);
     162             : 
     163      300983 :   auto it = _coupled_vars.find(var_name);
     164      300983 :   if (it != _coupled_vars.end())
     165      168184 :     return (i < it->second.size());
     166             :   else
     167             :   {
     168             :     // Make sure the user originally requested this value in the InputParameter syntax
     169      132799 :     if (!_c_parameters.hasCoupledValue(var_name))
     170           4 :       mooseError(_c_name,
     171             :                  ": The coupled variable \"",
     172             :                  var_name,
     173             :                  "\" was never added to this object's "
     174             :                  "InputParameters, please double-check your "
     175             :                  "spelling");
     176             : 
     177      132795 :     return false;
     178             :   }
     179      300979 : }
     180             : 
     181             : bool
     182        1616 : Coupleable::isCoupledConstant(const std::string & var_name) const
     183             : {
     184        1616 :   return _c_parameters.hasDefaultCoupledValue(var_name);
     185             : }
     186             : 
     187             : unsigned int
     188       97912 : Coupleable::coupledComponents(const std::string & var_name_in) const
     189             : {
     190       97912 :   const auto var_name = _c_parameters.checkForRename(var_name_in);
     191             : 
     192       97912 :   if (isCoupled(var_name))
     193             :   {
     194             :     mooseAssert(_coupled_vars.find(var_name) != _coupled_vars.end(),
     195             :                 var_name << " must not actually be coupled!");
     196        4540 :     return _coupled_vars.at(var_name).size();
     197             :   }
     198             :   else
     199             :   {
     200       93372 :     if (_c_parameters.hasDefaultCoupledValue(var_name))
     201          72 :       return _c_parameters.numberDefaultCoupledValues(var_name);
     202             :     else
     203       93300 :       return 0;
     204             :   }
     205       97912 : }
     206             : 
     207             : void
     208      164652 : checkComponent(const MooseObject * obj,
     209             :                unsigned int comp,
     210             :                unsigned int bound,
     211             :                const std::string & var_name)
     212             : {
     213      164652 :   if (bound > 0 && comp >= bound)
     214           8 :     obj->paramError(
     215             :         var_name, "component ", comp, " is out of range for this variable (max ", bound - 1, ")");
     216      164644 : }
     217             : 
     218             : // calls to this must go *after* get[bla]Var calls and (checking for nullptr
     219             : // return).  Because checkFuncType calls coupledCallback which should only be
     220             : // called if the variables was actually coupled.
     221             : void
     222      135353 : Coupleable::checkFuncType(const std::string var_name, VarType t, FuncAge age) const
     223             : {
     224      135353 :   if (t == VarType::Gradient && _c_nodal)
     225           0 :     mooseError(_c_name, ": nodal variables do not have gradients at nodes");
     226             : 
     227      135353 :   if (age == FuncAge::Old || age == FuncAge::Older || t == VarType::GradientDot ||
     228             :       t == VarType::Dot)
     229       51394 :     validateExecutionerType(var_name, "coupled[Vector][Gradient/Dot]Old[er]");
     230      135345 :   if (age == FuncAge::Older && !_c_is_implicit)
     231           0 :     mooseError("object '",
     232           0 :                _c_name,
     233             :                "' uses older variable values that are unavailable with explicit schemes");
     234             : 
     235      135345 :   coupledCallback(var_name, age == FuncAge::Old || age == FuncAge::Older);
     236      135345 : }
     237             : 
     238             : bool
     239      165333 : Coupleable::checkVar(const std::string & var_name_in,
     240             :                      unsigned int comp,
     241             :                      unsigned int comp_bound) const
     242             : {
     243      165333 :   const auto var_name = _c_parameters.checkForRename(var_name_in);
     244      165333 :   auto it = _c_coupled_scalar_vars.find(var_name);
     245      165333 :   if (it != _c_coupled_scalar_vars.end())
     246             :   {
     247           4 :     std::string cvars;
     248           8 :     for (auto jt : it->second)
     249           4 :       cvars += " " + jt->name();
     250             : 
     251           4 :     _obj->paramError(var_name,
     252             :                      "cannot couple '",
     253             :                      var_name,
     254             :                      "' to a scalar variable (",
     255             :                      cvars,
     256             :                      ") where field variable is expected");
     257           0 :   }
     258             : 
     259      165329 :   if (!isCoupled(var_name, comp))
     260        2302 :     return false; // return false since variable is *not* coupled
     261             : 
     262      163023 :   auto vars_vector_it = _coupled_vars.find(var_name);
     263      163023 :   if (vars_vector_it == _coupled_vars.end())
     264           0 :     mooseError(_c_name, ": Trying to get a coupled var ", var_name, " that doesn't exist");
     265             : 
     266      163023 :   const auto & vars_vector = vars_vector_it->second;
     267             : 
     268      163023 :   auto bound = comp_bound ? comp_bound : vars_vector.size();
     269      163023 :   checkComponent(_obj, comp, bound, var_name);
     270             : 
     271             :   // We should know we have a variable now
     272      163023 :   const auto * var = vars_vector[comp];
     273      163023 :   if (!var)
     274           0 :     mooseError(
     275           0 :         _c_name,
     276             :         ": We did all our checks for the existence of a var, yet we still don't have a var!?");
     277             : 
     278             :   // Only perform the following checks for objects that feed into residuals/Jacobians, e.g. objects
     279             :   // that inherit from the TaggingInterface
     280      163023 :   if (_c_parameters.have_parameter<MultiMooseEnum>("vector_tags"))
     281             :   {
     282             :     // Are we attempting to couple to a non-FV var in an FV object?
     283       18813 :     if (!var->isFV() && _is_fv)
     284           0 :       mooseError("Attempting to couple non-FV variable ",
     285           0 :                  var->name(),
     286             :                  " into an FV object ",
     287           0 :                  _c_name,
     288             :                  ". This is not currently supported");
     289             :   }
     290             : 
     291      163023 :   if (!(vars_vector[comp])->isNodal() && _c_nodal && !_c_allow_element_to_nodal_coupling)
     292           8 :     mooseError(_c_name, ": cannot couple elemental variables into nodal objects");
     293             : 
     294      163015 :   return true;
     295      165317 : }
     296             : 
     297             : const MooseVariableFieldBase *
     298           0 : Coupleable::getFEVar(const std::string & var_name, unsigned int comp) const
     299             : {
     300           0 :   mooseDeprecated("Coupleable::getFEVar is deprecated. Please use Coupleable::getFieldVar instead. "
     301             :                   "Note that this method could potentially return a finite volume variable");
     302           0 :   return getFieldVar(var_name, comp);
     303             : }
     304             : 
     305             : MooseVariableFieldBase *
     306        7248 : Coupleable::getFieldVar(const std::string & var_name, unsigned int comp)
     307             : {
     308        7248 :   return getVarHelper<MooseVariableFieldBase>(var_name, comp);
     309             : }
     310             : 
     311             : const MooseVariableFieldBase *
     312       23780 : Coupleable::getFieldVar(const std::string & var_name, unsigned int comp) const
     313             : {
     314       23780 :   return getVarHelper<MooseVariableFieldBase>(var_name, comp);
     315             : }
     316             : 
     317             : MooseVariable *
     318        3001 : Coupleable::getVar(const std::string & var_name, unsigned int comp)
     319             : {
     320        3001 :   return const_cast<MooseVariable *>(getVarHelper<MooseVariable>(var_name, comp));
     321             : }
     322             : 
     323             : VectorMooseVariable *
     324         557 : Coupleable::getVectorVar(const std::string & var_name, unsigned int comp)
     325             : {
     326             :   auto * const var =
     327         557 :       const_cast<VectorMooseVariable *>(getVarHelper<VectorMooseVariable>(var_name, comp));
     328             : 
     329         557 :   if (_c_nodal && var && var->feType().family != LAGRANGE_VEC)
     330           0 :     mooseError(_c_name, ": Only LAGRANGE_VEC vector variables are defined at nodes");
     331             : 
     332         557 :   return var;
     333             : }
     334             : 
     335             : ArrayMooseVariable *
     336         727 : Coupleable::getArrayVar(const std::string & var_name, unsigned int comp)
     337             : {
     338         727 :   return const_cast<ArrayMooseVariable *>(getVarHelper<ArrayMooseVariable>(var_name, comp));
     339             : }
     340             : 
     341             : const MooseVariable *
     342       25609 : Coupleable::getVar(const std::string & var_name, unsigned int comp) const
     343             : {
     344       25609 :   return getVarHelper<MooseVariable>(var_name, comp);
     345             : }
     346             : 
     347             : const VectorMooseVariable *
     348        1752 : Coupleable::getVectorVar(const std::string & var_name, unsigned int comp) const
     349             : {
     350        1752 :   const auto * const var = getVarHelper<VectorMooseVariable>(var_name, comp);
     351             : 
     352        1752 :   if (_c_nodal && var && var->feType().family != LAGRANGE_VEC)
     353           0 :     mooseError(_c_name, ": Only LAGRANGE_VEC vector variables are defined at nodes");
     354             : 
     355        1752 :   return var;
     356             : }
     357             : 
     358             : const ArrayMooseVariable *
     359        2259 : Coupleable::getArrayVar(const std::string & var_name, unsigned int comp) const
     360             : {
     361        2259 :   return getVarHelper<ArrayMooseVariable>(var_name, comp);
     362             : }
     363             : 
     364             : const VariableValue *
     365        1462 : Coupleable::getDefaultValue(const std::string & var_name, unsigned int comp) const
     366             : {
     367             :   // make sure we don't access values that were not provided
     368        1462 :   checkComponent(_obj, comp, _c_parameters.numberDefaultCoupledValues(var_name), var_name);
     369             : 
     370        1458 :   auto default_value_it = _default_value.find(var_name);
     371        1458 :   if (default_value_it == _default_value.end())
     372             :   {
     373        2852 :     _default_value[var_name].emplace_back(std::make_unique<VariableValue>(
     374        1426 :         _coupleable_max_qps, _c_parameters.defaultCoupledValue(var_name, 0)));
     375        1458 :     for (unsigned int j = 1; j < _c_parameters.numberDefaultCoupledValues(var_name); ++j)
     376          64 :       _default_value[var_name].emplace_back(std::make_unique<VariableValue>(
     377          64 :           _coupleable_max_qps, _c_parameters.defaultCoupledValue(var_name, j)));
     378        1426 :     default_value_it = _default_value.find(var_name);
     379             :   }
     380             : 
     381        1458 :   const auto & default_value_vec = default_value_it->second;
     382        1458 :   const auto n_default_vals = default_value_vec.size();
     383        1458 :   if (comp >= n_default_vals)
     384           0 :     mooseError("Requested comp ",
     385             :                comp,
     386             :                " is equal to or greater than the number of default values ",
     387             :                n_default_vals);
     388        2916 :   return default_value_vec[comp].get();
     389             : }
     390             : 
     391             : const VectorVariableValue *
     392         311 : Coupleable::getDefaultVectorValue(const std::string & var_name) const
     393             : {
     394         311 :   auto default_value_it = _default_vector_value.find(var_name);
     395         311 :   if (default_value_it == _default_vector_value.end())
     396             :   {
     397         311 :     auto value = std::make_unique<VectorVariableValue>(_coupleable_max_qps, 0);
     398         311 :     bool already_warned = false;
     399      311311 :     for (unsigned int qp = 0; qp < _coupleable_max_qps; ++qp)
     400     1244000 :       for (const auto i : make_range(Moose::dim))
     401             :       {
     402             :         try
     403             :         {
     404      933000 :           (*value)[qp](i) = _c_parameters.defaultCoupledValue(var_name, i);
     405             :         }
     406       11000 :         catch (const std::out_of_range &)
     407             :         {
     408       11000 :           if (!already_warned)
     409          11 :             mooseWarning(
     410             :                 "You supplied less than 3 arguments for the default vector value for variable ",
     411             :                 var_name,
     412             :                 ". Did you accidently leave something off? We are going to assign 0s, assuming "
     413             :                 "this "
     414             :                 "was intentional.");
     415       11000 :           already_warned = true;
     416       11000 :           (*value)[qp](i) = 0;
     417       11000 :         }
     418             :       }
     419         311 :     default_value_it =
     420         311 :         _default_vector_value.insert(std::make_pair(var_name, std::move(value))).first;
     421         311 :   }
     422             : 
     423         622 :   return default_value_it->second.get();
     424             : }
     425             : 
     426             : const ArrayVariableValue *
     427          14 : Coupleable::getDefaultArrayValue(const std::string & var_name) const
     428             : {
     429          14 :   auto default_value_it = _default_array_value.find(var_name);
     430          14 :   if (default_value_it == _default_array_value.end())
     431             :   {
     432          14 :     auto value = std::make_unique<ArrayVariableValue>(_coupleable_max_qps);
     433       14014 :     for (unsigned int qp = 0; qp < _coupleable_max_qps; ++qp)
     434             :     {
     435       14000 :       auto n = _c_parameters.numberDefaultCoupledValues(var_name);
     436       14000 :       (*value)[qp].resize(n);
     437       42000 :       for (unsigned int i = 0; i < n; ++i)
     438       28000 :         (*value)[qp](i) = _c_parameters.defaultCoupledValue(var_name, i);
     439             :     }
     440          14 :     default_value_it =
     441          14 :         _default_array_value.insert(std::make_pair(var_name, std::move(value))).first;
     442          14 :   }
     443             : 
     444          28 :   return default_value_it->second.get();
     445             : }
     446             : 
     447             : template <typename T>
     448             : const T &
     449           0 : Coupleable::getDefaultNodalValue(const std::string & var_name, unsigned int comp) const
     450             : {
     451           0 :   auto && default_variable_value = getDefaultValue(var_name, comp);
     452           0 :   return *default_variable_value->data();
     453             : }
     454             : 
     455             : template <>
     456             : const RealVectorValue &
     457           0 : Coupleable::getDefaultNodalValue<RealVectorValue>(const std::string & var_name, unsigned int) const
     458             : {
     459           0 :   auto && default_variable_value = getDefaultVectorValue(var_name);
     460           0 :   return *default_variable_value->data();
     461             : }
     462             : 
     463             : template <>
     464             : const RealEigenVector &
     465           0 : Coupleable::getDefaultNodalValue<RealEigenVector>(const std::string & var_name, unsigned int) const
     466             : {
     467           0 :   auto && default_variable_value = getDefaultArrayValue(var_name);
     468           0 :   return *default_variable_value->data();
     469             : }
     470             : 
     471             : unsigned int
     472       12744 : Coupleable::coupled(const std::string & var_name, unsigned int comp) const
     473             : {
     474       12744 :   const auto * var = getFieldVar(var_name, comp);
     475       12736 :   if (!var)
     476             :   {
     477             :     mooseAssert(_optional_var_index.find(var_name) != _optional_var_index.end(),
     478             :                 "optional var index for " << var_name << " does not exist!");
     479             :     // make sure we don't try to access default var ids that were not provided
     480         167 :     checkComponent(_obj, comp, _optional_var_index.at(var_name).size(), var_name);
     481         163 :     return _optional_var_index.at(var_name)[comp];
     482             :   }
     483       12569 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
     484             : 
     485       21570 :   if (var->kind() == Moose::VAR_SOLVER &&
     486             :       // are we not an object that feeds into the nonlinear system?
     487        9001 :       (!_c_sys || _c_sys->varKind() != Moose::VAR_SOLVER ||
     488             :        // are we an object that impacts the nonlinear system and this variable is within our
     489             :        // nonlinear system?
     490        5198 :        var->sys().number() == _c_sys->number()))
     491        8814 :     return var->number();
     492             :   else
     493             :     // Avoid registering coupling to variables outside of our system (e.g. avoid potentially
     494             :     // creating bad Jacobians)
     495        3755 :     return std::numeric_limits<unsigned int>::max() - var->number();
     496             : }
     497             : 
     498             : template <>
     499             : const GenericVariableValue<false> &
     500        5996 : Coupleable::coupledGenericValue<false>(const std::string & var_name, unsigned int comp) const
     501             : {
     502        5996 :   return coupledValue(var_name, comp);
     503             : }
     504             : 
     505             : template <>
     506             : const GenericVariableValue<true> &
     507         455 : Coupleable::coupledGenericValue<true>(const std::string & var_name, unsigned int comp) const
     508             : {
     509         455 :   return adCoupledValue(var_name, comp);
     510             : }
     511             : 
     512             : template <>
     513             : const GenericVectorVariableValue<false> &
     514         261 : Coupleable::coupledGenericVectorValue<false>(const std::string & var_name, unsigned int comp) const
     515             : {
     516         261 :   return coupledVectorValue(var_name, comp);
     517             : }
     518             : 
     519             : template <>
     520             : const GenericVectorVariableValue<true> &
     521          14 : Coupleable::coupledGenericVectorValue<true>(const std::string & var_name, unsigned int comp) const
     522             : {
     523          14 :   return adCoupledVectorValue(var_name, comp);
     524             : }
     525             : 
     526             : const VariableValue &
     527       57223 : Coupleable::coupledValue(const std::string & var_name, unsigned int comp) const
     528             : {
     529       57223 :   const auto * const var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
     530       57223 :   if (!var)
     531        1462 :     return *getDefaultValue(var_name, comp);
     532       55761 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
     533             : 
     534       55761 :   if (!_coupleable_neighbor)
     535             :   {
     536       54253 :     if (_c_nodal)
     537        4367 :       return (_c_is_implicit) ? var->dofValues() : var->dofValuesOld();
     538             :     else
     539       49886 :       return (_c_is_implicit) ? var->sln() : var->slnOld();
     540             :   }
     541             :   else
     542             :   {
     543        1508 :     if (_c_nodal)
     544           0 :       return (_c_is_implicit) ? var->dofValuesNeighbor() : var->dofValuesOldNeighbor();
     545             :     else
     546        1508 :       return (_c_is_implicit) ? var->slnNeighbor() : var->slnOldNeighbor();
     547             :   }
     548             : }
     549             : 
     550             : template <typename T>
     551             : const typename OutputTools<T>::VariableValue &
     552        1265 : Coupleable::vectorTagValueHelper(const std::string & var_names,
     553             :                                  const TagID tag,
     554             :                                  const unsigned int index) const
     555             : {
     556        1265 :   const auto * const var = getVarHelper<MooseVariableField<T>>(var_names, index);
     557        1265 :   if (!var)
     558           0 :     mooseError(var_names, ": invalid variable name for coupledVectorTagValue");
     559        1265 :   checkFuncType(var_names, VarType::Ignore, FuncAge::Curr);
     560             : 
     561        1265 :   if (!_c_fe_problem.vectorTagExists(tag))
     562           0 :     mooseError("Attempting to couple to vector tag with ID ",
     563             :                tag,
     564             :                "in ",
     565           0 :                _c_name,
     566             :                ", but a vector tag with that ID does not exist");
     567             : 
     568        1265 :   const_cast<Coupleable *>(this)->addFEVariableCoupleableVectorTag(tag);
     569             : 
     570        1265 :   if (_c_nodal)
     571         482 :     return var->nodalVectorTagValue(tag);
     572             :   else
     573         783 :     return var->vectorTagValue(tag);
     574             : }
     575             : 
     576             : template <typename T>
     577             : void
     578         134 : Coupleable::requestStates(const std::string & var_name,
     579             :                           const TagName & tag_name,
     580             :                           const unsigned int comp)
     581             : {
     582             :   auto var =
     583         134 :       const_cast<MooseVariableField<T> *>(getVarHelper<MooseVariableField<T>>(var_name, comp));
     584         134 :   if (!var)
     585           0 :     mooseError(var_name, ": invalid variable name for tag coupling");
     586             : 
     587         134 :   auto & var_sys = var->sys();
     588         134 :   if (tag_name == Moose::OLD_SOLUTION_TAG)
     589         106 :     var_sys.needSolutionState(1);
     590          28 :   else if (tag_name == Moose::OLDER_SOLUTION_TAG)
     591          28 :     var_sys.needSolutionState(2);
     592         134 : }
     593             : 
     594             : template <typename T>
     595             : const typename OutputTools<T>::VariableValue &
     596        1251 : Coupleable::vectorTagValueHelper(const std::string & var_names,
     597             :                                  const std::string & tag_param_name,
     598             :                                  const unsigned int index) const
     599             : {
     600        1251 :   if (!_c_parameters.isParamValid(tag_param_name))
     601           0 :     mooseError("Tag name parameter '", tag_param_name, "' is invalid");
     602             : 
     603        1251 :   const TagName tag_name = MooseUtils::toUpper(_c_parameters.get<TagName>(tag_param_name));
     604             : 
     605        1251 :   const bool older_state_tag = _older_state_tags.count(tag_name);
     606        1251 :   if (older_state_tag)
     607             :     // We may need to add solution states and create vector tags
     608         106 :     const_cast<Coupleable *>(this)->requestStates<T>(var_names, tag_name, index);
     609             : 
     610        1251 :   if (!_c_fe_problem.vectorTagExists(tag_name))
     611           0 :     mooseError("Tagged vector with tag name '", tag_name, "' does not exist");
     612             : 
     613        1251 :   TagID tag = _c_fe_problem.getVectorTagID(tag_name);
     614        2502 :   return vectorTagValueHelper<T>(var_names, tag, index);
     615        1251 : }
     616             : 
     617             : template <>
     618             : const GenericVariableValue<false> &
     619           0 : Coupleable::coupledGenericDofValue<false>(const std::string & var_name, unsigned int comp) const
     620             : {
     621           0 :   return coupledDofValues(var_name, comp);
     622             : }
     623             : 
     624             : template <>
     625             : const GenericVariableValue<true> &
     626           0 : Coupleable::coupledGenericDofValue<true>(const std::string & var_name, unsigned int comp) const
     627             : {
     628           0 :   return adCoupledDofValues(var_name, comp);
     629             : }
     630             : 
     631             : const VariableValue &
     632          14 : Coupleable::coupledValueLower(const std::string & var_name, const unsigned int comp) const
     633             : {
     634          14 :   const auto * var = getVar(var_name, comp);
     635          14 :   if (!var)
     636           0 :     return *getDefaultValue(var_name, comp);
     637          14 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
     638             : 
     639          14 :   if (_coupleable_neighbor)
     640           0 :     mooseError(_c_name, ":coupledValueLower cannot be called in a coupleable neighbor object");
     641             : 
     642          14 :   if (_c_nodal)
     643          14 :     return (_c_is_implicit) ? var->dofValues() : var->dofValuesOld();
     644             :   else
     645           0 :     return (_c_is_implicit) ? var->slnLower() : var->slnLowerOld();
     646             : }
     647             : 
     648             : const VariableValue &
     649          14 : Coupleable::coupledVectorTagValue(const std::string & var_names,
     650             :                                   TagID tag,
     651             :                                   unsigned int index) const
     652             : {
     653          14 :   return vectorTagValueHelper<Real>(var_names, tag, index);
     654             : }
     655             : 
     656             : const VariableValue &
     657        1201 : Coupleable::coupledVectorTagValue(const std::string & var_names,
     658             :                                   const std::string & tag_name,
     659             :                                   unsigned int index) const
     660             : {
     661        1201 :   return vectorTagValueHelper<Real>(var_names, tag_name, index);
     662             : }
     663             : 
     664             : const ArrayVariableValue &
     665           0 : Coupleable::coupledVectorTagArrayValue(const std::string & var_names,
     666             :                                        TagID tag,
     667             :                                        unsigned int index) const
     668             : {
     669           0 :   return vectorTagValueHelper<RealEigenVector>(var_names, tag, index);
     670             : }
     671             : 
     672             : const ArrayVariableValue &
     673          50 : Coupleable::coupledVectorTagArrayValue(const std::string & var_names,
     674             :                                        const std::string & tag_name,
     675             :                                        unsigned int index) const
     676             : {
     677          50 :   return vectorTagValueHelper<RealEigenVector>(var_names, tag_name, index);
     678             : }
     679             : 
     680             : const VariableGradient &
     681           0 : Coupleable::coupledVectorTagGradient(const std::string & var_names,
     682             :                                      TagID tag,
     683             :                                      unsigned int index) const
     684             : {
     685           0 :   const auto * var = getVar(var_names, index);
     686           0 :   if (!var)
     687           0 :     mooseError(var_names, ": invalid variable name for coupledVectorTagGradient");
     688           0 :   checkFuncType(var_names, VarType::Ignore, FuncAge::Curr);
     689             : 
     690           0 :   if (!_c_fe_problem.vectorTagExists(tag))
     691           0 :     mooseError("Attempting to couple to vector tag with ID ",
     692             :                tag,
     693             :                "in ",
     694           0 :                _c_name,
     695             :                ", but a vector tag with that ID does not exist");
     696             : 
     697           0 :   const_cast<Coupleable *>(this)->addFEVariableCoupleableVectorTag(tag);
     698             : 
     699           0 :   return var->vectorTagGradient(tag);
     700             : }
     701             : 
     702             : const VariableGradient &
     703           0 : Coupleable::coupledVectorTagGradient(const std::string & var_names,
     704             :                                      const std::string & tag_name,
     705             :                                      unsigned int index) const
     706             : {
     707           0 :   if (!_c_parameters.isParamValid(tag_name))
     708           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
     709             : 
     710           0 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
     711           0 :   if (!_c_fe_problem.vectorTagExists(tagname))
     712           0 :     mooseError("Tagged vector with tag name '", tagname, "' does not exist");
     713             : 
     714           0 :   TagID tag = _c_fe_problem.getVectorTagID(tagname);
     715           0 :   return coupledVectorTagGradient(var_names, tag, index);
     716           0 : }
     717             : 
     718             : const ArrayVariableGradient &
     719          28 : Coupleable::coupledVectorTagArrayGradient(const std::string & var_names,
     720             :                                           TagID tag,
     721             :                                           unsigned int index) const
     722             : {
     723          28 :   const auto * var = getArrayVar(var_names, index);
     724          28 :   if (!var)
     725           0 :     mooseError(var_names, ": invalid variable name for coupledVectorTagArrayGradient");
     726          28 :   checkFuncType(var_names, VarType::Ignore, FuncAge::Curr);
     727             : 
     728          28 :   if (!_c_fe_problem.vectorTagExists(tag))
     729           0 :     mooseError("Attempting to couple to vector tag with ID ",
     730             :                tag,
     731             :                "in ",
     732           0 :                _c_name,
     733             :                ", but a vector tag with that ID does not exist");
     734             : 
     735          28 :   const_cast<Coupleable *>(this)->addFEVariableCoupleableVectorTag(tag);
     736             : 
     737          28 :   return var->vectorTagGradient(tag);
     738             : }
     739             : 
     740             : const ArrayVariableGradient &
     741          28 : Coupleable::coupledVectorTagArrayGradient(const std::string & var_names,
     742             :                                           const std::string & tag_name,
     743             :                                           unsigned int index) const
     744             : {
     745          28 :   if (!_c_parameters.isParamValid(tag_name))
     746           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
     747             : 
     748          28 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
     749          28 :   if (!_c_fe_problem.vectorTagExists(tagname))
     750           0 :     mooseError("Tagged vector with tag name '", tagname, "' does not exist");
     751             : 
     752          28 :   TagID tag = _c_fe_problem.getVectorTagID(tagname);
     753          56 :   return coupledVectorTagArrayGradient(var_names, tag, index);
     754          28 : }
     755             : 
     756             : template <typename T>
     757             : const typename OutputTools<T>::VariableValue &
     758         148 : Coupleable::vectorTagDofValueHelper(const std::string & var_name,
     759             :                                     const TagID tag,
     760             :                                     const unsigned int comp) const
     761             : {
     762         148 :   const auto * var = getVarHelper<MooseVariableField<T>>(var_name, comp);
     763         148 :   if (!var)
     764           0 :     mooseError(var_name, ": invalid variable name for coupledVectorTagDofValue");
     765         148 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
     766             : 
     767         148 :   const_cast<Coupleable *>(this)->addFEVariableCoupleableVectorTag(tag);
     768             : 
     769         148 :   return var->vectorTagDofValue(tag);
     770             : }
     771             : 
     772             : template <typename T>
     773             : const typename OutputTools<T>::VariableValue &
     774         148 : Coupleable::vectorTagDofValueHelper(const std::string & var_name,
     775             :                                     const std::string & tag_param_name,
     776             :                                     const unsigned int comp) const
     777             : {
     778         148 :   if (!_c_parameters.isParamValid(tag_param_name))
     779           0 :     mooseError("Tag name parameter '", tag_param_name, "' is invalid");
     780             : 
     781         148 :   const TagName tag_name = MooseUtils::toUpper(_c_parameters.get<TagName>(tag_param_name));
     782             : 
     783         148 :   const bool older_state_tag = _older_state_tags.count(tag_name);
     784         148 :   if (older_state_tag)
     785             :     // We may need to add solution states and create vector tags
     786          28 :     const_cast<Coupleable *>(this)->requestStates<T>(var_name, tag_name, comp);
     787             : 
     788         148 :   if (!_c_fe_problem.vectorTagExists(tag_name))
     789           0 :     mooseError("Tagged vector with tag name '", tag_name, "' does not exist");
     790             : 
     791         148 :   TagID tag = _c_fe_problem.getVectorTagID(tag_name);
     792             : 
     793         296 :   return vectorTagDofValueHelper<T>(var_name, tag, comp);
     794         148 : }
     795             : 
     796             : const VariableValue &
     797           0 : Coupleable::coupledVectorTagDofValue(const std::string & var_name,
     798             :                                      TagID tag,
     799             :                                      unsigned int comp) const
     800             : {
     801           0 :   return vectorTagDofValueHelper<Real>(var_name, tag, comp);
     802             : }
     803             : 
     804             : const VariableValue &
     805         134 : Coupleable::coupledVectorTagDofValue(const std::string & var_name,
     806             :                                      const std::string & tag_name,
     807             :                                      unsigned int comp) const
     808             : {
     809         134 :   return vectorTagDofValueHelper<Real>(var_name, tag_name, comp);
     810             : }
     811             : 
     812             : const ArrayVariableValue &
     813          14 : Coupleable::coupledVectorTagArrayDofValue(const std::string & var_name,
     814             :                                           const std::string & tag_name,
     815             :                                           unsigned int comp) const
     816             : {
     817          14 :   return vectorTagDofValueHelper<RealEigenVector>(var_name, tag_name, comp);
     818             : }
     819             : 
     820             : const VariableValue &
     821         259 : Coupleable::coupledMatrixTagValue(const std::string & var_names,
     822             :                                   TagID tag,
     823             :                                   unsigned int index) const
     824             : {
     825         259 :   const auto * var = getVarHelper<MooseVariableField<Real>>(var_names, index);
     826         259 :   if (!var)
     827           0 :     mooseError(var_names, ": invalid variable name for coupledMatrixTagValue");
     828         259 :   checkFuncType(var_names, VarType::Ignore, FuncAge::Curr);
     829             : 
     830         259 :   const_cast<Coupleable *>(this)->addFEVariableCoupleableMatrixTag(tag);
     831             : 
     832         259 :   if (_c_nodal)
     833         205 :     return var->nodalMatrixTagValue(tag);
     834          54 :   return var->matrixTagValue(tag);
     835             : }
     836             : 
     837             : const VariableValue &
     838         259 : Coupleable::coupledMatrixTagValue(const std::string & var_names,
     839             :                                   const std::string & tag_name,
     840             :                                   unsigned int index) const
     841             : {
     842         259 :   if (!_c_parameters.isParamValid(tag_name))
     843           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
     844             : 
     845         259 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
     846         259 :   if (!_c_fe_problem.matrixTagExists(tagname))
     847           0 :     mooseError("Matrix tag name '", tagname, "' does not exist");
     848             : 
     849         259 :   TagID tag = _c_fe_problem.getMatrixTagID(tagname);
     850         518 :   return coupledMatrixTagValue(var_names, tag, index);
     851         259 : }
     852             : 
     853             : const VectorVariableValue &
     854         935 : Coupleable::coupledVectorValue(const std::string & var_name, unsigned int comp) const
     855             : {
     856         935 :   const auto * var = getVectorVar(var_name, comp);
     857         935 :   if (!var)
     858         311 :     return *getDefaultVectorValue(var_name);
     859         624 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
     860             : 
     861         624 :   if (!_coupleable_neighbor)
     862             :   {
     863         596 :     if (_c_nodal)
     864          70 :       return _c_is_implicit ? var->nodalValueArray() : var->nodalValueOldArray();
     865             :     else
     866         526 :       return _c_is_implicit ? var->sln() : var->slnOld();
     867             :   }
     868             :   else
     869             :   {
     870          28 :     if (_c_nodal)
     871             :       // Since this is at a node, I don't feel like there should be any "neighbor" logic
     872           0 :       return _c_is_implicit ? var->nodalValueArray() : var->nodalValueOldArray();
     873             :     else
     874          28 :       return _c_is_implicit ? var->slnNeighbor() : var->slnOldNeighbor();
     875             :   }
     876             : }
     877             : 
     878             : const ArrayVariableValue &
     879        1217 : Coupleable::coupledArrayValue(const std::string & var_name, unsigned int comp) const
     880             : {
     881        1217 :   const auto * var = getArrayVar(var_name, comp);
     882        1217 :   if (!var)
     883          14 :     return *getDefaultArrayValue(var_name);
     884        1203 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
     885             : 
     886        1203 :   if (!_coupleable_neighbor)
     887             :   {
     888        1203 :     if (_c_nodal)
     889          92 :       return (_c_is_implicit) ? var->dofValues() : var->dofValuesOld();
     890        1111 :     return (_c_is_implicit) ? var->sln() : var->slnOld();
     891             :   }
     892             :   else
     893             :   {
     894           0 :     if (_c_nodal)
     895           0 :       return (_c_is_implicit) ? var->dofValuesNeighbor() : var->dofValuesOldNeighbor();
     896           0 :     return (_c_is_implicit) ? var->slnNeighbor() : var->slnOldNeighbor();
     897             :   }
     898             : }
     899             : 
     900             : std::vector<const ArrayVariableValue *>
     901          18 : Coupleable::coupledArrayValues(const std::string & var_name) const
     902             : {
     903          36 :   auto func = [this, &var_name](unsigned int comp) { return &coupledArrayValue(var_name, comp); };
     904          36 :   return coupledVectorHelper<const ArrayVariableValue *>(var_name, func);
     905             : }
     906             : 
     907             : MooseWritableVariable &
     908         282 : Coupleable::writableVariable(const std::string & var_name, unsigned int comp)
     909             : {
     910         282 :   auto * var = getVarHelper<MooseWritableVariable>(var_name, comp);
     911             : 
     912         278 :   const auto * aux = dynamic_cast<const AuxKernel *>(this);
     913         278 :   const auto * euo = dynamic_cast<const ElementUserObject *>(this);
     914         278 :   const auto * nuo = dynamic_cast<const NodalUserObject *>(this);
     915         278 :   const auto * nfc = dynamic_cast<const NodeFaceConstraint *>(this);
     916         278 :   const auto * nec = dynamic_cast<const NodeElemConstraintBase *>(this);
     917             : 
     918         278 :   if (!aux && !euo && !nuo && !nfc && !nec)
     919           4 :     mooseError("writableVariable() can only be called from AuxKernels, ElementUserObjects, "
     920             :                "NodalUserObjects, NodeFaceConstraints, or NodeElemConstraints. '",
     921           4 :                _obj->name(),
     922             :                "' is none of those.");
     923             : 
     924         274 :   if (aux && !aux->isNodal() && var->isNodal())
     925           4 :     mooseError("The elemental AuxKernel '",
     926           4 :                _obj->name(),
     927             :                "' cannot obtain a writable reference to the nodal variable '",
     928           4 :                var->name(),
     929             :                "'.");
     930         270 :   if (euo && var->isNodal())
     931           4 :     mooseError("The ElementUserObject '",
     932           4 :                _obj->name(),
     933             :                "' cannot obtain a writable reference to the nodal variable '",
     934           4 :                var->name(),
     935             :                "'.");
     936             : 
     937             :   // make sure only one object can access a variable
     938         266 :   checkWritableVar(var);
     939             : 
     940         254 :   return *var;
     941             : }
     942             : 
     943             : VariableValue &
     944          44 : Coupleable::writableCoupledValue(const std::string & var_name, unsigned int comp)
     945             : {
     946          44 :   mooseDeprecated("Coupleable::writableCoupledValue is deprecated, please use "
     947             :                   "Coupleable::writableVariable instead. ");
     948             : 
     949             :   // check if the variable exists
     950          44 :   auto * const var = getVar(var_name, comp);
     951          44 :   if (!var)
     952           4 :     mooseError(
     953             :         "Unable to create a writable reference for '", var_name, "', is it a constant expression?");
     954             : 
     955             :   // is the requested variable an AuxiliaryVariable?
     956          40 :   if (!_c_fe_problem.getAuxiliarySystem().hasVariable(var->name()))
     957           4 :     mooseError(
     958           4 :         "'", var->name(), "' must be an auxiliary variable in Coupleable::writableCoupledValue");
     959             : 
     960             :   // check that the variable type (elemental/nodal) is compatible with the object type
     961          36 :   const auto * aux = dynamic_cast<const AuxKernel *>(this);
     962             : 
     963          36 :   if (!aux)
     964           4 :     mooseError("writableCoupledValue() can only be called from AuxKernels, but '",
     965           4 :                _obj->name(),
     966             :                "' is not an AuxKernel.");
     967             : 
     968          32 :   if (!aux->isNodal() && var->isNodal())
     969           4 :     mooseError("The elemental AuxKernel '",
     970           4 :                _obj->name(),
     971             :                "' cannot obtain a writable reference to the nodal variable '",
     972           4 :                var->name(),
     973             :                "'.");
     974             : 
     975             :   // make sure only one object can access a variable
     976          28 :   checkWritableVar(var);
     977             : 
     978          28 :   return const_cast<VariableValue &>(coupledValue(var_name, comp));
     979             : }
     980             : 
     981             : void
     982         294 : Coupleable::checkWritableVar(MooseWritableVariable * var)
     983             : {
     984             :   // check domain restrictions for compatibility
     985         294 :   const auto * br = dynamic_cast<const BlockRestrictable *>(this);
     986         294 :   const auto * nfc = dynamic_cast<const NodeFaceConstraint *>(this);
     987             : 
     988         294 :   if (br && !var->hasBlocks(br->blockIDs()))
     989           4 :     mooseError("The variable '",
     990           4 :                var->name(),
     991             :                "' must be defined on all blocks '",
     992           4 :                _obj->name(),
     993             :                "' is defined on.");
     994             : 
     995         290 :   if (nfc && !var->hasBlocks(nfc->getSecondaryConnectedBlocks()))
     996           0 :     mooseError("The variable '",
     997           0 :                var->name(),
     998             :                " must be defined on all blocks '",
     999           0 :                _obj->name(),
    1000             :                "'s secondary surface is defined on.");
    1001             : 
    1002             :   // make sure only one object can access a variable
    1003        1080 :   for (const auto & ci : _obj->getMooseApp().getInterfaceObjects<Coupleable>())
    1004         798 :     if (ci != this && ci->_writable_coupled_variables[_c_tid].count(var))
    1005             :     {
    1006             :       // if both this and ci are block restrictable then we check if the block restrictions
    1007             :       // are not overlapping. If they don't we permit the call.
    1008          41 :       const auto * br_other = dynamic_cast<const BlockRestrictable *>(ci);
    1009          78 :       if (br && br_other && br->blockRestricted() && br_other->blockRestricted() &&
    1010          37 :           !MooseUtils::setsIntersect(br->blockIDs(), br_other->blockIDs()))
    1011          33 :         continue;
    1012           8 :       else if (nfc)
    1013           0 :         continue;
    1014             : 
    1015           8 :       mooseError("'",
    1016           8 :                  ci->_obj->name(),
    1017             :                  "' already obtained a writable reference to '",
    1018           8 :                  var->name(),
    1019             :                  "'. Only one object can obtain such a reference per variable and subdomain in a "
    1020             :                  "simulation.");
    1021             :     }
    1022             : 
    1023             :   // var is unique across threads, so we could forego having a separate set per thread, but we
    1024             :   // need quick access to the list of all variables that need to be inserted into the solution
    1025             :   // vector by a given thread.
    1026             : 
    1027         282 :   _writable_coupled_variables[_c_tid].insert(var);
    1028         282 : }
    1029             : 
    1030             : const VariableValue &
    1031       12250 : Coupleable::coupledValueOld(const std::string & var_name, unsigned int comp) const
    1032             : {
    1033       12250 :   const auto * var = getVar(var_name, comp);
    1034       12250 :   if (!var)
    1035           0 :     return *getDefaultValue(var_name, comp);
    1036       12250 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Old);
    1037             : 
    1038       12250 :   if (!_coupleable_neighbor)
    1039             :   {
    1040        8279 :     if (_c_nodal)
    1041          96 :       return (_c_is_implicit) ? var->dofValuesOld() : var->dofValuesOlder();
    1042        8183 :     return (_c_is_implicit) ? var->slnOld() : var->slnOlder();
    1043             :   }
    1044             :   else
    1045             :   {
    1046        3971 :     if (_c_nodal)
    1047           0 :       return (_c_is_implicit) ? var->dofValuesOldNeighbor() : var->dofValuesOlderNeighbor();
    1048        3971 :     return (_c_is_implicit) ? var->slnOldNeighbor() : var->slnOlderNeighbor();
    1049             :   }
    1050             : }
    1051             : 
    1052             : const VariableValue &
    1053       11928 : Coupleable::coupledValueOlder(const std::string & var_name, unsigned int comp) const
    1054             : {
    1055       11928 :   const auto * var = getVar(var_name, comp);
    1056       11928 :   if (!var)
    1057           0 :     return *getDefaultValue(var_name, comp);
    1058       11928 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Older);
    1059             : 
    1060       11928 :   if (!_coupleable_neighbor)
    1061             :   {
    1062        7980 :     if (_c_nodal)
    1063          42 :       return var->dofValuesOlder();
    1064        7938 :     return var->slnOlder();
    1065             :   }
    1066             :   else
    1067             :   {
    1068        3948 :     if (_c_nodal)
    1069           0 :       return var->dofValuesOlderNeighbor();
    1070        3948 :     return var->slnOlderNeighbor();
    1071             :   }
    1072             : }
    1073             : 
    1074             : const VariableValue &
    1075          82 : Coupleable::coupledValuePreviousNL(const std::string & var_name, unsigned int comp) const
    1076             : {
    1077          82 :   const auto * var = getVar(var_name, comp);
    1078          82 :   if (!var)
    1079           0 :     return *getDefaultValue(var_name, comp);
    1080          82 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    1081             : 
    1082          82 :   _c_fe_problem.needsPreviousNewtonIteration(true);
    1083          82 :   if (!_coupleable_neighbor)
    1084             :   {
    1085          82 :     if (_c_nodal)
    1086           0 :       return var->dofValuesPreviousNL();
    1087          82 :     return var->slnPreviousNL();
    1088             :   }
    1089             :   else
    1090             :   {
    1091           0 :     if (_c_nodal)
    1092           0 :       return var->dofValuesPreviousNLNeighbor();
    1093           0 :     return var->slnPreviousNLNeighbor();
    1094             :   }
    1095             : }
    1096             : 
    1097             : const VectorVariableValue &
    1098          56 : Coupleable::coupledVectorValueOld(const std::string & var_name, unsigned int comp) const
    1099             : {
    1100          56 :   const auto * var = getVectorVar(var_name, comp);
    1101          56 :   if (!var)
    1102           0 :     return *getDefaultVectorValue(var_name);
    1103          56 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Old);
    1104             : 
    1105          56 :   if (_c_nodal)
    1106          28 :     return (_c_is_implicit) ? var->nodalValueOldArray() : var->nodalValueOlderArray();
    1107          28 :   if (!_coupleable_neighbor)
    1108          28 :     return (_c_is_implicit) ? var->slnOld() : var->slnOlder();
    1109           0 :   return (_c_is_implicit) ? var->slnOldNeighbor() : var->slnOlderNeighbor();
    1110             : }
    1111             : 
    1112             : const VectorVariableValue &
    1113           0 : Coupleable::coupledVectorValueOlder(const std::string & var_name, unsigned int comp) const
    1114             : {
    1115           0 :   const auto * var = getVectorVar(var_name, comp);
    1116           0 :   if (!var)
    1117           0 :     return *getDefaultVectorValue(var_name);
    1118           0 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Older);
    1119             : 
    1120           0 :   if (!_coupleable_neighbor)
    1121           0 :     return var->slnOlder();
    1122           0 :   return var->slnOlderNeighbor();
    1123             : }
    1124             : 
    1125             : const ArrayVariableValue &
    1126           0 : Coupleable::coupledArrayValueOld(const std::string & var_name, unsigned int comp) const
    1127             : {
    1128           0 :   const auto * var = getArrayVar(var_name, comp);
    1129           0 :   if (!var)
    1130           0 :     return *getDefaultArrayValue(var_name);
    1131           0 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Old);
    1132             : 
    1133           0 :   if (!_coupleable_neighbor)
    1134             :   {
    1135           0 :     if (_c_nodal)
    1136           0 :       return (_c_is_implicit) ? var->dofValuesOld() : var->dofValuesOlder();
    1137           0 :     return (_c_is_implicit) ? var->slnOld() : var->slnOlder();
    1138             :   }
    1139             :   else
    1140             :   {
    1141           0 :     if (_c_nodal)
    1142           0 :       return (_c_is_implicit) ? var->dofValuesOldNeighbor() : var->dofValuesOlderNeighbor();
    1143           0 :     return (_c_is_implicit) ? var->slnOldNeighbor() : var->slnOlderNeighbor();
    1144             :   }
    1145             : }
    1146             : 
    1147             : const ArrayVariableValue &
    1148           0 : Coupleable::coupledArrayValueOlder(const std::string & var_name, unsigned int comp) const
    1149             : {
    1150           0 :   const auto * var = getArrayVar(var_name, comp);
    1151           0 :   if (!var)
    1152           0 :     return *getDefaultArrayValue(var_name);
    1153           0 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Older);
    1154             : 
    1155           0 :   if (!_coupleable_neighbor)
    1156             :   {
    1157           0 :     if (_c_nodal)
    1158           0 :       return var->dofValuesOlder();
    1159           0 :     return var->slnOlder();
    1160             :   }
    1161             :   else
    1162             :   {
    1163           0 :     if (_c_nodal)
    1164           0 :       return var->dofValuesOlderNeighbor();
    1165           0 :     return var->slnOlderNeighbor();
    1166             :   }
    1167             : }
    1168             : 
    1169             : const VariableValue &
    1170         296 : Coupleable::coupledDot(const std::string & var_name, unsigned int comp) const
    1171             : {
    1172         296 :   const auto * var = getVar(var_name, comp);
    1173         296 :   if (!var)
    1174             :   {
    1175           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1176           0 :     return _default_value_zero;
    1177             :   }
    1178         296 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1179             : 
    1180         292 :   if (!_coupleable_neighbor)
    1181             :   {
    1182         264 :     if (_c_nodal)
    1183          42 :       return var->dofValuesDot();
    1184         222 :     return var->uDot();
    1185             :   }
    1186             :   else
    1187             :   {
    1188          28 :     if (_c_nodal)
    1189           0 :       return var->dofValuesDotNeighbor();
    1190          28 :     return var->uDotNeighbor();
    1191             :   }
    1192             : }
    1193             : 
    1194             : const VariableValue &
    1195         181 : Coupleable::coupledDotDot(const std::string & var_name, unsigned int comp) const
    1196             : {
    1197         181 :   const auto * var = getVar(var_name, comp);
    1198         181 :   if (!var)
    1199             :   {
    1200           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1201           0 :     return _default_value_zero;
    1202             :   }
    1203         181 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1204             : 
    1205         181 :   if (!_coupleable_neighbor)
    1206             :   {
    1207         153 :     if (_c_nodal)
    1208           4 :       return var->dofValuesDotDot();
    1209         149 :     return var->uDotDot();
    1210             :   }
    1211             :   else
    1212             :   {
    1213          28 :     if (_c_nodal)
    1214           0 :       return var->dofValuesDotDotNeighbor();
    1215          28 :     return var->uDotDotNeighbor();
    1216             :   }
    1217             : }
    1218             : 
    1219             : template <>
    1220             : const GenericVariableValue<false> &
    1221          84 : Coupleable::coupledGenericDotDot<false>(const std::string & var_name, unsigned int comp) const
    1222             : {
    1223          84 :   return coupledDotDot(var_name, comp);
    1224             : }
    1225             : 
    1226             : template <>
    1227             : const GenericVariableValue<true> &
    1228          42 : Coupleable::coupledGenericDotDot<true>(const std::string & var_name, unsigned int comp) const
    1229             : {
    1230          42 :   return adCoupledDotDot(var_name, comp);
    1231             : }
    1232             : 
    1233             : const VariableValue &
    1234           0 : Coupleable::coupledDotOld(const std::string & var_name, unsigned int comp) const
    1235             : {
    1236           0 :   const auto * var = getVar(var_name, comp);
    1237           0 :   if (!var)
    1238             :   {
    1239           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1240           0 :     return _default_value_zero;
    1241             :   }
    1242           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    1243             : 
    1244           0 :   if (!_coupleable_neighbor)
    1245             :   {
    1246           0 :     if (_c_nodal)
    1247           0 :       return var->dofValuesDotOld();
    1248           0 :     return var->uDotOld();
    1249             :   }
    1250             :   else
    1251             :   {
    1252           0 :     if (_c_nodal)
    1253           0 :       return var->dofValuesDotOldNeighbor();
    1254           0 :     return var->uDotOldNeighbor();
    1255             :   }
    1256             : }
    1257             : 
    1258             : const VariableValue &
    1259           0 : Coupleable::coupledDotDotOld(const std::string & var_name, unsigned int comp) const
    1260             : {
    1261           0 :   const auto * var = getVar(var_name, comp);
    1262           0 :   if (!var)
    1263             :   {
    1264           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1265           0 :     return _default_value_zero;
    1266             :   }
    1267           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    1268             : 
    1269           0 :   if (!_coupleable_neighbor)
    1270             :   {
    1271           0 :     if (_c_nodal)
    1272           0 :       return var->dofValuesDotDotOld();
    1273           0 :     return var->uDotDotOld();
    1274             :   }
    1275             :   else
    1276             :   {
    1277           0 :     if (_c_nodal)
    1278           0 :       return var->dofValuesDotDotOldNeighbor();
    1279           0 :     return var->uDotDotOldNeighbor();
    1280             :   }
    1281             : }
    1282             : 
    1283             : const VectorVariableValue &
    1284         123 : Coupleable::coupledVectorDot(const std::string & var_name, unsigned int comp) const
    1285             : {
    1286         123 :   const auto * var = getVectorVar(var_name, comp);
    1287         123 :   if (!var)
    1288             :   {
    1289           0 :     _default_vector_value_zero.resize(_coupleable_max_qps);
    1290           0 :     return _default_vector_value_zero;
    1291             :   }
    1292         123 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1293             : 
    1294         123 :   if (!_coupleable_neighbor)
    1295          95 :     return var->uDot();
    1296          28 :   return var->uDotNeighbor();
    1297             : }
    1298             : 
    1299             : const VectorVariableValue &
    1300          42 : Coupleable::coupledVectorDotDot(const std::string & var_name, unsigned int comp) const
    1301             : {
    1302          42 :   const auto * var = getVectorVar(var_name, comp);
    1303          42 :   if (!var)
    1304             :   {
    1305           0 :     _default_vector_value_zero.resize(_coupleable_max_qps);
    1306           0 :     return _default_vector_value_zero;
    1307             :   }
    1308          42 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1309             : 
    1310          42 :   if (!_coupleable_neighbor)
    1311          28 :     return var->uDotDot();
    1312          14 :   return var->uDotDotNeighbor();
    1313             : }
    1314             : 
    1315             : const VectorVariableValue &
    1316           0 : Coupleable::coupledVectorDotOld(const std::string & var_name, unsigned int comp) const
    1317             : {
    1318           0 :   const auto * var = getVectorVar(var_name, comp);
    1319           0 :   if (!var)
    1320             :   {
    1321           0 :     _default_vector_value_zero.resize(_coupleable_max_qps);
    1322           0 :     return _default_vector_value_zero;
    1323             :   }
    1324           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    1325             : 
    1326           0 :   if (!_coupleable_neighbor)
    1327           0 :     return var->uDotOld();
    1328           0 :   return var->uDotOldNeighbor();
    1329             : }
    1330             : 
    1331             : const VectorVariableValue &
    1332           0 : Coupleable::coupledVectorDotDotOld(const std::string & var_name, unsigned int comp) const
    1333             : {
    1334           0 :   const auto * var = getVectorVar(var_name, comp);
    1335           0 :   if (!var)
    1336             :   {
    1337           0 :     _default_vector_value_zero.resize(_coupleable_max_qps);
    1338           0 :     return _default_vector_value_zero;
    1339             :   }
    1340           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    1341             : 
    1342           0 :   if (!_coupleable_neighbor)
    1343           0 :     return var->uDotDotOld();
    1344           0 :   return var->uDotDotOldNeighbor();
    1345             : }
    1346             : 
    1347             : const VariableValue &
    1348         123 : Coupleable::coupledVectorDotDu(const std::string & var_name, unsigned int comp) const
    1349             : {
    1350         123 :   const auto * var = getVectorVar(var_name, comp);
    1351         123 :   if (!var)
    1352             :   {
    1353           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1354           0 :     return _default_value_zero;
    1355             :   }
    1356         123 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1357             : 
    1358         123 :   if (!_coupleable_neighbor)
    1359          95 :     return var->duDotDu();
    1360          28 :   return var->duDotDuNeighbor();
    1361             : }
    1362             : 
    1363             : const VariableValue &
    1364          42 : Coupleable::coupledVectorDotDotDu(const std::string & var_name, unsigned int comp) const
    1365             : {
    1366          42 :   const auto * var = getVectorVar(var_name, comp);
    1367          42 :   if (!var)
    1368             :   {
    1369           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1370           0 :     return _default_value_zero;
    1371             :   }
    1372          42 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1373             : 
    1374          42 :   if (!_coupleable_neighbor)
    1375          28 :     return var->duDotDotDu();
    1376          14 :   return var->duDotDotDuNeighbor();
    1377             : }
    1378             : 
    1379             : const ArrayVariableValue &
    1380          47 : Coupleable::coupledArrayDot(const std::string & var_name, unsigned int comp) const
    1381             : {
    1382          47 :   const auto * var = getArrayVar(var_name, comp);
    1383          47 :   if (!var)
    1384           0 :     return _default_array_value_zero;
    1385          47 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1386             : 
    1387          47 :   if (!_coupleable_neighbor)
    1388             :   {
    1389          47 :     if (_c_nodal)
    1390           0 :       return var->dofValuesDot();
    1391          47 :     return var->uDot();
    1392             :   }
    1393             :   else
    1394             :   {
    1395           0 :     if (_c_nodal)
    1396           0 :       return var->dofValuesDotNeighbor();
    1397           0 :     return var->uDotNeighbor();
    1398             :   }
    1399             : }
    1400             : 
    1401             : const ArrayVariableValue &
    1402           0 : Coupleable::coupledArrayDotDot(const std::string & var_name, unsigned int comp) const
    1403             : {
    1404           0 :   const auto * var = getArrayVar(var_name, comp);
    1405           0 :   if (!var)
    1406           0 :     return _default_array_value_zero;
    1407           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1408             : 
    1409           0 :   if (!_coupleable_neighbor)
    1410             :   {
    1411           0 :     if (_c_nodal)
    1412           0 :       return var->dofValuesDotDot();
    1413           0 :     return var->uDotDot();
    1414             :   }
    1415             :   else
    1416             :   {
    1417           0 :     if (_c_nodal)
    1418           0 :       return var->dofValuesDotDotNeighbor();
    1419           0 :     return var->uDotDotNeighbor();
    1420             :   }
    1421             : }
    1422             : 
    1423             : const ArrayVariableValue &
    1424           0 : Coupleable::coupledArrayDotOld(const std::string & var_name, unsigned int comp) const
    1425             : {
    1426           0 :   const auto * var = getArrayVar(var_name, comp);
    1427           0 :   if (!var)
    1428           0 :     return _default_array_value_zero;
    1429           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    1430             : 
    1431           0 :   if (!_coupleable_neighbor)
    1432             :   {
    1433           0 :     if (_c_nodal)
    1434           0 :       return var->dofValuesDotOld();
    1435           0 :     return var->uDotOld();
    1436             :   }
    1437             :   else
    1438             :   {
    1439           0 :     if (_c_nodal)
    1440           0 :       return var->dofValuesDotOldNeighbor();
    1441           0 :     return var->uDotOldNeighbor();
    1442             :   }
    1443             : }
    1444             : 
    1445             : const ArrayVariableValue &
    1446           0 : Coupleable::coupledArrayDotDotOld(const std::string & var_name, unsigned int comp) const
    1447             : {
    1448           0 :   const auto * var = getArrayVar(var_name, comp);
    1449           0 :   if (!var)
    1450           0 :     return _default_array_value_zero;
    1451           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    1452             : 
    1453           0 :   if (!_coupleable_neighbor)
    1454             :   {
    1455           0 :     if (_c_nodal)
    1456           0 :       return var->dofValuesDotDotOld();
    1457           0 :     return var->uDotDotOld();
    1458             :   }
    1459             :   else
    1460             :   {
    1461           0 :     if (_c_nodal)
    1462           0 :       return var->dofValuesDotDotOldNeighbor();
    1463           0 :     return var->uDotDotOldNeighbor();
    1464             :   }
    1465             : }
    1466             : 
    1467             : const VariableValue &
    1468         179 : Coupleable::coupledDotDu(const std::string & var_name, unsigned int comp) const
    1469             : {
    1470         179 :   const auto * var = getVar(var_name, comp);
    1471         179 :   if (!var)
    1472             :   {
    1473           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1474           0 :     return _default_value_zero;
    1475             :   }
    1476         179 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1477             : 
    1478         179 :   if (!_coupleable_neighbor)
    1479             :   {
    1480         137 :     if (_c_nodal)
    1481           0 :       return var->dofValuesDuDotDu();
    1482         137 :     return var->duDotDu();
    1483             :   }
    1484             :   else
    1485             :   {
    1486          42 :     if (_c_nodal)
    1487           0 :       return var->dofValuesDuDotDuNeighbor();
    1488          42 :     return var->duDotDuNeighbor();
    1489             :   }
    1490             : }
    1491             : 
    1492             : const VariableValue &
    1493         126 : Coupleable::coupledDotDotDu(const std::string & var_name, unsigned int comp) const
    1494             : {
    1495         126 :   const auto * var = getVar(var_name, comp);
    1496         126 :   if (!var)
    1497             :   {
    1498           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1499           0 :     return _default_value_zero;
    1500             :   }
    1501         126 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1502             : 
    1503         126 :   if (!_coupleable_neighbor)
    1504             :   {
    1505          84 :     if (_c_nodal)
    1506           0 :       return var->dofValuesDuDotDotDu();
    1507          84 :     return var->duDotDotDu();
    1508             :   }
    1509             :   else
    1510             :   {
    1511          42 :     if (_c_nodal)
    1512           0 :       return var->dofValuesDuDotDotDuNeighbor();
    1513          42 :     return var->duDotDotDuNeighbor();
    1514             :   }
    1515             : }
    1516             : 
    1517             : const VariableValue &
    1518          47 : Coupleable::coupledArrayDotDu(const std::string & var_name, unsigned int comp) const
    1519             : {
    1520          47 :   const auto * const var = getArrayVar(var_name, comp);
    1521          47 :   if (!var)
    1522             :   {
    1523           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    1524           0 :     return _default_value_zero;
    1525             :   }
    1526          47 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    1527             : 
    1528          47 :   if (!_coupleable_neighbor)
    1529             :   {
    1530          47 :     if (_c_nodal)
    1531           0 :       return var->dofValuesDuDotDu();
    1532          47 :     return var->duDotDu();
    1533             :   }
    1534             :   else
    1535             :   {
    1536           0 :     if (_c_nodal)
    1537           0 :       return var->dofValuesDuDotDuNeighbor();
    1538           0 :     return var->duDotDuNeighbor();
    1539             :   }
    1540             : }
    1541             : 
    1542             : const VariableGradient &
    1543       32575 : Coupleable::coupledGradient(const std::string & var_name, unsigned int comp) const
    1544             : {
    1545       32575 :   const auto * const var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    1546       32571 :   if (!var)
    1547             :   {
    1548          38 :     _default_gradient.resize(_coupleable_max_qps);
    1549          38 :     return _default_gradient;
    1550             :   }
    1551       32533 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    1552             : 
    1553       32533 :   if (!_coupleable_neighbor)
    1554       32519 :     return (_c_is_implicit) ? var->gradSln() : var->gradSlnOld();
    1555          14 :   return (_c_is_implicit) ? var->gradSlnNeighbor() : var->gradSlnOldNeighbor();
    1556             : }
    1557             : 
    1558             : const VariableGradient &
    1559           4 : Coupleable::coupledGradientOld(const std::string & var_name, unsigned int comp) const
    1560             : {
    1561           4 :   const auto * var = getVar(var_name, comp);
    1562           4 :   if (!var)
    1563             :   {
    1564           0 :     _default_gradient.resize(_coupleable_max_qps);
    1565           0 :     return _default_gradient;
    1566             :   }
    1567           4 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Old);
    1568             : 
    1569           0 :   if (!_coupleable_neighbor)
    1570           0 :     return (_c_is_implicit) ? var->gradSlnOld() : var->gradSlnOlder();
    1571           0 :   return (_c_is_implicit) ? var->gradSlnOldNeighbor() : var->gradSlnOlderNeighbor();
    1572             : }
    1573             : 
    1574             : const VariableGradient &
    1575           0 : Coupleable::coupledGradientOlder(const std::string & var_name, unsigned int comp) const
    1576             : {
    1577           0 :   const auto * var = getVar(var_name, comp);
    1578           0 :   if (!var)
    1579             :   {
    1580           0 :     _default_gradient.resize(_coupleable_max_qps);
    1581           0 :     return _default_gradient;
    1582             :   }
    1583           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Older);
    1584             : 
    1585           0 :   if (!_coupleable_neighbor)
    1586           0 :     return var->gradSlnOlder();
    1587           0 :   return var->gradSlnOlderNeighbor();
    1588             : }
    1589             : 
    1590             : const VariableGradient &
    1591           0 : Coupleable::coupledGradientPreviousNL(const std::string & var_name, unsigned int comp) const
    1592             : {
    1593           0 :   const auto * var = getVar(var_name, comp);
    1594           0 :   _c_fe_problem.needsPreviousNewtonIteration(true);
    1595           0 :   if (!var)
    1596             :   {
    1597           0 :     _default_gradient.resize(_coupleable_max_qps);
    1598           0 :     return _default_gradient;
    1599             :   }
    1600           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    1601             : 
    1602           0 :   if (!_coupleable_neighbor)
    1603           0 :     return var->gradSlnPreviousNL();
    1604           0 :   return var->gradSlnPreviousNLNeighbor();
    1605             : }
    1606             : 
    1607             : const VariableGradient &
    1608          25 : Coupleable::coupledGradientDot(const std::string & var_name, unsigned int comp) const
    1609             : {
    1610          25 :   const auto * var = getVar(var_name, comp);
    1611          25 :   if (!var)
    1612             :   {
    1613           0 :     _default_gradient.resize(_coupleable_max_qps);
    1614           0 :     return _default_gradient;
    1615             :   }
    1616          25 :   checkFuncType(var_name, VarType::GradientDot, FuncAge::Curr);
    1617             : 
    1618          25 :   if (!_coupleable_neighbor)
    1619          25 :     return var->gradSlnDot();
    1620           0 :   return var->gradSlnNeighborDot();
    1621             : }
    1622             : 
    1623             : const VariableGradient &
    1624           0 : Coupleable::coupledGradientDotDot(const std::string & var_name, unsigned int comp) const
    1625             : {
    1626           0 :   const auto * var = getVar(var_name, comp);
    1627           0 :   if (!var)
    1628             :   {
    1629           0 :     _default_gradient.resize(_coupleable_max_qps);
    1630           0 :     return _default_gradient;
    1631             :   }
    1632           0 :   checkFuncType(var_name, VarType::GradientDot, FuncAge::Curr);
    1633             : 
    1634           0 :   if (!_coupleable_neighbor)
    1635           0 :     return var->gradSlnDotDot();
    1636           0 :   return var->gradSlnNeighborDotDot();
    1637             : }
    1638             : 
    1639             : const VectorVariableGradient &
    1640          14 : Coupleable::coupledVectorGradient(const std::string & var_name, unsigned int comp) const
    1641             : {
    1642          14 :   const auto * var = getVectorVar(var_name, comp);
    1643          14 :   if (!var)
    1644             :   {
    1645           0 :     _default_vector_gradient.resize(_coupleable_max_qps);
    1646           0 :     return _default_vector_gradient;
    1647             :   }
    1648          14 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    1649             : 
    1650          14 :   if (!_coupleable_neighbor)
    1651          14 :     return (_c_is_implicit) ? var->gradSln() : var->gradSlnOld();
    1652           0 :   return (_c_is_implicit) ? var->gradSlnNeighbor() : var->gradSlnOldNeighbor();
    1653             : }
    1654             : 
    1655             : const VectorVariableGradient &
    1656          14 : Coupleable::coupledVectorGradientOld(const std::string & var_name, unsigned int comp) const
    1657             : {
    1658          14 :   const auto * var = getVectorVar(var_name, comp);
    1659          14 :   if (!var)
    1660             :   {
    1661           0 :     _default_vector_gradient.resize(_coupleable_max_qps);
    1662           0 :     return _default_vector_gradient;
    1663             :   }
    1664          14 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Old);
    1665             : 
    1666          14 :   if (!_coupleable_neighbor)
    1667          14 :     return (_c_is_implicit) ? var->gradSlnOld() : var->gradSlnOlder();
    1668           0 :   return (_c_is_implicit) ? var->gradSlnOldNeighbor() : var->gradSlnOlderNeighbor();
    1669             : }
    1670             : 
    1671             : const VectorVariableGradient &
    1672          14 : Coupleable::coupledVectorGradientOlder(const std::string & var_name, unsigned int comp) const
    1673             : {
    1674          14 :   const auto * var = getVectorVar(var_name, comp);
    1675          14 :   if (!var)
    1676             :   {
    1677           0 :     _default_vector_gradient.resize(_coupleable_max_qps);
    1678           0 :     return _default_vector_gradient;
    1679             :   }
    1680          14 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Older);
    1681             : 
    1682          14 :   if (!_coupleable_neighbor)
    1683          14 :     return var->gradSlnOlder();
    1684           0 :   return var->gradSlnOlderNeighbor();
    1685             : }
    1686             : 
    1687             : const ArrayVariableGradient &
    1688         906 : Coupleable::coupledArrayGradient(const std::string & var_name, unsigned int comp) const
    1689             : {
    1690         906 :   const auto * var = getArrayVar(var_name, comp);
    1691         906 :   if (!var)
    1692           0 :     return _default_array_gradient;
    1693         906 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    1694             : 
    1695         906 :   if (!_coupleable_neighbor)
    1696         906 :     return (_c_is_implicit) ? var->gradSln() : var->gradSlnOld();
    1697           0 :   return (_c_is_implicit) ? var->gradSlnNeighbor() : var->gradSlnOldNeighbor();
    1698             : }
    1699             : 
    1700             : const ArrayVariableGradient &
    1701           0 : Coupleable::coupledArrayGradientOld(const std::string & var_name, unsigned int comp) const
    1702             : {
    1703           0 :   const auto * var = getArrayVar(var_name, comp);
    1704           0 :   if (!var)
    1705           0 :     return _default_array_gradient;
    1706           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Old);
    1707             : 
    1708           0 :   if (!_coupleable_neighbor)
    1709           0 :     return (_c_is_implicit) ? var->gradSlnOld() : var->gradSlnOlder();
    1710           0 :   return (_c_is_implicit) ? var->gradSlnOldNeighbor() : var->gradSlnOlderNeighbor();
    1711             : }
    1712             : 
    1713             : const ArrayVariableGradient &
    1714           0 : Coupleable::coupledArrayGradientOlder(const std::string & var_name, unsigned int comp) const
    1715             : {
    1716           0 :   const auto * var = getArrayVar(var_name, comp);
    1717           0 :   if (!var)
    1718           0 :     return _default_array_gradient;
    1719           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Older);
    1720             : 
    1721           0 :   if (!_coupleable_neighbor)
    1722           0 :     return var->gradSlnOlder();
    1723           0 :   return var->gradSlnOlderNeighbor();
    1724             : }
    1725             : 
    1726             : const ArrayVariableGradient &
    1727          14 : Coupleable::coupledArrayGradientDot(const std::string & var_name, unsigned int comp) const
    1728             : {
    1729          14 :   const auto * const var = getArrayVar(var_name, comp);
    1730          14 :   if (!var)
    1731           0 :     return _default_array_gradient;
    1732          14 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Older);
    1733             : 
    1734          14 :   if (!_coupleable_neighbor)
    1735          14 :     return var->gradSlnDot();
    1736           0 :   return var->gradSlnNeighborDot();
    1737             : }
    1738             : 
    1739             : const VectorVariableCurl &
    1740           0 : Coupleable::coupledCurl(const std::string & var_name, unsigned int comp) const
    1741             : {
    1742           0 :   const auto * var = getVectorVar(var_name, comp);
    1743           0 :   if (!var)
    1744             :   {
    1745           0 :     _default_vector_curl.resize(_coupleable_max_qps);
    1746           0 :     return _default_vector_curl;
    1747             :   }
    1748           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    1749             : 
    1750           0 :   if (!_coupleable_neighbor)
    1751           0 :     return (_c_is_implicit) ? var->curlSln() : var->curlSlnOld();
    1752           0 :   return (_c_is_implicit) ? var->curlSlnNeighbor() : var->curlSlnOldNeighbor();
    1753             : }
    1754             : 
    1755             : const VectorVariableCurl &
    1756           0 : Coupleable::coupledCurlOld(const std::string & var_name, unsigned int comp) const
    1757             : {
    1758           0 :   const auto * var = getVectorVar(var_name, comp);
    1759           0 :   if (!var)
    1760             :   {
    1761           0 :     _default_vector_curl.resize(_coupleable_max_qps);
    1762           0 :     return _default_vector_curl;
    1763             :   }
    1764           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Old);
    1765             : 
    1766           0 :   if (!_coupleable_neighbor)
    1767           0 :     return (_c_is_implicit) ? var->curlSlnOld() : var->curlSlnOlder();
    1768           0 :   return (_c_is_implicit) ? var->curlSlnOldNeighbor() : var->curlSlnOlderNeighbor();
    1769             : }
    1770             : 
    1771             : const VectorVariableCurl &
    1772           0 : Coupleable::coupledCurlOlder(const std::string & var_name, unsigned int comp) const
    1773             : {
    1774           0 :   const auto * var = getVectorVar(var_name, comp);
    1775           0 :   if (!var)
    1776             :   {
    1777           0 :     _default_vector_curl.resize(_coupleable_max_qps);
    1778           0 :     return _default_vector_curl;
    1779             :   }
    1780           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Older);
    1781             : 
    1782           0 :   if (!_coupleable_neighbor)
    1783           0 :     return var->curlSlnOlder();
    1784           0 :   return var->curlSlnOlderNeighbor();
    1785             : }
    1786             : 
    1787             : const ADVectorVariableCurl &
    1788          14 : Coupleable::adCoupledCurl(const std::string & var_name, unsigned int comp) const
    1789             : {
    1790          14 :   const auto * var = getVectorVar(var_name, comp);
    1791             : 
    1792          14 :   if (!var)
    1793           0 :     return getADDefaultCurl();
    1794          14 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    1795             : 
    1796          14 :   if (!_c_is_implicit)
    1797           0 :     mooseError("Not implemented");
    1798             : 
    1799          14 :   if (!_coupleable_neighbor)
    1800          14 :     return var->adCurlSln();
    1801           0 :   return var->adCurlSlnNeighbor();
    1802             : }
    1803             : 
    1804             : const VectorVariableDivergence &
    1805         168 : Coupleable::coupledDiv(const std::string & var_name, unsigned int comp) const
    1806             : {
    1807         168 :   const auto * var = getVectorVar(var_name, comp);
    1808         168 :   if (!var)
    1809             :   {
    1810           0 :     _default_div.resize(_coupleable_max_qps);
    1811           0 :     return _default_div;
    1812             :   }
    1813         168 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    1814             : 
    1815         168 :   if (!_coupleable_neighbor)
    1816         168 :     return (_c_is_implicit) ? var->divSln() : var->divSlnOld();
    1817           0 :   return (_c_is_implicit) ? var->divSlnNeighbor() : var->divSlnOldNeighbor();
    1818             : }
    1819             : 
    1820             : const VectorVariableDivergence &
    1821           0 : Coupleable::coupledDivOld(const std::string & var_name, unsigned int comp) const
    1822             : {
    1823           0 :   const auto * var = getVectorVar(var_name, comp);
    1824           0 :   if (!var)
    1825             :   {
    1826           0 :     _default_div.resize(_coupleable_max_qps);
    1827           0 :     return _default_div;
    1828             :   }
    1829           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Old);
    1830             : 
    1831           0 :   if (!_coupleable_neighbor)
    1832           0 :     return (_c_is_implicit) ? var->divSlnOld() : var->divSlnOlder();
    1833           0 :   return (_c_is_implicit) ? var->divSlnOldNeighbor() : var->divSlnOlderNeighbor();
    1834             : }
    1835             : 
    1836             : const VectorVariableDivergence &
    1837           0 : Coupleable::coupledDivOlder(const std::string & var_name, unsigned int comp) const
    1838             : {
    1839           0 :   const auto * var = getVectorVar(var_name, comp);
    1840           0 :   if (!var)
    1841             :   {
    1842           0 :     _default_div.resize(_coupleable_max_qps);
    1843           0 :     return _default_div;
    1844             :   }
    1845           0 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Older);
    1846             : 
    1847           0 :   if (!_coupleable_neighbor)
    1848           0 :     return var->divSlnOlder();
    1849           0 :   return var->divSlnOlderNeighbor();
    1850             : }
    1851             : 
    1852             : const VariableSecond &
    1853          52 : Coupleable::coupledSecond(const std::string & var_name, unsigned int comp) const
    1854             : {
    1855          52 :   const auto * var = getVar(var_name, comp);
    1856          52 :   if (!var)
    1857             :   {
    1858          38 :     _default_second.resize(_coupleable_max_qps);
    1859          38 :     return _default_second;
    1860             :   }
    1861          14 :   checkFuncType(var_name, VarType::Second, FuncAge::Curr);
    1862             : 
    1863          14 :   if (!_coupleable_neighbor)
    1864          14 :     return (_c_is_implicit) ? var->secondSln() : var->secondSlnOlder();
    1865           0 :   return (_c_is_implicit) ? var->secondSlnNeighbor() : var->secondSlnOlderNeighbor();
    1866             : }
    1867             : 
    1868             : const VariableSecond &
    1869           0 : Coupleable::coupledSecondOld(const std::string & var_name, unsigned int comp) const
    1870             : {
    1871           0 :   const auto * var = getVar(var_name, comp);
    1872           0 :   if (!var)
    1873             :   {
    1874           0 :     _default_second.resize(_coupleable_max_qps);
    1875           0 :     return _default_second;
    1876             :   }
    1877           0 :   checkFuncType(var_name, VarType::Second, FuncAge::Old);
    1878             : 
    1879           0 :   if (!_coupleable_neighbor)
    1880           0 :     return (_c_is_implicit) ? var->secondSlnOld() : var->secondSlnOlder();
    1881           0 :   return (_c_is_implicit) ? var->secondSlnOldNeighbor() : var->secondSlnOlderNeighbor();
    1882             : }
    1883             : 
    1884             : const VariableSecond &
    1885           0 : Coupleable::coupledSecondOlder(const std::string & var_name, unsigned int comp) const
    1886             : {
    1887           0 :   const auto * var = getVar(var_name, comp);
    1888           0 :   if (!var)
    1889             :   {
    1890           0 :     _default_second.resize(_coupleable_max_qps);
    1891           0 :     return _default_second;
    1892             :   }
    1893           0 :   checkFuncType(var_name, VarType::Second, FuncAge::Older);
    1894             : 
    1895           0 :   if (!_coupleable_neighbor)
    1896           0 :     return var->secondSlnOlder();
    1897           0 :   return var->secondSlnOlderNeighbor();
    1898             : }
    1899             : 
    1900             : const VariableSecond &
    1901           0 : Coupleable::coupledSecondPreviousNL(const std::string & var_name, unsigned int comp) const
    1902             : {
    1903           0 :   const auto * var = getVar(var_name, comp);
    1904           0 :   _c_fe_problem.needsPreviousNewtonIteration(true);
    1905           0 :   if (!var)
    1906             :   {
    1907           0 :     _default_second.resize(_coupleable_max_qps);
    1908           0 :     return _default_second;
    1909             :   }
    1910           0 :   checkFuncType(var_name, VarType::Second, FuncAge::Curr);
    1911             : 
    1912           0 :   if (!_coupleable_neighbor)
    1913           0 :     return var->secondSlnPreviousNL();
    1914           0 :   return var->secondSlnPreviousNLNeighbor();
    1915             : }
    1916             : 
    1917             : template <typename T>
    1918             : const T &
    1919          46 : Coupleable::coupledNodalValue(const std::string & var_name, unsigned int comp) const
    1920             : {
    1921          46 :   const auto * var = getVarHelper<MooseVariableFE<T>>(var_name, comp);
    1922          46 :   if (!var)
    1923           0 :     return getDefaultNodalValue<T>(var_name, comp);
    1924          46 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    1925             : 
    1926          46 :   if (!var->isNodal())
    1927           4 :     mooseError(_c_name,
    1928             :                ": Trying to get nodal values of variable '",
    1929           4 :                var->name(),
    1930             :                "', but it is not nodal.");
    1931             : 
    1932          42 :   if (!_coupleable_neighbor)
    1933          42 :     return (_c_is_implicit) ? var->nodalValue() : var->nodalValueOld();
    1934           0 :   return (_c_is_implicit) ? var->nodalValueNeighbor() : var->nodalValueOldNeighbor();
    1935             : }
    1936             : 
    1937             : template <typename T>
    1938             : const T &
    1939           4 : Coupleable::coupledNodalValueOld(const std::string & var_name, unsigned int comp) const
    1940             : {
    1941           4 :   const auto * var = getVarHelper<MooseVariableFE<T>>(var_name, comp);
    1942           4 :   if (!var)
    1943           0 :     return getDefaultNodalValue<T>(var_name, comp);
    1944           4 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Old);
    1945             : 
    1946           4 :   if (!var->isNodal())
    1947           4 :     mooseError(_c_name,
    1948             :                ": Trying to get old nodal values of variable '",
    1949           4 :                var->name(),
    1950             :                "', but it is not nodal.");
    1951             : 
    1952           0 :   if (!_coupleable_neighbor)
    1953           0 :     return (_c_is_implicit) ? var->nodalValueOld() : var->nodalValueOlder();
    1954           0 :   return (_c_is_implicit) ? var->nodalValueOldNeighbor() : var->nodalValueOlderNeighbor();
    1955             : }
    1956             : 
    1957             : template <typename T>
    1958             : const T &
    1959           4 : Coupleable::coupledNodalValueOlder(const std::string & var_name, unsigned int comp) const
    1960             : {
    1961           4 :   const auto * var = getVarHelper<MooseVariableFE<T>>(var_name, comp);
    1962           4 :   if (!var)
    1963           0 :     return getDefaultNodalValue<T>(var_name, comp);
    1964           4 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Older);
    1965             : 
    1966           4 :   if (!var->isNodal())
    1967           4 :     mooseError(_c_name,
    1968             :                ": Trying to get older nodal values of variable '",
    1969           4 :                var->name(),
    1970             :                "', but it is not nodal.");
    1971             : 
    1972           0 :   if (!_coupleable_neighbor)
    1973           0 :     return var->nodalValueOlder();
    1974           0 :   return var->nodalValueOlderNeighbor();
    1975             : }
    1976             : 
    1977             : template <typename T>
    1978             : const T &
    1979           0 : Coupleable::coupledNodalValuePreviousNL(const std::string & var_name, unsigned int comp) const
    1980             : {
    1981           0 :   const auto * var = getVarHelper<MooseVariableFE<T>>(var_name, comp);
    1982           0 :   if (!var)
    1983           0 :     return getDefaultNodalValue<T>(var_name, comp);
    1984           0 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    1985             : 
    1986           0 :   _c_fe_problem.needsPreviousNewtonIteration(true);
    1987             : 
    1988           0 :   if (!_coupleable_neighbor)
    1989           0 :     return var->nodalValuePreviousNL();
    1990           0 :   return var->nodalValuePreviousNLNeighbor();
    1991             : }
    1992             : 
    1993             : template <typename T>
    1994             : const T &
    1995           0 : Coupleable::coupledNodalDot(const std::string & var_name, unsigned int comp) const
    1996             : {
    1997           0 :   static const T zero = 0;
    1998           0 :   const auto * var = getVarHelper<MooseVariableFE<T>>(var_name, comp);
    1999           0 :   if (!var)
    2000           0 :     return zero;
    2001           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    2002             : 
    2003           0 :   if (!_coupleable_neighbor)
    2004           0 :     return var->nodalValueDot();
    2005           0 :   mooseError("Neighbor version not implemented");
    2006             : }
    2007             : 
    2008             : const VariableValue &
    2009           0 : Coupleable::coupledNodalDotDot(const std::string & var_name, unsigned int comp) const
    2010             : {
    2011           0 :   const auto * var = getVar(var_name, comp);
    2012           0 :   if (!var)
    2013             :   {
    2014           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    2015           0 :     return _default_value_zero;
    2016             :   }
    2017           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    2018             : 
    2019           0 :   if (!_coupleable_neighbor)
    2020           0 :     return var->dofValuesDotDot();
    2021           0 :   return var->dofValuesDotDotNeighbor();
    2022             : }
    2023             : 
    2024             : const VariableValue &
    2025           0 : Coupleable::coupledNodalDotOld(const std::string & var_name, unsigned int comp) const
    2026             : {
    2027           0 :   const auto * var = getVar(var_name, comp);
    2028           0 :   if (!var)
    2029             :   {
    2030           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    2031           0 :     return _default_value_zero;
    2032             :   }
    2033           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    2034             : 
    2035           0 :   if (!_coupleable_neighbor)
    2036           0 :     return var->dofValuesDotOld();
    2037           0 :   return var->dofValuesDotOldNeighbor();
    2038             : }
    2039             : 
    2040             : const VariableValue &
    2041           0 : Coupleable::coupledNodalDotDotOld(const std::string & var_name, unsigned int comp) const
    2042             : {
    2043           0 :   const auto * var = getVar(var_name, comp);
    2044           0 :   if (!var)
    2045             :   {
    2046           0 :     _default_value_zero.resize(_coupleable_max_qps, 0);
    2047           0 :     return _default_value_zero;
    2048             :   }
    2049           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Old);
    2050             : 
    2051           0 :   if (!_coupleable_neighbor)
    2052           0 :     return var->dofValuesDotDotOld();
    2053           0 :   return var->dofValuesDotDotOldNeighbor();
    2054             : }
    2055             : 
    2056             : const VariableValue &
    2057         170 : Coupleable::coupledDofValues(const std::string & var_name, unsigned int comp) const
    2058             : {
    2059         170 :   const auto * var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2060         170 :   if (!var)
    2061           0 :     return *getDefaultValue(var_name, comp);
    2062         170 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    2063             : 
    2064         170 :   if (!_coupleable_neighbor)
    2065         156 :     return (_c_is_implicit) ? var->dofValues() : var->dofValuesOld();
    2066          14 :   return (_c_is_implicit) ? var->dofValuesNeighbor() : var->dofValuesOldNeighbor();
    2067             : }
    2068             : 
    2069             : std::vector<const VariableValue *>
    2070          36 : Coupleable::coupledAllDofValues(const std::string & var_name) const
    2071             : {
    2072          72 :   auto func = [this, &var_name](unsigned int comp) { return &coupledDofValues(var_name, comp); };
    2073          72 :   return coupledVectorHelper<const VariableValue *>(var_name, func);
    2074             : }
    2075             : 
    2076             : const VariableValue &
    2077          14 : Coupleable::coupledDofValuesOld(const std::string & var_name, unsigned int comp) const
    2078             : {
    2079          14 :   const auto * var = getVar(var_name, comp);
    2080          14 :   if (!var)
    2081           0 :     return *getDefaultValue(var_name, comp);
    2082          14 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Old);
    2083             : 
    2084          14 :   if (!_coupleable_neighbor)
    2085          14 :     return (_c_is_implicit) ? var->dofValuesOld() : var->dofValuesOlder();
    2086           0 :   return (_c_is_implicit) ? var->dofValuesOldNeighbor() : var->dofValuesOlderNeighbor();
    2087             : }
    2088             : 
    2089             : std::vector<const VariableValue *>
    2090           0 : Coupleable::coupledAllDofValuesOld(const std::string & var_name) const
    2091             : {
    2092           0 :   auto func = [this, &var_name](unsigned int comp) { return &coupledDofValuesOld(var_name, comp); };
    2093           0 :   return coupledVectorHelper<const VariableValue *>(var_name, func);
    2094             : }
    2095             : 
    2096             : const VariableValue &
    2097           0 : Coupleable::coupledDofValuesOlder(const std::string & var_name, unsigned int comp) const
    2098             : {
    2099           0 :   const auto * var = getVar(var_name, comp);
    2100           0 :   if (!var)
    2101           0 :     return *getDefaultValue(var_name, comp);
    2102           0 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Older);
    2103             : 
    2104           0 :   if (!_coupleable_neighbor)
    2105           0 :     return var->dofValuesOlder();
    2106           0 :   return var->dofValuesOlderNeighbor();
    2107             : }
    2108             : 
    2109             : std::vector<const VariableValue *>
    2110           0 : Coupleable::coupledAllDofValuesOlder(const std::string & var_name) const
    2111             : {
    2112           0 :   auto func = [this, &var_name](unsigned int comp)
    2113           0 :   { return &coupledDofValuesOlder(var_name, comp); };
    2114           0 :   return coupledVectorHelper<const VariableValue *>(var_name, func);
    2115             : }
    2116             : 
    2117             : const ArrayVariableValue &
    2118           0 : Coupleable::coupledArrayDofValues(const std::string & var_name, unsigned int comp) const
    2119             : {
    2120           0 :   const auto * var = getArrayVar(var_name, comp);
    2121           0 :   if (!var)
    2122           0 :     return *getDefaultArrayValue(var_name);
    2123           0 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    2124             : 
    2125           0 :   if (!_coupleable_neighbor)
    2126           0 :     return (_c_is_implicit) ? var->dofValues() : var->dofValuesOld();
    2127           0 :   return (_c_is_implicit) ? var->dofValuesNeighbor() : var->dofValuesOldNeighbor();
    2128             : }
    2129             : 
    2130             : const ADVariableValue &
    2131           0 : Coupleable::adCoupledDofValues(const std::string & var_name, unsigned int comp) const
    2132             : {
    2133           0 :   const auto * var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2134             : 
    2135           0 :   if (!var)
    2136           0 :     return *getADDefaultValue(var_name);
    2137           0 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    2138             : 
    2139           0 :   if (!_c_is_implicit)
    2140           0 :     mooseError("Not implemented");
    2141             : 
    2142           0 :   if (!_coupleable_neighbor)
    2143           0 :     return var->adDofValues();
    2144           0 :   return var->adDofValuesNeighbor();
    2145             : }
    2146             : 
    2147             : void
    2148       25905 : Coupleable::validateExecutionerType(const std::string & name, const std::string & fn_name) const
    2149             : {
    2150       25905 :   if (!_c_fe_problem.isTransient())
    2151           8 :     mooseError(_c_name,
    2152             :                ": Calling \"",
    2153             :                fn_name,
    2154             :                "\" on variable \"",
    2155             :                name,
    2156             :                "\" when using a \"Steady\" executioner is not allowed. This value is available "
    2157             :                "only in transient simulations.");
    2158       25897 : }
    2159             : 
    2160             : template <typename T>
    2161             : const typename Moose::ADType<T>::type &
    2162          23 : Coupleable::adCoupledNodalValue(const std::string & var_name, unsigned int comp) const
    2163             : {
    2164          23 :   static const typename Moose::ADType<T>::type zero = 0;
    2165          23 :   if (!isCoupled(var_name))
    2166           0 :     return zero;
    2167             : 
    2168          23 :   if (!_c_nodal)
    2169           0 :     mooseError("The adCoupledNodalValue method should only be called for nodal computing objects");
    2170          23 :   if (_coupleable_neighbor)
    2171           0 :     mooseError(
    2172             :         "The adCoupledNodalValue method shouldn't be called for neighbor computing objects. I "
    2173             :         "don't even know what that would mean, although maybe someone could explain it to me.");
    2174          23 :   if (!_c_is_implicit)
    2175           0 :     mooseError("If you're going to use an explicit scheme, then use coupledNodalValue instead of "
    2176             :                "adCoupledNodalValue");
    2177             : 
    2178          23 :   const auto * var = getVarHelper<MooseVariableFE<T>>(var_name, comp);
    2179             : 
    2180          23 :   return var->adNodalValue();
    2181             : }
    2182             : 
    2183             : const ADVariableValue &
    2184        3497 : Coupleable::adCoupledValue(const std::string & var_name, unsigned int comp) const
    2185             : {
    2186        3497 :   const auto * const var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2187             : 
    2188        3497 :   if (!var)
    2189         222 :     return *getADDefaultValue(var_name);
    2190        3275 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    2191             : 
    2192        3275 :   if (!_c_is_implicit)
    2193           0 :     mooseError("Not implemented");
    2194             : 
    2195        3275 :   if (_c_nodal)
    2196         131 :     return var->adDofValues();
    2197             : 
    2198        3144 :   if (!_coupleable_neighbor)
    2199        2289 :     return var->adSln();
    2200         855 :   return var->adSlnNeighbor();
    2201             : }
    2202             : 
    2203             : const ADVariableValue &
    2204          28 : Coupleable::adCoupledLowerValue(const std::string & var_name, unsigned int comp) const
    2205             : {
    2206          28 :   auto var = getVarHelper<MooseVariableFE<Real>>(var_name, comp);
    2207             : 
    2208          28 :   if (!var)
    2209           0 :     return *getADDefaultValue(var_name);
    2210          28 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    2211             : 
    2212          28 :   if (!_c_is_implicit)
    2213           0 :     mooseError("adCoupledLowerValue cannot be called in a coupleable neighbor object");
    2214             : 
    2215          28 :   if (_c_nodal)
    2216           0 :     return var->adDofValues();
    2217             :   else
    2218          28 :     return var->adSlnLower();
    2219             : }
    2220             : 
    2221             : const ADVariableGradient &
    2222         366 : Coupleable::adCoupledGradient(const std::string & var_name, unsigned int comp) const
    2223             : {
    2224         366 :   const auto * var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2225             : 
    2226         366 :   if (!var)
    2227           0 :     return getADDefaultGradient();
    2228         366 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    2229             : 
    2230         366 :   if (!_c_is_implicit)
    2231           0 :     mooseError("Not implemented");
    2232             : 
    2233         366 :   if (!_coupleable_neighbor)
    2234         268 :     return var->adGradSln();
    2235          98 :   return var->adGradSlnNeighbor();
    2236             : }
    2237             : 
    2238             : const ADVariableGradient &
    2239           0 : Coupleable::adCoupledGradientDot(const std::string & var_name, unsigned int comp) const
    2240             : {
    2241           0 :   const auto * var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2242             : 
    2243           0 :   if (!var)
    2244           0 :     return getADDefaultGradient();
    2245           0 :   checkFuncType(var_name, VarType::GradientDot, FuncAge::Curr);
    2246             : 
    2247           0 :   if (!_c_is_implicit)
    2248           0 :     mooseError("Not implemented");
    2249             : 
    2250           0 :   if (!_coupleable_neighbor)
    2251           0 :     return var->adGradSlnDot();
    2252           0 :   return var->adGradSlnNeighborDot();
    2253             : }
    2254             : 
    2255             : const ADVariableSecond &
    2256           0 : Coupleable::adCoupledSecond(const std::string & var_name, unsigned int comp) const
    2257             : {
    2258           0 :   const auto * var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2259             : 
    2260           0 :   if (!var)
    2261           0 :     return getADDefaultSecond();
    2262           0 :   checkFuncType(var_name, VarType::Second, FuncAge::Curr);
    2263             : 
    2264           0 :   if (!_c_is_implicit)
    2265           0 :     mooseError("Not implemented");
    2266             : 
    2267           0 :   if (!_coupleable_neighbor)
    2268           0 :     return var->adSecondSln();
    2269             :   else
    2270           0 :     return var->adSecondSlnNeighbor();
    2271             : }
    2272             : 
    2273             : const ADVectorVariableSecond &
    2274           0 : adCoupledVectorSecond(const std::string & /*var_name*/, unsigned int /*comp = 0*/)
    2275             : {
    2276           0 :   mooseError("Automatic differentiation using second derivatives of vector variables is not "
    2277             :              "implemented.");
    2278             : }
    2279             : 
    2280             : const ADVariableValue &
    2281          98 : Coupleable::adCoupledDot(const std::string & var_name, unsigned int comp) const
    2282             : {
    2283          98 :   const auto * var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2284             : 
    2285          98 :   if (!var)
    2286           0 :     return *getADDefaultValue(var_name);
    2287          98 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    2288             : 
    2289          98 :   if (!_coupleable_neighbor)
    2290             :   {
    2291          84 :     if (_c_nodal)
    2292          14 :       return var->adDofValuesDot();
    2293          70 :     return var->adUDot();
    2294             :   }
    2295             :   else
    2296             :   {
    2297          14 :     if (_c_nodal)
    2298           0 :       mooseError("AD neighbor nodal dof dot not implemented");
    2299          14 :     return var->adUDotNeighbor();
    2300             :   }
    2301             : }
    2302             : 
    2303             : const ADVariableValue &
    2304          70 : Coupleable::adCoupledDotDot(const std::string & var_name, unsigned int comp) const
    2305             : {
    2306          70 :   const auto * const var = getVarHelper<MooseVariableField<Real>>(var_name, comp);
    2307             : 
    2308          70 :   if (!var)
    2309           0 :     return *getADDefaultValue(var_name);
    2310          70 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    2311             : 
    2312          70 :   if (_c_nodal)
    2313           0 :     mooseError("Not implemented");
    2314             : 
    2315          70 :   if (!_coupleable_neighbor)
    2316          56 :     return var->adUDotDot();
    2317          14 :   return var->adUDotDotNeighbor();
    2318             : }
    2319             : 
    2320             : const ADVectorVariableValue &
    2321           0 : Coupleable::adCoupledVectorDot(const std::string & var_name, unsigned int comp) const
    2322             : {
    2323           0 :   const auto * var = getVectorVar(var_name, comp);
    2324           0 :   if (!var)
    2325           0 :     return *getADDefaultVectorValue(var_name);
    2326           0 :   checkFuncType(var_name, VarType::Dot, FuncAge::Curr);
    2327             : 
    2328           0 :   if (_c_nodal)
    2329           0 :     mooseError("Not implemented");
    2330             : 
    2331           0 :   if (!_coupleable_neighbor)
    2332           0 :     return var->adUDot();
    2333           0 :   return var->adUDotNeighbor();
    2334             : }
    2335             : 
    2336             : const ADVectorVariableValue &
    2337         165 : Coupleable::adCoupledVectorValue(const std::string & var_name, unsigned int comp) const
    2338             : {
    2339         165 :   const auto * var = getVectorVar(var_name, comp);
    2340         165 :   if (!var)
    2341          28 :     return *getADDefaultVectorValue(var_name);
    2342         137 :   checkFuncType(var_name, VarType::Ignore, FuncAge::Curr);
    2343             : 
    2344         137 :   if (_c_nodal)
    2345           0 :     mooseError("Not implemented");
    2346         137 :   if (!_c_is_implicit)
    2347           0 :     mooseError("Not implemented");
    2348             : 
    2349         137 :   if (!_coupleable_neighbor)
    2350         109 :     return var->adSln();
    2351          28 :   return var->adSlnNeighbor();
    2352             : }
    2353             : 
    2354             : const ADVectorVariableGradient &
    2355          42 : Coupleable::adCoupledVectorGradient(const std::string & var_name, unsigned int comp) const
    2356             : {
    2357          42 :   const auto * var = getVectorVar(var_name, comp);
    2358          42 :   if (!var)
    2359          14 :     return getADDefaultVectorGradient();
    2360          28 :   checkFuncType(var_name, VarType::Gradient, FuncAge::Curr);
    2361             : 
    2362          28 :   if (!_c_is_implicit)
    2363           0 :     mooseError("Not implemented");
    2364             : 
    2365          28 :   if (!_coupleable_neighbor)
    2366          28 :     return var->adGradSln();
    2367           0 :   return var->adGradSlnNeighbor();
    2368             : }
    2369             : 
    2370             : const ADVariableValue *
    2371         222 : Coupleable::getADDefaultValue(const std::string & var_name) const
    2372             : {
    2373         222 :   auto default_value_it = _ad_default_value.find(var_name);
    2374         222 :   if (default_value_it == _ad_default_value.end())
    2375             :   {
    2376         222 :     auto value = std::make_unique<ADVariableValue>(_coupleable_max_qps,
    2377         222 :                                                    _c_parameters.defaultCoupledValue(var_name));
    2378         222 :     default_value_it = _ad_default_value.insert(std::make_pair(var_name, std::move(value))).first;
    2379         222 :   }
    2380             : 
    2381         444 :   return default_value_it->second.get();
    2382             : }
    2383             : 
    2384             : const ADVectorVariableValue *
    2385          28 : Coupleable::getADDefaultVectorValue(const std::string & var_name) const
    2386             : {
    2387          28 :   auto default_value_it = _ad_default_vector_value.find(var_name);
    2388          28 :   if (default_value_it == _ad_default_vector_value.end())
    2389             :   {
    2390          28 :     RealVectorValue default_vec;
    2391          98 :     for (unsigned int i = 0; i < _c_parameters.numberDefaultCoupledValues(var_name); ++i)
    2392          70 :       default_vec(i) = _c_parameters.defaultCoupledValue(var_name, i);
    2393          28 :     auto value = std::make_unique<ADVectorVariableValue>(_coupleable_max_qps, default_vec);
    2394          28 :     default_value_it =
    2395          28 :         _ad_default_vector_value.insert(std::make_pair(var_name, std::move(value))).first;
    2396          28 :   }
    2397             : 
    2398          56 :   return default_value_it->second.get();
    2399             : }
    2400             : 
    2401             : const ADVariableGradient &
    2402           0 : Coupleable::getADDefaultGradient() const
    2403             : {
    2404           0 :   _ad_default_gradient.resize(_coupleable_max_qps);
    2405           0 :   return _ad_default_gradient;
    2406             : }
    2407             : 
    2408             : const ADVectorVariableGradient &
    2409          14 : Coupleable::getADDefaultVectorGradient() const
    2410             : {
    2411          14 :   _ad_default_vector_gradient.resize(_coupleable_max_qps);
    2412          14 :   return _ad_default_vector_gradient;
    2413             : }
    2414             : 
    2415             : const ADVariableSecond &
    2416           0 : Coupleable::getADDefaultSecond() const
    2417             : {
    2418           0 :   _ad_default_second.resize(_coupleable_max_qps);
    2419           0 :   return _ad_default_second;
    2420             : }
    2421             : 
    2422             : const ADVectorVariableCurl &
    2423           0 : Coupleable::getADDefaultCurl() const
    2424             : {
    2425           0 :   _ad_default_curl.resize(_coupleable_max_qps);
    2426           0 :   return _ad_default_curl;
    2427             : }
    2428             : 
    2429             : const ADVariableValue &
    2430           0 : Coupleable::adZeroValue() const
    2431             : {
    2432           0 :   mooseDeprecated("Method adZeroValue() is deprecated. Use '_ad_zero' instead.");
    2433           0 :   return _ad_zero;
    2434             : }
    2435             : 
    2436             : const ADVariableGradient &
    2437           0 : Coupleable::adZeroGradient() const
    2438             : {
    2439           0 :   mooseDeprecated("Method adZeroGradient() is deprecated. Use '_ad_grad_zero' instead.");
    2440           0 :   return _ad_grad_zero;
    2441             : }
    2442             : 
    2443             : const ADVariableSecond &
    2444           0 : Coupleable::adZeroSecond() const
    2445             : {
    2446           0 :   mooseDeprecated("Method adZeroSecond() is deprecated. Use '_ad_second_zero' instead.");
    2447           0 :   return _ad_second_zero;
    2448             : }
    2449             : 
    2450             : template <>
    2451             : const GenericVariableValue<false> &
    2452         276 : Coupleable::genericZeroValue<false>()
    2453             : {
    2454         276 :   return _zero;
    2455             : }
    2456             : 
    2457             : template <>
    2458             : const GenericVariableValue<true> &
    2459         234 : Coupleable::genericZeroValue<true>()
    2460             : {
    2461         234 :   return _ad_zero;
    2462             : }
    2463             : 
    2464             : template <>
    2465             : const GenericVariableGradient<false> &
    2466           0 : Coupleable::genericZeroGradient<false>()
    2467             : {
    2468           0 :   return _grad_zero;
    2469             : }
    2470             : 
    2471             : template <>
    2472             : const GenericVariableGradient<true> &
    2473           0 : Coupleable::genericZeroGradient<true>()
    2474             : {
    2475           0 :   return _ad_grad_zero;
    2476             : }
    2477             : 
    2478             : template <>
    2479             : const GenericVariableSecond<false> &
    2480           0 : Coupleable::genericZeroSecond<false>()
    2481             : {
    2482           0 :   return _second_zero;
    2483             : }
    2484             : 
    2485             : template <>
    2486             : const GenericVariableSecond<true> &
    2487           0 : Coupleable::genericZeroSecond<true>()
    2488             : {
    2489           0 :   return _ad_second_zero;
    2490             : }
    2491             : 
    2492             : template <>
    2493             : const GenericVariableGradient<false> &
    2494          96 : Coupleable::coupledGenericGradient<false>(const std::string & var_name, unsigned int comp) const
    2495             : {
    2496          96 :   return coupledGradient(var_name, comp);
    2497             : }
    2498             : 
    2499             : template <>
    2500             : const GenericVariableGradient<true> &
    2501         126 : Coupleable::coupledGenericGradient<true>(const std::string & var_name, unsigned int comp) const
    2502             : {
    2503         126 :   return adCoupledGradient(var_name, comp);
    2504             : }
    2505             : 
    2506             : std::vector<unsigned int>
    2507          79 : Coupleable::coupledIndices(const std::string & var_name) const
    2508             : {
    2509         133 :   auto func = [this, &var_name](unsigned int comp) { return coupled(var_name, comp); };
    2510         158 :   return coupledVectorHelper<unsigned int>(var_name, func);
    2511             : }
    2512             : 
    2513             : VariableName
    2514        5520 : Coupleable::coupledName(const std::string & var_name, unsigned int comp) const
    2515             : {
    2516        5520 :   if (getFieldVar(var_name, comp))
    2517        5516 :     return getFieldVar(var_name, comp)->name();
    2518             :   // Detect if we are in the case where a constant was passed in lieu of a variable
    2519           4 :   else if (isCoupledConstant(var_name))
    2520           4 :     mooseError(_c_name,
    2521             :                ": a variable name was queried but a constant was passed for parameter '",
    2522             :                var_name,
    2523             :                "Either pass a true variable or contact a developer to shield the call to "
    2524             :                "'coupledName' with 'isCoupledConstant'");
    2525             :   else
    2526           0 :     mooseError(
    2527           0 :         _c_name, ": Variable '", var_name, "' does not exist, yet its coupled name is requested");
    2528             : }
    2529             : 
    2530             : std::vector<VariableName>
    2531           0 : Coupleable::coupledNames(const std::string & var_name) const
    2532             : {
    2533           0 :   auto func = [this, &var_name](unsigned int comp) { return coupledName(var_name, comp); };
    2534           0 :   return coupledVectorHelper<VariableName>(var_name, func);
    2535             : }
    2536             : 
    2537             : std::vector<const VariableValue *>
    2538        1797 : Coupleable::coupledValues(const std::string & var_name) const
    2539             : {
    2540        1274 :   auto func = [this, &var_name](unsigned int comp) { return &coupledValue(var_name, comp); };
    2541        3594 :   return coupledVectorHelper<const VariableValue *>(var_name, func);
    2542             : }
    2543             : 
    2544             : std::vector<const VectorVariableValue *>
    2545          42 : Coupleable::coupledVectorValues(const std::string & var_name) const
    2546             : {
    2547          56 :   auto func = [this, &var_name](unsigned int comp) { return &coupledVectorValue(var_name, comp); };
    2548          84 :   return coupledVectorHelper<const VectorVariableValue *>(var_name, func);
    2549             : }
    2550             : 
    2551             : template <>
    2552             : std::vector<const GenericVariableValue<false> *>
    2553          92 : Coupleable::coupledGenericValues<false>(const std::string & var_name) const
    2554             : {
    2555          92 :   return coupledValues(var_name);
    2556             : }
    2557             : 
    2558             : template <>
    2559             : std::vector<const GenericVariableValue<true> *>
    2560          66 : Coupleable::coupledGenericValues<true>(const std::string & var_name) const
    2561             : {
    2562          66 :   return adCoupledValues(var_name);
    2563             : }
    2564             : 
    2565             : std::vector<const ADVariableValue *>
    2566          66 : Coupleable::adCoupledValues(const std::string & var_name) const
    2567             : {
    2568          66 :   auto func = [this, &var_name](unsigned int comp) { return &adCoupledValue(var_name, comp); };
    2569         132 :   return coupledVectorHelper<const ADVariableValue *>(var_name, func);
    2570             : }
    2571             : 
    2572             : std::vector<const ADVectorVariableValue *>
    2573           0 : Coupleable::adCoupledVectorValues(const std::string & var_name) const
    2574             : {
    2575           0 :   auto func = [this, &var_name](unsigned int comp)
    2576           0 :   { return &adCoupledVectorValue(var_name, comp); };
    2577           0 :   return coupledVectorHelper<const ADVectorVariableValue *>(var_name, func);
    2578             : }
    2579             : 
    2580             : std::vector<const VariableValue *>
    2581          14 : Coupleable::coupledVectorTagValues(const std::string & var_names, TagID tag) const
    2582             : {
    2583          14 :   auto func = [this, &var_names, &tag](unsigned int comp)
    2584          14 :   { return &coupledVectorTagValue(var_names, tag, comp); };
    2585          28 :   return coupledVectorHelper<const VariableValue *>(var_names, func);
    2586             : }
    2587             : 
    2588             : std::vector<const VariableValue *>
    2589          14 : Coupleable::coupledVectorTagValues(const std::string & var_names,
    2590             :                                    const std::string & tag_name) const
    2591             : {
    2592          14 :   if (!_c_parameters.isParamValid(tag_name))
    2593           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
    2594             : 
    2595          14 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
    2596          14 :   if (!_c_fe_problem.vectorTagExists(tagname))
    2597           0 :     mooseError("Tagged vector with tag name '", tagname, "' does not exist");
    2598             : 
    2599          14 :   TagID tag = _c_fe_problem.getVectorTagID(tagname);
    2600          28 :   return coupledVectorTagValues(var_names, tag);
    2601          14 : }
    2602             : 
    2603             : std::vector<const ArrayVariableValue *>
    2604           0 : Coupleable::coupledVectorTagArrayValues(const std::string & var_names, TagID tag) const
    2605             : {
    2606           0 :   auto func = [this, &var_names, &tag](unsigned int index)
    2607           0 :   { return &coupledVectorTagArrayValue(var_names, tag, index); };
    2608           0 :   return coupledVectorHelper<const ArrayVariableValue *>(var_names, func);
    2609             : }
    2610             : 
    2611             : std::vector<const ArrayVariableValue *>
    2612           0 : Coupleable::coupledVectorTagArrayValues(const std::string & var_names,
    2613             :                                         const std::string & tag_name) const
    2614             : {
    2615           0 :   if (!_c_parameters.isParamValid(tag_name))
    2616           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
    2617             : 
    2618           0 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
    2619           0 :   if (!_c_fe_problem.vectorTagExists(tagname))
    2620           0 :     mooseError("Tagged vector with tag name '", tagname, "' does not exist");
    2621             : 
    2622           0 :   TagID tag = _c_fe_problem.getVectorTagID(tagname);
    2623           0 :   return coupledVectorTagArrayValues(var_names, tag);
    2624           0 : }
    2625             : 
    2626             : std::vector<const VariableGradient *>
    2627           0 : Coupleable::coupledVectorTagGradients(const std::string & var_names, TagID tag) const
    2628             : {
    2629           0 :   auto func = [this, &var_names, &tag](unsigned int index)
    2630           0 :   { return &coupledVectorTagGradient(var_names, tag, index); };
    2631           0 :   return coupledVectorHelper<const VariableGradient *>(var_names, func);
    2632             : }
    2633             : 
    2634             : std::vector<const VariableGradient *>
    2635           0 : Coupleable::coupledVectorTagGradients(const std::string & var_names,
    2636             :                                       const std::string & tag_name) const
    2637             : {
    2638           0 :   if (!_c_parameters.isParamValid(tag_name))
    2639           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
    2640             : 
    2641           0 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
    2642           0 :   if (!_c_fe_problem.vectorTagExists(tagname))
    2643           0 :     mooseError("Tagged vector with tag name '", tagname, "' does not exist");
    2644             : 
    2645           0 :   TagID tag = _c_fe_problem.getVectorTagID(tagname);
    2646           0 :   return coupledVectorTagGradients(var_names, tag);
    2647           0 : }
    2648             : 
    2649             : std::vector<const ArrayVariableGradient *>
    2650           0 : Coupleable::coupledVectorTagArrayGradients(const std::string & var_names, TagID tag) const
    2651             : {
    2652           0 :   auto func = [this, &var_names, &tag](unsigned int index)
    2653           0 :   { return &coupledVectorTagArrayGradient(var_names, tag, index); };
    2654           0 :   return coupledVectorHelper<const ArrayVariableGradient *>(var_names, func);
    2655             : }
    2656             : 
    2657             : std::vector<const ArrayVariableGradient *>
    2658           0 : Coupleable::coupledVectorTagArrayGradients(const std::string & var_names,
    2659             :                                            const std::string & tag_name) const
    2660             : {
    2661           0 :   if (!_c_parameters.isParamValid(tag_name))
    2662           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
    2663             : 
    2664           0 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
    2665           0 :   if (!_c_fe_problem.vectorTagExists(tagname))
    2666           0 :     mooseError("Tagged vector with tag name '", tagname, "' does not exist");
    2667             : 
    2668           0 :   TagID tag = _c_fe_problem.getVectorTagID(tagname);
    2669           0 :   return coupledVectorTagArrayGradients(var_names, tag);
    2670           0 : }
    2671             : 
    2672             : std::vector<const VariableValue *>
    2673           0 : Coupleable::coupledVectorTagDofValues(const std::string & var_names, TagID tag) const
    2674             : {
    2675           0 :   auto func = [this, &var_names, &tag](unsigned int comp)
    2676           0 :   { return &coupledVectorTagDofValue(var_names, tag, comp); };
    2677           0 :   return coupledVectorHelper<const VariableValue *>(var_names, func);
    2678             : }
    2679             : 
    2680             : std::vector<const VariableValue *>
    2681           0 : Coupleable::coupledVectorTagDofValues(const std::string & var_names,
    2682             :                                       const std::string & tag_name) const
    2683             : {
    2684           0 :   if (!_c_parameters.isParamValid(tag_name))
    2685           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
    2686             : 
    2687           0 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
    2688           0 :   if (!_c_fe_problem.vectorTagExists(tagname))
    2689           0 :     mooseError("Tagged vector with tag name '", tagname, "' does not exist");
    2690             : 
    2691           0 :   TagID tag = _c_fe_problem.getVectorTagID(tagname);
    2692           0 :   return coupledVectorTagDofValues(var_names, tag);
    2693           0 : }
    2694             : 
    2695             : std::vector<const VariableValue *>
    2696           0 : Coupleable::coupledMatrixTagValues(const std::string & var_names, TagID tag) const
    2697             : {
    2698           0 :   auto func = [this, &var_names, &tag](unsigned int comp)
    2699           0 :   { return &coupledMatrixTagValue(var_names, tag, comp); };
    2700           0 :   return coupledVectorHelper<const VariableValue *>(var_names, func);
    2701             : }
    2702             : 
    2703             : std::vector<const VariableValue *>
    2704           0 : Coupleable::coupledMatrixTagValues(const std::string & var_names,
    2705             :                                    const std::string & tag_name) const
    2706             : {
    2707           0 :   if (!_c_parameters.isParamValid(tag_name))
    2708           0 :     mooseError("Tag name parameter '", tag_name, "' is invalid");
    2709             : 
    2710           0 :   TagName tagname = _c_parameters.get<TagName>(tag_name);
    2711           0 :   if (!_c_fe_problem.matrixTagExists(tagname))
    2712           0 :     mooseError("Matrix tag name '", tagname, "' does not exist");
    2713             : 
    2714           0 :   TagID tag = _c_fe_problem.getMatrixTagID(tagname);
    2715           0 :   return coupledMatrixTagValues(var_names, tag);
    2716           0 : }
    2717             : 
    2718             : std::vector<const VariableValue *>
    2719         504 : Coupleable::coupledValuesOld(const std::string & var_name) const
    2720             : {
    2721       11844 :   auto func = [this, &var_name](unsigned int comp) { return &coupledValueOld(var_name, comp); };
    2722        1008 :   return coupledVectorHelper<const VariableValue *>(var_name, func);
    2723             : }
    2724             : 
    2725             : std::vector<const VariableValue *>
    2726         504 : Coupleable::coupledValuesOlder(const std::string & var_name) const
    2727             : {
    2728       11844 :   auto func = [this, &var_name](unsigned int comp) { return &coupledValueOlder(var_name, comp); };
    2729        1008 :   return coupledVectorHelper<const VariableValue *>(var_name, func);
    2730             : }
    2731             : 
    2732             : std::vector<const VectorVariableValue *>
    2733          28 : Coupleable::coupledVectorValuesOld(const std::string & var_name) const
    2734             : {
    2735          56 :   auto func = [this, &var_name](unsigned int comp)
    2736          56 :   { return &coupledVectorValueOld(var_name, comp); };
    2737          56 :   return coupledVectorHelper<const VectorVariableValue *>(var_name, func);
    2738             : }
    2739             : 
    2740             : std::vector<const VariableGradient *>
    2741           0 : Coupleable::coupledGradients(const std::string & var_name) const
    2742             : {
    2743           0 :   auto func = [this, &var_name](unsigned int comp) { return &coupledGradient(var_name, comp); };
    2744           0 :   return coupledVectorHelper<const VariableGradient *>(var_name, func);
    2745             : }
    2746             : 
    2747             : template <>
    2748             : std::vector<const GenericVariableGradient<false> *>
    2749           0 : Coupleable::coupledGenericGradients<false>(const std::string & var_name) const
    2750             : {
    2751           0 :   return coupledGradients(var_name);
    2752             : }
    2753             : 
    2754             : template <>
    2755             : std::vector<const GenericVariableGradient<true> *>
    2756           0 : Coupleable::coupledGenericGradients<true>(const std::string & var_name) const
    2757             : {
    2758           0 :   auto func = [this, &var_name](unsigned int comp) { return &adCoupledGradient(var_name, comp); };
    2759           0 :   return coupledVectorHelper<const GenericVariableGradient<true> *>(var_name, func);
    2760             : }
    2761             : 
    2762             : std::vector<const ADVariableGradient *>
    2763           0 : Coupleable::adCoupledGradients(const std::string & var_name) const
    2764             : {
    2765           0 :   auto func = [this, &var_name](unsigned int comp) { return &adCoupledGradient(var_name, comp); };
    2766           0 :   return coupledVectorHelper<const ADVariableGradient *>(var_name, func);
    2767             : }
    2768             : 
    2769             : std::vector<const VariableGradient *>
    2770           0 : Coupleable::coupledGradientsOld(const std::string & var_name) const
    2771             : {
    2772           0 :   auto func = [this, &var_name](unsigned int comp) { return &coupledGradientOld(var_name, comp); };
    2773           0 :   return coupledVectorHelper<const VariableGradient *>(var_name, func);
    2774             : }
    2775             : 
    2776             : std::vector<const VariableValue *>
    2777           0 : Coupleable::coupledDots(const std::string & var_name) const
    2778             : {
    2779           0 :   auto func = [this, &var_name](unsigned int comp) { return &coupledDot(var_name, comp); };
    2780           0 :   return coupledVectorHelper<const VariableValue *>(var_name, func);
    2781             : }
    2782             : 
    2783             : std::vector<const ADVariableValue *>
    2784           0 : Coupleable::adCoupledDots(const std::string & var_name) const
    2785             : {
    2786           0 :   auto func = [this, &var_name](unsigned int comp) { return &adCoupledDot(var_name, comp); };
    2787           0 :   return coupledVectorHelper<const ADVariableValue *>(var_name, func);
    2788             : }
    2789             : 
    2790             : template <>
    2791             : const GenericVariableValue<false> &
    2792         158 : Coupleable::coupledGenericDot<false>(const std::string & var_name, unsigned int comp) const
    2793             : {
    2794         158 :   return coupledDot(var_name, comp);
    2795             : }
    2796             : 
    2797             : template <>
    2798             : const GenericVariableValue<true> &
    2799          56 : Coupleable::coupledGenericDot<true>(const std::string & var_name, unsigned int comp) const
    2800             : {
    2801          56 :   return adCoupledDot(var_name, comp);
    2802             : }
    2803             : 
    2804             : // Explicit instantiations
    2805             : 
    2806             : template const Real & Coupleable::getDefaultNodalValue<Real>(const std::string & var_name,
    2807             :                                                              unsigned int comp) const;
    2808             : 
    2809             : template const Real & Coupleable::coupledNodalValue<Real>(const std::string & var_name,
    2810             :                                                           unsigned int comp) const;
    2811             : template const ADReal & Coupleable::adCoupledNodalValue<Real>(const std::string & var_name,
    2812             :                                                               unsigned int comp) const;
    2813             : template const ADRealVectorValue &
    2814             : Coupleable::adCoupledNodalValue<RealVectorValue>(const std::string & var_name,
    2815             :                                                  unsigned int comp) const;
    2816             : 
    2817             : template const RealVectorValue &
    2818             : Coupleable::coupledNodalValue<RealVectorValue>(const std::string & var_name,
    2819             :                                                unsigned int comp) const;
    2820             : template const Real & Coupleable::coupledNodalValueOld<Real>(const std::string & var_name,
    2821             :                                                              unsigned int comp) const;
    2822             : template const RealVectorValue &
    2823             : Coupleable::coupledNodalValueOld<RealVectorValue>(const std::string & var_name,
    2824             :                                                   unsigned int comp) const;
    2825             : template const Real & Coupleable::coupledNodalValueOlder<Real>(const std::string & var_name,
    2826             :                                                                unsigned int comp) const;
    2827             : template const RealVectorValue &
    2828             : Coupleable::coupledNodalValueOlder<RealVectorValue>(const std::string & var_name,
    2829             :                                                     unsigned int comp) const;
    2830             : template const Real & Coupleable::coupledNodalValuePreviousNL<Real>(const std::string & var_name,
    2831             :                                                                     unsigned int comp) const;
    2832             : template const RealVectorValue &
    2833             : Coupleable::coupledNodalValuePreviousNL<RealVectorValue>(const std::string & var_name,
    2834             :                                                          unsigned int comp) const;
    2835             : template const Real & Coupleable::coupledNodalDot<Real>(const std::string & var_name,
    2836             :                                                         unsigned int comp) const;
    2837             : template const RealVectorValue &
    2838             : Coupleable::coupledNodalDot<RealVectorValue>(const std::string & var_name, unsigned int comp) const;

Generated by: LCOV version 1.14