LCOV - code coverage report
Current view: top level - src/variables - MooseVariableFE.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 386 537 71.9 %
Date: 2026-05-29 20:35:17 Functions: 153 364 42.0 %
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      116885 : MooseVariableFE<Real>::validParams()
      26             : {
      27      116885 :   auto params = MooseVariableField<Real>::validParams();
      28      116885 :   params.addClassDescription(
      29             :       "Represents standard field variables, e.g. Lagrange, Hermite, or non-constant Monomials");
      30      116885 :   return params;
      31           0 : }
      32             : 
      33             : template <>
      34             : InputParameters
      35        4627 : MooseVariableFE<RealVectorValue>::validParams()
      36             : {
      37        4627 :   auto params = MooseVariableField<RealVectorValue>::validParams();
      38        4627 :   params.addClassDescription(
      39             :       "Represents vector field variables, e.g. Vector Lagrange, Nedelec or Raviart-Thomas");
      40        4627 :   return params;
      41           0 : }
      42             : 
      43             : template <>
      44             : InputParameters
      45        5574 : MooseVariableFE<RealEigenVector>::validParams()
      46             : {
      47        5574 :   auto params = MooseVariableField<RealEigenVector>::validParams();
      48        5574 :   params.addClassDescription(
      49             :       "Used for grouping standard field variables with the same finite element family and order");
      50        5574 :   return params;
      51           0 : }
      52             : 
      53             : template <typename OutputType>
      54      174071 : MooseVariableFE<OutputType>::MooseVariableFE(const InputParameters & parameters)
      55      174071 :   : MooseVariableField<OutputType>(parameters)
      56             : {
      57      174071 :   _element_data = std::make_unique<MooseVariableData<OutputType>>(*this,
      58             :                                                                   _sys,
      59      174071 :                                                                   _tid,
      60      174071 :                                                                   Moose::ElementType::Element,
      61      174071 :                                                                   this->_assembly.qRule(),
      62      174071 :                                                                   this->_assembly.qRuleFace(),
      63      174071 :                                                                   this->_assembly.node(),
      64      174071 :                                                                   this->_assembly.elem());
      65      174071 :   _neighbor_data = std::make_unique<MooseVariableData<OutputType>>(
      66             :       *this,
      67             :       _sys,
      68      174071 :       _tid,
      69      174071 :       Moose::ElementType::Neighbor,
      70      174071 :       this->_assembly.qRuleNeighbor(), // Place holder
      71      174071 :       this->_assembly.qRuleNeighbor(),
      72      174071 :       this->_assembly.nodeNeighbor(),
      73      174071 :       this->_assembly.neighbor());
      74      174071 :   _lower_data =
      75             :       std::make_unique<MooseVariableData<OutputType>>(*this,
      76             :                                                       _sys,
      77      174071 :                                                       _tid,
      78      174071 :                                                       Moose::ElementType::Lower,
      79      174071 :                                                       this->_assembly.qRuleFace(),
      80      174071 :                                                       this->_assembly.qRuleFace(), // Place holder
      81      174071 :                                                       this->_assembly.node(),      // Place holder
      82      174071 :                                                       this->_assembly.lowerDElem());
      83      174071 : }
      84             : 
      85             : template <typename OutputType>
      86             : void
      87   691173809 : MooseVariableFE<OutputType>::clearDofIndices()
      88             : {
      89   691173809 :   _element_data->clearDofIndices();
      90   691173809 : }
      91             : 
      92             : template <typename OutputType>
      93             : void
      94   460622142 : MooseVariableFE<OutputType>::prepare()
      95             : {
      96   460622142 :   _element_data->prepare();
      97   460622142 : }
      98             : 
      99             : template <typename OutputType>
     100             : void
     101    12686135 : MooseVariableFE<OutputType>::prepareNeighbor()
     102             : {
     103    12686135 :   _neighbor_data->prepare();
     104    12686135 : }
     105             : 
     106             : template <typename OutputType>
     107             : void
     108      567998 : MooseVariableFE<OutputType>::prepareLowerD()
     109             : {
     110      567998 :   _lower_data->prepare();
     111      567998 : }
     112             : 
     113             : template <typename OutputType>
     114             : void
     115     8245939 : MooseVariableFE<OutputType>::prepareAux()
     116             : {
     117     8245939 :   _element_data->prepareAux();
     118     8245939 :   _neighbor_data->prepareAux();
     119     8245939 :   _lower_data->prepareAux();
     120     8245939 : }
     121             : 
     122             : template <typename OutputType>
     123             : void
     124   282198903 : MooseVariableFE<OutputType>::reinitNode()
     125             : {
     126   282198903 :   _element_data->reinitNode();
     127   282198903 : }
     128             : 
     129             : template <typename OutputType>
     130             : void
     131   146841631 : MooseVariableFE<OutputType>::reinitAux()
     132             : {
     133   146841631 :   _element_data->reinitAux();
     134   146841631 : }
     135             : 
     136             : template <typename OutputType>
     137             : void
     138     5366777 : MooseVariableFE<OutputType>::reinitAuxNeighbor()
     139             : {
     140     5366777 :   _neighbor_data->reinitAux();
     141     5366777 : }
     142             : 
     143             : template <typename OutputType>
     144             : void
     145        5355 : MooseVariableFE<OutputType>::reinitNodes(const std::vector<dof_id_type> & nodes)
     146             : {
     147        5355 :   _element_data->reinitNodes(nodes);
     148        5355 : }
     149             : 
     150             : template <typename OutputType>
     151             : void
     152        1257 : MooseVariableFE<OutputType>::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes)
     153             : {
     154        1257 :   _neighbor_data->reinitNodes(nodes);
     155        1257 : }
     156             : 
     157             : template <typename OutputType>
     158             : void
     159       18960 : MooseVariableFE<OutputType>::getDofIndices(const Elem * elem,
     160             :                                            std::vector<dof_id_type> & dof_indices) const
     161             : {
     162       18960 :   _element_data->getDofIndices(elem, dof_indices);
     163       18960 : }
     164             : 
     165             : template <typename OutputType>
     166             : typename MooseVariableFE<OutputType>::DofValue
     167        1199 : MooseVariableFE<OutputType>::getNodalValue(const Node & node) const
     168             : {
     169        1199 :   return _element_data->getNodalValue(node, Moose::Current);
     170             : }
     171             : 
     172             : template <typename OutputType>
     173             : typename MooseVariableFE<OutputType>::DofValue
     174      108900 : MooseVariableFE<OutputType>::getNodalValueOld(const Node & node) const
     175             : {
     176      108900 :   return _element_data->getNodalValue(node, Moose::Old);
     177             : }
     178             : 
     179             : template <typename OutputType>
     180             : typename MooseVariableFE<OutputType>::DofValue
     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>::DofValue
     188       69803 : MooseVariableFE<OutputType>::getElementalValue(const Elem * elem, unsigned int idx) const
     189             : {
     190       69803 :   return _element_data->getElementalValue(elem, Moose::Current, idx);
     191             : }
     192             : 
     193             : template <typename OutputType>
     194             : typename MooseVariableFE<OutputType>::DofValue
     195         492 : MooseVariableFE<OutputType>::getElementalValueOld(const Elem * elem, unsigned int idx) const
     196             : {
     197         492 :   return _element_data->getElementalValue(elem, Moose::Old, idx);
     198             : }
     199             : 
     200             : template <typename OutputType>
     201             : typename MooseVariableFE<OutputType>::DofValue
     202         492 : MooseVariableFE<OutputType>::getElementalValueOlder(const Elem * elem, unsigned int idx) const
     203             : {
     204         492 :   return _element_data->getElementalValue(elem, Moose::Older, idx);
     205             : }
     206             : 
     207             : template <typename OutputType>
     208             : void
     209    49830860 : MooseVariableFE<OutputType>::insert(NumericVector<Number> & vector)
     210             : {
     211    49830860 :   _element_data->insert(vector);
     212    49830860 : }
     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     1923567 : MooseVariableFE<OutputType>::add(NumericVector<Number> & vector)
     224             : {
     225     1923567 :   _element_data->add(vector);
     226     1923567 : }
     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>::DofValues &
     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>::DofValues &
     252      890830 : MooseVariableFE<OutputType>::dofValues() const
     253             : {
     254      890830 :   return _element_data->dofValues();
     255             : }
     256             : 
     257             : template <typename OutputType>
     258             : const typename MooseVariableFE<OutputType>::DofValues &
     259         115 : MooseVariableFE<OutputType>::dofValuesOld() const
     260             : {
     261         115 :   return _element_data->dofValuesOld();
     262             : }
     263             : 
     264             : template <typename OutputType>
     265             : const typename MooseVariableFE<OutputType>::DofValues &
     266          52 : MooseVariableFE<OutputType>::dofValuesOlder() const
     267             : {
     268          52 :   return _element_data->dofValuesOlder();
     269             : }
     270             : 
     271             : template <typename OutputType>
     272             : const typename MooseVariableFE<OutputType>::DofValues &
     273           0 : MooseVariableFE<OutputType>::dofValuesPreviousNL() const
     274             : {
     275           0 :   return _element_data->dofValuesPreviousNL();
     276             : }
     277             : 
     278             : template <typename OutputType>
     279             : const typename MooseVariableFE<OutputType>::DofValues &
     280         114 : MooseVariableFE<OutputType>::dofValuesNeighbor() const
     281             : {
     282         114 :   return _neighbor_data->dofValues();
     283             : }
     284             : 
     285             : template <typename OutputType>
     286             : const typename MooseVariableFE<OutputType>::DofValues &
     287          13 : MooseVariableFE<OutputType>::dofValuesOldNeighbor() const
     288             : {
     289          13 :   return _neighbor_data->dofValuesOld();
     290             : }
     291             : 
     292             : template <typename OutputType>
     293             : const typename MooseVariableFE<OutputType>::DofValues &
     294           0 : MooseVariableFE<OutputType>::dofValuesOlderNeighbor() const
     295             : {
     296           0 :   return _neighbor_data->dofValuesOlder();
     297             : }
     298             : 
     299             : template <typename OutputType>
     300             : const typename MooseVariableFE<OutputType>::DofValues &
     301           0 : MooseVariableFE<OutputType>::dofValuesPreviousNLNeighbor() const
     302             : {
     303           0 :   return _neighbor_data->dofValuesPreviousNL();
     304             : }
     305             : 
     306             : template <typename OutputType>
     307             : const typename MooseVariableFE<OutputType>::DofValues &
     308         348 : MooseVariableFE<OutputType>::dofValuesDot() const
     309             : {
     310         348 :   return _element_data->dofValuesDot();
     311             : }
     312             : 
     313             : template <typename OutputType>
     314             : const typename MooseVariableFE<OutputType>::DofValues &
     315           3 : MooseVariableFE<OutputType>::dofValuesDotDot() const
     316             : {
     317           3 :   return _element_data->dofValuesDotDot();
     318             : }
     319             : 
     320             : template <typename OutputType>
     321             : const typename MooseVariableFE<OutputType>::DofValues &
     322           0 : MooseVariableFE<OutputType>::dofValuesDotOld() const
     323             : {
     324           0 :   return _element_data->dofValuesDotOld();
     325             : }
     326             : 
     327             : template <typename OutputType>
     328             : const typename MooseVariableFE<OutputType>::DofValues &
     329           0 : MooseVariableFE<OutputType>::dofValuesDotDotOld() const
     330             : {
     331           0 :   return _element_data->dofValuesDotDotOld();
     332             : }
     333             : 
     334             : template <typename OutputType>
     335             : const typename MooseVariableFE<OutputType>::DofValues &
     336           0 : MooseVariableFE<OutputType>::dofValuesDotNeighbor() const
     337             : {
     338           0 :   return _neighbor_data->dofValuesDot();
     339             : }
     340             : 
     341             : template <typename OutputType>
     342             : const typename MooseVariableFE<OutputType>::DofValues &
     343           0 : MooseVariableFE<OutputType>::dofValuesDotDotNeighbor() const
     344             : {
     345           0 :   return _neighbor_data->dofValuesDotDot();
     346             : }
     347             : 
     348             : template <typename OutputType>
     349             : const typename MooseVariableFE<OutputType>::DofValues &
     350           0 : MooseVariableFE<OutputType>::dofValuesDotOldNeighbor() const
     351             : {
     352           0 :   return _neighbor_data->dofValuesDotOld();
     353             : }
     354             : 
     355             : template <typename OutputType>
     356             : const typename MooseVariableFE<OutputType>::DofValues &
     357           0 : MooseVariableFE<OutputType>::dofValuesDotDotOldNeighbor() const
     358             : {
     359           0 :   return _neighbor_data->dofValuesDotDotOld();
     360             : }
     361             : 
     362             : template <typename OutputType>
     363             : const MooseArray<Number> &
     364         165 : MooseVariableFE<OutputType>::dofValuesDuDotDu() const
     365             : {
     366         165 :   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     2207079 : MooseVariableFE<OutputType>::prepareIC()
     393             : {
     394     2207079 :   _element_data->prepareIC();
     395     2207079 : }
     396             : 
     397             : template <typename OutputType>
     398             : void
     399   520547203 : MooseVariableFE<OutputType>::computeElemValues()
     400             : {
     401   520547203 :   _element_data->setGeometry(Moose::Volume);
     402   520547203 :   _element_data->computeValues();
     403   520547203 : }
     404             : 
     405             : template <typename OutputType>
     406             : void
     407    15701447 : MooseVariableFE<OutputType>::computeElemValuesFace()
     408             : {
     409    15701447 :   _element_data->setGeometry(Moose::Face);
     410    15701447 :   _element_data->computeValues();
     411    15701447 : }
     412             : 
     413             : template <typename OutputType>
     414             : void
     415     8106973 : MooseVariableFE<OutputType>::computeNeighborValuesFace()
     416             : {
     417     8106973 :   _neighbor_data->setGeometry(Moose::Face);
     418     8106973 :   _neighbor_data->computeValues();
     419     8106973 : }
     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      567998 : MooseVariableFE<OutputType>::computeLowerDValues()
     432             : {
     433      567998 :   _lower_data->setGeometry(Moose::Volume);
     434      567998 :   _lower_data->computeValues();
     435      567998 : }
     436             : 
     437             : template <typename OutputType>
     438             : void
     439        1563 : MooseVariableFE<OutputType>::computeIncrementAtQps(const NumericVector<Number> & increment_vec)
     440             : {
     441        1563 :   _element_data->computeIncrementAtQps(increment_vec);
     442        1563 : }
     443             : 
     444             : template <typename OutputType>
     445             : void
     446        7525 : MooseVariableFE<OutputType>::computeIncrementAtNode(const NumericVector<Number> & increment_vec)
     447             : {
     448        7525 :   _element_data->computeIncrementAtNode(increment_vec);
     449        7525 : }
     450             : 
     451             : template <typename OutputType>
     452             : OutputType
     453      252897 : MooseVariableFE<OutputType>::getValue(const Elem * elem,
     454             :                                       const std::vector<std::vector<OutputShape>> & phi) const
     455             : {
     456      252897 :   std::vector<dof_id_type> dof_indices;
     457      252897 :   this->_dof_map.dof_indices(elem, dof_indices, _var_num);
     458             : 
     459      252897 :   OutputType value = 0;
     460      252897 :   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     1120539 :     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      867642 :       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      252897 :   return value;
     478      252897 : }
     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        1239 : MooseVariableFE<OutputType>::nodalValue() const
     570             : {
     571        1239 :   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>::DofValues &
     583         433 : MooseVariableFE<OutputType>::nodalVectorTagValue(TagID tag) const
     584             : {
     585         433 :   return _element_data->nodalVectorTagValue(tag);
     586             : }
     587             : 
     588             : template <typename OutputType>
     589             : const typename MooseVariableFE<OutputType>::DofValues &
     590         225 : MooseVariableFE<OutputType>::nodalMatrixTagValue(TagID tag) const
     591             : {
     592         225 :   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   246347577 : MooseVariableFE<OutputType>::computeNodalValues()
     668             : {
     669   246347577 :   _element_data->computeNodalValues();
     670   246347577 : }
     671             : 
     672             : template <typename OutputType>
     673             : void
     674        1257 : MooseVariableFE<OutputType>::computeNodalNeighborValues()
     675             : {
     676        1257 :   _neighbor_data->computeNodalValues();
     677        1257 : }
     678             : 
     679             : template <typename OutputType>
     680             : void
     681    45819322 : MooseVariableFE<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
     682             : {
     683    45819322 :   _element_data->setNodalValue(value, idx);
     684    45819322 : }
     685             : 
     686             : template <typename OutputType>
     687             : void
     688     8421231 : MooseVariableFE<OutputType>::setDofValue(const DofValue & value, unsigned int index)
     689             : {
     690     8421231 :   _element_data->setDofValue(value, index);
     691     8421231 : }
     692             : 
     693             : template <typename OutputType>
     694             : void
     695      581243 : MooseVariableFE<OutputType>::setDofValues(const DenseVector<DofValue> & values)
     696             : {
     697      581243 :   _element_data->setDofValues(values);
     698      581243 : }
     699             : 
     700             : template <typename OutputType>
     701             : void
     702        1644 : MooseVariableFE<OutputType>::setLowerDofValues(const DenseVector<DofValue> & values)
     703             : {
     704        1644 :   _lower_data->setDofValues(values);
     705        1644 : }
     706             : 
     707             : template <typename OutputType>
     708             : void
     709    55691662 : MooseVariableFE<OutputType>::insertNodalValue(NumericVector<Number> & residual, const DofValue & v)
     710             : {
     711    55691662 :   _element_data->insertNodalValue(residual, v);
     712    55691662 : }
     713             : 
     714             : template <typename OutputType>
     715             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     716       24335 : MooseVariableFE<OutputType>::secondPhi() const
     717             : {
     718       24335 :   return _element_data->secondPhi();
     719             : }
     720             : 
     721             : template <typename OutputType>
     722             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     723       57030 : MooseVariableFE<OutputType>::curlPhi() const
     724             : {
     725       57030 :   return _element_data->curlPhi();
     726             : }
     727             : 
     728             : template <typename OutputType>
     729             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     730      520870 : MooseVariableFE<OutputType>::divPhi() const
     731             : {
     732      520870 :   return _element_data->divPhi();
     733             : }
     734             : 
     735             : template <typename OutputType>
     736             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     737        4261 : MooseVariableFE<OutputType>::secondPhiFace() const
     738             : {
     739        4261 :   return _element_data->secondPhiFace();
     740             : }
     741             : 
     742             : template <typename OutputType>
     743             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     744           0 : MooseVariableFE<OutputType>::curlPhiFace() const
     745             : {
     746           0 :   return _element_data->curlPhiFace();
     747             : }
     748             : 
     749             : template <typename OutputType>
     750             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     751           0 : MooseVariableFE<OutputType>::divPhiFace() const
     752             : {
     753           0 :   return _element_data->divPhiFace();
     754             : }
     755             : 
     756             : template <typename OutputType>
     757             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     758           0 : MooseVariableFE<OutputType>::secondPhiNeighbor() const
     759             : {
     760           0 :   return _neighbor_data->secondPhi();
     761             : }
     762             : 
     763             : template <typename OutputType>
     764             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     765           0 : MooseVariableFE<OutputType>::curlPhiNeighbor() const
     766             : {
     767           0 :   return _neighbor_data->curlPhi();
     768             : }
     769             : 
     770             : template <typename OutputType>
     771             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     772           0 : MooseVariableFE<OutputType>::divPhiNeighbor() const
     773             : {
     774           0 :   return _neighbor_data->divPhi();
     775             : }
     776             : 
     777             : template <typename OutputType>
     778             : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
     779           0 : MooseVariableFE<OutputType>::secondPhiFaceNeighbor() const
     780             : {
     781           0 :   return _neighbor_data->secondPhiFace();
     782             : }
     783             : 
     784             : template <typename OutputType>
     785             : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
     786           0 : MooseVariableFE<OutputType>::curlPhiFaceNeighbor() const
     787             : {
     788           0 :   return _neighbor_data->curlPhiFace();
     789             : }
     790             : 
     791             : template <typename OutputType>
     792             : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
     793           0 : MooseVariableFE<OutputType>::divPhiFaceNeighbor() const
     794             : {
     795           0 :   return _neighbor_data->divPhiFace();
     796             : }
     797             : 
     798             : template <typename OutputType>
     799             : bool
     800   126918663 : MooseVariableFE<OutputType>::usesSecondPhi() const
     801             : {
     802   126918663 :   return _element_data->usesSecondPhi();
     803             : }
     804             : 
     805             : template <typename OutputType>
     806             : bool
     807      188641 : MooseVariableFE<OutputType>::usesSecondPhiNeighbor() const
     808             : {
     809      188641 :   return _neighbor_data->usesSecondPhi();
     810             : }
     811             : 
     812             : template <typename OutputType>
     813             : bool
     814     1873054 : MooseVariableFE<OutputType>::computingCurl() const
     815             : {
     816     1873054 :   return _element_data->computingCurl();
     817             : }
     818             : 
     819             : template <typename OutputType>
     820             : bool
     821     1873054 : MooseVariableFE<OutputType>::computingDiv() const
     822             : {
     823     1873054 :   return _element_data->computingDiv();
     824             : }
     825             : 
     826             : template <typename OutputType>
     827             : bool
     828   418254962 : MooseVariableFE<OutputType>::isNodalDefined() const
     829             : {
     830   418254962 :   return _element_data->isNodalDefined();
     831             : }
     832             : 
     833             : template <typename OutputType>
     834             : bool
     835           0 : MooseVariableFE<OutputType>::isNodalNeighborDefined() const
     836             : {
     837           0 :   return _neighbor_data->isNodalDefined();
     838             : }
     839             : 
     840             : template <typename OutputType>
     841             : unsigned int
     842      153919 : MooseVariableFE<OutputType>::oldestSolutionStateRequested() const
     843             : {
     844      153919 :   unsigned int state = 0;
     845      153919 :   state = std::max(state, _element_data->oldestSolutionStateRequested());
     846      153919 :   state = std::max(state, _neighbor_data->oldestSolutionStateRequested());
     847      153919 :   state = std::max(state, _lower_data->oldestSolutionStateRequested());
     848      153919 :   return state;
     849             : }
     850             : 
     851             : template <typename OutputType>
     852             : void
     853     1234433 : MooseVariableFE<OutputType>::clearAllDofIndices()
     854             : {
     855     1234433 :   _element_data->clearDofIndices();
     856     1234433 :   _neighbor_data->clearDofIndices();
     857     1234433 :   _lower_data->clearDofIndices();
     858     1234433 : }
     859             : 
     860             : template <typename OutputType>
     861             : typename MooseVariableFE<OutputType>::ValueType
     862       80384 : MooseVariableFE<OutputType>::evaluate(const NodeArg & node_arg, const StateArg & state) const
     863             : {
     864             :   mooseAssert(node_arg.node, "Must have a node");
     865       80384 :   const Node & node = *node_arg.node;
     866             :   mooseAssert(node.n_dofs(this->_sys.number(), this->number()),
     867             :               "Our variable must have dofs on the requested node");
     868       80384 :   const auto & soln = this->getSolution(state);
     869             :   if constexpr (std::is_same<OutputType, Real>::value)
     870             :   {
     871       80384 :     const auto dof_number = node.dof_number(this->_sys.number(), this->number(), 0);
     872       80384 :     ValueType ret = soln(dof_number);
     873       80384 :     if (Moose::doDerivatives(_subproblem, _sys))
     874       19104 :       Moose::derivInsert(ret.derivatives(), dof_number, 1);
     875      160768 :     return ret;
     876       80384 :   }
     877             :   else if constexpr (std::is_same<OutputType, RealVectorValue>::value)
     878             :   {
     879           0 :     ValueType ret;
     880           0 :     const auto do_derivatives = Moose::doDerivatives(_subproblem, _sys);
     881           0 :     for (const auto d : make_range(this->_mesh.dimension()))
     882             :     {
     883           0 :       const auto dof_number = node.dof_number(this->_sys.number(), this->number(), d);
     884           0 :       auto & component = ret(d);
     885           0 :       component = soln(dof_number);
     886           0 :       if (do_derivatives)
     887           0 :         Moose::derivInsert(component.derivatives(), dof_number, 1);
     888             :     }
     889           0 :     return ret;
     890           0 :   }
     891             :   else
     892           0 :     mooseError("RealEigenVector not yet supported for functors");
     893             : }
     894             : 
     895             : namespace
     896             : {
     897             : template <typename OutputType>
     898             : struct FEBaseHelper
     899             : {
     900             :   typedef FEBase type;
     901             : };
     902             : 
     903             : template <>
     904             : struct FEBaseHelper<RealVectorValue>
     905             : {
     906             :   typedef FEVectorBase type;
     907             : };
     908             : }
     909             : 
     910             : template <typename OutputType>
     911             : template <typename Shapes, typename Solution, typename GradShapes, typename GradSolution>
     912             : void
     913      864590 : MooseVariableFE<OutputType>::computeSolution(const Elem * const elem,
     914             :                                              const unsigned int n_qp,
     915             :                                              const StateArg & state,
     916             :                                              const Shapes & phi,
     917             :                                              Solution & local_soln,
     918             :                                              const GradShapes & grad_phi,
     919             :                                              GradSolution & grad_local_soln,
     920             :                                              Solution & dot_local_soln,
     921             :                                              GradSolution & grad_dot_local_soln) const
     922             : {
     923      864590 :   std::vector<dof_id_type> dof_indices;
     924      864590 :   this->_dof_map.dof_indices(elem, dof_indices, _var_num);
     925      864590 :   std::vector<ADReal> dof_values;
     926      864590 :   std::vector<ADReal> dof_values_dot;
     927      864590 :   dof_values.reserve(dof_indices.size());
     928             : 
     929      864590 :   const bool computing_dot = _time_integrator && _time_integrator->dt();
     930      864590 :   if (computing_dot)
     931      321170 :     dof_values_dot.reserve(dof_indices.size());
     932             : 
     933      864590 :   const bool do_derivatives = Moose::doDerivatives(_subproblem, _sys);
     934      864590 :   const auto & global_soln = getSolution(state);
     935     3869072 :   for (const auto dof_index : dof_indices)
     936             :   {
     937     3004482 :     dof_values.push_back(ADReal(global_soln(dof_index)));
     938     3004482 :     if (do_derivatives && state.state == 0)
     939      356376 :       Moose::derivInsert(dof_values.back().derivatives(), dof_index, 1.);
     940     3004482 :     if (computing_dot)
     941             :     {
     942     1652174 :       if (_var_kind == Moose::VAR_SOLVER)
     943             :       {
     944     1637940 :         dof_values_dot.push_back(dof_values.back());
     945     1637940 :         _time_integrator->computeADTimeDerivatives(
     946     1637940 :             dof_values_dot.back(), dof_index, _ad_real_dummy);
     947             :       }
     948             :       else
     949       14234 :         dof_values_dot.push_back((*this->_sys.solutionUDot())(dof_index));
     950             :     }
     951             :   }
     952             : 
     953      864590 :   local_soln.resize(n_qp);
     954      864590 :   grad_local_soln.resize(n_qp);
     955      864590 :   if (computing_dot)
     956             :   {
     957      321170 :     dot_local_soln.resize(n_qp);
     958      321170 :     grad_dot_local_soln.resize(n_qp);
     959             :   }
     960             : 
     961     3720158 :   for (const auto qp : make_range(n_qp))
     962             :   {
     963     2855568 :     local_soln[qp] = 0;
     964     2855568 :     grad_local_soln[qp] = 0;
     965     2855568 :     if (computing_dot)
     966             :     {
     967     1629086 :       dot_local_soln[qp] = 0;
     968     1629086 :       grad_dot_local_soln[qp] = GradientType{};
     969             :     }
     970    15756838 :     for (const auto i : index_range(dof_indices))
     971             :     {
     972    12901270 :       local_soln[qp] += dof_values[i] * phi[i][qp];
     973    12901270 :       grad_local_soln[qp] += dof_values[i] * grad_phi[i][qp];
     974    12901270 :       if (computing_dot)
     975             :       {
     976     9579322 :         dot_local_soln[qp] += dof_values_dot[i] * phi[i][qp];
     977     9579322 :         grad_dot_local_soln[qp] += dof_values_dot[i] * grad_phi[i][qp];
     978             :       }
     979             :     }
     980             :   }
     981      864590 : }
     982             : 
     983             : template <typename OutputType>
     984             : void
     985    14297900 : MooseVariableFE<OutputType>::evaluateOnElement(const ElemQpArg & elem_qp,
     986             :                                                const StateArg & state,
     987             :                                                const bool cache_eligible) const
     988             : {
     989             :   mooseAssert(this->hasBlocks(elem_qp.elem->subdomain_id()),
     990             :               "Variable " + this->name() + " doesn't exist on block " +
     991             :                   std::to_string(elem_qp.elem->subdomain_id()));
     992             : 
     993    14297900 :   const Elem * const elem = elem_qp.elem;
     994    14297900 :   if (!cache_eligible || (elem != _current_elem_qp_functor_elem))
     995             :   {
     996      847992 :     const QBase * const qrule_template = elem_qp.qrule;
     997             : 
     998             :     using FEBaseType = typename FEBaseHelper<OutputType>::type;
     999      847992 :     std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
    1000      847992 :     auto qrule = qrule_template->clone();
    1001             : 
    1002      847992 :     const auto & phi = fe->get_phi();
    1003      847992 :     const auto & dphi = fe->get_dphi();
    1004      847992 :     fe->attach_quadrature_rule(qrule.get());
    1005      847992 :     fe->reinit(elem);
    1006             : 
    1007      847992 :     computeSolution(elem,
    1008             :                     qrule->n_points(),
    1009             :                     state,
    1010             :                     phi,
    1011      847992 :                     _current_elem_qp_functor_sln,
    1012             :                     dphi,
    1013      847992 :                     _current_elem_qp_functor_gradient,
    1014      847992 :                     _current_elem_qp_functor_dot,
    1015      847992 :                     _current_elem_qp_functor_grad_dot);
    1016      847992 :   }
    1017    14297900 :   if (cache_eligible)
    1018    14269036 :     _current_elem_qp_functor_elem = elem;
    1019             :   else
    1020             :     // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
    1021             :     // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
    1022             :     // re-used when this function is called with a standard quadrature rule or a different point
    1023       28864 :     _current_elem_qp_functor_elem = nullptr;
    1024    14297900 : }
    1025             : 
    1026             : template <>
    1027             : void
    1028           0 : MooseVariableFE<RealEigenVector>::evaluateOnElement(const ElemQpArg &, const StateArg &, bool) const
    1029             : {
    1030           0 :   mooseError("evaluate not implemented for array variables");
    1031             : }
    1032             : 
    1033             : template <typename OutputType>
    1034             : typename MooseVariableFE<OutputType>::ValueType
    1035     2023396 : MooseVariableFE<OutputType>::evaluate(const ElemQpArg & elem_qp, const StateArg & state) const
    1036             : {
    1037     2023396 :   evaluateOnElement(elem_qp, state, /*query_cache=*/true);
    1038     2023396 :   const auto qp = elem_qp.qp;
    1039             :   mooseAssert(qp < _current_elem_qp_functor_sln.size(),
    1040             :               "The requested " << qp << " is outside our solution size");
    1041     2023396 :   return _current_elem_qp_functor_sln[qp];
    1042             : }
    1043             : 
    1044             : template <typename OutputType>
    1045             : typename MooseVariableFE<OutputType>::ValueType
    1046       21548 : MooseVariableFE<OutputType>::evaluate(const ElemArg & elem_arg, const StateArg & state) const
    1047             : {
    1048       21548 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1049             :   // We can use whatever we want for the point argument since it won't be used
    1050       21548 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1051       21548 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1052       43096 :   return _current_elem_qp_functor_sln[0];
    1053       21548 : }
    1054             : 
    1055             : template <typename OutputType>
    1056             : typename MooseVariableFE<OutputType>::ValueType
    1057        2664 : MooseVariableFE<OutputType>::faceEvaluate(const FaceArg & face_arg,
    1058             :                                           const StateArg & state,
    1059             :                                           const std::vector<ValueType> & cache_data) const
    1060             : {
    1061        2664 :   const QMonomial qrule(face_arg.fi->elem().dim() - 1, CONSTANT);
    1062        2664 :   auto side_evaluate =
    1063        2664 :       [this, &qrule, &state, &cache_data](const Elem * const elem, const unsigned int side)
    1064             :   {
    1065             :     // We can use whatever we want for the point argument since it won't be used
    1066        2664 :     const ElemSideQpArg elem_side_qp_arg{elem, side, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1067        2664 :     evaluateOnElementSide(elem_side_qp_arg, state, /*cache_eligible=*/false);
    1068        5328 :     return cache_data[0];
    1069             :   };
    1070             : 
    1071        2664 :   const auto continuity = this->getContinuity();
    1072             :   bool on_elem;
    1073             :   bool on_neighbor;
    1074        2664 :   if (!face_arg.face_side)
    1075             :   {
    1076        2364 :     on_elem = this->hasBlocks(face_arg.fi->elemPtr()->subdomain_id());
    1077        2364 :     on_neighbor =
    1078        2364 :         face_arg.fi->neighborPtr() && this->hasBlocks(face_arg.fi->neighborPtr()->subdomain_id());
    1079             :   }
    1080             :   else
    1081             :   {
    1082         300 :     on_elem = face_arg.face_side == face_arg.fi->elemPtr();
    1083         300 :     on_neighbor = face_arg.face_side == face_arg.fi->neighborPtr();
    1084             :   }
    1085             : 
    1086             :   // Only do multiple evaluations if we are not continuous and we are on an internal face
    1087        2664 :   if ((continuity != C_ZERO && continuity != C_ONE) && on_elem && on_neighbor)
    1088           0 :     return (side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID()) +
    1089           0 :             side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID())) /
    1090           0 :            2;
    1091        2664 :   else if (on_elem)
    1092        2664 :     return side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID());
    1093           0 :   else if (on_neighbor)
    1094           0 :     return side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID());
    1095             :   else
    1096           0 :     mooseError(
    1097             :         "Attempted to evaluate a moose finite element variable on a face where it is not defined");
    1098        2664 : }
    1099             : 
    1100             : template <typename OutputType>
    1101             : typename MooseVariableFE<OutputType>::ValueType
    1102        2664 : MooseVariableFE<OutputType>::evaluate(const FaceArg & face_arg, const StateArg & state) const
    1103             : {
    1104        2664 :   return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_sln);
    1105             : }
    1106             : 
    1107             : template <typename OutputType>
    1108             : typename MooseVariableFE<OutputType>::ValueType
    1109        3532 : MooseVariableFE<OutputType>::evaluate(const ElemPointArg & elem_point_arg,
    1110             :                                       const StateArg & state) const
    1111             : {
    1112             :   mooseAssert(elem_point_arg.elem, "We need an Elem");
    1113        3532 :   const Elem & elem = *elem_point_arg.elem;
    1114        3532 :   const auto dim = elem.dim();
    1115        3532 :   ArbitraryQuadrature qrule(dim);
    1116        7064 :   const std::vector<Point> ref_point = {FEMap::inverse_map(dim, &elem, elem_point_arg.point)};
    1117        3532 :   qrule.setPoints(ref_point);
    1118             :   // We can use whatever we want for the point argument since it won't be used
    1119        3532 :   const ElemQpArg elem_qp_arg{elem_point_arg.elem, /*qp=*/0, &qrule, elem_point_arg.point};
    1120        3532 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1121        7064 :   return _current_elem_qp_functor_sln[0];
    1122        3532 : }
    1123             : 
    1124             : template <typename OutputType>
    1125             : typename MooseVariableFE<OutputType>::GradientType
    1126    11408032 : MooseVariableFE<OutputType>::evaluateGradient(const ElemQpArg & elem_qp,
    1127             :                                               const StateArg & state) const
    1128             : {
    1129    11408032 :   evaluateOnElement(elem_qp, state, /*query_cache=*/true);
    1130    11408032 :   const auto qp = elem_qp.qp;
    1131             :   mooseAssert(qp < _current_elem_qp_functor_gradient.size(),
    1132             :               "The requested " << qp << " is outside our gradient size");
    1133    11408032 :   return _current_elem_qp_functor_gradient[qp];
    1134             : }
    1135             : 
    1136             : template <typename OutputType>
    1137             : typename MooseVariableFE<OutputType>::GradientType
    1138        1080 : MooseVariableFE<OutputType>::evaluateGradient(const ElemArg & elem_arg,
    1139             :                                               const StateArg & state) const
    1140             : {
    1141        1080 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1142             :   // We can use whatever we want for the point argument since it won't be used
    1143        1080 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1144        1080 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1145        2160 :   return _current_elem_qp_functor_gradient[0];
    1146        1080 : }
    1147             : 
    1148             : template <typename OutputType>
    1149             : typename MooseVariableFE<OutputType>::DotType
    1150      837608 : MooseVariableFE<OutputType>::evaluateDot(const ElemQpArg & elem_qp, const StateArg & state) const
    1151             : {
    1152             :   mooseAssert(_time_integrator,
    1153             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1154             :               "have no idea how to compute it");
    1155             :   mooseAssert(_time_integrator->dt(),
    1156             :               "A time derivative is being requested but the time integrator wants to perform a 0s "
    1157             :               "time step");
    1158      837608 :   evaluateOnElement(elem_qp, state, /*query_cache=*/true);
    1159      837608 :   const auto qp = elem_qp.qp;
    1160             :   mooseAssert(qp < _current_elem_qp_functor_dot.size(),
    1161             :               "The requested " << qp << " is outside our dot size");
    1162      837608 :   return _current_elem_qp_functor_dot[qp];
    1163             : }
    1164             : 
    1165             : template <typename OutputType>
    1166             : typename MooseVariableFE<OutputType>::DotType
    1167        1624 : MooseVariableFE<OutputType>::evaluateDot(const ElemArg & elem_arg, const StateArg & state) const
    1168             : {
    1169             :   mooseAssert(_time_integrator,
    1170             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1171             :               "have no idea how to compute it");
    1172             :   mooseAssert(_time_integrator->dt(),
    1173             :               "A time derivative is being requested but the time integrator wants to perform a 0s "
    1174             :               "time step");
    1175        1624 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1176             :   // We can use whatever we want for the point argument since it won't be used
    1177        1624 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1178        1624 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1179        3248 :   return _current_elem_qp_functor_dot[0];
    1180        1624 : }
    1181             : 
    1182             : template <typename OutputType>
    1183             : typename MooseVariableFE<OutputType>::GradientType
    1184        1080 : MooseVariableFE<OutputType>::evaluateGradDot(const ElemArg & elem_arg, const StateArg & state) const
    1185             : {
    1186             :   mooseAssert(_time_integrator,
    1187             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1188             :               "have no idea how to compute it");
    1189             :   mooseAssert(_time_integrator->dt(),
    1190             :               "A time derivative is being requested but the time integrator wants to perform a 0s "
    1191             :               "time step");
    1192        1080 :   const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
    1193             :   // We can use whatever we want for the point argument since it won't be used
    1194        1080 :   const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
    1195        1080 :   evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
    1196        2160 :   return _current_elem_qp_functor_grad_dot[0];
    1197        1080 : }
    1198             : 
    1199             : template <typename OutputType>
    1200             : void
    1201      100340 : MooseVariableFE<OutputType>::evaluateOnElementSide(const ElemSideQpArg & elem_side_qp,
    1202             :                                                    const StateArg & state,
    1203             :                                                    const bool cache_eligible) const
    1204             : {
    1205             :   mooseAssert(this->hasBlocks(elem_side_qp.elem->subdomain_id()),
    1206             :               "Variable " + this->name() + " doesn't exist on block " +
    1207             :                   std::to_string(elem_side_qp.elem->subdomain_id()));
    1208             : 
    1209      100340 :   const Elem * const elem = elem_side_qp.elem;
    1210      100340 :   const auto side = elem_side_qp.side;
    1211      100340 :   if (!cache_eligible || elem != _current_elem_side_qp_functor_elem_side.first ||
    1212       84078 :       side != _current_elem_side_qp_functor_elem_side.second)
    1213             :   {
    1214       16598 :     const QBase * const qrule_template = elem_side_qp.qrule;
    1215             : 
    1216             :     using FEBaseType = typename FEBaseHelper<OutputType>::type;
    1217       16598 :     std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
    1218       16598 :     auto qrule = qrule_template->clone();
    1219             : 
    1220       16598 :     const auto & phi = fe->get_phi();
    1221       16598 :     const auto & dphi = fe->get_dphi();
    1222       16598 :     fe->attach_quadrature_rule(qrule.get());
    1223       16598 :     fe->reinit(elem, side);
    1224             : 
    1225       16598 :     computeSolution(elem,
    1226             :                     qrule->n_points(),
    1227             :                     state,
    1228             :                     phi,
    1229       16598 :                     _current_elem_side_qp_functor_sln,
    1230             :                     dphi,
    1231       16598 :                     _current_elem_side_qp_functor_gradient,
    1232       16598 :                     _current_elem_side_qp_functor_dot,
    1233       16598 :                     _current_elem_side_qp_functor_grad_dot);
    1234       16598 :   }
    1235      100340 :   if (cache_eligible)
    1236       97676 :     _current_elem_side_qp_functor_elem_side = std::make_pair(elem, side);
    1237             :   else
    1238             :     // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
    1239             :     // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
    1240             :     // re-used when this function is called with a standard quadrature rule or a different point
    1241        2664 :     _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1242      100340 : }
    1243             : 
    1244             : template <>
    1245             : void
    1246           0 : MooseVariableFE<RealEigenVector>::evaluateOnElementSide(const ElemSideQpArg &,
    1247             :                                                         const StateArg &,
    1248             :                                                         bool) const
    1249             : {
    1250           0 :   mooseError("evaluate not implemented for array variables");
    1251             : }
    1252             : 
    1253             : template <typename OutputType>
    1254             : typename MooseVariableFE<OutputType>::ValueType
    1255       97676 : MooseVariableFE<OutputType>::evaluate(const ElemSideQpArg & elem_side_qp,
    1256             :                                       const StateArg & state) const
    1257             : {
    1258       97676 :   evaluateOnElementSide(elem_side_qp, state, true);
    1259       97676 :   const auto qp = elem_side_qp.qp;
    1260             :   mooseAssert(qp < _current_elem_side_qp_functor_sln.size(),
    1261             :               "The requested " << qp << " is outside our solution size");
    1262       97676 :   return _current_elem_side_qp_functor_sln[qp];
    1263             : }
    1264             : 
    1265             : template <typename OutputType>
    1266             : typename MooseVariableFE<OutputType>::GradientType
    1267           0 : MooseVariableFE<OutputType>::evaluateGradient(const ElemSideQpArg & elem_side_qp,
    1268             :                                               const StateArg & state) const
    1269             : {
    1270           0 :   evaluateOnElementSide(elem_side_qp, state, true);
    1271           0 :   const auto qp = elem_side_qp.qp;
    1272             :   mooseAssert(qp < _current_elem_side_qp_functor_gradient.size(),
    1273             :               "The requested " << qp << " is outside our gradient size");
    1274           0 :   return _current_elem_side_qp_functor_gradient[qp];
    1275             : }
    1276             : 
    1277             : template <typename OutputType>
    1278             : typename MooseVariableFE<OutputType>::DotType
    1279           0 : MooseVariableFE<OutputType>::evaluateDot(const ElemSideQpArg & elem_side_qp,
    1280             :                                          const StateArg & state) const
    1281             : {
    1282             :   mooseAssert(_time_integrator && _time_integrator->dt(),
    1283             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1284             :               "have no idea how to compute it");
    1285           0 :   evaluateOnElementSide(elem_side_qp, state, true);
    1286           0 :   const auto qp = elem_side_qp.qp;
    1287             :   mooseAssert(qp < _current_elem_side_qp_functor_dot.size(),
    1288             :               "The requested " << qp << " is outside our dot size");
    1289           0 :   return _current_elem_side_qp_functor_dot[qp];
    1290             : }
    1291             : 
    1292             : template <typename OutputType>
    1293             : typename MooseVariableFE<OutputType>::DotType
    1294           0 : MooseVariableFE<OutputType>::evaluateDot(const FaceArg & face_arg, const StateArg & state) const
    1295             : {
    1296             :   mooseAssert(_time_integrator && _time_integrator->dt(),
    1297             :               "A time derivative is being requested but we do not have a time integrator so we'll "
    1298             :               "have no idea how to compute it");
    1299           0 :   return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_dot);
    1300             : }
    1301             : 
    1302             : template <>
    1303             : typename MooseVariableFE<RealEigenVector>::ValueType
    1304           0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemQpArg &, const StateArg &) const
    1305             : {
    1306           0 :   mooseError(
    1307             :       "MooseVariableFE::evaluate(ElemQpArg &, const StateArg &) overload not implemented for "
    1308             :       "array variables");
    1309             : }
    1310             : 
    1311             : template <>
    1312             : typename MooseVariableFE<RealEigenVector>::ValueType
    1313           0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemSideQpArg &, const StateArg &) const
    1314             : {
    1315           0 :   mooseError("MooseVariableFE::evaluate(ElemSideQpArg &, const StateArg &) overload not "
    1316             :              "implemented for array variables");
    1317             : }
    1318             : 
    1319             : template <>
    1320             : typename MooseVariableFE<RealEigenVector>::GradientType
    1321           0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemQpArg &, const StateArg &) const
    1322             : {
    1323           0 :   mooseError("MooseVariableFE::evaluateGradient(ElemQpArg &, const StateArg &) overload not "
    1324             :              "implemented for array variables");
    1325             : }
    1326             : 
    1327             : template <>
    1328             : typename MooseVariableFE<RealEigenVector>::GradientType
    1329           0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemSideQpArg &, const StateArg &) const
    1330             : {
    1331           0 :   mooseError("MooseVariableFE::evaluateGradient(ElemSideQpArg &, const StateArg &) overload not "
    1332             :              "implemented for array variables");
    1333             : }
    1334             : 
    1335             : template <>
    1336             : typename MooseVariableFE<RealEigenVector>::DotType
    1337           0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemQpArg &, const StateArg &) const
    1338             : {
    1339           0 :   mooseError("MooseVariableFE::evaluateDot(ElemQpArg &, const StateArg &) overload not "
    1340             :              "implemented for array variables");
    1341             : }
    1342             : 
    1343             : template <>
    1344             : typename MooseVariableFE<RealEigenVector>::DotType
    1345           0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemSideQpArg &, const StateArg &) const
    1346             : {
    1347           0 :   mooseError("MooseVariableFE::evaluateDot(ElemSideQpArg &, const StateArg &) overload not "
    1348             :              "implemented for array variables");
    1349             : }
    1350             : 
    1351             : template <typename OutputType>
    1352             : void
    1353       23988 : MooseVariableFE<OutputType>::meshChanged()
    1354             : {
    1355       23988 :   _current_elem_qp_functor_elem = nullptr;
    1356       23988 :   _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1357       23988 :   MooseVariableField<OutputType>::meshChanged();
    1358       23988 : }
    1359             : 
    1360             : template <typename OutputType>
    1361             : void
    1362     7433477 : MooseVariableFE<OutputType>::residualSetup()
    1363             : {
    1364     7433477 :   _current_elem_qp_functor_elem = nullptr;
    1365     7433477 :   _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1366     7433477 :   MooseVariableField<OutputType>::residualSetup();
    1367     7433477 : }
    1368             : 
    1369             : template <typename OutputType>
    1370             : void
    1371     1232525 : MooseVariableFE<OutputType>::jacobianSetup()
    1372             : {
    1373     1232525 :   _current_elem_qp_functor_elem = nullptr;
    1374     1232525 :   _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
    1375     1232525 :   MooseVariableField<OutputType>::jacobianSetup();
    1376     1232525 : }
    1377             : 
    1378             : template <typename OutputType>
    1379             : void
    1380      124792 : MooseVariableFE<OutputType>::sizeMatrixTagData()
    1381             : {
    1382      124792 :   _element_data->sizeMatrixTagData();
    1383      124792 :   _neighbor_data->sizeMatrixTagData();
    1384      124792 :   _lower_data->sizeMatrixTagData();
    1385      124792 : }
    1386             : 
    1387             : template class MooseVariableFE<Real>;
    1388             : template class MooseVariableFE<RealVectorValue>;
    1389             : template class MooseVariableFE<RealEigenVector>;

Generated by: LCOV version 1.14