LCOV - code coverage report
Current view: top level - src/variables - MooseVariableFE.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 378 532 71.1 %
Date: 2025-07-17 01:28:37 Functions: 145 359 40.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 "MooseVariableFE.h"
      11             : #include <typeinfo>
      12             : #include "TimeIntegrator.h"
      13             : #include "NonlinearSystemBase.h"
      14             : #include "DisplacedSystem.h"
      15             : #include "Assembly.h"
      16             : #include "MooseVariableData.h"
      17             : #include "ArbitraryQuadrature.h"
      18             : 
      19             : #include "libmesh/quadrature_monomial.h"
      20             : 
      21             : using namespace libMesh;
      22             : 
      23             : template <>
      24             : InputParameters
      25      122468 : MooseVariableFE<Real>::validParams()
      26             : {
      27      122468 :   auto params = MooseVariableField<Real>::validParams();
      28      122468 :   params.addClassDescription(
      29             :       "Represents standard field variables, e.g. Lagrange, Hermite, or non-constant Monomials");
      30      122468 :   return params;
      31           0 : }
      32             : 
      33             : template <>
      34             : InputParameters
      35       15848 : MooseVariableFE<RealVectorValue>::validParams()
      36             : {
      37       15848 :   auto params = MooseVariableField<RealVectorValue>::validParams();
      38       15848 :   params.addClassDescription(
      39             :       "Represents vector field variables, e.g. Vector Lagrange, Nedelec or Raviart-Thomas");
      40       15848 :   return params;
      41           0 : }
      42             : 
      43             : template <>
      44             : InputParameters
      45       16761 : MooseVariableFE<RealEigenVector>::validParams()
      46             : {
      47       16761 :   auto params = MooseVariableField<RealEigenVector>::validParams();
      48       16761 :   params.addClassDescription(
      49             :       "Used for grouping standard field variables with the same finite element family and order");
      50       16761 :   return params;
      51           0 : }
      52             : 
      53             : template <typename OutputType>
      54      165179 : MooseVariableFE<OutputType>::MooseVariableFE(const InputParameters & parameters)
      55      165179 :   : MooseVariableField<OutputType>(parameters)
      56             : {
      57      165179 :   _element_data = std::make_unique<MooseVariableData<OutputType>>(*this,
      58             :                                                                   _sys,
      59      165179 :                                                                   _tid,
      60      165179 :                                                                   Moose::ElementType::Element,
      61      165179 :                                                                   this->_assembly.qRule(),
      62      165179 :                                                                   this->_assembly.qRuleFace(),
      63      165179 :                                                                   this->_assembly.node(),
      64      165179 :                                                                   this->_assembly.elem());
      65      165179 :   _neighbor_data = std::make_unique<MooseVariableData<OutputType>>(
      66             :       *this,
      67             :       _sys,
      68      165179 :       _tid,
      69      165179 :       Moose::ElementType::Neighbor,
      70      165179 :       this->_assembly.qRuleNeighbor(), // Place holder
      71      165179 :       this->_assembly.qRuleNeighbor(),
      72      165179 :       this->_assembly.nodeNeighbor(),
      73      165179 :       this->_assembly.neighbor());
      74      165179 :   _lower_data =
      75             :       std::make_unique<MooseVariableData<OutputType>>(*this,
      76             :                                                       _sys,
      77      165179 :                                                       _tid,
      78      165179 :                                                       Moose::ElementType::Lower,
      79      165179 :                                                       this->_assembly.qRuleFace(),
      80      165179 :                                                       this->_assembly.qRuleFace(), // Place holder
      81      165179 :                                                       this->_assembly.node(),      // Place holder
      82      165179 :                                                       this->_assembly.lowerDElem());
      83      165179 : }
      84             : 
      85             : template <typename OutputType>
      86             : void
      87   693405953 : MooseVariableFE<OutputType>::clearDofIndices()
      88             : {
      89   693405953 :   _element_data->clearDofIndices();
      90   693405953 : }
      91             : 
      92             : template <typename OutputType>
      93             : void
      94   467675853 : MooseVariableFE<OutputType>::prepare()
      95             : {
      96   467675853 :   _element_data->prepare();
      97   467675853 : }
      98             : 
      99             : template <typename OutputType>
     100             : void
     101    13311610 : MooseVariableFE<OutputType>::prepareNeighbor()
     102             : {
     103    13311610 :   _neighbor_data->prepare();
     104    13311610 : }
     105             : 
     106             : template <typename OutputType>
     107             : void
     108      580115 : MooseVariableFE<OutputType>::prepareLowerD()
     109             : {
     110      580115 :   _lower_data->prepare();
     111      580115 : }
     112             : 
     113             : template <typename OutputType>
     114             : void
     115     8572939 : MooseVariableFE<OutputType>::prepareAux()
     116             : {
     117     8572939 :   _element_data->prepareAux();
     118     8572939 :   _neighbor_data->prepareAux();
     119     8572939 :   _lower_data->prepareAux();
     120     8572939 : }
     121             : 
     122             : template <typename OutputType>
     123             : void
     124   307731586 : MooseVariableFE<OutputType>::reinitNode()
     125             : {
     126   307731586 :   _element_data->reinitNode();
     127   307731586 : }
     128             : 
     129             : template <typename OutputType>
     130             : void
     131   142955746 : MooseVariableFE<OutputType>::reinitAux()
     132             : {
     133   142955746 :   _element_data->reinitAux();
     134   142955746 : }
     135             : 
     136             : template <typename OutputType>
     137             : void
     138     5556415 : MooseVariableFE<OutputType>::reinitAuxNeighbor()
     139             : {
     140     5556415 :   _neighbor_data->reinitAux();
     141     5556415 : }
     142             : 
     143             : template <typename OutputType>
     144             : void
     145        6190 : MooseVariableFE<OutputType>::reinitNodes(const std::vector<dof_id_type> & nodes)
     146             : {
     147        6190 :   _element_data->reinitNodes(nodes);
     148        6190 : }
     149             : 
     150             : template <typename OutputType>
     151             : void
     152         800 : MooseVariableFE<OutputType>::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes)
     153             : {
     154         800 :   _neighbor_data->reinitNodes(nodes);
     155         800 : }
     156             : 
     157             : template <typename OutputType>
     158             : void
     159       18860 : MooseVariableFE<OutputType>::getDofIndices(const Elem * elem,
     160             :                                            std::vector<dof_id_type> & dof_indices) const
     161             : {
     162       18860 :   _element_data->getDofIndices(elem, dof_indices);
     163       18860 : }
     164             : 
     165             : template <typename OutputType>
     166             : typename MooseVariableFE<OutputType>::OutputData
     167        1220 : MooseVariableFE<OutputType>::getNodalValue(const Node & node) const
     168             : {
     169        1220 :   return _element_data->getNodalValue(node, Moose::Current);
     170             : }
     171             : 
     172             : template <typename OutputType>
     173             : typename MooseVariableFE<OutputType>::OutputData
     174      103334 : MooseVariableFE<OutputType>::getNodalValueOld(const Node & node) const
     175             : {
     176      103334 :   return _element_data->getNodalValue(node, Moose::Old);
     177             : }
     178             : 
     179             : template <typename OutputType>
     180             : typename MooseVariableFE<OutputType>::OutputData
     181           0 : MooseVariableFE<OutputType>::getNodalValueOlder(const Node & node) const
     182             : {
     183           0 :   return _element_data->getNodalValue(node, Moose::Older);
     184             : }
     185             : 
     186             : template <typename OutputType>
     187             : typename MooseVariableFE<OutputType>::OutputData
     188       69928 : MooseVariableFE<OutputType>::getElementalValue(const Elem * elem, unsigned int idx) const
     189             : {
     190       69928 :   return _element_data->getElementalValue(elem, Moose::Current, idx);
     191             : }
     192             : 
     193             : template <typename OutputType>
     194             : typename MooseVariableFE<OutputType>::OutputData
     195         480 : MooseVariableFE<OutputType>::getElementalValueOld(const Elem * elem, unsigned int idx) const
     196             : {
     197         480 :   return _element_data->getElementalValue(elem, Moose::Old, idx);
     198             : }
     199             : 
     200             : template <typename OutputType>
     201             : typename MooseVariableFE<OutputType>::OutputData
     202         480 : MooseVariableFE<OutputType>::getElementalValueOlder(const Elem * elem, unsigned int idx) const
     203             : {
     204         480 :   return _element_data->getElementalValue(elem, Moose::Older, idx);
     205             : }
     206             : 
     207             : template <typename OutputType>
     208             : void
     209    49232061 : MooseVariableFE<OutputType>::insert(NumericVector<Number> & vector)
     210             : {
     211    49232061 :   _element_data->insert(vector);
     212    49232061 : }
     213             : 
     214             : template <typename OutputType>
     215             : void
     216        1644 : MooseVariableFE<OutputType>::insertLower(NumericVector<Number> & vector)
     217             : {
     218        1644 :   _lower_data->insert(vector);
     219        1644 : }
     220             : 
     221             : template <typename OutputType>
     222             : void
     223     2007301 : MooseVariableFE<OutputType>::add(NumericVector<Number> & vector)
     224             : {
     225     2007301 :   _element_data->add(vector);
     226     2007301 : }
     227             : 
     228             : template <typename OutputType>
     229             : void
     230        1760 : MooseVariableFE<OutputType>::addSolution(const DenseVector<Number> & v)
     231             : {
     232        1760 :   _element_data->addSolution(this->_sys.solution(), v);
     233        1760 : }
     234             : 
     235             : template <typename OutputType>
     236             : void
     237         960 : MooseVariableFE<OutputType>::addSolutionNeighbor(const DenseVector<Number> & v)
     238             : {
     239         960 :   _neighbor_data->addSolution(this->_sys.solution(), v);
     240         960 : }
     241             : 
     242             : template <typename OutputType>
     243             : const typename MooseVariableFE<OutputType>::DoFValue &
     244           0 : MooseVariableFE<OutputType>::dofValue() const
     245             : {
     246           0 :   mooseDeprecated("Use dofValues instead of dofValue");
     247           0 :   return dofValues();
     248             : }
     249             : 
     250             : template <typename OutputType>
     251             : const typename MooseVariableFE<OutputType>::DoFValue &
     252      923581 : MooseVariableFE<OutputType>::dofValues() const
     253             : {
     254      923581 :   return _element_data->dofValues();
     255             : }
     256             : 
     257             : template <typename OutputType>
     258             : const typename MooseVariableFE<OutputType>::DoFValue &
     259         102 : MooseVariableFE<OutputType>::dofValuesOld() const
     260             : {
     261         102 :   return _element_data->dofValuesOld();
     262             : }
     263             : 
     264             : template <typename OutputType>
     265             : const typename MooseVariableFE<OutputType>::DoFValue &
     266          39 : MooseVariableFE<OutputType>::dofValuesOlder() const
     267             : {
     268          39 :   return _element_data->dofValuesOlder();
     269             : }
     270             : 
     271             : template <typename OutputType>
     272             : const typename MooseVariableFE<OutputType>::DoFValue &
     273           0 : MooseVariableFE<OutputType>::dofValuesPreviousNL() const
     274             : {
     275           0 :   return _element_data->dofValuesPreviousNL();
     276             : }
     277             : 
     278             : template <typename OutputType>
     279             : const typename MooseVariableFE<OutputType>::DoFValue &
     280          84 : MooseVariableFE<OutputType>::dofValuesNeighbor() const
     281             : {
     282          84 :   return _neighbor_data->dofValues();
     283             : }
     284             : 
     285             : template <typename OutputType>
     286             : const typename MooseVariableFE<OutputType>::DoFValue &
     287          13 : MooseVariableFE<OutputType>::dofValuesOldNeighbor() const
     288             : {
     289          13 :   return _neighbor_data->dofValuesOld();
     290             : }
     291             : 
     292             : template <typename OutputType>
     293             : const typename MooseVariableFE<OutputType>::DoFValue &
     294           0 : MooseVariableFE<OutputType>::dofValuesOlderNeighbor() const
     295             : {
     296           0 :   return _neighbor_data->dofValuesOlder();
     297             : }
     298             : 
     299             : template <typename OutputType>
     300             : const typename MooseVariableFE<OutputType>::DoFValue &
     301           0 : MooseVariableFE<OutputType>::dofValuesPreviousNLNeighbor() const
     302             : {
     303           0 :   return _neighbor_data->dofValuesPreviousNL();
     304             : }
     305             : 
     306             : template <typename OutputType>
     307             : const typename MooseVariableFE<OutputType>::DoFValue &
     308         305 : MooseVariableFE<OutputType>::dofValuesDot() const
     309             : {
     310         305 :   return _element_data->dofValuesDot();
     311             : }
     312             : 
     313             : template <typename OutputType>
     314             : const typename MooseVariableFE<OutputType>::DoFValue &
     315           4 : MooseVariableFE<OutputType>::dofValuesDotDot() const
     316             : {
     317           4 :   return _element_data->dofValuesDotDot();
     318             : }
     319             : 
     320             : template <typename OutputType>
     321             : const typename MooseVariableFE<OutputType>::DoFValue &
     322           0 : MooseVariableFE<OutputType>::dofValuesDotOld() const
     323             : {
     324           0 :   return _element_data->dofValuesDotOld();
     325             : }
     326             : 
     327             : template <typename OutputType>
     328             : const typename MooseVariableFE<OutputType>::DoFValue &
     329           0 : MooseVariableFE<OutputType>::dofValuesDotDotOld() const
     330             : {
     331           0 :   return _element_data->dofValuesDotDotOld();
     332             : }
     333             : 
     334             : template <typename OutputType>
     335             : const typename MooseVariableFE<OutputType>::DoFValue &
     336           0 : MooseVariableFE<OutputType>::dofValuesDotNeighbor() const
     337             : {
     338           0 :   return _neighbor_data->dofValuesDot();
     339             : }
     340             : 
     341             : template <typename OutputType>
     342             : const typename MooseVariableFE<OutputType>::DoFValue &
     343           0 : MooseVariableFE<OutputType>::dofValuesDotDotNeighbor() const
     344             : {
     345           0 :   return _neighbor_data->dofValuesDotDot();
     346             : }
     347             : 
     348             : template <typename OutputType>
     349             : const typename MooseVariableFE<OutputType>::DoFValue &
     350           0 : MooseVariableFE<OutputType>::dofValuesDotOldNeighbor() const
     351             : {
     352           0 :   return _neighbor_data->dofValuesDotOld();
     353             : }
     354             : 
     355             : template <typename OutputType>
     356             : const typename MooseVariableFE<OutputType>::DoFValue &
     357           0 : MooseVariableFE<OutputType>::dofValuesDotDotOldNeighbor() const
     358             : {
     359           0 :   return _neighbor_data->dofValuesDotDotOld();
     360             : }
     361             : 
     362             : template <typename OutputType>
     363             : const MooseArray<Number> &
     364         122 : MooseVariableFE<OutputType>::dofValuesDuDotDu() const
     365             : {
     366         122 :   return _element_data->dofValuesDuDotDu();
     367             : }
     368             : 
     369             : template <typename OutputType>
     370             : const MooseArray<Number> &
     371           0 : MooseVariableFE<OutputType>::dofValuesDuDotDotDu() const
     372             : {
     373           0 :   return _element_data->dofValuesDuDotDotDu();
     374             : }
     375             : 
     376             : template <typename OutputType>
     377             : const MooseArray<Number> &
     378           0 : MooseVariableFE<OutputType>::dofValuesDuDotDuNeighbor() const
     379             : {
     380           0 :   return _neighbor_data->dofValuesDuDotDu();
     381             : }
     382             : 
     383             : template <typename OutputType>
     384             : const MooseArray<Number> &
     385           0 : MooseVariableFE<OutputType>::dofValuesDuDotDotDuNeighbor() const
     386             : {
     387           0 :   return _neighbor_data->dofValuesDuDotDotDu();
     388             : }
     389             : 
     390             : template <typename OutputType>
     391             : void
     392     1998668 : MooseVariableFE<OutputType>::prepareIC()
     393             : {
     394     1998668 :   _element_data->prepareIC();
     395     1998668 : }
     396             : 
     397             : template <typename OutputType>
     398             : void
     399   524572406 : MooseVariableFE<OutputType>::computeElemValues()
     400             : {
     401   524572406 :   _element_data->setGeometry(Moose::Volume);
     402   524572406 :   _element_data->computeValues();
     403   524572406 : }
     404             : 
     405             : template <typename OutputType>
     406             : void
     407    22604868 : MooseVariableFE<OutputType>::computeElemValuesFace()
     408             : {
     409    22604868 :   _element_data->setGeometry(Moose::Face);
     410    22604868 :   _element_data->computeValues();
     411    22604868 : }
     412             : 
     413             : template <typename OutputType>
     414             : void
     415     8555386 : MooseVariableFE<OutputType>::computeNeighborValuesFace()
     416             : {
     417     8555386 :   _neighbor_data->setGeometry(Moose::Face);
     418     8555386 :   _neighbor_data->computeValues();
     419     8555386 : }
     420             : 
     421             : template <typename OutputType>
     422             : void
     423       29120 : MooseVariableFE<OutputType>::computeNeighborValues()
     424             : {
     425       29120 :   _neighbor_data->setGeometry(Moose::Volume);
     426       29120 :   _neighbor_data->computeValues();
     427       29120 : }
     428             : 
     429             : template <typename OutputType>
     430             : void
     431      580115 : MooseVariableFE<OutputType>::computeLowerDValues()
     432             : {
     433      580115 :   _lower_data->setGeometry(Moose::Volume);
     434      580115 :   _lower_data->computeValues();
     435      580115 : }
     436             : 
     437             : template <typename OutputType>
     438             : void
     439        1774 : MooseVariableFE<OutputType>::computeIncrementAtQps(const NumericVector<Number> & increment_vec)
     440             : {
     441        1774 :   _element_data->computeIncrementAtQps(increment_vec);
     442        1774 : }
     443             : 
     444             : template <typename OutputType>
     445             : void
     446        7440 : MooseVariableFE<OutputType>::computeIncrementAtNode(const NumericVector<Number> & increment_vec)
     447             : {
     448        7440 :   _element_data->computeIncrementAtNode(increment_vec);
     449        7440 : }
     450             : 
     451             : template <typename OutputType>
     452             : OutputType
     453      253568 : MooseVariableFE<OutputType>::getValue(const Elem * elem,
     454             :                                       const std::vector<std::vector<OutputShape>> & phi) const
     455             : {
     456      253568 :   std::vector<dof_id_type> dof_indices;
     457      253568 :   this->_dof_map.dof_indices(elem, dof_indices, _var_num);
     458             : 
     459      253568 :   OutputType value = 0;
     460      253568 :   if (isNodal())
     461             :   {
     462             :     mooseAssert(dof_indices.size() == phi.size(),
     463             :                 "The number of shapes does not match the number of dof indices on the elem");
     464             : 
     465     1121652 :     for (unsigned int i = 0; i < dof_indices.size(); ++i)
     466             :     {
     467             :       // The zero index is because we only have one point that the phis are evaluated at
     468      868084 :       value += phi[i][0] * (*this->_sys.currentSolution())(dof_indices[i]);
     469             :     }
     470             :   }
     471             :   else
     472             :   {
     473             :     mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
     474           0 :     value = (*this->_sys.currentSolution())(dof_indices[0]);
     475             :   }
     476             : 
     477      253568 :   return value;
     478      253568 : }
     479             : 
     480             : template <>
     481             : RealEigenVector
     482           0 : MooseVariableFE<RealEigenVector>::getValue(const Elem * elem,
     483             :                                            const std::vector<std::vector<Real>> & phi) const
     484             : {
     485           0 :   std::vector<dof_id_type> dof_indices;
     486           0 :   this->_dof_map.dof_indices(elem, dof_indices, _var_num);
     487             : 
     488           0 :   RealEigenVector value(_count);
     489           0 :   if (isNodal())
     490             :   {
     491           0 :     for (unsigned int i = 0; i < dof_indices.size(); ++i)
     492           0 :       for (unsigned int j = 0; j < _count; j++)
     493             :       {
     494             :         // The zero index is because we only have one point that the phis are evaluated at
     495           0 :         value(j) += phi[i][0] * (*this->_sys.currentSolution())(dof_indices[i] + j);
     496             :       }
     497             :   }
     498             :   else
     499             :   {
     500             :     mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
     501           0 :     unsigned int n = 0;
     502           0 :     for (unsigned int j = 0; j < _count; j++)
     503             :     {
     504           0 :       value(j) = (*this->_sys.currentSolution())(dof_indices[0] + n);
     505           0 :       n += this->_dof_indices.size();
     506             :     }
     507             :   }
     508             : 
     509           0 :   return value;
     510           0 : }
     511             : 
     512             : template <typename OutputType>
     513             : typename OutputTools<OutputType>::OutputGradient
     514           0 : MooseVariableFE<OutputType>::getGradient(
     515             :     const Elem * elem,
     516             :     const std::vector<std::vector<typename OutputTools<OutputType>::OutputShapeGradient>> &
     517             :         grad_phi) const
     518             : {
     519           0 :   std::vector<dof_id_type> dof_indices;
     520           0 :   this->_dof_map.dof_indices(elem, dof_indices, _var_num);
     521             : 
     522           0 :   typename OutputTools<OutputType>::OutputGradient value;
     523           0 :   if (isNodal())
     524             :   {
     525           0 :     for (unsigned int i = 0; i < dof_indices.size(); ++i)
     526             :     {
     527             :       // The zero index is because we only have one point that the phis are evaluated at
     528           0 :       value += grad_phi[i][0] * (*this->_sys.currentSolution())(dof_indices[i]);
     529             :     }
     530             :   }
     531             :   else
     532             :   {
     533             :     mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
     534           0 :     value = 0.0;
     535             :   }
     536             : 
     537           0 :   return value;
     538           0 : }
     539             : 
     540             : template <>
     541             : RealVectorArrayValue
     542           0 : MooseVariableFE<RealEigenVector>::getGradient(
     543             :     const Elem * elem, const std::vector<std::vector<RealVectorValue>> & grad_phi) const
     544             : {
     545           0 :   std::vector<dof_id_type> dof_indices;
     546           0 :   this->_dof_map.dof_indices(elem, dof_indices, _var_num);
     547             : 
     548           0 :   RealVectorArrayValue value(_count, LIBMESH_DIM);
     549           0 :   if (isNodal())
     550             :   {
     551           0 :     for (unsigned int i = 0; i < dof_indices.size(); ++i)
     552           0 :       for (unsigned int j = 0; j < _count; ++j)
     553           0 :         for (const auto k : make_range(Moose::dim))
     554             :         {
     555             :           // The zero index is because we only have one point that the phis are evaluated at
     556           0 :           value(j, k) += grad_phi[i][0](k) * (*this->_sys.currentSolution())(dof_indices[i] + j);
     557             :         }
     558             :   }
     559             :   else
     560             :   {
     561             :     mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
     562             :   }
     563             : 
     564           0 :   return value;
     565           0 : }
     566             : 
     567             : template <typename OutputType>
     568             : const OutputType &
     569        1233 : MooseVariableFE<OutputType>::nodalValue() const
     570             : {
     571        1233 :   return _element_data->nodalValue(Moose::Current);
     572             : }
     573             : 
     574             : template <typename OutputType>
     575             : const OutputType &
     576           0 : MooseVariableFE<OutputType>::nodalValueNeighbor() const
     577             : {
     578           0 :   return _neighbor_data->nodalValue(Moose::Current);
     579             : }
     580             : 
     581             : template <typename OutputType>
     582             : const typename MooseVariableFE<OutputType>::DoFValue &
     583         363 : MooseVariableFE<OutputType>::nodalVectorTagValue(TagID tag) const
     584             : {
     585         363 :   return _element_data->nodalVectorTagValue(tag);
     586             : }
     587             : 
     588             : template <typename OutputType>
     589             : const typename MooseVariableFE<OutputType>::DoFValue &
     590         130 : MooseVariableFE<OutputType>::nodalMatrixTagValue(TagID tag) const
     591             : {
     592         130 :   return _element_data->nodalMatrixTagValue(tag);
     593             : }
     594             : 
     595             : template <typename OutputType>
     596             : const OutputType &
     597           0 : MooseVariableFE<OutputType>::nodalValueOld() const
     598             : {
     599           0 :   return _element_data->nodalValue(Moose::Old);
     600             : }
     601             : 
     602             : template <typename OutputType>
     603             : const OutputType &
     604           0 : MooseVariableFE<OutputType>::nodalValueOldNeighbor() const
     605             : {
     606           0 :   return _neighbor_data->nodalValue(Moose::Old);
     607             : }
     608             : 
     609             : template <typename OutputType>
     610             : const OutputType &
     611           0 : MooseVariableFE<OutputType>::nodalValueOlder() const
     612             : {
     613           0 :   return _element_data->nodalValue(Moose::Older);
     614             : }
     615             : 
     616             : template <typename OutputType>
     617             : const OutputType &
     618           0 : MooseVariableFE<OutputType>::nodalValueOlderNeighbor() const
     619             : {
     620           0 :   return _neighbor_data->nodalValue(Moose::Older);
     621             : }
     622             : 
     623             : template <typename OutputType>
     624             : const OutputType &
     625           0 : MooseVariableFE<OutputType>::nodalValuePreviousNL() const
     626             : {
     627           0 :   return _element_data->nodalValue(Moose::PreviousNL);
     628             : }
     629             : 
     630             : template <typename OutputType>
     631             : const OutputType &
     632           0 : MooseVariableFE<OutputType>::nodalValuePreviousNLNeighbor() const
     633             : {
     634           0 :   return _neighbor_data->nodalValue(Moose::PreviousNL);
     635             : }
     636             : 
     637             : template <typename OutputType>
     638             : const OutputType &
     639           0 : MooseVariableFE<OutputType>::nodalValueDot() const
     640             : {
     641           0 :   return _element_data->nodalValueDot();
     642             : }
     643             : 
     644             : template <typename OutputType>
     645             : const OutputType &
     646           0 : MooseVariableFE<OutputType>::nodalValueDotDot() const
     647             : {
     648           0 :   return _element_data->nodalValueDotDot();
     649             : }
     650             : 
     651             : template <typename OutputType>
     652             : const OutputType &
     653           0 : MooseVariableFE<OutputType>::nodalValueDotOld() const
     654             : {
     655           0 :   return _element_data->nodalValueDotOld();
     656             : }
     657             : 
     658             : template <typename OutputType>
     659             : const OutputType &
     660           0 : MooseVariableFE<OutputType>::nodalValueDotDotOld() const
     661             : {
     662           0 :   return _element_data->nodalValueDotDotOld();
     663             : }
     664             : 
     665             : template <typename OutputType>
     666             : void
     667   270794637 : MooseVariableFE<OutputType>::computeNodalValues()
     668             : {
     669   270794637 :   _element_data->computeNodalValues();
     670   270794637 : }
     671             : 
     672             : template <typename OutputType>
     673             : void
     674         800 : MooseVariableFE<OutputType>::computeNodalNeighborValues()
     675             : {
     676         800 :   _neighbor_data->computeNodalValues();
     677         800 : }
     678             : 
     679             : template <typename OutputType>
     680             : void
     681    45408588 : MooseVariableFE<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
     682             : {
     683    45408588 :   _element_data->setNodalValue(value, idx);
     684    45408588 : }
     685             : 
     686             : template <typename OutputType>
     687             : void
     688     7623827 : MooseVariableFE<OutputType>::setDofValue(const OutputData & value, unsigned int index)
     689             : {
     690     7623827 :   _element_data->setDofValue(value, index);
     691     7623827 : }
     692             : 
     693             : template <typename OutputType>
     694             : void
     695      571836 : MooseVariableFE<OutputType>::setDofValues(const DenseVector<OutputData> & values)
     696             : {
     697      571836 :   _element_data->setDofValues(values);
     698      571836 : }
     699             : 
     700             : template <typename OutputType>
     701             : void
     702        1644 : MooseVariableFE<OutputType>::setLowerDofValues(const DenseVector<OutputData> & values)
     703             : {
     704        1644 :   _lower_data->setDofValues(values);
     705        1644 : }
     706             : 
     707             : template <typename OutputType>
     708             : void
     709    54801697 : MooseVariableFE<OutputType>::insertNodalValue(NumericVector<Number> & residual,
     710             :                                               const OutputData & v)
     711             : {
     712    54801697 :   _element_data->insertNodalValue(residual, v);
     713    54801697 : }
     714             : 
     715             : template <typename OutputType>
     716             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     717       26699 : MooseVariableFE<OutputType>::secondPhi() const
     718             : {
     719       26699 :   return _element_data->secondPhi();
     720             : }
     721             : 
     722             : template <typename OutputType>
     723             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     724       57036 : MooseVariableFE<OutputType>::curlPhi() const
     725             : {
     726       57036 :   return _element_data->curlPhi();
     727             : }
     728             : 
     729             : template <typename OutputType>
     730             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     731      468756 : MooseVariableFE<OutputType>::divPhi() const
     732             : {
     733      468756 :   return _element_data->divPhi();
     734             : }
     735             : 
     736             : template <typename OutputType>
     737             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     738        5221 : MooseVariableFE<OutputType>::secondPhiFace() const
     739             : {
     740        5221 :   return _element_data->secondPhiFace();
     741             : }
     742             : 
     743             : template <typename OutputType>
     744             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     745           0 : MooseVariableFE<OutputType>::curlPhiFace() const
     746             : {
     747           0 :   return _element_data->curlPhiFace();
     748             : }
     749             : 
     750             : template <typename OutputType>
     751             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     752           0 : MooseVariableFE<OutputType>::divPhiFace() const
     753             : {
     754           0 :   return _element_data->divPhiFace();
     755             : }
     756             : 
     757             : template <typename OutputType>
     758             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     759           0 : MooseVariableFE<OutputType>::secondPhiNeighbor() const
     760             : {
     761           0 :   return _neighbor_data->secondPhi();
     762             : }
     763             : 
     764             : template <typename OutputType>
     765             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     766           0 : MooseVariableFE<OutputType>::curlPhiNeighbor() const
     767             : {
     768           0 :   return _neighbor_data->curlPhi();
     769             : }
     770             : 
     771             : template <typename OutputType>
     772             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     773           0 : MooseVariableFE<OutputType>::divPhiNeighbor() const
     774             : {
     775           0 :   return _neighbor_data->divPhi();
     776             : }
     777             : 
     778             : template <typename OutputType>
     779             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     780           0 : MooseVariableFE<OutputType>::secondPhiFaceNeighbor() const
     781             : {
     782           0 :   return _neighbor_data->secondPhiFace();
     783             : }
     784             : 
     785             : template <typename OutputType>
     786             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     787           0 : MooseVariableFE<OutputType>::curlPhiFaceNeighbor() const
     788             : {
     789           0 :   return _neighbor_data->curlPhiFace();
     790             : }
     791             : 
     792             : template <typename OutputType>
     793             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     794           0 : MooseVariableFE<OutputType>::divPhiFaceNeighbor() const
     795             : {
     796           0 :   return _neighbor_data->divPhiFace();
     797             : }
     798             : 
     799             : template <typename OutputType>
     800             : bool
     801   131499690 : MooseVariableFE<OutputType>::usesSecondPhi() const
     802             : {
     803   131499690 :   return _element_data->usesSecondPhi();
     804             : }
     805             : 
     806             : template <typename OutputType>
     807             : bool
     808      194810 : MooseVariableFE<OutputType>::usesSecondPhiNeighbor() const
     809             : {
     810      194810 :   return _neighbor_data->usesSecondPhi();
     811             : }
     812             : 
     813             : template <typename OutputType>
     814             : bool
     815     1950419 : MooseVariableFE<OutputType>::computingCurl() const
     816             : {
     817     1950419 :   return _element_data->computingCurl();
     818             : }
     819             : 
     820             : template <typename OutputType>
     821             : bool
     822     1950419 : MooseVariableFE<OutputType>::computingDiv() const
     823             : {
     824     1950419 :   return _element_data->computingDiv();
     825             : }
     826             : 
     827             : template <typename OutputType>
     828             : bool
     829   442052425 : MooseVariableFE<OutputType>::isNodalDefined() const
     830             : {
     831   442052425 :   return _element_data->isNodalDefined();
     832             : }
     833             : 
     834             : template <typename OutputType>
     835             : bool
     836           0 : MooseVariableFE<OutputType>::isNodalNeighborDefined() const
     837             : {
     838           0 :   return _neighbor_data->isNodalDefined();
     839             : }
     840             : 
     841             : template <typename OutputType>
     842             : unsigned int
     843      145344 : MooseVariableFE<OutputType>::oldestSolutionStateRequested() const
     844             : {
     845      145344 :   unsigned int state = 0;
     846      145344 :   state = std::max(state, _element_data->oldestSolutionStateRequested());
     847      145344 :   state = std::max(state, _neighbor_data->oldestSolutionStateRequested());
     848      145344 :   state = std::max(state, _lower_data->oldestSolutionStateRequested());
     849      145344 :   return state;
     850             : }
     851             : 
     852             : template <typename OutputType>
     853             : void
     854     1208735 : MooseVariableFE<OutputType>::clearAllDofIndices()
     855             : {
     856     1208735 :   _element_data->clearDofIndices();
     857     1208735 :   _neighbor_data->clearDofIndices();
     858     1208735 :   _lower_data->clearDofIndices();
     859     1208735 : }
     860             : 
     861             : template <typename OutputType>
     862             : typename MooseVariableFE<OutputType>::ValueType
     863       77346 : MooseVariableFE<OutputType>::evaluate(const NodeArg & node_arg, const StateArg & state) const
     864             : {
     865             :   mooseAssert(node_arg.node, "Must have a node");
     866       77346 :   const Node & node = *node_arg.node;
     867             :   mooseAssert(node.n_dofs(this->_sys.number(), this->number()),
     868             :               "Our variable must have dofs on the requested node");
     869       77346 :   const auto & soln = this->getSolution(state);
     870             :   if constexpr (std::is_same<OutputType, Real>::value)
     871             :   {
     872       77346 :     const auto dof_number = node.dof_number(this->_sys.number(), this->number(), 0);
     873       77346 :     ValueType ret = soln(dof_number);
     874       77346 :     if (Moose::doDerivatives(_subproblem, _sys))
     875       19528 :       Moose::derivInsert(ret.derivatives(), dof_number, 1);
     876      154692 :     return ret;
     877       77346 :   }
     878             :   else if constexpr (std::is_same<OutputType, RealVectorValue>::value)
     879             :   {
     880           0 :     ValueType ret;
     881           0 :     const auto do_derivatives = Moose::doDerivatives(_subproblem, _sys);
     882           0 :     for (const auto d : make_range(this->_mesh.dimension()))
     883             :     {
     884           0 :       const auto dof_number = node.dof_number(this->_sys.number(), this->number(), d);
     885           0 :       auto & component = ret(d);
     886           0 :       component = soln(dof_number);
     887           0 :       if (do_derivatives)
     888           0 :         Moose::derivInsert(component.derivatives(), dof_number, 1);
     889             :     }
     890           0 :     return ret;
     891           0 :   }
     892             :   else
     893           0 :     mooseError("RealEigenVector not yet supported for functors");
     894             : }
     895             : 
     896             : namespace
     897             : {
     898             : template <typename OutputType>
     899             : struct FEBaseHelper
     900             : {
     901             :   typedef FEBase type;
     902             : };
     903             : 
     904             : template <>
     905             : struct FEBaseHelper<RealVectorValue>
     906             : {
     907             :   typedef FEVectorBase type;
     908             : };
     909             : }
     910             : 
     911             : template <typename OutputType>
     912             : template <typename Shapes, typename Solution, typename GradShapes, typename GradSolution>
     913             : void
     914      870135 : MooseVariableFE<OutputType>::computeSolution(const Elem * const elem,
     915             :                                              const unsigned int n_qp,
     916             :                                              const StateArg & state,
     917             :                                              const Shapes & phi,
     918             :                                              Solution & local_soln,
     919             :                                              const GradShapes & grad_phi,
     920             :                                              GradSolution & grad_local_soln,
     921             :                                              Solution & dot_local_soln,
     922             :                                              GradSolution & grad_dot_local_soln) const
     923             : {
     924      870135 :   std::vector<dof_id_type> dof_indices;
     925      870135 :   this->_dof_map.dof_indices(elem, dof_indices, _var_num);
     926      870135 :   std::vector<ADReal> dof_values;
     927      870135 :   std::vector<ADReal> dof_values_dot;
     928      870135 :   dof_values.reserve(dof_indices.size());
     929             : 
     930      870135 :   const bool computing_dot = _time_integrator && _time_integrator->dt();
     931      870135 :   if (computing_dot)
     932      301200 :     dof_values_dot.reserve(dof_indices.size());
     933             : 
     934      870135 :   const bool do_derivatives = Moose::doDerivatives(_subproblem, _sys);
     935      870135 :   const auto & global_soln = getSolution(state);
     936     3735025 :   for (const auto dof_index : dof_indices)
     937             :   {
     938     2864890 :     dof_values.push_back(ADReal(global_soln(dof_index)));
     939     2864890 :     if (do_derivatives && state.state == 0)
     940      304402 :       Moose::derivInsert(dof_values.back().derivatives(), dof_index, 1.);
     941     2864890 :     if (computing_dot)
     942             :     {
     943     1546456 :       if (_var_kind == Moose::VAR_SOLVER)
     944             :       {
     945     1542040 :         dof_values_dot.push_back(dof_values.back());
     946     1542040 :         _time_integrator->computeADTimeDerivatives(
     947     1542040 :             dof_values_dot.back(), dof_index, _ad_real_dummy);
     948             :       }
     949             :       else
     950        4416 :         dof_values_dot.push_back((*this->_sys.solutionUDot())(dof_index));
     951             :     }
     952             :   }
     953             : 
     954      870135 :   local_soln.resize(n_qp);
     955      870135 :   grad_local_soln.resize(n_qp);
     956      870135 :   if (computing_dot)
     957             :   {
     958      301200 :     dot_local_soln.resize(n_qp);
     959      301200 :     grad_dot_local_soln.resize(n_qp);
     960             :   }
     961             : 
     962     3662544 :   for (const auto qp : make_range(n_qp))
     963             :   {
     964     2792409 :     local_soln[qp] = 0;
     965     2792409 :     grad_local_soln[qp] = 0;
     966     2792409 :     if (computing_dot)
     967             :     {
     968     1535704 :       dot_local_soln[qp] = 0;
     969     1535704 :       grad_dot_local_soln[qp] = GradientType{};
     970             :     }
     971    14884827 :     for (const auto i : index_range(dof_indices))
     972             :     {
     973    12092418 :       local_soln[qp] += dof_values[i] * phi[i][qp];
     974    12092418 :       grad_local_soln[qp] += dof_values[i] * grad_phi[i][qp];
     975    12092418 :       if (computing_dot)
     976             :       {
     977     8919832 :         dot_local_soln[qp] += dof_values_dot[i] * phi[i][qp];
     978     8919832 :         grad_dot_local_soln[qp] += dof_values_dot[i] * grad_phi[i][qp];
     979             :       }
     980             :     }
     981             :   }
     982      870135 : }
     983             : 
     984             : template <typename OutputType>
     985             : void
     986    14093595 : MooseVariableFE<OutputType>::evaluateOnElement(const ElemQpArg & elem_qp,
     987             :                                                const StateArg & state,
     988             :                                                const bool cache_eligible) const
     989             : {
     990             :   mooseAssert(this->hasBlocks(elem_qp.elem->subdomain_id()),
     991             :               "Variable " + this->name() + " doesn't exist on block " +
     992             :                   std::to_string(elem_qp.elem->subdomain_id()));
     993             : 
     994    14093595 :   const Elem * const elem = elem_qp.elem;
     995    14093595 :   if (!cache_eligible || (elem != _current_elem_qp_functor_elem))
     996             :   {
     997      858063 :     const QBase * const qrule_template = elem_qp.qrule;
     998             : 
     999             :     using FEBaseType = typename FEBaseHelper<OutputType>::type;
    1000      858063 :     std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
    1001      858063 :     auto qrule = qrule_template->clone();
    1002             : 
    1003      858063 :     const auto & phi = fe->get_phi();
    1004      858063 :     const auto & dphi = fe->get_dphi();
    1005      858063 :     fe->attach_quadrature_rule(qrule.get());
    1006      858063 :     fe->reinit(elem);
    1007             : 
    1008      858063 :     computeSolution(elem,
    1009             :                     qrule->n_points(),
    1010             :                     state,
    1011             :                     phi,
    1012      858063 :                     _current_elem_qp_functor_sln,
    1013             :                     dphi,
    1014      858063 :                     _current_elem_qp_functor_gradient,
    1015      858063 :                     _current_elem_qp_functor_dot,
    1016      858063 :                     _current_elem_qp_functor_grad_dot);
    1017      858063 :   }
    1018    14093595 :   if (cache_eligible)
    1019    14088083 :     _current_elem_qp_functor_elem = elem;
    1020             :   else
    1021             :     // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
    1022             :     // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
    1023             :     // re-used when this function is called with a standard quadrature rule or a different point
    1024        5512 :     _current_elem_qp_functor_elem = nullptr;
    1025    14093595 : }
    1026             : 
    1027             : template <>
    1028             : void
    1029           0 : MooseVariableFE<RealEigenVector>::evaluateOnElement(const ElemQpArg &, const StateArg &, bool) const
    1030             : {
    1031           0 :   mooseError("evaluate not implemented for array variables");
    1032             : }
    1033             : 
    1034             : template <typename OutputType>
    1035             : typename MooseVariableFE<OutputType>::ValueType
    1036     2208211 : MooseVariableFE<OutputType>::evaluate(const ElemQpArg & elem_qp, const StateArg & state) const
    1037             : {
    1038     2208211 :   evaluateOnElement(elem_qp, state, /*query_cache=*/true);
    1039     2208211 :   const auto qp = elem_qp.qp;
    1040             :   mooseAssert(qp < _current_elem_qp_functor_sln.size(),
    1041             :               "The requested " << qp << " is outside our solution size");
    1042     2208211 :   return _current_elem_qp_functor_sln[qp];
    1043             : }
    1044             : 
    1045             : template <typename OutputType>
    1046             : typename MooseVariableFE<OutputType>::ValueType
    1047        1608 : MooseVariableFE<OutputType>::evaluate(const ElemArg & elem_arg, const StateArg & state) const
    1048             : {
    1049        1608 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1050             :   // We can use whatever we want for the point argument since it won't be used
    1051        1608 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1052        1608 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1053        3216 :   return _current_elem_qp_functor_sln[0];
    1054        1608 : }
    1055             : 
    1056             : template <typename OutputType>
    1057             : typename MooseVariableFE<OutputType>::ValueType
    1058         346 : MooseVariableFE<OutputType>::faceEvaluate(const FaceArg & face_arg,
    1059             :                                           const StateArg & state,
    1060             :                                           const std::vector<ValueType> & cache_data) const
    1061             : {
    1062         346 :   const QMonomial qrule(face_arg.fi->elem().dim() - 1, CONSTANT);
    1063         346 :   auto side_evaluate =
    1064        1038 :       [this, &qrule, &state, &cache_data](const Elem * const elem, const unsigned int side)
    1065             :   {
    1066             :     // We can use whatever we want for the point argument since it won't be used
    1067         346 :     const ElemSideQpArg elem_side_qp_arg{elem, side, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1068         346 :     evaluateOnElementSide(elem_side_qp_arg, state, /*cache_eligible=*/false);
    1069         692 :     return cache_data[0];
    1070             :   };
    1071             : 
    1072         346 :   const auto continuity = this->getContinuity();
    1073             :   bool on_elem;
    1074             :   bool on_neighbor;
    1075         346 :   if (!face_arg.face_side)
    1076             :   {
    1077           0 :     on_elem = this->hasBlocks(face_arg.fi->elemPtr()->subdomain_id());
    1078           0 :     on_neighbor =
    1079           0 :         face_arg.fi->neighborPtr() && this->hasBlocks(face_arg.fi->neighborPtr()->subdomain_id());
    1080             :   }
    1081             :   else
    1082             :   {
    1083         346 :     on_elem = face_arg.face_side == face_arg.fi->elemPtr();
    1084         346 :     on_neighbor = face_arg.face_side == face_arg.fi->neighborPtr();
    1085             :   }
    1086             : 
    1087             :   // Only do multiple evaluations if we are not continuous and we are on an internal face
    1088         346 :   if ((continuity != C_ZERO && continuity != C_ONE) && on_elem && on_neighbor)
    1089           0 :     return (side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID()) +
    1090           0 :             side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID())) /
    1091           0 :            2;
    1092         346 :   else if (on_elem)
    1093         346 :     return side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID());
    1094           0 :   else if (on_neighbor)
    1095           0 :     return side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID());
    1096             :   else
    1097           0 :     mooseError(
    1098             :         "Attempted to evaluate a moose finite element variable on a face where it is not defined");
    1099         346 : }
    1100             : 
    1101             : template <typename OutputType>
    1102             : typename MooseVariableFE<OutputType>::ValueType
    1103         346 : MooseVariableFE<OutputType>::evaluate(const FaceArg & face_arg, const StateArg & state) const
    1104             : {
    1105         346 :   return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_sln);
    1106             : }
    1107             : 
    1108             : template <typename OutputType>
    1109             : typename MooseVariableFE<OutputType>::ValueType
    1110         512 : MooseVariableFE<OutputType>::evaluate(const ElemPointArg & elem_point_arg,
    1111             :                                       const StateArg & state) const
    1112             : {
    1113             :   mooseAssert(elem_point_arg.elem, "We need an Elem");
    1114         512 :   const Elem & elem = *elem_point_arg.elem;
    1115         512 :   const auto dim = elem.dim();
    1116         512 :   ArbitraryQuadrature qrule(dim);
    1117         512 :   const std::vector<Point> ref_point = {FEMap::inverse_map(dim, &elem, elem_point_arg.point)};
    1118         512 :   qrule.setPoints(ref_point);
    1119             :   // We can use whatever we want for the point argument since it won't be used
    1120         512 :   const ElemQpArg elem_qp_arg{elem_point_arg.elem, /*qp=*/0, &qrule, elem_point_arg.point};
    1121         512 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1122        1024 :   return _current_elem_qp_functor_sln[0];
    1123         512 : }
    1124             : 
    1125             : template <typename OutputType>
    1126             : typename MooseVariableFE<OutputType>::GradientType
    1127    11047488 : MooseVariableFE<OutputType>::evaluateGradient(const ElemQpArg & elem_qp,
    1128             :                                               const StateArg & state) const
    1129             : {
    1130    11047488 :   evaluateOnElement(elem_qp, state, /*query_cache=*/true);
    1131    11047488 :   const auto qp = elem_qp.qp;
    1132             :   mooseAssert(qp < _current_elem_qp_functor_gradient.size(),
    1133             :               "The requested " << qp << " is outside our gradient size");
    1134    11047488 :   return _current_elem_qp_functor_gradient[qp];
    1135             : }
    1136             : 
    1137             : template <typename OutputType>
    1138             : typename MooseVariableFE<OutputType>::GradientType
    1139         960 : MooseVariableFE<OutputType>::evaluateGradient(const ElemArg & elem_arg,
    1140             :                                               const StateArg & state) const
    1141             : {
    1142         960 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1143             :   // We can use whatever we want for the point argument since it won't be used
    1144         960 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1145         960 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1146        1920 :   return _current_elem_qp_functor_gradient[0];
    1147         960 : }
    1148             : 
    1149             : template <typename OutputType>
    1150             : typename MooseVariableFE<OutputType>::DotType
    1151      832384 : MooseVariableFE<OutputType>::evaluateDot(const ElemQpArg & elem_qp, const StateArg & state) const
    1152             : {
    1153             :   mooseAssert(_time_integrator,
    1154             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1155             :               "have no idea how to compute it");
    1156             :   mooseAssert(_time_integrator->dt(),
    1157             :               "A time derivative is being requested but the time integrator wants to perform a 0s "
    1158             :               "time step");
    1159      832384 :   evaluateOnElement(elem_qp, state, /*query_cache=*/true);
    1160      832384 :   const auto qp = elem_qp.qp;
    1161             :   mooseAssert(qp < _current_elem_qp_functor_dot.size(),
    1162             :               "The requested " << qp << " is outside our dot size");
    1163      832384 :   return _current_elem_qp_functor_dot[qp];
    1164             : }
    1165             : 
    1166             : template <typename OutputType>
    1167             : typename MooseVariableFE<OutputType>::DotType
    1168        1472 : MooseVariableFE<OutputType>::evaluateDot(const ElemArg & elem_arg, const StateArg & state) const
    1169             : {
    1170             :   mooseAssert(_time_integrator,
    1171             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1172             :               "have no idea how to compute it");
    1173             :   mooseAssert(_time_integrator->dt(),
    1174             :               "A time derivative is being requested but the time integrator wants to perform a 0s "
    1175             :               "time step");
    1176        1472 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1177             :   // We can use whatever we want for the point argument since it won't be used
    1178        1472 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1179        1472 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1180        2944 :   return _current_elem_qp_functor_dot[0];
    1181        1472 : }
    1182             : 
    1183             : template <typename OutputType>
    1184             : typename MooseVariableFE<OutputType>::GradientType
    1185         960 : MooseVariableFE<OutputType>::evaluateGradDot(const ElemArg & elem_arg, const StateArg & state) const
    1186             : {
    1187             :   mooseAssert(_time_integrator,
    1188             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1189             :               "have no idea how to compute it");
    1190             :   mooseAssert(_time_integrator->dt(),
    1191             :               "A time derivative is being requested but the time integrator wants to perform a 0s "
    1192             :               "time step");
    1193         960 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1194             :   // We can use whatever we want for the point argument since it won't be used
    1195         960 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1196         960 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1197        1920 :   return _current_elem_qp_functor_grad_dot[0];
    1198         960 : }
    1199             : 
    1200             : template <typename OutputType>
    1201             : void
    1202       87658 : MooseVariableFE<OutputType>::evaluateOnElementSide(const ElemSideQpArg & elem_side_qp,
    1203             :                                                    const StateArg & state,
    1204             :                                                    const bool cache_eligible) const
    1205             : {
    1206             :   mooseAssert(this->hasBlocks(elem_side_qp.elem->subdomain_id()),
    1207             :               "Variable " + this->name() + " doesn't exist on block " +
    1208             :                   std::to_string(elem_side_qp.elem->subdomain_id()));
    1209             : 
    1210       87658 :   const Elem * const elem = elem_side_qp.elem;
    1211       87658 :   const auto side = elem_side_qp.side;
    1212       87658 :   if (!cache_eligible || elem != _current_elem_side_qp_functor_elem_side.first ||
    1213       75922 :       side != _current_elem_side_qp_functor_elem_side.second)
    1214             :   {
    1215       12072 :     const QBase * const qrule_template = elem_side_qp.qrule;
    1216             : 
    1217             :     using FEBaseType = typename FEBaseHelper<OutputType>::type;
    1218       12072 :     std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
    1219       12072 :     auto qrule = qrule_template->clone();
    1220             : 
    1221       12072 :     const auto & phi = fe->get_phi();
    1222       12072 :     const auto & dphi = fe->get_dphi();
    1223       12072 :     fe->attach_quadrature_rule(qrule.get());
    1224       12072 :     fe->reinit(elem, side);
    1225             : 
    1226       12072 :     computeSolution(elem,
    1227             :                     qrule->n_points(),
    1228             :                     state,
    1229             :                     phi,
    1230       12072 :                     _current_elem_side_qp_functor_sln,
    1231             :                     dphi,
    1232       12072 :                     _current_elem_side_qp_functor_gradient,
    1233       12072 :                     _current_elem_side_qp_functor_dot,
    1234       12072 :                     _current_elem_side_qp_functor_grad_dot);
    1235       12072 :   }
    1236       87658 :   if (cache_eligible)
    1237       87312 :     _current_elem_side_qp_functor_elem_side = std::make_pair(elem, side);
    1238             :   else
    1239             :     // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
    1240             :     // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
    1241             :     // re-used when this function is called with a standard quadrature rule or a different point
    1242         346 :     _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1243       87658 : }
    1244             : 
    1245             : template <>
    1246             : void
    1247           0 : MooseVariableFE<RealEigenVector>::evaluateOnElementSide(const ElemSideQpArg &,
    1248             :                                                         const StateArg &,
    1249             :                                                         bool) const
    1250             : {
    1251           0 :   mooseError("evaluate not implemented for array variables");
    1252             : }
    1253             : 
    1254             : template <typename OutputType>
    1255             : typename MooseVariableFE<OutputType>::ValueType
    1256       87312 : MooseVariableFE<OutputType>::evaluate(const ElemSideQpArg & elem_side_qp,
    1257             :                                       const StateArg & state) const
    1258             : {
    1259       87312 :   evaluateOnElementSide(elem_side_qp, state, true);
    1260       87312 :   const auto qp = elem_side_qp.qp;
    1261             :   mooseAssert(qp < _current_elem_side_qp_functor_sln.size(),
    1262             :               "The requested " << qp << " is outside our solution size");
    1263       87312 :   return _current_elem_side_qp_functor_sln[qp];
    1264             : }
    1265             : 
    1266             : template <typename OutputType>
    1267             : typename MooseVariableFE<OutputType>::GradientType
    1268           0 : MooseVariableFE<OutputType>::evaluateGradient(const ElemSideQpArg & elem_side_qp,
    1269             :                                               const StateArg & state) const
    1270             : {
    1271           0 :   evaluateOnElementSide(elem_side_qp, state, true);
    1272           0 :   const auto qp = elem_side_qp.qp;
    1273             :   mooseAssert(qp < _current_elem_side_qp_functor_gradient.size(),
    1274             :               "The requested " << qp << " is outside our gradient size");
    1275           0 :   return _current_elem_side_qp_functor_gradient[qp];
    1276             : }
    1277             : 
    1278             : template <typename OutputType>
    1279             : typename MooseVariableFE<OutputType>::DotType
    1280           0 : MooseVariableFE<OutputType>::evaluateDot(const ElemSideQpArg & elem_side_qp,
    1281             :                                          const StateArg & state) const
    1282             : {
    1283             :   mooseAssert(_time_integrator && _time_integrator->dt(),
    1284             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1285             :               "have no idea how to compute it");
    1286           0 :   evaluateOnElementSide(elem_side_qp, state, true);
    1287           0 :   const auto qp = elem_side_qp.qp;
    1288             :   mooseAssert(qp < _current_elem_side_qp_functor_dot.size(),
    1289             :               "The requested " << qp << " is outside our dot size");
    1290           0 :   return _current_elem_side_qp_functor_dot[qp];
    1291             : }
    1292             : 
    1293             : template <typename OutputType>
    1294             : typename MooseVariableFE<OutputType>::DotType
    1295           0 : MooseVariableFE<OutputType>::evaluateDot(const FaceArg & face_arg, const StateArg & state) const
    1296             : {
    1297             :   mooseAssert(_time_integrator && _time_integrator->dt(),
    1298             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1299             :               "have no idea how to compute it");
    1300           0 :   return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_dot);
    1301             : }
    1302             : 
    1303             : template <>
    1304             : typename MooseVariableFE<RealEigenVector>::ValueType
    1305           0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemQpArg &, const StateArg &) const
    1306             : {
    1307           0 :   mooseError(
    1308             :       "MooseVariableFE::evaluate(ElemQpArg &, const StateArg &) overload not implemented for "
    1309             :       "array variables");
    1310             : }
    1311             : 
    1312             : template <>
    1313             : typename MooseVariableFE<RealEigenVector>::ValueType
    1314           0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemSideQpArg &, const StateArg &) const
    1315             : {
    1316           0 :   mooseError("MooseVariableFE::evaluate(ElemSideQpArg &, const StateArg &) overload not "
    1317             :              "implemented for array variables");
    1318             : }
    1319             : 
    1320             : template <>
    1321             : typename MooseVariableFE<RealEigenVector>::GradientType
    1322           0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemQpArg &, const StateArg &) const
    1323             : {
    1324           0 :   mooseError("MooseVariableFE::evaluateGradient(ElemQpArg &, const StateArg &) overload not "
    1325             :              "implemented for array variables");
    1326             : }
    1327             : 
    1328             : template <>
    1329             : typename MooseVariableFE<RealEigenVector>::GradientType
    1330           0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemSideQpArg &, const StateArg &) const
    1331             : {
    1332           0 :   mooseError("MooseVariableFE::evaluateGradient(ElemSideQpArg &, const StateArg &) overload not "
    1333             :              "implemented for array variables");
    1334             : }
    1335             : 
    1336             : template <>
    1337             : typename MooseVariableFE<RealEigenVector>::DotType
    1338           0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemQpArg &, const StateArg &) const
    1339             : {
    1340           0 :   mooseError("MooseVariableFE::evaluateDot(ElemQpArg &, const StateArg &) overload not "
    1341             :              "implemented for array variables");
    1342             : }
    1343             : 
    1344             : template <>
    1345             : typename MooseVariableFE<RealEigenVector>::DotType
    1346           0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemSideQpArg &, const StateArg &) const
    1347             : {
    1348           0 :   mooseError("MooseVariableFE::evaluateDot(ElemSideQpArg &, const StateArg &) overload not "
    1349             :              "implemented for array variables");
    1350             : }
    1351             : 
    1352             : template <typename OutputType>
    1353             : void
    1354       20675 : MooseVariableFE<OutputType>::meshChanged()
    1355             : {
    1356       20675 :   _current_elem_qp_functor_elem = nullptr;
    1357       20675 :   _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1358       20675 :   MooseVariableField<OutputType>::meshChanged();
    1359       20675 : }
    1360             : 
    1361             : template <typename OutputType>
    1362             : void
    1363     7247313 : MooseVariableFE<OutputType>::residualSetup()
    1364             : {
    1365     7247313 :   _current_elem_qp_functor_elem = nullptr;
    1366     7247313 :   _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1367     7247313 :   MooseVariableField<OutputType>::residualSetup();
    1368     7247313 : }
    1369             : 
    1370             : template <typename OutputType>
    1371             : void
    1372     1204373 : MooseVariableFE<OutputType>::jacobianSetup()
    1373             : {
    1374     1204373 :   _current_elem_qp_functor_elem = nullptr;
    1375     1204373 :   _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1376     1204373 :   MooseVariableField<OutputType>::jacobianSetup();
    1377     1204373 : }
    1378             : 
    1379             : template class MooseVariableFE<Real>;
    1380             : template class MooseVariableFE<RealVectorValue>;
    1381             : template class MooseVariableFE<RealEigenVector>;

Generated by: LCOV version 1.14