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

Generated by: LCOV version 1.14