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

Generated by: LCOV version 1.14