LCOV - code coverage report
Current view: top level - src/variables - MooseVariableDataBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 339 421 80.5 %
Date: 2025-07-17 01:28:37 Functions: 82 106 77.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 "MooseVariableDataBase.h"
      11             : #include "MooseError.h"
      12             : #include "MooseTypes.h"
      13             : #include "SystemBase.h"
      14             : #include "SubProblem.h"
      15             : #include "MooseVariableField.h"
      16             : 
      17             : template <typename OutputType>
      18      510907 : MooseVariableDataBase<OutputType>::MooseVariableDataBase(const MooseVariableField<OutputType> & var,
      19             :                                                          SystemBase & sys,
      20             :                                                          THREAD_ID tid)
      21      510907 :   : _sys(sys),
      22     1021814 :     _subproblem(_sys.subproblem()),
      23      510907 :     _tid(tid),
      24      510907 :     _dof_map(_sys.dofMap()),
      25      510907 :     _count(var.count()),
      26      510907 :     _has_dof_values(false),
      27      510907 :     _max_state(0),
      28      510907 :     _solution_tag(_subproblem.getVectorTagID(Moose::SOLUTION_TAG)),
      29      510907 :     _old_solution_tag(Moose::INVALID_TAG_ID),
      30      510907 :     _older_solution_tag(Moose::INVALID_TAG_ID),
      31      510907 :     _previous_nl_solution_tag(Moose::INVALID_TAG_ID),
      32      510907 :     _need_u_dot(false),
      33      510907 :     _need_u_dotdot(false),
      34      510907 :     _need_u_dot_old(false),
      35      510907 :     _need_u_dotdot_old(false),
      36      510907 :     _need_du_dot_du(false),
      37      510907 :     _need_du_dotdot_du(false),
      38      510907 :     _need_grad_dot(false),
      39      510907 :     _need_grad_dotdot(false),
      40      510907 :     _need_dof_values_dot(false),
      41      510907 :     _need_dof_values_dotdot(false),
      42      510907 :     _need_dof_values_dot_old(false),
      43      510907 :     _need_dof_values_dotdot_old(false),
      44      510907 :     _need_dof_du_dot_du(false),
      45      510907 :     _need_dof_du_dotdot_du(false),
      46     1021814 :     _var(var)
      47             : {
      48      510907 :   auto num_vector_tags = _subproblem.numVectorTags();
      49             :   // Additional solution tags corresponding to older-than-current solution states may be requested
      50             :   // on-the-fly by consumer objects after variable construction. To accomodate this we should
      51             :   // reserve the possibly requisite memory. As of now we only support old and older solution states
      52             :   // but this could potentially increase in the future
      53      510907 :   const auto max_future_num_vector_tags = num_vector_tags + 2;
      54             : 
      55      510907 :   _vector_tags_dof_u.reserve(max_future_num_vector_tags);
      56      510907 :   _vector_tags_dof_u.resize(num_vector_tags);
      57      510907 :   _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
      58      510907 :   _need_vector_tag_dof_u.resize(num_vector_tags, false);
      59             : 
      60      510907 :   _need_vector_tag_u.reserve(max_future_num_vector_tags);
      61      510907 :   _need_vector_tag_u.resize(num_vector_tags, false);
      62      510907 :   _vector_tag_u.reserve(max_future_num_vector_tags);
      63      510907 :   _vector_tag_u.resize(num_vector_tags);
      64             : 
      65      510907 :   _need_vector_tag_grad.reserve(max_future_num_vector_tags);
      66      510907 :   _need_vector_tag_grad.resize(num_vector_tags, false);
      67      510907 :   _vector_tag_grad.reserve(max_future_num_vector_tags);
      68      510907 :   _vector_tag_grad.resize(num_vector_tags);
      69             : 
      70      510907 :   auto num_matrix_tags = _subproblem.numMatrixTags();
      71             : 
      72      510907 :   _matrix_tags_dof_u.resize(num_matrix_tags);
      73      510907 :   _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
      74             : 
      75      510907 :   _need_matrix_tag_u.resize(num_matrix_tags, false);
      76      510907 :   _matrix_tag_u.resize(num_matrix_tags);
      77             : 
      78             :   // Always fetch the dof values for the solution tag
      79      510907 :   const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
      80      510907 :   _need_vector_tag_dof_u[soln_tag] = true;
      81      510907 :   _need_vector_tag_u[soln_tag] = true;
      82      510907 :   insertSolutionTag(soln_tag);
      83             : 
      84             :   // These MooseArray objects are used by AuxKernelBase for nodal AuxKernel objects, hence the size
      85             :   // size is always 1 (i.e, nodal kernels work with _qp=0 only).
      86      510907 :   _nodal_value_array.resize(1);
      87      510907 :   _nodal_value_old_array.resize(1);
      88      510907 :   _nodal_value_older_array.resize(1);
      89      510907 : }
      90             : 
      91             : template <typename OutputType>
      92             : const typename MooseVariableDataBase<OutputType>::DoFValue &
      93         363 : MooseVariableDataBase<OutputType>::nodalVectorTagValue(TagID tag) const
      94             : {
      95         363 :   if (isNodal())
      96             :   {
      97         363 :     if (tag >= _need_vector_tag_dof_u.size())
      98           0 :       const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
      99             : 
     100         363 :     _need_vector_tag_dof_u[tag] = true;
     101             : 
     102         363 :     if (_sys.hasVector(tag))
     103         363 :       return _vector_tags_dof_u[tag];
     104             :     else
     105           0 :       mooseError(
     106           0 :           "Tag ", tag, " is not associated with any vector for nodal variable ", _var.name());
     107             :   }
     108             :   else
     109           0 :     mooseError("Nodal values can be requested only on nodal variables, variable '",
     110           0 :                _var.name(),
     111             :                "' is not nodal.");
     112             : }
     113             : 
     114             : template <typename OutputType>
     115             : const typename MooseVariableDataBase<OutputType>::DoFValue &
     116         130 : MooseVariableDataBase<OutputType>::nodalMatrixTagValue(TagID tag) const
     117             : {
     118         130 :   if (isNodal())
     119             :   {
     120         130 :     if (tag >= _matrix_tags_dof_u.size())
     121             :     {
     122           0 :       _need_matrix_tag_dof_u.resize(tag + 1, false);
     123           0 :       const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tags_dof_u.resize(tag + 1);
     124             :     }
     125             : 
     126         130 :     _need_matrix_tag_dof_u[tag] = true;
     127             : 
     128         130 :     if (_sys.hasMatrix(tag))
     129         130 :       return _matrix_tags_dof_u[tag];
     130             :     else
     131           0 :       mooseError(
     132           0 :           "Tag ", tag, " is not associated with any matrix for nodal variable ", _var.name());
     133             :   }
     134             :   else
     135           0 :     mooseError("Nodal values can be requested only on nodal variables, variable '",
     136           0 :                _var.name(),
     137             :                "' is not nodal.");
     138             : }
     139             : 
     140             : template <typename OutputType>
     141             : void
     142         494 : MooseVariableDataBase<OutputType>::resizeVectorTagData(TagID tag)
     143             : {
     144             :   mooseAssert(_need_vector_tag_dof_u.size() == _need_vector_tag_u.size() &&
     145             :                   _need_vector_tag_dof_u.size() == _need_vector_tag_grad.size() &&
     146             :                   _need_vector_tag_dof_u.size() == _vector_tags_dof_u.size() &&
     147             :                   _need_vector_tag_dof_u.size() == _vector_tag_u.size() &&
     148             :                   _need_vector_tag_dof_u.size() == _vector_tag_grad.size(),
     149             :               "These sizes should be in sync.");
     150             : 
     151        6422 :   auto check_capacity = [tag](const auto & vector_to_check)
     152             :   {
     153        2964 :     if (tag + 1 > vector_to_check.capacity())
     154           0 :       mooseError("New size greater than tag capacity. This will cause reallocation which will "
     155             :                  "invalidate any stored references.");
     156             :   };
     157         494 :   check_capacity(_need_vector_tag_dof_u);
     158         494 :   check_capacity(_need_vector_tag_u);
     159         494 :   check_capacity(_need_vector_tag_grad);
     160         494 :   check_capacity(_vector_tags_dof_u);
     161         494 :   check_capacity(_vector_tag_u);
     162         494 :   check_capacity(_vector_tag_grad);
     163             : 
     164         494 :   _need_vector_tag_dof_u.resize(tag + 1, false);
     165         494 :   _need_vector_tag_u.resize(tag + 1, false);
     166         494 :   _need_vector_tag_grad.resize(tag + 1, false);
     167         494 :   _vector_tags_dof_u.resize(tag + 1);
     168         494 :   _vector_tag_u.resize(tag + 1);
     169         494 :   _vector_tag_grad.resize(tag + 1);
     170         494 : }
     171             : 
     172             : template <typename OutputType>
     173             : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
     174      330753 : MooseVariableDataBase<OutputType>::vectorTagValue(TagID tag) const
     175             : {
     176      330753 :   if (tag >= _need_vector_tag_u.size())
     177         117 :     const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
     178             : 
     179      330753 :   _need_vector_tag_u[tag] = true;
     180             : 
     181      330753 :   if (_sys.hasVector(tag))
     182      330753 :     return _vector_tag_u[tag];
     183             :   else
     184           0 :     mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
     185             : }
     186             : 
     187             : template <typename OutputType>
     188             : const typename MooseVariableDataBase<OutputType>::DoFValue &
     189      947831 : MooseVariableDataBase<OutputType>::vectorTagDofValue(TagID tag) const
     190             : {
     191      947831 :   if (tag >= _need_vector_tag_dof_u.size())
     192         143 :     const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
     193             : 
     194      947831 :   _need_vector_tag_dof_u[tag] = true;
     195             : 
     196      947831 :   if (_sys.hasVector(tag))
     197      947831 :     return _vector_tags_dof_u[tag];
     198             :   else
     199           0 :     mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
     200             : }
     201             : 
     202             : template <typename OutputType>
     203             : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
     204      127188 : MooseVariableDataBase<OutputType>::vectorTagGradient(TagID tag) const
     205             : {
     206      127188 :   if (tag >= _need_vector_tag_grad.size())
     207          13 :     const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
     208             : 
     209      127188 :   _need_vector_tag_grad[tag] = true;
     210             : 
     211      127188 :   if (_sys.hasVector(tag))
     212      127188 :     return _vector_tag_grad[tag];
     213             :   else
     214           0 :     mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
     215             : }
     216             : 
     217             : template <typename OutputType>
     218             : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
     219          50 : MooseVariableDataBase<OutputType>::matrixTagValue(TagID tag) const
     220             : {
     221          50 :   if (tag >= _matrix_tag_u.size())
     222             :   {
     223           0 :     _need_matrix_tag_u.resize(tag + 1, false);
     224           0 :     const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tag_u.resize(tag + 1);
     225             :   }
     226             : 
     227          50 :   _need_matrix_tag_u[tag] = true;
     228             : 
     229          50 :   if (_sys.hasMatrix(tag))
     230          50 :     return _matrix_tag_u[tag];
     231             :   else
     232           0 :     mooseError("Tag ", tag, " is not associated with any matrix for variable ", _var.name());
     233             : }
     234             : 
     235             : template <typename OutputType>
     236             : unsigned int
     237   488440160 : MooseVariableDataBase<OutputType>::oldestSolutionStateRequested() const
     238             : {
     239   488440160 :   return _max_state;
     240             : }
     241             : 
     242             : template <typename OutputType>
     243             : void
     244       36003 : MooseVariableDataBase<OutputType>::needSolutionState(const unsigned int state)
     245             : {
     246       36003 :   if (state > _max_state)
     247             :   {
     248       15772 :     _sys.needSolutionState(state);
     249       15772 :     _max_state = state;
     250             :   }
     251       36003 : }
     252             : 
     253             : template <typename OutputType>
     254             : template <typename ReturnType, typename Functor>
     255             : const ReturnType &
     256     1404878 : MooseVariableDataBase<OutputType>::stateToTagHelper(const Moose::SolutionState state,
     257             :                                                     Functor functor)
     258             : {
     259     1404878 :   if (state > 0)
     260             :   {
     261             :     // We need to request all states that are between current and the requested state
     262       36003 :     stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
     263       36003 :     needSolutionState(cast_int<unsigned int>(state));
     264             :   }
     265             : 
     266     1404878 :   switch (state)
     267             :   {
     268     1368797 :     case Moose::Current:
     269     1368797 :       return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
     270             : 
     271       24849 :     case Moose::Old:
     272             :     {
     273       24849 :       _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
     274       24849 :       insertSolutionTag(_old_solution_tag);
     275       24849 :       return functor(_old_solution_tag);
     276             :     }
     277             : 
     278       11154 :     case Moose::Older:
     279             :     {
     280       11154 :       _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
     281       11154 :       insertSolutionTag(_older_solution_tag);
     282       11154 :       return functor(_older_solution_tag);
     283             :     }
     284             : 
     285          78 :     case Moose::PreviousNL:
     286             :     {
     287          78 :       _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
     288          78 :       insertSolutionTag(_previous_nl_solution_tag);
     289          78 :       return functor(_previous_nl_solution_tag);
     290             :     }
     291             : 
     292           0 :     default:
     293             :       // We should never get here but gcc requires that we have a default. See
     294             :       // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
     295           0 :       mooseError("Unknown SolutionState!");
     296             :   }
     297             : }
     298             : 
     299             : template <typename OutputType>
     300             : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
     301      295340 : MooseVariableDataBase<OutputType>::sln(Moose::SolutionState state) const
     302             : {
     303      625362 :   auto functor = [this](TagID tag_id) -> const FieldVariableValue &
     304      330022 :   { return vectorTagValue(tag_id); };
     305             : 
     306             :   return const_cast<MooseVariableDataBase<OutputType> *>(this)
     307      590680 :       ->stateToTagHelper<FieldVariableValue>(state, functor);
     308             : }
     309             : 
     310             : template <typename OutputType>
     311             : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
     312      126190 : MooseVariableDataBase<OutputType>::gradSln(Moose::SolutionState state) const
     313             : {
     314      253352 :   auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
     315      127162 :   { return vectorTagGradient(tag_id); };
     316             : 
     317             :   return const_cast<MooseVariableDataBase<OutputType> *>(this)
     318      252380 :       ->stateToTagHelper<FieldVariableGradient>(state, functor);
     319             : }
     320             : 
     321             : template <typename OutputType>
     322             : const typename MooseVariableDataBase<OutputType>::DoFValue &
     323      947345 : MooseVariableDataBase<OutputType>::vectorTagDofValue(Moose::SolutionState state) const
     324             : {
     325     1895039 :   auto functor = [this](TagID tag_id) -> const DoFValue & { return vectorTagDofValue(tag_id); };
     326             : 
     327      947345 :   return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DoFValue>(state,
     328     1894690 :                                                                                            functor);
     329             : }
     330             : 
     331             : template <typename OutputType>
     332             : const typename MooseVariableDataBase<OutputType>::DoFValue &
     333      923730 : MooseVariableDataBase<OutputType>::dofValues() const
     334             : {
     335      923730 :   return vectorTagDofValue(Moose::Current);
     336             : }
     337             : 
     338             : template <typename OutputType>
     339             : const typename MooseVariableDataBase<OutputType>::DoFValue &
     340         115 : MooseVariableDataBase<OutputType>::dofValuesOld() const
     341             : {
     342         115 :   return vectorTagDofValue(Moose::Old);
     343             : }
     344             : 
     345             : template <typename OutputType>
     346             : const typename MooseVariableDataBase<OutputType>::DoFValue &
     347          39 : MooseVariableDataBase<OutputType>::dofValuesOlder() const
     348             : {
     349          39 :   return vectorTagDofValue(Moose::Older);
     350             : }
     351             : 
     352             : template <typename OutputType>
     353             : const typename MooseVariableDataBase<OutputType>::DoFValue &
     354           0 : MooseVariableDataBase<OutputType>::dofValuesPreviousNL() const
     355             : {
     356           0 :   return vectorTagDofValue(Moose::PreviousNL);
     357             : }
     358             : 
     359             : template <typename OutputType>
     360             : void
     361    45400478 : MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
     362             : {
     363    45400478 :   auto & dof_values = _vector_tags_dof_u[_solution_tag];
     364             :   mooseAssert(idx < dof_values.size(), "idx is out of the bounds of degree of freedom values");
     365    45400478 :   dof_values[idx] = value; // update variable nodal value
     366    45400478 :   _has_dof_values = true;
     367    45400478 :   _nodal_value = value;
     368             : 
     369             :   // Update the qp values as well
     370    45400478 :   auto & u = _vector_tag_u[_solution_tag];
     371   224711450 :   for (unsigned int qp = 0; qp < u.size(); qp++)
     372   179310972 :     u[qp] = value;
     373    45400478 : }
     374             : 
     375             : template <>
     376             : void
     377        8110 : MooseVariableDataBase<RealVectorValue>::setNodalValue(const RealVectorValue & value,
     378             :                                                       unsigned int idx)
     379             : {
     380        8110 :   auto & dof_values = _vector_tags_dof_u[_solution_tag];
     381       27780 :   for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
     382       19670 :     dof_values[idx] = value(i);
     383             : 
     384        8110 :   _has_dof_values = true;
     385        8110 :   _nodal_value = value;
     386        8110 : }
     387             : 
     388             : template <typename OutputType>
     389             : void
     390    49040191 : MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
     391             : {
     392    49040191 :   if (_has_dof_values)
     393             :   {
     394    47880887 :     auto & dof_values = _vector_tags_dof_u[_solution_tag];
     395             :     mooseAssert(dof_values.size() == _dof_indices.size(),
     396             :                 "Degree of freedom values size and degree of freedom indices sizes must match.");
     397    47880887 :     residual.insert(&dof_values[0], _dof_indices);
     398             :   }
     399    49040191 : }
     400             : 
     401             : template <>
     402             : void
     403      624826 : MooseVariableDataBase<RealEigenVector>::insert(NumericVector<Number> & residual)
     404             : {
     405      624826 :   if (_has_dof_values)
     406             :   {
     407      624826 :     auto & dof_values = _vector_tags_dof_u[_solution_tag];
     408      624826 :     if (isNodal())
     409             :     {
     410     1286854 :       for (unsigned int i = 0; i < _dof_indices.size(); ++i)
     411     2104604 :         for (unsigned int j = 0; j < _count; ++j)
     412     1409992 :           residual.set(_dof_indices[i] + j, dof_values[i](j));
     413             :     }
     414             :     else
     415             :     {
     416       32584 :       unsigned int n = 0;
     417      103544 :       for (unsigned int j = 0; j < _count; ++j)
     418             :       {
     419      485264 :         for (unsigned int i = 0; i < _dof_indices.size(); ++i)
     420      414304 :           residual.set(_dof_indices[i] + n, dof_values[i](j));
     421       70960 :         n += _dof_indices.size();
     422             :       }
     423             :     }
     424             :   }
     425      624826 : }
     426             : 
     427             : template <typename OutputType>
     428             : void
     429     2043437 : MooseVariableDataBase<OutputType>::add(NumericVector<Number> & residual)
     430             : {
     431     2043437 :   if (_has_dof_values)
     432             :   {
     433       36956 :     auto & dof_values = _vector_tags_dof_u[_solution_tag];
     434       36956 :     residual.add_vector(&dof_values[0], _dof_indices);
     435             :   }
     436     2043437 : }
     437             : 
     438             : template <>
     439             : void
     440           0 : MooseVariableDataBase<RealEigenVector>::add(NumericVector<Number> & residual)
     441             : {
     442           0 :   if (_has_dof_values)
     443             :   {
     444           0 :     auto & dof_values = _vector_tags_dof_u[_solution_tag];
     445           0 :     if (isNodal())
     446             :     {
     447           0 :       for (unsigned int i = 0; i < _dof_indices.size(); ++i)
     448           0 :         for (unsigned int j = 0; j < _count; ++j)
     449           0 :           residual.add(_dof_indices[i] + j, dof_values[i](j));
     450             :     }
     451             :     else
     452             :     {
     453           0 :       unsigned int n = 0;
     454           0 :       for (unsigned int j = 0; j < _count; ++j)
     455             :       {
     456           0 :         for (unsigned int i = 0; i < _dof_indices.size(); ++i)
     457           0 :           residual.add(_dof_indices[i] + n, dof_values[i](j));
     458           0 :         n += _dof_indices.size();
     459             :       }
     460             :     }
     461             :   }
     462           0 : }
     463             : 
     464             : template <typename OutputType>
     465             : const OutputType &
     466        1233 : MooseVariableDataBase<OutputType>::nodalValue(Moose::SolutionState state) const
     467             : {
     468        1233 :   if (isNodal())
     469             :   {
     470             :     // Request the correct solution states and data members
     471        1233 :     vectorTagDofValue(state);
     472        1233 :     switch (state)
     473             :     {
     474        1233 :       case Moose::Current:
     475        1233 :         return _nodal_value;
     476             : 
     477           0 :       case Moose::Old:
     478           0 :         return _nodal_value_old;
     479             : 
     480           0 :       case Moose::Older:
     481           0 :         return _nodal_value_older;
     482             : 
     483           0 :       case Moose::PreviousNL:
     484           0 :         return _nodal_value_previous_nl;
     485             : 
     486           0 :       default:
     487             :         // We should never get here but gcc requires that we have a default. See
     488             :         // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
     489           0 :         mooseError("Unknown SolutionState!");
     490             :     }
     491             :   }
     492             :   else
     493           0 :     mooseError("Nodal values can be requested only on nodal variables, variable '",
     494           0 :                _var.name(),
     495             :                "' is not nodal.");
     496             : }
     497             : 
     498             : template <typename OutputType>
     499             : const MooseArray<OutputType> &
     500       22228 : MooseVariableDataBase<OutputType>::nodalValueArray(Moose::SolutionState state) const
     501             : {
     502       22228 :   if (isNodal())
     503             :   {
     504             :     // Request the correct solution states and data members
     505       22228 :     vectorTagDofValue(state);
     506       22228 :     switch (state)
     507             :     {
     508       22085 :       case Moose::Current:
     509       22085 :         return _nodal_value_array;
     510             : 
     511         130 :       case Moose::Old:
     512         130 :         return _nodal_value_old_array;
     513             : 
     514          13 :       case Moose::Older:
     515          13 :         return _nodal_value_older_array;
     516             : 
     517           0 :       default:
     518           0 :         mooseError("No current support for PreviousNL for nodal value array");
     519             :     }
     520             :   }
     521             :   else
     522           0 :     mooseError("Nodal values can be requested only on nodal variables, variable '",
     523           0 :                _var.name(),
     524             :                "' is not nodal.");
     525             : }
     526             : 
     527             : template <typename OutputType>
     528             : void
     529  1104787514 : MooseVariableDataBase<OutputType>::fetchDoFValues()
     530             : {
     531  1104787514 :   bool is_transient = _subproblem.isTransient();
     532             : 
     533  1104787514 :   auto n = _dof_indices.size();
     534             :   libmesh_assert(n);
     535             : 
     536  1104787514 :   if (is_transient)
     537             :   {
     538   867099440 :     if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
     539             :     {
     540             :       libmesh_assert(_sys.solutionUDot());
     541   315625731 :       _dof_values_dot.resize(n);
     542   315625731 :       _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
     543             :     }
     544   867099440 :     if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
     545             :     {
     546             :       libmesh_assert(_sys.solutionUDotDot());
     547       15476 :       _dof_values_dotdot.resize(n);
     548       15476 :       _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
     549             :     }
     550   867099440 :     if (_need_u_dot_old || _need_dof_values_dot_old)
     551             :     {
     552             :       libmesh_assert(_sys.solutionUDotOld());
     553           0 :       _dof_values_dot_old.resize(n);
     554           0 :       _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
     555             :     }
     556   867099440 :     if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
     557             :     {
     558             :       libmesh_assert(_sys.solutionUDotDotOld());
     559           0 :       _dof_values_dotdot_old.resize(n);
     560           0 :       _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
     561             :     }
     562             :   }
     563             : 
     564  2224271197 :   for (auto tag : _required_vector_tags)
     565  1119483683 :     if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
     566  1119019415 :       if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
     567  2237972506 :            _subproblem.safeAccessTaggedVectors()) ||
     568  1118953091 :           _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
     569             :       {
     570             :         // tag is defined on problem but may not be used by a system
     571             :         // the grain tracker requires being able to read from solution vectors that we are also in
     572             :         // the process of writing :-/
     573  1119019415 :         if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
     574             :         {
     575  1119019415 :           auto & vec = _sys.getVector(tag);
     576  1119019415 :           _vector_tags_dof_u[tag].resize(n);
     577  1119019415 :           vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
     578             :         }
     579             :       }
     580             : 
     581  1104787514 :   if (_subproblem.safeAccessTaggedMatrices())
     582             :   {
     583             :     auto & active_coupleable_matrix_tags =
     584   879509362 :         _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
     585             : 
     586   879725354 :     for (auto tag : active_coupleable_matrix_tags)
     587             :     {
     588      215992 :       _matrix_tags_dof_u[tag].resize(n);
     589      215992 :       if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
     590       54032 :         if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
     591             :         {
     592       54032 :           auto & mat = _sys.getMatrix(tag);
     593      108320 :           for (unsigned i = 0; i < n; i++)
     594             :           {
     595       54288 :             Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     596       54288 :             _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
     597             :           }
     598             :         }
     599             :     }
     600             :   }
     601             : 
     602  1104787514 :   if (_need_du_dot_du || _need_dof_du_dot_du)
     603             :   {
     604   315619731 :     _dof_du_dot_du.resize(n);
     605  1436211072 :     for (decltype(n) i = 0; i < n; ++i)
     606  1120591341 :       _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
     607             :   }
     608  1104787514 :   if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
     609             :   {
     610       10204 :     _dof_du_dotdot_du.resize(n);
     611       57864 :     for (decltype(n) i = 0; i < n; ++i)
     612       47660 :       _dof_du_dotdot_du[i] = _sys.duDotDotDu();
     613             :   }
     614  1104787514 : }
     615             : 
     616             : template <typename OutputType>
     617             : void
     618     8429962 : MooseVariableDataBase<OutputType>::getArrayDoFValues(const NumericVector<Number> & sol,
     619             :                                                      unsigned int n,
     620             :                                                      MooseArray<RealEigenVector> & dof_values) const
     621             : {
     622     8429962 :   dof_values.resize(n);
     623     8429962 :   if (isNodal())
     624             :   {
     625    34062579 :     for (unsigned int i = 0; i < n; ++i)
     626             :     {
     627    25908456 :       dof_values[i].resize(_count);
     628    25908456 :       auto dof = _dof_indices[i];
     629    87529416 :       for (unsigned int j = 0; j < _count; ++j)
     630    61620960 :         dof_values[i](j) = sol(dof++);
     631             :     }
     632             :   }
     633             :   else
     634             :   {
     635     1585061 :     for (unsigned int i = 0; i < n; ++i)
     636             :     {
     637     1309222 :       dof_values[i].resize(_count);
     638     1309222 :       auto dof = _dof_indices[i];
     639     4450347 :       for (unsigned int j = 0; j < _count; ++j)
     640             :       {
     641     3141125 :         dof_values[i](j) = sol(dof);
     642     3141125 :         dof += n;
     643             :       }
     644             :     }
     645             :   }
     646     8429962 : }
     647             : 
     648             : template <>
     649             : void
     650     5745919 : MooseVariableDataBase<RealEigenVector>::fetchDoFValues()
     651             : {
     652     5745919 :   bool is_transient = _subproblem.isTransient();
     653             : 
     654     5745919 :   auto n = _dof_indices.size();
     655             :   libmesh_assert(n);
     656             : 
     657     5745919 :   if (is_transient)
     658             :   {
     659     5408493 :     if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
     660             :     {
     661             :       libmesh_assert(_sys.solutionUDot());
     662     2683515 :       getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dot);
     663             :     }
     664     5408493 :     if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
     665             :     {
     666             :       libmesh_assert(_sys.solutionUDotDot());
     667           0 :       getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
     668             :     }
     669     5408493 :     if (_need_u_dot_old || _need_dof_values_dot_old)
     670             :     {
     671             :       libmesh_assert(_sys.solutionUDotOld());
     672           0 :       getArrayDoFValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
     673             :     }
     674     5408493 :     if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
     675             :     {
     676             :       libmesh_assert(_sys.solutionUDotDotOld());
     677           0 :       getArrayDoFValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
     678             :     }
     679             :   }
     680             : 
     681    11493278 :   for (auto tag : _required_vector_tags)
     682     5747359 :     if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
     683    11493278 :          _subproblem.safeAccessTaggedVectors()) ||
     684     5745919 :         _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
     685             :       // tag is defined on problem but may not be used by a system
     686     5747359 :       if (_sys.hasVector(tag) && _sys.getVector(tag).closed())
     687     5746447 :         getArrayDoFValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
     688             : 
     689     5745919 :   if (_subproblem.safeAccessTaggedMatrices())
     690             :   {
     691             :     auto & active_coupleable_matrix_tags =
     692     4778301 :         _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
     693     4778301 :     for (auto tag : active_coupleable_matrix_tags)
     694             :     {
     695           0 :       _matrix_tags_dof_u[tag].resize(n);
     696           0 :       if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
     697           0 :         if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
     698             :         {
     699           0 :           auto & mat = _sys.getMatrix(tag);
     700           0 :           for (unsigned i = 0; i < n; i++)
     701             :           {
     702           0 :             Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     703           0 :             for (unsigned j = 0; j < _count; j++)
     704           0 :               _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
     705           0 :           }
     706             :         }
     707             :     }
     708             :   }
     709             : 
     710     5745919 :   if (_need_du_dot_du || _need_dof_du_dot_du)
     711             :   {
     712     2683515 :     _dof_du_dot_du.resize(n);
     713    12284505 :     for (decltype(n) i = 0; i < n; ++i)
     714     9600990 :       _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
     715             :   }
     716     5745919 :   if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
     717             :   {
     718           0 :     _dof_du_dotdot_du.resize(n);
     719           0 :     for (decltype(n) i = 0; i < n; ++i)
     720           0 :       _dof_du_dotdot_du[i] = _sys.duDotDotDu();
     721             :   }
     722     5745919 : }
     723             : 
     724             : template <typename OutputType>
     725             : void
     726         210 : MooseVariableDataBase<OutputType>::zeroSizeDofValues()
     727             : {
     728         210 :   if (_subproblem.isTransient())
     729             :   {
     730         162 :     _dof_values_dot.resize(0);
     731         162 :     _dof_values_dotdot.resize(0);
     732         162 :     _dof_values_dot_old.resize(0);
     733         162 :     _dof_values_dotdot_old.resize(0);
     734         162 :     _dof_du_dot_du.resize(0);
     735         162 :     _dof_du_dotdot_du.resize(0);
     736             :   }
     737             : 
     738        1698 :   for (auto & dof_values : _vector_tags_dof_u)
     739        1488 :     dof_values.resize(0);
     740             : 
     741         210 :   _has_dof_values = false;
     742         210 : }
     743             : 
     744             : template <typename OutputType>
     745             : void
     746   270234871 : MooseVariableDataBase<OutputType>::assignNodalValue()
     747             : {
     748   270234871 :   bool is_transient = _subproblem.isTransient();
     749             : 
     750             :   libmesh_assert(_dof_indices.size());
     751             : 
     752   270234871 :   auto & dof_values = _vector_tags_dof_u[_solution_tag];
     753   270234871 :   _nodal_value = dof_values[0];
     754   270234871 :   _nodal_value_array[0] = _nodal_value;
     755             : 
     756   270234871 :   if (is_transient)
     757             :   {
     758   243705317 :     if (oldestSolutionStateRequested() >= 1)
     759             :     {
     760     4694156 :       _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
     761     4694156 :       _nodal_value_old_array[0] = _nodal_value_old;
     762             :     }
     763   243705317 :     if (oldestSolutionStateRequested() >= 2)
     764             :     {
     765     1632476 :       _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
     766     1632476 :       _nodal_value_older_array[0] = _nodal_value_older;
     767             :     }
     768   243705317 :     if (_need_dof_values_dot)
     769     1442439 :       _nodal_value_dot = _dof_values_dot[0];
     770   243705317 :     if (_need_dof_values_dotdot)
     771           0 :       _nodal_value_dotdot = _dof_values_dotdot[0];
     772   243705317 :     if (_need_dof_values_dot_old)
     773           0 :       _nodal_value_dot_old = _dof_values_dot_old[0];
     774   243705317 :     if (_need_dof_values_dotdot_old)
     775           0 :       _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
     776             :   }
     777   270234871 :   if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
     778       51656 :     _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
     779   270234871 : }
     780             : 
     781             : template <>
     782             : void
     783      560356 : MooseVariableDataBase<RealVectorValue>::assignNodalValue()
     784             : {
     785      560356 :   bool is_transient = _subproblem.isTransient();
     786             : 
     787      560356 :   auto n = _dof_indices.size();
     788             :   libmesh_assert(n);
     789             : 
     790      560356 :   auto & dof_values = _vector_tags_dof_u[_solution_tag];
     791     1807923 :   for (decltype(n) i = 0; i < n; ++i)
     792     1247567 :     _nodal_value(i) = dof_values[i];
     793      560356 :   _nodal_value_array[0] = _nodal_value;
     794             : 
     795      560356 :   if (is_transient)
     796             :   {
     797      289628 :     if (oldestSolutionStateRequested() >= 1)
     798             :     {
     799       50536 :       auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
     800      198448 :       for (decltype(n) i = 0; i < n; ++i)
     801      147912 :         _nodal_value_old(i) = dof_values_old[i];
     802       50536 :       _nodal_value_old_array[0] = _nodal_value_old;
     803             :     }
     804      289628 :     if (oldestSolutionStateRequested() >= 2)
     805             :     {
     806        3696 :       auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
     807       11088 :       for (decltype(n) i = 0; i < n; ++i)
     808        7392 :         _nodal_value_older(i) = dof_values_older[i];
     809        3696 :       _nodal_value_older_array[0] = _nodal_value_older;
     810             :     }
     811      289628 :     if (_need_dof_values_dot)
     812           0 :       for (decltype(n) i = 0; i < n; ++i)
     813           0 :         _nodal_value_dot(i) = _dof_values_dot[i];
     814      289628 :     if (_need_dof_values_dotdot)
     815           0 :       for (decltype(n) i = 0; i < n; ++i)
     816           0 :         _nodal_value_dotdot(i) = _dof_values_dotdot[i];
     817      289628 :     if (_need_dof_values_dot_old)
     818           0 :       for (decltype(n) i = 0; i < n; ++i)
     819           0 :         _nodal_value_dot_old(i) = _dof_values_dot_old[i];
     820      289628 :     if (_need_dof_values_dotdot_old)
     821           0 :       for (decltype(n) i = 0; i < n; ++i)
     822           0 :         _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
     823             :   }
     824      560356 :   if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
     825             :   {
     826           0 :     auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
     827           0 :     for (decltype(n) i = 0; i < n; ++i)
     828           0 :       _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
     829             :   }
     830      560356 : }
     831             : 
     832             : template class MooseVariableDataBase<Real>;
     833             : template class MooseVariableDataBase<RealVectorValue>;
     834             : template class MooseVariableDataBase<RealEigenVector>;

Generated by: LCOV version 1.14