LCOV - code coverage report
Current view: top level - src/systems - SystemBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 3501bd Lines: 739 860 85.9 %
Date: 2025-09-04 20:01:23 Functions: 116 127 91.3 %
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 "MooseApp.h"
      11             : #include "SystemBase.h"
      12             : #include "Factory.h"
      13             : #include "SubProblem.h"
      14             : #include "MooseVariableFE.h"
      15             : #include "MooseVariableFV.h"
      16             : #include "MooseVariableScalar.h"
      17             : #include "MooseVariableConstMonomial.h"
      18             : #include "Conversion.h"
      19             : #include "Parser.h"
      20             : #include "AllLocalDofIndicesThread.h"
      21             : #include "MooseTypes.h"
      22             : #include "InitialCondition.h"
      23             : #include "ScalarInitialCondition.h"
      24             : #include "Assembly.h"
      25             : #include "MooseMesh.h"
      26             : #include "MooseUtils.h"
      27             : #include "FVBoundaryCondition.h"
      28             : #include "FEProblemBase.h"
      29             : #include "TimeIntegrator.h"
      30             : 
      31             : #include "libmesh/dof_map.h"
      32             : #include "libmesh/string_to_enum.h"
      33             : #include "libmesh/fe_interface.h"
      34             : #include "libmesh/static_condensation.h"
      35             : 
      36             : using namespace libMesh;
      37             : 
      38             : /// Free function used for a libMesh callback
      39             : void
      40       65414 : extraSendList(std::vector<dof_id_type> & send_list, void * context)
      41             : {
      42       65414 :   SystemBase * sys = static_cast<SystemBase *>(context);
      43       65414 :   sys->augmentSendList(send_list);
      44       65414 : }
      45             : 
      46             : /// Free function used for a libMesh callback
      47             : void
      48       68579 : extraSparsity(SparsityPattern::Graph & sparsity,
      49             :               std::vector<dof_id_type> & n_nz,
      50             :               std::vector<dof_id_type> & n_oz,
      51             :               void * context)
      52             : {
      53       68579 :   SystemBase * sys = static_cast<SystemBase *>(context);
      54       68579 :   sys->augmentSparsity(sparsity, n_nz, n_oz);
      55       68579 : }
      56             : 
      57      131304 : SystemBase::SystemBase(SubProblem & subproblem,
      58             :                        FEProblemBase & fe_problem,
      59             :                        const std::string & name,
      60      131304 :                        Moose::VarKindType var_kind)
      61             :   : libMesh::ParallelObject(subproblem),
      62             :     ConsoleStreamInterface(subproblem.getMooseApp()),
      63      131304 :     _subproblem(subproblem),
      64      131304 :     _fe_problem(fe_problem),
      65      262608 :     _app(subproblem.getMooseApp()),
      66      131304 :     _factory(_app.getFactory()),
      67      131304 :     _mesh(subproblem.mesh()),
      68      131304 :     _name(name),
      69      262608 :     _vars(libMesh::n_threads()),
      70      131304 :     _var_map(),
      71      131304 :     _max_var_number(0),
      72      131304 :     _u_dot(nullptr),
      73      131304 :     _u_dotdot(nullptr),
      74      131304 :     _u_dot_old(nullptr),
      75      131304 :     _u_dotdot_old(nullptr),
      76      131304 :     _saved_old(nullptr),
      77      131304 :     _saved_older(nullptr),
      78      131304 :     _saved_dot_old(nullptr),
      79      131304 :     _saved_dotdot_old(nullptr),
      80      131304 :     _var_kind(var_kind),
      81      131304 :     _max_var_n_dofs_per_elem(0),
      82      131304 :     _max_var_n_dofs_per_node(0),
      83      131304 :     _automatic_scaling(false),
      84      131304 :     _verbose(false),
      85      262608 :     _solution_states_initialized(false)
      86             : {
      87      131304 : }
      88             : 
      89             : MooseVariableFieldBase &
      90     4885378 : SystemBase::getVariable(THREAD_ID tid, const std::string & var_name) const
      91             : {
      92             :   MooseVariableFieldBase * var =
      93     4885378 :       dynamic_cast<MooseVariableFieldBase *>(_vars[tid].getVariable(var_name));
      94     4885378 :   if (!var)
      95           4 :     mooseError("Variable '", var_name, "' does not exist in this system");
      96     4885374 :   return *var;
      97             : }
      98             : 
      99             : MooseVariableFieldBase &
     100   169801494 : SystemBase::getVariable(THREAD_ID tid, unsigned int var_number) const
     101             : {
     102   169801494 :   if (var_number < _numbered_vars[tid].size())
     103   169801494 :     if (_numbered_vars[tid][var_number])
     104   169801494 :       return *_numbered_vars[tid][var_number];
     105             : 
     106           0 :   mooseError("Variable #", Moose::stringify(var_number), " does not exist in this system");
     107             : }
     108             : 
     109             : template <typename T>
     110             : MooseVariableFE<T> &
     111       60158 : SystemBase::getFieldVariable(THREAD_ID tid, const std::string & var_name)
     112             : {
     113       60158 :   return *_vars[tid].getFieldVariable<T>(var_name);
     114             : }
     115             : 
     116             : template <typename T>
     117             : MooseVariableField<T> &
     118      110896 : SystemBase::getActualFieldVariable(THREAD_ID tid, const std::string & var_name)
     119             : {
     120      110896 :   return *_vars[tid].getActualFieldVariable<T>(var_name);
     121             : }
     122             : 
     123             : template <typename T>
     124             : MooseVariableFV<T> &
     125         690 : SystemBase::getFVVariable(THREAD_ID tid, const std::string & var_name)
     126             : {
     127         690 :   return *_vars[tid].getFVVariable<T>(var_name);
     128             : }
     129             : 
     130             : template <typename T>
     131             : MooseVariableFE<T> &
     132           0 : SystemBase::getFieldVariable(THREAD_ID tid, unsigned int var_number)
     133             : {
     134           0 :   return *_vars[tid].getFieldVariable<T>(var_number);
     135             : }
     136             : 
     137             : template <typename T>
     138             : MooseVariableField<T> &
     139   147053271 : SystemBase::getActualFieldVariable(THREAD_ID tid, unsigned int var_number)
     140             : {
     141   147053271 :   return *_vars[tid].getActualFieldVariable<T>(var_number);
     142             : }
     143             : 
     144             : MooseVariableScalar &
     145       60040 : SystemBase::getScalarVariable(THREAD_ID tid, const std::string & var_name) const
     146             : {
     147       60040 :   MooseVariableScalar * var = dynamic_cast<MooseVariableScalar *>(_vars[tid].getVariable(var_name));
     148       60040 :   if (!var)
     149           8 :     mooseError("Scalar variable '" + var_name + "' does not exist in this system");
     150       60032 :   return *var;
     151             : }
     152             : 
     153             : MooseVariableScalar &
     154      207789 : SystemBase::getScalarVariable(THREAD_ID tid, unsigned int var_number) const
     155             : {
     156             :   MooseVariableScalar * var =
     157      207789 :       dynamic_cast<MooseVariableScalar *>(_vars[tid].getVariable(var_number));
     158      207789 :   if (!var)
     159           0 :     mooseError("variable #" + Moose::stringify(var_number) + " does not exist in this system");
     160      207789 :   return *var;
     161             : }
     162             : 
     163             : const std::set<SubdomainID> *
     164         344 : SystemBase::getVariableBlocks(unsigned int var_number)
     165             : {
     166             :   mooseAssert(_var_map.find(var_number) != _var_map.end(), "Variable does not exist.");
     167         344 :   if (_var_map[var_number].empty())
     168         344 :     return nullptr;
     169             :   else
     170           0 :     return &_var_map[var_number];
     171             : }
     172             : 
     173             : void
     174         509 : SystemBase::addVariableToZeroOnResidual(std::string var_name)
     175             : {
     176         509 :   _vars_to_be_zeroed_on_residual.push_back(var_name);
     177         509 : }
     178             : 
     179             : void
     180         339 : SystemBase::addVariableToZeroOnJacobian(std::string var_name)
     181             : {
     182         339 :   _vars_to_be_zeroed_on_jacobian.push_back(var_name);
     183         339 : }
     184             : 
     185             : void
     186         116 : SystemBase::setVariableGlobalDoFs(const std::string & var_name)
     187             : {
     188         348 :   AllLocalDofIndicesThread aldit(_subproblem, {var_name});
     189         116 :   ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
     190         116 :   Threads::parallel_reduce(elem_range, aldit);
     191             : 
     192             :   // Gather the dof indices across procs to get all the dof indices for var_name
     193         116 :   aldit.dofIndicesSetUnion();
     194             : 
     195         116 :   const auto & all_dof_indices = aldit.getDofIndices();
     196         116 :   _var_all_dof_indices.assign(all_dof_indices.begin(), all_dof_indices.end());
     197         232 : }
     198             : 
     199             : void
     200     3826133 : SystemBase::zeroVariables(std::vector<std::string> & vars_to_be_zeroed)
     201             : {
     202     3826133 :   if (vars_to_be_zeroed.size() > 0)
     203             :   {
     204       10142 :     NumericVector<Number> & solution = this->solution();
     205             : 
     206       10142 :     auto problem = dynamic_cast<FEProblemBase *>(&_subproblem);
     207       10142 :     if (!problem)
     208           0 :       mooseError("System needs to be registered in FEProblemBase for using zeroVariables.");
     209             : 
     210       10142 :     AllLocalDofIndicesThread aldit(*problem, vars_to_be_zeroed, true);
     211       10142 :     ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
     212       10142 :     Threads::parallel_reduce(elem_range, aldit);
     213             : 
     214       10142 :     const auto & dof_indices_to_zero = aldit.getDofIndices();
     215             : 
     216       10142 :     solution.close();
     217             : 
     218     3082797 :     for (const auto & dof : dof_indices_to_zero)
     219     3072655 :       solution.set(dof, 0);
     220             : 
     221       10142 :     solution.close();
     222             : 
     223             :     // Call update to update the current_local_solution for this system
     224       10142 :     system().update();
     225       10142 :   }
     226     3826133 : }
     227             : 
     228             : void
     229     3296816 : SystemBase::zeroVariablesForResidual()
     230             : {
     231     3296816 :   zeroVariables(_vars_to_be_zeroed_on_residual);
     232     3296816 : }
     233             : 
     234             : void
     235      519693 : SystemBase::zeroVariablesForJacobian()
     236             : {
     237      519693 :   zeroVariables(_vars_to_be_zeroed_on_jacobian);
     238      519693 : }
     239             : 
     240             : Order
     241       62676 : SystemBase::getMinQuadratureOrder()
     242             : {
     243       62676 :   Order order = CONSTANT;
     244       62676 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[0].fieldVariables();
     245      124120 :   for (const auto & var : vars)
     246             :   {
     247       61444 :     FEType fe_type = var->feType();
     248       61444 :     if (fe_type.default_quadrature_order() > order)
     249       50359 :       order = fe_type.default_quadrature_order();
     250             :   }
     251             : 
     252       62676 :   return order;
     253             : }
     254             : 
     255             : void
     256   879636850 : SystemBase::prepare(THREAD_ID tid)
     257             : {
     258   879636850 :   if (_subproblem.hasActiveElementalMooseVariables(tid))
     259             :   {
     260             :     const std::set<MooseVariableFieldBase *> & active_elemental_moose_variables =
     261   845703393 :         _subproblem.getActiveElementalMooseVariables(tid);
     262   845703393 :     const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     263  1646426752 :     for (const auto & var : vars)
     264   800723359 :       var->clearDofIndices();
     265             : 
     266  1899911028 :     for (const auto & var : active_elemental_moose_variables)
     267  1054207635 :       if (&(var->sys()) == this)
     268   514606187 :         var->prepare();
     269             :   }
     270             :   else
     271             :   {
     272    33933457 :     const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     273    70436184 :     for (const auto & var : vars)
     274    36502727 :       var->prepare();
     275             :   }
     276   879636850 : }
     277             : 
     278             : void
     279       58958 : SystemBase::prepareFace(THREAD_ID tid, bool resize_data)
     280             : {
     281             :   // We only need to do something if the element prepare was restricted
     282       58958 :   if (_subproblem.hasActiveElementalMooseVariables(tid))
     283             :   {
     284             :     const std::set<MooseVariableFieldBase *> & active_elemental_moose_variables =
     285       36574 :         _subproblem.getActiveElementalMooseVariables(tid);
     286             : 
     287       36574 :     std::vector<MooseVariableFieldBase *> newly_prepared_vars;
     288             : 
     289       36574 :     const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     290       66881 :     for (const auto & var : vars)
     291             :     {
     292             :       mooseAssert(&var->sys() == this,
     293             :                   "I will cry if we store variables in our warehouse that don't belong to us");
     294             : 
     295             :       // If it wasn't in the active list, we need to prepare it. This has the potential to duplicate
     296             :       // prepare if we have these conditions:
     297             :       //
     298             :       // 1. We have a displaced problem
     299             :       // 2. We are using AD
     300             :       // 3. We are not using global AD indexing
     301             :       //
     302             :       // But I think I would rather risk duplicate prepare than introduce an additional member set
     303             :       // variable for tracking prepared variables. Set insertion is slow and some simulations have a
     304             :       // ton of variables
     305       30307 :       if (!active_elemental_moose_variables.count(var))
     306             :       {
     307        3646 :         var->prepare();
     308        3646 :         newly_prepared_vars.push_back(var);
     309             :       }
     310             :     }
     311             : 
     312             :     // Make sure to resize the residual and jacobian datastructures for all the new variables
     313       36574 :     if (resize_data)
     314       19912 :       for (const auto var_ptr : newly_prepared_vars)
     315             :       {
     316        1625 :         _subproblem.assembly(tid, number()).prepareVariable(var_ptr);
     317        1625 :         if (_subproblem.checkNonlocalCouplingRequirement())
     318           0 :           _subproblem.assembly(tid, number()).prepareVariableNonlocal(var_ptr);
     319             :       }
     320       36574 :   }
     321       58958 : }
     322             : 
     323             : void
     324     9248134 : SystemBase::prepareNeighbor(THREAD_ID tid)
     325             : {
     326     9248134 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     327    23724231 :   for (const auto & var : vars)
     328    14476097 :     var->prepareNeighbor();
     329     9248134 : }
     330             : 
     331             : void
     332      652032 : SystemBase::prepareLowerD(THREAD_ID tid)
     333             : {
     334      652032 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     335     1293713 :   for (const auto & var : vars)
     336      641681 :     var->prepareLowerD();
     337      652032 : }
     338             : 
     339             : void
     340   442178865 : SystemBase::reinitElem(const Elem * const elem, THREAD_ID tid)
     341             : {
     342   442178865 :   if (_subproblem.hasActiveElementalMooseVariables(tid))
     343             :   {
     344             :     const std::set<MooseVariableFieldBase *> & active_elemental_moose_variables =
     345   425442884 :         _subproblem.getActiveElementalMooseVariables(tid);
     346   957199962 :     for (const auto & var : active_elemental_moose_variables)
     347   531757078 :       if (&(var->sys()) == this)
     348   437064780 :         var->computeElemValues();
     349             :   }
     350             :   else
     351             :   {
     352    16735981 :     const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     353    33085914 :     for (const auto & var : vars)
     354    16349933 :       var->computeElemValues();
     355             :   }
     356             : 
     357   442178865 :   if (system().has_static_condensation())
     358     1159995 :     for (auto & [tag, matrix] : _active_tagged_matrices)
     359             :     {
     360      255139 :       libmesh_ignore(tag);
     361      255139 :       cast_ptr<StaticCondensation *>(matrix)->set_current_elem(*elem);
     362             :     }
     363   442178865 : }
     364             : 
     365             : void
     366    13259811 : SystemBase::reinitElemFace(const Elem * /*elem*/, unsigned int /*side*/, THREAD_ID tid)
     367             : {
     368    13259811 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     369    35754299 :   for (const auto & var : vars)
     370    22494488 :     var->computeElemValuesFace();
     371    13259811 : }
     372             : 
     373             : void
     374     9202694 : SystemBase::reinitNeighborFace(const Elem * /*elem*/, unsigned int /*side*/, THREAD_ID tid)
     375             : {
     376     9202694 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     377    23645511 :   for (const auto & var : vars)
     378    14442817 :     var->computeNeighborValuesFace();
     379     9202694 : }
     380             : 
     381             : void
     382       45440 : SystemBase::reinitNeighbor(const Elem * /*elem*/, THREAD_ID tid)
     383             : {
     384       45440 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     385       78720 :   for (const auto & var : vars)
     386       33280 :     var->computeNeighborValues();
     387       45440 : }
     388             : 
     389             : void
     390      652032 : SystemBase::reinitLowerD(THREAD_ID tid)
     391             : {
     392      652032 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     393     1293713 :   for (const auto & var : vars)
     394      641681 :     var->computeLowerDValues();
     395      652032 : }
     396             : 
     397             : void
     398    60356192 : SystemBase::reinitNode(const Node * /*node*/, THREAD_ID tid)
     399             : {
     400    60356192 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     401   164461072 :   for (const auto & var : vars)
     402             :   {
     403   104104880 :     var->reinitNode();
     404   104104880 :     if (var->isNodalDefined())
     405    87974034 :       var->computeNodalValues();
     406             :   }
     407    60356192 : }
     408             : 
     409             : void
     410   169868338 : SystemBase::reinitNodeFace(const Node * /*node*/, BoundaryID /*bnd_id*/, THREAD_ID tid)
     411             : {
     412   169868338 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     413   413422589 :   for (const auto & var : vars)
     414             :   {
     415   243554251 :     var->reinitNode();
     416   243554251 :     if (var->isNodalDefined())
     417   216829859 :       var->computeNodalValues();
     418             :   }
     419   169868338 : }
     420             : 
     421             : void
     422       13626 : SystemBase::reinitNodes(const std::vector<dof_id_type> & nodes, THREAD_ID tid)
     423             : {
     424       13626 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     425       20604 :   for (const auto & var : vars)
     426             :   {
     427        6978 :     var->reinitNodes(nodes);
     428        6978 :     var->computeNodalValues();
     429             :   }
     430       13626 : }
     431             : 
     432             : void
     433        1446 : SystemBase::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes, THREAD_ID tid)
     434             : {
     435        1446 :   const std::vector<MooseVariableFieldBase *> & vars = _vars[tid].fieldVariables();
     436        2334 :   for (const auto & var : vars)
     437             :   {
     438         888 :     var->reinitNodesNeighbor(nodes);
     439         888 :     var->computeNodalNeighborValues();
     440             :   }
     441        1446 : }
     442             : 
     443             : void
     444    18527453 : SystemBase::reinitScalars(THREAD_ID tid, bool reinit_for_derivative_reordering /*=false*/)
     445             : {
     446    18527453 :   const std::vector<MooseVariableScalar *> & vars = _vars[tid].scalars();
     447    19053260 :   for (const auto & var : vars)
     448      525807 :     var->reinit(reinit_for_derivative_reordering);
     449    18527453 : }
     450             : 
     451             : void
     452       65414 : SystemBase::augmentSendList(std::vector<dof_id_type> & send_list)
     453             : {
     454       65414 :   std::set<dof_id_type> & ghosted_elems = _subproblem.ghostedElems();
     455             : 
     456       65414 :   DofMap & dof_map = dofMap();
     457             : 
     458       65414 :   std::vector<dof_id_type> dof_indices;
     459             : 
     460       65414 :   System & sys = system();
     461             : 
     462       65414 :   unsigned int sys_num = sys.number();
     463             : 
     464       65414 :   unsigned int n_vars = sys.n_vars();
     465             : 
     466      156187 :   for (const auto & elem_id : ghosted_elems)
     467             :   {
     468       90773 :     Elem * elem = _mesh.elemPtr(elem_id);
     469             : 
     470       90773 :     if (elem->active())
     471             :     {
     472       90773 :       dof_map.dof_indices(elem, dof_indices);
     473             : 
     474             :       // Only need to ghost it if it's actually not on this processor
     475     1188329 :       for (const auto & dof : dof_indices)
     476     1097556 :         if (dof < dof_map.first_dof() || dof >= dof_map.end_dof())
     477     1073406 :           send_list.push_back(dof);
     478             : 
     479             :       // Now add the DoFs from all of the nodes.  This is necessary because of block
     480             :       // restricted variables.  A variable might not live _on_ this element but it
     481             :       // might live on nodes connected to this element.
     482      508467 :       for (unsigned int n = 0; n < elem->n_nodes(); n++)
     483             :       {
     484      417694 :         Node * node = elem->node_ptr(n);
     485             : 
     486             :         // Have to get each variable's dofs
     487     1629124 :         for (unsigned int v = 0; v < n_vars; v++)
     488             :         {
     489     1211430 :           const Variable & var = sys.variable(v);
     490     1211430 :           unsigned int var_num = var.number();
     491     1211430 :           unsigned int n_comp = var.n_components();
     492             : 
     493             :           // See if this variable has any dofs at this node
     494     1211430 :           if (node->n_dofs(sys_num, var_num) > 0)
     495             :           {
     496             :             // Loop over components of the variable
     497     2128568 :             for (unsigned int c = 0; c < n_comp; c++)
     498     1064284 :               send_list.push_back(node->dof_number(sys_num, var_num, c));
     499             :           }
     500             :         }
     501             :       }
     502             :     }
     503             :   }
     504       65414 : }
     505             : 
     506             : /**
     507             :  * Save the old and older solutions.
     508             :  */
     509             : void
     510         252 : SystemBase::saveOldSolutions()
     511             : {
     512             :   const auto states =
     513         252 :       _solution_states[static_cast<unsigned short>(Moose::SolutionIterationType::Time)].size();
     514         252 :   if (states > 1)
     515             :   {
     516         230 :     _saved_solution_states.resize(states);
     517         690 :     for (unsigned int i = 1; i <= states - 1; ++i)
     518         460 :       if (!_saved_solution_states[i])
     519         920 :         _saved_solution_states[i] =
     520         460 :             &addVector("save_solution_state_" + std::to_string(i), false, PARALLEL);
     521             : 
     522         690 :     for (unsigned int i = 1; i <= states - 1; ++i)
     523         460 :       *(_saved_solution_states[i]) = solutionState(i);
     524             :   }
     525             : 
     526         252 :   if (!_saved_dot_old && solutionUDotOld())
     527           0 :     _saved_dot_old = &addVector("save_solution_dot_old", false, PARALLEL);
     528         252 :   if (!_saved_dotdot_old && solutionUDotDotOld())
     529           0 :     _saved_dotdot_old = &addVector("save_solution_dotdot_old", false, PARALLEL);
     530             : 
     531         252 :   if (solutionUDotOld())
     532           0 :     *_saved_dot_old = *solutionUDotOld();
     533             : 
     534         252 :   if (solutionUDotDotOld())
     535           0 :     *_saved_dotdot_old = *solutionUDotDotOld();
     536         252 : }
     537             : 
     538             : /**
     539             :  * Restore the old and older solutions when the saved solutions present.
     540             :  */
     541             : void
     542         252 : SystemBase::restoreOldSolutions()
     543             : {
     544             :   const auto states =
     545         252 :       _solution_states[static_cast<unsigned short>(Moose::SolutionIterationType::Time)].size();
     546         252 :   if (states > 1)
     547         690 :     for (unsigned int i = 1; i <= states - 1; ++i)
     548         460 :       if (_saved_solution_states[i])
     549             :       {
     550         460 :         solutionState(i) = *(_saved_solution_states[i]);
     551         460 :         removeVector("save_solution_state_" + std::to_string(i));
     552         460 :         _saved_solution_states[i] = nullptr;
     553             :       }
     554             : 
     555         252 :   if (_saved_dot_old && solutionUDotOld())
     556             :   {
     557           0 :     *solutionUDotOld() = *_saved_dot_old;
     558           0 :     removeVector("save_solution_dot_old");
     559           0 :     _saved_dot_old = nullptr;
     560             :   }
     561         252 :   if (_saved_dotdot_old && solutionUDotDotOld())
     562             :   {
     563           0 :     *solutionUDotDotOld() = *_saved_dotdot_old;
     564           0 :     removeVector("save_solution_dotdot_old");
     565           0 :     _saved_dotdot_old = nullptr;
     566             :   }
     567         252 : }
     568             : 
     569             : SparseMatrix<Number> &
     570         348 : SystemBase::addMatrix(TagID tag)
     571             : {
     572         348 :   if (!_subproblem.matrixTagExists(tag))
     573           0 :     mooseError("Cannot add tagged matrix with TagID ",
     574             :                tag,
     575             :                " in system '",
     576           0 :                name(),
     577             :                "' because the tag does not exist in the problem");
     578             : 
     579         348 :   if (hasMatrix(tag))
     580           0 :     return getMatrix(tag);
     581             : 
     582         348 :   const auto matrix_name = _subproblem.matrixTagName(tag);
     583         348 :   SparseMatrix<Number> & mat = system().add_matrix(matrix_name);
     584         348 :   associateMatrixToTag(mat, tag);
     585             : 
     586         348 :   return mat;
     587         348 : }
     588             : 
     589             : void
     590           0 : SystemBase::removeMatrix(TagID tag_id)
     591             : {
     592           0 :   if (!_subproblem.matrixTagExists(tag_id))
     593           0 :     mooseError("Cannot remove the matrix with TagID ",
     594             :                tag_id,
     595             :                "\nin system '",
     596           0 :                name(),
     597             :                "', because that tag does not exist in the problem");
     598             : 
     599           0 :   if (hasMatrix(tag_id))
     600             :   {
     601           0 :     const auto matrix_name = _subproblem.matrixTagName(tag_id);
     602           0 :     system().remove_matrix(matrix_name);
     603           0 :     _tagged_matrices[tag_id] = nullptr;
     604           0 :   }
     605           0 : }
     606             : 
     607             : NumericVector<Number> &
     608       69362 : SystemBase::addVector(const std::string & vector_name, const bool project, const ParallelType type)
     609             : {
     610       69362 :   if (hasVector(vector_name))
     611         449 :     return getVector(vector_name);
     612             : 
     613       68913 :   NumericVector<Number> & vec = system().add_vector(vector_name, project, type);
     614       68913 :   return vec;
     615             : }
     616             : 
     617             : NumericVector<Number> &
     618      164787 : SystemBase::addVector(TagID tag, const bool project, const ParallelType type)
     619             : {
     620      164787 :   if (!_subproblem.vectorTagExists(tag))
     621           0 :     mooseError("Cannot add tagged vector with TagID ",
     622             :                tag,
     623             :                " in system '",
     624           0 :                name(),
     625             :                "' because the tag does not exist in the problem");
     626             : 
     627      164787 :   if (hasVector(tag))
     628             :   {
     629           0 :     auto & vec = getVector(tag);
     630             : 
     631           0 :     if (type != ParallelType::AUTOMATIC && vec.type() != type)
     632           0 :       mooseError("Cannot add tagged vector '",
     633           0 :                  _subproblem.vectorTagName(tag),
     634             :                  "', in system '",
     635           0 :                  name(),
     636             :                  "' because a vector with the same name was found with a different parallel type");
     637             : 
     638           0 :     return vec;
     639             :   }
     640             : 
     641      164787 :   const auto vector_name = _subproblem.vectorTagName(tag);
     642      164787 :   NumericVector<Number> & vec = system().add_vector(vector_name, project, type);
     643      164787 :   associateVectorToTag(vec, tag);
     644             : 
     645      164787 :   return vec;
     646      164787 : }
     647             : 
     648             : void
     649    19024195 : SystemBase::closeTaggedVector(const TagID tag)
     650             : {
     651    19024195 :   if (!_subproblem.vectorTagExists(tag))
     652           0 :     mooseError("Cannot close vector with TagID ",
     653             :                tag,
     654             :                " in system '",
     655           0 :                name(),
     656             :                "' because that tag does not exist in the problem");
     657    19024195 :   else if (!hasVector(tag))
     658           0 :     mooseError("Cannot close vector tag with name '",
     659           0 :                _subproblem.vectorTagName(tag),
     660             :                "' in system '",
     661           0 :                name(),
     662             :                "' because there is no vector associated with that tag");
     663    19024195 :   getVector(tag).close();
     664    19024195 : }
     665             : 
     666             : void
     667     6593749 : SystemBase::closeTaggedVectors(const std::set<TagID> & tags)
     668             : {
     669    25617944 :   for (const auto tag : tags)
     670    19024195 :     closeTaggedVector(tag);
     671     6593749 : }
     672             : 
     673             : void
     674     9512434 : SystemBase::zeroTaggedVector(const TagID tag)
     675             : {
     676     9512434 :   if (!_subproblem.vectorTagExists(tag))
     677           0 :     mooseError("Cannot zero vector with TagID ",
     678             :                tag,
     679             :                " in system '",
     680           0 :                name(),
     681             :                "' because that tag does not exist in the problem");
     682     9512434 :   else if (!hasVector(tag))
     683           0 :     mooseError("Cannot zero vector tag with name '",
     684           0 :                _subproblem.vectorTagName(tag),
     685             :                "' in system '",
     686           0 :                name(),
     687             :                "' because there is no vector associated with that tag");
     688     9512434 :   if (!_subproblem.vectorTagNotZeroed(tag))
     689     9512412 :     getVector(tag).zero();
     690     9512434 : }
     691             : 
     692             : void
     693     3296947 : SystemBase::zeroTaggedVectors(const std::set<TagID> & tags)
     694             : {
     695    12809381 :   for (const auto tag : tags)
     696     9512434 :     zeroTaggedVector(tag);
     697     3296947 : }
     698             : 
     699             : void
     700           0 : SystemBase::removeVector(TagID tag_id)
     701             : {
     702           0 :   if (!_subproblem.vectorTagExists(tag_id))
     703           0 :     mooseError("Cannot remove the vector with TagID ",
     704             :                tag_id,
     705             :                "\nin system '",
     706           0 :                name(),
     707             :                "', because that tag does not exist in the problem");
     708             : 
     709           0 :   if (hasVector(tag_id))
     710             :   {
     711           0 :     auto vector_name = _subproblem.vectorTagName(tag_id);
     712           0 :     system().remove_vector(vector_name);
     713           0 :     _tagged_vectors[tag_id] = nullptr;
     714           0 :   }
     715           0 : }
     716             : 
     717             : void
     718      174087 : SystemBase::addVariable(const std::string & var_type,
     719             :                         const std::string & name,
     720             :                         InputParameters & parameters)
     721             : {
     722      174087 :   _numbered_vars.resize(libMesh::n_threads());
     723             : 
     724      174087 :   const auto components = parameters.get<unsigned int>("components");
     725             : 
     726             :   // Convert the std::vector parameter provided by the user into a std::set for use by libMesh's
     727             :   // System::add_variable method
     728      174087 :   std::set<SubdomainID> blocks;
     729      174087 :   const auto & block_param = parameters.get<std::vector<SubdomainName>>("block");
     730      185838 :   for (const auto & subdomain_name : block_param)
     731             :   {
     732       11751 :     SubdomainID blk_id = _mesh.getSubdomainID(subdomain_name);
     733       11751 :     blocks.insert(blk_id);
     734             :   }
     735             : 
     736             :   const auto fe_type =
     737      348174 :       FEType(Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")),
     738      522261 :              Utility::string_to_enum<FEFamily>(parameters.get<MooseEnum>("family")));
     739      174087 :   const auto fe_field_type = FEInterface::field_type(fe_type);
     740             : 
     741             :   unsigned int var_num;
     742             : 
     743      174087 :   if (var_type == "ArrayMooseVariable")
     744             :   {
     745        2375 :     if (fe_field_type == TYPE_VECTOR)
     746           0 :       mooseError("Vector family type cannot be used in an array variable");
     747             : 
     748        2375 :     std::vector<std::string> array_var_component_names;
     749        2375 :     const bool has_array_names = parameters.isParamValid("array_var_component_names");
     750        2375 :     if (has_array_names)
     751             :     {
     752             :       array_var_component_names =
     753         160 :           parameters.get<std::vector<std::string>>("array_var_component_names");
     754         160 :       if (array_var_component_names.size() != components)
     755           8 :         parameters.paramError("array_var_component_names",
     756             :                               "Must be the same size as 'components' (size ",
     757             :                               components,
     758             :                               ") for array variable '",
     759             :                               name,
     760             :                               "'");
     761             :     }
     762             : 
     763             :     // Build up the variable names
     764        2371 :     std::vector<std::string> var_names;
     765        7779 :     for (unsigned int i = 0; i < components; i++)
     766             :     {
     767        5408 :       if (!has_array_names)
     768        4849 :         array_var_component_names.push_back(std::to_string(i));
     769        5408 :       var_names.push_back(name + "_" + array_var_component_names[i]);
     770             :     }
     771             : 
     772             :     // makes sure there is always a name, either the provided one or '1 2 3 ...'
     773        4742 :     parameters.set<std::vector<std::string>>("array_var_component_names") =
     774        2371 :         array_var_component_names;
     775             : 
     776             :     // The number returned by libMesh is the _last_ variable number... we want to hold onto the
     777             :     // _first_
     778        2371 :     var_num = system().add_variables(var_names, fe_type, &blocks) - (components - 1);
     779             : 
     780             :     // Set as array variable
     781        7113 :     if (parameters.isParamSetByUser("array") && !parameters.get<bool>("array"))
     782           8 :       parameters.paramError("array",
     783             :                             "Must be set to true for variable '",
     784             :                             name,
     785             :                             "' because 'components' > 1 (is an array variable)");
     786        2367 :     parameters.set<bool>("array") = true;
     787        2367 :   }
     788             :   else
     789             :   {
     790      343424 :     if (parameters.isParamSetByUser("array_var_component_names"))
     791           8 :       parameters.paramError("array_var_component_names",
     792             :                             "Should not be set because this variable (",
     793             :                             name,
     794             :                             ") is a non-array variable");
     795      171708 :     var_num = system().add_variable(name, fe_type, &blocks);
     796             :   }
     797             : 
     798      348150 :   parameters.set<unsigned int>("_var_num") = var_num;
     799      348150 :   parameters.set<SystemBase *>("_system_base") = this;
     800             : 
     801      364229 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
     802             :   {
     803      380316 :     parameters.set<THREAD_ID>("tid") = tid;
     804             :     std::shared_ptr<MooseVariableBase> var =
     805      190158 :         _factory.create<MooseVariableBase>(var_type, name, parameters, tid);
     806             : 
     807      190154 :     _vars[tid].add(name, var);
     808             : 
     809      190154 :     if (auto fe_var = dynamic_cast<MooseVariableFieldBase *>(var.get()))
     810             :     {
     811      186614 :       auto required_size = var_num + components;
     812      186614 :       if (required_size > _numbered_vars[tid].size())
     813      186614 :         _numbered_vars[tid].resize(required_size);
     814      376588 :       for (MooseIndex(components) component = 0; component < components; ++component)
     815      189974 :         _numbered_vars[tid][var_num + component] = fe_var;
     816             : 
     817      186614 :       if (auto * const functor = dynamic_cast<Moose::FunctorBase<ADReal> *>(fe_var))
     818      182326 :         _subproblem.addFunctor(name, *functor, tid);
     819        4288 :       else if (auto * const functor = dynamic_cast<Moose::FunctorBase<ADRealVectorValue> *>(fe_var))
     820        1666 :         _subproblem.addFunctor(name, *functor, tid);
     821        2622 :       else if (auto * const functor = dynamic_cast<Moose::FunctorBase<RealEigenVector> *>(fe_var))
     822        2622 :         _subproblem.addFunctor(name, *functor, tid);
     823             :       else
     824           0 :         mooseError("This should be a functor");
     825             :     }
     826             : 
     827      190154 :     if (auto scalar_var = dynamic_cast<MooseVariableScalar *>(var.get()))
     828             :     {
     829        3540 :       if (auto * const functor = dynamic_cast<Moose::FunctorBase<ADReal> *>(scalar_var))
     830        3540 :         _subproblem.addFunctor(name, *functor, tid);
     831             :       else
     832           0 :         mooseError("Scalar variables should be functors");
     833             :     }
     834             : 
     835      190154 :     if (var->blockRestricted())
     836       22890 :       for (const SubdomainID & id : var->blockIDs())
     837       25842 :         for (MooseIndex(components) component = 0; component < components; ++component)
     838       13150 :           _var_map[var_num + component].insert(id);
     839             :     else
     840      362814 :       for (MooseIndex(components) component = 0; component < components; ++component)
     841      182858 :         _var_map[var_num + component] = std::set<SubdomainID>();
     842      190154 :   }
     843             : 
     844             :   // getMaxVariableNumber is an API method used in Rattlesnake
     845      174071 :   if (var_num > _max_var_number)
     846       92888 :     _max_var_number = var_num;
     847      174071 :   _du_dot_du.resize(var_num + 1);
     848      174071 : }
     849             : 
     850             : bool
     851     6450011 : SystemBase::hasVariable(const std::string & var_name) const
     852             : {
     853     6450011 :   auto & names = getVariableNames();
     854     6450011 :   if (system().has_variable(var_name))
     855     5073575 :     return system().variable_type(var_name).family != SCALAR;
     856     1376436 :   if (std::find(names.begin(), names.end(), var_name) != names.end())
     857             :     // array variable
     858       36173 :     return true;
     859             :   else
     860     1340263 :     return false;
     861             : }
     862             : 
     863             : bool
     864           0 : SystemBase::isArrayVariable(const std::string & var_name) const
     865             : {
     866           0 :   auto & names = getVariableNames();
     867           0 :   if (!system().has_variable(var_name) &&
     868           0 :       std::find(names.begin(), names.end(), var_name) != names.end())
     869             :     // array variable
     870           0 :     return true;
     871             :   else
     872           0 :     return false;
     873             : }
     874             : 
     875             : bool
     876      548989 : SystemBase::hasScalarVariable(const std::string & var_name) const
     877             : {
     878      548989 :   if (system().has_variable(var_name))
     879      296719 :     return system().variable_type(var_name).family == SCALAR;
     880             :   else
     881      252270 :     return false;
     882             : }
     883             : 
     884             : bool
     885       98106 : SystemBase::isScalarVariable(unsigned int var_num) const
     886             : {
     887       98106 :   return (system().variable(var_num).type().family == SCALAR);
     888             : }
     889             : 
     890             : unsigned int
     891    59564103 : SystemBase::nVariables() const
     892             : {
     893    59564103 :   unsigned int n = nFieldVariables();
     894    59564103 :   n += _vars[0].scalars().size();
     895             : 
     896    59564103 :   return n;
     897             : }
     898             : 
     899             : unsigned int
     900    59564103 : SystemBase::nFieldVariables() const
     901             : {
     902    59564103 :   unsigned int n = 0;
     903   136699864 :   for (auto & var : _vars[0].fieldVariables())
     904    77135761 :     n += var->count();
     905             : 
     906    59564103 :   return n;
     907             : }
     908             : 
     909             : unsigned int
     910     2539914 : SystemBase::nFVVariables() const
     911             : {
     912     2539914 :   unsigned int n = 0;
     913     5444926 :   for (auto & var : _vars[0].fieldVariables())
     914     2905012 :     if (var->isFV())
     915     1599006 :       n += var->count();
     916             : 
     917     2539914 :   return n;
     918             : }
     919             : 
     920             : /**
     921             :  * Check if the named vector exists in the system.
     922             :  */
     923             : bool
     924      510351 : SystemBase::hasVector(const std::string & name) const
     925             : {
     926      510351 :   return system().have_vector(name);
     927             : }
     928             : 
     929             : /**
     930             :  * Get a raw NumericVector with the given name.
     931             :  */
     932             : NumericVector<Number> &
     933        5737 : SystemBase::getVector(const std::string & name)
     934             : {
     935        5737 :   return system().get_vector(name);
     936             : }
     937             : 
     938             : const NumericVector<Number> &
     939           0 : SystemBase::getVector(const std::string & name) const
     940             : {
     941           0 :   return system().get_vector(name);
     942             : }
     943             : 
     944             : NumericVector<Number> &
     945  2775230930 : SystemBase::getVector(TagID tag)
     946             : {
     947  2775230930 :   if (!hasVector(tag))
     948             :   {
     949           0 :     if (!_subproblem.vectorTagExists(tag))
     950           0 :       mooseError("Cannot retreive vector with tag ", tag, " because that tag does not exist");
     951             :     else
     952           0 :       mooseError("Cannot retreive vector with tag ",
     953             :                  tag,
     954             :                  " in system '",
     955           0 :                  name(),
     956             :                  "'\nbecause a vector has not been associated with that tag.");
     957             :   }
     958             : 
     959  2775230930 :   return *_tagged_vectors[tag];
     960             : }
     961             : 
     962             : const NumericVector<Number> &
     963         688 : SystemBase::getVector(TagID tag) const
     964             : {
     965         688 :   if (!hasVector(tag))
     966             :   {
     967           0 :     if (!_subproblem.vectorTagExists(tag))
     968           0 :       mooseError("Cannot retreive vector with tag ", tag, " because that tag does not exist");
     969             :     else
     970           0 :       mooseError("Cannot retreive vector with tag ",
     971             :                  tag,
     972             :                  " in system '",
     973           0 :                  name(),
     974             :                  "'\nbecause a vector has not been associated with that tag.");
     975             :   }
     976             : 
     977         688 :   return *_tagged_vectors[tag];
     978             : }
     979             : 
     980             : void
     981    10806209 : SystemBase::associateVectorToTag(NumericVector<Number> & vec, TagID tag)
     982             : {
     983    10806209 :   if (!_subproblem.vectorTagExists(tag))
     984           0 :     mooseError("Cannot associate vector to tag ", tag, " because that tag does not exist");
     985             : 
     986    10806209 :   if (_tagged_vectors.size() < tag + 1)
     987      261055 :     _tagged_vectors.resize(tag + 1);
     988             : 
     989    10806209 :   _tagged_vectors[tag] = &vec;
     990    10806209 : }
     991             : 
     992             : void
     993     3321733 : SystemBase::disassociateVectorFromTag(NumericVector<Number> & vec, TagID tag)
     994             : {
     995     3321733 :   if (!_subproblem.vectorTagExists(tag))
     996           0 :     mooseError("Cannot disassociate vector from tag ", tag, " because that tag does not exist");
     997     3321733 :   if (hasVector(tag) && &getVector(tag) != &vec)
     998           0 :     mooseError("You can not disassociate a vector from a tag which it was not associated to");
     999             : 
    1000     3321733 :   disassociateVectorFromTag(tag);
    1001     3321733 : }
    1002             : 
    1003             : void
    1004     3449117 : SystemBase::disassociateVectorFromTag(TagID tag)
    1005             : {
    1006     3449117 :   if (!_subproblem.vectorTagExists(tag))
    1007           0 :     mooseError("Cannot disassociate vector from tag ", tag, " because that tag does not exist");
    1008             : 
    1009     3449117 :   if (_tagged_vectors.size() < tag + 1)
    1010           0 :     _tagged_vectors.resize(tag + 1);
    1011     3449117 :   _tagged_vectors[tag] = nullptr;
    1012     3449117 : }
    1013             : 
    1014             : void
    1015       31846 : SystemBase::disassociateDefaultVectorTags()
    1016             : {
    1017       31846 :   const auto tags = defaultVectorTags();
    1018      191076 :   for (const auto tag : tags)
    1019      159230 :     if (_subproblem.vectorTagExists(tag))
    1020      127384 :       disassociateVectorFromTag(tag);
    1021       31846 : }
    1022             : 
    1023             : SparseMatrix<Number> &
    1024  2019948483 : SystemBase::getMatrix(TagID tag)
    1025             : {
    1026  2019948483 :   if (!hasMatrix(tag))
    1027             :   {
    1028           0 :     if (!_subproblem.matrixTagExists(tag))
    1029           0 :       mooseError("Cannot retreive matrix with tag ", tag, " because that tag does not exist");
    1030             :     else
    1031           0 :       mooseError("Cannot retreive matrix with tag ",
    1032             :                  tag,
    1033             :                  " in system '",
    1034           0 :                  name(),
    1035             :                  "'\nbecause a matrix has not been associated with that tag.");
    1036             :   }
    1037             : 
    1038  2019948483 :   return *_tagged_matrices[tag];
    1039             : }
    1040             : 
    1041             : const SparseMatrix<Number> &
    1042         344 : SystemBase::getMatrix(TagID tag) const
    1043             : {
    1044         344 :   if (!hasMatrix(tag))
    1045             :   {
    1046           0 :     if (!_subproblem.matrixTagExists(tag))
    1047           0 :       mooseError("Cannot retreive matrix with tag ", tag, " because that tag does not exist");
    1048             :     else
    1049           0 :       mooseError("Cannot retreive matrix with tag ",
    1050             :                  tag,
    1051             :                  " in system '",
    1052           0 :                  name(),
    1053             :                  "'\nbecause a matrix has not been associated with that tag.");
    1054             :   }
    1055             : 
    1056         344 :   return *_tagged_matrices[tag];
    1057             : }
    1058             : 
    1059             : void
    1060      959257 : SystemBase::closeTaggedMatrices(const std::set<TagID> & tags)
    1061             : {
    1062     2857375 :   for (auto tag : tags)
    1063     1898118 :     if (hasMatrix(tag))
    1064      962537 :       getMatrix(tag).close();
    1065      959257 : }
    1066             : 
    1067             : void
    1068           0 : SystemBase::flushTaggedMatrices(const std::set<TagID> & tags)
    1069             : {
    1070           0 :   for (auto tag : tags)
    1071           0 :     if (hasMatrix(tag))
    1072           0 :       getMatrix(tag).flush();
    1073           0 : }
    1074             : 
    1075             : void
    1076      542541 : SystemBase::associateMatrixToTag(SparseMatrix<Number> & matrix, TagID tag)
    1077             : {
    1078      542541 :   if (!_subproblem.matrixTagExists(tag))
    1079           0 :     mooseError("Cannot associate matrix to tag ", tag, " because that tag does not exist");
    1080             : 
    1081      542541 :   if (_tagged_matrices.size() < tag + 1)
    1082       40026 :     _tagged_matrices.resize(tag + 1);
    1083             : 
    1084      542541 :   _tagged_matrices[tag] = &matrix;
    1085      542541 : }
    1086             : 
    1087             : void
    1088      536435 : SystemBase::disassociateMatrixFromTag(SparseMatrix<Number> & matrix, TagID tag)
    1089             : {
    1090      536435 :   if (!_subproblem.matrixTagExists(tag))
    1091           0 :     mooseError("Cannot disassociate matrix from tag ", tag, " because that tag does not exist");
    1092      536435 :   if (hasMatrix(tag) && &getMatrix(tag) != &matrix)
    1093           0 :     mooseError("You can not disassociate a matrix from a tag which it was not associated to");
    1094             : 
    1095      536435 :   disassociateMatrixFromTag(tag);
    1096      536435 : }
    1097             : 
    1098             : void
    1099      548735 : SystemBase::disassociateMatrixFromTag(TagID tag)
    1100             : {
    1101      548735 :   if (!_subproblem.matrixTagExists(tag))
    1102           0 :     mooseError("Cannot disassociate matrix from tag ", tag, " because that tag does not exist");
    1103             : 
    1104      548735 :   if (_tagged_matrices.size() < tag + 1)
    1105        1410 :     _tagged_matrices.resize(tag + 1);
    1106      548735 :   _tagged_matrices[tag] = nullptr;
    1107      548735 : }
    1108             : 
    1109             : void
    1110        4100 : SystemBase::disassociateDefaultMatrixTags()
    1111             : {
    1112        4100 :   const auto tags = defaultMatrixTags();
    1113       16400 :   for (const auto tag : tags)
    1114       12300 :     if (_subproblem.matrixTagExists(tag))
    1115       12300 :       disassociateMatrixFromTag(tag);
    1116        4100 : }
    1117             : 
    1118             : void
    1119     3607328 : SystemBase::deactivateAllMatrixTags()
    1120             : {
    1121     3607328 :   auto num_matrix_tags = _subproblem.numMatrixTags();
    1122             : 
    1123     3607328 :   _matrix_tag_active_flags.resize(num_matrix_tags);
    1124             : 
    1125    10929968 :   for (decltype(num_matrix_tags) tag = 0; tag < num_matrix_tags; tag++)
    1126     7322640 :     _matrix_tag_active_flags[tag] = false;
    1127     3607328 :   _active_tagged_matrices.clear();
    1128     3607328 : }
    1129             : 
    1130             : void
    1131     3822280 : SystemBase::activateAllMatrixTags()
    1132             : {
    1133     3822280 :   auto num_matrix_tags = _subproblem.numMatrixTags();
    1134             : 
    1135     3822280 :   _matrix_tag_active_flags.resize(num_matrix_tags);
    1136     3822280 :   _active_tagged_matrices.clear();
    1137             : 
    1138    11578851 :   for (const auto tag : make_range(num_matrix_tags))
    1139     7756571 :     if (hasMatrix(tag))
    1140             :     {
    1141      535698 :       _matrix_tag_active_flags[tag] = true;
    1142      535698 :       _active_tagged_matrices.emplace(tag, &getMatrix(tag));
    1143             :     }
    1144             :     else
    1145     7220873 :       _matrix_tag_active_flags[tag] = false;
    1146     3822280 : }
    1147             : 
    1148             : bool
    1149       61996 : SystemBase::matrixTagActive(TagID tag) const
    1150             : {
    1151             :   mooseAssert(_subproblem.matrixTagExists(tag), "Matrix tag " << tag << " does not exist");
    1152             : 
    1153       61996 :   return tag < _matrix_tag_active_flags.size() && _matrix_tag_active_flags[tag];
    1154             : }
    1155             : 
    1156             : unsigned int
    1157  1909696021 : SystemBase::number() const
    1158             : {
    1159  1909696021 :   return system().number();
    1160             : }
    1161             : 
    1162             : DofMap &
    1163     1967340 : SystemBase::dofMap()
    1164             : {
    1165     1967340 :   return system().get_dof_map();
    1166             : }
    1167             : 
    1168             : const DofMap &
    1169           0 : SystemBase::dofMap() const
    1170             : {
    1171           0 :   return system().get_dof_map();
    1172             : }
    1173             : 
    1174             : void
    1175         430 : SystemBase::addVariableToCopy(const std::string & dest_name,
    1176             :                               const std::string & source_name,
    1177             :                               const std::string & timestep)
    1178             : {
    1179         430 :   _var_to_copy.push_back(VarCopyInfo(dest_name, source_name, timestep));
    1180         430 : }
    1181             : 
    1182             : void
    1183         586 : SystemBase::copyVars(ExodusII_IO & io)
    1184             : {
    1185         586 :   int n_steps = io.get_num_time_steps();
    1186             : 
    1187         586 :   bool did_copy = false;
    1188         995 :   for (const auto & vci : _var_to_copy)
    1189             :   {
    1190         413 :     int timestep = -1;
    1191             : 
    1192         413 :     if (vci._timestep == "LATEST")
    1193             :       // Use the last time step in the file from which to retrieve the solution
    1194         320 :       timestep = n_steps;
    1195             :     else
    1196             :     {
    1197          93 :       timestep = MooseUtils::convert<int>(vci._timestep);
    1198          93 :       if (timestep > n_steps)
    1199           4 :         mooseError("Invalid value passed as \"initial_from_file_timestep\". Expected \"LATEST\" or "
    1200             :                    "a valid integer between 1 and ",
    1201             :                    n_steps,
    1202             :                    " inclusive, received ",
    1203           4 :                    vci._timestep);
    1204             :     }
    1205             : 
    1206         409 :     did_copy = true;
    1207             : 
    1208         409 :     if (hasVariable(vci._dest_name))
    1209             :     {
    1210         361 :       const auto & var = getVariable(0, vci._dest_name);
    1211         361 :       if (var.isArray())
    1212             :       {
    1213          24 :         const auto & array_var = getFieldVariable<RealEigenVector>(0, vci._dest_name);
    1214          72 :         for (MooseIndex(var.count()) i = 0; i < var.count(); ++i)
    1215             :         {
    1216          48 :           const auto & exodus_var = var.arrayVariableComponent(i);
    1217          48 :           const auto & system_var = array_var.componentName(i);
    1218          48 :           if (var.isNodal())
    1219          24 :             io.copy_nodal_solution(system(), exodus_var, system_var, timestep);
    1220             :           else
    1221          24 :             io.copy_elemental_solution(system(), exodus_var, system_var, timestep);
    1222             :         }
    1223             :       }
    1224             :       else
    1225             :       {
    1226         337 :         if (var.isNodal())
    1227         289 :           io.copy_nodal_solution(system(), vci._dest_name, vci._source_name, timestep);
    1228             :         else
    1229          48 :           io.copy_elemental_solution(system(), vci._dest_name, vci._source_name, timestep);
    1230             :       }
    1231             :     }
    1232          48 :     else if (hasScalarVariable(vci._dest_name))
    1233         288 :       io.copy_scalar_solution(system(), {vci._dest_name}, {vci._source_name}, timestep);
    1234             :     else
    1235           0 :       mooseError("Unrecognized variable ", vci._dest_name, " in variables to copy.");
    1236             :   }
    1237             : 
    1238         582 :   if (did_copy)
    1239         297 :     solution().close();
    1240         678 : }
    1241             : 
    1242             : void
    1243     4300710 : SystemBase::update()
    1244             : {
    1245     4300710 :   system().update();
    1246     4300710 : }
    1247             : 
    1248             : void
    1249           0 : SystemBase::solve()
    1250             : {
    1251           0 :   system().solve();
    1252           0 : }
    1253             : 
    1254             : /**
    1255             :  * Copy current solution into old and older
    1256             :  */
    1257             : void
    1258      112411 : SystemBase::copySolutionsBackwards()
    1259             : {
    1260      112411 :   system().update();
    1261      112411 :   copyOldSolutions();
    1262      112411 :   copyPreviousNonlinearSolutions();
    1263      112411 : }
    1264             : 
    1265             : /**
    1266             :  * Shifts the solutions backwards in nonlinear iteration history
    1267             :  */
    1268             : void
    1269      112411 : SystemBase::copyPreviousNonlinearSolutions()
    1270             : {
    1271             :   const auto states =
    1272      112411 :       _solution_states[static_cast<unsigned short>(Moose::SolutionIterationType::Nonlinear)].size();
    1273      112411 :   if (states > 1)
    1274         400 :     for (unsigned int i = states - 1; i > 0; --i)
    1275         400 :       solutionState(i, Moose::SolutionIterationType::Nonlinear) =
    1276         200 :           solutionState(i - 1, Moose::SolutionIterationType::Nonlinear);
    1277             : 
    1278      112411 :   if (solutionPreviousNewton())
    1279         200 :     *solutionPreviousNewton() = *currentSolution();
    1280      112411 : }
    1281             : 
    1282             : /**
    1283             :  * Shifts the solutions backwards in time
    1284             :  */
    1285             : void
    1286      684478 : SystemBase::copyOldSolutions()
    1287             : {
    1288             :   // copy the solutions backward: current->old, old->older
    1289             :   const auto states =
    1290      684478 :       _solution_states[static_cast<unsigned short>(Moose::SolutionIterationType::Time)].size();
    1291      684478 :   if (states > 1)
    1292     1023938 :     for (unsigned int i = states - 1; i > 0; --i)
    1293      526256 :       solutionState(i) = solutionState(i - 1);
    1294             : 
    1295      684478 :   if (solutionUDotOld())
    1296       11496 :     *solutionUDotOld() = *solutionUDot();
    1297      684478 :   if (solutionUDotDotOld())
    1298       11496 :     *solutionUDotDotOld() = *solutionUDotDot();
    1299      684478 : }
    1300             : 
    1301             : void
    1302      665748 : SystemBase::copyPreviousFixedPointSolutions()
    1303             : {
    1304             :   const auto n_states =
    1305      665748 :       _solution_states[static_cast<unsigned short>(Moose::SolutionIterationType::FixedPoint)]
    1306      665748 :           .size();
    1307      665748 :   if (n_states > 1)
    1308       91958 :     for (unsigned int i = n_states - 1; i > 0; --i)
    1309       91958 :       solutionState(i, Moose::SolutionIterationType::FixedPoint) =
    1310       45979 :           solutionState(i - 1, Moose::SolutionIterationType::FixedPoint);
    1311      665748 : }
    1312             : 
    1313             : /**
    1314             :  * Restore current solutions (call after your solve failed)
    1315             :  */
    1316             : void
    1317       10652 : SystemBase::restoreSolutions()
    1318             : {
    1319       10652 :   if (!hasSolutionState(1))
    1320           0 :     mooseError("Cannot restore solutions without old solution");
    1321             : 
    1322       10652 :   *(const_cast<NumericVector<Number> *&>(currentSolution())) = solutionOld();
    1323       10652 :   solution() = solutionOld();
    1324       10652 :   if (solutionUDotOld())
    1325          22 :     *solutionUDot() = *solutionUDotOld();
    1326       10652 :   if (solutionUDotDotOld())
    1327          22 :     *solutionUDotDot() = *solutionUDotDotOld();
    1328       10652 :   if (solutionPreviousNewton())
    1329           2 :     *solutionPreviousNewton() = solutionOld();
    1330       10652 :   system().update();
    1331       10652 : }
    1332             : 
    1333             : void
    1334         460 : SystemBase::removeVector(const std::string & name)
    1335             : {
    1336         460 :   system().remove_vector(name);
    1337         460 : }
    1338             : 
    1339             : const std::string &
    1340      458133 : SystemBase::name() const
    1341             : {
    1342      458133 :   return system().name();
    1343             : }
    1344             : 
    1345             : NumericVector<Number> *
    1346      124377 : SystemBase::solutionPreviousNewton()
    1347             : {
    1348      124377 :   if (hasVector(Moose::PREVIOUS_NL_SOLUTION_TAG))
    1349        1516 :     return &getVector(Moose::PREVIOUS_NL_SOLUTION_TAG);
    1350             :   else
    1351      122861 :     return nullptr;
    1352             : }
    1353             : 
    1354             : const NumericVector<Number> *
    1355           0 : SystemBase::solutionPreviousNewton() const
    1356             : {
    1357           0 :   if (hasVector(Moose::PREVIOUS_NL_SOLUTION_TAG))
    1358           0 :     return &getVector(Moose::PREVIOUS_NL_SOLUTION_TAG);
    1359             :   else
    1360           0 :     return nullptr;
    1361             : }
    1362             : 
    1363             : void
    1364      126267 : SystemBase::initSolutionState()
    1365             : {
    1366             :   // Default is the current solution
    1367      126267 :   unsigned int state = 0;
    1368             : 
    1369             :   // Add additional states as required by the variable states requested
    1370      292288 :   for (const auto & var : getVariables(/* tid = */ 0))
    1371      166021 :     state = std::max(state, var->oldestSolutionStateRequested());
    1372      129467 :   for (const auto & var : getScalarVariables(/* tid = */ 0))
    1373        3200 :     state = std::max(state, var->oldestSolutionStateRequested());
    1374             : 
    1375      126267 :   needSolutionState(state, Moose::SolutionIterationType::Time);
    1376             : 
    1377      126267 :   _solution_states_initialized = true;
    1378      126267 : }
    1379             : 
    1380             : TagName
    1381       65274 : SystemBase::oldSolutionStateVectorName(const unsigned int state,
    1382             :                                        const Moose::SolutionIterationType iteration_type) const
    1383             : {
    1384             :   mooseAssert(state != 0, "Not an old state");
    1385             : 
    1386       65274 :   if (iteration_type == Moose::SolutionIterationType::Time)
    1387             :   {
    1388       64222 :     if (state == 1)
    1389       62736 :       return Moose::OLD_SOLUTION_TAG;
    1390        1486 :     else if (state == 2)
    1391        1486 :       return Moose::OLDER_SOLUTION_TAG;
    1392             :   }
    1393        1052 :   else if (iteration_type == Moose::SolutionIterationType::Nonlinear && state == 1)
    1394         214 :     return Moose::PREVIOUS_NL_SOLUTION_TAG;
    1395         838 :   else if (iteration_type == Moose::SolutionIterationType::FixedPoint && state == 1)
    1396         838 :     return Moose::PREVIOUS_FP_SOLUTION_TAG;
    1397             : 
    1398           0 :   return "solution_state_" + std::to_string(state) + "_" + Moose::stringify(iteration_type);
    1399             : }
    1400             : 
    1401             : const NumericVector<Number> &
    1402   166820198 : SystemBase::solutionState(const unsigned int state,
    1403             :                           const Moose::SolutionIterationType iteration_type) const
    1404             : {
    1405   166820198 :   if (!hasSolutionState(state, iteration_type))
    1406           0 :     mooseError("For iteration type '",
    1407           0 :                Moose::stringify(iteration_type),
    1408             :                "': solution state ",
    1409             :                state,
    1410             :                " was requested in ",
    1411           0 :                name(),
    1412             :                " but only up to state ",
    1413           0 :                (_solution_states[static_cast<unsigned short>(iteration_type)].size() == 0)
    1414           0 :                    ? 0
    1415           0 :                    : _solution_states[static_cast<unsigned short>(iteration_type)].size() - 1,
    1416             :                " is available.");
    1417             : 
    1418   166820198 :   const auto & solution_states = _solution_states[static_cast<unsigned short>(iteration_type)];
    1419             : 
    1420   166820198 :   if (state == 0)
    1421             :     mooseAssert(solution_states[0] == &solutionInternal(), "Inconsistent current solution");
    1422             :   else
    1423             :     mooseAssert(solution_states[state] ==
    1424             :                     &getVector(oldSolutionStateVectorName(state, iteration_type)),
    1425             :                 "Inconsistent solution state");
    1426             : 
    1427   166820198 :   return *solution_states[state];
    1428             : }
    1429             : 
    1430             : NumericVector<Number> &
    1431    62195316 : SystemBase::solutionState(const unsigned int state,
    1432             :                           const Moose::SolutionIterationType iteration_type)
    1433             : {
    1434    62195316 :   if (!hasSolutionState(state, iteration_type))
    1435       71142 :     needSolutionState(state, iteration_type);
    1436    62195316 :   return *_solution_states[static_cast<unsigned short>(iteration_type)][state];
    1437             : }
    1438             : 
    1439             : libMesh::ParallelType
    1440        1254 : SystemBase::solutionStateParallelType(const unsigned int state,
    1441             :                                       const Moose::SolutionIterationType iteration_type) const
    1442             : {
    1443        1254 :   if (!hasSolutionState(state, iteration_type))
    1444           0 :     mooseError("solutionStateParallelType() may only be called if the solution state exists.");
    1445             : 
    1446        1254 :   return _solution_states[static_cast<unsigned short>(iteration_type)][state]->type();
    1447             : }
    1448             : 
    1449             : void
    1450      215887 : SystemBase::needSolutionState(const unsigned int state,
    1451             :                               const Moose::SolutionIterationType iteration_type,
    1452             :                               const libMesh::ParallelType parallel_type)
    1453             : {
    1454             :   libmesh_parallel_only(this->comm());
    1455             :   mooseAssert(!Threads::in_threads,
    1456             :               "This routine is not thread-safe. Request the solution state before using it in "
    1457             :               "a threaded region.");
    1458             : 
    1459      215887 :   if (hasSolutionState(state, iteration_type))
    1460       90018 :     return;
    1461             : 
    1462      125869 :   auto & solution_states = _solution_states[static_cast<unsigned short>(iteration_type)];
    1463      125869 :   solution_states.resize(state + 1);
    1464             : 
    1465             :   // The 0-th (current) solution state is owned by libMesh
    1466      125869 :   if (!solution_states[0])
    1467      124527 :     solution_states[0] = &solutionInternal();
    1468             :   else
    1469             :     mooseAssert(solution_states[0] == &solutionInternal(), "Inconsistent current solution");
    1470             : 
    1471             :   // We will manually add all states past current
    1472      192397 :   for (unsigned int i = 1; i <= state; ++i)
    1473       66528 :     if (!solution_states[i])
    1474             :     {
    1475       65274 :       auto tag = _subproblem.addVectorTag(oldSolutionStateVectorName(i, iteration_type),
    1476             :                                           Moose::VECTOR_TAG_SOLUTION);
    1477       65274 :       solution_states[i] = &addVector(tag, true, parallel_type);
    1478             :     }
    1479             :     else
    1480             :     {
    1481             :       // If the existing parallel type is PARALLEL and GHOSTED is now requested,
    1482             :       // this would require an upgrade, which is risky if anybody has already
    1483             :       // stored a pointer to the existing vector, since the upgrade would create
    1484             :       // a new vector and make that pointer null. If the existing parallel type
    1485             :       // is GHOSTED and PARALLEL is now requested, we don't need to do anything.
    1486        1254 :       if (parallel_type == GHOSTED && solutionStateParallelType(i, iteration_type) == PARALLEL)
    1487           0 :         mooseError("The solution state has already been declared as PARALLEL");
    1488             : 
    1489             :       mooseAssert(solution_states[i] == &getVector(oldSolutionStateVectorName(i, iteration_type)),
    1490             :                   "Inconsistent solution state");
    1491             :     }
    1492             : }
    1493             : 
    1494             : void
    1495         715 : SystemBase::applyScalingFactors(const std::vector<Real> & inverse_scaling_factors)
    1496             : {
    1497        1500 :   for (MooseIndex(_vars) thread = 0; thread < _vars.size(); ++thread)
    1498             :   {
    1499         785 :     auto & field_variables = _vars[thread].fieldVariables();
    1500        1977 :     for (MooseIndex(field_variables) i = 0, p = 0; i < field_variables.size(); ++i)
    1501             :     {
    1502        1192 :       auto factors = field_variables[i]->arrayScalingFactor();
    1503        2395 :       for (unsigned int j = 0; j < field_variables[i]->count(); ++j, ++p)
    1504        1203 :         factors[j] /= inverse_scaling_factors[p];
    1505             : 
    1506        1192 :       field_variables[i]->scalingFactor(factors);
    1507        1192 :     }
    1508             : 
    1509         785 :     auto offset = field_variables.size();
    1510             : 
    1511         785 :     auto & scalar_variables = _vars[thread].scalars();
    1512         909 :     for (MooseIndex(scalar_variables) i = 0; i < scalar_variables.size(); ++i)
    1513         372 :       scalar_variables[i]->scalingFactor(
    1514         124 :           {1. / inverse_scaling_factors[offset + i] * scalar_variables[i]->scalingFactor()});
    1515             : 
    1516         785 :     if (thread == 0 && _verbose)
    1517             :     {
    1518         286 :       _console << "Automatic scaling factors:\n";
    1519         286 :       auto original_flags = _console.flags();
    1520         286 :       auto original_precision = _console.precision();
    1521         286 :       _console.unsetf(std::ios_base::floatfield);
    1522         286 :       _console.precision(6);
    1523             : 
    1524         738 :       for (const auto & field_variable : field_variables)
    1525             :       {
    1526         452 :         const auto & factors = field_variable->arrayScalingFactor();
    1527         452 :         _console << "  " << field_variable->name() << ":";
    1528         914 :         for (const auto i : make_range(field_variable->count()))
    1529         462 :           _console << " " << factors[i];
    1530         452 :         _console << "\n";
    1531             :       }
    1532         382 :       for (const auto & scalar_variable : scalar_variables)
    1533         192 :         _console << "  " << scalar_variable->name() << ": " << scalar_variable->scalingFactor()
    1534          96 :                  << "\n";
    1535         286 :       _console << "\n" << std::endl;
    1536             : 
    1537             :       // restore state
    1538         286 :       _console.flags(original_flags);
    1539         286 :       _console.precision(original_precision);
    1540             :     }
    1541             :   }
    1542         715 : }
    1543             : 
    1544             : void
    1545         363 : SystemBase::addScalingVector()
    1546             : {
    1547         363 :   addVector("scaling_factors", /*project=*/false, libMesh::ParallelType::GHOSTED);
    1548         363 :   _subproblem.hasScalingVector(number());
    1549         363 : }
    1550             : 
    1551             : bool
    1552    78662077 : SystemBase::computingScalingJacobian() const
    1553             : {
    1554    78662077 :   return _subproblem.computingScalingJacobian();
    1555             : }
    1556             : 
    1557             : void
    1558      125633 : SystemBase::initialSetup()
    1559             : {
    1560      262781 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    1561      137148 :     _vars[tid].initialSetup();
    1562             : 
    1563             :   // If we need raw gradients, we initialize them here.
    1564      125633 :   bool gradient_storage_initialized = false;
    1565      291209 :   for (const auto & field_var : _vars[0].fieldVariables())
    1566      165576 :     if (!gradient_storage_initialized && field_var->needsGradientVectorStorage())
    1567             :     {
    1568         979 :       _raw_grad_container.clear();
    1569        2542 :       for (const auto i : make_range(this->_mesh.dimension()))
    1570             :       {
    1571        1563 :         libmesh_ignore(i);
    1572        1563 :         _raw_grad_container.push_back(currentSolution()->zero_clone());
    1573             :       }
    1574             :     }
    1575      125633 : }
    1576             : 
    1577             : void
    1578      641225 : SystemBase::timestepSetup()
    1579             : {
    1580     1339155 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    1581      697930 :     _vars[tid].timestepSetup();
    1582      641225 : }
    1583             : 
    1584             : void
    1585     4134900 : SystemBase::customSetup(const ExecFlagType & exec_type)
    1586             : {
    1587     8639522 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    1588     4504622 :     _vars[tid].customSetup(exec_type);
    1589     4134900 : }
    1590             : 
    1591             : void
    1592     6188103 : SystemBase::subdomainSetup()
    1593             : {
    1594    13309515 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    1595     7121412 :     _vars[tid].subdomainSetup();
    1596     6188103 : }
    1597             : 
    1598             : void
    1599     6961449 : SystemBase::residualSetup()
    1600             : {
    1601    14547321 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    1602     7585872 :     _vars[tid].residualSetup();
    1603     6961449 : }
    1604             : 
    1605             : void
    1606     1107868 : SystemBase::jacobianSetup()
    1607             : {
    1608     2317352 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    1609     1209484 :     _vars[tid].jacobianSetup();
    1610     1107868 : }
    1611             : 
    1612             : void
    1613      772096 : SystemBase::clearAllDofIndices()
    1614             : {
    1615     1611948 :   for (auto & var_warehouse : _vars)
    1616      839852 :     var_warehouse.clearAllDofIndices();
    1617      772096 : }
    1618             : 
    1619             : void
    1620    15411218 : SystemBase::setActiveVariableCoupleableVectorTags(const std::set<TagID> & vtags, THREAD_ID tid)
    1621             : {
    1622    15411218 :   _vars[tid].setActiveVariableCoupleableVectorTags(vtags);
    1623    15411218 : }
    1624             : 
    1625             : void
    1626      112062 : SystemBase::setActiveScalarVariableCoupleableVectorTags(const std::set<TagID> & vtags,
    1627             :                                                         THREAD_ID tid)
    1628             : {
    1629      112062 :   _vars[tid].setActiveScalarVariableCoupleableVectorTags(vtags);
    1630      112062 : }
    1631             : 
    1632             : void
    1633       62506 : SystemBase::addDotVectors()
    1634             : {
    1635       62506 :   if (_fe_problem.uDotRequested())
    1636      125012 :     _u_dot = &addVector("u_dot", true, GHOSTED);
    1637       62506 :   if (_fe_problem.uDotOldRequested())
    1638         656 :     _u_dot_old = &addVector("u_dot_old", true, GHOSTED);
    1639       62506 :   if (_fe_problem.uDotDotRequested())
    1640         656 :     _u_dotdot = &addVector("u_dotdot", true, GHOSTED);
    1641       62506 :   if (_fe_problem.uDotDotOldRequested())
    1642         656 :     _u_dotdot_old = &addVector("u_dotdot_old", true, GHOSTED);
    1643       62506 : }
    1644             : 
    1645             : NumericVector<Number> &
    1646        1140 : SystemBase::serializedSolution()
    1647             : {
    1648        1140 :   if (!_serialized_solution.get())
    1649             :   {
    1650         113 :     _serialized_solution = NumericVector<Number>::build(_communicator);
    1651         113 :     _serialized_solution->init(system().n_dofs(), false, SERIAL);
    1652             :   }
    1653             : 
    1654        1140 :   return *_serialized_solution;
    1655             : }
    1656             : 
    1657             : void
    1658       62532 : SystemBase::addTimeIntegrator(const std::string & type,
    1659             :                               const std::string & name,
    1660             :                               InputParameters & parameters)
    1661             : {
    1662      125064 :   parameters.set<SystemBase *>("_sys") = this;
    1663       62532 :   _time_integrators.push_back(_factory.create<TimeIntegrator>(type, name, parameters));
    1664       62532 : }
    1665             : 
    1666             : void
    1667        3816 : SystemBase::copyTimeIntegrators(const SystemBase & other_sys)
    1668             : {
    1669        3816 :   _time_integrators = other_sys._time_integrators;
    1670        3816 : }
    1671             : 
    1672             : const TimeIntegrator *
    1673      739061 : SystemBase::queryTimeIntegrator(const unsigned int var_num) const
    1674             : {
    1675      740021 :   for (auto & ti : _time_integrators)
    1676      471242 :     if (ti->integratesVar(var_num))
    1677      470282 :       return ti.get();
    1678             : 
    1679      268779 :   return nullptr;
    1680             : }
    1681             : 
    1682             : const TimeIntegrator &
    1683          92 : SystemBase::getTimeIntegrator(const unsigned int var_num) const
    1684             : {
    1685          92 :   const auto * const ti = queryTimeIntegrator(var_num);
    1686             : 
    1687          92 :   if (ti)
    1688          92 :     return *ti;
    1689             :   else
    1690           0 :     mooseError("No time integrator found that integrates variable number ",
    1691           0 :                std::to_string(var_num));
    1692             : }
    1693             : 
    1694             : const std::vector<std::shared_ptr<TimeIntegrator>> &
    1695      587636 : SystemBase::getTimeIntegrators()
    1696             : {
    1697      587636 :   return _time_integrators;
    1698             : }
    1699             : 
    1700             : const Number &
    1701  1275643343 : SystemBase::duDotDu(const unsigned int var_num) const
    1702             : {
    1703  1275643343 :   return _du_dot_du[var_num];
    1704             : }
    1705             : 
    1706             : const std::set<SubdomainID> &
    1707         363 : SystemBase::getSubdomainsForVar(const std::string & var_name) const
    1708             : {
    1709         363 :   return getSubdomainsForVar(getVariable(0, var_name).number());
    1710             : }
    1711             : 
    1712             : std::string
    1713       77655 : SystemBase::prefix() const
    1714             : {
    1715      231181 :   return system().prefix_with_name() ? system().prefix() : "";
    1716             : }
    1717             : 
    1718             : void
    1719      125289 : SystemBase::sizeVariableMatrixData()
    1720             : {
    1721      262713 :   for (const auto & warehouse : _vars)
    1722      275818 :     for (const auto & [var_num, var_ptr] : warehouse.numberToVariableMap())
    1723      138394 :       var_ptr->sizeMatrixTagData();
    1724      125289 : }
    1725             : 
    1726             : template MooseVariableFE<Real> & SystemBase::getFieldVariable<Real>(THREAD_ID tid,
    1727             :                                                                     const std::string & var_name);
    1728             : 
    1729             : template MooseVariableFE<RealVectorValue> &
    1730             : SystemBase::getFieldVariable<RealVectorValue>(THREAD_ID tid, const std::string & var_name);
    1731             : 
    1732             : template MooseVariableFE<RealEigenVector> &
    1733             : SystemBase::getFieldVariable<RealEigenVector>(THREAD_ID tid, const std::string & var_name);
    1734             : 
    1735             : template MooseVariableFE<Real> & SystemBase::getFieldVariable<Real>(THREAD_ID tid,
    1736             :                                                                     unsigned int var_number);
    1737             : 
    1738             : template MooseVariableFE<RealVectorValue> &
    1739             : SystemBase::getFieldVariable<RealVectorValue>(THREAD_ID tid, unsigned int var_number);
    1740             : 
    1741             : template MooseVariableFE<RealEigenVector> &
    1742             : SystemBase::getFieldVariable<RealEigenVector>(THREAD_ID tid, unsigned int var_number);
    1743             : 
    1744             : template MooseVariableField<Real> &
    1745             : SystemBase::getActualFieldVariable<Real>(THREAD_ID tid, const std::string & var_name);
    1746             : 
    1747             : template MooseVariableField<RealVectorValue> &
    1748             : SystemBase::getActualFieldVariable<RealVectorValue>(THREAD_ID tid, const std::string & var_name);
    1749             : 
    1750             : template MooseVariableField<RealEigenVector> &
    1751             : SystemBase::getActualFieldVariable<RealEigenVector>(THREAD_ID tid, const std::string & var_name);
    1752             : 
    1753             : template MooseVariableField<Real> &
    1754             : SystemBase::getActualFieldVariable<Real>(THREAD_ID tid, unsigned int var_number);
    1755             : 
    1756             : template MooseVariableField<RealVectorValue> &
    1757             : SystemBase::getActualFieldVariable<RealVectorValue>(THREAD_ID tid, unsigned int var_number);
    1758             : 
    1759             : template MooseVariableField<RealEigenVector> &
    1760             : SystemBase::getActualFieldVariable<RealEigenVector>(THREAD_ID tid, unsigned int var_number);
    1761             : 
    1762             : template MooseVariableFV<Real> & SystemBase::getFVVariable<Real>(THREAD_ID tid,
    1763             :                                                                  const std::string & var_name);

Generated by: LCOV version 1.14