LCOV - code coverage report
Current view: top level - src/problems - FEProblemBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 863ef6 Lines: 4160 4803 86.6 %
Date: 2025-10-15 18:16:15 Functions: 359 405 88.6 %
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             : #ifdef MOOSE_KOKKOS_ENABLED
      11             : #include "KokkosMaterialPropertyStorage.h"
      12             : #endif
      13             : 
      14             : #include "FEProblemBase.h"
      15             : #include "AuxiliarySystem.h"
      16             : #include "MaterialPropertyStorage.h"
      17             : #include "MooseEnum.h"
      18             : #include "Factory.h"
      19             : #include "MooseUtils.h"
      20             : #include "DisplacedProblem.h"
      21             : #include "SystemBase.h"
      22             : #include "MaterialData.h"
      23             : #include "ComputeUserObjectsThread.h"
      24             : #include "ComputeNodalUserObjectsThread.h"
      25             : #include "ComputeThreadedGeneralUserObjectsThread.h"
      26             : #include "ComputeMaterialsObjectThread.h"
      27             : #include "ProjectMaterialProperties.h"
      28             : #include "ComputeIndicatorThread.h"
      29             : #include "ComputeMarkerThread.h"
      30             : #include "ComputeInitialConditionThread.h"
      31             : #include "ComputeFVInitialConditionThread.h"
      32             : #include "ComputeBoundaryInitialConditionThread.h"
      33             : #include "MaxQpsThread.h"
      34             : #include "ActionWarehouse.h"
      35             : #include "Conversion.h"
      36             : #include "Material.h"
      37             : #include "FunctorMaterial.h"
      38             : #include "ConstantIC.h"
      39             : #include "Parser.h"
      40             : #include "ElementH1Error.h"
      41             : #include "Function.h"
      42             : #include "Convergence.h"
      43             : #include "NonlinearSystem.h"
      44             : #include "LinearSystem.h"
      45             : #include "SolverSystem.h"
      46             : #include "Distribution.h"
      47             : #include "Sampler.h"
      48             : #include "PetscSupport.h"
      49             : #include "RandomInterface.h"
      50             : #include "RandomData.h"
      51             : #include "MooseEigenSystem.h"
      52             : #include "MooseParsedFunction.h"
      53             : #include "MeshChangedInterface.h"
      54             : #include "MeshDisplacedInterface.h"
      55             : #include "ComputeJacobianBlocksThread.h"
      56             : #include "ScalarInitialCondition.h"
      57             : #include "FVInitialConditionTempl.h"
      58             : #include "ElementPostprocessor.h"
      59             : #include "NodalPostprocessor.h"
      60             : #include "SidePostprocessor.h"
      61             : #include "InternalSidePostprocessor.h"
      62             : #include "InterfacePostprocessor.h"
      63             : #include "GeneralPostprocessor.h"
      64             : #include "ElementVectorPostprocessor.h"
      65             : #include "NodalVectorPostprocessor.h"
      66             : #include "SideVectorPostprocessor.h"
      67             : #include "InternalSideVectorPostprocessor.h"
      68             : #include "GeneralVectorPostprocessor.h"
      69             : #include "Positions.h"
      70             : #include "Indicator.h"
      71             : #include "Marker.h"
      72             : #include "MultiApp.h"
      73             : #include "MultiAppTransfer.h"
      74             : #include "TransientMultiApp.h"
      75             : #include "ElementUserObject.h"
      76             : #include "DomainUserObject.h"
      77             : #include "NodalUserObject.h"
      78             : #include "SideUserObject.h"
      79             : #include "InternalSideUserObject.h"
      80             : #include "InterfaceUserObject.h"
      81             : #include "GeneralUserObject.h"
      82             : #include "ThreadedGeneralUserObject.h"
      83             : #include "InternalSideIndicatorBase.h"
      84             : #include "Transfer.h"
      85             : #include "MultiAppTransfer.h"
      86             : #include "MultiMooseEnum.h"
      87             : #include "Predictor.h"
      88             : #include "Assembly.h"
      89             : #include "Control.h"
      90             : #include "XFEMInterface.h"
      91             : #include "ConsoleUtils.h"
      92             : #include "NonlocalKernel.h"
      93             : #include "NonlocalIntegratedBC.h"
      94             : #include "ShapeElementUserObject.h"
      95             : #include "ShapeSideUserObject.h"
      96             : #include "MooseVariableFE.h"
      97             : #include "MooseVariableScalar.h"
      98             : #include "InputParameterWarehouse.h"
      99             : #include "TimeIntegrator.h"
     100             : #include "LineSearch.h"
     101             : #include "FloatingPointExceptionGuard.h"
     102             : #include "MaxVarNDofsPerElem.h"
     103             : #include "MaxVarNDofsPerNode.h"
     104             : #include "FVKernel.h"
     105             : #include "LinearFVKernel.h"
     106             : #include "FVTimeKernel.h"
     107             : #include "MooseVariableFV.h"
     108             : #include "MooseLinearVariableFV.h"
     109             : #include "FVBoundaryCondition.h"
     110             : #include "LinearFVBoundaryCondition.h"
     111             : #include "FVInterfaceKernel.h"
     112             : #include "Reporter.h"
     113             : #include "ADUtils.h"
     114             : #include "Executioner.h"
     115             : #include "VariadicTable.h"
     116             : #include "BoundaryNodeIntegrityCheckThread.h"
     117             : #include "BoundaryElemIntegrityCheckThread.h"
     118             : #include "NodalBCBase.h"
     119             : #include "MortarUserObject.h"
     120             : #include "MortarUserObjectThread.h"
     121             : #include "RedistributeProperties.h"
     122             : #include "Checkpoint.h"
     123             : 
     124             : #include "libmesh/exodusII_io.h"
     125             : #include "libmesh/quadrature.h"
     126             : #include "libmesh/coupling_matrix.h"
     127             : #include "libmesh/nonlinear_solver.h"
     128             : #include "libmesh/sparse_matrix.h"
     129             : #include "libmesh/string_to_enum.h"
     130             : #include "libmesh/fe_interface.h"
     131             : #include "libmesh/enum_norm_type.h"
     132             : #include "libmesh/petsc_solver_exception.h"
     133             : 
     134             : #include "metaphysicl/dualnumber.h"
     135             : 
     136             : using namespace libMesh;
     137             : 
     138             : // Anonymous namespace for helper function
     139             : namespace
     140             : {
     141             : /**
     142             :  * Method for sorting the MooseVariableFEBases based on variable numbers
     143             :  */
     144             : bool
     145          78 : sortMooseVariables(const MooseVariableFEBase * a, const MooseVariableFEBase * b)
     146             : {
     147          78 :   return a->number() < b->number();
     148             : }
     149             : } // namespace
     150             : 
     151             : Threads::spin_mutex get_function_mutex;
     152             : 
     153             : InputParameters
     154      350459 : FEProblemBase::validParams()
     155             : {
     156      350459 :   InputParameters params = SubProblem::validParams();
     157     1401836 :   params.addParam<unsigned int>("null_space_dimension", 0, "The dimension of the nullspace");
     158     1051377 :   params.addParam<unsigned int>(
     159      700918 :       "transpose_null_space_dimension", 0, "The dimension of the transpose nullspace");
     160     1051377 :   params.addParam<unsigned int>(
     161      700918 :       "near_null_space_dimension", 0, "The dimension of the near nullspace");
     162     1051377 :   params.addParam<bool>("solve",
     163      700918 :                         true,
     164             :                         "Whether or not to actually solve the Nonlinear system.  "
     165             :                         "This is handy in the case that all you want to do is "
     166             :                         "execute AuxKernels, Transfers, etc. without actually "
     167             :                         "solving anything");
     168     1051377 :   params.addParam<bool>("use_nonlinear",
     169      700918 :                         true,
     170             :                         "Determines whether to use a Nonlinear vs a "
     171             :                         "Eigenvalue system (Automatically determined based "
     172             :                         "on executioner)");
     173     1401836 :   params.addParam<bool>("error_on_jacobian_nonzero_reallocation",
     174             :                         "This causes PETSc to error if it had to reallocate memory in the Jacobian "
     175             :                         "matrix due to not having enough nonzeros");
     176     1051377 :   params.addParam<bool>("ignore_zeros_in_jacobian",
     177      700918 :                         false,
     178             :                         "Do not explicitly store zero values in "
     179             :                         "the Jacobian matrix if true");
     180     1051377 :   params.addParam<bool>("force_restart",
     181      700918 :                         false,
     182             :                         "EXPERIMENTAL: If true, a sub_app may use a "
     183             :                         "restart file instead of using of using the master "
     184             :                         "backup file");
     185     1752295 :   params.addDeprecatedParam<bool>("skip_additional_restart_data",
     186      700918 :                                   false,
     187             :                                   "True to skip additional data in equation system for restart.",
     188             :                                   "This parameter is no longer used, as we do not load additional "
     189             :                                   "vectors by default with restart");
     190     1051377 :   params.addParam<bool>("skip_nl_system_check",
     191      700918 :                         false,
     192             :                         "True to skip the NonlinearSystem check for work to do (e.g. Make sure "
     193             :                         "that there are variables to solve for).");
     194     1051377 :   params.addParam<bool>("allow_initial_conditions_with_restart",
     195      700918 :                         false,
     196             :                         "True to allow the user to specify initial conditions when restarting. "
     197             :                         "Initial conditions can override any restarted field");
     198             : 
     199      700918 :   auto coverage_check_description = [](std::string scope, std::string list_param_name)
     200             :   {
     201     1401836 :     return "Controls, if and how a " + scope +
     202             :            " subdomain coverage check is performed. "
     203             :            "With 'TRUE' or 'ON' all subdomains are checked (the default). Setting 'FALSE' or 'OFF' "
     204             :            "will disable the check for all subdomains. "
     205             :            "To exclude a predefined set of subdomains 'SKIP_LIST' is to "
     206     1401836 :            "be used, while the subdomains to skip are to be defined in the parameter '" +
     207     1401836 :            list_param_name +
     208             :            "'. To limit the check to a list of subdomains, 'ONLY_LIST' is to "
     209     2102754 :            "be used (again, using the parameter '" +
     210     1401836 :            list_param_name + "').";
     211             :   };
     212             : 
     213     1752295 :   params.addParam<std::vector<SubdomainName>>(
     214             :       "block",
     215             :       {"ANY_BLOCK_ID"},
     216             :       "List of subdomains for kernel coverage and material coverage checks. Setting this parameter "
     217             :       "is equivalent to setting 'kernel_coverage_block_list' and 'material_coverage_block_list' as "
     218             :       "well as using 'ONLY_LIST' as the coverage check mode.");
     219             : 
     220     1401836 :   MooseEnum kernel_coverage_check_modes("FALSE TRUE OFF ON SKIP_LIST ONLY_LIST", "TRUE");
     221      350459 :   params.addParam<MooseEnum>("kernel_coverage_check",
     222             :                              kernel_coverage_check_modes,
     223     1752295 :                              coverage_check_description("kernel", "kernel_coverage_block_list"));
     224     1401836 :   params.addParam<std::vector<SubdomainName>>(
     225             :       "kernel_coverage_block_list",
     226             :       {},
     227             :       "List of subdomains for kernel coverage check. The meaning of this list is controlled by the "
     228             :       "parameter 'kernel_coverage_check' (whether this is the list of subdomains to be checked, "
     229             :       "not to be checked or not taken into account).");
     230     1051377 :   params.addParam<bool>(
     231             :       "boundary_restricted_node_integrity_check",
     232      700918 :       true,
     233             :       "Set to false to disable checking of boundary restricted nodal object variable dependencies, "
     234             :       "e.g. are the variable dependencies defined on the selected boundaries?");
     235     1051377 :   params.addParam<bool>("boundary_restricted_elem_integrity_check",
     236      700918 :                         true,
     237             :                         "Set to false to disable checking of boundary restricted elemental object "
     238             :                         "variable dependencies, e.g. are the variable dependencies defined on the "
     239             :                         "selected boundaries?");
     240     1401836 :   MooseEnum material_coverage_check_modes("FALSE TRUE OFF ON SKIP_LIST ONLY_LIST", "TRUE");
     241      350459 :   params.addParam<MooseEnum>(
     242             :       "material_coverage_check",
     243             :       material_coverage_check_modes,
     244     1752295 :       coverage_check_description("material", "material_coverage_block_list"));
     245     1401836 :   params.addParam<std::vector<SubdomainName>>(
     246             :       "material_coverage_block_list",
     247             :       {},
     248             :       "List of subdomains for material coverage check. The meaning of this list is controlled by "
     249             :       "the parameter 'material_coverage_check' (whether this is the list of subdomains to be "
     250             :       "checked, not to be checked or not taken into account).");
     251             : 
     252     1051377 :   params.addParam<bool>("fv_bcs_integrity_check",
     253      700918 :                         true,
     254             :                         "Set to false to disable checking of overlapping Dirichlet and Flux BCs "
     255             :                         "and/or multiple DirichletBCs per sideset");
     256             : 
     257     1051377 :   params.addParam<bool>(
     258      700918 :       "material_dependency_check", true, "Set to false to disable material dependency check");
     259     1051377 :   params.addParam<bool>("parallel_barrier_messaging",
     260      700918 :                         false,
     261             :                         "Displays messaging from parallel "
     262             :                         "barrier notifications when executing "
     263             :                         "or transferring to/from Multiapps "
     264             :                         "(default: false)");
     265             : 
     266     1401836 :   MooseEnum verbosity("false true extra", "false");
     267     1401836 :   params.addParam<MooseEnum>("verbose_setup",
     268             :                              verbosity,
     269             :                              "Set to 'true' to have the problem report on any object created. Set "
     270             :                              "to 'extra' to also display all parameters.");
     271     1051377 :   params.addParam<bool>("verbose_multiapps",
     272      700918 :                         false,
     273             :                         "Set to True to enable verbose screen printing related to MultiApps");
     274     1051377 :   params.addParam<bool>(
     275             :       "verbose_restore",
     276      700918 :       false,
     277             :       "Set to True to enable verbose screen printing related to solution restoration");
     278             : 
     279     1401836 :   params.addParam<FileNameNoExtension>("restart_file_base",
     280             :                                        "File base name used for restart (e.g. "
     281             :                                        "<path>/<filebase> or <path>/LATEST to "
     282             :                                        "grab the latest file available)");
     283             : 
     284     1401836 :   params.addParam<std::vector<std::vector<TagName>>>(
     285             :       "extra_tag_vectors",
     286             :       {},
     287             :       "Extra vectors to add to the system that can be filled by objects which compute residuals "
     288             :       "and Jacobians (Kernels, BCs, etc.) by setting tags on them. The outer index is for which "
     289             :       "nonlinear system the extra tag vectors should be added for");
     290             : 
     291     1401836 :   params.addParam<std::vector<std::vector<TagName>>>(
     292             :       "not_zeroed_tag_vectors",
     293             :       {},
     294             :       "Extra vector tags which the sytem will not zero when other vector tags are zeroed. "
     295             :       "The outer index is for which nonlinear system the extra tag vectors should be added for");
     296             : 
     297     1401836 :   params.addParam<std::vector<std::vector<TagName>>>(
     298             :       "extra_tag_matrices",
     299             :       {},
     300             :       "Extra matrices to add to the system that can be filled "
     301             :       "by objects which compute residuals and Jacobians "
     302             :       "(Kernels, BCs, etc.) by setting tags on them. The outer index is for which "
     303             :       "nonlinear system the extra tag vectors should be added for");
     304             : 
     305     1401836 :   params.addParam<std::vector<TagName>>(
     306             :       "extra_tag_solutions",
     307             :       {},
     308             :       "Extra solution vectors to add to the system that can be used by "
     309             :       "objects for coupling variable values stored in them.");
     310             : 
     311     1051377 :   params.addParam<bool>("previous_nl_solution_required",
     312      700918 :                         false,
     313             :                         "True to indicate that this calculation requires a solution vector for "
     314             :                         "storing the previous nonlinear iteration.");
     315             : 
     316     1051377 :   params.addParam<std::vector<NonlinearSystemName>>(
     317     1401836 :       "nl_sys_names", std::vector<NonlinearSystemName>{"nl0"}, "The nonlinear system names");
     318             : 
     319     1401836 :   params.addParam<std::vector<LinearSystemName>>("linear_sys_names", {}, "The linear system names");
     320             : 
     321     1051377 :   params.addParam<bool>("check_uo_aux_state",
     322      700918 :                         false,
     323             :                         "True to turn on a check that no state presents during the evaluation of "
     324             :                         "user objects and aux kernels");
     325             : 
     326      350459 :   params.addPrivateParam<MooseMesh *>("mesh");
     327             : 
     328     1051377 :   params.declareControllable("solve");
     329             : 
     330     1051377 :   params.addParam<bool>(
     331             :       "allow_invalid_solution",
     332      700918 :       false,
     333             :       "Set to true to allow convergence even though the solution has been marked as 'invalid'");
     334     1051377 :   params.addParam<bool>("show_invalid_solution_console",
     335      700918 :                         true,
     336             :                         "Set to true to show the invalid solution occurance summary in console");
     337     1051377 :   params.addParam<bool>("immediately_print_invalid_solution",
     338      700918 :                         false,
     339             :                         "Whether or not to report invalid solution warnings at the time the "
     340             :                         "warning is produced instead of after the calculation");
     341             : 
     342     1051377 :   params.addParam<bool>(
     343             :       "identify_variable_groups_in_nl",
     344      700918 :       true,
     345             :       "Whether to identify variable groups in nonlinear systems. This affects dof ordering");
     346             : 
     347     1051377 :   params.addParam<bool>(
     348             :       "regard_general_exceptions_as_errors",
     349      700918 :       false,
     350             :       "If we catch an exception during residual/Jacobian evaluaton for which we don't have "
     351             :       "specific handling, immediately error instead of allowing the time step to be cut");
     352             : 
     353     1051377 :   params.addParam<bool>("use_hash_table_matrix_assembly",
     354      700918 :                         false,
     355             :                         "Whether to assemble matrices using hash tables instead of preallocating "
     356             :                         "matrix memory. This can be a good option if the sparsity pattern changes "
     357             :                         "throughout the course of the simulation.");
     358     1401836 :   params.addParam<bool>(
     359             :       "restore_original_nonzero_pattern",
     360             :       "Whether we should reset matrix memory for every Jacobian evaluation. This option is useful "
     361             :       "if the sparsity pattern is constantly changing and you are using hash table assembly or if "
     362             :       "you wish to continually restore the matrix to the originally preallocated sparsity pattern "
     363             :       "computed by relationship managers.");
     364             : 
     365     1401836 :   params.addParamNamesToGroup(
     366             :       "skip_nl_system_check kernel_coverage_check kernel_coverage_block_list "
     367             :       "boundary_restricted_node_integrity_check "
     368             :       "boundary_restricted_elem_integrity_check material_coverage_check "
     369             :       "material_coverage_block_list fv_bcs_integrity_check "
     370             :       "material_dependency_check check_uo_aux_state error_on_jacobian_nonzero_reallocation",
     371             :       "Simulation checks");
     372     1401836 :   params.addParamNamesToGroup("use_nonlinear previous_nl_solution_required nl_sys_names "
     373             :                               "ignore_zeros_in_jacobian identify_variable_groups_in_nl "
     374             :                               "use_hash_table_matrix_assembly restore_original_nonzero_pattern",
     375             :                               "Nonlinear system(s)");
     376     1401836 :   params.addParamNamesToGroup(
     377             :       "restart_file_base force_restart allow_initial_conditions_with_restart", "Restart");
     378     1401836 :   params.addParamNamesToGroup(
     379             :       "verbose_setup verbose_multiapps verbose_restore parallel_barrier_messaging", "Verbosity");
     380     1401836 :   params.addParamNamesToGroup(
     381             :       "null_space_dimension transpose_null_space_dimension near_null_space_dimension",
     382             :       "Null space removal");
     383     1401836 :   params.addParamNamesToGroup(
     384             :       "extra_tag_vectors extra_tag_matrices extra_tag_solutions not_zeroed_tag_vectors",
     385             :       "Contribution to tagged field data");
     386     1051377 :   params.addParamNamesToGroup(
     387             :       "allow_invalid_solution show_invalid_solution_console immediately_print_invalid_solution",
     388             :       "Solution validity control");
     389             : 
     390      700918 :   return params;
     391     1051377 : }
     392             : 
     393       64512 : FEProblemBase::FEProblemBase(const InputParameters & parameters)
     394             :   : SubProblem(parameters),
     395             :     Restartable(this, "FEProblemBase"),
     396      258048 :     _mesh(*getCheckedPointerParam<MooseMesh *>("mesh")),
     397      129024 :     _req(declareManagedRestartableDataWithContext<RestartableEquationSystems>(
     398             :         "equation_systems", nullptr, _mesh)),
     399       64512 :     _initialized(false),
     400      129024 :     _solve(getParam<bool>("solve")),
     401       64512 :     _transient(false),
     402      129024 :     _time(declareRestartableData<Real>("time")),
     403      129024 :     _time_old(declareRestartableData<Real>("time_old")),
     404      129024 :     _t_step(declareRecoverableData<int>("t_step")),
     405      129024 :     _dt(declareRestartableData<Real>("dt")),
     406      129024 :     _dt_old(declareRestartableData<Real>("dt_old")),
     407       64512 :     _need_to_add_default_nonlinear_convergence(false),
     408       64512 :     _need_to_add_default_multiapp_fixed_point_convergence(false),
     409       64512 :     _need_to_add_default_steady_state_convergence(false),
     410      129024 :     _linear_sys_names(getParam<std::vector<LinearSystemName>>("linear_sys_names")),
     411       64512 :     _num_linear_sys(_linear_sys_names.size()),
     412      129024 :     _linear_systems(_num_linear_sys, nullptr),
     413       64512 :     _current_linear_sys(nullptr),
     414      129024 :     _using_default_nl(!isParamSetByUser("nl_sys_names")),
     415      190982 :     _nl_sys_names(!_using_default_nl || (_using_default_nl && !_linear_sys_names.size())
     416       64512 :                       ? getParam<std::vector<NonlinearSystemName>>("nl_sys_names")
     417             :                       : std::vector<NonlinearSystemName>()),
     418       64512 :     _num_nl_sys(_nl_sys_names.size()),
     419      129024 :     _nl(_num_nl_sys, nullptr),
     420       64512 :     _current_nl_sys(nullptr),
     421      129024 :     _solver_systems(_num_nl_sys + _num_linear_sys, nullptr),
     422       64512 :     _aux(nullptr),
     423       64512 :     _coupling(Moose::COUPLING_DIAG),
     424             : #ifdef MOOSE_KOKKOS_ENABLED
     425       42995 :     _kokkos_assembly(*this),
     426             : #endif
     427       64512 :     _mesh_divisions(/*threaded=*/true),
     428       64512 :     _material_props(declareRestartableDataWithContext<MaterialPropertyStorage>(
     429       64512 :         "material_props", &_mesh, _material_prop_registry, *this)),
     430       64512 :     _bnd_material_props(declareRestartableDataWithContext<MaterialPropertyStorage>(
     431       64512 :         "bnd_material_props", &_mesh, _material_prop_registry, *this)),
     432       64512 :     _neighbor_material_props(declareRestartableDataWithContext<MaterialPropertyStorage>(
     433       64512 :         "neighbor_material_props", &_mesh, _material_prop_registry, *this)),
     434             : #ifdef MOOSE_KOKKOS_ENABLED
     435       42995 :     _kokkos_material_props(
     436       42995 :         declareRestartableDataWithContext<Moose::Kokkos::MaterialPropertyStorage>(
     437       42995 :             "kokkos_material_props", &_mesh, _material_prop_registry, *this)),
     438       42995 :     _kokkos_bnd_material_props(
     439       42995 :         declareRestartableDataWithContext<Moose::Kokkos::MaterialPropertyStorage>(
     440       42995 :             "kokkos_bnd_material_props", &_mesh, _material_prop_registry, *this)),
     441       42995 :     _kokkos_neighbor_material_props(
     442       42995 :         declareRestartableDataWithContext<Moose::Kokkos::MaterialPropertyStorage>(
     443       42995 :             "kokkos_neighbor_material_props", &_mesh, _material_prop_registry, *this)),
     444             : #endif
     445       64512 :     _reporter_data(_app),
     446             :     // TODO: delete the following line after apps have been updated to not call getUserObjects
     447       64512 :     _all_user_objects(_app.getExecuteOnEnum()),
     448       64512 :     _multi_apps(_app.getExecuteOnEnum()),
     449       64512 :     _transient_multi_apps(_app.getExecuteOnEnum()),
     450       64512 :     _transfers(_app.getExecuteOnEnum(), /*threaded=*/false),
     451       64512 :     _to_multi_app_transfers(_app.getExecuteOnEnum(), /*threaded=*/false),
     452       64512 :     _from_multi_app_transfers(_app.getExecuteOnEnum(), /*threaded=*/false),
     453       64512 :     _between_multi_app_transfers(_app.getExecuteOnEnum(), /*threaded=*/false),
     454             : #ifdef LIBMESH_ENABLE_AMR
     455       64512 :     _adaptivity(*this),
     456       64512 :     _cycles_completed(0),
     457             : #endif
     458       64512 :     _displaced_mesh(nullptr),
     459       64512 :     _geometric_search_data(*this, _mesh),
     460       64512 :     _mortar_data(*this),
     461       64512 :     _reinit_displaced_elem(false),
     462       64512 :     _reinit_displaced_face(false),
     463       64512 :     _reinit_displaced_neighbor(false),
     464       64512 :     _input_file_saved(false),
     465       64512 :     _has_dampers(false),
     466       64512 :     _has_constraints(false),
     467       64512 :     _snesmf_reuse_base(true),
     468       64512 :     _skip_exception_check(false),
     469       64512 :     _snesmf_reuse_base_set_by_user(false),
     470       64512 :     _has_initialized_stateful(false),
     471       64512 :     _const_jacobian(false),
     472       64512 :     _has_jacobian(false),
     473       64512 :     _needs_old_newton_iter(false),
     474      129024 :     _previous_nl_solution_required(getParam<bool>("previous_nl_solution_required")),
     475       64512 :     _has_nonlocal_coupling(false),
     476       64512 :     _calculate_jacobian_in_uo(false),
     477       64512 :     _kernel_coverage_check(
     478      129024 :         getParam<MooseEnum>("kernel_coverage_check").getEnum<CoverageCheckMode>()),
     479      129024 :     _kernel_coverage_blocks(getParam<std::vector<SubdomainName>>("kernel_coverage_block_list")),
     480       64512 :     _boundary_restricted_node_integrity_check(
     481      129024 :         getParam<bool>("boundary_restricted_node_integrity_check")),
     482       64512 :     _boundary_restricted_elem_integrity_check(
     483      129024 :         getParam<bool>("boundary_restricted_elem_integrity_check")),
     484       64512 :     _material_coverage_check(
     485      129024 :         getParam<MooseEnum>("material_coverage_check").getEnum<CoverageCheckMode>()),
     486      129024 :     _material_coverage_blocks(getParam<std::vector<SubdomainName>>("material_coverage_block_list")),
     487      129024 :     _fv_bcs_integrity_check(getParam<bool>("fv_bcs_integrity_check")),
     488      129024 :     _material_dependency_check(getParam<bool>("material_dependency_check")),
     489      129024 :     _uo_aux_state_check(getParam<bool>("check_uo_aux_state")),
     490       64512 :     _max_qps(std::numeric_limits<unsigned int>::max()),
     491       64512 :     _max_scalar_order(INVALID_ORDER),
     492       64512 :     _has_time_integrator(false),
     493       64512 :     _has_exception(false),
     494      129024 :     _parallel_barrier_messaging(getParam<bool>("parallel_barrier_messaging")),
     495      129024 :     _verbose_setup(getParam<MooseEnum>("verbose_setup")),
     496      129024 :     _verbose_multiapps(getParam<bool>("verbose_multiapps")),
     497      129024 :     _verbose_restore(getParam<bool>("verbose_restore")),
     498       64512 :     _current_execute_on_flag(EXEC_NONE),
     499       64512 :     _control_warehouse(_app.getExecuteOnEnum(), /*threaded=*/false),
     500       64512 :     _is_petsc_options_inserted(false),
     501       64512 :     _line_search(nullptr),
     502       64512 :     _using_ad_mat_props(false),
     503       64512 :     _current_ic_state(0),
     504      129024 :     _use_hash_table_matrix_assembly(getParam<bool>("use_hash_table_matrix_assembly")),
     505       64512 :     _error_on_jacobian_nonzero_reallocation(
     506      129024 :         isParamValid("error_on_jacobian_nonzero_reallocation")
     507      129630 :             ? getParam<bool>("error_on_jacobian_nonzero_reallocation")
     508       63906 :             : _app.errorOnJacobianNonzeroReallocation()),
     509      129024 :     _restore_original_nonzero_pattern(isParamValid("restore_original_nonzero_pattern")
     510      129024 :                                           ? getParam<bool>("restore_original_nonzero_pattern")
     511       64512 :                                           : _use_hash_table_matrix_assembly),
     512      129024 :     _ignore_zeros_in_jacobian(getParam<bool>("ignore_zeros_in_jacobian")),
     513       64512 :     _preserve_matrix_sparsity_pattern(true),
     514      129024 :     _force_restart(getParam<bool>("force_restart")),
     515      129024 :     _allow_ics_during_restart(getParam<bool>("allow_initial_conditions_with_restart")),
     516      129024 :     _skip_nl_system_check(getParam<bool>("skip_nl_system_check")),
     517       64512 :     _fail_next_system_convergence_check(false),
     518      129024 :     _allow_invalid_solution(getParam<bool>("allow_invalid_solution")),
     519      129024 :     _show_invalid_solution_console(getParam<bool>("show_invalid_solution_console")),
     520      129024 :     _immediately_print_invalid_solution(getParam<bool>("immediately_print_invalid_solution")),
     521       64512 :     _started_initial_setup(false),
     522       64512 :     _has_internal_edge_residual_objects(false),
     523       64512 :     _u_dot_requested(false),
     524       64512 :     _u_dotdot_requested(false),
     525       64512 :     _u_dot_old_requested(false),
     526       64512 :     _u_dotdot_old_requested(false),
     527       64512 :     _has_mortar(false),
     528       64512 :     _num_grid_steps(0),
     529       64512 :     _print_execution_on(),
     530      129024 :     _identify_variable_groups_in_nl(getParam<bool>("identify_variable_groups_in_nl")),
     531       64512 :     _regard_general_exceptions_as_errors(getParam<bool>("regard_general_exceptions_as_errors")),
     532     1225728 :     _requires_nonlocal_coupling(false)
     533             : {
     534             :   auto checkCoverageCheckConflict =
     535      129024 :       [this](const std::string & coverage_check,
     536             :              const CoverageCheckMode & coverage_check_mode,
     537             :              const std::vector<SubdomainName> & coverage_blocks) -> void
     538             :   {
     539      129024 :     if (coverage_check_mode != CoverageCheckMode::FALSE &&
     540      124266 :         coverage_check_mode != CoverageCheckMode::OFF)
     541      124245 :       if (coverage_blocks.size() > 1)
     542           0 :         if (std::find(coverage_blocks.begin(), coverage_blocks.end(), "ANY_BLOCK_ID") !=
     543           0 :             coverage_blocks.end())
     544           0 :           paramError(coverage_check,
     545             :                      "The list of blocks used for ",
     546             :                      coverage_check,
     547             :                      " cannot contain 'ANY_BLOCK_ID' along with other blocks. ");
     548      129024 :   };
     549             : 
     550       64512 :   checkCoverageCheckConflict(
     551       64512 :       "kernel_coverage_check", _kernel_coverage_check, _kernel_coverage_blocks);
     552       64512 :   checkCoverageCheckConflict(
     553       64512 :       "material_coverage_check", _material_coverage_check, _material_coverage_blocks);
     554             : 
     555             :   //  Initialize static do_derivatives member. We initialize this to true so that all the
     556             :   //  default AD things that we setup early in the simulation actually get their derivative
     557             :   //  vectors initalized. We will toggle this to false when doing residual evaluations
     558       64512 :   ADReal::do_derivatives = true;
     559             : 
     560             :   // Disable refinement/coarsening in EquationSystems::reinit because we already do this ourselves
     561       64512 :   es().disable_refine_in_reinit();
     562             : 
     563       64512 :   _solver_params.reserve(_num_nl_sys + _num_linear_sys);
     564             :   // Default constructor fine for nonlinear because it will be populated later by framework
     565             :   // executioner/solve object parameters
     566       64512 :   _solver_params.resize(_num_nl_sys);
     567      127987 :   for (const auto i : index_range(_nl_sys_names))
     568             :   {
     569       63475 :     const auto & name = _nl_sys_names[i];
     570       63475 :     _nl_sys_name_to_num[name] = i;
     571       63475 :     _solver_sys_name_to_num[name] = i;
     572       63475 :     _solver_sys_names.push_back(name);
     573             :   }
     574             : 
     575       65852 :   for (const auto i : index_range(_linear_sys_names))
     576             :   {
     577        1340 :     const auto & name = _linear_sys_names[i];
     578        1340 :     _linear_sys_name_to_num[name] = i;
     579        1340 :     _solver_sys_name_to_num[name] = i + _num_nl_sys;
     580        1340 :     _solver_sys_names.push_back(name);
     581             :     // Unlike for nonlinear these are basically dummy parameters
     582        1340 :     _solver_params.push_back(makeLinearSolverParams());
     583             :   }
     584             : 
     585       64512 :   _nonlocal_cm.resize(numSolverSystems());
     586       64512 :   _cm.resize(numSolverSystems());
     587             : 
     588       64512 :   _time = 0.0;
     589       64512 :   _time_old = 0.0;
     590       64512 :   _t_step = 0;
     591       64512 :   _dt = 0;
     592       64512 :   _dt_old = _dt;
     593             : 
     594       64512 :   unsigned int n_threads = libMesh::n_threads();
     595             : 
     596       64512 :   _real_zero.resize(n_threads, 0.);
     597       64512 :   _scalar_zero.resize(n_threads);
     598       64512 :   _zero.resize(n_threads);
     599       64512 :   _phi_zero.resize(n_threads);
     600       64512 :   _ad_zero.resize(n_threads);
     601       64512 :   _grad_zero.resize(n_threads);
     602       64512 :   _ad_grad_zero.resize(n_threads);
     603       64512 :   _grad_phi_zero.resize(n_threads);
     604       64512 :   _second_zero.resize(n_threads);
     605       64512 :   _ad_second_zero.resize(n_threads);
     606       64512 :   _second_phi_zero.resize(n_threads);
     607       64512 :   _point_zero.resize(n_threads);
     608       64512 :   _vector_zero.resize(n_threads);
     609       64512 :   _vector_curl_zero.resize(n_threads);
     610       64512 :   _uo_jacobian_moose_vars.resize(n_threads);
     611             : 
     612       64512 :   _has_active_material_properties.resize(n_threads, 0);
     613             : 
     614       64512 :   _block_mat_side_cache.resize(n_threads);
     615       64512 :   _bnd_mat_side_cache.resize(n_threads);
     616       64512 :   _interface_mat_side_cache.resize(n_threads);
     617             : 
     618      129024 :   es().parameters.set<FEProblemBase *>("_fe_problem_base") = this;
     619             : 
     620      193536 :   if (isParamValid("restart_file_base"))
     621             :   {
     622        1018 :     std::string restart_file_base = getParam<FileNameNoExtension>("restart_file_base");
     623             : 
     624             :     // This check reverts to old behavior of providing "restart_file_base=" to mean
     625             :     // don't restart... BISON currently relies on this. It could probably be removed.
     626             :     // The new MooseUtils::convertLatestCheckpoint will error out if a checkpoint file
     627             :     // is not found, which I think makes sense. Which means, without this, if you
     628             :     // set "restart_file_base=", you'll get a "No checkpoint file found" error
     629         509 :     if (restart_file_base.size())
     630             :     {
     631         509 :       restart_file_base = MooseUtils::convertLatestCheckpoint(restart_file_base);
     632         509 :       setRestartFile(restart_file_base);
     633             :     }
     634         509 :   }
     635             : 
     636             :   // // Generally speaking, the mesh is prepared for use, and consequently remote elements are deleted
     637             :   // // well before our Problem(s) are constructed. Historically, in MooseMesh we have a bunch of
     638             :   // // needs_prepare type flags that make it so we never call prepare_for_use (and consequently
     639             :   // // delete_remote_elements) again. So the below line, historically, has had no impact. HOWEVER:
     640             :   // // I've added some code in SetupMeshCompleteAction for deleting remote elements post
     641             :   // // EquationSystems::init. If I execute that code without default ghosting, then I get > 40 MOOSE
     642             :   // // test failures, so we clearly have some simulations that are not yet covered properly by
     643             :   // // relationship managers. Until that is resolved, I am going to retain default geometric ghosting
     644             :   // if (!_default_ghosting)
     645             :   //   _mesh.getMesh().remove_ghosting_functor(_mesh.getMesh().default_ghosting());
     646             : 
     647             : #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
     648             :   // Main app should hold the default database to handle system petsc options
     649       64512 :   if (!_app.isUltimateMaster())
     650       12471 :     LibmeshPetscCall(PetscOptionsCreate(&_petsc_option_data_base));
     651             : #endif
     652             : 
     653       64512 :   if (!_solve)
     654             :   {
     655             :     // If we are not solving, we do not care about seeing unused petsc options
     656       47118 :     Moose::PetscSupport::setSinglePetscOption("-options_left", "0");
     657             :     // We don't want petscSetOptions being called in solve and clearing the option that was just set
     658       15706 :     _is_petsc_options_inserted = true;
     659             :   }
     660       64512 : }
     661             : 
     662             : const MooseMesh &
     663      322586 : FEProblemBase::mesh(bool use_displaced) const
     664             : {
     665      322586 :   if (use_displaced && !_displaced_problem)
     666           0 :     mooseWarning("Displaced mesh was requested but the displaced problem does not exist. "
     667             :                  "Regular mesh will be returned");
     668      322586 :   return ((use_displaced && _displaced_problem) ? _displaced_problem->mesh() : mesh());
     669             : }
     670             : 
     671             : void
     672       64512 : FEProblemBase::createTagVectors()
     673             : {
     674             :   // add vectors and their tags to system
     675      129024 :   auto & vectors = getParam<std::vector<std::vector<TagName>>>("extra_tag_vectors");
     676       65237 :   for (const auto sys_num : index_range(vectors))
     677        1694 :     for (auto & vector : vectors[sys_num])
     678             :     {
     679         969 :       auto tag = addVectorTag(vector);
     680         969 :       _solver_systems[sys_num]->addVector(tag, false, libMesh::GHOSTED);
     681             :     }
     682             : 
     683      129024 :   auto & not_zeroed_vectors = getParam<std::vector<std::vector<TagName>>>("not_zeroed_tag_vectors");
     684       64524 :   for (const auto sys_num : index_range(not_zeroed_vectors))
     685          24 :     for (auto & vector : not_zeroed_vectors[sys_num])
     686             :     {
     687          12 :       auto tag = addVectorTag(vector);
     688          12 :       _solver_systems[sys_num]->addVector(tag, false, GHOSTED);
     689          12 :       addNotZeroedVectorTag(tag);
     690             :     }
     691       64512 : }
     692             : 
     693             : void
     694       63634 : FEProblemBase::createTagMatrices(CreateTaggedMatrixKey)
     695             : {
     696      127268 :   auto & matrices = getParam<std::vector<std::vector<TagName>>>("extra_tag_matrices");
     697       63882 :   for (const auto sys_num : index_range(matrices))
     698         692 :     for (auto & matrix : matrices[sys_num])
     699             :     {
     700         444 :       auto tag = addMatrixTag(matrix);
     701         444 :       _solver_systems[sys_num]->addMatrix(tag);
     702             :     }
     703             : 
     704      127543 :   for (auto & sys : _solver_systems)
     705       63909 :     sys->sizeVariableMatrixData();
     706       63634 :   _aux->sizeVariableMatrixData();
     707       63634 : }
     708             : 
     709             : void
     710       64512 : FEProblemBase::createTagSolutions()
     711             : {
     712      193567 :   for (auto & vector : getParam<std::vector<TagName>>("extra_tag_solutions"))
     713             :   {
     714          31 :     auto tag = addVectorTag(vector, Moose::VECTOR_TAG_SOLUTION);
     715          62 :     for (auto & sys : _solver_systems)
     716          31 :       sys->addVector(tag, false, libMesh::GHOSTED);
     717          31 :     _aux->addVector(tag, false, libMesh::GHOSTED);
     718             :   }
     719             : 
     720       64512 :   if (_previous_nl_solution_required)
     721             :   {
     722             :     // We'll populate the zeroth state of the nonlinear iterations with the current solution for
     723             :     // ease of use in doing things like copying solutions backwards. We're just storing pointers in
     724             :     // the solution states containers so populating the zeroth state does not cost us the memory of
     725             :     // a new vector
     726          94 :     needSolutionState(1, Moose::SolutionIterationType::Nonlinear);
     727             :   }
     728             : 
     729       64512 :   auto tag = addVectorTag(Moose::SOLUTION_TAG, Moose::VECTOR_TAG_SOLUTION);
     730      129327 :   for (auto & sys : _solver_systems)
     731       64815 :     sys->associateVectorToTag(*sys->system().current_local_solution.get(), tag);
     732       64512 :   _aux->associateVectorToTag(*_aux->system().current_local_solution.get(), tag);
     733       64512 : }
     734             : 
     735             : void
     736         150 : FEProblemBase::needSolutionState(unsigned int state, Moose::SolutionIterationType iteration_type)
     737             : {
     738         300 :   for (auto & sys : _solver_systems)
     739         150 :     sys->needSolutionState(state, iteration_type);
     740         150 :   _aux->needSolutionState(state, iteration_type);
     741         150 : }
     742             : 
     743             : void
     744       64512 : FEProblemBase::newAssemblyArray(std::vector<std::shared_ptr<SolverSystem>> & solver_systems)
     745             : {
     746       64512 :   unsigned int n_threads = libMesh::n_threads();
     747             : 
     748       64512 :   _assembly.resize(n_threads);
     749      135334 :   for (const auto i : make_range(n_threads))
     750             :   {
     751       70822 :     _assembly[i].resize(solver_systems.size());
     752      141971 :     for (const auto j : index_range(solver_systems))
     753       71149 :       _assembly[i][j] = std::make_unique<Assembly>(*solver_systems[j], i);
     754             :   }
     755       64512 : }
     756             : 
     757             : void
     758       62558 : FEProblemBase::initNullSpaceVectors(const InputParameters & parameters,
     759             :                                     std::vector<std::shared_ptr<NonlinearSystemBase>> & nls)
     760             : {
     761      312790 :   TIME_SECTION("initNullSpaceVectors", 5, "Initializing Null Space Vectors");
     762             : 
     763       62558 :   unsigned int dimNullSpace = parameters.get<unsigned int>("null_space_dimension");
     764             :   unsigned int dimTransposeNullSpace =
     765       62558 :       parameters.get<unsigned int>("transpose_null_space_dimension");
     766       62558 :   unsigned int dimNearNullSpace = parameters.get<unsigned int>("near_null_space_dimension");
     767       62584 :   for (unsigned int i = 0; i < dimNullSpace; ++i)
     768             :   {
     769          26 :     std::ostringstream oss;
     770          26 :     oss << "_" << i;
     771             :     // do not project, since this will be recomputed, but make it ghosted, since the near nullspace
     772             :     // builder might march over all nodes
     773          52 :     for (auto & nl : nls)
     774          26 :       nl->addVector("NullSpace" + oss.str(), false, libMesh::GHOSTED);
     775          26 :   }
     776      125116 :   _subspace_dim["NullSpace"] = dimNullSpace;
     777       62571 :   for (unsigned int i = 0; i < dimTransposeNullSpace; ++i)
     778             :   {
     779          13 :     std::ostringstream oss;
     780          13 :     oss << "_" << i;
     781             :     // do not project, since this will be recomputed, but make it ghosted, since the near nullspace
     782             :     // builder might march over all nodes
     783          26 :     for (auto & nl : nls)
     784          13 :       nl->addVector("TransposeNullSpace" + oss.str(), false, libMesh::GHOSTED);
     785          13 :   }
     786      125116 :   _subspace_dim["TransposeNullSpace"] = dimTransposeNullSpace;
     787       62558 :   for (unsigned int i = 0; i < dimNearNullSpace; ++i)
     788             :   {
     789           0 :     std::ostringstream oss;
     790           0 :     oss << "_" << i;
     791             :     // do not project, since this will be recomputed, but make it ghosted, since the near-nullspace
     792             :     // builder might march over all semilocal nodes
     793           0 :     for (auto & nl : nls)
     794           0 :       nl->addVector("NearNullSpace" + oss.str(), false, libMesh::GHOSTED);
     795           0 :   }
     796      125116 :   _subspace_dim["NearNullSpace"] = dimNearNullSpace;
     797       62558 : }
     798             : 
     799      180288 : FEProblemBase::~FEProblemBase()
     800             : {
     801             :   // Flush the Console stream, the underlying call to Console::mooseConsole
     802             :   // relies on a call to Output::checkInterval that has references to
     803             :   // _time, etc. If it is not flushed here memory problems arise if you have
     804             :   // an unflushed stream and start destructing things.
     805       60096 :   _console << std::flush;
     806             : 
     807       60096 :   unsigned int n_threads = libMesh::n_threads();
     808      125422 :   for (unsigned int i = 0; i < n_threads; i++)
     809             :   {
     810       65326 :     _zero[i].release();
     811       65326 :     _phi_zero[i].release();
     812       65326 :     _scalar_zero[i].release();
     813       65326 :     _grad_zero[i].release();
     814       65326 :     _grad_phi_zero[i].release();
     815       65326 :     _second_zero[i].release();
     816       65326 :     _second_phi_zero[i].release();
     817       65326 :     _vector_zero[i].release();
     818       65326 :     _vector_curl_zero[i].release();
     819       65326 :     _ad_zero[i].release();
     820       65326 :     _ad_grad_zero[i].release();
     821       65326 :     _ad_second_zero[i].release();
     822             :   }
     823             : 
     824             : #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
     825       60096 :   if (!_app.isUltimateMaster())
     826             :   {
     827       11081 :     auto ierr = PetscOptionsDestroy(&_petsc_option_data_base);
     828             :     // Don't throw on destruction
     829       11081 :     CHKERRABORT(this->comm().get(), ierr);
     830             :   }
     831             : #endif
     832       60096 : }
     833             : 
     834             : void
     835           0 : FEProblemBase::setCoordSystem(const std::vector<SubdomainName> & blocks,
     836             :                               const MultiMooseEnum & coord_sys)
     837             : {
     838           0 :   TIME_SECTION("setCoordSystem", 5, "Setting Coordinate System");
     839           0 :   _mesh.setCoordSystem(blocks, coord_sys);
     840           0 : }
     841             : 
     842             : void
     843           0 : FEProblemBase::setAxisymmetricCoordAxis(const MooseEnum & rz_coord_axis)
     844             : {
     845           0 :   _mesh.setAxisymmetricCoordAxis(rz_coord_axis);
     846           0 : }
     847             : 
     848             : const ConstElemRange &
     849        1457 : FEProblemBase::getEvaluableElementRange()
     850             : {
     851        1457 :   if (!_evaluable_local_elem_range)
     852             :   {
     853         688 :     std::vector<const DofMap *> dof_maps(es().n_systems());
     854        2064 :     for (const auto i : make_range(es().n_systems()))
     855             :     {
     856        1376 :       const auto & sys = es().get_system(i);
     857        1376 :       dof_maps[i] = &sys.get_dof_map();
     858             :     }
     859             :     _evaluable_local_elem_range =
     860        1376 :         std::make_unique<ConstElemRange>(_mesh.getMesh().multi_evaluable_elements_begin(dof_maps),
     861        2064 :                                          _mesh.getMesh().multi_evaluable_elements_end(dof_maps));
     862         688 :   }
     863        1457 :   return *_evaluable_local_elem_range;
     864             : }
     865             : 
     866             : const ConstElemRange &
     867         234 : FEProblemBase::getNonlinearEvaluableElementRange()
     868             : {
     869         234 :   if (!_nl_evaluable_local_elem_range)
     870             :   {
     871         234 :     std::vector<const DofMap *> dof_maps(_nl.size());
     872         468 :     for (const auto i : index_range(dof_maps))
     873         234 :       dof_maps[i] = &_nl[i]->dofMap();
     874             :     _nl_evaluable_local_elem_range =
     875         468 :         std::make_unique<ConstElemRange>(_mesh.getMesh().multi_evaluable_elements_begin(dof_maps),
     876         702 :                                          _mesh.getMesh().multi_evaluable_elements_end(dof_maps));
     877         234 :   }
     878             : 
     879         234 :   return *_nl_evaluable_local_elem_range;
     880             : }
     881             : 
     882             : void
     883       61886 : FEProblemBase::initialSetup()
     884             : {
     885      309430 :   TIME_SECTION("initialSetup", 2, "Performing Initial Setup");
     886             : 
     887       61886 :   SubProblem::initialSetup();
     888             : 
     889       61886 :   if (_app.isRecovering() + _app.isRestarting() + bool(_app.getExReaderForRestart()) > 1)
     890           0 :     mooseError("Checkpoint recovery and restart and exodus restart are all mutually exclusive.");
     891             : 
     892       61886 :   if (_skip_exception_check)
     893          10 :     mooseWarning("MOOSE may fail to catch an exception when the \"skip_exception_check\" parameter "
     894             :                  "is used. If you receive a terse MPI error during execution, remove this "
     895             :                  "parameter and rerun your simulation");
     896             : 
     897             :   // set state flag indicating that we are in or beyond initialSetup.
     898             :   // This can be used to throw errors in methods that _must_ be called at construction time.
     899       61886 :   _started_initial_setup = true;
     900       61886 :   setCurrentExecuteOnFlag(EXEC_INITIAL);
     901             : 
     902             :   // Setup the solution states (current, old, etc) in each system based on
     903             :   // its default and the states requested of each of its variables
     904      124047 :   for (const auto i : index_range(_solver_systems))
     905             :   {
     906       62161 :     _solver_systems[i]->initSolutionState();
     907       62161 :     if (getDisplacedProblem())
     908        2234 :       getDisplacedProblem()->solverSys(i).initSolutionState();
     909             :   }
     910       61886 :   _aux->initSolutionState();
     911       61886 :   if (getDisplacedProblem())
     912        2234 :     getDisplacedProblem()->auxSys().initSolutionState();
     913             : 
     914             :   // always execute to get the max number of DoF per element and node needed to initialize phi_zero
     915             :   // variables
     916       61886 :   dof_id_type global_max_var_n_dofs_per_elem = 0;
     917      124047 :   for (const auto i : index_range(_solver_systems))
     918             :   {
     919       62161 :     auto & sys = *_solver_systems[i];
     920             :     dof_id_type max_var_n_dofs_per_elem;
     921             :     dof_id_type max_var_n_dofs_per_node;
     922             :     {
     923      310805 :       TIME_SECTION("computingMaxDofs", 3, "Computing Max Dofs Per Element");
     924             : 
     925       62161 :       MaxVarNDofsPerElem mvndpe(*this, sys);
     926       62161 :       Threads::parallel_reduce(*_mesh.getActiveLocalElementRange(), mvndpe);
     927       62161 :       max_var_n_dofs_per_elem = mvndpe.max();
     928       62161 :       _communicator.max(max_var_n_dofs_per_elem);
     929             : 
     930       62161 :       MaxVarNDofsPerNode mvndpn(*this, sys);
     931       62161 :       Threads::parallel_reduce(*_mesh.getLocalNodeRange(), mvndpn);
     932       62161 :       max_var_n_dofs_per_node = mvndpn.max();
     933       62161 :       _communicator.max(max_var_n_dofs_per_node);
     934       62161 :       global_max_var_n_dofs_per_elem =
     935       62161 :           std::max(global_max_var_n_dofs_per_elem, max_var_n_dofs_per_elem);
     936       62161 :     }
     937             : 
     938             :     {
     939      310805 :       TIME_SECTION("assignMaxDofs", 5, "Assigning Maximum Dofs Per Elem");
     940             : 
     941       62161 :       sys.assignMaxVarNDofsPerElem(max_var_n_dofs_per_elem);
     942       62161 :       auto displaced_problem = getDisplacedProblem();
     943       62161 :       if (displaced_problem)
     944        2234 :         displaced_problem->solverSys(i).assignMaxVarNDofsPerElem(max_var_n_dofs_per_elem);
     945             : 
     946       62161 :       sys.assignMaxVarNDofsPerNode(max_var_n_dofs_per_node);
     947       62161 :       if (displaced_problem)
     948        2234 :         displaced_problem->solverSys(i).assignMaxVarNDofsPerNode(max_var_n_dofs_per_node);
     949       62161 :     }
     950             :   }
     951             : 
     952             :   {
     953      309430 :     TIME_SECTION("resizingVarValues", 5, "Resizing Variable Values");
     954             : 
     955      129519 :     for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
     956             :     {
     957      135266 :       _phi_zero[tid].resize(global_max_var_n_dofs_per_elem, std::vector<Real>(getMaxQps(), 0.));
     958      135266 :       _grad_phi_zero[tid].resize(global_max_var_n_dofs_per_elem,
     959      135266 :                                  std::vector<RealGradient>(getMaxQps(), RealGradient(0.)));
     960      135266 :       _second_phi_zero[tid].resize(global_max_var_n_dofs_per_elem,
     961      135266 :                                    std::vector<RealTensor>(getMaxQps(), RealTensor(0.)));
     962             :     }
     963       61886 :   }
     964             : 
     965             :   // Set up stateful material property redistribution, if we suspect
     966             :   // it may be necessary later.
     967       61886 :   addAnyRedistributers();
     968             : 
     969       61886 :   if (_app.isRestarting() || _app.isRecovering() || _force_restart)
     970             :   {
     971             :     // Only load all of the vectors if we're recovering
     972        4577 :     _req.set().setLoadAllVectors(_app.isRecovering());
     973             : 
     974             :     // This forces stateful material property loading to be an exact one-to-one match
     975        4577 :     if (_app.isRecovering())
     976             :     {
     977       15992 :       for (auto props : {&_material_props, &_bnd_material_props, &_neighbor_material_props})
     978       11994 :         props->setRecovering();
     979             : 
     980             : #ifdef MOOSE_KOKKOS_ENABLED
     981       15772 :       for (auto props :
     982       19715 :            {&_kokkos_material_props, &_kokkos_bnd_material_props, &_kokkos_neighbor_material_props})
     983       11829 :         props->setRecovering();
     984             : #endif
     985             :     }
     986             : 
     987       22885 :     TIME_SECTION("restore", 3, "Restoring from backup");
     988             : 
     989             :     // We could have a cached backup when this app is a sub-app and has been given a Backup
     990        4577 :     if (!_app.hasInitialBackup())
     991        3580 :       _app.restore(_app.restartFolderBase(_app.getRestartRecoverFileBase()), _app.isRestarting());
     992             :     else
     993         997 :       _app.restoreFromInitialBackup(_app.isRestarting());
     994             : 
     995             :     /**
     996             :      * If this is a restart run, the user may want to override the start time, which we already set
     997             :      * in the constructor. "_time" however will have been "restored" from the restart file. We need
     998             :      * to honor the original request of the developer now that the restore has been completed.
     999             :      */
    1000        4530 :     if (_app.isRestarting())
    1001             :     {
    1002         532 :       if (_app.hasStartTime())
    1003         178 :         _time = _time_old = _app.getStartTime();
    1004             :       else
    1005         354 :         _time_old = _time;
    1006             :     }
    1007        4530 :   }
    1008             :   else
    1009             :   {
    1010       57309 :     libMesh::ExodusII_IO * reader = _app.getExReaderForRestart();
    1011             : 
    1012       57309 :     if (reader)
    1013             :     {
    1014        1445 :       TIME_SECTION("copyingFromExodus", 3, "Copying Variables From Exodus");
    1015             : 
    1016         586 :       for (auto & sys : _solver_systems)
    1017         301 :         sys->copyVars(*reader);
    1018         285 :       _aux->copyVars(*reader);
    1019         285 :     }
    1020             :     else
    1021             :     {
    1022       57020 :       if (_solver_systems[0]->hasVarCopy() || _aux->hasVarCopy())
    1023           0 :         mooseError("Need Exodus reader to restart variables but the reader is not available\n"
    1024             :                    "Use either FileMesh with an Exodus mesh file or FileMeshGenerator with an "
    1025             :                    "Exodus mesh file and with use_for_exodus_restart equal to true");
    1026             :     }
    1027             :   }
    1028             : 
    1029             :   // Perform output related setups
    1030       61835 :   _app.getOutputWarehouse().initialSetup();
    1031             : 
    1032             :   // Flush all output to _console that occur during construction and initialization of objects
    1033       61767 :   _app.getOutputWarehouse().mooseConsole();
    1034             : 
    1035             :   // Build Refinement and Coarsening maps for stateful material projections if necessary
    1036       64187 :   if ((_adaptivity.isOn() || _num_grid_steps) &&
    1037        2420 :       (_material_props.hasStatefulProperties() || _bnd_material_props.hasStatefulProperties() ||
    1038        2349 :        _neighbor_material_props.hasStatefulProperties()))
    1039             :   {
    1040          71 :     if (_has_internal_edge_residual_objects)
    1041           8 :       mooseError("Stateful neighbor material properties do not work with mesh adaptivity");
    1042             : 
    1043          63 :     _mesh.buildRefinementAndCoarseningMaps(_assembly[0][0].get());
    1044             :   }
    1045             : 
    1046       61759 :   if (!_app.isRecovering())
    1047             :   {
    1048             :     /**
    1049             :      * If we are not recovering but we are doing restart (_app.getExodusFileRestart() == true) with
    1050             :      * additional uniform refinements. We have to delay the refinement until this point
    1051             :      * in time so that the equation systems are initialized and projections can be performed.
    1052             :      */
    1053       57761 :     if (_mesh.uniformRefineLevel() > 0 && _app.getExodusFileRestart())
    1054             :     {
    1055          11 :       if (!_app.isUltimateMaster())
    1056           0 :         mooseError(
    1057             :             "Doing extra refinements when restarting is NOT supported for sub-apps of a MultiApp");
    1058             : 
    1059          11 :       adaptivity().uniformRefineWithProjection();
    1060             :     }
    1061             :   }
    1062             : 
    1063       61759 :   unsigned int n_threads = libMesh::n_threads();
    1064             : 
    1065             :   // Convergence initial setup
    1066             :   {
    1067      308795 :     TIME_SECTION("convergenceInitialSetup", 5, "Initializing Convergence objects");
    1068             : 
    1069      129206 :     for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1070       67467 :       _convergences.initialSetup(tid);
    1071       61739 :   }
    1072             : 
    1073             :   // UserObject initialSetup
    1074       61739 :   std::set<std::string> depend_objects_ic = _ics.getDependObjects();
    1075       61739 :   std::set<std::string> depend_objects_aux = _aux->getDependObjects();
    1076             : 
    1077             :   // This replaces all prior updateDependObjects calls on the old user object warehouses.
    1078       61739 :   TheWarehouse::Query uo_query = theWarehouse().query().condition<AttribSystem>("UserObject");
    1079       61739 :   std::vector<UserObject *> userobjs;
    1080       61739 :   uo_query.queryInto(userobjs);
    1081       61739 :   groupUserObjects(
    1082       61739 :       theWarehouse(), getAuxiliarySystem(), _app.getExecuteOnEnum(), userobjs, depend_objects_ic);
    1083             : 
    1084       61739 :   std::map<int, std::vector<UserObject *>> group_userobjs;
    1085      143101 :   for (auto obj : userobjs)
    1086      244086 :     group_userobjs[obj->getParam<int>("execution_order_group")].push_back(obj);
    1087             : 
    1088       94086 :   for (auto & [group, objs] : group_userobjs)
    1089      113669 :     for (auto obj : objs)
    1090       81322 :       obj->initialSetup();
    1091             : 
    1092             :   // check if jacobian calculation is done in userobject
    1093      128961 :   for (THREAD_ID tid = 0; tid < n_threads; ++tid)
    1094       67322 :     checkUserObjectJacobianRequirement(tid);
    1095             : 
    1096             :   // Check whether nonlocal couling is required or not
    1097       61639 :   checkNonlocalCoupling();
    1098       61639 :   if (_requires_nonlocal_coupling)
    1099          81 :     setVariableAllDoFMap(_uo_jacobian_moose_vars[0]);
    1100             : 
    1101             :   {
    1102      308195 :     TIME_SECTION("initializingFunctions", 5, "Initializing Functions");
    1103             : 
    1104             :     // Call the initialSetup methods for functions
    1105      128921 :     for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1106             :     {
    1107       67314 :       reinitScalars(tid); // initialize scalars so they are properly sized for use as input into
    1108             :                           // ParsedFunctions
    1109       67314 :       _functions.initialSetup(tid);
    1110             :     }
    1111       61607 :   }
    1112             : 
    1113             :   {
    1114      308035 :     TIME_SECTION("initializingRandomObjects", 5, "Initializing Random Objects");
    1115             : 
    1116             :     // Random interface objects
    1117       62000 :     for (const auto & it : _random_data_objects)
    1118         393 :       it.second->updateSeeds(EXEC_INITIAL);
    1119       61607 :   }
    1120             : 
    1121       61607 :   if (!_app.isRecovering())
    1122             :   {
    1123       57609 :     computeUserObjects(EXEC_INITIAL, Moose::PRE_IC);
    1124             : 
    1125             :     {
    1126      288045 :       TIME_SECTION("ICinitialSetup", 5, "Setting Up Initial Conditions");
    1127             : 
    1128      120840 :       for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1129       63239 :         _ics.initialSetup(tid);
    1130             : 
    1131       57601 :       _scalar_ics.initialSetup();
    1132       57601 :     }
    1133             : 
    1134       57601 :     projectSolution();
    1135             :   }
    1136             : 
    1137             :   // Materials
    1138       61591 :   if (_all_materials.hasActiveObjects(0))
    1139             :   {
    1140       44410 :     TIME_SECTION("materialInitialSetup", 3, "Setting Up Materials");
    1141             : 
    1142       18407 :     for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1143             :     {
    1144             :       // Sort the Material objects, these will be actually computed by MOOSE in reinit methods.
    1145        9549 :       _materials.sort(tid);
    1146        9545 :       _interface_materials.sort(tid);
    1147             : 
    1148             :       // Call initialSetup on all material objects
    1149        9545 :       _all_materials.initialSetup(tid);
    1150             : 
    1151             :       // Discrete materials may insert additional dependencies on materials during the initial
    1152             :       // setup. Therefore we resolve the dependencies once more, now with the additional
    1153             :       // dependencies due to discrete materials.
    1154        9525 :       if (_discrete_materials.hasActiveObjects())
    1155             :       {
    1156          61 :         _materials.sort(tid);
    1157          61 :         _interface_materials.sort(tid);
    1158             :       }
    1159             :     }
    1160             : 
    1161             : #ifdef MOOSE_KOKKOS_ENABLED
    1162        5959 :     _kokkos_materials.sort(0, true);
    1163             : #endif
    1164             : 
    1165             :     {
    1166       44280 :       TIME_SECTION("computingInitialStatefulProps", 3, "Computing Initial Material Values");
    1167             : 
    1168        8856 :       initElementStatefulProps(*_mesh.getActiveLocalElementRange(), true);
    1169             : 
    1170       16950 :       if (_material_props.hasStatefulProperties() || _bnd_material_props.hasStatefulProperties() ||
    1171        8094 :           _neighbor_material_props.hasStatefulProperties())
    1172         762 :         _has_initialized_stateful = true;
    1173             : #ifdef MOOSE_KOKKOS_ENABLED
    1174        5444 :       else if (_kokkos_material_props.hasStatefulProperties() ||
    1175       10736 :                _kokkos_bnd_material_props.hasStatefulProperties() ||
    1176        5292 :                _kokkos_neighbor_material_props.hasStatefulProperties())
    1177         152 :         _has_initialized_stateful = true;
    1178             : #endif
    1179        8856 :     }
    1180        8856 :   }
    1181             : 
    1182             :   // setRestartInPlace() is set because the property maps have now been setup and we can
    1183             :   // dataLoad() them directly in place
    1184             :   // setRecovering() is set because from now on we require a one-to-one mapping of
    1185             :   // stateful properties because we shouldn't be declaring any more
    1186      246260 :   for (auto props : {&_material_props, &_bnd_material_props, &_neighbor_material_props})
    1187             :   {
    1188      184695 :     props->setRestartInPlace();
    1189      184695 :     props->setRecovering();
    1190             :   }
    1191             : 
    1192      128794 :   for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1193             :   {
    1194       67229 :     _internal_side_indicators.initialSetup(tid);
    1195       67229 :     _indicators.initialSetup(tid);
    1196       67229 :     _markers.sort(tid);
    1197       67229 :     _markers.initialSetup(tid);
    1198             :   }
    1199             : 
    1200             : #ifdef LIBMESH_ENABLE_AMR
    1201             : 
    1202       61565 :   if (!_app.isRecovering())
    1203             :   {
    1204       57567 :     unsigned int n = adaptivity().getInitialSteps();
    1205       57567 :     if (n && !_app.isUltimateMaster() && _app.isRestarting())
    1206           0 :       mooseError("Cannot perform initial adaptivity during restart on sub-apps of a MultiApp!");
    1207             : 
    1208       57567 :     initialAdaptMesh();
    1209             :   }
    1210             : 
    1211             : #endif // LIBMESH_ENABLE_AMR
    1212             : 
    1213       61561 :   if (!_app.isRecovering() && !_app.isRestarting())
    1214             :   {
    1215             :     // During initial setup the solution is copied to the older solution states (old, older, etc)
    1216       57031 :     copySolutionsBackwards();
    1217             : 
    1218             :     // Check if there are old state initial conditions
    1219       57031 :     auto ics = _ics.getActiveObjects();
    1220       57031 :     auto fv_ics = _fv_ics.getActiveObjects();
    1221       57031 :     auto scalar_ics = _scalar_ics.getActiveObjects();
    1222       57031 :     unsigned short ic_state_max = 0;
    1223             : 
    1224      171093 :     auto findMax = [&ic_state_max](const auto & obj_list)
    1225             :     {
    1226      201573 :       for (auto ic : obj_list.getActiveObjects())
    1227       30480 :         ic_state_max = std::max(ic_state_max, ic->getState());
    1228      228124 :     };
    1229       57031 :     findMax(_ics);
    1230       57031 :     findMax(_fv_ics);
    1231       57031 :     findMax(_scalar_ics);
    1232             : 
    1233             :     // if there are old state ICs, compute them and write to old states accordingly
    1234       57031 :     if (ic_state_max > 0)
    1235             :     {
    1236             :       // state 0 copy (we'll overwrite current state when evaluating ICs and need to restore it once
    1237             :       // we're done with the old/older state ICs)
    1238           0 :       std::vector<std::unique_ptr<NumericVector<Real>>> state0_sys_buffers(_solver_systems.size());
    1239           0 :       std::unique_ptr<NumericVector<Real>> state0_aux_buffer;
    1240             : 
    1241             :       // save state 0
    1242           0 :       for (const auto i : index_range(_solver_systems))
    1243           0 :         state0_sys_buffers[i] = _solver_systems[i]->solutionState(0).clone();
    1244             : 
    1245           0 :       state0_aux_buffer = _aux->solutionState(0).clone();
    1246             : 
    1247             :       // compute old state ICs
    1248           0 :       for (_current_ic_state = 1; _current_ic_state <= ic_state_max; _current_ic_state++)
    1249             :       {
    1250           0 :         projectSolution();
    1251             : 
    1252           0 :         for (auto & sys : _solver_systems)
    1253           0 :           sys->solutionState(_current_ic_state) = sys->solutionState(0);
    1254             : 
    1255           0 :         _aux->solutionState(_current_ic_state) = _aux->solutionState(0);
    1256             :       }
    1257           0 :       _current_ic_state = 0;
    1258             : 
    1259             :       // recover state 0
    1260           0 :       for (const auto i : index_range(_solver_systems))
    1261             :       {
    1262           0 :         _solver_systems[i]->solutionState(0) = *state0_sys_buffers[i];
    1263           0 :         _solver_systems[i]->solutionState(0).close();
    1264           0 :         _solver_systems[i]->update();
    1265             :       }
    1266           0 :       _aux->solutionState(0) = *state0_aux_buffer;
    1267           0 :       _aux->solutionState(0).close();
    1268           0 :       _aux->update();
    1269           0 :     }
    1270       57031 :   }
    1271             : 
    1272       61561 :   if (!_app.isRecovering())
    1273             :   {
    1274       57563 :     if (haveXFEM())
    1275           0 :       updateMeshXFEM();
    1276             :   }
    1277             : 
    1278             :   // Call initialSetup on the solver systems
    1279      123397 :   for (auto & sys : _solver_systems)
    1280       61836 :     sys->initialSetup();
    1281             : 
    1282             :   // Auxilary variable initialSetup calls
    1283       61561 :   _aux->initialSetup();
    1284             : 
    1285       61557 :   if (_displaced_problem)
    1286             :     // initialSetup for displaced systems
    1287        2234 :     _displaced_problem->initialSetup();
    1288             : 
    1289      123389 :   for (auto & sys : _solver_systems)
    1290       61832 :     sys->setSolution(*(sys->system().current_local_solution.get()));
    1291             : 
    1292             :   // Update the nearest node searches (has to be called after the problem is all set up)
    1293             :   // We do this here because this sets up the Element's DoFs to ghost
    1294       61557 :   updateGeomSearch(GeometricSearchData::NEAREST_NODE);
    1295             : 
    1296       61557 :   _mesh.updateActiveSemiLocalNodeRange(_ghosted_elems);
    1297       61557 :   if (_displaced_mesh)
    1298        2234 :     _displaced_mesh->updateActiveSemiLocalNodeRange(_ghosted_elems);
    1299             : 
    1300             :   // We need to move the mesh in order to build a map between mortar secondary and primary
    1301             :   // interfaces. This map will then be used by the AgumentSparsityOnInterface ghosting functor to
    1302             :   // know which dofs we need ghosted when we call EquationSystems::reinit
    1303       61557 :   if (_displaced_problem && _mortar_data.hasDisplacedObjects())
    1304             :   {
    1305         124 :     _displaced_problem->updateMesh();
    1306             :     // if displacements were applied to the mesh, the mortar mesh should be updated too
    1307         124 :     updateMortarMesh();
    1308             :   }
    1309             : 
    1310             :   // Possibly reinit one more time to get ghosting correct
    1311       61557 :   reinitBecauseOfGhostingOrNewGeomObjects();
    1312             : 
    1313       61557 :   if (_displaced_mesh)
    1314        2234 :     _displaced_problem->updateMesh();
    1315             : 
    1316       61557 :   updateGeomSearch(); // Call all of the rest of the geometric searches
    1317             : 
    1318      123385 :   for (auto & sys : _solver_systems)
    1319             :   {
    1320       61832 :     const auto & tis = sys->getTimeIntegrators();
    1321             : 
    1322             :     {
    1323      309160 :       TIME_SECTION("timeIntegratorInitialSetup", 5, "Initializing Time Integrator");
    1324       92803 :       for (auto & ti : tis)
    1325       30975 :         ti->initialSetup();
    1326       61828 :     }
    1327             :   }
    1328             : 
    1329             :   // HUGE NOTE: MultiApp initialSetup() MUST... I repeat MUST be _after_ main-app restartable data
    1330             :   // has been restored
    1331             : 
    1332             :   // Call initialSetup on the MultiApps
    1333       61553 :   if (_multi_apps.hasObjects())
    1334             :   {
    1335       32955 :     TIME_SECTION("initialSetupMultiApps", 2, "Initializing MultiApps", false);
    1336        6591 :     _multi_apps.initialSetup();
    1337        6583 :   }
    1338             : 
    1339             :   // Call initialSetup on the transfers
    1340             :   {
    1341      307725 :     TIME_SECTION("initialSetupTransfers", 2, "Initializing Transfers");
    1342             : 
    1343       61545 :     _transfers.initialSetup();
    1344             : 
    1345             :     // Call initialSetup on the MultiAppTransfers to be executed on TO_MULTIAPP
    1346       61545 :     const auto & to_multi_app_objects = _to_multi_app_transfers.getActiveObjects();
    1347       66709 :     for (const auto & transfer : to_multi_app_objects)
    1348             :     {
    1349        5228 :       transfer->setCurrentDirection(Transfer::DIRECTION::TO_MULTIAPP);
    1350        5228 :       transfer->initialSetup();
    1351             :     }
    1352             : 
    1353             :     // Call initialSetup on the MultiAppTransfers to be executed on FROM_MULTIAPP
    1354       61481 :     const auto & from_multi_app_objects = _from_multi_app_transfers.getActiveObjects();
    1355       67216 :     for (const auto & transfer : from_multi_app_objects)
    1356             :     {
    1357        5791 :       transfer->setCurrentDirection(Transfer::DIRECTION::FROM_MULTIAPP);
    1358        5791 :       transfer->initialSetup();
    1359             :     }
    1360             : 
    1361             :     // Call initialSetup on the MultiAppTransfers to be executed on BETWEEN_MULTIAPP
    1362       61425 :     const auto & between_multi_app_objects = _between_multi_app_transfers.getActiveObjects();
    1363       62621 :     for (const auto & transfer : between_multi_app_objects)
    1364             :     {
    1365        1196 :       transfer->setCurrentDirection(Transfer::DIRECTION::BETWEEN_MULTIAPP);
    1366        1196 :       transfer->initialSetup();
    1367             :     }
    1368       61425 :   }
    1369             : 
    1370       61425 :   if (_boundary_restricted_node_integrity_check)
    1371             :   {
    1372      184236 :     TIME_SECTION("BoundaryRestrictedNodeIntegrityCheck", 5);
    1373             : 
    1374             :     // check that variables are defined along boundaries of boundary restricted nodal objects
    1375       61412 :     ConstBndNodeRange & bnd_nodes = *mesh().getBoundaryNodeRange();
    1376       61412 :     BoundaryNodeIntegrityCheckThread bnict(*this, uo_query);
    1377       61412 :     Threads::parallel_reduce(bnd_nodes, bnict);
    1378             : 
    1379             :     // Nodal bcs aren't threaded
    1380       61400 :     const auto & node_to_elem_map = _mesh.nodeToActiveSemilocalElemMap();
    1381     4690584 :     for (const auto & bnode : bnd_nodes)
    1382             :     {
    1383     4629196 :       const auto boundary_id = bnode->_bnd_id;
    1384     4629196 :       const Node * const node = bnode->_node;
    1385             : 
    1386     4629196 :       if (node->processor_id() != this->processor_id())
    1387      878711 :         continue;
    1388             : 
    1389             :       // Only check vertices. Variables may not be defined on non-vertex nodes (think first order
    1390             :       // Lagrange on a second order mesh) and user-code can often handle that
    1391             :       const Elem * const an_elem =
    1392     3750485 :           _mesh.getMesh().elem_ptr(libmesh_map_find(node_to_elem_map, node->id()).front());
    1393     3750485 :       if (!an_elem->is_vertex(an_elem->get_node_index(node)))
    1394      463837 :         continue;
    1395             : 
    1396     3286648 :       const auto & bnd_name = _mesh.getBoundaryName(boundary_id);
    1397             : 
    1398     6527004 :       for (auto & nl : _nl)
    1399             :       {
    1400     3240368 :         const auto & nodal_bcs = nl->getNodalBCWarehouse();
    1401     3240368 :         if (!nodal_bcs.hasBoundaryObjects(boundary_id, 0))
    1402     2325877 :           continue;
    1403             : 
    1404      914491 :         const auto & bnd_objects = nodal_bcs.getBoundaryObjects(boundary_id, 0);
    1405     1919363 :         for (const auto & bnd_object : bnd_objects)
    1406             :           // Skip if this object uses geometric search because coupled variables may be defined on
    1407             :           // paired boundaries instead of the boundary this node is on
    1408     2009768 :           if (!bnd_object->requiresGeometricSearch() &&
    1409     1004884 :               bnd_object->checkVariableBoundaryIntegrity())
    1410             :           {
    1411             :             std::set<MooseVariableFieldBase *> vars_to_omit = {
    1412             :                 &static_cast<MooseVariableFieldBase &>(
    1413     2009768 :                     const_cast<MooseVariableBase &>(bnd_object->variable()))};
    1414             : 
    1415     2009768 :             boundaryIntegrityCheckError(
    1416     2009756 :                 *bnd_object, bnd_object->checkAllVariables(*node, vars_to_omit), bnd_name);
    1417     1004872 :           }
    1418             :       }
    1419             :     }
    1420       61388 :   }
    1421             : 
    1422       61401 :   if (_boundary_restricted_elem_integrity_check)
    1423             :   {
    1424      184101 :     TIME_SECTION("BoundaryRestrictedElemIntegrityCheck", 5);
    1425             : 
    1426             :     // check that variables are defined along boundaries of boundary restricted elemental objects
    1427       61367 :     ConstBndElemRange & bnd_elems = *mesh().getBoundaryElementRange();
    1428       61367 :     BoundaryElemIntegrityCheckThread beict(*this, uo_query);
    1429       61367 :     Threads::parallel_reduce(bnd_elems, beict);
    1430       61351 :   }
    1431             : 
    1432       61385 :   if (!_app.isRecovering())
    1433             :   {
    1434       57387 :     execTransfers(EXEC_INITIAL);
    1435             : 
    1436       57387 :     bool converged = execMultiApps(EXEC_INITIAL);
    1437       57379 :     if (!converged)
    1438           4 :       mooseError("failed to converge initial MultiApp");
    1439             : 
    1440             :     // We'll backup the Multiapp here
    1441       57375 :     backupMultiApps(EXEC_INITIAL);
    1442             : 
    1443      120323 :     for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1444       62948 :       reinitScalars(tid);
    1445             : 
    1446       57375 :     execute(EXEC_INITIAL);
    1447             : 
    1448             :     // The FEProblemBase::execute method doesn't call all the systems on EXEC_INITIAL, but it does
    1449             :     // set/unset the current flag. Therefore, this resets the current flag to EXEC_INITIAL so that
    1450             :     // subsequent calls (e.g., executeControls) have the proper flag.
    1451       57306 :     setCurrentExecuteOnFlag(EXEC_INITIAL);
    1452             :   }
    1453             : 
    1454             :   // Here we will initialize the stateful properties once more since they may have been updated
    1455             :   // during initialSetup by calls to computeProperties.
    1456             :   //
    1457             :   // It's really bad that we don't allow this during restart.  It means that we can't add new
    1458             :   // stateful materials
    1459             :   // during restart.  This is only happening because this _has_ to be below initial userobject
    1460             :   // execution.
    1461             :   // Otherwise this could be done up above... _before_ restoring restartable data... which would
    1462             :   // allow you to have
    1463             :   // this happen during restart.  I honestly have no idea why this has to happen after initial user
    1464             :   // object computation.
    1465             :   // THAT is something we should fix... so I've opened this ticket: #5804
    1466      118078 :   if (!_app.isRecovering() && !_app.isRestarting() &&
    1467       56774 :       (_material_props.hasStatefulProperties() || _bnd_material_props.hasStatefulProperties() ||
    1468       56128 :        _neighbor_material_props.hasStatefulProperties()))
    1469             :   {
    1470        3230 :     TIME_SECTION("computeMaterials", 2, "Computing Initial Material Properties");
    1471             : 
    1472         646 :     initElementStatefulProps(*_mesh.getActiveLocalElementRange(), true);
    1473         646 :   }
    1474             : 
    1475             :   // Control Logic
    1476       61304 :   executeControls(EXEC_INITIAL);
    1477             : 
    1478             :   // Scalar variables need to reinited for the initial conditions to be available for output
    1479      128181 :   for (unsigned int tid = 0; tid < n_threads; tid++)
    1480       66889 :     reinitScalars(tid);
    1481             : 
    1482       61292 :   if (_displaced_mesh)
    1483        2234 :     _displaced_problem->syncSolutions();
    1484             : 
    1485             :   // Writes all calls to _console from initialSetup() methods
    1486       61292 :   _app.getOutputWarehouse().mooseConsole();
    1487             : 
    1488       61292 :   if (_requires_nonlocal_coupling)
    1489             :   {
    1490          81 :     setNonlocalCouplingMatrix();
    1491         162 :     for (THREAD_ID tid = 0; tid < n_threads; ++tid)
    1492         162 :       for (auto & assembly : _assembly[tid])
    1493          81 :         assembly->initNonlocalCoupling();
    1494             :   }
    1495             : 
    1496             :   {
    1497      306460 :     TIME_SECTION("lineSearchInitialSetup", 5, "Initializing Line Search");
    1498             : 
    1499       61292 :     if (_line_search)
    1500           0 :       _line_search->initialSetup();
    1501       61292 :   }
    1502             : 
    1503             :   // Perform Reporter get/declare check
    1504       61292 :   _reporter_data.check();
    1505             : 
    1506             :   // We do this late to allow objects to get late restartable data
    1507       61292 :   if (_app.isRestarting() || _app.isRecovering() || _force_restart)
    1508        4530 :     _app.finalizeRestore();
    1509             : 
    1510       61292 :   setCurrentExecuteOnFlag(EXEC_NONE);
    1511       61292 : }
    1512             : 
    1513             : void
    1514       62316 : FEProblemBase::checkDuplicatePostprocessorVariableNames()
    1515             : {
    1516      117452 :   for (const auto & pp : _reporter_data.getPostprocessorNames())
    1517       55136 :     if (hasScalarVariable(pp))
    1518           0 :       mooseError("Postprocessor \"" + pp +
    1519       62316 :                  "\" has the same name as a scalar variable in the system.");
    1520       62316 : }
    1521             : 
    1522             : void
    1523      289206 : FEProblemBase::timestepSetup()
    1524             : {
    1525      289206 :   SubProblem::timestepSetup();
    1526             : 
    1527      289206 :   if (_t_step > 1 && _num_grid_steps)
    1528             :   {
    1529          35 :     libMesh::MeshRefinement mesh_refinement(_mesh);
    1530          35 :     std::unique_ptr<libMesh::MeshRefinement> displaced_mesh_refinement(nullptr);
    1531          35 :     if (_displaced_mesh)
    1532          25 :       displaced_mesh_refinement = std::make_unique<libMesh::MeshRefinement>(*_displaced_mesh);
    1533             : 
    1534          70 :     for (MooseIndex(_num_grid_steps) i = 0; i < _num_grid_steps; ++i)
    1535             :     {
    1536          35 :       if (_displaced_problem)
    1537             :         // If the DisplacedProblem is active, undisplace the DisplacedMesh in preparation for
    1538             :         // refinement.  We can't safely refine the DisplacedMesh directly, since the Hilbert keys
    1539             :         // computed on the inconsistenly-displaced Mesh are different on different processors,
    1540             :         // leading to inconsistent Hilbert keys.  We must do this before the undisplaced Mesh is
    1541             :         // coarsensed, so that the element and node numbering is still consistent. We also have to
    1542             :         // make sure this is done during every step of coarsening otherwise different partitions
    1543             :         // will be generated for the reference and displaced meshes (even for replicated)
    1544          25 :         _displaced_problem->undisplaceMesh();
    1545             : 
    1546          35 :       mesh_refinement.uniformly_coarsen();
    1547          35 :       if (_displaced_mesh)
    1548          25 :         displaced_mesh_refinement->uniformly_coarsen();
    1549             : 
    1550             :       // Mark this as an intermediate change because we do not yet want to reinit_systems. E.g. we
    1551             :       // need things to happen in the following order for the undisplaced problem:
    1552             :       // u1) EquationSystems::reinit_solutions. This will restrict the solution vectors and then
    1553             :       //     contract the mesh
    1554             :       // u2) MooseMesh::meshChanged. This will update the node/side lists and other
    1555             :       //     things which needs to happen after the contraction
    1556             :       // u3) GeometricSearchData::reinit. Once the node/side lists are updated we can perform our
    1557             :       //     geometric searches which will aid in determining sparsity patterns
    1558             :       //
    1559             :       // We do these things for the displaced problem (if it exists)
    1560             :       // d1) EquationSystems::reinit. Restrict the displaced problem vector copies and then contract
    1561             :       //     the mesh. It's safe to do a full reinit with the displaced because there are no
    1562             :       //     matrices that sparsity pattern calculations will be conducted for
    1563             :       // d2) MooseMesh::meshChanged. This will update the node/side lists and other
    1564             :       //     things which needs to happen after the contraction
    1565             :       // d3) UpdateDisplacedMeshThread::operator(). Re-displace the mesh using the *displaced*
    1566             :       //     solution vector copy because we don't know the state of the reference solution vector.
    1567             :       //     It's safe to use the displaced copy because we are outside of a non-linear solve,
    1568             :       //     and there is no concern about differences between solution and current_local_solution
    1569             :       // d4) GeometricSearchData::reinit. With the node/side lists updated and the mesh
    1570             :       //     re-displaced, we can perform our geometric searches, which will aid in determining the
    1571             :       //     sparsity pattern of the matrix held by the libMesh::ImplicitSystem held by the
    1572             :       //     NonlinearSystem held by this
    1573          35 :       meshChanged(
    1574             :           /*intermediate_change=*/true, /*contract_mesh=*/true, /*clean_refinement_flags=*/true);
    1575             :     }
    1576             : 
    1577             :     // u4) Now that all the geometric searches have been done (both undisplaced and displaced),
    1578             :     //     we're ready to update the sparsity pattern
    1579          35 :     es().reinit_systems();
    1580          35 :   }
    1581             : 
    1582      289206 :   if (_line_search)
    1583           0 :     _line_search->timestepSetup();
    1584             : 
    1585             :   // Random interface objects
    1586      290919 :   for (const auto & it : _random_data_objects)
    1587        1713 :     it.second->updateSeeds(EXEC_TIMESTEP_BEGIN);
    1588             : 
    1589      289206 :   unsigned int n_threads = libMesh::n_threads();
    1590      604132 :   for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1591             :   {
    1592      314926 :     _all_materials.timestepSetup(tid);
    1593      314926 :     _functions.timestepSetup(tid);
    1594             :   }
    1595             : 
    1596      289206 :   _aux->timestepSetup();
    1597      582187 :   for (auto & sys : _solver_systems)
    1598      292981 :     sys->timestepSetup();
    1599             : 
    1600      289206 :   if (_displaced_problem)
    1601             :     // timestepSetup for displaced systems
    1602       33515 :     _displaced_problem->timestepSetup();
    1603             : 
    1604      604132 :   for (THREAD_ID tid = 0; tid < n_threads; tid++)
    1605             :   {
    1606      314926 :     _internal_side_indicators.timestepSetup(tid);
    1607      314926 :     _indicators.timestepSetup(tid);
    1608      314926 :     _markers.timestepSetup(tid);
    1609             :   }
    1610             : 
    1611      289206 :   std::vector<UserObject *> userobjs;
    1612      289206 :   theWarehouse().query().condition<AttribSystem>("UserObject").queryIntoUnsorted(userobjs);
    1613      652305 :   for (auto obj : userobjs)
    1614      363099 :     obj->timestepSetup();
    1615             : 
    1616             :   // Timestep setup of output objects
    1617      289206 :   _app.getOutputWarehouse().timestepSetup();
    1618             : 
    1619      289206 :   if (_requires_nonlocal_coupling)
    1620         123 :     if (_nonlocal_kernels.hasActiveObjects() || _nonlocal_integrated_bcs.hasActiveObjects())
    1621         123 :       _has_nonlocal_coupling = true;
    1622      289206 : }
    1623             : 
    1624             : unsigned int
    1625      833793 : FEProblemBase::getMaxQps() const
    1626             : {
    1627      833793 :   if (_max_qps == std::numeric_limits<unsigned int>::max())
    1628           0 :     mooseError("Max QPS uninitialized");
    1629      833793 :   return _max_qps;
    1630             : }
    1631             : 
    1632             : Order
    1633          56 : FEProblemBase::getMaxScalarOrder() const
    1634             : {
    1635          56 :   return _max_scalar_order;
    1636             : }
    1637             : 
    1638             : void
    1639       61639 : FEProblemBase::checkNonlocalCoupling()
    1640             : {
    1641      308195 :   TIME_SECTION("checkNonlocalCoupling", 5, "Checking Nonlocal Coupling");
    1642             : 
    1643      128961 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    1644      133596 :     for (auto & nl : _nl)
    1645             :     {
    1646       66274 :       const auto & all_kernels = nl->getKernelWarehouse();
    1647       66274 :       const auto & kernels = all_kernels.getObjects(tid);
    1648      157207 :       for (const auto & kernel : kernels)
    1649             :       {
    1650             :         std::shared_ptr<NonlocalKernel> nonlocal_kernel =
    1651       90933 :             std::dynamic_pointer_cast<NonlocalKernel>(kernel);
    1652       90933 :         if (nonlocal_kernel)
    1653             :         {
    1654          45 :           if (_calculate_jacobian_in_uo)
    1655          45 :             _requires_nonlocal_coupling = true;
    1656          45 :           _nonlocal_kernels.addObject(kernel, tid);
    1657             :         }
    1658       90933 :       }
    1659             :       const MooseObjectWarehouse<IntegratedBCBase> & all_integrated_bcs =
    1660       66274 :           nl->getIntegratedBCWarehouse();
    1661       66274 :       const auto & integrated_bcs = all_integrated_bcs.getObjects(tid);
    1662       76019 :       for (const auto & integrated_bc : integrated_bcs)
    1663             :       {
    1664             :         std::shared_ptr<NonlocalIntegratedBC> nonlocal_integrated_bc =
    1665        9745 :             std::dynamic_pointer_cast<NonlocalIntegratedBC>(integrated_bc);
    1666        9745 :         if (nonlocal_integrated_bc)
    1667             :         {
    1668          36 :           if (_calculate_jacobian_in_uo)
    1669          36 :             _requires_nonlocal_coupling = true;
    1670          36 :           _nonlocal_integrated_bcs.addObject(integrated_bc, tid);
    1671             :         }
    1672        9745 :       }
    1673             :     }
    1674       61639 : }
    1675             : 
    1676             : void
    1677       67322 : FEProblemBase::checkUserObjectJacobianRequirement(THREAD_ID tid)
    1678             : {
    1679       67322 :   std::set<const MooseVariableFEBase *> uo_jacobian_moose_vars;
    1680             :   {
    1681       67322 :     std::vector<ShapeElementUserObject *> objs;
    1682       67322 :     theWarehouse()
    1683       67322 :         .query()
    1684      134644 :         .condition<AttribInterfaces>(Interfaces::ShapeElementUserObject)
    1685       67322 :         .condition<AttribThread>(tid)
    1686       67322 :         .queryInto(objs);
    1687             : 
    1688       67378 :     for (const auto & uo : objs)
    1689             :     {
    1690          56 :       _calculate_jacobian_in_uo = uo->computeJacobianFlag();
    1691          56 :       const auto & mv_deps = uo->jacobianMooseVariables();
    1692          56 :       uo_jacobian_moose_vars.insert(mv_deps.begin(), mv_deps.end());
    1693             :     }
    1694       67322 :   }
    1695             :   {
    1696       67322 :     std::vector<ShapeSideUserObject *> objs;
    1697       67322 :     theWarehouse()
    1698       67322 :         .query()
    1699      134644 :         .condition<AttribInterfaces>(Interfaces::ShapeSideUserObject)
    1700       67322 :         .condition<AttribThread>(tid)
    1701       67322 :         .queryInto(objs);
    1702       67394 :     for (const auto & uo : objs)
    1703             :     {
    1704          72 :       _calculate_jacobian_in_uo = uo->computeJacobianFlag();
    1705          72 :       const auto & mv_deps = uo->jacobianMooseVariables();
    1706          72 :       uo_jacobian_moose_vars.insert(mv_deps.begin(), mv_deps.end());
    1707             :     }
    1708       67322 :   }
    1709             : 
    1710       67322 :   _uo_jacobian_moose_vars[tid].assign(uo_jacobian_moose_vars.begin(), uo_jacobian_moose_vars.end());
    1711      134644 :   std::sort(
    1712      134644 :       _uo_jacobian_moose_vars[tid].begin(), _uo_jacobian_moose_vars[tid].end(), sortMooseVariables);
    1713       67322 : }
    1714             : 
    1715             : void
    1716          81 : FEProblemBase::setVariableAllDoFMap(const std::vector<const MooseVariableFEBase *> & moose_vars)
    1717             : {
    1718         197 :   for (unsigned int i = 0; i < moose_vars.size(); ++i)
    1719             :   {
    1720         116 :     VariableName var_name = moose_vars[i]->name();
    1721         116 :     auto & sys = _solver_systems[moose_vars[i]->sys().number()];
    1722         116 :     sys->setVariableGlobalDoFs(var_name);
    1723         116 :     _var_dof_map[var_name] = sys->getVariableGlobalDoFs();
    1724         116 :   }
    1725          81 : }
    1726             : 
    1727             : void
    1728   430996498 : FEProblemBase::prepare(const Elem * elem, const THREAD_ID tid)
    1729             : {
    1730   864791956 :   for (const auto i : index_range(_solver_systems))
    1731             :   {
    1732   433795458 :     _assembly[tid][i]->reinit(elem);
    1733   433795458 :     _solver_systems[i]->prepare(tid);
    1734             : 
    1735   433795458 :     if (i < _num_nl_sys)
    1736             :     {
    1737             :       // This method is called outside of residual/Jacobian callbacks during initial condition
    1738             :       // evaluation
    1739   433122628 :       if ((!_has_jacobian || !_const_jacobian) && currentlyComputingJacobian())
    1740    56155136 :         _assembly[tid][i]->prepareJacobianBlock();
    1741   433122628 :       _assembly[tid][i]->prepareResidual();
    1742   433122628 :       if (_has_nonlocal_coupling && currentlyComputingJacobian())
    1743       11792 :         _assembly[tid][i]->prepareNonlocal();
    1744             :     }
    1745             :   }
    1746   430996498 :   _aux->prepare(tid);
    1747             : 
    1748   444279260 :   if (_displaced_problem &&
    1749             :       // _reinit_displaced_neighbor applies to interface type objects which will do computations
    1750             :       // based on both elem and neighbor. Consequently, despite what you might think by its name, we
    1751             :       // must make sure we prepare the displaced elem
    1752   444279260 :       (_reinit_displaced_elem || _reinit_displaced_face || _reinit_displaced_neighbor))
    1753             :   {
    1754     8536374 :     _displaced_problem->prepare(_displaced_mesh->elemPtr(elem->id()), tid);
    1755     8536346 :     if (_has_nonlocal_coupling)
    1756           0 :       _displaced_problem->prepareNonlocal(tid);
    1757             :   }
    1758   430996470 : }
    1759             : 
    1760             : void
    1761       29479 : FEProblemBase::prepareFace(const Elem * elem, const THREAD_ID tid)
    1762             : {
    1763       58958 :   for (auto & nl : _nl)
    1764       29479 :     nl->prepareFace(tid, true);
    1765       29479 :   _aux->prepareFace(tid, false);
    1766             : 
    1767       29479 :   if (_displaced_problem && (_reinit_displaced_elem || _reinit_displaced_face))
    1768           0 :     _displaced_problem->prepareFace(_displaced_mesh->elemPtr(elem->id()), tid);
    1769       29479 : }
    1770             : 
    1771             : void
    1772           0 : FEProblemBase::prepare(const Elem * elem,
    1773             :                        unsigned int ivar,
    1774             :                        unsigned int jvar,
    1775             :                        const std::vector<dof_id_type> & dof_indices,
    1776             :                        const THREAD_ID tid)
    1777             : {
    1778           0 :   for (const auto i : index_range(_nl))
    1779             :   {
    1780           0 :     _assembly[tid][i]->reinit(elem);
    1781           0 :     _nl[i]->prepare(tid);
    1782             :   }
    1783             : 
    1784           0 :   _aux->prepare(tid);
    1785           0 :   const auto current_nl_sys_num = _current_nl_sys->number();
    1786           0 :   _assembly[tid][current_nl_sys_num]->prepareBlock(ivar, jvar, dof_indices);
    1787           0 :   if (_has_nonlocal_coupling)
    1788           0 :     if (_nonlocal_cm[current_nl_sys_num](ivar, jvar) != 0)
    1789             :     {
    1790           0 :       MooseVariableFEBase & jv = _current_nl_sys->getVariable(tid, jvar);
    1791           0 :       _assembly[tid][current_nl_sys_num]->prepareBlockNonlocal(
    1792             :           ivar, jvar, dof_indices, jv.allDofIndices());
    1793             :     }
    1794             : 
    1795           0 :   if (_displaced_problem && (_reinit_displaced_elem || _reinit_displaced_face))
    1796             :   {
    1797           0 :     _displaced_problem->prepare(_displaced_mesh->elemPtr(elem->id()), ivar, jvar, dof_indices, tid);
    1798           0 :     if (_has_nonlocal_coupling)
    1799           0 :       if (_nonlocal_cm[current_nl_sys_num](ivar, jvar) != 0)
    1800             :       {
    1801           0 :         MooseVariableFEBase & jv = _current_nl_sys->getVariable(tid, jvar);
    1802           0 :         _displaced_problem->prepareBlockNonlocal(ivar, jvar, dof_indices, jv.allDofIndices(), tid);
    1803             :       }
    1804             :   }
    1805           0 : }
    1806             : 
    1807             : void
    1808   471808933 : FEProblemBase::setCurrentSubdomainID(const Elem * elem, const THREAD_ID tid)
    1809             : {
    1810   471808933 :   SubdomainID did = elem->subdomain_id();
    1811   947555525 :   for (const auto i : index_range(_solver_systems))
    1812             :   {
    1813   475746592 :     _assembly[tid][i]->setCurrentSubdomainID(did);
    1814   489956196 :     if (_displaced_problem &&
    1815   489956196 :         (_reinit_displaced_elem || _reinit_displaced_face || _reinit_displaced_neighbor))
    1816     8817056 :       _displaced_problem->assembly(tid, i).setCurrentSubdomainID(did);
    1817             :   }
    1818   471808933 : }
    1819             : 
    1820             : void
    1821  1663490364 : FEProblemBase::setNeighborSubdomainID(const Elem * elem, unsigned int side, const THREAD_ID tid)
    1822             : {
    1823  1663490364 :   SubdomainID did = elem->neighbor_ptr(side)->subdomain_id();
    1824  3332261128 :   for (const auto i : index_range(_nl))
    1825             :   {
    1826  1668770764 :     _assembly[tid][i]->setCurrentNeighborSubdomainID(did);
    1827  1718454867 :     if (_displaced_problem &&
    1828  1718454867 :         (_reinit_displaced_elem || _reinit_displaced_face || _reinit_displaced_neighbor))
    1829    29111734 :       _displaced_problem->assembly(tid, i).setCurrentNeighborSubdomainID(did);
    1830             :   }
    1831  1663490364 : }
    1832             : 
    1833             : void
    1834    23572031 : FEProblemBase::setNeighborSubdomainID(const Elem * elem, const THREAD_ID tid)
    1835             : {
    1836    23572031 :   SubdomainID did = elem->subdomain_id();
    1837    48214288 :   for (const auto i : index_range(_nl))
    1838             :   {
    1839    24642257 :     _assembly[tid][i]->setCurrentNeighborSubdomainID(did);
    1840    24699961 :     if (_displaced_problem &&
    1841    24699961 :         (_reinit_displaced_elem || _reinit_displaced_face || _reinit_displaced_neighbor))
    1842       57704 :       _displaced_problem->assembly(tid, i).setCurrentNeighborSubdomainID(did);
    1843             :   }
    1844    23572031 : }
    1845             : 
    1846             : void
    1847      153242 : FEProblemBase::prepareAssembly(const THREAD_ID tid)
    1848             : {
    1849      153242 :   _assembly[tid][_current_nl_sys->number()]->prepare();
    1850      153242 :   if (_has_nonlocal_coupling)
    1851           0 :     _assembly[tid][_current_nl_sys->number()]->prepareNonlocal();
    1852             : 
    1853      153242 :   if (_displaced_problem && (_reinit_displaced_elem || _reinit_displaced_face))
    1854             :   {
    1855       57704 :     _displaced_problem->prepareAssembly(tid);
    1856       57704 :     if (_has_nonlocal_coupling)
    1857           0 :       _displaced_problem->prepareNonlocal(tid);
    1858             :   }
    1859      153242 : }
    1860             : 
    1861             : void
    1862      299901 : FEProblemBase::addResidual(const THREAD_ID tid)
    1863             : {
    1864      599802 :   _assembly[tid][_current_nl_sys->number()]->addResidual(Assembly::GlobalDataKey{},
    1865      299901 :                                                          currentResidualVectorTags());
    1866             : 
    1867      299901 :   if (_displaced_problem)
    1868        5288 :     _displaced_problem->addResidual(tid);
    1869      299901 : }
    1870             : 
    1871             : void
    1872     2337539 : FEProblemBase::addResidualNeighbor(const THREAD_ID tid)
    1873             : {
    1874     4675078 :   _assembly[tid][_current_nl_sys->number()]->addResidualNeighbor(Assembly::GlobalDataKey{},
    1875     2337539 :                                                                  currentResidualVectorTags());
    1876             : 
    1877     2337539 :   if (_displaced_problem)
    1878       68460 :     _displaced_problem->addResidualNeighbor(tid);
    1879     2337539 : }
    1880             : 
    1881             : void
    1882     2312671 : FEProblemBase::addResidualLower(const THREAD_ID tid)
    1883             : {
    1884     4625342 :   _assembly[tid][_current_nl_sys->number()]->addResidualLower(Assembly::GlobalDataKey{},
    1885     2312671 :                                                               currentResidualVectorTags());
    1886             : 
    1887     2312671 :   if (_displaced_problem)
    1888       68688 :     _displaced_problem->addResidualLower(tid);
    1889     2312671 : }
    1890             : 
    1891             : void
    1892       64576 : FEProblemBase::addResidualScalar(const THREAD_ID tid /* = 0*/)
    1893             : {
    1894      129152 :   _assembly[tid][_current_nl_sys->number()]->addResidualScalar(Assembly::GlobalDataKey{},
    1895       64576 :                                                                currentResidualVectorTags());
    1896       64576 : }
    1897             : 
    1898             : void
    1899   329375914 : FEProblemBase::cacheResidual(const THREAD_ID tid)
    1900             : {
    1901   329375914 :   SubProblem::cacheResidual(tid);
    1902   329375914 :   if (_displaced_problem)
    1903     8645975 :     _displaced_problem->cacheResidual(tid);
    1904   329375914 : }
    1905             : 
    1906             : void
    1907       55594 : FEProblemBase::cacheResidualNeighbor(const THREAD_ID tid)
    1908             : {
    1909       55594 :   SubProblem::cacheResidualNeighbor(tid);
    1910       55594 :   if (_displaced_problem)
    1911          36 :     _displaced_problem->cacheResidualNeighbor(tid);
    1912       55594 : }
    1913             : 
    1914             : void
    1915    19071646 : FEProblemBase::addCachedResidual(const THREAD_ID tid)
    1916             : {
    1917    19071646 :   SubProblem::addCachedResidual(tid);
    1918    19071646 :   if (_displaced_problem)
    1919      555761 :     _displaced_problem->addCachedResidual(tid);
    1920    19071646 : }
    1921             : 
    1922             : void
    1923       11826 : FEProblemBase::addCachedResidualDirectly(NumericVector<Number> & residual, const THREAD_ID tid)
    1924             : {
    1925       11826 :   if (_current_nl_sys->hasVector(_current_nl_sys->timeVectorTag()))
    1926       32553 :     _assembly[tid][_current_nl_sys->number()]->addCachedResidualDirectly(
    1927       32553 :         residual, Assembly::GlobalDataKey{}, getVectorTag(_current_nl_sys->timeVectorTag()));
    1928             : 
    1929       11826 :   if (_current_nl_sys->hasVector(_current_nl_sys->nonTimeVectorTag()))
    1930       35478 :     _assembly[tid][_current_nl_sys->number()]->addCachedResidualDirectly(
    1931       35478 :         residual, Assembly::GlobalDataKey{}, getVectorTag(_current_nl_sys->nonTimeVectorTag()));
    1932             : 
    1933             :   // We do this because by adding the cached residual directly, we cannot ensure that all of the
    1934             :   // cached residuals are emptied after only the two add calls above
    1935       11826 :   _assembly[tid][_current_nl_sys->number()]->clearCachedResiduals(Assembly::GlobalDataKey{});
    1936             : 
    1937       11826 :   if (_displaced_problem)
    1938          48 :     _displaced_problem->addCachedResidualDirectly(residual, tid);
    1939       11826 : }
    1940             : 
    1941             : void
    1942           0 : FEProblemBase::setResidual(NumericVector<Number> & residual, const THREAD_ID tid)
    1943             : {
    1944           0 :   _assembly[tid][_current_nl_sys->number()]->setResidual(
    1945             :       residual,
    1946           0 :       Assembly::GlobalDataKey{},
    1947           0 :       getVectorTag(_nl[_current_nl_sys->number()]->residualVectorTag()));
    1948           0 :   if (_displaced_problem)
    1949           0 :     _displaced_problem->setResidual(residual, tid);
    1950           0 : }
    1951             : 
    1952             : void
    1953           0 : FEProblemBase::setResidualNeighbor(NumericVector<Number> & residual, const THREAD_ID tid)
    1954             : {
    1955           0 :   _assembly[tid][_current_nl_sys->number()]->setResidualNeighbor(
    1956           0 :       residual, Assembly::GlobalDataKey{}, getVectorTag(_current_nl_sys->residualVectorTag()));
    1957           0 :   if (_displaced_problem)
    1958           0 :     _displaced_problem->setResidualNeighbor(residual, tid);
    1959           0 : }
    1960             : 
    1961             : void
    1962       42048 : FEProblemBase::addJacobian(const THREAD_ID tid)
    1963             : {
    1964       42048 :   _assembly[tid][_current_nl_sys->number()]->addJacobian(Assembly::GlobalDataKey{});
    1965       42048 :   if (_has_nonlocal_coupling)
    1966           0 :     _assembly[tid][_current_nl_sys->number()]->addJacobianNonlocal(Assembly::GlobalDataKey{});
    1967       42048 :   if (_displaced_problem)
    1968             :   {
    1969         224 :     _displaced_problem->addJacobian(tid);
    1970         224 :     if (_has_nonlocal_coupling)
    1971           0 :       _displaced_problem->addJacobianNonlocal(tid);
    1972             :   }
    1973       42048 : }
    1974             : 
    1975             : void
    1976        9105 : FEProblemBase::addJacobianNeighbor(const THREAD_ID tid)
    1977             : {
    1978        9105 :   _assembly[tid][_current_nl_sys->number()]->addJacobianNeighbor(Assembly::GlobalDataKey{});
    1979        9105 :   if (_displaced_problem)
    1980          54 :     _displaced_problem->addJacobianNeighbor(tid);
    1981        9105 : }
    1982             : 
    1983             : void
    1984      127506 : FEProblemBase::addJacobianNeighborLowerD(const THREAD_ID tid)
    1985             : {
    1986      127506 :   _assembly[tid][_current_nl_sys->number()]->addJacobianNeighborLowerD(Assembly::GlobalDataKey{});
    1987      127506 :   if (_displaced_problem)
    1988        3456 :     _displaced_problem->addJacobianNeighborLowerD(tid);
    1989      127506 : }
    1990             : 
    1991             : void
    1992        5220 : FEProblemBase::addJacobianLowerD(const THREAD_ID tid)
    1993             : {
    1994        5220 :   _assembly[tid][_current_nl_sys->number()]->addJacobianLowerD(Assembly::GlobalDataKey{});
    1995        5220 :   if (_displaced_problem)
    1996         216 :     _displaced_problem->addJacobianLowerD(tid);
    1997        5220 : }
    1998             : 
    1999             : void
    2000       15622 : FEProblemBase::addJacobianScalar(const THREAD_ID tid /* = 0*/)
    2001             : {
    2002       15622 :   _assembly[tid][_current_nl_sys->number()]->addJacobianScalar(Assembly::GlobalDataKey{});
    2003       15622 : }
    2004             : 
    2005             : void
    2006       39233 : FEProblemBase::addJacobianOffDiagScalar(unsigned int ivar, const THREAD_ID tid /* = 0*/)
    2007             : {
    2008       78466 :   _assembly[tid][_current_nl_sys->number()]->addJacobianOffDiagScalar(ivar,
    2009       39233 :                                                                       Assembly::GlobalDataKey{});
    2010       39233 : }
    2011             : 
    2012             : void
    2013    55521385 : FEProblemBase::cacheJacobian(const THREAD_ID tid)
    2014             : {
    2015    55521385 :   SubProblem::cacheJacobian(tid);
    2016    55521385 :   if (_displaced_problem)
    2017     1767232 :     _displaced_problem->cacheJacobian(tid);
    2018    55521385 : }
    2019             : 
    2020             : void
    2021       10576 : FEProblemBase::cacheJacobianNeighbor(const THREAD_ID tid)
    2022             : {
    2023       10576 :   SubProblem::cacheJacobianNeighbor(tid);
    2024       10576 :   if (_displaced_problem)
    2025           0 :     _displaced_problem->cacheJacobianNeighbor(tid);
    2026       10576 : }
    2027             : 
    2028             : void
    2029     3465172 : FEProblemBase::addCachedJacobian(const THREAD_ID tid)
    2030             : {
    2031     3465172 :   SubProblem::addCachedJacobian(tid);
    2032     3465168 :   if (_displaced_problem)
    2033      108865 :     _displaced_problem->addCachedJacobian(tid);
    2034     3465168 : }
    2035             : 
    2036             : void
    2037       81172 : FEProblemBase::addJacobianBlockTags(SparseMatrix<Number> & jacobian,
    2038             :                                     unsigned int ivar,
    2039             :                                     unsigned int jvar,
    2040             :                                     const DofMap & dof_map,
    2041             :                                     std::vector<dof_id_type> & dof_indices,
    2042             :                                     const std::set<TagID> & tags,
    2043             :                                     const THREAD_ID tid)
    2044             : {
    2045      162344 :   _assembly[tid][_current_nl_sys->number()]->addJacobianBlockTags(
    2046       81172 :       jacobian, ivar, jvar, dof_map, dof_indices, Assembly::GlobalDataKey{}, tags);
    2047             : 
    2048       81172 :   if (_has_nonlocal_coupling)
    2049           0 :     if (_nonlocal_cm[_current_nl_sys->number()](ivar, jvar) != 0)
    2050             :     {
    2051           0 :       MooseVariableFEBase & jv = _current_nl_sys->getVariable(tid, jvar);
    2052           0 :       _assembly[tid][_current_nl_sys->number()]->addJacobianBlockNonlocalTags(
    2053             :           jacobian,
    2054             :           ivar,
    2055             :           jvar,
    2056             :           dof_map,
    2057             :           dof_indices,
    2058             :           jv.allDofIndices(),
    2059           0 :           Assembly::GlobalDataKey{},
    2060             :           tags);
    2061             :     }
    2062             : 
    2063       81172 :   if (_displaced_problem)
    2064             :   {
    2065           0 :     _displaced_problem->addJacobianBlockTags(jacobian, ivar, jvar, dof_map, dof_indices, tags, tid);
    2066           0 :     if (_has_nonlocal_coupling)
    2067           0 :       if (_nonlocal_cm[_current_nl_sys->number()](ivar, jvar) != 0)
    2068             :       {
    2069           0 :         MooseVariableFEBase & jv = _current_nl_sys->getVariable(tid, jvar);
    2070           0 :         _displaced_problem->addJacobianBlockNonlocal(
    2071             :             jacobian, ivar, jvar, dof_map, dof_indices, jv.allDofIndices(), tags, tid);
    2072             :       }
    2073             :   }
    2074       81172 : }
    2075             : 
    2076             : void
    2077        1344 : FEProblemBase::addJacobianNeighbor(SparseMatrix<Number> & jacobian,
    2078             :                                    unsigned int ivar,
    2079             :                                    unsigned int jvar,
    2080             :                                    const DofMap & dof_map,
    2081             :                                    std::vector<dof_id_type> & dof_indices,
    2082             :                                    std::vector<dof_id_type> & neighbor_dof_indices,
    2083             :                                    const std::set<TagID> & tags,
    2084             :                                    const THREAD_ID tid)
    2085             : {
    2086        2688 :   _assembly[tid][_current_nl_sys->number()]->addJacobianNeighborTags(jacobian,
    2087             :                                                                      ivar,
    2088             :                                                                      jvar,
    2089             :                                                                      dof_map,
    2090             :                                                                      dof_indices,
    2091             :                                                                      neighbor_dof_indices,
    2092        1344 :                                                                      Assembly::GlobalDataKey{},
    2093             :                                                                      tags);
    2094        1344 :   if (_displaced_problem)
    2095           0 :     _displaced_problem->addJacobianNeighbor(
    2096             :         jacobian, ivar, jvar, dof_map, dof_indices, neighbor_dof_indices, tags, tid);
    2097        1344 : }
    2098             : 
    2099             : void
    2100   146024609 : FEProblemBase::prepareShapes(unsigned int var, const THREAD_ID tid)
    2101             : {
    2102   146024609 :   _assembly[tid][_current_nl_sys->number()]->copyShapes(var);
    2103   146024609 : }
    2104             : 
    2105             : void
    2106      720551 : FEProblemBase::prepareFaceShapes(unsigned int var, const THREAD_ID tid)
    2107             : {
    2108      720551 :   _assembly[tid][_current_nl_sys->number()]->copyFaceShapes(var);
    2109      720551 : }
    2110             : 
    2111             : void
    2112      217901 : FEProblemBase::prepareNeighborShapes(unsigned int var, const THREAD_ID tid)
    2113             : {
    2114      217901 :   _assembly[tid][_current_nl_sys->number()]->copyNeighborShapes(var);
    2115      217901 : }
    2116             : 
    2117             : void
    2118      965942 : FEProblemBase::addGhostedElem(dof_id_type elem_id)
    2119             : {
    2120      965942 :   if (_mesh.elemPtr(elem_id)->processor_id() != processor_id())
    2121      205714 :     _ghosted_elems.insert(elem_id);
    2122      965942 : }
    2123             : 
    2124             : void
    2125       31700 : FEProblemBase::addGhostedBoundary(BoundaryID boundary_id)
    2126             : {
    2127       31700 :   _mesh.addGhostedBoundary(boundary_id);
    2128       31700 :   if (_displaced_problem)
    2129       28798 :     _displaced_mesh->addGhostedBoundary(boundary_id);
    2130       31700 : }
    2131             : 
    2132             : void
    2133       70074 : FEProblemBase::ghostGhostedBoundaries()
    2134             : {
    2135      350370 :   TIME_SECTION("ghostGhostedBoundaries", 3, "Ghosting Ghosted Boundaries");
    2136             : 
    2137       70074 :   _mesh.ghostGhostedBoundaries();
    2138             : 
    2139       70074 :   if (_displaced_problem)
    2140        2879 :     _displaced_mesh->ghostGhostedBoundaries();
    2141       70074 : }
    2142             : 
    2143             : void
    2144           0 : FEProblemBase::sizeZeroes(unsigned int /*size*/, const THREAD_ID /*tid*/)
    2145             : {
    2146           0 :   mooseDoOnce(mooseWarning(
    2147             :       "This function is deprecated and no longer performs any function. Please do not call it."));
    2148           0 : }
    2149             : 
    2150             : bool
    2151      341949 : FEProblemBase::reinitDirac(const Elem * elem, const THREAD_ID tid)
    2152             : {
    2153      341949 :   std::vector<Point> & points = _dirac_kernel_info.getPoints()[elem].first;
    2154             : 
    2155      341949 :   unsigned int n_points = points.size();
    2156             : 
    2157      341949 :   if (n_points)
    2158             :   {
    2159      336437 :     if (n_points > _max_qps)
    2160             :     {
    2161           0 :       _max_qps = n_points;
    2162             : 
    2163             :       /**
    2164             :        * The maximum number of qps can rise if several Dirac points are added to a single element.
    2165             :        * In that case we need to resize the zeros to compensate.
    2166             :        */
    2167           0 :       unsigned int max_qpts = getMaxQps();
    2168           0 :       for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
    2169             :       {
    2170             :         // the highest available order in libMesh is 43
    2171           0 :         _scalar_zero[tid].resize(FORTYTHIRD, 0);
    2172           0 :         _zero[tid].resize(max_qpts, 0);
    2173           0 :         _grad_zero[tid].resize(max_qpts, RealGradient(0.));
    2174           0 :         _second_zero[tid].resize(max_qpts, RealTensor(0.));
    2175           0 :         _vector_zero[tid].resize(max_qpts, RealGradient(0.));
    2176           0 :         _vector_curl_zero[tid].resize(max_qpts, RealGradient(0.));
    2177             :       }
    2178             :     }
    2179             : 
    2180      672874 :     for (const auto i : index_range(_nl))
    2181             :     {
    2182      336437 :       _assembly[tid][i]->reinitAtPhysical(elem, points);
    2183      336437 :       _nl[i]->prepare(tid);
    2184             :     }
    2185      336437 :     _aux->prepare(tid);
    2186             : 
    2187      336437 :     reinitElem(elem, tid);
    2188             :   }
    2189             : 
    2190      341949 :   _assembly[tid][_current_nl_sys->number()]->prepare();
    2191      341949 :   if (_has_nonlocal_coupling)
    2192           0 :     _assembly[tid][_current_nl_sys->number()]->prepareNonlocal();
    2193             : 
    2194      341949 :   bool have_points = n_points > 0;
    2195      341949 :   if (_displaced_problem && (_reinit_displaced_elem))
    2196             :   {
    2197        5512 :     have_points |= _displaced_problem->reinitDirac(_displaced_mesh->elemPtr(elem->id()), tid);
    2198        5512 :     if (_has_nonlocal_coupling)
    2199           0 :       _displaced_problem->prepareNonlocal(tid);
    2200             :   }
    2201             : 
    2202      341949 :   return have_points;
    2203             : }
    2204             : 
    2205             : void
    2206   431260861 : FEProblemBase::reinitElem(const Elem * elem, const THREAD_ID tid)
    2207             : {
    2208   865320682 :   for (auto & sys : _solver_systems)
    2209   434059821 :     sys->reinitElem(elem, tid);
    2210   431260861 :   _aux->reinitElem(elem, tid);
    2211             : 
    2212   431260861 :   if (_displaced_problem && _reinit_displaced_elem)
    2213     4961598 :     _displaced_problem->reinitElem(_displaced_mesh->elemPtr(elem->id()), tid);
    2214   431260861 : }
    2215             : 
    2216             : void
    2217       53471 : FEProblemBase::reinitElemPhys(const Elem * const elem,
    2218             :                               const std::vector<Point> & phys_points_in_elem,
    2219             :                               const THREAD_ID tid)
    2220             : {
    2221             :   mooseAssert(_mesh.queryElemPtr(elem->id()) == elem,
    2222             :               "Are you calling this method with a displaced mesh element?");
    2223             : 
    2224      106942 :   for (const auto i : index_range(_solver_systems))
    2225             :   {
    2226       53471 :     _assembly[tid][i]->reinitAtPhysical(elem, phys_points_in_elem);
    2227       53471 :     _solver_systems[i]->prepare(tid);
    2228       53471 :     _assembly[tid][i]->prepare();
    2229       53471 :     if (_has_nonlocal_coupling)
    2230           0 :       _assembly[tid][i]->prepareNonlocal();
    2231             :   }
    2232       53471 :   _aux->prepare(tid);
    2233             : 
    2234       53471 :   reinitElem(elem, tid);
    2235       53471 : }
    2236             : 
    2237             : void
    2238           0 : FEProblemBase::reinitElemFace(const Elem * const elem,
    2239             :                               const unsigned int side,
    2240             :                               const BoundaryID,
    2241             :                               const THREAD_ID tid)
    2242             : {
    2243           0 :   mooseDeprecated(
    2244             :       "reinitElemFace with a BoundaryID argument is deprecated because the boundary id was never "
    2245             :       "used. Please call reinitElemFace without the BoundaryID argument instead");
    2246             : 
    2247           0 :   reinitElemFace(elem, side, tid);
    2248           0 : }
    2249             : 
    2250             : void
    2251     8553235 : FEProblemBase::reinitElemFace(const Elem * const elem, const unsigned int side, const THREAD_ID tid)
    2252             : {
    2253    17106875 :   for (const auto i : index_range(_solver_systems))
    2254             :   {
    2255     8553640 :     _assembly[tid][i]->reinit(elem, side);
    2256     8553640 :     _solver_systems[i]->reinitElemFace(elem, side, tid);
    2257             :   }
    2258     8553235 :   _aux->reinitElemFace(elem, side, tid);
    2259             : 
    2260     8553235 :   if (_displaced_problem && _reinit_displaced_face)
    2261       97294 :     _displaced_problem->reinitElemFace(_displaced_mesh->elemPtr(elem->id()), side, tid);
    2262     8553235 : }
    2263             : 
    2264             : void
    2265      300162 : FEProblemBase::reinitLowerDElem(const Elem * lower_d_elem,
    2266             :                                 const THREAD_ID tid,
    2267             :                                 const std::vector<Point> * const pts,
    2268             :                                 const std::vector<Real> * const weights)
    2269             : {
    2270      300162 :   SubProblem::reinitLowerDElem(lower_d_elem, tid, pts, weights);
    2271             : 
    2272      300162 :   if (_displaced_problem && _displaced_mesh)
    2273        1080 :     _displaced_problem->reinitLowerDElem(
    2274        1080 :         _displaced_mesh->elemPtr(lower_d_elem->id()), tid, pts, weights);
    2275      300162 : }
    2276             : 
    2277             : void
    2278    29212471 : FEProblemBase::reinitNode(const Node * node, const THREAD_ID tid)
    2279             : {
    2280    29212471 :   if (_displaced_problem && _reinit_displaced_elem)
    2281     1122418 :     _displaced_problem->reinitNode(&_displaced_mesh->nodeRef(node->id()), tid);
    2282             : 
    2283    58428218 :   for (const auto i : index_range(_nl))
    2284             :   {
    2285    29215747 :     _assembly[tid][i]->reinit(node);
    2286    29215747 :     _nl[i]->reinitNode(node, tid);
    2287             :   }
    2288    29212471 :   _aux->reinitNode(node, tid);
    2289    29212471 : }
    2290             : 
    2291             : void
    2292    71773155 : FEProblemBase::reinitNodeFace(const Node * node, BoundaryID bnd_id, const THREAD_ID tid)
    2293             : {
    2294    71773155 :   if (_displaced_problem && _reinit_displaced_face)
    2295     3818746 :     _displaced_problem->reinitNodeFace(&_displaced_mesh->nodeRef(node->id()), bnd_id, tid);
    2296             : 
    2297   144423718 :   for (const auto i : index_range(_nl))
    2298             :   {
    2299    72650563 :     _assembly[tid][i]->reinit(node);
    2300    72650563 :     _nl[i]->reinitNodeFace(node, bnd_id, tid);
    2301             :   }
    2302    71773155 :   _aux->reinitNodeFace(node, bnd_id, tid);
    2303    71773155 : }
    2304             : 
    2305             : void
    2306        6813 : FEProblemBase::reinitNodes(const std::vector<dof_id_type> & nodes, const THREAD_ID tid)
    2307             : {
    2308        6813 :   if (_displaced_problem && _reinit_displaced_elem)
    2309           0 :     _displaced_problem->reinitNodes(nodes, tid);
    2310             : 
    2311       13626 :   for (auto & nl : _nl)
    2312        6813 :     nl->reinitNodes(nodes, tid);
    2313        6813 :   _aux->reinitNodes(nodes, tid);
    2314        6813 : }
    2315             : 
    2316             : void
    2317         723 : FEProblemBase::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes, const THREAD_ID tid)
    2318             : {
    2319         723 :   if (_displaced_problem && _reinit_displaced_elem)
    2320           0 :     _displaced_problem->reinitNodesNeighbor(nodes, tid);
    2321             : 
    2322        1446 :   for (auto & nl : _nl)
    2323         723 :     nl->reinitNodesNeighbor(nodes, tid);
    2324         723 :   _aux->reinitNodesNeighbor(nodes, tid);
    2325         723 : }
    2326             : 
    2327             : void
    2328     9131703 : FEProblemBase::reinitScalars(const THREAD_ID tid, bool reinit_for_derivative_reordering /*=false*/)
    2329             : {
    2330    45658515 :   TIME_SECTION("reinitScalars", 3, "Reinitializing Scalar Variables");
    2331             : 
    2332     9131703 :   if (_displaced_problem && _reinit_displaced_elem)
    2333      124637 :     _displaced_problem->reinitScalars(tid, reinit_for_derivative_reordering);
    2334             : 
    2335    18508145 :   for (auto & nl : _nl)
    2336     9376442 :     nl->reinitScalars(tid, reinit_for_derivative_reordering);
    2337     9131703 :   _aux->reinitScalars(tid, reinit_for_derivative_reordering);
    2338             : 
    2339             :   // This is called outside of residual/Jacobian call-backs
    2340    18514949 :   for (auto & assembly : _assembly[tid])
    2341     9383246 :     assembly->prepareScalar();
    2342     9131703 : }
    2343             : 
    2344             : void
    2345      210604 : FEProblemBase::reinitOffDiagScalars(const THREAD_ID tid)
    2346             : {
    2347      210604 :   _assembly[tid][_current_nl_sys->number()]->prepareOffDiagScalar();
    2348      210604 :   if (_displaced_problem)
    2349          90 :     _displaced_problem->reinitOffDiagScalars(tid);
    2350      210604 : }
    2351             : 
    2352             : void
    2353     4228377 : FEProblemBase::reinitNeighbor(const Elem * elem, unsigned int side, const THREAD_ID tid)
    2354             : {
    2355     4228377 :   setNeighborSubdomainID(elem, side, tid);
    2356             : 
    2357     4228377 :   const Elem * neighbor = elem->neighbor_ptr(side);
    2358     4228377 :   unsigned int neighbor_side = neighbor->which_neighbor_am_i(elem);
    2359             : 
    2360     8456784 :   for (const auto i : index_range(_nl))
    2361             :   {
    2362     4228407 :     _assembly[tid][i]->reinitElemAndNeighbor(elem, side, neighbor, neighbor_side);
    2363     4228407 :     _nl[i]->prepareNeighbor(tid);
    2364             :     // Called during stateful material property evaluation outside of solve
    2365     4228407 :     _assembly[tid][i]->prepareNeighbor();
    2366             :   }
    2367     4228377 :   _aux->prepareNeighbor(tid);
    2368             : 
    2369     8456784 :   for (auto & nl : _nl)
    2370             :   {
    2371     4228407 :     nl->reinitElemFace(elem, side, tid);
    2372     4228407 :     nl->reinitNeighborFace(neighbor, neighbor_side, tid);
    2373             :   }
    2374     4228377 :   _aux->reinitElemFace(elem, side, tid);
    2375     4228377 :   _aux->reinitNeighborFace(neighbor, neighbor_side, tid);
    2376             : 
    2377     4228377 :   if (_displaced_problem && _reinit_displaced_neighbor)
    2378             :   {
    2379             :     // There are cases like for cohesive zone modeling without significant sliding where we cannot
    2380             :     // use FEInterface::inverse_map in Assembly::reinitElemAndNeighbor in the displaced problem
    2381             :     // because the physical points coming from the element don't actually lie on the neighbor.
    2382             :     // Moreover, what's the point of doing another physical point inversion in other cases? We only
    2383             :     // care about the reference points which we can just take from the undisplaced computation
    2384       71886 :     const auto & displaced_ref_pts = _assembly[tid][0]->qRuleNeighbor()->get_points();
    2385             : 
    2386       71886 :     _displaced_problem->reinitNeighbor(
    2387       71886 :         _displaced_mesh->elemPtr(elem->id()), side, tid, &displaced_ref_pts);
    2388             :   }
    2389     4228377 : }
    2390             : 
    2391             : void
    2392     2433898 : FEProblemBase::reinitElemNeighborAndLowerD(const Elem * elem,
    2393             :                                            unsigned int side,
    2394             :                                            const THREAD_ID tid)
    2395             : {
    2396     2433898 :   reinitNeighbor(elem, side, tid);
    2397             : 
    2398     2433898 :   const Elem * lower_d_elem = _mesh.getLowerDElem(elem, side);
    2399     2433898 :   if (lower_d_elem && _mesh.interiorLowerDBlocks().count(lower_d_elem->subdomain_id()) > 0)
    2400       11610 :     reinitLowerDElem(lower_d_elem, tid);
    2401             :   else
    2402             :   {
    2403             :     // with mesh refinement, lower-dimensional element might be defined on neighbor side
    2404     2422288 :     auto & neighbor = _assembly[tid][0]->neighbor();
    2405     2422288 :     auto & neighbor_side = _assembly[tid][0]->neighborSide();
    2406     2422288 :     const Elem * lower_d_elem_neighbor = _mesh.getLowerDElem(neighbor, neighbor_side);
    2407     2422288 :     if (lower_d_elem_neighbor &&
    2408     2422288 :         _mesh.interiorLowerDBlocks().count(lower_d_elem_neighbor->subdomain_id()) > 0)
    2409             :     {
    2410           0 :       auto qps = _assembly[tid][0]->qPointsFaceNeighbor().stdVector();
    2411           0 :       std::vector<Point> reference_points;
    2412           0 :       FEMap::inverse_map(
    2413           0 :           lower_d_elem_neighbor->dim(), lower_d_elem_neighbor, qps, reference_points);
    2414           0 :       reinitLowerDElem(lower_d_elem_neighbor, tid, &reference_points);
    2415           0 :     }
    2416             :   }
    2417             : 
    2418     2433898 :   if (_displaced_problem && (_reinit_displaced_face || _reinit_displaced_neighbor))
    2419       71820 :     _displaced_problem->reinitElemNeighborAndLowerD(
    2420       71820 :         _displaced_mesh->elemPtr(elem->id()), side, tid);
    2421     2433898 : }
    2422             : 
    2423             : void
    2424      108178 : FEProblemBase::reinitNeighborPhys(const Elem * neighbor,
    2425             :                                   unsigned int neighbor_side,
    2426             :                                   const std::vector<Point> & physical_points,
    2427             :                                   const THREAD_ID tid)
    2428             : {
    2429             :   mooseAssert(_mesh.queryElemPtr(neighbor->id()) == neighbor,
    2430             :               "Are you calling this method with a displaced mesh element?");
    2431             : 
    2432      216356 :   for (const auto i : index_range(_nl))
    2433             :   {
    2434             :     // Reinits shape the functions at the physical points
    2435      108178 :     _assembly[tid][i]->reinitNeighborAtPhysical(neighbor, neighbor_side, physical_points);
    2436             : 
    2437             :     // Sets the neighbor dof indices
    2438      108178 :     _nl[i]->prepareNeighbor(tid);
    2439             :   }
    2440      108178 :   _aux->prepareNeighbor(tid);
    2441             : 
    2442             :   // Resizes Re and Ke
    2443      108178 :   _assembly[tid][_current_nl_sys->number()]->prepareNeighbor();
    2444             : 
    2445             :   // Compute the values of each variable at the points
    2446      216356 :   for (auto & nl : _nl)
    2447      108178 :     nl->reinitNeighborFace(neighbor, neighbor_side, tid);
    2448      108178 :   _aux->reinitNeighborFace(neighbor, neighbor_side, tid);
    2449      108178 : }
    2450             : 
    2451             : void
    2452       22720 : FEProblemBase::reinitNeighborPhys(const Elem * neighbor,
    2453             :                                   const std::vector<Point> & physical_points,
    2454             :                                   const THREAD_ID tid)
    2455             : {
    2456             :   mooseAssert(_mesh.queryElemPtr(neighbor->id()) == neighbor,
    2457             :               "Are you calling this method with a displaced mesh element?");
    2458             : 
    2459       45440 :   for (const auto i : index_range(_nl))
    2460             :   {
    2461             :     // Reinits shape the functions at the physical points
    2462       22720 :     _assembly[tid][i]->reinitNeighborAtPhysical(neighbor, physical_points);
    2463             : 
    2464             :     // Sets the neighbor dof indices
    2465       22720 :     _nl[i]->prepareNeighbor(tid);
    2466             :   }
    2467       22720 :   _aux->prepareNeighbor(tid);
    2468             : 
    2469             :   // Resizes Re and Ke
    2470       22720 :   _assembly[tid][_current_nl_sys->number()]->prepareNeighbor();
    2471             : 
    2472             :   // Compute the values of each variable at the points
    2473       45440 :   for (auto & nl : _nl)
    2474       22720 :     nl->reinitNeighbor(neighbor, tid);
    2475       22720 :   _aux->reinitNeighbor(neighbor, tid);
    2476       22720 : }
    2477             : 
    2478             : void
    2479       38401 : FEProblemBase::getDiracElements(std::set<const Elem *> & elems)
    2480             : {
    2481             :   // First add in the undisplaced elements
    2482       38401 :   elems = _dirac_kernel_info.getElements();
    2483             : 
    2484       38401 :   if (_displaced_problem)
    2485             :   {
    2486        2539 :     std::set<const Elem *> displaced_elements;
    2487        2539 :     _displaced_problem->getDiracElements(displaced_elements);
    2488             : 
    2489             :     { // Use the ids from the displaced elements to get the undisplaced elements
    2490             :       // and add them to the list
    2491        8051 :       for (const auto & elem : displaced_elements)
    2492        5512 :         elems.insert(_mesh.elemPtr(elem->id()));
    2493             :     }
    2494        2539 :   }
    2495       38401 : }
    2496             : 
    2497             : void
    2498     3862291 : FEProblemBase::clearDiracInfo()
    2499             : {
    2500     3862291 :   _dirac_kernel_info.clearPoints();
    2501             : 
    2502     3862291 :   if (_displaced_problem)
    2503      159253 :     _displaced_problem->clearDiracInfo();
    2504     3862291 : }
    2505             : 
    2506             : void
    2507     6059448 : FEProblemBase::subdomainSetup(SubdomainID subdomain, const THREAD_ID tid)
    2508             : {
    2509     6059448 :   _all_materials.subdomainSetup(subdomain, tid);
    2510             :   // Call the subdomain methods of the output system, these are not threaded so only call it once
    2511     6059448 :   if (tid == 0)
    2512     5610509 :     _app.getOutputWarehouse().subdomainSetup();
    2513             : 
    2514    12270426 :   for (auto & nl : _nl)
    2515     6210978 :     nl->subdomainSetup(subdomain, tid);
    2516             : 
    2517             :   // FIXME: call displaced_problem->subdomainSetup() ?
    2518             :   //        When adding possibility with materials being evaluated on displaced mesh
    2519     6059448 : }
    2520             : 
    2521             : void
    2522    18300817 : FEProblemBase::neighborSubdomainSetup(SubdomainID subdomain, const THREAD_ID tid)
    2523             : {
    2524    18300817 :   _all_materials.neighborSubdomainSetup(subdomain, tid);
    2525    18300817 : }
    2526             : 
    2527             : void
    2528       53061 : FEProblemBase::addFunction(const std::string & type,
    2529             :                            const std::string & name,
    2530             :                            InputParameters & parameters)
    2531             : {
    2532             :   parallel_object_only();
    2533             : 
    2534      106122 :   parameters.set<SubProblem *>("_subproblem") = this;
    2535             : 
    2536      110068 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    2537             :   {
    2538       57144 :     std::shared_ptr<Function> func = _factory.create<Function>(type, name, parameters, tid);
    2539       57007 :     logAdd("Function", name, type, parameters);
    2540       57007 :     _functions.addObject(func, tid);
    2541             : 
    2542       57007 :     if (auto * const functor = dynamic_cast<Moose::FunctorBase<Real> *>(func.get()))
    2543             :     {
    2544       57007 :       this->addFunctor(name, *functor, tid);
    2545       57007 :       if (_displaced_problem)
    2546        1953 :         _displaced_problem->addFunctor(name, *functor, tid);
    2547             :     }
    2548             :     else
    2549           0 :       mooseError("Unrecognized function functor type");
    2550       57007 :   }
    2551       52924 : }
    2552             : 
    2553             : void
    2554      159423 : FEProblemBase::addConvergence(const std::string & type,
    2555             :                               const std::string & name,
    2556             :                               InputParameters & parameters)
    2557             : {
    2558             :   parallel_object_only();
    2559             : 
    2560      334393 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    2561             :   {
    2562      175006 :     std::shared_ptr<Convergence> conv = _factory.create<Convergence>(type, name, parameters, tid);
    2563      174970 :     _convergences.addObject(conv, tid);
    2564      174970 :   }
    2565      159387 : }
    2566             : 
    2567             : void
    2568       63002 : FEProblemBase::addDefaultNonlinearConvergence(const InputParameters & params_to_apply)
    2569             : {
    2570       63002 :   const std::string class_name = "DefaultNonlinearConvergence";
    2571       63002 :   InputParameters params = _factory.getValidParams(class_name);
    2572       63002 :   params.applyParameters(params_to_apply);
    2573       63002 :   params.applyParameters(parameters());
    2574       63002 :   params.set<bool>("added_as_default") = true;
    2575      124943 :   for (const auto & conv_name : getNonlinearConvergenceNames())
    2576       61941 :     addConvergence(class_name, conv_name, params);
    2577       63002 : }
    2578             : 
    2579             : void
    2580       63811 : FEProblemBase::addDefaultMultiAppFixedPointConvergence(const InputParameters & params_to_apply)
    2581             : {
    2582       63811 :   const std::string class_name = "DefaultMultiAppFixedPointConvergence";
    2583       63811 :   InputParameters params = _factory.getValidParams(class_name);
    2584       63811 :   params.applyParameters(params_to_apply);
    2585       63811 :   params.applyParameters(parameters());
    2586       63811 :   params.set<bool>("added_as_default") = true;
    2587       63811 :   addConvergence(class_name, getMultiAppFixedPointConvergenceName(), params);
    2588       63799 : }
    2589             : 
    2590             : void
    2591       31731 : FEProblemBase::addDefaultSteadyStateConvergence(const InputParameters & params_to_apply)
    2592             : {
    2593       31731 :   const std::string class_name = "DefaultSteadyStateConvergence";
    2594       31731 :   InputParameters params = _factory.getValidParams(class_name);
    2595       31731 :   params.applyParameters(params_to_apply);
    2596       31731 :   params.applyParameters(parameters());
    2597       31731 :   params.set<bool>("added_as_default") = true;
    2598       31731 :   addConvergence(class_name, getSteadyStateConvergenceName(), params);
    2599       31731 : }
    2600             : 
    2601             : bool
    2602       88771 : FEProblemBase::hasFunction(const std::string & name, const THREAD_ID tid)
    2603             : {
    2604       88771 :   return _functions.hasActiveObject(name, tid);
    2605             : }
    2606             : 
    2607             : Function &
    2608       64713 : FEProblemBase::getFunction(const std::string & name, const THREAD_ID tid)
    2609             : {
    2610             :   // This thread lock is necessary since this method will create functions
    2611             :   // for all threads if one is missing.
    2612       64713 :   Threads::spin_mutex::scoped_lock lock(get_function_mutex);
    2613             : 
    2614       64713 :   if (!hasFunction(name, tid))
    2615             :   {
    2616             :     // If we didn't find a function, it might be a default function, attempt to construct one now
    2617       20215 :     std::istringstream ss(name);
    2618             :     Real real_value;
    2619             : 
    2620             :     // First see if it's just a constant. If it is, build a ConstantFunction
    2621       20215 :     if (ss >> real_value && ss.eof())
    2622             :     {
    2623       12938 :       InputParameters params = _factory.getValidParams("ConstantFunction");
    2624       12938 :       params.set<Real>("value") = real_value;
    2625       19407 :       addFunction("ConstantFunction", ss.str(), params);
    2626        6469 :     }
    2627             :     else
    2628             :     {
    2629       13746 :       FunctionParserBase<Real> fp;
    2630       13746 :       std::string vars = "x,y,z,t,NaN,pi,e";
    2631       13746 :       if (fp.Parse(name, vars) == -1) // -1 for success
    2632             :       {
    2633             :         // It parsed ok, so build a MooseParsedFunction
    2634       41226 :         InputParameters params = _factory.getValidParams("ParsedFunction");
    2635       13742 :         params.set<std::string>("expression") = name;
    2636       27484 :         addFunction("ParsedFunction", name, params);
    2637       13742 :       }
    2638       13746 :     }
    2639             : 
    2640             :     // Try once more
    2641       20215 :     if (!hasFunction(name, tid))
    2642           4 :       mooseError("Unable to find function " + name);
    2643       20211 :   }
    2644             : 
    2645       64709 :   auto * const ret = dynamic_cast<Function *>(_functions.getActiveObject(name, tid).get());
    2646       64709 :   if (!ret)
    2647           0 :     mooseError("No function named ", name, " of appropriate type");
    2648             : 
    2649       64709 :   return *ret;
    2650       64709 : }
    2651             : 
    2652             : bool
    2653      220921 : FEProblemBase::hasConvergence(const std::string & name, const THREAD_ID tid) const
    2654             : {
    2655      220921 :   return _convergences.hasActiveObject(name, tid);
    2656             : }
    2657             : 
    2658             : Convergence &
    2659     1229893 : FEProblemBase::getConvergence(const std::string & name, const THREAD_ID tid) const
    2660             : {
    2661     1229893 :   auto * const ret = dynamic_cast<Convergence *>(_convergences.getActiveObject(name, tid).get());
    2662     1229893 :   if (!ret)
    2663           0 :     mooseError("The Convergence object '", name, "' does not exist.");
    2664             : 
    2665     1229893 :   return *ret;
    2666             : }
    2667             : 
    2668             : const std::vector<std::shared_ptr<Convergence>> &
    2669      209858 : FEProblemBase::getConvergenceObjects(const THREAD_ID tid) const
    2670             : {
    2671      209858 :   return _convergences.getActiveObjects(tid);
    2672             : }
    2673             : 
    2674             : void
    2675         770 : FEProblemBase::addMeshDivision(const std::string & type,
    2676             :                                const std::string & name,
    2677             :                                InputParameters & parameters)
    2678             : {
    2679             :   parallel_object_only();
    2680        1540 :   parameters.set<FEProblemBase *>("_fe_problem_base") = this;
    2681        1540 :   parameters.set<SubProblem *>("_subproblem") = this;
    2682        1623 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    2683             :   {
    2684         865 :     std::shared_ptr<MeshDivision> func = _factory.create<MeshDivision>(type, name, parameters, tid);
    2685         853 :     _mesh_divisions.addObject(func, tid);
    2686         853 :   }
    2687         758 : }
    2688             : 
    2689             : MeshDivision &
    2690        1665 : FEProblemBase::getMeshDivision(const std::string & name, const THREAD_ID tid) const
    2691             : {
    2692        1665 :   auto * const ret = dynamic_cast<MeshDivision *>(_mesh_divisions.getActiveObject(name, tid).get());
    2693        1665 :   if (!ret)
    2694           0 :     mooseError("No MeshDivision object named ", name, " of appropriate type");
    2695        1665 :   return *ret;
    2696             : }
    2697             : 
    2698             : void
    2699           0 : FEProblemBase::lineSearch()
    2700             : {
    2701           0 :   _line_search->lineSearch();
    2702           0 : }
    2703             : 
    2704             : NonlinearSystem &
    2705           0 : FEProblemBase::getNonlinearSystem(const unsigned int sys_num)
    2706             : {
    2707           0 :   mooseDeprecated("FEProblemBase::getNonlinearSystem() is deprecated, please use "
    2708             :                   "FEProblemBase::getNonlinearSystemBase() \n");
    2709             : 
    2710             :   mooseAssert(sys_num < _nl.size(), "System number greater than the number of nonlinear systems");
    2711           0 :   auto nl_sys = std::dynamic_pointer_cast<NonlinearSystem>(_nl[sys_num]);
    2712             : 
    2713           0 :   if (!nl_sys)
    2714           0 :     mooseError("This is not a NonlinearSystem");
    2715             : 
    2716           0 :   return *nl_sys;
    2717           0 : }
    2718             : 
    2719             : void
    2720           0 : FEProblemBase::addDistribution(const std::string & type,
    2721             :                                const std::string & name,
    2722             :                                InputParameters & parameters)
    2723             : {
    2724           0 :   parameters.set<std::string>("type") = type;
    2725           0 :   addObject<Distribution>(type, name, parameters, /* threaded = */ false);
    2726           0 : }
    2727             : 
    2728             : Distribution &
    2729           0 : FEProblemBase::getDistribution(const std::string & name)
    2730             : {
    2731           0 :   std::vector<Distribution *> objs;
    2732           0 :   theWarehouse()
    2733           0 :       .query()
    2734           0 :       .condition<AttribSystem>("Distribution")
    2735           0 :       .condition<AttribName>(name)
    2736           0 :       .queryInto(objs);
    2737           0 :   if (objs.empty())
    2738           0 :     mooseError("Unable to find Distribution with name '" + name + "'");
    2739           0 :   return *(objs[0]);
    2740           0 : }
    2741             : 
    2742             : void
    2743         354 : FEProblemBase::addSampler(const std::string & type,
    2744             :                           const std::string & name,
    2745             :                           InputParameters & parameters)
    2746             : {
    2747         354 :   const auto samplers = addObject<Sampler>(type, name, parameters);
    2748         722 :   for (auto & sampler : samplers)
    2749         380 :     sampler->init();
    2750         342 : }
    2751             : 
    2752             : Sampler &
    2753         342 : FEProblemBase::getSampler(const std::string & name, const THREAD_ID tid)
    2754             : {
    2755         342 :   std::vector<Sampler *> objs;
    2756         342 :   theWarehouse()
    2757         684 :       .query()
    2758         342 :       .condition<AttribSystem>("Sampler")
    2759         342 :       .condition<AttribThread>(tid)
    2760         342 :       .condition<AttribName>(name)
    2761         342 :       .queryInto(objs);
    2762         342 :   if (objs.empty())
    2763           0 :     mooseError(
    2764           0 :         "Unable to find Sampler with name '" + name +
    2765             :         "', if you are attempting to access this object in the constructor of another object then "
    2766             :         "the object being retrieved must occur prior to the caller within the input file.");
    2767         684 :   return *(objs[0]);
    2768         342 : }
    2769             : 
    2770             : bool
    2771      161260 : FEProblemBase::duplicateVariableCheck(const std::string & var_name,
    2772             :                                       const FEType & type,
    2773             :                                       bool is_aux,
    2774             :                                       const std::set<SubdomainID> * const active_subdomains)
    2775             : {
    2776      161260 :   std::set<SubdomainID> subdomainIDs;
    2777      161260 :   if (active_subdomains->size() == 0)
    2778             :   {
    2779      152490 :     const auto subdomains = _mesh.meshSubdomains();
    2780      152490 :     subdomainIDs.insert(subdomains.begin(), subdomains.end());
    2781      152490 :   }
    2782             :   else
    2783        8770 :     subdomainIDs.insert(active_subdomains->begin(), active_subdomains->end());
    2784             : 
    2785      323261 :   for (auto & sys : _solver_systems)
    2786             :   {
    2787      162017 :     SystemBase * curr_sys_ptr = sys.get();
    2788      162017 :     SystemBase * other_sys_ptr = _aux.get();
    2789      162017 :     std::string error_prefix = "";
    2790      162017 :     if (is_aux)
    2791             :     {
    2792       96444 :       curr_sys_ptr = _aux.get();
    2793       96444 :       other_sys_ptr = sys.get();
    2794       96444 :       error_prefix = "aux";
    2795             :     }
    2796             : 
    2797      162017 :     if (other_sys_ptr->hasVariable(var_name))
    2798           4 :       mooseError("Cannot have an auxiliary variable and a solver variable with the same name: ",
    2799             :                  var_name);
    2800             : 
    2801      162013 :     if (curr_sys_ptr->hasVariable(var_name))
    2802             :     {
    2803             :       const Variable & var =
    2804          12 :           curr_sys_ptr->system().variable(curr_sys_ptr->system().variable_number(var_name));
    2805             : 
    2806             :       // variable type
    2807          12 :       if (var.type() != type)
    2808             :       {
    2809          16 :         const auto stringifyType = [](FEType t)
    2810          16 :         { return Moose::stringify(t.family) + " of order " + Moose::stringify(t.order); };
    2811             : 
    2812           8 :         mooseError("Mismatching types are specified for ",
    2813             :                    error_prefix,
    2814             :                    "variable with name '",
    2815             :                    var_name,
    2816             :                    "': '",
    2817           8 :                    stringifyType(var.type()),
    2818             :                    "' and '",
    2819           8 :                    stringifyType(type),
    2820             :                    "'");
    2821             :       }
    2822             : 
    2823             :       // block-restriction
    2824           4 :       if (!(active_subdomains->size() == 0 && var.active_subdomains().size() == 0))
    2825             :       {
    2826           4 :         const auto varActiveSubdomains = var.active_subdomains();
    2827           4 :         std::set<SubdomainID> varSubdomainIDs;
    2828           4 :         if (varActiveSubdomains.size() == 0)
    2829             :         {
    2830           0 :           const auto subdomains = _mesh.meshSubdomains();
    2831           0 :           varSubdomainIDs.insert(subdomains.begin(), subdomains.end());
    2832           0 :         }
    2833             :         else
    2834           4 :           varSubdomainIDs.insert(varActiveSubdomains.begin(), varActiveSubdomains.end());
    2835             : 
    2836             :         // Is subdomainIDs a subset of varSubdomainIDs? With this we allow the case that the newly
    2837             :         // requested block restriction is only a subset of the existing one.
    2838           4 :         const auto isSubset = std::includes(varSubdomainIDs.begin(),
    2839             :                                             varSubdomainIDs.end(),
    2840             :                                             subdomainIDs.begin(),
    2841             :                                             subdomainIDs.end());
    2842             : 
    2843           4 :         if (!isSubset)
    2844             :         {
    2845             :           // helper function: make a string from a set of subdomain ids
    2846           8 :           const auto stringifySubdomains = [this](std::set<SubdomainID> subdomainIDs)
    2847             :           {
    2848           8 :             std::stringstream s;
    2849          20 :             for (auto const i : subdomainIDs)
    2850             :             {
    2851             :               // do we need to insert a comma?
    2852          12 :               if (s.tellp() != 0)
    2853           4 :                 s << ", ";
    2854             : 
    2855             :               // insert subdomain name and id -or- only the id (if no name is given)
    2856          12 :               const auto subdomainName = _mesh.getSubdomainName(i);
    2857          12 :               if (subdomainName.empty())
    2858          12 :                 s << i;
    2859             :               else
    2860           0 :                 s << subdomainName << " (" << i << ")";
    2861          12 :             }
    2862          16 :             return s.str();
    2863           8 :           };
    2864             : 
    2865           8 :           const std::string msg = "Mismatching block-restrictions are specified for " +
    2866           8 :                                   error_prefix + "variable with name '" + var_name + "': {" +
    2867          16 :                                   stringifySubdomains(varSubdomainIDs) + "} and {" +
    2868          12 :                                   stringifySubdomains(subdomainIDs) + "}";
    2869             : 
    2870           4 :           mooseError(msg);
    2871           0 :         }
    2872           0 :       }
    2873             : 
    2874           0 :       return true;
    2875             :     }
    2876      162001 :   }
    2877             : 
    2878      161244 :   return false;
    2879      161244 : }
    2880             : 
    2881             : void
    2882       64972 : FEProblemBase::addVariable(const std::string & var_type,
    2883             :                            const std::string & var_name,
    2884             :                            InputParameters & params)
    2885             : {
    2886             :   parallel_object_only();
    2887             : 
    2888       64972 :   const auto order = Utility::string_to_enum<Order>(params.get<MooseEnum>("order"));
    2889       64972 :   const auto family = Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family"));
    2890       64972 :   const auto fe_type = FEType(order, family);
    2891             : 
    2892             :   const auto active_subdomains_vector =
    2893       64972 :       _mesh.getSubdomainIDs(params.get<std::vector<SubdomainName>>("block"));
    2894             :   const std::set<SubdomainID> active_subdomains(active_subdomains_vector.begin(),
    2895       64972 :                                                 active_subdomains_vector.end());
    2896             : 
    2897       64972 :   if (duplicateVariableCheck(var_name, fe_type, /* is_aux = */ false, &active_subdomains))
    2898           0 :     return;
    2899             : 
    2900      194904 :   params.set<FEProblemBase *>("_fe_problem_base") = this;
    2901       64968 :   params.set<Moose::VarKindType>("_var_kind") = Moose::VarKindType::VAR_SOLVER;
    2902       64968 :   SolverSystemName sys_name = params.get<SolverSystemName>("solver_sys");
    2903             : 
    2904       64968 :   const auto solver_system_number = solverSysNum(sys_name);
    2905       64968 :   logAdd("Variable", var_name, var_type, params);
    2906       64968 :   _solver_systems[solver_system_number]->addVariable(var_type, var_name, params);
    2907       64952 :   if (_displaced_problem)
    2908             :     // MooseObjects need to be unique so change the name here
    2909        3839 :     _displaced_problem->addVariable(var_type, var_name, params, solver_system_number);
    2910             : 
    2911       64952 :   _solver_var_to_sys_num[var_name] = solver_system_number;
    2912             : 
    2913       64952 :   markFamilyPRefinement(params);
    2914       64952 : }
    2915             : 
    2916             : std::pair<bool, unsigned int>
    2917     5043687 : FEProblemBase::determineSolverSystem(const std::string & var_name,
    2918             :                                      const bool error_if_not_found) const
    2919             : {
    2920     5043687 :   auto map_it = _solver_var_to_sys_num.find(var_name);
    2921     5043687 :   const bool var_in_sys = map_it != _solver_var_to_sys_num.end();
    2922     5043687 :   if (var_in_sys)
    2923             :     mooseAssert(_solver_systems[map_it->second]->hasVariable(var_name) ||
    2924             :                     _solver_systems[map_it->second]->hasScalarVariable(var_name),
    2925             :                 "If the variable is in our FEProblem solver system map, then it must be in the "
    2926             :                 "solver system we expect");
    2927     3409286 :   else if (error_if_not_found)
    2928             :   {
    2929          42 :     if (_aux->hasVariable(var_name) || _aux->hasScalarVariable(var_name))
    2930          28 :       mooseError("No solver variable named ",
    2931             :                  var_name,
    2932             :                  " found. Did you specify an auxiliary variable when you meant to specify a "
    2933             :                  "solver variable?");
    2934             :     else
    2935          14 :       mooseError("Unknown variable '",
    2936             :                  var_name,
    2937             :                  "'. It does not exist in the solver system(s) or auxiliary system");
    2938             :   }
    2939             : 
    2940    10087290 :   return std::make_pair(var_in_sys, var_in_sys ? map_it->second : libMesh::invalid_uint);
    2941             : }
    2942             : 
    2943             : void
    2944      170040 : FEProblemBase::setResidualObjectParamsAndLog(const std::string & ro_name,
    2945             :                                              const std::string & name,
    2946             :                                              InputParameters & parameters,
    2947             :                                              const unsigned int nl_sys_num,
    2948             :                                              const std::string & base_name,
    2949             :                                              bool & reinit_displaced)
    2950             : {
    2951      170040 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    2952             :   {
    2953        2160 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    2954        2160 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(nl_sys_num);
    2955        1080 :     reinit_displaced = true;
    2956             :   }
    2957             :   else
    2958             :   {
    2959      168960 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    2960             :     {
    2961             :       // We allow Kernels to request that they use_displaced_mesh,
    2962             :       // but then be overridden when no displacements variables are
    2963             :       // provided in the Mesh block.  If that happened, update the value
    2964             :       // of use_displaced_mesh appropriately for this Kernel.
    2965         136 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    2966         272 :         parameters.set<bool>("use_displaced_mesh") = false;
    2967             :     }
    2968             : 
    2969      337920 :     parameters.set<SubProblem *>("_subproblem") = this;
    2970      506880 :     parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    2971             :   }
    2972             : 
    2973      170040 :   logAdd(base_name, name, ro_name, parameters);
    2974      170040 : }
    2975             : 
    2976             : void
    2977       83549 : FEProblemBase::addKernel(const std::string & kernel_name,
    2978             :                          const std::string & name,
    2979             :                          InputParameters & parameters)
    2980             : {
    2981             :   parallel_object_only();
    2982      167098 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    2983       83533 :   if (!isSolverSystemNonlinear(nl_sys_num))
    2984           0 :     mooseError("You are trying to add a Kernel to a linear variable/system, which is not "
    2985             :                "supported at the moment!");
    2986       83533 :   setResidualObjectParamsAndLog(
    2987       83533 :       kernel_name, name, parameters, nl_sys_num, "Kernel", _reinit_displaced_elem);
    2988             : 
    2989       83533 :   _nl[nl_sys_num]->addKernel(kernel_name, name, parameters);
    2990       83329 : }
    2991             : 
    2992             : void
    2993         808 : FEProblemBase::addHDGKernel(const std::string & kernel_name,
    2994             :                             const std::string & name,
    2995             :                             InputParameters & parameters)
    2996             : {
    2997             :   parallel_object_only();
    2998        1616 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    2999         808 :   if (!isSolverSystemNonlinear(nl_sys_num))
    3000           0 :     mooseError("You are trying to add a HDGKernel to a linear variable/system, which is not "
    3001             :                "supported at the moment!");
    3002         808 :   setResidualObjectParamsAndLog(
    3003         808 :       kernel_name, name, parameters, nl_sys_num, "HDGKernel", _reinit_displaced_elem);
    3004             : 
    3005         808 :   _nl[nl_sys_num]->addHDGKernel(kernel_name, name, parameters);
    3006         808 : }
    3007             : 
    3008             : void
    3009         574 : FEProblemBase::addNodalKernel(const std::string & kernel_name,
    3010             :                               const std::string & name,
    3011             :                               InputParameters & parameters)
    3012             : {
    3013             :   parallel_object_only();
    3014             : 
    3015        1148 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    3016         570 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3017             :   {
    3018           0 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3019           0 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(nl_sys_num);
    3020           0 :     _reinit_displaced_elem = true;
    3021             :   }
    3022             :   else
    3023             :   {
    3024         570 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    3025             :     {
    3026             :       // We allow NodalKernels to request that they use_displaced_mesh,
    3027             :       // but then be overridden when no displacements variables are
    3028             :       // provided in the Mesh block.  If that happened, update the value
    3029             :       // of use_displaced_mesh appropriately for this NodalKernel.
    3030           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3031           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    3032             :     }
    3033             : 
    3034        1140 :     parameters.set<SubProblem *>("_subproblem") = this;
    3035        1710 :     parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    3036             :   }
    3037         570 :   logAdd("NodalKernel", name, kernel_name, parameters);
    3038         570 :   _nl[nl_sys_num]->addNodalKernel(kernel_name, name, parameters);
    3039         570 : }
    3040             : 
    3041             : void
    3042        1551 : FEProblemBase::addScalarKernel(const std::string & kernel_name,
    3043             :                                const std::string & name,
    3044             :                                InputParameters & parameters)
    3045             : {
    3046             :   parallel_object_only();
    3047             : 
    3048        3102 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    3049        1551 :   if (!isSolverSystemNonlinear(nl_sys_num))
    3050           0 :     mooseError("You are trying to add a ScalarKernel to a linear variable/system, which is not "
    3051             :                "supported at the moment!");
    3052             : 
    3053        1551 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3054             :   {
    3055           0 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3056           0 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(nl_sys_num);
    3057             :   }
    3058             :   else
    3059             :   {
    3060        1551 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    3061             :     {
    3062             :       // We allow ScalarKernels to request that they use_displaced_mesh,
    3063             :       // but then be overridden when no displacements variables are
    3064             :       // provided in the Mesh block.  If that happened, update the value
    3065             :       // of use_displaced_mesh appropriately for this ScalarKernel.
    3066           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3067           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    3068             :     }
    3069             : 
    3070        3102 :     parameters.set<SubProblem *>("_subproblem") = this;
    3071        4653 :     parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    3072             :   }
    3073             : 
    3074        1551 :   logAdd("ScalarKernel", name, kernel_name, parameters);
    3075        1551 :   _nl[nl_sys_num]->addScalarKernel(kernel_name, name, parameters);
    3076        1543 : }
    3077             : 
    3078             : void
    3079       82736 : FEProblemBase::addBoundaryCondition(const std::string & bc_name,
    3080             :                                     const std::string & name,
    3081             :                                     InputParameters & parameters)
    3082             : {
    3083             :   parallel_object_only();
    3084             : 
    3085      165476 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    3086       82726 :   if (!isSolverSystemNonlinear(nl_sys_num))
    3087           0 :     mooseError(
    3088             :         "You are trying to add a BoundaryCondition to a linear variable/system, which is not "
    3089             :         "supported at the moment!");
    3090             : 
    3091       82726 :   setResidualObjectParamsAndLog(
    3092       82726 :       bc_name, name, parameters, nl_sys_num, "BoundaryCondition", _reinit_displaced_face);
    3093       82726 :   _nl[nl_sys_num]->addBoundaryCondition(bc_name, name, parameters);
    3094       82668 : }
    3095             : 
    3096             : void
    3097        1731 : FEProblemBase::addConstraint(const std::string & c_name,
    3098             :                              const std::string & name,
    3099             :                              InputParameters & parameters)
    3100             : {
    3101             :   parallel_object_only();
    3102             : 
    3103        1731 :   _has_constraints = true;
    3104             : 
    3105        1731 :   auto determine_var_param_name = [&parameters, this]()
    3106             :   {
    3107        5193 :     if (parameters.isParamValid("variable"))
    3108        1125 :       return "variable";
    3109             :     else
    3110             :     {
    3111             :       // must be a mortar constraint
    3112        1212 :       const bool has_secondary_var = parameters.isParamValid("secondary_variable");
    3113        1212 :       const bool has_primary_var = parameters.isParamValid("primary_variable");
    3114         606 :       if (!has_secondary_var && !has_primary_var)
    3115           0 :         mooseError(
    3116             :             "Either a 'secondary_variable' or 'primary_variable' parameter must be supplied for '",
    3117           0 :             parameters.getObjectName(),
    3118             :             "'");
    3119         606 :       return has_secondary_var ? "secondary_variable" : "primary_variable";
    3120             :     }
    3121        1731 :   };
    3122             : 
    3123             :   const auto nl_sys_num =
    3124        3462 :       determineSolverSystem(parameters.varName(determine_var_param_name(), name), true).second;
    3125        1727 :   if (!isSolverSystemNonlinear(nl_sys_num))
    3126           0 :     mooseError("You are trying to add a Constraint to a linear variable/system, which is not "
    3127             :                "supported at the moment!");
    3128             : 
    3129        1727 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3130             :   {
    3131         294 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3132         294 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(nl_sys_num);
    3133         147 :     _reinit_displaced_face = true;
    3134             :   }
    3135             :   else
    3136             :   {
    3137             :     // It might _want_ to use a displaced mesh... but we're not so set it to false
    3138        1580 :     if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3139        3160 :       parameters.set<bool>("use_displaced_mesh") = false;
    3140             : 
    3141        3160 :     parameters.set<SubProblem *>("_subproblem") = this;
    3142        4740 :     parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    3143             :   }
    3144             : 
    3145        1727 :   logAdd("Constraint", name, c_name, parameters);
    3146        1727 :   _nl[nl_sys_num]->addConstraint(c_name, name, parameters);
    3147        1719 : }
    3148             : 
    3149             : void
    3150       96288 : FEProblemBase::addAuxVariable(const std::string & var_type,
    3151             :                               const std::string & var_name,
    3152             :                               InputParameters & params)
    3153             : {
    3154             :   parallel_object_only();
    3155             : 
    3156       96288 :   const auto order = Utility::string_to_enum<Order>(params.get<MooseEnum>("order"));
    3157       96288 :   const auto family = Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family"));
    3158       96288 :   const auto fe_type = FEType(order, family);
    3159             : 
    3160             :   const auto active_subdomains_vector =
    3161       96288 :       _mesh.getSubdomainIDs(params.get<std::vector<SubdomainName>>("block"));
    3162             :   const std::set<SubdomainID> active_subdomains(active_subdomains_vector.begin(),
    3163       96288 :                                                 active_subdomains_vector.end());
    3164             : 
    3165       96288 :   if (duplicateVariableCheck(var_name, fe_type, /* is_aux = */ true, &active_subdomains))
    3166           0 :     return;
    3167             : 
    3168      288828 :   params.set<FEProblemBase *>("_fe_problem_base") = this;
    3169      192552 :   params.set<Moose::VarKindType>("_var_kind") = Moose::VarKindType::VAR_AUXILIARY;
    3170             : 
    3171       96276 :   logAdd("AuxVariable", var_name, var_type, params);
    3172       96276 :   _aux->addVariable(var_type, var_name, params);
    3173       96276 :   if (_displaced_problem)
    3174             :     // MooseObjects need to be unique so change the name here
    3175       11112 :     _displaced_problem->addAuxVariable(var_type, var_name, params);
    3176             : 
    3177       96276 :   markFamilyPRefinement(params);
    3178       96276 : }
    3179             : 
    3180             : void
    3181           0 : FEProblemBase::addAuxVariable(const std::string & var_name,
    3182             :                               const FEType & type,
    3183             :                               const std::set<SubdomainID> * const active_subdomains)
    3184             : {
    3185             :   parallel_object_only();
    3186             : 
    3187           0 :   mooseDeprecated("Please use the addAuxVariable(var_type, var_name, params) API instead");
    3188             : 
    3189           0 :   if (duplicateVariableCheck(var_name, type, /* is_aux = */ true, active_subdomains))
    3190           0 :     return;
    3191             : 
    3192           0 :   std::string var_type;
    3193           0 :   if (type == FEType(0, MONOMIAL))
    3194           0 :     var_type = "MooseVariableConstMonomial";
    3195           0 :   else if (type.family == SCALAR)
    3196           0 :     var_type = "MooseVariableScalar";
    3197           0 :   else if (FEInterface::field_type(type) == TYPE_VECTOR)
    3198           0 :     var_type = "VectorMooseVariable";
    3199             :   else
    3200           0 :     var_type = "MooseVariable";
    3201             : 
    3202           0 :   InputParameters params = _factory.getValidParams(var_type);
    3203           0 :   params.set<FEProblemBase *>("_fe_problem_base") = this;
    3204           0 :   params.set<Moose::VarKindType>("_var_kind") = Moose::VarKindType::VAR_AUXILIARY;
    3205           0 :   params.set<MooseEnum>("order") = type.order.get_order();
    3206           0 :   params.set<MooseEnum>("family") = Moose::stringify(type.family);
    3207             : 
    3208           0 :   if (active_subdomains)
    3209           0 :     for (const SubdomainID & id : *active_subdomains)
    3210           0 :       params.set<std::vector<SubdomainName>>("block").push_back(Moose::stringify(id));
    3211             : 
    3212           0 :   logAdd("AuxVariable", var_name, var_type, params);
    3213           0 :   _aux->addVariable(var_type, var_name, params);
    3214           0 :   if (_displaced_problem)
    3215           0 :     _displaced_problem->addAuxVariable("MooseVariable", var_name, params);
    3216             : 
    3217           0 :   markFamilyPRefinement(params);
    3218           0 : }
    3219             : 
    3220             : void
    3221           0 : FEProblemBase::addAuxArrayVariable(const std::string & var_name,
    3222             :                                    const FEType & type,
    3223             :                                    unsigned int components,
    3224             :                                    const std::set<SubdomainID> * const active_subdomains)
    3225             : {
    3226             :   parallel_object_only();
    3227             : 
    3228           0 :   mooseDeprecated("Please use the addAuxVariable(var_type, var_name, params) API instead");
    3229             : 
    3230           0 :   if (duplicateVariableCheck(var_name, type, /* is_aux = */ true, active_subdomains))
    3231           0 :     return;
    3232             : 
    3233           0 :   InputParameters params = _factory.getValidParams("ArrayMooseVariable");
    3234           0 :   params.set<FEProblemBase *>("_fe_problem_base") = this;
    3235           0 :   params.set<Moose::VarKindType>("_var_kind") = Moose::VarKindType::VAR_AUXILIARY;
    3236           0 :   params.set<MooseEnum>("order") = type.order.get_order();
    3237           0 :   params.set<MooseEnum>("family") = Moose::stringify(type.family);
    3238           0 :   params.set<unsigned int>("components") = components;
    3239             : 
    3240           0 :   if (active_subdomains)
    3241           0 :     for (const SubdomainID & id : *active_subdomains)
    3242           0 :       params.set<std::vector<SubdomainName>>("block").push_back(Moose::stringify(id));
    3243             : 
    3244           0 :   logAdd("Variable", var_name, "ArrayMooseVariable", params);
    3245           0 :   _aux->addVariable("ArrayMooseVariable", var_name, params);
    3246           0 :   if (_displaced_problem)
    3247           0 :     _displaced_problem->addAuxVariable("ArrayMooseVariable", var_name, params);
    3248             : 
    3249           0 :   markFamilyPRefinement(params);
    3250           0 : }
    3251             : 
    3252             : void
    3253           0 : FEProblemBase::addAuxScalarVariable(const std::string & var_name,
    3254             :                                     Order order,
    3255             :                                     Real /*scale_factor*/,
    3256             :                                     const std::set<SubdomainID> * const active_subdomains)
    3257             : {
    3258             :   parallel_object_only();
    3259             : 
    3260           0 :   mooseDeprecated("Please use the addAuxVariable(var_type, var_name, params) API instead");
    3261             : 
    3262           0 :   if (order > _max_scalar_order)
    3263           0 :     _max_scalar_order = order;
    3264             : 
    3265           0 :   FEType type(order, SCALAR);
    3266           0 :   if (duplicateVariableCheck(var_name, type, /* is_aux = */ true, active_subdomains))
    3267           0 :     return;
    3268             : 
    3269           0 :   InputParameters params = _factory.getValidParams("MooseVariableScalar");
    3270           0 :   params.set<FEProblemBase *>("_fe_problem_base") = this;
    3271           0 :   params.set<Moose::VarKindType>("_var_kind") = Moose::VarKindType::VAR_AUXILIARY;
    3272             : 
    3273           0 :   params.set<MooseEnum>("order") = type.order.get_order();
    3274           0 :   params.set<MooseEnum>("family") = "SCALAR";
    3275           0 :   params.set<std::vector<Real>>("scaling") = {1};
    3276           0 :   if (active_subdomains)
    3277           0 :     for (const SubdomainID & id : *active_subdomains)
    3278           0 :       params.set<std::vector<SubdomainName>>("block").push_back(Moose::stringify(id));
    3279             : 
    3280           0 :   logAdd("ScalarVariable", var_name, "MooseVariableScalar", params);
    3281           0 :   _aux->addVariable("MooseVariableScalar", var_name, params);
    3282           0 :   if (_displaced_problem)
    3283           0 :     _displaced_problem->addAuxVariable("MooseVariableScalar", var_name, params);
    3284           0 : }
    3285             : 
    3286             : void
    3287       68455 : FEProblemBase::addAuxKernel(const std::string & kernel_name,
    3288             :                             const std::string & name,
    3289             :                             InputParameters & parameters)
    3290             : {
    3291             :   parallel_object_only();
    3292             : 
    3293       68455 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3294             :   {
    3295       24808 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3296       24808 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->auxSys();
    3297       24808 :     parameters.set<SystemBase *>("_nl_sys") = &_displaced_problem->solverSys(0);
    3298       12404 :     if (!parameters.get<std::vector<BoundaryName>>("boundary").empty())
    3299       11916 :       _reinit_displaced_face = true;
    3300             :     else
    3301         488 :       _reinit_displaced_elem = true;
    3302             :   }
    3303             :   else
    3304             :   {
    3305       56051 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    3306             :     {
    3307             :       // We allow AuxKernels to request that they use_displaced_mesh,
    3308             :       // but then be overridden when no displacements variables are
    3309             :       // provided in the Mesh block.  If that happened, update the value
    3310             :       // of use_displaced_mesh appropriately for this AuxKernel.
    3311         863 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3312        1726 :         parameters.set<bool>("use_displaced_mesh") = false;
    3313             :     }
    3314             : 
    3315      112102 :     parameters.set<SubProblem *>("_subproblem") = this;
    3316      112102 :     parameters.set<SystemBase *>("_sys") = _aux.get();
    3317      168153 :     parameters.set<SystemBase *>("_nl_sys") = _solver_systems[0].get();
    3318             :   }
    3319             : 
    3320       68455 :   logAdd("AuxKernel", name, kernel_name, parameters);
    3321       68455 :   _aux->addKernel(kernel_name, name, parameters);
    3322       68303 : }
    3323             : 
    3324             : void
    3325         537 : FEProblemBase::addAuxScalarKernel(const std::string & kernel_name,
    3326             :                                   const std::string & name,
    3327             :                                   InputParameters & parameters)
    3328             : {
    3329             :   parallel_object_only();
    3330             : 
    3331         537 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3332             :   {
    3333           0 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3334           0 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->auxSys();
    3335             :   }
    3336             :   else
    3337             :   {
    3338         537 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    3339             :     {
    3340             :       // We allow AuxScalarKernels to request that they use_displaced_mesh,
    3341             :       // but then be overridden when no displacements variables are
    3342             :       // provided in the Mesh block.  If that happened, update the value
    3343             :       // of use_displaced_mesh appropriately for this AuxScalarKernel.
    3344           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3345           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    3346             :     }
    3347             : 
    3348        1074 :     parameters.set<SubProblem *>("_subproblem") = this;
    3349        1611 :     parameters.set<SystemBase *>("_sys") = _aux.get();
    3350             :   }
    3351             : 
    3352         537 :   logAdd("AuxScalarKernel", name, kernel_name, parameters);
    3353         537 :   _aux->addScalarKernel(kernel_name, name, parameters);
    3354         533 : }
    3355             : 
    3356             : void
    3357         919 : FEProblemBase::addDiracKernel(const std::string & kernel_name,
    3358             :                               const std::string & name,
    3359             :                               InputParameters & parameters)
    3360             : {
    3361             :   parallel_object_only();
    3362             : 
    3363        1838 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    3364         915 :   if (!isSolverSystemNonlinear(nl_sys_num))
    3365           0 :     mooseError("You are trying to add a DiracKernel to a linear variable/system, which is not "
    3366             :                "supported at the moment!");
    3367             : 
    3368         915 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3369             :   {
    3370          26 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3371          26 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(nl_sys_num);
    3372          13 :     _reinit_displaced_elem = true;
    3373             :   }
    3374             :   else
    3375             :   {
    3376         902 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    3377             :     {
    3378             :       // We allow DiracKernels to request that they use_displaced_mesh,
    3379             :       // but then be overridden when no displacements variables are
    3380             :       // provided in the Mesh block.  If that happened, update the value
    3381             :       // of use_displaced_mesh appropriately for this DiracKernel.
    3382           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3383           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    3384             :     }
    3385             : 
    3386        1804 :     parameters.set<SubProblem *>("_subproblem") = this;
    3387        2706 :     parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    3388             :   }
    3389             : 
    3390         915 :   logAdd("DiracKernel", name, kernel_name, parameters);
    3391         915 :   _nl[nl_sys_num]->addDiracKernel(kernel_name, name, parameters);
    3392         907 : }
    3393             : 
    3394             : // DGKernels ////
    3395             : 
    3396             : void
    3397        1453 : FEProblemBase::addDGKernel(const std::string & dg_kernel_name,
    3398             :                            const std::string & name,
    3399             :                            InputParameters & parameters)
    3400             : {
    3401             :   parallel_object_only();
    3402             : 
    3403        2906 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    3404        1449 :   if (!isSolverSystemNonlinear(nl_sys_num))
    3405           0 :     mooseError("You are trying to add a DGKernel to a linear variable/system, which is not "
    3406             :                "supported at the moment!");
    3407             : 
    3408        1449 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3409             :   {
    3410          52 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3411          52 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(nl_sys_num);
    3412          26 :     _reinit_displaced_neighbor = true;
    3413             :   }
    3414             :   else
    3415             :   {
    3416        1423 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    3417             :     {
    3418             :       // We allow DGKernels to request that they use_displaced_mesh,
    3419             :       // but then be overridden when no displacements variables are
    3420             :       // provided in the Mesh block.  If that happened, update the value
    3421             :       // of use_displaced_mesh appropriately for this DGKernel.
    3422           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3423           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    3424             :     }
    3425             : 
    3426        2846 :     parameters.set<SubProblem *>("_subproblem") = this;
    3427        4269 :     parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    3428             :   }
    3429             : 
    3430        1449 :   logAdd("DGKernel", name, dg_kernel_name, parameters);
    3431        1449 :   _nl[nl_sys_num]->addDGKernel(dg_kernel_name, name, parameters);
    3432             : 
    3433        1449 :   _has_internal_edge_residual_objects = true;
    3434        1449 : }
    3435             : 
    3436             : void
    3437        9076 : FEProblemBase::addFVKernel(const std::string & fv_kernel_name,
    3438             :                            const std::string & name,
    3439             :                            InputParameters & parameters)
    3440             : {
    3441        9076 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3442             :     // FVElementalKernels are computed in the historically finite element threaded loops. They rely
    3443             :     // on Assembly data like _current_elem. When we call reinit on the FEProblemBase we will only
    3444             :     // reinit the DisplacedProblem and its associated Assembly objects if we mark this boolean as
    3445             :     // true
    3446           0 :     _reinit_displaced_elem = true;
    3447        9076 :   addObject<FVKernel>(fv_kernel_name, name, parameters);
    3448        9068 : }
    3449             : 
    3450             : void
    3451        7779 : FEProblemBase::addFVBC(const std::string & fv_bc_name,
    3452             :                        const std::string & name,
    3453             :                        InputParameters & parameters)
    3454             : {
    3455        7779 :   addObject<FVBoundaryCondition>(fv_bc_name, name, parameters);
    3456        7779 : }
    3457             : 
    3458             : void
    3459         327 : FEProblemBase::addFVInterfaceKernel(const std::string & fv_ik_name,
    3460             :                                     const std::string & name,
    3461             :                                     InputParameters & parameters)
    3462             : {
    3463             :   /// We assume that variable1 and variable2 can live on different systems, in this case
    3464             :   /// the user needs to create two interface kernels with flipped variables and parameters
    3465         327 :   addObject<FVInterfaceKernel>(
    3466             :       fv_ik_name, name, parameters, /*threaded=*/true, /*variable_param_name=*/"variable1");
    3467         315 : }
    3468             : 
    3469             : void
    3470        3295 : FEProblemBase::addLinearFVKernel(const std::string & kernel_name,
    3471             :                                  const std::string & name,
    3472             :                                  InputParameters & parameters)
    3473             : {
    3474        3295 :   addObject<LinearFVKernel>(kernel_name, name, parameters);
    3475        3295 : }
    3476             : 
    3477             : void
    3478        2382 : FEProblemBase::addLinearFVBC(const std::string & bc_name,
    3479             :                              const std::string & name,
    3480             :                              InputParameters & parameters)
    3481             : {
    3482        2382 :   addObject<LinearFVBoundaryCondition>(bc_name, name, parameters);
    3483        2382 : }
    3484             : 
    3485             : // InterfaceKernels ////
    3486             : 
    3487             : void
    3488         919 : FEProblemBase::addInterfaceKernel(const std::string & interface_kernel_name,
    3489             :                                   const std::string & name,
    3490             :                                   InputParameters & parameters)
    3491             : {
    3492             :   parallel_object_only();
    3493             : 
    3494        1838 :   const auto nl_sys_num = determineSolverSystem(parameters.varName("variable", name), true).second;
    3495         915 :   if (!isSolverSystemNonlinear(nl_sys_num))
    3496           0 :     mooseError("You are trying to add a InterfaceKernel to a linear variable/system, which is not "
    3497             :                "supported at the moment!");
    3498             : 
    3499         915 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    3500             :   {
    3501          26 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3502          26 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(nl_sys_num);
    3503          13 :     _reinit_displaced_neighbor = true;
    3504             :   }
    3505             :   else
    3506             :   {
    3507         902 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    3508             :     {
    3509             :       // We allow InterfaceKernels to request that they use_displaced_mesh,
    3510             :       // but then be overridden when no displacements variables are
    3511             :       // provided in the Mesh block.  If that happened, update the value
    3512             :       // of use_displaced_mesh appropriately for this InterfaceKernel.
    3513           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    3514           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    3515             :     }
    3516             : 
    3517        1804 :     parameters.set<SubProblem *>("_subproblem") = this;
    3518        2706 :     parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    3519             :   }
    3520             : 
    3521         915 :   logAdd("InterfaceKernel", name, interface_kernel_name, parameters);
    3522         915 :   _nl[nl_sys_num]->addInterfaceKernel(interface_kernel_name, name, parameters);
    3523             : 
    3524         915 :   _has_internal_edge_residual_objects = true;
    3525         915 : }
    3526             : 
    3527             : void
    3528       33887 : FEProblemBase::checkICRestartError(const std::string & ic_name,
    3529             :                                    const std::string & name,
    3530             :                                    const VariableName & var_name)
    3531             : {
    3532       33887 :   if (!_allow_ics_during_restart)
    3533             :   {
    3534       33791 :     std::string restart_method = "";
    3535       33791 :     if (_app.isRestarting())
    3536             :       restart_method =
    3537           0 :           "a checkpoint restart, by IC object '" + ic_name + "' for variable '" + name + "'";
    3538       33791 :     else if (_app.getExReaderForRestart())
    3539             :     {
    3540           4 :       std::vector<std::string> restarted_vars = _app.getExReaderForRestart()->get_elem_var_names();
    3541           4 :       const auto nodal_vars = _app.getExReaderForRestart()->get_nodal_var_names();
    3542           4 :       const auto global_vars = _app.getExReaderForRestart()->get_global_var_names();
    3543           4 :       restarted_vars.insert(restarted_vars.end(), nodal_vars.begin(), nodal_vars.end());
    3544           4 :       restarted_vars.insert(restarted_vars.end(), global_vars.begin(), global_vars.end());
    3545             : 
    3546           4 :       if (std::find(restarted_vars.begin(), restarted_vars.end(), var_name) != restarted_vars.end())
    3547           8 :         restart_method = "an Exodus restart, by IC object '" + ic_name + "' for variable '" + name +
    3548           4 :                          "' that is also being restarted";
    3549           4 :     }
    3550       33791 :     if (!restart_method.empty())
    3551           4 :       mooseError(
    3552             :           "Initial conditions have been specified during ",
    3553             :           restart_method,
    3554             :           ".\nThis is only allowed if you specify 'allow_initial_conditions_with_restart' to "
    3555             :           "the [Problem], as initial conditions can override restarted fields");
    3556       33787 :   }
    3557       33883 : }
    3558             : 
    3559             : void
    3560       31054 : FEProblemBase::addInitialCondition(const std::string & ic_name,
    3561             :                                    const std::string & name,
    3562             :                                    InputParameters & parameters)
    3563             : {
    3564             :   parallel_object_only();
    3565             : 
    3566             :   // before we start to mess with the initial condition, we need to check parameters for errors.
    3567       31054 :   parameters.checkParams(name);
    3568       31050 :   const std::string & var_name = parameters.get<VariableName>("variable");
    3569             : 
    3570             :   // Forbid initial conditions on a restarted problem, as they would override the restart
    3571       31050 :   checkICRestartError(ic_name, name, var_name);
    3572             : 
    3573       62092 :   parameters.set<SubProblem *>("_subproblem") = this;
    3574             : 
    3575             :   // field IC
    3576       31046 :   if (hasVariable(var_name))
    3577             :   {
    3578       61510 :     for (THREAD_ID tid = 0; tid < libMesh::n_threads(); ++tid)
    3579             :     {
    3580       32258 :       MooseVariableFEBase & var = getVariable(
    3581             :           tid, var_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY);
    3582       64516 :       parameters.set<SystemBase *>("_sys") = &var.sys();
    3583       32258 :       std::shared_ptr<InitialConditionBase> ic;
    3584       32258 :       if (dynamic_cast<MooseVariable *>(&var))
    3585       29675 :         ic = _factory.create<InitialCondition>(ic_name, name, parameters, tid);
    3586        2583 :       else if (dynamic_cast<VectorMooseVariable *>(&var))
    3587         272 :         ic = _factory.create<VectorInitialCondition>(ic_name, name, parameters, tid);
    3588        2311 :       else if (dynamic_cast<ArrayMooseVariable *>(&var))
    3589        1289 :         ic = _factory.create<ArrayInitialCondition>(ic_name, name, parameters, tid);
    3590        1022 :       else if (dynamic_cast<MooseVariableFVReal *>(&var))
    3591        1022 :         ic = _factory.create<InitialCondition>(ic_name, name, parameters, tid);
    3592           0 :       else if (dynamic_cast<MooseLinearVariableFVReal *>(&var))
    3593           0 :         ic = _factory.create<InitialCondition>(ic_name, name, parameters, tid);
    3594             :       else
    3595           0 :         mooseError("Your FE variable in initial condition ",
    3596             :                    name,
    3597             :                    " must be either of scalar or vector type");
    3598       32230 :       logAdd("IC", name, ic_name, parameters);
    3599       32230 :       _ics.addObject(ic, tid);
    3600       32210 :     }
    3601             :   }
    3602             : 
    3603             :   // scalar IC
    3604        1746 :   else if (hasScalarVariable(var_name))
    3605             :   {
    3606        1746 :     MooseVariableScalar & var = getScalarVariable(0, var_name);
    3607        3492 :     parameters.set<SystemBase *>("_sys") = &var.sys();
    3608             :     std::shared_ptr<ScalarInitialCondition> ic =
    3609        1746 :         _factory.create<ScalarInitialCondition>(ic_name, name, parameters);
    3610        1746 :     logAdd("ScalarIC", name, ic_name, parameters);
    3611        1746 :     _scalar_ics.addObject(ic);
    3612        1746 :   }
    3613             : 
    3614             :   else
    3615           0 :     mooseError(
    3616             :         "Variable '", var_name, "' requested in initial condition '", name, "' does not exist.");
    3617       30998 : }
    3618             : 
    3619             : void
    3620        2837 : FEProblemBase::addFVInitialCondition(const std::string & ic_name,
    3621             :                                      const std::string & name,
    3622             :                                      InputParameters & parameters)
    3623             : {
    3624             :   parallel_object_only();
    3625             : 
    3626             :   // before we start to mess with the initial condition, we need to check parameters for errors.
    3627        2837 :   parameters.checkParams(name);
    3628        2837 :   const std::string & var_name = parameters.get<VariableName>("variable");
    3629             : 
    3630             :   // Forbid initial conditions on a restarted problem, as they would override the restart
    3631        2837 :   checkICRestartError(ic_name, name, var_name);
    3632             : 
    3633        5674 :   parameters.set<SubProblem *>("_subproblem") = this;
    3634             : 
    3635             :   // field IC
    3636        2837 :   if (hasVariable(var_name))
    3637             :   {
    3638        5754 :     for (THREAD_ID tid = 0; tid < libMesh::n_threads(); ++tid)
    3639             :     {
    3640        2917 :       auto & var = getVariable(
    3641             :           tid, var_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY);
    3642        5834 :       parameters.set<SystemBase *>("_sys") = &var.sys();
    3643        2917 :       std::shared_ptr<FVInitialConditionBase> ic;
    3644        2917 :       if (var.isFV())
    3645        2917 :         ic = _factory.create<FVInitialCondition>(ic_name, name, parameters, tid);
    3646             :       else
    3647           0 :         mooseError(
    3648             :             "Your variable for an FVInitialCondition needs to be an a finite volume variable!");
    3649        2917 :       _fv_ics.addObject(ic, tid);
    3650        2917 :     }
    3651             :   }
    3652             :   else
    3653           0 :     mooseError("Variable '",
    3654             :                var_name,
    3655             :                "' requested in finite volume initial condition '",
    3656             :                name,
    3657             :                "' does not exist.");
    3658        2837 : }
    3659             : 
    3660             : void
    3661       58577 : FEProblemBase::projectSolution()
    3662             : {
    3663      292885 :   TIME_SECTION("projectSolution", 2, "Projecting Initial Solutions")
    3664             : 
    3665       58577 :   FloatingPointExceptionGuard fpe_guard(_app);
    3666             : 
    3667       58577 :   ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
    3668       58577 :   ComputeInitialConditionThread cic(*this);
    3669       58577 :   Threads::parallel_reduce(elem_range, cic);
    3670             : 
    3671       58569 :   if (haveFV())
    3672             :   {
    3673             :     using ElemInfoRange = StoredRange<MooseMesh::const_elem_info_iterator, const ElemInfo *>;
    3674        5204 :     ElemInfoRange elem_info_range(_mesh.ownedElemInfoBegin(), _mesh.ownedElemInfoEnd());
    3675             : 
    3676        5204 :     ComputeFVInitialConditionThread cfvic(*this);
    3677        5204 :     Threads::parallel_reduce(elem_info_range, cfvic);
    3678        5204 :   }
    3679             : 
    3680             :   // Need to close the solution vector here so that boundary ICs take precendence
    3681      116069 :   for (auto & nl : _nl)
    3682       57500 :     nl->solution().close();
    3683       58569 :   _aux->solution().close();
    3684             : 
    3685             :   // now run boundary-restricted initial conditions
    3686       58569 :   ConstBndNodeRange & bnd_nodes = *_mesh.getBoundaryNodeRange();
    3687       58569 :   ComputeBoundaryInitialConditionThread cbic(*this);
    3688       58569 :   Threads::parallel_reduce(bnd_nodes, cbic);
    3689             : 
    3690      116069 :   for (auto & nl : _nl)
    3691       57500 :     nl->solution().close();
    3692       58569 :   _aux->solution().close();
    3693             : 
    3694             :   // Also, load values into the SCALAR dofs
    3695             :   // Note: We assume that all SCALAR dofs are on the
    3696             :   // processor with highest ID
    3697       58569 :   if (processor_id() == (n_processors() - 1) && _scalar_ics.hasActiveObjects())
    3698             :   {
    3699         678 :     const auto & ics = _scalar_ics.getActiveObjects();
    3700        1864 :     for (const auto & ic : ics)
    3701             :     {
    3702        1186 :       MooseVariableScalar & var = ic->variable();
    3703        1186 :       var.reinit();
    3704             : 
    3705        1186 :       DenseVector<Number> vals(var.order());
    3706        1186 :       ic->compute(vals);
    3707             : 
    3708        1186 :       const unsigned int n_scalar_dofs = var.dofIndices().size();
    3709        2757 :       for (unsigned int i = 0; i < n_scalar_dofs; i++)
    3710             :       {
    3711        1571 :         const auto global_index = var.dofIndices()[i];
    3712        1571 :         var.sys().solution().set(global_index, vals(i));
    3713        1571 :         var.setValue(i, vals(i));
    3714             :       }
    3715        1186 :     }
    3716             :   }
    3717             : 
    3718      117395 :   for (auto & sys : _solver_systems)
    3719             :   {
    3720       58826 :     sys->solution().close();
    3721       58826 :     sys->solution().localize(*sys->system().current_local_solution, sys->dofMap().get_send_list());
    3722             :   }
    3723             : 
    3724       58569 :   _aux->solution().close();
    3725       58569 :   _aux->solution().localize(*_aux->sys().current_local_solution, _aux->dofMap().get_send_list());
    3726       58569 : }
    3727             : 
    3728             : void
    3729        2191 : FEProblemBase::projectInitialConditionOnCustomRange(
    3730             :     ConstElemRange & elem_range,
    3731             :     ConstBndNodeRange & bnd_nodes,
    3732             :     const std::optional<std::set<VariableName>> & target_vars)
    3733             : {
    3734        2191 :   if (target_vars)
    3735             :   {
    3736        2191 :     ComputeInitialConditionThread cic(*this, &(*target_vars));
    3737        2191 :     Threads::parallel_reduce(elem_range, cic);
    3738             :   }
    3739             :   else
    3740             :   {
    3741           0 :     ComputeInitialConditionThread cic(*this);
    3742           0 :     Threads::parallel_reduce(elem_range, cic);
    3743             :   }
    3744             : 
    3745             :   // Need to close the solution vector here so that boundary ICs take precendence
    3746        4382 :   for (auto & nl : _nl)
    3747        2191 :     nl->solution().close();
    3748        2191 :   _aux->solution().close();
    3749             : 
    3750        2191 :   if (target_vars)
    3751             :   {
    3752        2191 :     ComputeBoundaryInitialConditionThread cbic(*this, &(*target_vars));
    3753        2191 :     Threads::parallel_reduce(bnd_nodes, cbic);
    3754        2191 :   }
    3755             :   else
    3756             :   {
    3757           0 :     ComputeBoundaryInitialConditionThread cbic(*this);
    3758           0 :     Threads::parallel_reduce(bnd_nodes, cbic);
    3759           0 :   }
    3760             : 
    3761        4382 :   for (auto & nl : _nl)
    3762        2191 :     nl->solution().close();
    3763        2191 :   _aux->solution().close();
    3764             : 
    3765             :   // Also, load values into the SCALAR dofs
    3766             :   // Note: We assume that all SCALAR dofs are on the
    3767             :   // processor with highest ID
    3768        2191 :   if (processor_id() == (n_processors() - 1) && _scalar_ics.hasActiveObjects())
    3769             :   {
    3770           0 :     const auto & ics = _scalar_ics.getActiveObjects();
    3771           0 :     for (const auto & ic : ics)
    3772             :     {
    3773           0 :       MooseVariableScalar & var = ic->variable();
    3774             : 
    3775           0 :       if (target_vars && !target_vars->count(var.name()))
    3776           0 :         continue;
    3777             : 
    3778           0 :       var.reinit();
    3779             : 
    3780           0 :       DenseVector<Number> vals(var.order());
    3781           0 :       ic->compute(vals);
    3782             : 
    3783           0 :       const unsigned int n_scalar_dofs = var.dofIndices().size();
    3784           0 :       for (unsigned int i = 0; i < n_scalar_dofs; i++)
    3785             :       {
    3786           0 :         const auto global_index = var.dofIndices()[i];
    3787           0 :         var.sys().solution().set(global_index, vals(i));
    3788           0 :         var.setValue(i, vals(i));
    3789             :       }
    3790           0 :     }
    3791             :   }
    3792             : 
    3793        4382 :   for (auto & nl : _nl)
    3794             :   {
    3795        2191 :     nl->solution().close();
    3796        2191 :     nl->solution().localize(*nl->system().current_local_solution, nl->dofMap().get_send_list());
    3797             :   }
    3798             : 
    3799        2191 :   _aux->solution().close();
    3800        2191 :   _aux->solution().localize(*_aux->sys().current_local_solution, _aux->dofMap().get_send_list());
    3801        2191 : }
    3802             : 
    3803             : void
    3804         765 : FEProblemBase::projectFunctionOnCustomRange(ConstElemRange & elem_range,
    3805             :                                             Number (*func)(const Point &,
    3806             :                                                            const libMesh::Parameters &,
    3807             :                                                            const std::string &,
    3808             :                                                            const std::string &),
    3809             :                                             Gradient (*func_grad)(const Point &,
    3810             :                                                                   const libMesh::Parameters &,
    3811             :                                                                   const std::string &,
    3812             :                                                                   const std::string &),
    3813             :                                             const libMesh::Parameters & params,
    3814             :                                             const VariableName & target_var)
    3815             : {
    3816             :   mooseAssert(!Threads::in_threads,
    3817             :               "We're performing a projection based on data from just the thread 0 variable, so any "
    3818             :               "modifications to the variable solution must have been thread joined already");
    3819             : 
    3820         765 :   const auto & var = getStandardVariable(0, target_var);
    3821         765 :   const auto var_num = var.number();
    3822         765 :   const auto sn = systemNumForVariable(target_var);
    3823         765 :   auto & sys = getSystemBase(sn);
    3824             : 
    3825             :   // Let libmesh handle the projection
    3826         765 :   System & libmesh_sys = getSystem(target_var);
    3827         765 :   auto temp_vec = libmesh_sys.current_local_solution->zero_clone();
    3828         765 :   libmesh_sys.project_vector(func, func_grad, params, *temp_vec);
    3829         765 :   temp_vec->close();
    3830             : 
    3831             :   // Get the dof indices to copy
    3832         765 :   DofMap & dof_map = sys.dofMap();
    3833         765 :   std::set<dof_id_type> dof_indices;
    3834         765 :   std::vector<dof_id_type> elem_dof_indices;
    3835             : 
    3836        4853 :   for (const auto & elem : elem_range)
    3837             :   {
    3838        4088 :     dof_map.dof_indices(elem, elem_dof_indices, var_num);
    3839        4088 :     dof_indices.insert(elem_dof_indices.begin(), elem_dof_indices.end());
    3840             :   }
    3841         765 :   std::vector<dof_id_type> dof_indices_v(dof_indices.begin(), dof_indices.end());
    3842             : 
    3843             :   // Copy the projected values into the solution vector
    3844         765 :   std::vector<Real> dof_vals;
    3845         765 :   temp_vec->get(dof_indices_v, dof_vals);
    3846             :   mooseAssert(sys.solution().closed(),
    3847             :               "The solution should be closed before mapping our projection");
    3848         765 :   sys.solution().insert(dof_vals, dof_indices_v);
    3849         765 :   sys.solution().close();
    3850         765 :   sys.solution().localize(*libmesh_sys.current_local_solution, sys.dofMap().get_send_list());
    3851         765 : }
    3852             : 
    3853             : std::shared_ptr<MaterialBase>
    3854         276 : FEProblemBase::getMaterial(std::string name,
    3855             :                            Moose::MaterialDataType type,
    3856             :                            const THREAD_ID tid,
    3857             :                            bool no_warn)
    3858             : {
    3859         276 :   switch (type)
    3860             :   {
    3861          70 :     case Moose::NEIGHBOR_MATERIAL_DATA:
    3862          70 :       name += "_neighbor";
    3863          70 :       break;
    3864          70 :     case Moose::FACE_MATERIAL_DATA:
    3865          70 :       name += "_face";
    3866          70 :       break;
    3867         136 :     default:
    3868         136 :       break;
    3869             :   }
    3870             : 
    3871         276 :   std::shared_ptr<MaterialBase> material = _all_materials[type].getActiveObject(name, tid);
    3872         716 :   if (!no_warn && material->getParam<bool>("compute") && type == Moose::BLOCK_MATERIAL_DATA)
    3873           4 :     mooseWarning("You are retrieving a Material object (",
    3874           4 :                  material->name(),
    3875             :                  "), but its compute flag is set to true. This indicates that MOOSE is "
    3876             :                  "computing this property which may not be desired and produce un-expected "
    3877             :                  "results.");
    3878             : 
    3879         268 :   return material;
    3880             : }
    3881             : 
    3882             : MaterialData &
    3883    50269340 : FEProblemBase::getMaterialData(Moose::MaterialDataType type,
    3884             :                                const THREAD_ID tid,
    3885             :                                const MooseObject * object) const
    3886             : {
    3887    50269340 :   switch (type)
    3888             :   {
    3889      905139 :     case Moose::BLOCK_MATERIAL_DATA:
    3890      905139 :       if (object)
    3891      281663 :         _material_props.addConsumer(type, object);
    3892      905139 :       return _material_props.getMaterialData(tid);
    3893    23467616 :     case Moose::NEIGHBOR_MATERIAL_DATA:
    3894    23467616 :       if (object)
    3895       26483 :         _neighbor_material_props.addConsumer(type, object);
    3896    23467616 :       return _neighbor_material_props.getMaterialData(tid);
    3897    25896585 :     case Moose::BOUNDARY_MATERIAL_DATA:
    3898             :     case Moose::FACE_MATERIAL_DATA:
    3899             :     case Moose::INTERFACE_MATERIAL_DATA:
    3900    25896585 :       if (object)
    3901       58903 :         _bnd_material_props.addConsumer(type, object);
    3902    25896585 :       return _bnd_material_props.getMaterialData(tid);
    3903             :   }
    3904             : 
    3905           0 :   mooseError("FEProblemBase::getMaterialData(): Invalid MaterialDataType ", type);
    3906             : }
    3907             : 
    3908             : const std::set<const MooseObject *> &
    3909           0 : FEProblemBase::getMaterialPropertyStorageConsumers(Moose::MaterialDataType type) const
    3910             : {
    3911           0 :   switch (type)
    3912             :   {
    3913           0 :     case Moose::BLOCK_MATERIAL_DATA:
    3914           0 :       return _material_props.getConsumers(type);
    3915           0 :     case Moose::NEIGHBOR_MATERIAL_DATA:
    3916           0 :       return _neighbor_material_props.getConsumers(type);
    3917           0 :     case Moose::BOUNDARY_MATERIAL_DATA:
    3918             :     case Moose::FACE_MATERIAL_DATA:
    3919             :     case Moose::INTERFACE_MATERIAL_DATA:
    3920           0 :       return _bnd_material_props.getConsumers(type);
    3921             :   }
    3922             : 
    3923           0 :   mooseError("FEProblemBase::getMaterialPropertyStorageConsumers(): Invalid MaterialDataType ",
    3924             :              type);
    3925             : }
    3926             : 
    3927             : void
    3928           0 : FEProblemBase::setPreserveMatrixSparsityPattern(bool preserve)
    3929             : {
    3930           0 :   if (_ignore_zeros_in_jacobian && preserve)
    3931           0 :     paramWarning(
    3932             :         "ignore_zeros_in_jacobian",
    3933             :         "We likely cannot preserve the sparsity pattern if ignoring zeros in the Jacobian, which "
    3934             :         "leads to removing those entries from the Jacobian sparsity pattern");
    3935           0 :   _preserve_matrix_sparsity_pattern = preserve;
    3936           0 : }
    3937             : 
    3938             : bool
    3939      339995 : FEProblemBase::acceptInvalidSolution() const
    3940             : {
    3941      679896 :   return allowInvalidSolution() || // invalid solutions are always allowed
    3942      679896 :          !_app.solutionInvalidity().hasInvalidSolutionError(); // if not allowed, check for errors
    3943             : }
    3944             : 
    3945             : void
    3946        1177 : FEProblemBase::addFunctorMaterial(const std::string & functor_material_name,
    3947             :                                   const std::string & name,
    3948             :                                   InputParameters & parameters)
    3949             : {
    3950             :   parallel_object_only();
    3951             : 
    3952        1177 :   auto add_functor_materials = [&](const auto & parameters, const auto & name)
    3953             :   {
    3954        2437 :     for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    3955             :     {
    3956             :       // Create the general Block/Boundary MaterialBase object
    3957        1260 :       std::shared_ptr<MaterialBase> material =
    3958        1260 :           _factory.create<MaterialBase>(functor_material_name, name, parameters, tid);
    3959        2520 :       logAdd("FunctorMaterial", name, functor_material_name, parameters);
    3960        1260 :       _all_materials.addObject(material, tid);
    3961        1260 :       _materials.addObject(material, tid);
    3962             :     }
    3963        1177 :   };
    3964             : 
    3965        2354 :   parameters.set<SubProblem *>("_subproblem") = this;
    3966        1177 :   add_functor_materials(parameters, name);
    3967        1177 :   if (_displaced_problem)
    3968             :   {
    3969           0 :     auto disp_params = parameters;
    3970           0 :     disp_params.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    3971           0 :     add_functor_materials(disp_params, name + "_displaced");
    3972           0 :   }
    3973        1177 : }
    3974             : 
    3975             : void
    3976       13457 : FEProblemBase::addMaterial(const std::string & mat_name,
    3977             :                            const std::string & name,
    3978             :                            InputParameters & parameters)
    3979             : {
    3980       26914 :   addMaterialHelper({&_materials}, mat_name, name, parameters);
    3981       13327 : }
    3982             : 
    3983             : void
    3984         348 : FEProblemBase::addInterfaceMaterial(const std::string & mat_name,
    3985             :                                     const std::string & name,
    3986             :                                     InputParameters & parameters)
    3987             : {
    3988         696 :   addMaterialHelper({&_interface_materials}, mat_name, name, parameters);
    3989         348 : }
    3990             : 
    3991             : void
    3992       14099 : FEProblemBase::addMaterialHelper(std::vector<MaterialWarehouse *> warehouses,
    3993             :                                  const std::string & mat_name,
    3994             :                                  const std::string & name,
    3995             :                                  InputParameters & parameters)
    3996             : {
    3997             :   parallel_object_only();
    3998             : 
    3999       14099 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    4000             :   {
    4001         274 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    4002         137 :     _reinit_displaced_elem = _reinit_displaced_face = _reinit_displaced_neighbor = true;
    4003             :   }
    4004             :   else
    4005             :   {
    4006       13962 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    4007             :     {
    4008             :       // We allow Materials to request that they use_displaced_mesh,
    4009             :       // but then be overridden when no displacements variables are
    4010             :       // provided in the Mesh block.  If that happened, update the value
    4011             :       // of use_displaced_mesh appropriately for this Material.
    4012           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    4013           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    4014             :     }
    4015             : 
    4016       41886 :     parameters.set<SubProblem *>("_subproblem") = this;
    4017             :   }
    4018             : 
    4019       29258 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    4020             :   {
    4021             :     // Create the general Block/Boundary MaterialBase object
    4022             :     std::shared_ptr<MaterialBase> material =
    4023       15295 :         _factory.create<MaterialBase>(mat_name, name, parameters, tid);
    4024       15159 :     logAdd("Material", name, mat_name, parameters);
    4025       30318 :     bool discrete = !material->getParam<bool>("compute");
    4026             : 
    4027             :     // If the object is boundary restricted or if it is a functor material we do not create the
    4028             :     // neighbor and face objects
    4029       15159 :     if (material->boundaryRestricted() || dynamic_cast<FunctorMaterial *>(material.get()))
    4030             :     {
    4031        3429 :       _all_materials.addObject(material, tid);
    4032        3429 :       if (discrete)
    4033           5 :         _discrete_materials.addObject(material, tid);
    4034             :       else
    4035        6848 :         for (auto && warehouse : warehouses)
    4036        3424 :           warehouse->addObject(material, tid);
    4037             :     }
    4038             : 
    4039             :     // Non-boundary restricted require face and neighbor objects
    4040             :     else
    4041             :     {
    4042             :       // TODO: we only need to do this if we have needs for face materials (e.g.
    4043             :       // FV, DG, etc.) - but currently we always do it.  Figure out how to fix
    4044             :       // this.
    4045             : 
    4046             :       // The name of the object being created, this is changed multiple times as objects are
    4047             :       // created below
    4048       11730 :       std::string object_name;
    4049             : 
    4050             :       // Create a copy of the supplied parameters to the setting for "_material_data_type" isn't
    4051             :       // used from a previous tid loop
    4052       11730 :       InputParameters current_parameters = parameters;
    4053             : 
    4054             :       // face material
    4055       11730 :       current_parameters.set<Moose::MaterialDataType>("_material_data_type") =
    4056             :           Moose::FACE_MATERIAL_DATA;
    4057       11730 :       object_name = name + "_face";
    4058             :       std::shared_ptr<MaterialBase> face_material =
    4059       11730 :           _factory.create<MaterialBase>(mat_name, object_name, current_parameters, tid);
    4060             : 
    4061             :       // neighbor material
    4062       23460 :       current_parameters.set<Moose::MaterialDataType>("_material_data_type") =
    4063             :           Moose::NEIGHBOR_MATERIAL_DATA;
    4064       11730 :       current_parameters.set<bool>("_neighbor") = true;
    4065       11730 :       object_name = name + "_neighbor";
    4066             :       std::shared_ptr<MaterialBase> neighbor_material =
    4067       11730 :           _factory.create<MaterialBase>(mat_name, object_name, current_parameters, tid);
    4068             : 
    4069             :       // Store the material objects
    4070       11730 :       _all_materials.addObjects(material, neighbor_material, face_material, tid);
    4071             : 
    4072       11730 :       if (discrete)
    4073          80 :         _discrete_materials.addObjects(material, neighbor_material, face_material, tid);
    4074             :       else
    4075       23300 :         for (auto && warehouse : warehouses)
    4076       11650 :           warehouse->addObjects(material, neighbor_material, face_material, tid);
    4077             : 
    4078             :       // Names of all controllable parameters for this Material object
    4079       11730 :       const std::string & base = parameters.getBase();
    4080       35190 :       MooseObjectParameterName name(MooseObjectName(base, material->name()), "*");
    4081             :       const auto param_names =
    4082       11730 :           _app.getInputParameterWarehouse().getControllableParameterNames(name);
    4083             : 
    4084             :       // Connect parameters of the primary Material object to those on the face and neighbor
    4085             :       // objects
    4086       29812 :       for (const auto & p_name : param_names)
    4087             :       {
    4088       36164 :         MooseObjectParameterName primary_name(MooseObjectName(base, material->name()),
    4089       36164 :                                               p_name.parameter());
    4090       36164 :         MooseObjectParameterName face_name(MooseObjectName(base, face_material->name()),
    4091       36164 :                                            p_name.parameter());
    4092       36164 :         MooseObjectParameterName neighbor_name(MooseObjectName(base, neighbor_material->name()),
    4093       36164 :                                                p_name.parameter());
    4094       18082 :         _app.getInputParameterWarehouse().addControllableParameterConnection(
    4095             :             primary_name, face_name, false);
    4096       18082 :         _app.getInputParameterWarehouse().addControllableParameterConnection(
    4097             :             primary_name, neighbor_name, false);
    4098       18082 :       }
    4099       11730 :     }
    4100       15159 :   }
    4101       13963 : }
    4102             : 
    4103             : void
    4104     5599568 : FEProblemBase::prepareMaterials(const std::unordered_set<unsigned int> & consumer_needed_mat_props,
    4105             :                                 const SubdomainID blk_id,
    4106             :                                 const THREAD_ID tid)
    4107             : {
    4108     5599568 :   std::set<MooseVariableFEBase *> needed_moose_vars;
    4109     5599568 :   std::unordered_set<unsigned int> needed_mat_props;
    4110             : 
    4111     5599568 :   if (_all_materials.hasActiveBlockObjects(blk_id, tid))
    4112             :   {
    4113      676652 :     _all_materials.updateVariableDependency(needed_moose_vars, tid);
    4114      676652 :     _all_materials.updateBlockMatPropDependency(blk_id, needed_mat_props, tid);
    4115             :   }
    4116             : 
    4117     5599568 :   const auto & ids = _mesh.getSubdomainBoundaryIds(blk_id);
    4118    25778183 :   for (const auto id : ids)
    4119             :   {
    4120    20178615 :     _materials.updateBoundaryVariableDependency(id, needed_moose_vars, tid);
    4121    20178615 :     _materials.updateBoundaryMatPropDependency(id, needed_mat_props, tid);
    4122             :   }
    4123             : 
    4124     5599568 :   const auto & current_active_elemental_moose_variables = getActiveElementalMooseVariables(tid);
    4125     5599568 :   needed_moose_vars.insert(current_active_elemental_moose_variables.begin(),
    4126             :                            current_active_elemental_moose_variables.end());
    4127             : 
    4128     5599568 :   needed_mat_props.insert(consumer_needed_mat_props.begin(), consumer_needed_mat_props.end());
    4129             : 
    4130     5599568 :   setActiveElementalMooseVariables(needed_moose_vars, tid);
    4131     5599568 :   setActiveMaterialProperties(needed_mat_props, tid);
    4132     5599568 : }
    4133             : 
    4134             : void
    4135   418683088 : FEProblemBase::reinitMaterials(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful)
    4136             : {
    4137   418683088 :   if (hasActiveMaterialProperties(tid))
    4138             :   {
    4139    19995953 :     auto && elem = _assembly[tid][0]->elem();
    4140    19995953 :     unsigned int n_points = _assembly[tid][0]->qRule()->n_points();
    4141             : 
    4142    19995953 :     auto & material_data = _material_props.getMaterialData(tid);
    4143    19995953 :     material_data.resize(n_points);
    4144             : 
    4145             :     // Only swap if requested
    4146    19995953 :     if (swap_stateful)
    4147    19988614 :       material_data.swap(*elem);
    4148             : 
    4149    19995953 :     if (_discrete_materials.hasActiveBlockObjects(blk_id, tid))
    4150        3089 :       material_data.reset(_discrete_materials.getActiveBlockObjects(blk_id, tid));
    4151             : 
    4152    19995949 :     if (_materials.hasActiveBlockObjects(blk_id, tid))
    4153    19975253 :       material_data.reinit(_materials.getActiveBlockObjects(blk_id, tid));
    4154             :   }
    4155   418683006 : }
    4156             : 
    4157             : void
    4158     8596433 : FEProblemBase::reinitMaterialsFace(const SubdomainID blk_id,
    4159             :                                    const THREAD_ID tid,
    4160             :                                    const bool swap_stateful,
    4161             :                                    const std::deque<MaterialBase *> * const reinit_mats)
    4162             : {
    4163             :   // we reinit more often than needed here because we dont have a way to check whether
    4164             :   // we need to compute the face materials on a particular (possibly external) face
    4165     8596433 :   if (hasActiveMaterialProperties(tid))
    4166             :   {
    4167     2896935 :     auto && elem = _assembly[tid][0]->elem();
    4168     2896935 :     unsigned int side = _assembly[tid][0]->side();
    4169     2896935 :     unsigned int n_points = _assembly[tid][0]->qRuleFace()->n_points();
    4170             : 
    4171     2896935 :     auto & bnd_material_data = _bnd_material_props.getMaterialData(tid);
    4172     2896935 :     bnd_material_data.resize(n_points);
    4173             : 
    4174     2896935 :     if (swap_stateful && !bnd_material_data.isSwapped())
    4175     2872583 :       bnd_material_data.swap(*elem, side);
    4176             : 
    4177     2896935 :     if (_discrete_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    4178           0 :       bnd_material_data.reset(
    4179           0 :           _discrete_materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid));
    4180             : 
    4181     2896935 :     if (reinit_mats)
    4182       24352 :       bnd_material_data.reinit(*reinit_mats);
    4183     2872583 :     else if (_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    4184     2872583 :       bnd_material_data.reinit(
    4185     2872583 :           _materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid));
    4186             :   }
    4187     8596433 : }
    4188             : 
    4189             : void
    4190     4343491 : FEProblemBase::reinitMaterialsFaceOnBoundary(const BoundaryID boundary_id,
    4191             :                                              const SubdomainID blk_id,
    4192             :                                              const THREAD_ID tid,
    4193             :                                              const bool swap_stateful,
    4194             :                                              const std::deque<MaterialBase *> * const reinit_mats)
    4195             : {
    4196     4731455 :   if (hasActiveMaterialProperties(tid) && (needBoundaryMaterialOnSide(boundary_id, tid) ||
    4197      387964 :                                            needInterfaceMaterialOnSide(boundary_id, tid) ||
    4198      387964 :                                            needInternalNeighborSideMaterial(blk_id, tid)))
    4199             :   {
    4200      519715 :     const auto * const elem = _assembly[tid][0]->elem();
    4201      519715 :     unsigned int side = _assembly[tid][0]->side();
    4202      519715 :     unsigned int n_points = _assembly[tid][0]->qRuleFace()->n_points();
    4203             : 
    4204      519715 :     auto & bnd_material_data = _bnd_material_props.getMaterialData(tid);
    4205      519715 :     bnd_material_data.resize(n_points);
    4206             : 
    4207      519715 :     if (swap_stateful && !bnd_material_data.isSwapped())
    4208      519715 :       bnd_material_data.swap(*elem, side);
    4209             : 
    4210      519715 :     if (_discrete_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    4211           0 :       bnd_material_data.reset(
    4212           0 :           _discrete_materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid));
    4213             : 
    4214      519715 :     if (reinit_mats)
    4215           0 :       bnd_material_data.reinit(*reinit_mats);
    4216      519715 :     else if (_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    4217      503690 :       bnd_material_data.reinit(
    4218      503690 :           _materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid));
    4219             :   }
    4220     4343491 : }
    4221             : 
    4222             : void
    4223       54438 : FEProblemBase::reinitMaterialsNeighborOnBoundary(
    4224             :     const BoundaryID boundary_id,
    4225             :     const SubdomainID blk_id,
    4226             :     const THREAD_ID tid,
    4227             :     const bool swap_stateful,
    4228             :     const std::deque<MaterialBase *> * const reinit_mats)
    4229             : {
    4230             :   // Since objects don't declare whether they need the face or neighbor (side) material properties,
    4231             :   // we use the same criteria for skipping material property computations as for face material
    4232             :   // properties This could be a future optimization.
    4233       59223 :   if (hasActiveMaterialProperties(tid) && (needBoundaryMaterialOnSide(boundary_id, tid) ||
    4234        4785 :                                            needInterfaceMaterialOnSide(boundary_id, tid) ||
    4235        4785 :                                            needInternalNeighborSideMaterial(blk_id, tid)))
    4236       45110 :     reinitMaterialsNeighbor(blk_id, tid, swap_stateful, reinit_mats);
    4237       54438 : }
    4238             : 
    4239             : void
    4240     4596860 : FEProblemBase::reinitMaterialsNeighbor(const SubdomainID blk_id,
    4241             :                                        const THREAD_ID tid,
    4242             :                                        const bool swap_stateful,
    4243             :                                        const std::deque<MaterialBase *> * const reinit_mats)
    4244             : {
    4245     4596860 :   if (hasActiveMaterialProperties(tid))
    4246             :   {
    4247             :     // NOTE: this will not work with h-adaptivity
    4248             :     // lindsayad: why not?
    4249             : 
    4250     1092527 :     const Elem * neighbor = _assembly[tid][0]->neighbor();
    4251     1092527 :     unsigned int neighbor_side = neighbor->which_neighbor_am_i(_assembly[tid][0]->elem());
    4252             : 
    4253             :     mooseAssert(neighbor, "neighbor should be non-null");
    4254             :     mooseAssert(blk_id == neighbor->subdomain_id(),
    4255             :                 "The provided blk_id " << blk_id << " and neighbor subdomain ID "
    4256             :                                        << neighbor->subdomain_id() << " do not match.");
    4257             : 
    4258     1092527 :     unsigned int n_points = _assembly[tid][0]->qRuleNeighbor()->n_points();
    4259             : 
    4260     1092527 :     auto & neighbor_material_data = _neighbor_material_props.getMaterialData(tid);
    4261     1092527 :     neighbor_material_data.resize(n_points);
    4262             : 
    4263             :     // Only swap if requested
    4264     1092527 :     if (swap_stateful)
    4265     1068175 :       neighbor_material_data.swap(*neighbor, neighbor_side);
    4266             : 
    4267     1092527 :     if (_discrete_materials[Moose::NEIGHBOR_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    4268           0 :       neighbor_material_data.reset(
    4269           0 :           _discrete_materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid));
    4270             : 
    4271     1092527 :     if (reinit_mats)
    4272       24352 :       neighbor_material_data.reinit(*reinit_mats);
    4273     1068175 :     else if (_materials[Moose::NEIGHBOR_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    4274     1067876 :       neighbor_material_data.reinit(
    4275     1067876 :           _materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid));
    4276             :   }
    4277     4596860 : }
    4278             : 
    4279             : void
    4280     4627872 : FEProblemBase::reinitMaterialsBoundary(const BoundaryID boundary_id,
    4281             :                                        const THREAD_ID tid,
    4282             :                                        const bool swap_stateful,
    4283             :                                        const std::deque<MaterialBase *> * const reinit_mats)
    4284             : {
    4285     4627872 :   if (hasActiveMaterialProperties(tid) && needBoundaryMaterialOnSide(boundary_id, tid))
    4286             :   {
    4287      365687 :     auto && elem = _assembly[tid][0]->elem();
    4288      365687 :     unsigned int side = _assembly[tid][0]->side();
    4289      365687 :     unsigned int n_points = _assembly[tid][0]->qRuleFace()->n_points();
    4290             : 
    4291      365687 :     auto & bnd_material_data = _bnd_material_props.getMaterialData(tid);
    4292      365687 :     bnd_material_data.resize(n_points);
    4293             : 
    4294      365687 :     if (swap_stateful && !bnd_material_data.isSwapped())
    4295      310985 :       bnd_material_data.swap(*elem, side);
    4296             : 
    4297      365687 :     if (_discrete_materials.hasActiveBoundaryObjects(boundary_id, tid))
    4298           0 :       bnd_material_data.reset(_discrete_materials.getActiveBoundaryObjects(boundary_id, tid));
    4299             : 
    4300      365687 :     if (reinit_mats)
    4301       24352 :       bnd_material_data.reinit(*reinit_mats);
    4302      341335 :     else if (_materials.hasActiveBoundaryObjects(boundary_id, tid))
    4303       25963 :       bnd_material_data.reinit(_materials.getActiveBoundaryObjects(boundary_id, tid));
    4304             :   }
    4305     4627872 : }
    4306             : 
    4307             : void
    4308       57823 : FEProblemBase::reinitMaterialsInterface(BoundaryID boundary_id,
    4309             :                                         const THREAD_ID tid,
    4310             :                                         bool swap_stateful)
    4311             : {
    4312       57823 :   if (hasActiveMaterialProperties(tid) && needInterfaceMaterialOnSide(boundary_id, tid))
    4313             :   {
    4314       46343 :     const Elem * const & elem = _assembly[tid][0]->elem();
    4315       46343 :     unsigned int side = _assembly[tid][0]->side();
    4316       46343 :     unsigned int n_points = _assembly[tid][0]->qRuleFace()->n_points();
    4317             : 
    4318       46343 :     auto & bnd_material_data = _bnd_material_props.getMaterialData(tid);
    4319       46343 :     bnd_material_data.resize(n_points);
    4320             : 
    4321       46343 :     if (swap_stateful && !bnd_material_data.isSwapped())
    4322       44568 :       bnd_material_data.swap(*elem, side);
    4323             : 
    4324       46343 :     if (_interface_materials.hasActiveBoundaryObjects(boundary_id, tid))
    4325        1317 :       bnd_material_data.reinit(_interface_materials.getActiveBoundaryObjects(boundary_id, tid));
    4326             :   }
    4327       57823 : }
    4328             : 
    4329             : void
    4330   416853272 : FEProblemBase::swapBackMaterials(const THREAD_ID tid)
    4331             : {
    4332   416853272 :   auto && elem = _assembly[tid][0]->elem();
    4333   416853272 :   _material_props.getMaterialData(tid).swapBack(*elem);
    4334   416853272 : }
    4335             : 
    4336             : void
    4337    12655524 : FEProblemBase::swapBackMaterialsFace(const THREAD_ID tid)
    4338             : {
    4339    12655524 :   auto && elem = _assembly[tid][0]->elem();
    4340    12655524 :   unsigned int side = _assembly[tid][0]->side();
    4341    12655524 :   _bnd_material_props.getMaterialData(tid).swapBack(*elem, side);
    4342    12655524 : }
    4343             : 
    4344             : void
    4345     4213629 : FEProblemBase::swapBackMaterialsNeighbor(const THREAD_ID tid)
    4346             : {
    4347             :   // NOTE: this will not work with h-adaptivity
    4348     4213629 :   const Elem * neighbor = _assembly[tid][0]->neighbor();
    4349             :   unsigned int neighbor_side =
    4350     4213629 :       neighbor ? neighbor->which_neighbor_am_i(_assembly[tid][0]->elem()) : libMesh::invalid_uint;
    4351             : 
    4352     4213629 :   if (!neighbor)
    4353             :   {
    4354           0 :     if (haveFV())
    4355             :     {
    4356             :       // If neighbor is null, then we're on the neighbor side of a mesh boundary, e.g. we're off
    4357             :       // the mesh in ghost-land. If we're using the finite volume method, then variable values and
    4358             :       // consequently material properties have well-defined values in this ghost region outside of
    4359             :       // the mesh and we really do want to reinit our neighbor materials in this case. Since we're
    4360             :       // off in ghost land it's safe to do swaps with `MaterialPropertyStorage` using the elem and
    4361             :       // elem_side keys
    4362           0 :       neighbor = _assembly[tid][0]->elem();
    4363           0 :       neighbor_side = _assembly[tid][0]->side();
    4364             :       mooseAssert(neighbor, "We should have an appropriate value for elem coming from Assembly");
    4365             :     }
    4366             :     else
    4367           0 :       mooseError("neighbor is null in Assembly!");
    4368             :   }
    4369             : 
    4370     4213629 :   _neighbor_material_props.getMaterialData(tid).swapBack(*neighbor, neighbor_side);
    4371     4213629 : }
    4372             : 
    4373             : void
    4374     1005278 : FEProblemBase::logAdd(const std::string & system,
    4375             :                       const std::string & name,
    4376             :                       const std::string & type,
    4377             :                       const InputParameters & params) const
    4378             : {
    4379     1005278 :   if (_verbose_setup != "false")
    4380       19260 :     _console << "[DBG] Adding " << system << " '" << name << "' of type " << type << std::endl;
    4381     1005278 :   if (_verbose_setup == "extra")
    4382           0 :     _console << params << std::endl;
    4383     1005278 : }
    4384             : 
    4385             : void
    4386      135187 : FEProblemBase::addObjectParamsHelper(InputParameters & parameters,
    4387             :                                      const std::string & object_name,
    4388             :                                      const std::string & var_param_name)
    4389             : {
    4390             :   // Due to objects like SolutionUserObject which manipulate libmesh objects
    4391             :   // and variables directly at the back end, we need a default option here
    4392             :   // which is going to be the pointer to the first solver system within this
    4393             :   // problem
    4394      135187 :   unsigned int sys_num = 0;
    4395      135187 :   if (parameters.isParamValid(var_param_name))
    4396             :   {
    4397       59117 :     const auto variable_name = parameters.varName(var_param_name, object_name);
    4398       59117 :     if (this->hasVariable(variable_name) || this->hasScalarVariable(variable_name))
    4399       57591 :       sys_num = getSystem(variable_name).number();
    4400       59117 :   }
    4401      270374 :   if (parameters.isParamValid("solver_sys"))
    4402             :   {
    4403         863 :     const auto var_sys_num = sys_num;
    4404         863 :     sys_num = getSystemBase(parameters.get<SolverSystemName>("solver_sys")).number();
    4405         863 :     if (sys_num != var_sys_num && parameters.isParamValid(var_param_name))
    4406           0 :       mooseError("We dont support setting 'variable' to a variable that is not set to the same "
    4407             :                  "system as the 'solver_sys' parameter");
    4408             :   }
    4409             : 
    4410      136470 :   if (_displaced_problem && parameters.have_parameter<bool>("use_displaced_mesh") &&
    4411      136470 :       parameters.get<bool>("use_displaced_mesh"))
    4412             :   {
    4413        1260 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    4414         630 :     if (sys_num == _aux->number())
    4415        1197 :       parameters.set<SystemBase *>("_sys") = &_displaced_problem->systemBaseAuxiliary();
    4416             :     else
    4417         693 :       parameters.set<SystemBase *>("_sys") = &_displaced_problem->solverSys(sys_num);
    4418             :   }
    4419             :   else
    4420             :   {
    4421             :     // The object requested use_displaced_mesh, but it was overridden
    4422             :     // due to there being no displacements variables in the [Mesh] block.
    4423             :     // If that happened, update the value of use_displaced_mesh appropriately.
    4424      233551 :     if (!_displaced_problem && parameters.have_parameter<bool>("use_displaced_mesh") &&
    4425      233551 :         parameters.get<bool>("use_displaced_mesh"))
    4426         146 :       parameters.set<bool>("use_displaced_mesh") = false;
    4427             : 
    4428      269114 :     parameters.set<SubProblem *>("_subproblem") = this;
    4429             : 
    4430      134557 :     if (sys_num == _aux->number())
    4431       38220 :       parameters.set<SystemBase *>("_sys") = _aux.get();
    4432             :     else
    4433      365451 :       parameters.set<SystemBase *>("_sys") = _solver_systems[sys_num].get();
    4434             :   }
    4435      135187 : }
    4436             : 
    4437             : void
    4438       55054 : FEProblemBase::addPostprocessor(const std::string & pp_name,
    4439             :                                 const std::string & name,
    4440             :                                 InputParameters & parameters)
    4441             : {
    4442             :   // Check for name collision
    4443       55054 :   if (hasUserObject(name))
    4444           4 :     mooseError("A ",
    4445           4 :                getUserObjectBase(name).typeAndName(),
    4446             :                " already exists. You may not add a Postprocessor by the same name.");
    4447             : 
    4448       55050 :   addUserObject(pp_name, name, parameters);
    4449       55014 : }
    4450             : 
    4451             : void
    4452        5794 : FEProblemBase::addVectorPostprocessor(const std::string & pp_name,
    4453             :                                       const std::string & name,
    4454             :                                       InputParameters & parameters)
    4455             : {
    4456             :   // Check for name collision
    4457        5794 :   if (hasUserObject(name))
    4458           4 :     mooseError("A ",
    4459           4 :                getUserObjectBase(name).typeAndName(),
    4460             :                " already exists. You may not add a VectorPostprocessor by the same name.");
    4461             : 
    4462        5790 :   addUserObject(pp_name, name, parameters);
    4463        5750 : }
    4464             : 
    4465             : void
    4466        4900 : FEProblemBase::addReporter(const std::string & type,
    4467             :                            const std::string & name,
    4468             :                            InputParameters & parameters)
    4469             : {
    4470             :   // Check for name collision
    4471        4900 :   if (hasUserObject(name))
    4472           4 :     mooseError("A ",
    4473           4 :                getUserObjectBase(name).typeAndName(),
    4474             :                " already exists. You may not add a Reporter by the same name.");
    4475             : 
    4476        4896 :   addUserObject(type, name, parameters);
    4477        4852 : }
    4478             : 
    4479             : std::vector<std::shared_ptr<UserObject>>
    4480       79542 : FEProblemBase::addUserObject(const std::string & user_object_name,
    4481             :                              const std::string & name,
    4482             :                              InputParameters & parameters)
    4483             : {
    4484             :   parallel_object_only();
    4485             : 
    4486       79542 :   std::vector<std::shared_ptr<UserObject>> uos;
    4487             : 
    4488             :   // Add the _subproblem and _sys parameters depending on use_displaced_mesh
    4489       79542 :   addObjectParamsHelper(parameters, name);
    4490             : 
    4491      126731 :   for (const auto tid : make_range(libMesh::n_threads()))
    4492             :   {
    4493             :     // Create the UserObject
    4494             :     std::shared_ptr<UserObject> user_object =
    4495       83118 :         _factory.create<UserObject>(user_object_name, name, parameters, tid);
    4496       82738 :     logAdd("UserObject", name, user_object_name, parameters);
    4497       82738 :     uos.push_back(user_object);
    4498             : 
    4499       82738 :     if (tid != 0)
    4500        3576 :       user_object->setPrimaryThreadCopy(uos[0].get());
    4501             : 
    4502             :     // TODO: delete this line after apps have been updated to not call getUserObjects
    4503       82738 :     _all_user_objects.addObject(user_object, tid);
    4504             : 
    4505       82730 :     theWarehouse().add(user_object);
    4506             : 
    4507             :     // Attempt to create all the possible UserObject types
    4508       82730 :     auto euo = std::dynamic_pointer_cast<ElementUserObject>(user_object);
    4509       82730 :     auto suo = std::dynamic_pointer_cast<SideUserObject>(user_object);
    4510       82730 :     auto isuo = std::dynamic_pointer_cast<InternalSideUserObject>(user_object);
    4511       82730 :     auto iuo = std::dynamic_pointer_cast<InterfaceUserObjectBase>(user_object);
    4512       82730 :     auto nuo = std::dynamic_pointer_cast<NodalUserObject>(user_object);
    4513       82730 :     auto duo = std::dynamic_pointer_cast<DomainUserObject>(user_object);
    4514       82730 :     auto guo = std::dynamic_pointer_cast<GeneralUserObject>(user_object);
    4515       82730 :     auto tguo = std::dynamic_pointer_cast<ThreadedGeneralUserObject>(user_object);
    4516       82730 :     auto muo = std::dynamic_pointer_cast<MortarUserObject>(user_object);
    4517             : 
    4518             :     // Account for displaced mesh use
    4519       82730 :     if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    4520             :     {
    4521             :       // Whether to re-init or not depends on the attributes of the base classes.
    4522             :       // For example, InterfaceUOBase has "_current_side_elem" and "_neighbor_elem"
    4523             :       // so it needs to reinit on displaced neighbors and faces
    4524             :       // _reinit_displaced_elem -> _current_elem will be reinited
    4525             :       // _reinit_displaced_face -> _current_elem, lowerD if any and _current_side_elem to be
    4526             :       // reinited _reinit_displaced_neighbor -> _current_elem, lowerD if any and _current_neighbor
    4527             :       // to be reinited Note that as soon as you use materials on the displaced mesh, all three get
    4528             :       // turned on.
    4529         680 :       if (euo || nuo || duo)
    4530         606 :         _reinit_displaced_elem = true;
    4531         680 :       if (suo || duo || isuo || iuo)
    4532          35 :         _reinit_displaced_face = true;
    4533         680 :       if (iuo || duo || isuo)
    4534           0 :         _reinit_displaced_neighbor = true;
    4535             :     }
    4536             : 
    4537             :     // These objects only require one thread
    4538       82730 :     if ((guo && !tguo) || muo)
    4539       35541 :       break;
    4540      402599 :   }
    4541             : 
    4542             :   // Add as a Functor if it is one. We usually need to add the user object from thread 0 as the
    4543             :   // registered functor for all threads because when user objects are thread joined, generally only
    4544             :   // the primary thread copy ends up with all the data
    4545      165865 :   for (const auto tid : make_range(libMesh::n_threads()))
    4546             :   {
    4547       86711 :     const decltype(uos)::size_type uo_index = uos.front()->needThreadedCopy() ? tid : 0;
    4548       86711 :     if (const auto functor = dynamic_cast<Moose::FunctorBase<Real> *>(uos[uo_index].get()))
    4549             :     {
    4550       65016 :       this->addFunctor(name, *functor, tid);
    4551       65016 :       if (_displaced_problem)
    4552         804 :         _displaced_problem->addFunctor(name, *functor, tid);
    4553             :     }
    4554             :   }
    4555             : 
    4556       79154 :   return uos;
    4557          16 : }
    4558             : 
    4559             : const UserObject &
    4560      330086 : FEProblemBase::getUserObjectBase(const std::string & name, const THREAD_ID tid /* = 0 */) const
    4561             : {
    4562      330086 :   std::vector<UserObject *> objs;
    4563      330086 :   theWarehouse()
    4564      660172 :       .query()
    4565      330086 :       .condition<AttribSystem>("UserObject")
    4566      330086 :       .condition<AttribThread>(tid)
    4567      330086 :       .condition<AttribName>(name)
    4568      330086 :       .queryInto(objs);
    4569      330086 :   if (objs.empty())
    4570           0 :     mooseError("Unable to find user object with name '" + name + "'");
    4571             :   mooseAssert(objs.size() == 1, "Should only find one UO");
    4572      660172 :   return *(objs[0]);
    4573      330086 : }
    4574             : 
    4575             : const Positions &
    4576        1154 : FEProblemBase::getPositionsObject(const std::string & name) const
    4577             : {
    4578        1154 :   std::vector<Positions *> objs;
    4579        1154 :   theWarehouse()
    4580        2308 :       .query()
    4581        1154 :       .condition<AttribSystem>("UserObject")
    4582        1154 :       .condition<AttribName>(name)
    4583        1154 :       .queryInto(objs);
    4584        1154 :   if (objs.empty())
    4585           0 :     mooseError("Unable to find Positions object with name '" + name + "'");
    4586             :   mooseAssert(objs.size() == 1, "Should only find one Positions");
    4587        2308 :   return *(objs[0]);
    4588        1154 : }
    4589             : 
    4590             : bool
    4591       93251 : FEProblemBase::hasUserObject(const std::string & name) const
    4592             : {
    4593       93251 :   std::vector<UserObject *> objs;
    4594       93251 :   theWarehouse()
    4595       93251 :       .query()
    4596       93251 :       .condition<AttribSystem>("UserObject")
    4597      186502 :       .condition<AttribThread>(0)
    4598       93251 :       .condition<AttribName>(name)
    4599       93251 :       .queryInto(objs);
    4600      186502 :   return !objs.empty();
    4601       93251 : }
    4602             : 
    4603             : bool
    4604         478 : FEProblemBase::hasPostprocessorValueByName(const PostprocessorName & name) const
    4605             : {
    4606         478 :   return _reporter_data.hasReporterValue<PostprocessorValue>(PostprocessorReporterName(name));
    4607             : }
    4608             : 
    4609             : const PostprocessorValue &
    4610      907331 : FEProblemBase::getPostprocessorValueByName(const PostprocessorName & name,
    4611             :                                            std::size_t t_index) const
    4612             : {
    4613     1814662 :   return _reporter_data.getReporterValue<PostprocessorValue>(PostprocessorReporterName(name),
    4614     1814662 :                                                              t_index);
    4615             : }
    4616             : 
    4617             : void
    4618      601781 : FEProblemBase::setPostprocessorValueByName(const PostprocessorName & name,
    4619             :                                            const PostprocessorValue & value,
    4620             :                                            std::size_t t_index)
    4621             : {
    4622      601781 :   _reporter_data.setReporterValue<PostprocessorValue>(
    4623     1203562 :       PostprocessorReporterName(name), value, t_index);
    4624      601781 : }
    4625             : 
    4626             : bool
    4627          56 : FEProblemBase::hasPostprocessor(const std::string & name) const
    4628             : {
    4629          56 :   mooseDeprecated("FEProblemBase::hasPostprocssor is being removed; use "
    4630             :                   "hasPostprocessorValueByName instead.");
    4631          56 :   return hasPostprocessorValueByName(name);
    4632             : }
    4633             : 
    4634             : const VectorPostprocessorValue &
    4635          57 : FEProblemBase::getVectorPostprocessorValueByName(const std::string & object_name,
    4636             :                                                  const std::string & vector_name,
    4637             :                                                  std::size_t t_index) const
    4638             : {
    4639          57 :   return _reporter_data.getReporterValue<VectorPostprocessorValue>(
    4640         114 :       VectorPostprocessorReporterName(object_name, vector_name), t_index);
    4641             : }
    4642             : 
    4643             : void
    4644          20 : FEProblemBase::setVectorPostprocessorValueByName(const std::string & object_name,
    4645             :                                                  const std::string & vector_name,
    4646             :                                                  const VectorPostprocessorValue & value,
    4647             :                                                  std::size_t t_index)
    4648             : {
    4649          20 :   _reporter_data.setReporterValue<VectorPostprocessorValue>(
    4650          40 :       VectorPostprocessorReporterName(object_name, vector_name), value, t_index);
    4651          20 : }
    4652             : 
    4653             : const VectorPostprocessor &
    4654        9248 : FEProblemBase::getVectorPostprocessorObjectByName(const std::string & object_name,
    4655             :                                                   const THREAD_ID tid) const
    4656             : {
    4657        9248 :   return getUserObject<VectorPostprocessor>(object_name, tid);
    4658             : }
    4659             : 
    4660             : void
    4661          77 : FEProblemBase::parentOutputPositionChanged()
    4662             : {
    4663        2156 :   for (const auto & it : _multi_apps)
    4664             :   {
    4665        2079 :     const auto & objects = it.second.getActiveObjects();
    4666        2100 :     for (const auto & obj : objects)
    4667          21 :       obj->parentOutputPositionChanged();
    4668             :   }
    4669          77 : }
    4670             : 
    4671             : void
    4672           0 : FEProblemBase::computeIndicatorsAndMarkers()
    4673             : {
    4674           0 :   computeIndicators();
    4675           0 :   computeMarkers();
    4676           0 : }
    4677             : 
    4678             : void
    4679      239806 : FEProblemBase::computeIndicators()
    4680             : {
    4681             :   // Initialize indicator aux variable fields
    4682      239806 :   if (_indicators.hasActiveObjects() || _internal_side_indicators.hasActiveObjects())
    4683             :   {
    4684       12880 :     TIME_SECTION("computeIndicators", 1, "Computing Indicators");
    4685             : 
    4686             :     // Internal side indicators may lead to creating a much larger sparsity pattern than dictated by
    4687             :     // the actual finite element scheme (e.g. CFEM)
    4688        2576 :     const auto old_do_derivatives = ADReal::do_derivatives;
    4689        2576 :     ADReal::do_derivatives = false;
    4690             : 
    4691        2576 :     std::vector<std::string> fields;
    4692             : 
    4693             :     // Indicator Fields
    4694        2576 :     const auto & indicators = _indicators.getActiveObjects();
    4695        2736 :     for (const auto & indicator : indicators)
    4696         160 :       fields.push_back(indicator->name());
    4697             : 
    4698             :     // InternalSideIndicator Fields
    4699        2576 :     const auto & internal_indicators = _internal_side_indicators.getActiveObjects();
    4700        5056 :     for (const auto & internal_indicator : internal_indicators)
    4701        2480 :       fields.push_back(internal_indicator->name());
    4702             : 
    4703        2576 :     _aux->zeroVariables(fields);
    4704             : 
    4705             :     // compute Indicators
    4706        2576 :     ComputeIndicatorThread cit(*this);
    4707        2576 :     Threads::parallel_reduce(*_mesh.getActiveLocalElementRange(), cit);
    4708        2576 :     _aux->solution().close();
    4709        2576 :     _aux->update();
    4710             : 
    4711        2576 :     ComputeIndicatorThread finalize_cit(*this, true);
    4712        2576 :     Threads::parallel_reduce(*_mesh.getActiveLocalElementRange(), finalize_cit);
    4713        2576 :     _aux->solution().close();
    4714        2576 :     _aux->update();
    4715             : 
    4716        2576 :     ADReal::do_derivatives = old_do_derivatives;
    4717        2576 :   }
    4718      239806 : }
    4719             : 
    4720             : void
    4721      239830 : FEProblemBase::computeMarkers()
    4722             : {
    4723      239830 :   if (_markers.hasActiveObjects())
    4724             :   {
    4725       35360 :     TIME_SECTION("computeMarkers", 1, "Computing Markers");
    4726             : 
    4727        7072 :     std::vector<std::string> fields;
    4728             : 
    4729             :     // Marker Fields
    4730        7072 :     const auto & markers = _markers.getActiveObjects();
    4731       15122 :     for (const auto & marker : markers)
    4732        8050 :       fields.push_back(marker->name());
    4733             : 
    4734        7072 :     _aux->zeroVariables(fields);
    4735             : 
    4736        7072 :     _adaptivity.updateErrorVectors();
    4737             : 
    4738       14764 :     for (THREAD_ID tid = 0; tid < libMesh::n_threads(); ++tid)
    4739             :     {
    4740        7696 :       const auto & markers = _markers.getActiveObjects(tid);
    4741       16453 :       for (const auto & marker : markers)
    4742        8761 :         marker->markerSetup();
    4743             :     }
    4744             : 
    4745        7068 :     ComputeMarkerThread cmt(*this);
    4746        7068 :     Threads::parallel_reduce(*_mesh.getActiveLocalElementRange(), cmt);
    4747             : 
    4748        7068 :     _aux->solution().close();
    4749        7068 :     _aux->update();
    4750        7068 :   }
    4751      239826 : }
    4752             : 
    4753             : const ExecFlagType &
    4754     2736867 : FEProblemBase::getCurrentExecuteOnFlag() const
    4755             : {
    4756     2736867 :   return _current_execute_on_flag;
    4757             : }
    4758             : 
    4759             : void
    4760     7478084 : FEProblemBase::setCurrentExecuteOnFlag(const ExecFlagType & flag)
    4761             : {
    4762     7478084 :   _current_execute_on_flag = flag;
    4763     7478084 : }
    4764             : 
    4765             : void
    4766          80 : FEProblemBase::executeAllObjects(const ExecFlagType & /*exec_type*/)
    4767             : {
    4768          80 : }
    4769             : 
    4770             : void
    4771     1918202 : FEProblemBase::customSetup(const ExecFlagType & exec_type)
    4772             : {
    4773     1918202 :   SubProblem::customSetup(exec_type);
    4774             : 
    4775     1918202 :   if (_line_search)
    4776           0 :     _line_search->customSetup(exec_type);
    4777             : 
    4778     1918202 :   unsigned int n_threads = libMesh::n_threads();
    4779     4008286 :   for (THREAD_ID tid = 0; tid < n_threads; tid++)
    4780             :   {
    4781     2090084 :     _all_materials.customSetup(exec_type, tid);
    4782     2090084 :     _functions.customSetup(exec_type, tid);
    4783             :   }
    4784             : 
    4785     1918202 :   _aux->customSetup(exec_type);
    4786     3867010 :   for (auto & nl : _nl)
    4787     1948808 :     nl->customSetup(exec_type);
    4788             : 
    4789     1918202 :   if (_displaced_problem)
    4790      158920 :     _displaced_problem->customSetup(exec_type);
    4791             : 
    4792     4008286 :   for (THREAD_ID tid = 0; tid < n_threads; tid++)
    4793             :   {
    4794     2090084 :     _internal_side_indicators.customSetup(exec_type, tid);
    4795     2090084 :     _indicators.customSetup(exec_type, tid);
    4796     2090084 :     _markers.customSetup(exec_type, tid);
    4797             :   }
    4798             : 
    4799     1918202 :   std::vector<UserObject *> userobjs;
    4800     1918202 :   theWarehouse().query().condition<AttribSystem>("UserObject").queryIntoUnsorted(userobjs);
    4801     4761728 :   for (auto obj : userobjs)
    4802     2843526 :     obj->customSetup(exec_type);
    4803             : 
    4804     1918202 :   _app.getOutputWarehouse().customSetup(exec_type);
    4805     1918202 : }
    4806             : 
    4807             : void
    4808     2316497 : FEProblemBase::execute(const ExecFlagType & exec_type)
    4809             : {
    4810             :   // Set the current flag
    4811     2316497 :   setCurrentExecuteOnFlag(exec_type);
    4812             : 
    4813     2316497 :   if (exec_type != EXEC_INITIAL)
    4814     2258948 :     executeControls(exec_type);
    4815             : 
    4816             :   // intentially call this after executing controls because the setups may rely on the controls
    4817             :   // FIXME: we skip the following flags because they have dedicated setup functions in
    4818             :   //        SetupInterface and it may not be appropriate to call them here.
    4819     4237411 :   if (!(exec_type == EXEC_INITIAL || exec_type == EXEC_TIMESTEP_BEGIN ||
    4820     1920922 :         exec_type == EXEC_SUBDOMAIN || exec_type == EXEC_NONLINEAR || exec_type == EXEC_LINEAR))
    4821     1918202 :     customSetup(exec_type);
    4822             : 
    4823             :   // Samplers; EXEC_INITIAL is not called because the Sampler::init() method that is called after
    4824             :   // construction makes the first Sampler::execute() call. This ensures that the random number
    4825             :   // generator object is the correct state prior to any other object (e.g., Transfers) attempts to
    4826             :   // extract data from the Sampler. That is, if the Sampler::execute() call is delayed to here
    4827             :   // then it is not in the correct state for other objects.
    4828     2316489 :   if (exec_type != EXEC_INITIAL)
    4829     2258940 :     executeSamplers(exec_type);
    4830             : 
    4831             :   // Pre-aux UserObjects
    4832     2316457 :   computeUserObjects(exec_type, Moose::PRE_AUX);
    4833             : 
    4834             :   // Systems (includes system time derivative and aux kernel calculations)
    4835     2316457 :   computeSystems(exec_type);
    4836             :   // With the auxiliary system solution computed, sync the displaced problem auxiliary solution
    4837             :   // before computation of post-aux user objects. The undisplaced auxiliary system current local
    4838             :   // solution is updated (via System::update) within the AuxiliarySystem class's variable
    4839             :   // computation methods (e.g. computeElementalVarsHelper, computeNodalVarsHelper), so it is safe to
    4840             :   // use it here
    4841     2316412 :   if (_displaced_problem)
    4842      196607 :     _displaced_problem->syncAuxSolution(*getAuxiliarySystem().currentSolution());
    4843             : 
    4844             :   // Post-aux UserObjects
    4845     2316412 :   computeUserObjects(exec_type, Moose::POST_AUX);
    4846             : 
    4847             :   // Return the current flag to None
    4848     2316295 :   setCurrentExecuteOnFlag(EXEC_NONE);
    4849             : 
    4850     2316295 :   if (_uo_aux_state_check && !_checking_uo_aux_state)
    4851             :   {
    4852             :     // we will only check aux variables and postprocessors
    4853             :     // checking more reporter data can be added in the future if needed
    4854         624 :     std::unique_ptr<NumericVector<Number>> x = _aux->currentSolution()->clone();
    4855         624 :     DenseVector<Real> pp_values = getReporterData().getAllRealReporterValues();
    4856             : 
    4857             :     // call THIS execute one more time for checking the possible states
    4858         624 :     _checking_uo_aux_state = true;
    4859         624 :     FEProblemBase::execute(exec_type);
    4860         624 :     _checking_uo_aux_state = false;
    4861             : 
    4862         624 :     const Real check_tol = 1e-8;
    4863             : 
    4864         624 :     const Real xnorm = x->l2_norm();
    4865         624 :     *x -= *_aux->currentSolution();
    4866         624 :     if (x->l2_norm() > check_tol * xnorm)
    4867             :     {
    4868           4 :       const auto & sys = _aux->system();
    4869           4 :       const unsigned int n_vars = sys.n_vars();
    4870           4 :       std::multimap<Real, std::string, std::greater<Real>> ordered_map;
    4871          20 :       for (const auto i : make_range(n_vars))
    4872             :       {
    4873          16 :         const Real vnorm = sys.calculate_norm(*x, i, DISCRETE_L2);
    4874          16 :         ordered_map.emplace(vnorm, sys.variable_name(i));
    4875             :       }
    4876             : 
    4877           4 :       std::ostringstream oss;
    4878          20 :       for (const auto & [error_norm, var_name] : ordered_map)
    4879          16 :         oss << "  {" << var_name << ", " << error_norm << "},\n";
    4880             : 
    4881           4 :       mooseError("Aux kernels, user objects appear to have states for aux variables on ",
    4882             :                  exec_type,
    4883             :                  ".\nVariable error norms in descending order:\n",
    4884           4 :                  oss.str());
    4885           0 :     }
    4886             : 
    4887         620 :     const DenseVector<Real> new_pp_values = getReporterData().getAllRealReporterValues();
    4888         620 :     if (pp_values.size() != new_pp_values.size())
    4889           0 :       mooseError("Second execution for uo/aux state check should not change the number of "
    4890             :                  "real reporter values");
    4891             : 
    4892         620 :     const Real ppnorm = pp_values.l2_norm();
    4893         620 :     pp_values -= new_pp_values;
    4894         620 :     if (pp_values.l2_norm() > check_tol * ppnorm)
    4895             :     {
    4896           4 :       const auto pp_names = getReporterData().getAllRealReporterFullNames();
    4897           4 :       std::multimap<Real, std::string, std::greater<Real>> ordered_map;
    4898          16 :       for (const auto i : index_range(pp_names))
    4899          12 :         ordered_map.emplace(std::abs(pp_values(i)), pp_names[i]);
    4900             : 
    4901           4 :       std::ostringstream oss;
    4902          16 :       for (const auto & [error_norm, pp_name] : ordered_map)
    4903          12 :         oss << "  {" << pp_name << ", " << error_norm << "},\n";
    4904             : 
    4905           4 :       mooseError("Aux kernels, user objects appear to have states for real reporter values on ",
    4906             :                  exec_type,
    4907             :                  ".\nErrors of real reporter values in descending order:\n",
    4908           4 :                  oss.str());
    4909           0 :     }
    4910         616 :   }
    4911     2316287 : }
    4912             : 
    4913             : // Finalize, threadJoin, and update PP values of Elemental/Nodal/Side/InternalSideUserObjects
    4914             : void
    4915     1424413 : FEProblemBase::joinAndFinalize(TheWarehouse::Query query, bool isgen)
    4916             : {
    4917     1424413 :   std::vector<UserObject *> objs;
    4918     1424413 :   query.queryInto(objs);
    4919     1424413 :   if (!isgen)
    4920             :   {
    4921             :     // join all threaded user objects (i.e. not regular general user objects) to the primary
    4922             :     // thread
    4923     1507488 :     for (auto obj : objs)
    4924      391436 :       if (obj->primaryThreadCopy())
    4925       29096 :         obj->primaryThreadCopy()->threadJoin(*obj);
    4926             :   }
    4927             : 
    4928     1424413 :   query.condition<AttribThread>(0).queryInto(objs);
    4929             : 
    4930             :   // finalize objects and retrieve/store any postprocessor values
    4931     2030553 :   for (auto obj : objs)
    4932             :   {
    4933      606249 :     if (isgen && dynamic_cast<ThreadedGeneralUserObject *>(obj))
    4934         116 :       continue;
    4935      606133 :     if (isgen)
    4936             :     {
    4937             :       // general user objects are not run in their own threaded loop object - so run them here
    4938      243793 :       if (shouldPrintExecution(0))
    4939         798 :         _console << "[DBG] Initializing, executing & finalizing general UO '" << obj->name()
    4940         798 :                  << "' on " << _current_execute_on_flag.name() << std::endl;
    4941      243793 :       obj->initialize();
    4942      243793 :       obj->execute();
    4943             :     }
    4944             : 
    4945      606064 :     obj->finalize();
    4946             : 
    4947             :     // These have to be stored piecemeal (with every call to this function) because general
    4948             :     // postprocessors (which run last after other userobjects have been completed) might depend on
    4949             :     // them being stored.  This wouldn't be a problem if all userobjects satisfied the dependency
    4950             :     // resolver interface and could be sorted appropriately with the general userobjects, but they
    4951             :     // don't.
    4952      606044 :     auto pp = dynamic_cast<const Postprocessor *>(obj);
    4953      606044 :     if (pp)
    4954             :     {
    4955      528014 :       _reporter_data.finalize(obj->name());
    4956      528014 :       setPostprocessorValueByName(obj->name(), pp->getValue());
    4957             :     }
    4958             : 
    4959      606032 :     auto vpp = dynamic_cast<VectorPostprocessor *>(obj);
    4960      606032 :     if (vpp)
    4961       14348 :       _reporter_data.finalize(obj->name());
    4962             : 
    4963             :     // Update Reporter data
    4964      606032 :     auto reporter = dynamic_cast<Reporter *>(obj);
    4965      606032 :     if (reporter)
    4966        5375 :       _reporter_data.finalize(obj->name());
    4967             :   }
    4968     1424304 : }
    4969             : 
    4970             : void
    4971       57176 : FEProblemBase::computeUserObjectByName(const ExecFlagType & type,
    4972             :                                        const Moose::AuxGroup & group,
    4973             :                                        const std::string & name)
    4974             : {
    4975       57176 :   const auto old_exec_flag = _current_execute_on_flag;
    4976       57176 :   _current_execute_on_flag = type;
    4977       57176 :   TheWarehouse::Query query = theWarehouse()
    4978      114352 :                                   .query()
    4979       57176 :                                   .condition<AttribSystem>("UserObject")
    4980       57176 :                                   .condition<AttribExecOns>(type)
    4981       57176 :                                   .condition<AttribName>(name);
    4982       57176 :   computeUserObjectsInternal(type, group, query);
    4983       57176 :   _current_execute_on_flag = old_exec_flag;
    4984       57176 : }
    4985             : 
    4986             : void
    4987    12434890 : FEProblemBase::computeUserObjects(const ExecFlagType & type, const Moose::AuxGroup & group)
    4988             : {
    4989             :   TheWarehouse::Query query =
    4990    12434890 :       theWarehouse().query().condition<AttribSystem>("UserObject").condition<AttribExecOns>(type);
    4991    12434890 :   computeUserObjectsInternal(type, group, query);
    4992    12434773 : }
    4993             : 
    4994             : void
    4995    12492066 : FEProblemBase::computeUserObjectsInternal(const ExecFlagType & type,
    4996             :                                           const Moose::AuxGroup & group,
    4997             :                                           TheWarehouse::Query & primary_query)
    4998             : {
    4999             :   try
    5000             :   {
    5001    62460330 :     TIME_SECTION("computeUserObjects", 1, "Computing User Objects");
    5002             : 
    5003             :     // Add group to query
    5004    12492066 :     if (group == Moose::PRE_IC)
    5005       57609 :       primary_query.condition<AttribPreIC>(true);
    5006    12434457 :     else if (group == Moose::PRE_AUX)
    5007     6216993 :       primary_query.condition<AttribPreAux>(type);
    5008     6217464 :     else if (group == Moose::POST_AUX)
    5009     6217420 :       primary_query.condition<AttribPostAux>(type);
    5010             : 
    5011             :     // query everything first to obtain a list of execution groups
    5012    12492066 :     std::vector<UserObject *> uos;
    5013    12492066 :     primary_query.clone().queryIntoUnsorted(uos);
    5014    12492066 :     std::set<int> execution_groups;
    5015    13127431 :     for (const auto & uo : uos)
    5016     1906095 :       execution_groups.insert(uo->getParam<int>("execution_order_group"));
    5017             : 
    5018             :     // iterate over execution order groups
    5019    12800326 :     for (const auto execution_group : execution_groups)
    5020             :     {
    5021      308377 :       auto query = primary_query.clone().condition<AttribExecutionOrderGroup>(execution_group);
    5022             : 
    5023      308377 :       std::vector<GeneralUserObject *> genobjs;
    5024      308377 :       query.clone().condition<AttribInterfaces>(Interfaces::GeneralUserObject).queryInto(genobjs);
    5025             : 
    5026      308377 :       std::vector<UserObject *> userobjs;
    5027      308377 :       query.clone()
    5028      616754 :           .condition<AttribInterfaces>(Interfaces::ElementUserObject | Interfaces::SideUserObject |
    5029             :                                        Interfaces::InternalSideUserObject |
    5030      616754 :                                        Interfaces::InterfaceUserObject |
    5031             :                                        Interfaces::DomainUserObject)
    5032      308377 :           .queryInto(userobjs);
    5033             : 
    5034      308377 :       std::vector<UserObject *> tgobjs;
    5035      308377 :       query.clone()
    5036      616754 :           .condition<AttribInterfaces>(Interfaces::ThreadedGeneralUserObject)
    5037      308377 :           .queryInto(tgobjs);
    5038             : 
    5039      308377 :       std::vector<UserObject *> nodal;
    5040      308377 :       query.clone().condition<AttribInterfaces>(Interfaces::NodalUserObject).queryInto(nodal);
    5041             : 
    5042      308377 :       std::vector<MortarUserObject *> mortar;
    5043      308377 :       query.clone().condition<AttribInterfaces>(Interfaces::MortarUserObject).queryInto(mortar);
    5044             : 
    5045      308377 :       if (userobjs.empty() && genobjs.empty() && tgobjs.empty() && nodal.empty() && mortar.empty())
    5046           0 :         continue;
    5047             : 
    5048             :       // Start the timer here since we have at least one active user object
    5049      308377 :       std::string compute_uo_tag = "computeUserObjects(" + Moose::stringify(type) + ")";
    5050             : 
    5051             :       // Perform Residual/Jacobian setups
    5052      308377 :       if (type == EXEC_LINEAR)
    5053             :       {
    5054      132237 :         for (auto obj : userobjs)
    5055       74488 :           obj->residualSetup();
    5056       62541 :         for (auto obj : nodal)
    5057        4792 :           obj->residualSetup();
    5058       57749 :         for (auto obj : mortar)
    5059           0 :           obj->residualSetup();
    5060       57749 :         for (auto obj : tgobjs)
    5061           0 :           obj->residualSetup();
    5062       69324 :         for (auto obj : genobjs)
    5063       11575 :           obj->residualSetup();
    5064             :       }
    5065      250628 :       else if (type == EXEC_NONLINEAR)
    5066             :       {
    5067       11622 :         for (auto obj : userobjs)
    5068        2809 :           obj->jacobianSetup();
    5069        9237 :         for (auto obj : nodal)
    5070         424 :           obj->jacobianSetup();
    5071        8813 :         for (auto obj : mortar)
    5072           0 :           obj->jacobianSetup();
    5073        8813 :         for (auto obj : tgobjs)
    5074           0 :           obj->jacobianSetup();
    5075       24077 :         for (auto obj : genobjs)
    5076       15264 :           obj->jacobianSetup();
    5077             :       }
    5078             : 
    5079      677030 :       for (auto obj : userobjs)
    5080      368653 :         obj->initialize();
    5081             : 
    5082             :       // Execute Side/InternalSide/Interface/Elemental/DomainUserObjects
    5083      308377 :       if (!userobjs.empty())
    5084             :       {
    5085             :         // non-nodal user objects have to be run separately before the nodal user objects run
    5086             :         // because some nodal user objects (NodalNormal related) depend on elemental user objects
    5087             :         // :-(
    5088      219639 :         ComputeUserObjectsThread cppt(*this, query);
    5089      219639 :         Threads::parallel_reduce(*_mesh.getActiveLocalElementRange(), cppt);
    5090             : 
    5091             :         // There is one instance in rattlesnake where an elemental user object's finalize depends
    5092             :         // on a side user object having been finalized first :-(
    5093      219631 :         joinAndFinalize(query.clone().condition<AttribInterfaces>(Interfaces::SideUserObject));
    5094      219627 :         joinAndFinalize(
    5095      439254 :             query.clone().condition<AttribInterfaces>(Interfaces::InternalSideUserObject));
    5096      219627 :         joinAndFinalize(query.clone().condition<AttribInterfaces>(Interfaces::InterfaceUserObject));
    5097      219627 :         joinAndFinalize(query.clone().condition<AttribInterfaces>(Interfaces::ElementUserObject));
    5098      219623 :         joinAndFinalize(query.clone().condition<AttribInterfaces>(Interfaces::DomainUserObject));
    5099      219623 :       }
    5100             : 
    5101             :       // if any userobject may have written to variables we need to close the aux solution
    5102      676912 :       for (const auto & uo : userobjs)
    5103      368587 :         if (auto euo = dynamic_cast<const ElementUserObject *>(uo);
    5104      368587 :             euo && euo->hasWritableCoupledVariables())
    5105             :         {
    5106          36 :           _aux->solution().close();
    5107          36 :           _aux->system().update();
    5108          36 :           break;
    5109             :         }
    5110             : 
    5111             :       // Execute NodalUserObjects
    5112             :       // BISON has an axial reloc elemental user object that has a finalize func that depends on a
    5113             :       // nodal user object's prev value. So we can't initialize this until after elemental objects
    5114             :       // have been finalized :-(
    5115      330732 :       for (auto obj : nodal)
    5116       22371 :         obj->initialize();
    5117      308361 :       if (query.clone().condition<AttribInterfaces>(Interfaces::NodalUserObject).count() > 0)
    5118             :       {
    5119       17801 :         ComputeNodalUserObjectsThread cnppt(*this, query);
    5120       17801 :         Threads::parallel_reduce(*_mesh.getLocalNodeRange(), cnppt);
    5121       17801 :         joinAndFinalize(query.clone().condition<AttribInterfaces>(Interfaces::NodalUserObject));
    5122       17801 :       }
    5123             : 
    5124             :       // if any userobject may have written to variables we need to close the aux solution
    5125      330693 :       for (const auto & uo : nodal)
    5126       22356 :         if (auto nuo = dynamic_cast<const NodalUserObject *>(uo);
    5127       22356 :             nuo && nuo->hasWritableCoupledVariables())
    5128             :         {
    5129          24 :           _aux->solution().close();
    5130          24 :           _aux->system().update();
    5131          24 :           break;
    5132             :         }
    5133             : 
    5134             :       // Execute MortarUserObjects
    5135             :       {
    5136      308385 :         for (auto obj : mortar)
    5137          24 :           obj->initialize();
    5138      308361 :         if (!mortar.empty())
    5139             :         {
    5140          36 :           auto create_and_run_mortar_functors = [this, type, &mortar](const bool displaced)
    5141             :           {
    5142             :             // go over mortar interfaces and construct functors
    5143          36 :             const auto & mortar_interfaces = getMortarInterfaces(displaced);
    5144          60 :             for (const auto & mortar_interface : mortar_interfaces)
    5145             :             {
    5146          24 :               const auto primary_secondary_boundary_pair = mortar_interface.first;
    5147             :               auto mortar_uos_to_execute =
    5148          24 :                   getMortarUserObjects(primary_secondary_boundary_pair.first,
    5149          24 :                                        primary_secondary_boundary_pair.second,
    5150             :                                        displaced,
    5151          24 :                                        mortar);
    5152          24 :               const auto & mortar_generation_object = mortar_interface.second;
    5153             : 
    5154             :               auto * const subproblem = displaced
    5155          24 :                                             ? static_cast<SubProblem *>(_displaced_problem.get())
    5156          24 :                                             : static_cast<SubProblem *>(this);
    5157             :               MortarUserObjectThread muot(mortar_uos_to_execute,
    5158             :                                           mortar_generation_object,
    5159             :                                           *subproblem,
    5160             :                                           *this,
    5161             :                                           displaced,
    5162          24 :                                           subproblem->assembly(0, 0));
    5163             : 
    5164          24 :               muot();
    5165          24 :             }
    5166          60 :           };
    5167             : 
    5168          24 :           create_and_run_mortar_functors(false);
    5169          24 :           if (_displaced_problem)
    5170          12 :             create_and_run_mortar_functors(true);
    5171          24 :         }
    5172      308385 :         for (auto obj : mortar)
    5173          24 :           obj->finalize();
    5174             :       }
    5175             : 
    5176             :       // Execute threaded general user objects
    5177      308813 :       for (auto obj : tgobjs)
    5178         452 :         obj->initialize();
    5179      308361 :       std::vector<GeneralUserObject *> tguos_zero;
    5180      308361 :       query.clone()
    5181      308361 :           .condition<AttribThread>(0)
    5182      616722 :           .condition<AttribInterfaces>(Interfaces::ThreadedGeneralUserObject)
    5183      308361 :           .queryInto(tguos_zero);
    5184      308477 :       for (auto obj : tguos_zero)
    5185             :       {
    5186         116 :         std::vector<GeneralUserObject *> tguos;
    5187         116 :         auto q = query.clone()
    5188         116 :                      .condition<AttribName>(obj->name())
    5189         116 :                      .condition<AttribInterfaces>(Interfaces::ThreadedGeneralUserObject);
    5190         116 :         q.queryInto(tguos);
    5191             : 
    5192         116 :         ComputeThreadedGeneralUserObjectsThread ctguot(*this);
    5193         116 :         Threads::parallel_reduce(GeneralUserObjectRange(tguos.begin(), tguos.end()), ctguot);
    5194         116 :         joinAndFinalize(q);
    5195         116 :       }
    5196             : 
    5197             :       // Execute general user objects
    5198      308361 :       joinAndFinalize(query.clone().condition<AttribInterfaces>(Interfaces::GeneralUserObject),
    5199             :                       true);
    5200      308260 :     }
    5201    12491949 :   }
    5202           0 :   catch (...)
    5203             :   {
    5204           0 :     handleException("computeUserObjectsInternal");
    5205           0 :   }
    5206    12491949 : }
    5207             : 
    5208             : void
    5209     6192434 : FEProblemBase::executeControls(const ExecFlagType & exec_type)
    5210             : {
    5211     6192434 :   if (_control_warehouse[exec_type].hasActiveObjects())
    5212             :   {
    5213       40995 :     TIME_SECTION("executeControls", 1, "Executing Controls");
    5214             : 
    5215        8199 :     DependencyResolver<std::shared_ptr<Control>> resolver;
    5216             : 
    5217        8199 :     auto controls_wh = _control_warehouse[exec_type];
    5218             :     // Add all of the dependencies into the resolver and sort them
    5219       20252 :     for (const auto & it : controls_wh.getActiveObjects())
    5220             :     {
    5221             :       // Make sure an item with no dependencies comes out too!
    5222       12057 :       resolver.addItem(it);
    5223             : 
    5224       12057 :       std::vector<std::string> & dependent_controls = it->getDependencies();
    5225       14790 :       for (const auto & depend_name : dependent_controls)
    5226             :       {
    5227        2737 :         if (controls_wh.hasActiveObject(depend_name))
    5228             :         {
    5229        2733 :           auto dep_control = controls_wh.getActiveObject(depend_name);
    5230        2733 :           resolver.addEdge(dep_control, it);
    5231        2733 :         }
    5232             :         else
    5233           4 :           mooseError("The Control \"",
    5234             :                      depend_name,
    5235             :                      "\" was not created, did you make a "
    5236             :                      "spelling mistake or forget to include it "
    5237             :                      "in your input file?");
    5238             :       }
    5239             :     }
    5240             : 
    5241        8195 :     const auto & ordered_controls = resolver.getSortedValues();
    5242             : 
    5243        8195 :     if (!ordered_controls.empty())
    5244             :     {
    5245        8195 :       _control_warehouse.setup(exec_type);
    5246             :       // Run the controls in the proper order
    5247       20232 :       for (const auto & control : ordered_controls)
    5248       12053 :         control->execute();
    5249             :     }
    5250        8179 :   }
    5251     6192414 : }
    5252             : 
    5253             : void
    5254     2258940 : FEProblemBase::executeSamplers(const ExecFlagType & exec_type)
    5255             : {
    5256             :   // TODO: This should be done in a threaded loop, but this should be super quick so for now
    5257             :   // do a serial loop.
    5258     4719770 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); ++tid)
    5259             :   {
    5260     2460862 :     std::vector<Sampler *> objects;
    5261     2460862 :     theWarehouse()
    5262     4921724 :         .query()
    5263     2460862 :         .condition<AttribSystem>("Sampler")
    5264     2460862 :         .condition<AttribThread>(tid)
    5265     2460862 :         .condition<AttribExecOns>(exec_type)
    5266     2460862 :         .queryInto(objects);
    5267             : 
    5268     2460862 :     if (!objects.empty())
    5269             :     {
    5270         275 :       TIME_SECTION("executeSamplers", 1, "Executing Samplers");
    5271          55 :       FEProblemBase::objectSetupHelper<Sampler>(objects, exec_type);
    5272          55 :       FEProblemBase::objectExecuteHelper<Sampler>(objects);
    5273          23 :     }
    5274     2460830 :   }
    5275     2258908 : }
    5276             : 
    5277             : void
    5278      338001 : FEProblemBase::updateActiveObjects()
    5279             : {
    5280     1690005 :   TIME_SECTION("updateActiveObjects", 5, "Updating Active Objects");
    5281             : 
    5282      705817 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); ++tid)
    5283             :   {
    5284      738156 :     for (auto & nl : _nl)
    5285      370340 :       nl->updateActive(tid);
    5286      367816 :     _aux->updateActive(tid);
    5287      367816 :     _indicators.updateActive(tid);
    5288      367816 :     _internal_side_indicators.updateActive(tid);
    5289      367816 :     _markers.updateActive(tid);
    5290      367816 :     _all_materials.updateActive(tid);
    5291      367816 :     _materials.updateActive(tid);
    5292      367816 :     _discrete_materials.updateActive(tid);
    5293             :   }
    5294             : 
    5295      338001 :   _control_warehouse.updateActive();
    5296      338001 :   _multi_apps.updateActive();
    5297      338001 :   _transient_multi_apps.updateActive();
    5298      338001 :   _transfers.updateActive();
    5299      338001 :   _to_multi_app_transfers.updateActive();
    5300      338001 :   _from_multi_app_transfers.updateActive();
    5301      338001 :   _between_multi_app_transfers.updateActive();
    5302             : 
    5303             : #ifdef MOOSE_KOKKOS_ENABLED
    5304      222650 :   _kokkos_materials.updateActive();
    5305             : #endif
    5306      338001 : }
    5307             : 
    5308             : void
    5309           0 : FEProblemBase::reportMooseObjectDependency(MooseObject * /*a*/, MooseObject * /*b*/)
    5310             : {
    5311             :   //<< "Object " << a->name() << " -> " << b->name() << std::endl;
    5312           0 : }
    5313             : 
    5314             : void
    5315       70013 : FEProblemBase::reinitBecauseOfGhostingOrNewGeomObjects(const bool mortar_changed)
    5316             : {
    5317      350065 :   TIME_SECTION("reinitBecauseOfGhostingOrNewGeomObjects",
    5318             :                3,
    5319             :                "Reinitializing Because of Geometric Search Objects");
    5320             : 
    5321             :   // Need to see if _any_ processor has ghosted elems or geometry objects.
    5322       70013 :   bool needs_reinit = !_ghosted_elems.empty();
    5323      139616 :   needs_reinit = needs_reinit || !_geometric_search_data._nearest_node_locators.empty() ||
    5324       69603 :                  (_mortar_data.hasObjects() && mortar_changed);
    5325       70013 :   needs_reinit =
    5326      141569 :       needs_reinit || (_displaced_problem &&
    5327        5002 :                        (!_displaced_problem->geomSearchData()._nearest_node_locators.empty() ||
    5328       70919 :                         (_mortar_data.hasDisplacedObjects() && mortar_changed)));
    5329       70013 :   _communicator.max(needs_reinit);
    5330             : 
    5331       70013 :   if (needs_reinit)
    5332             :   {
    5333             :     // Call reinit to get the ghosted vectors correct now that some geometric search has been done
    5334        2354 :     es().reinit();
    5335             : 
    5336        2354 :     if (_displaced_mesh)
    5337        1748 :       _displaced_problem->es().reinit();
    5338             :   }
    5339       70013 : }
    5340             : 
    5341             : void
    5342         181 : FEProblemBase::addDamper(const std::string & damper_name,
    5343             :                          const std::string & name,
    5344             :                          InputParameters & parameters)
    5345             : {
    5346             :   parallel_object_only();
    5347             : 
    5348             :   const auto nl_sys_num =
    5349         181 :       parameters.isParamValid("variable")
    5350         582 :           ? determineSolverSystem(parameters.varName("variable", name), true).second
    5351         177 :           : (unsigned int)0;
    5352             : 
    5353         177 :   if (!isSolverSystemNonlinear(nl_sys_num))
    5354           0 :     mooseError("You are trying to add a DGKernel to a linear variable/system, which is not "
    5355             :                "supported at the moment!");
    5356             : 
    5357         354 :   parameters.set<SubProblem *>("_subproblem") = this;
    5358         354 :   parameters.set<SystemBase *>("_sys") = _nl[nl_sys_num].get();
    5359             : 
    5360         177 :   _has_dampers = true;
    5361         177 :   logAdd("Damper", name, damper_name, parameters);
    5362         177 :   _nl[nl_sys_num]->addDamper(damper_name, name, parameters);
    5363         177 : }
    5364             : 
    5365             : void
    5366         163 : FEProblemBase::setupDampers()
    5367             : {
    5368         326 :   for (auto & nl : _nl)
    5369         163 :     nl->setupDampers();
    5370         163 : }
    5371             : 
    5372             : void
    5373         697 : FEProblemBase::addIndicator(const std::string & indicator_name,
    5374             :                             const std::string & name,
    5375             :                             InputParameters & parameters)
    5376             : {
    5377             :   parallel_object_only();
    5378             : 
    5379         697 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    5380             :   {
    5381           0 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    5382           0 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->auxSys();
    5383           0 :     _reinit_displaced_elem = true;
    5384             :   }
    5385             :   else
    5386             :   {
    5387         697 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    5388             :     {
    5389             :       // We allow Indicators to request that they use_displaced_mesh,
    5390             :       // but then be overridden when no displacements variables are
    5391             :       // provided in the Mesh block.  If that happened, update the value
    5392             :       // of use_displaced_mesh appropriately for this Indicator.
    5393           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    5394           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    5395             :     }
    5396             : 
    5397        1394 :     parameters.set<SubProblem *>("_subproblem") = this;
    5398        2091 :     parameters.set<SystemBase *>("_sys") = _aux.get();
    5399             :   }
    5400             : 
    5401        1456 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    5402             :   {
    5403             :     std::shared_ptr<Indicator> indicator =
    5404         759 :         _factory.create<Indicator>(indicator_name, name, parameters, tid);
    5405         759 :     logAdd("Indicator", name, indicator_name, parameters);
    5406             :     std::shared_ptr<InternalSideIndicatorBase> isi =
    5407         759 :         std::dynamic_pointer_cast<InternalSideIndicatorBase>(indicator);
    5408         759 :     if (isi)
    5409         650 :       _internal_side_indicators.addObject(isi, tid);
    5410             :     else
    5411         109 :       _indicators.addObject(indicator, tid);
    5412         759 :   }
    5413         697 : }
    5414             : 
    5415             : void
    5416        2095 : FEProblemBase::addMarker(const std::string & marker_name,
    5417             :                          const std::string & name,
    5418             :                          InputParameters & parameters)
    5419             : {
    5420             :   parallel_object_only();
    5421             : 
    5422        2095 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    5423             :   {
    5424           0 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    5425           0 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->auxSys();
    5426           0 :     _reinit_displaced_elem = true;
    5427             :   }
    5428             :   else
    5429             :   {
    5430        2095 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    5431             :     {
    5432             :       // We allow Markers to request that they use_displaced_mesh,
    5433             :       // but then be overridden when no displacements variables are
    5434             :       // provided in the Mesh block.  If that happened, update the value
    5435             :       // of use_displaced_mesh appropriately for this Marker.
    5436           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    5437           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    5438             :     }
    5439             : 
    5440        4190 :     parameters.set<SubProblem *>("_subproblem") = this;
    5441        6285 :     parameters.set<SystemBase *>("_sys") = _aux.get();
    5442             :   }
    5443             : 
    5444        4360 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    5445             :   {
    5446        2269 :     std::shared_ptr<Marker> marker = _factory.create<Marker>(marker_name, name, parameters, tid);
    5447        2265 :     logAdd("Marker", name, marker_name, parameters);
    5448        2265 :     _markers.addObject(marker, tid);
    5449        2265 :   }
    5450        2091 : }
    5451             : 
    5452             : void
    5453        7672 : FEProblemBase::addMultiApp(const std::string & multi_app_name,
    5454             :                            const std::string & name,
    5455             :                            InputParameters & parameters)
    5456             : {
    5457             :   parallel_object_only();
    5458             : 
    5459       15344 :   parameters.set<MPI_Comm>("_mpi_comm") = _communicator.get();
    5460             : 
    5461        7672 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    5462             :   {
    5463           0 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    5464           0 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->auxSys();
    5465           0 :     _reinit_displaced_elem = true;
    5466             :   }
    5467             :   else
    5468             :   {
    5469        7672 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    5470             :     {
    5471             :       // We allow MultiApps to request that they use_displaced_mesh,
    5472             :       // but then be overridden when no displacements variables are
    5473             :       // provided in the Mesh block.  If that happened, update the value
    5474             :       // of use_displaced_mesh appropriately for this MultiApp.
    5475          49 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    5476          98 :         parameters.set<bool>("use_displaced_mesh") = false;
    5477             :     }
    5478             : 
    5479       15344 :     parameters.set<SubProblem *>("_subproblem") = this;
    5480       23016 :     parameters.set<SystemBase *>("_sys") = _aux.get();
    5481             :   }
    5482             : 
    5483        7672 :   std::shared_ptr<MultiApp> multi_app = _factory.create<MultiApp>(multi_app_name, name, parameters);
    5484        7656 :   logAdd("MultiApp", name, multi_app_name, parameters);
    5485        7656 :   multi_app->setupPositions();
    5486             : 
    5487        7541 :   _multi_apps.addObject(multi_app);
    5488             : 
    5489             :   // Store TransientMultiApp objects in another container, this is needed for calling computeDT
    5490             :   std::shared_ptr<TransientMultiApp> trans_multi_app =
    5491        7541 :       std::dynamic_pointer_cast<TransientMultiApp>(multi_app);
    5492        7541 :   if (trans_multi_app)
    5493        5401 :     _transient_multi_apps.addObject(trans_multi_app);
    5494        7541 : }
    5495             : 
    5496             : bool
    5497      120680 : FEProblemBase::hasMultiApps(ExecFlagType type) const
    5498             : {
    5499      120680 :   return _multi_apps[type].hasActiveObjects();
    5500             : }
    5501             : 
    5502             : bool
    5503           0 : FEProblemBase::hasMultiApp(const std::string & multi_app_name) const
    5504             : {
    5505           0 :   return _multi_apps.hasActiveObject(multi_app_name);
    5506             : }
    5507             : 
    5508             : std::shared_ptr<MultiApp>
    5509       24983 : FEProblemBase::getMultiApp(const std::string & multi_app_name) const
    5510             : {
    5511       24983 :   return _multi_apps.getObject(multi_app_name);
    5512             : }
    5513             : 
    5514             : void
    5515    15686753 : FEProblemBase::execMultiAppTransfers(ExecFlagType type, Transfer::DIRECTION direction)
    5516             : {
    5517    15686753 :   bool to_multiapp = direction == MultiAppTransfer::TO_MULTIAPP;
    5518    15686753 :   bool from_multiapp = direction == MultiAppTransfer::FROM_MULTIAPP;
    5519    15686753 :   std::string string_direction;
    5520    15686753 :   if (to_multiapp)
    5521     5228990 :     string_direction = " To ";
    5522    10457763 :   else if (from_multiapp)
    5523     5228821 :     string_direction = " From ";
    5524             :   else
    5525     5228942 :     string_direction = " Between ";
    5526             : 
    5527    15686970 :   const MooseObjectWarehouse<Transfer> & wh = to_multiapp     ? _to_multi_app_transfers[type]
    5528    26144395 :                                               : from_multiapp ? _from_multi_app_transfers[type]
    5529    36602375 :                                                               : _between_multi_app_transfers[type];
    5530             : 
    5531    15686753 :   if (wh.hasActiveObjects())
    5532             :   {
    5533      570085 :     TIME_SECTION("execMultiAppTransfers", 1, "Executing Transfers");
    5534             : 
    5535      114017 :     const auto & transfers = wh.getActiveObjects();
    5536             : 
    5537      114017 :     if (_verbose_multiapps)
    5538             :     {
    5539        2486 :       _console << COLOR_CYAN << "\nTransfers on " << Moose::stringify(type) << string_direction
    5540        2486 :                << "MultiApps" << COLOR_DEFAULT << ":" << std::endl;
    5541             : 
    5542             :       VariadicTable<std::string, std::string, std::string, std::string> table(
    5543        4972 :           {"Name", "Type", "From", "To"});
    5544             : 
    5545             :       // Build Table of Transfer Info
    5546        5932 :       for (const auto & transfer : transfers)
    5547             :       {
    5548        3446 :         auto multiapp_transfer = dynamic_cast<MultiAppTransfer *>(transfer.get());
    5549             : 
    5550        3446 :         table.addRow(multiapp_transfer->name(),
    5551        3446 :                      multiapp_transfer->type(),
    5552        6892 :                      multiapp_transfer->getFromName(),
    5553        6892 :                      multiapp_transfer->getToName());
    5554             :       }
    5555             : 
    5556             :       // Print it
    5557        2486 :       table.print(_console);
    5558        2486 :     }
    5559             : 
    5560      233099 :     for (const auto & transfer : transfers)
    5561             :     {
    5562      119205 :       transfer->setCurrentDirection(direction);
    5563      119205 :       transfer->execute();
    5564             :     }
    5565             : 
    5566      113894 :     MooseUtils::parallelBarrierNotify(_communicator, _parallel_barrier_messaging);
    5567             : 
    5568      113894 :     if (_verbose_multiapps)
    5569        4956 :       _console << COLOR_CYAN << "Transfers on " << Moose::stringify(type) << " Are Finished\n"
    5570        2478 :                << COLOR_DEFAULT << std::endl;
    5571      113894 :   }
    5572    15572736 :   else if (_multi_apps[type].getActiveObjects().size())
    5573             :   {
    5574      116089 :     if (_verbose_multiapps)
    5575        7988 :       _console << COLOR_CYAN << "\nNo Transfers on " << Moose::stringify(type) << string_direction
    5576        3994 :                << "MultiApps\n"
    5577        3994 :                << COLOR_DEFAULT << std::endl;
    5578             :   }
    5579    15686630 : }
    5580             : 
    5581             : std::vector<std::shared_ptr<Transfer>>
    5582          13 : FEProblemBase::getTransfers(ExecFlagType type, Transfer::DIRECTION direction) const
    5583             : {
    5584          13 :   if (direction == MultiAppTransfer::TO_MULTIAPP)
    5585          13 :     return _to_multi_app_transfers[type].getActiveObjects();
    5586           0 :   else if (direction == MultiAppTransfer::FROM_MULTIAPP)
    5587           0 :     return _from_multi_app_transfers[type].getActiveObjects();
    5588             :   else
    5589           0 :     return _between_multi_app_transfers[type].getActiveObjects();
    5590             : }
    5591             : 
    5592             : std::vector<std::shared_ptr<Transfer>>
    5593           0 : FEProblemBase::getTransfers(Transfer::DIRECTION direction) const
    5594             : {
    5595           0 :   if (direction == MultiAppTransfer::TO_MULTIAPP)
    5596           0 :     return _to_multi_app_transfers.getActiveObjects();
    5597           0 :   else if (direction == MultiAppTransfer::FROM_MULTIAPP)
    5598           0 :     return _from_multi_app_transfers.getActiveObjects();
    5599             :   else
    5600           0 :     return _between_multi_app_transfers.getActiveObjects();
    5601             : }
    5602             : 
    5603             : const ExecuteMooseObjectWarehouse<Transfer> &
    5604           0 : FEProblemBase::getMultiAppTransferWarehouse(Transfer::DIRECTION direction) const
    5605             : {
    5606           0 :   if (direction == MultiAppTransfer::TO_MULTIAPP)
    5607           0 :     return _to_multi_app_transfers;
    5608           0 :   else if (direction == MultiAppTransfer::FROM_MULTIAPP)
    5609           0 :     return _from_multi_app_transfers;
    5610             :   else
    5611           0 :     return _between_multi_app_transfers;
    5612             : }
    5613             : 
    5614             : bool
    5615     5228994 : FEProblemBase::execMultiApps(ExecFlagType type, bool auto_advance)
    5616             : {
    5617             :   // Active MultiApps
    5618             :   const std::vector<MooseSharedPointer<MultiApp>> & multi_apps =
    5619     5228994 :       _multi_apps[type].getActiveObjects();
    5620             : 
    5621             :   // Do anything that needs to be done to Apps before transfers
    5622     5296940 :   for (const auto & multi_app : multi_apps)
    5623       67950 :     multi_app->preTransfer(_dt, _time);
    5624             : 
    5625             :   // Execute Transfers _to_ MultiApps
    5626     5228990 :   execMultiAppTransfers(type, MultiAppTransfer::TO_MULTIAPP);
    5627             : 
    5628             :   // Execute Transfers _between_ Multiapps
    5629     5228942 :   execMultiAppTransfers(type, MultiAppTransfer::BETWEEN_MULTIAPP);
    5630             : 
    5631             :   // Execute MultiApps
    5632     5228942 :   if (multi_apps.size())
    5633             :   {
    5634      333535 :     TIME_SECTION("execMultiApps", 1, "Executing MultiApps", false);
    5635             : 
    5636       66707 :     if (_verbose_multiapps)
    5637        4192 :       _console << COLOR_CYAN << "\nExecuting MultiApps on " << Moose::stringify(type)
    5638        2096 :                << COLOR_DEFAULT << std::endl;
    5639             : 
    5640       66707 :     bool success = true;
    5641             : 
    5642      134481 :     for (const auto & multi_app : multi_apps)
    5643             :     {
    5644       67887 :       success = multi_app->solveStep(_dt, _time, auto_advance);
    5645             :       // no need to finish executing the subapps if one fails
    5646       67875 :       if (!success)
    5647         101 :         break;
    5648             :     }
    5649             : 
    5650       66695 :     MooseUtils::parallelBarrierNotify(_communicator, _parallel_barrier_messaging);
    5651             : 
    5652       66695 :     _communicator.min(success);
    5653             : 
    5654       66695 :     if (!success)
    5655         109 :       return false;
    5656             : 
    5657       66586 :     if (_verbose_multiapps)
    5658        4192 :       _console << COLOR_CYAN << "Finished Executing MultiApps on " << Moose::stringify(type) << "\n"
    5659        2096 :                << COLOR_DEFAULT << std::endl;
    5660       66695 :   }
    5661             : 
    5662             :   // Execute Transfers _from_ MultiApps
    5663     5228821 :   execMultiAppTransfers(type, MultiAppTransfer::FROM_MULTIAPP);
    5664             : 
    5665             :   // If we made it here then everything passed
    5666     5228746 :   return true;
    5667             : }
    5668             : 
    5669             : void
    5670       49992 : FEProblemBase::finalizeMultiApps()
    5671             : {
    5672       49992 :   const auto & multi_apps = _multi_apps.getActiveObjects();
    5673             : 
    5674       56351 :   for (const auto & multi_app : multi_apps)
    5675        6359 :     multi_app->finalize();
    5676       49992 : }
    5677             : 
    5678             : void
    5679       51579 : FEProblemBase::postExecute()
    5680             : {
    5681       51579 :   const auto & multi_apps = _multi_apps.getActiveObjects();
    5682             : 
    5683       58295 :   for (const auto & multi_app : multi_apps)
    5684        6716 :     multi_app->postExecute();
    5685       51579 : }
    5686             : 
    5687             : void
    5688      724164 : FEProblemBase::incrementMultiAppTStep(ExecFlagType type)
    5689             : {
    5690      724164 :   const auto & multi_apps = _multi_apps[type].getActiveObjects();
    5691             : 
    5692      724164 :   if (multi_apps.size())
    5693       28639 :     for (const auto & multi_app : multi_apps)
    5694       14497 :       multi_app->incrementTStep(_time);
    5695      724164 : }
    5696             : 
    5697             : void
    5698       39872 : FEProblemBase::finishMultiAppStep(ExecFlagType type, bool recurse_through_multiapp_levels)
    5699             : {
    5700       39872 :   const auto & multi_apps = _multi_apps[type].getActiveObjects();
    5701             : 
    5702       39872 :   if (multi_apps.size())
    5703             :   {
    5704        9407 :     if (_verbose_multiapps)
    5705         416 :       _console << COLOR_CYAN << "\nAdvancing MultiApps on " << type.name() << COLOR_DEFAULT
    5706         416 :                << std::endl;
    5707             : 
    5708       18828 :     for (const auto & multi_app : multi_apps)
    5709        9421 :       multi_app->finishStep(recurse_through_multiapp_levels);
    5710             : 
    5711        9407 :     MooseUtils::parallelBarrierNotify(_communicator, _parallel_barrier_messaging);
    5712             : 
    5713        9407 :     if (_verbose_multiapps)
    5714         416 :       _console << COLOR_CYAN << "Finished Advancing MultiApps on " << type.name() << "\n"
    5715         416 :                << COLOR_DEFAULT << std::endl;
    5716             :   }
    5717       39872 : }
    5718             : 
    5719             : void
    5720     1213055 : FEProblemBase::backupMultiApps(ExecFlagType type)
    5721             : {
    5722     1213055 :   const auto & multi_apps = _multi_apps[type].getActiveObjects();
    5723             : 
    5724     1213055 :   if (multi_apps.size())
    5725             :   {
    5726      106985 :     TIME_SECTION("backupMultiApps", 5, "Backing Up MultiApp");
    5727             : 
    5728       21397 :     if (_verbose_multiapps)
    5729        1007 :       _console << COLOR_CYAN << "\nBacking Up MultiApps on " << type.name() << COLOR_DEFAULT
    5730        1007 :                << std::endl;
    5731             : 
    5732       43915 :     for (const auto & multi_app : multi_apps)
    5733       22518 :       multi_app->backup();
    5734             : 
    5735       21397 :     MooseUtils::parallelBarrierNotify(_communicator, _parallel_barrier_messaging);
    5736             : 
    5737       21397 :     if (_verbose_multiapps)
    5738        1007 :       _console << COLOR_CYAN << "Finished Backing Up MultiApps on " << type.name() << "\n"
    5739        1007 :                << COLOR_DEFAULT << std::endl;
    5740       21397 :   }
    5741     1213055 : }
    5742             : 
    5743             : void
    5744      118888 : FEProblemBase::restoreMultiApps(ExecFlagType type, bool force)
    5745             : {
    5746      118888 :   const auto & multi_apps = _multi_apps[type].getActiveObjects();
    5747             : 
    5748      118888 :   if (multi_apps.size())
    5749             :   {
    5750       45872 :     if (_verbose_multiapps)
    5751             :     {
    5752        1092 :       if (force)
    5753           3 :         _console << COLOR_CYAN << "\nRestoring Multiapps on " << type.name()
    5754           3 :                  << " because of solve failure!" << COLOR_DEFAULT << std::endl;
    5755             :       else
    5756        1089 :         _console << COLOR_CYAN << "\nRestoring MultiApps on " << type.name() << COLOR_DEFAULT
    5757        1089 :                  << std::endl;
    5758             :     }
    5759             : 
    5760       91829 :     for (const auto & multi_app : multi_apps)
    5761       45961 :       multi_app->restore(force);
    5762             : 
    5763       45868 :     MooseUtils::parallelBarrierNotify(_communicator, _parallel_barrier_messaging);
    5764             : 
    5765       45868 :     if (_verbose_multiapps)
    5766        1092 :       _console << COLOR_CYAN << "Finished Restoring MultiApps on " << type.name() << "\n"
    5767        1092 :                << COLOR_DEFAULT << std::endl;
    5768             :   }
    5769      118884 : }
    5770             : 
    5771             : Real
    5772      752208 : FEProblemBase::computeMultiAppsDT(ExecFlagType type)
    5773             : {
    5774      752208 :   const auto & multi_apps = _transient_multi_apps[type].getActiveObjects();
    5775             : 
    5776      752208 :   Real smallest_dt = std::numeric_limits<Real>::max();
    5777             : 
    5778      770734 :   for (const auto & multi_app : multi_apps)
    5779       18526 :     smallest_dt = std::min(smallest_dt, multi_app->computeDT());
    5780             : 
    5781      752208 :   return smallest_dt;
    5782             : }
    5783             : 
    5784             : void
    5785     5173951 : FEProblemBase::execTransfers(ExecFlagType type)
    5786             : {
    5787     5173951 :   if (_transfers[type].hasActiveObjects())
    5788             :   {
    5789           0 :     TIME_SECTION("execTransfers", 3, "Executing Transfers");
    5790             : 
    5791           0 :     const auto & transfers = _transfers[type].getActiveObjects();
    5792             : 
    5793           0 :     for (const auto & transfer : transfers)
    5794           0 :       transfer->execute();
    5795           0 :   }
    5796     5173951 : }
    5797             : 
    5798             : void
    5799       12603 : FEProblemBase::addTransfer(const std::string & transfer_name,
    5800             :                            const std::string & name,
    5801             :                            InputParameters & parameters)
    5802             : {
    5803             :   parallel_object_only();
    5804             : 
    5805       12603 :   if (_displaced_problem && parameters.get<bool>("use_displaced_mesh"))
    5806             :   {
    5807           0 :     parameters.set<SubProblem *>("_subproblem") = _displaced_problem.get();
    5808           0 :     parameters.set<SystemBase *>("_sys") = &_displaced_problem->auxSys();
    5809           0 :     _reinit_displaced_elem = true;
    5810             :   }
    5811             :   else
    5812             :   {
    5813       12603 :     if (_displaced_problem == nullptr && parameters.get<bool>("use_displaced_mesh"))
    5814             :     {
    5815             :       // We allow Transfers to request that they use_displaced_mesh,
    5816             :       // but then be overridden when no displacements variables are
    5817             :       // provided in the Mesh block.  If that happened, update the value
    5818             :       // of use_displaced_mesh appropriately for this Transfer.
    5819           0 :       if (parameters.have_parameter<bool>("use_displaced_mesh"))
    5820           0 :         parameters.set<bool>("use_displaced_mesh") = false;
    5821             :     }
    5822             : 
    5823       25206 :     parameters.set<SubProblem *>("_subproblem") = this;
    5824       37809 :     parameters.set<SystemBase *>("_sys") = _aux.get();
    5825             :   }
    5826             : 
    5827             :   // Handle the "SAME_AS_MULTIAPP" execute option. The get method is used to test for the
    5828             :   // flag so the set by user flag is not reset, calling set with the true flag causes the set
    5829             :   // by user status to be reset, which should only be done if the EXEC_SAME_AS_MULTIAPP is
    5830             :   // being applied to the object.
    5831       12603 :   if (parameters.get<ExecFlagEnum>("execute_on").isValueSet(EXEC_SAME_AS_MULTIAPP))
    5832             :   {
    5833       10280 :     ExecFlagEnum & exec_enum = parameters.set<ExecFlagEnum>("execute_on", true);
    5834       10280 :     std::shared_ptr<MultiApp> multiapp;
    5835       20560 :     if (parameters.isParamValid("multi_app"))
    5836          56 :       multiapp = getMultiApp(parameters.get<MultiAppName>("multi_app"));
    5837             :     // This catches the sibling transfer case, where we want to be executing only as often as the
    5838             :     // receiving application. A transfer 'to' a multiapp is executed before that multiapp
    5839       20448 :     else if (parameters.isParamValid("to_multi_app"))
    5840        5465 :       multiapp = getMultiApp(parameters.get<MultiAppName>("to_multi_app"));
    5841        9518 :     else if (parameters.isParamValid("from_multi_app"))
    5842        4751 :       multiapp = getMultiApp(parameters.get<MultiAppName>("from_multi_app"));
    5843             :     // else do nothing because the user has provided invalid input. They should get a nice error
    5844             :     // about this during transfer construction. This necessitates checking for null in this next
    5845             :     // line, however
    5846       10280 :     if (multiapp)
    5847       30816 :       exec_enum = multiapp->getParam<ExecFlagEnum>("execute_on");
    5848       10280 :   }
    5849             : 
    5850             :   // Create the Transfer objects
    5851       12603 :   std::shared_ptr<Transfer> transfer = _factory.create<Transfer>(transfer_name, name, parameters);
    5852       12527 :   logAdd("Transfer", name, transfer_name, parameters);
    5853             : 
    5854             :   // Add MultiAppTransfer object
    5855             :   std::shared_ptr<MultiAppTransfer> multi_app_transfer =
    5856       12527 :       std::dynamic_pointer_cast<MultiAppTransfer>(transfer);
    5857       12527 :   if (multi_app_transfer)
    5858             :   {
    5859       12527 :     if (multi_app_transfer->directions().isValueSet(MultiAppTransfer::TO_MULTIAPP))
    5860        5352 :       _to_multi_app_transfers.addObject(multi_app_transfer);
    5861       12527 :     if (multi_app_transfer->directions().isValueSet(MultiAppTransfer::FROM_MULTIAPP))
    5862        5979 :       _from_multi_app_transfers.addObject(multi_app_transfer);
    5863       12527 :     if (multi_app_transfer->directions().isValueSet(MultiAppTransfer::BETWEEN_MULTIAPP))
    5864        1196 :       _between_multi_app_transfers.addObject(multi_app_transfer);
    5865             :   }
    5866             :   else
    5867           0 :     _transfers.addObject(transfer);
    5868       12527 : }
    5869             : 
    5870             : bool
    5871     1506861 : FEProblemBase::hasVariable(const std::string & var_name) const
    5872             : {
    5873     2442167 :   for (auto & sys : _solver_systems)
    5874     1512772 :     if (sys->hasVariable(var_name))
    5875      577466 :       return true;
    5876      929395 :   if (_aux->hasVariable(var_name))
    5877      856932 :     return true;
    5878             : 
    5879       72463 :   return false;
    5880             : }
    5881             : 
    5882             : bool
    5883           0 : FEProblemBase::hasSolverVariable(const std::string & var_name) const
    5884             : {
    5885           0 :   for (auto & sys : _solver_systems)
    5886           0 :     if (sys->hasVariable(var_name))
    5887           0 :       return true;
    5888             : 
    5889           0 :   return false;
    5890             : }
    5891             : 
    5892             : const MooseVariableFieldBase &
    5893     4764542 : FEProblemBase::getVariable(const THREAD_ID tid,
    5894             :                            const std::string & var_name,
    5895             :                            Moose::VarKindType expected_var_type,
    5896             :                            Moose::VarFieldType expected_var_field_type) const
    5897             : {
    5898    14293618 :   return getVariableHelper(
    5899     4764542 :       tid, var_name, expected_var_type, expected_var_field_type, _solver_systems, *_aux);
    5900             : }
    5901             : 
    5902             : MooseVariable &
    5903        8001 : FEProblemBase::getStandardVariable(const THREAD_ID tid, const std::string & var_name)
    5904             : {
    5905       12111 :   for (auto & sys : _solver_systems)
    5906        8001 :     if (sys->hasVariable(var_name))
    5907        3891 :       return sys->getFieldVariable<Real>(tid, var_name);
    5908        4110 :   if (_aux->hasVariable(var_name))
    5909        4106 :     return _aux->getFieldVariable<Real>(tid, var_name);
    5910             : 
    5911           4 :   mooseError("Unknown variable " + var_name);
    5912             : }
    5913             : 
    5914             : MooseVariableFieldBase &
    5915         661 : FEProblemBase::getActualFieldVariable(const THREAD_ID tid, const std::string & var_name)
    5916             : {
    5917         877 :   for (auto & sys : _solver_systems)
    5918         661 :     if (sys->hasVariable(var_name))
    5919         445 :       return sys->getActualFieldVariable<Real>(tid, var_name);
    5920         216 :   if (_aux->hasVariable(var_name))
    5921         216 :     return _aux->getActualFieldVariable<Real>(tid, var_name);
    5922             : 
    5923           0 :   mooseError("Unknown variable " + var_name);
    5924             : }
    5925             : 
    5926             : VectorMooseVariable &
    5927           0 : FEProblemBase::getVectorVariable(const THREAD_ID tid, const std::string & var_name)
    5928             : {
    5929           0 :   for (auto & sys : _solver_systems)
    5930           0 :     if (sys->hasVariable(var_name))
    5931           0 :       return sys->getFieldVariable<RealVectorValue>(tid, var_name);
    5932           0 :   if (_aux->hasVariable(var_name))
    5933           0 :     return _aux->getFieldVariable<RealVectorValue>(tid, var_name);
    5934             : 
    5935           0 :   mooseError("Unknown variable " + var_name);
    5936             : }
    5937             : 
    5938             : ArrayMooseVariable &
    5939         378 : FEProblemBase::getArrayVariable(const THREAD_ID tid, const std::string & var_name)
    5940             : {
    5941         657 :   for (auto & sys : _solver_systems)
    5942         378 :     if (sys->hasVariable(var_name))
    5943          99 :       return sys->getFieldVariable<RealEigenVector>(tid, var_name);
    5944         279 :   if (_aux->hasVariable(var_name))
    5945         279 :     return _aux->getFieldVariable<RealEigenVector>(tid, var_name);
    5946             : 
    5947           0 :   mooseError("Unknown variable " + var_name);
    5948             : }
    5949             : 
    5950             : bool
    5951      189394 : FEProblemBase::hasScalarVariable(const std::string & var_name) const
    5952             : {
    5953      353381 :   for (auto & sys : _solver_systems)
    5954      190017 :     if (sys->hasScalarVariable(var_name))
    5955       26030 :       return true;
    5956      163364 :   if (_aux->hasScalarVariable(var_name))
    5957       12603 :     return true;
    5958             : 
    5959      150761 :   return false;
    5960             : }
    5961             : 
    5962             : MooseVariableScalar &
    5963       56126 : FEProblemBase::getScalarVariable(const THREAD_ID tid, const std::string & var_name)
    5964             : {
    5965       71989 :   for (auto & sys : _solver_systems)
    5966       56126 :     if (sys->hasScalarVariable(var_name))
    5967       40263 :       return sys->getScalarVariable(tid, var_name);
    5968       15863 :   if (_aux->hasScalarVariable(var_name))
    5969       15863 :     return _aux->getScalarVariable(tid, var_name);
    5970             : 
    5971           0 :   mooseError("Unknown variable " + var_name);
    5972             : }
    5973             : 
    5974             : System &
    5975       66252 : FEProblemBase::getSystem(const std::string & var_name)
    5976             : {
    5977       66252 :   const auto [var_in_sys, sys_num] = determineSolverSystem(var_name);
    5978       66252 :   if (var_in_sys)
    5979       47548 :     return _solver_systems[sys_num]->system();
    5980       18704 :   else if (_aux->hasVariable(var_name) || _aux->hasScalarVariable(var_name))
    5981       18704 :     return _aux->system();
    5982             :   else
    5983           0 :     mooseError("Unable to find a system containing the variable " + var_name);
    5984             : }
    5985             : 
    5986             : const RestartableEquationSystems &
    5987           0 : FEProblemBase::getRestartableEquationSystems() const
    5988             : {
    5989           0 :   return _req.get();
    5990             : }
    5991             : 
    5992             : void
    5993      541510 : FEProblemBase::setActiveFEVariableCoupleableMatrixTags(std::set<TagID> & mtags, const THREAD_ID tid)
    5994             : {
    5995      541510 :   SubProblem::setActiveFEVariableCoupleableMatrixTags(mtags, tid);
    5996             : 
    5997      541510 :   if (_displaced_problem)
    5998      114396 :     _displaced_problem->setActiveFEVariableCoupleableMatrixTags(mtags, tid);
    5999      541510 : }
    6000             : 
    6001             : void
    6002     7262060 : FEProblemBase::setActiveFEVariableCoupleableVectorTags(std::set<TagID> & vtags, const THREAD_ID tid)
    6003             : {
    6004     7262060 :   SubProblem::setActiveFEVariableCoupleableVectorTags(vtags, tid);
    6005             : 
    6006     7262060 :   if (_displaced_problem)
    6007      400132 :     _displaced_problem->setActiveFEVariableCoupleableVectorTags(vtags, tid);
    6008     7262060 : }
    6009             : 
    6010             : void
    6011       56031 : FEProblemBase::setActiveScalarVariableCoupleableMatrixTags(std::set<TagID> & mtags,
    6012             :                                                            const THREAD_ID tid)
    6013             : {
    6014       56031 :   SubProblem::setActiveScalarVariableCoupleableMatrixTags(mtags, tid);
    6015             : 
    6016       56031 :   if (_displaced_problem)
    6017           0 :     _displaced_problem->setActiveScalarVariableCoupleableMatrixTags(mtags, tid);
    6018       56031 : }
    6019             : 
    6020             : void
    6021       56031 : FEProblemBase::setActiveScalarVariableCoupleableVectorTags(std::set<TagID> & vtags,
    6022             :                                                            const THREAD_ID tid)
    6023             : {
    6024       56031 :   SubProblem::setActiveScalarVariableCoupleableVectorTags(vtags, tid);
    6025             : 
    6026       56031 :   if (_displaced_problem)
    6027           0 :     _displaced_problem->setActiveScalarVariableCoupleableVectorTags(vtags, tid);
    6028       56031 : }
    6029             : 
    6030             : void
    6031    11282214 : FEProblemBase::setActiveElementalMooseVariables(const std::set<MooseVariableFEBase *> & moose_vars,
    6032             :                                                 const THREAD_ID tid)
    6033             : {
    6034    11282214 :   SubProblem::setActiveElementalMooseVariables(moose_vars, tid);
    6035             : 
    6036    11282214 :   if (_displaced_problem)
    6037      567951 :     _displaced_problem->setActiveElementalMooseVariables(moose_vars, tid);
    6038    11282214 : }
    6039             : 
    6040             : void
    6041     4691863 : FEProblemBase::clearActiveElementalMooseVariables(const THREAD_ID tid)
    6042             : {
    6043     4691863 :   SubProblem::clearActiveElementalMooseVariables(tid);
    6044             : 
    6045     4691863 :   if (_displaced_problem)
    6046      204061 :     _displaced_problem->clearActiveElementalMooseVariables(tid);
    6047     4691863 : }
    6048             : 
    6049             : void
    6050      248925 : FEProblemBase::clearActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid)
    6051             : {
    6052      248925 :   SubProblem::clearActiveFEVariableCoupleableMatrixTags(tid);
    6053             : 
    6054      248925 :   if (_displaced_problem)
    6055       50039 :     _displaced_problem->clearActiveFEVariableCoupleableMatrixTags(tid);
    6056      248925 : }
    6057             : 
    6058             : void
    6059      248925 : FEProblemBase::clearActiveFEVariableCoupleableVectorTags(const THREAD_ID tid)
    6060             : {
    6061      248925 :   SubProblem::clearActiveFEVariableCoupleableVectorTags(tid);
    6062             : 
    6063      248925 :   if (_displaced_problem)
    6064       50039 :     _displaced_problem->clearActiveFEVariableCoupleableVectorTags(tid);
    6065      248925 : }
    6066             : 
    6067             : void
    6068       56031 : FEProblemBase::clearActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid)
    6069             : {
    6070       56031 :   SubProblem::clearActiveScalarVariableCoupleableMatrixTags(tid);
    6071             : 
    6072       56031 :   if (_displaced_problem)
    6073           0 :     _displaced_problem->clearActiveScalarVariableCoupleableMatrixTags(tid);
    6074       56031 : }
    6075             : 
    6076             : void
    6077       56031 : FEProblemBase::clearActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid)
    6078             : {
    6079       56031 :   SubProblem::clearActiveScalarVariableCoupleableVectorTags(tid);
    6080             : 
    6081       56031 :   if (_displaced_problem)
    6082           0 :     _displaced_problem->clearActiveScalarVariableCoupleableVectorTags(tid);
    6083       56031 : }
    6084             : 
    6085             : void
    6086     5807788 : FEProblemBase::setActiveMaterialProperties(const std::unordered_set<unsigned int> & mat_prop_ids,
    6087             :                                            const THREAD_ID tid)
    6088             : {
    6089             :   // mark active properties in every material
    6090     7041220 :   for (auto & mat : _all_materials.getObjects(tid))
    6091     1233432 :     mat->setActiveProperties(mat_prop_ids);
    6092     6784644 :   for (auto & mat : _all_materials[Moose::FACE_MATERIAL_DATA].getObjects(tid))
    6093      976856 :     mat->setActiveProperties(mat_prop_ids);
    6094     6784644 :   for (auto & mat : _all_materials[Moose::NEIGHBOR_MATERIAL_DATA].getObjects(tid))
    6095      976856 :     mat->setActiveProperties(mat_prop_ids);
    6096             : 
    6097     5807788 :   _has_active_material_properties[tid] = !mat_prop_ids.empty();
    6098     5807788 : }
    6099             : 
    6100             : bool
    6101   442870451 : FEProblemBase::hasActiveMaterialProperties(const THREAD_ID tid) const
    6102             : {
    6103   442870451 :   return _has_active_material_properties[tid];
    6104             : }
    6105             : 
    6106             : void
    6107     4799449 : FEProblemBase::clearActiveMaterialProperties(const THREAD_ID tid)
    6108             : {
    6109     4799449 :   _has_active_material_properties[tid] = 0;
    6110     4799449 : }
    6111             : 
    6112             : void
    6113       61886 : FEProblemBase::addAnyRedistributers()
    6114             : {
    6115             : #ifdef LIBMESH_ENABLE_AMR
    6116       64306 :   if ((_adaptivity.isOn() || _num_grid_steps) &&
    6117        2420 :       (_material_props.hasStatefulProperties() || _bnd_material_props.hasStatefulProperties() ||
    6118        2349 :        _neighbor_material_props.hasStatefulProperties()))
    6119             :   {
    6120             :     // Even on a serialized Mesh, we don't keep our material
    6121             :     // properties serialized, so we'll rely on the callback to
    6122             :     // redistribute() to redistribute properties at the same time
    6123             :     // libMesh is redistributing elements.
    6124          71 :     auto add_redistributer = [this](MooseMesh & mesh,
    6125             :                                     const std::string & redistributer_name,
    6126             :                                     const bool use_displaced_mesh)
    6127             :     {
    6128          71 :       InputParameters redistribute_params = RedistributeProperties::validParams();
    6129          71 :       redistribute_params.set<MooseApp *>(MooseBase::app_param) = &_app;
    6130         142 :       redistribute_params.set<std::string>("for_whom") = this->name();
    6131         213 :       redistribute_params.set<MooseMesh *>("mesh") = &mesh;
    6132          71 :       redistribute_params.set<Moose::RelationshipManagerType>("rm_type") =
    6133             :           Moose::RelationshipManagerType::GEOMETRIC;
    6134         142 :       redistribute_params.set<bool>("use_displaced_mesh") = use_displaced_mesh;
    6135          71 :       redistribute_params.setHitNode(*parameters().getHitNode(), {});
    6136             : 
    6137             :       std::shared_ptr<RedistributeProperties> redistributer =
    6138          71 :           _factory.create<RedistributeProperties>(
    6139         142 :               "RedistributeProperties", redistributer_name, redistribute_params);
    6140             : 
    6141          71 :       if (_material_props.hasStatefulProperties())
    6142          71 :         redistributer->addMaterialPropertyStorage(_material_props);
    6143             : 
    6144          71 :       if (_bnd_material_props.hasStatefulProperties())
    6145          71 :         redistributer->addMaterialPropertyStorage(_bnd_material_props);
    6146             : 
    6147          71 :       if (_neighbor_material_props.hasStatefulProperties())
    6148          71 :         redistributer->addMaterialPropertyStorage(_neighbor_material_props);
    6149             : 
    6150          71 :       mesh.getMesh().add_ghosting_functor(redistributer);
    6151         142 :     };
    6152             : 
    6153          71 :     add_redistributer(_mesh, "mesh_property_redistributer", false);
    6154          71 :     if (_displaced_problem)
    6155           0 :       add_redistributer(_displaced_problem->mesh(), "displaced_mesh_property_redistributer", true);
    6156             :   }
    6157             : #endif // LIBMESH_ENABLE_AMR
    6158       61886 : }
    6159             : 
    6160             : void
    6161       64129 : FEProblemBase::updateMaxQps()
    6162             : {
    6163             :   // Find the maximum number of quadrature points
    6164             :   {
    6165       64129 :     MaxQpsThread mqt(*this);
    6166       64129 :     Threads::parallel_reduce(*_mesh.getActiveLocalElementRange(), mqt);
    6167       64129 :     _max_qps = mqt.max();
    6168             : 
    6169             :     // If we have more shape functions or more quadrature points on
    6170             :     // another processor, then we may need to handle those elements
    6171             :     // ourselves later after repartitioning.
    6172       64129 :     _communicator.max(_max_qps);
    6173             :   }
    6174             : 
    6175       64129 :   unsigned int max_qpts = getMaxQps();
    6176       64129 :   if (max_qpts > Moose::constMaxQpsPerElem)
    6177           0 :     mooseError("Max quadrature points per element assumptions made in some code (e.g.  Coupleable ",
    6178             :                "and MaterialPropertyInterface classes) have been violated.\n",
    6179             :                "Complain to Moose developers to have constMaxQpsPerElem increased from ",
    6180             :                Moose::constMaxQpsPerElem,
    6181             :                " to ",
    6182             :                max_qpts);
    6183      134527 :   for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
    6184             :   {
    6185             :     // the highest available order in libMesh is 43
    6186       70398 :     _scalar_zero[tid].resize(FORTYTHIRD, 0);
    6187       70398 :     _zero[tid].resize(max_qpts, 0);
    6188       70398 :     _ad_zero[tid].resize(max_qpts, 0);
    6189       70398 :     _grad_zero[tid].resize(max_qpts, RealGradient(0.));
    6190       70398 :     _ad_grad_zero[tid].resize(max_qpts, ADRealGradient(0));
    6191       70398 :     _second_zero[tid].resize(max_qpts, RealTensor(0.));
    6192       70398 :     _ad_second_zero[tid].resize(max_qpts, ADRealTensorValue(0));
    6193       70398 :     _vector_zero[tid].resize(max_qpts, RealGradient(0.));
    6194       70398 :     _vector_curl_zero[tid].resize(max_qpts, RealGradient(0.));
    6195             :   }
    6196       64129 : }
    6197             : 
    6198             : void
    6199          84 : FEProblemBase::bumpVolumeQRuleOrder(Order order, SubdomainID block)
    6200             : {
    6201         180 :   for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
    6202         192 :     for (const auto i : index_range(_nl))
    6203          96 :       _assembly[tid][i]->bumpVolumeQRuleOrder(order, block);
    6204             : 
    6205          84 :   if (_displaced_problem)
    6206           0 :     _displaced_problem->bumpVolumeQRuleOrder(order, block);
    6207             : 
    6208          84 :   updateMaxQps();
    6209          84 : }
    6210             : 
    6211             : void
    6212          14 : FEProblemBase::bumpAllQRuleOrder(Order order, SubdomainID block)
    6213             : {
    6214          30 :   for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
    6215          32 :     for (const auto i : index_range(_nl))
    6216          16 :       _assembly[tid][i]->bumpAllQRuleOrder(order, block);
    6217             : 
    6218          14 :   if (_displaced_problem)
    6219           0 :     _displaced_problem->bumpAllQRuleOrder(order, block);
    6220             : 
    6221          14 :   updateMaxQps();
    6222          14 : }
    6223             : 
    6224             : void
    6225       64031 : FEProblemBase::createQRules(QuadratureType type,
    6226             :                             Order order,
    6227             :                             Order volume_order,
    6228             :                             Order face_order,
    6229             :                             SubdomainID block,
    6230             :                             const bool allow_negative_qweights)
    6231             : {
    6232       64031 :   if (order == INVALID_ORDER)
    6233             :   {
    6234             :     // automatically determine the integration order
    6235       63524 :     order = _solver_systems[0]->getMinQuadratureOrder();
    6236       63803 :     for (const auto i : make_range(std::size_t(1), _solver_systems.size()))
    6237         279 :       if (order < _solver_systems[i]->getMinQuadratureOrder())
    6238           0 :         order = _solver_systems[i]->getMinQuadratureOrder();
    6239       63524 :     if (order < _aux->getMinQuadratureOrder())
    6240        5566 :       order = _aux->getMinQuadratureOrder();
    6241             :   }
    6242             : 
    6243       64031 :   if (volume_order == INVALID_ORDER)
    6244       63936 :     volume_order = order;
    6245             : 
    6246       64031 :   if (face_order == INVALID_ORDER)
    6247       63936 :     face_order = order;
    6248             : 
    6249      134317 :   for (unsigned int tid = 0; tid < libMesh::n_threads(); ++tid)
    6250      140869 :     for (const auto i : index_range(_solver_systems))
    6251       70583 :       _assembly[tid][i]->createQRules(
    6252             :           type, order, volume_order, face_order, block, allow_negative_qweights);
    6253             : 
    6254       64031 :   if (_displaced_problem)
    6255        2246 :     _displaced_problem->createQRules(
    6256             :         type, order, volume_order, face_order, block, allow_negative_qweights);
    6257             : 
    6258       64031 :   updateMaxQps();
    6259       64031 : }
    6260             : 
    6261             : void
    6262       22645 : FEProblemBase::setCoupling(Moose::CouplingType type)
    6263             : {
    6264       22645 :   if (_trust_user_coupling_matrix)
    6265             :   {
    6266           4 :     if (_coupling != Moose::COUPLING_CUSTOM)
    6267           0 :       mooseError("Someone told us (the FEProblemBase) to trust the user coupling matrix, but we "
    6268             :                  "haven't been provided a coupling matrix!");
    6269             : 
    6270             :     // We've been told to trust the user coupling matrix, so we're going to leave things alone
    6271           4 :     return;
    6272             :   }
    6273             : 
    6274       22641 :   _coupling = type;
    6275             : }
    6276             : 
    6277             : void
    6278           0 : FEProblemBase::setCouplingMatrix(CouplingMatrix * cm, const unsigned int i)
    6279             : {
    6280             :   // TODO: Deprecate method
    6281           0 :   setCoupling(Moose::COUPLING_CUSTOM);
    6282           0 :   _cm[i].reset(cm);
    6283           0 : }
    6284             : 
    6285             : void
    6286       15030 : FEProblemBase::setCouplingMatrix(std::unique_ptr<CouplingMatrix> cm, const unsigned int i)
    6287             : {
    6288       15030 :   setCoupling(Moose::COUPLING_CUSTOM);
    6289       15030 :   _cm[i] = std::move(cm);
    6290       15030 : }
    6291             : 
    6292             : void
    6293           4 : FEProblemBase::trustUserCouplingMatrix()
    6294             : {
    6295           4 :   if (_coupling != Moose::COUPLING_CUSTOM)
    6296           0 :     mooseError("Someone told us (the FEProblemBase) to trust the user coupling matrix, but we "
    6297             :                "haven't been provided a coupling matrix!");
    6298             : 
    6299           4 :   _trust_user_coupling_matrix = true;
    6300           4 : }
    6301             : 
    6302             : void
    6303          81 : FEProblemBase::setNonlocalCouplingMatrix()
    6304             : {
    6305         405 :   TIME_SECTION("setNonlocalCouplingMatrix", 5, "Setting Nonlocal Coupling Matrix");
    6306             : 
    6307          81 :   if (_nl.size() > 1)
    6308           0 :     mooseError("Nonlocal kernels are weirdly stored on the FEProblem so we don't currently support "
    6309             :                "multiple nonlinear systems with nonlocal kernels.");
    6310             : 
    6311         162 :   for (const auto nl_sys_num : index_range(_nl))
    6312             :   {
    6313          81 :     auto & nl = _nl[nl_sys_num];
    6314          81 :     auto & nonlocal_cm = _nonlocal_cm[nl_sys_num];
    6315          81 :     unsigned int n_vars = nl->nVariables();
    6316          81 :     nonlocal_cm.resize(n_vars);
    6317          81 :     const auto & vars = nl->getVariables(0);
    6318          81 :     const auto & nonlocal_kernel = _nonlocal_kernels.getObjects();
    6319          81 :     const auto & nonlocal_integrated_bc = _nonlocal_integrated_bcs.getObjects();
    6320         243 :     for (const auto & ivar : vars)
    6321             :     {
    6322         252 :       for (const auto & kernel : nonlocal_kernel)
    6323             :       {
    6324         180 :         for (unsigned int i = ivar->number(); i < ivar->number() + ivar->count(); ++i)
    6325          90 :           if (i == kernel->variable().number())
    6326         135 :             for (const auto & jvar : vars)
    6327             :             {
    6328          90 :               const auto it = _var_dof_map.find(jvar->name());
    6329          90 :               if (it != _var_dof_map.end())
    6330             :               {
    6331          80 :                 unsigned int j = jvar->number();
    6332          80 :                 nonlocal_cm(i, j) = 1;
    6333             :               }
    6334             :             }
    6335             :       }
    6336         234 :       for (const auto & integrated_bc : nonlocal_integrated_bc)
    6337             :       {
    6338         144 :         for (unsigned int i = ivar->number(); i < ivar->number() + ivar->count(); ++i)
    6339          72 :           if (i == integrated_bc->variable().number())
    6340         108 :             for (const auto & jvar : vars)
    6341             :             {
    6342          72 :               const auto it = _var_dof_map.find(jvar->name());
    6343          72 :               if (it != _var_dof_map.end())
    6344             :               {
    6345          36 :                 unsigned int j = jvar->number();
    6346          36 :                 nonlocal_cm(i, j) = 1;
    6347             :               }
    6348             :             }
    6349             :       }
    6350             :     }
    6351             :   }
    6352          81 : }
    6353             : 
    6354             : bool
    6355         712 : FEProblemBase::areCoupled(const unsigned int ivar,
    6356             :                           const unsigned int jvar,
    6357             :                           const unsigned int nl_sys) const
    6358             : {
    6359         712 :   return (*_cm[nl_sys])(ivar, jvar);
    6360             : }
    6361             : 
    6362             : std::vector<std::pair<MooseVariableFEBase *, MooseVariableFEBase *>> &
    6363    19036606 : FEProblemBase::couplingEntries(const THREAD_ID tid, const unsigned int nl_sys)
    6364             : {
    6365    19036606 :   return _assembly[tid][nl_sys]->couplingEntries();
    6366             : }
    6367             : 
    6368             : std::vector<std::pair<MooseVariableFEBase *, MooseVariableFEBase *>> &
    6369        5558 : FEProblemBase::nonlocalCouplingEntries(const THREAD_ID tid, const unsigned int nl_sys)
    6370             : {
    6371        5558 :   return _assembly[tid][nl_sys]->nonlocalCouplingEntries();
    6372             : }
    6373             : 
    6374             : void
    6375       62487 : FEProblemBase::init()
    6376             : {
    6377       62487 :   if (_initialized)
    6378           0 :     return;
    6379             : 
    6380      312435 :   TIME_SECTION("init", 2, "Initializing");
    6381             : 
    6382             :   // call executioner's preProblemInit so that it can do some setups before problem init
    6383       62487 :   _app.getExecutioner()->preProblemInit();
    6384             : 
    6385             :   // If we have AD and we are doing global AD indexing, then we should by default set the matrix
    6386             :   // coupling to full. If the user has told us to trust their coupling matrix, then this call will
    6387             :   // not do anything
    6388       62487 :   if (haveADObjects() && Moose::globalADIndexing())
    6389        7513 :     setCoupling(Moose::COUPLING_FULL);
    6390             : 
    6391      123909 :   for (const auto i : index_range(_nl))
    6392             :   {
    6393       61422 :     auto & nl = _nl[i];
    6394       61422 :     auto & cm = _cm[i];
    6395             : 
    6396       61422 :     unsigned int n_vars = nl->nVariables();
    6397             :     {
    6398      307110 :       TIME_SECTION("fillCouplingMatrix", 3, "Filling Coupling Matrix");
    6399             : 
    6400       61422 :       switch (_coupling)
    6401             :       {
    6402       44489 :         case Moose::COUPLING_DIAG:
    6403       44489 :           cm = std::make_unique<CouplingMatrix>(n_vars);
    6404       82774 :           for (unsigned int i = 0; i < n_vars; i++)
    6405       38285 :             (*cm)(i, i) = 1;
    6406       44489 :           break;
    6407             : 
    6408             :           // for full jacobian
    6409        7656 :         case Moose::COUPLING_FULL:
    6410        7656 :           cm = std::make_unique<CouplingMatrix>(n_vars);
    6411       19421 :           for (unsigned int i = 0; i < n_vars; i++)
    6412       33792 :             for (unsigned int j = 0; j < n_vars; j++)
    6413       22027 :               (*cm)(i, j) = 1;
    6414        7656 :           break;
    6415             : 
    6416        9277 :         case Moose::COUPLING_CUSTOM:
    6417             :           // do nothing, _cm was already set through couplingMatrix() call
    6418        9277 :           break;
    6419             :       }
    6420       61422 :     }
    6421             : 
    6422       61422 :     nl->dofMap()._dof_coupling = cm.get();
    6423             : 
    6424             :     // If there are no variables, make sure to pass a nullptr coupling
    6425             :     // matrix, to avoid warnings about non-nullptr yet empty
    6426             :     // CouplingMatrices.
    6427       61422 :     if (n_vars == 0)
    6428       12170 :       nl->dofMap()._dof_coupling = nullptr;
    6429             : 
    6430       61422 :     nl->dofMap().attach_extra_sparsity_function(&extraSparsity, nl.get());
    6431       61422 :     nl->dofMap().attach_extra_send_list_function(&extraSendList, nl.get());
    6432       61422 :     _aux->dofMap().attach_extra_send_list_function(&extraSendList, _aux.get());
    6433             : 
    6434       61422 :     if (!_skip_nl_system_check && _solve && n_vars == 0)
    6435           0 :       mooseError("No variables specified in nonlinear system '", nl->name(), "'.");
    6436             :   }
    6437             : 
    6438       62487 :   ghostGhostedBoundaries(); // We do this again right here in case new boundaries have been added
    6439             : 
    6440             :   // We may have added element/nodes to the mesh in ghostGhostedBoundaries so we need to update
    6441             :   // all of our mesh information. We need to make sure that mesh information is up-to-date before
    6442             :   // EquationSystems::init because that will call through to updateGeomSearch (for sparsity
    6443             :   // augmentation) and if we haven't added back boundary node information before that latter call,
    6444             :   // then we're screwed. We'll get things like "Unable to find closest node!"
    6445       62487 :   _mesh.meshChanged();
    6446       62487 :   if (_displaced_problem)
    6447        2246 :     _displaced_mesh->meshChanged();
    6448             : 
    6449       62487 :   if (_mesh.doingPRefinement())
    6450             :   {
    6451         234 :     preparePRefinement();
    6452         234 :     if (_displaced_problem)
    6453           0 :       _displaced_problem->preparePRefinement();
    6454             :   }
    6455             : 
    6456             :   // do not assemble system matrix for JFNK solve
    6457      123909 :   for (auto & nl : _nl)
    6458       61422 :     if (solverParams(nl->number())._type == Moose::ST_JFNK)
    6459         139 :       nl->turnOffJacobian();
    6460             : 
    6461      125249 :   for (auto & sys : _solver_systems)
    6462       62762 :     sys->preInit();
    6463       62487 :   _aux->preInit();
    6464             : 
    6465             :   // Build the mortar segment meshes, if they haven't been already, for a couple reasons:
    6466             :   // 1) Get the ghosting correct for both static and dynamic meshes
    6467             :   // 2) Make sure the mortar mesh is built for mortar constraints that live on the static mesh
    6468             :   //
    6469             :   // It is worth-while to note that mortar meshes that live on a dynamic mesh will be built
    6470             :   // during residual and Jacobian evaluation because when displacements are solution variables
    6471             :   // the mortar mesh will move and change during the course of a non-linear solve. We DO NOT
    6472             :   // redo ghosting during non-linear solve, so for purpose 1) the below call has to be made
    6473       62487 :   if (!_mortar_data.initialized())
    6474       46418 :     updateMortarMesh();
    6475             : 
    6476             :   {
    6477      312435 :     TIME_SECTION("EquationSystems::Init", 2, "Initializing Equation Systems");
    6478       62487 :     es().init();
    6479       62487 :   }
    6480             : 
    6481      125249 :   for (auto & sys : _solver_systems)
    6482       62762 :     sys->postInit();
    6483       62487 :   _aux->postInit();
    6484             : 
    6485             :   // Now that the equation system and the dof distribution is done, we can generate the
    6486             :   // finite volume-related parts if needed.
    6487       62487 :   if (haveFV())
    6488        5384 :     _mesh.setupFiniteVolumeMeshData();
    6489             : 
    6490      125249 :   for (auto & sys : _solver_systems)
    6491       62762 :     sys->update();
    6492       62487 :   _aux->update();
    6493             : 
    6494      130863 :   for (THREAD_ID tid = 0; tid < libMesh::n_threads(); ++tid)
    6495      135704 :     for (const auto i : index_range(_nl))
    6496             :     {
    6497             :       mooseAssert(
    6498             :           _cm[i],
    6499             :           "Coupling matrix not set for system "
    6500             :               << i
    6501             :               << ". This should only happen if a preconditioner was not setup for this system");
    6502       67328 :       _assembly[tid][i]->init(_cm[i].get());
    6503             :     }
    6504             : 
    6505       62487 :   if (_displaced_problem)
    6506        2246 :     _displaced_problem->init();
    6507             : 
    6508             : #ifdef MOOSE_KOKKOS_ENABLED
    6509       41814 :   if (_has_kokkos_objects)
    6510         693 :     initKokkos();
    6511             : #endif
    6512             : 
    6513       62487 :   _initialized = true;
    6514       62487 : }
    6515             : 
    6516             : unsigned int
    6517       13626 : FEProblemBase::nlSysNum(const NonlinearSystemName & nl_sys_name) const
    6518             : {
    6519       13626 :   std::istringstream ss(nl_sys_name);
    6520             :   unsigned int nl_sys_num;
    6521       13626 :   if (!(ss >> nl_sys_num) || !ss.eof())
    6522       13626 :     nl_sys_num = libmesh_map_find(_nl_sys_name_to_num, nl_sys_name);
    6523             : 
    6524       13626 :   return nl_sys_num;
    6525       13626 : }
    6526             : 
    6527             : unsigned int
    6528       39884 : FEProblemBase::linearSysNum(const LinearSystemName & linear_sys_name) const
    6529             : {
    6530       39884 :   std::istringstream ss(linear_sys_name);
    6531             :   unsigned int linear_sys_num;
    6532       39884 :   if (!(ss >> linear_sys_num) || !ss.eof())
    6533       39884 :     linear_sys_num = libmesh_map_find(_linear_sys_name_to_num, linear_sys_name);
    6534             : 
    6535       39884 :   return linear_sys_num;
    6536       39884 : }
    6537             : 
    6538             : unsigned int
    6539      130314 : FEProblemBase::solverSysNum(const SolverSystemName & solver_sys_name) const
    6540             : {
    6541      130314 :   std::istringstream ss(solver_sys_name);
    6542             :   unsigned int solver_sys_num;
    6543      130314 :   if (!(ss >> solver_sys_num) || !ss.eof())
    6544             :   {
    6545      130314 :     const auto & search = _solver_sys_name_to_num.find(solver_sys_name);
    6546      130314 :     if (search == _solver_sys_name_to_num.end())
    6547           0 :       mooseError("The solver system number was requested for system '" + solver_sys_name,
    6548             :                  "' but this system does not exist in the Problem. Systems can be added to the "
    6549             :                  "problem using the 'nl_sys_names'/'linear_sys_names' parameter.\nSystems in the "
    6550           0 :                  "Problem: " +
    6551           0 :                      Moose::stringify(_solver_sys_names));
    6552      130314 :     solver_sys_num = search->second;
    6553             :   }
    6554             : 
    6555      130314 :   return solver_sys_num;
    6556      130314 : }
    6557             : 
    6558             : unsigned int
    6559        1641 : FEProblemBase::systemNumForVariable(const VariableName & variable_name) const
    6560             : {
    6561        1752 :   for (const auto & solver_sys : _solver_systems)
    6562        1641 :     if (solver_sys->hasVariable(variable_name))
    6563        1530 :       return solver_sys->number();
    6564             :   mooseAssert(_aux, "Should have an auxiliary system");
    6565         111 :   if (_aux->hasVariable(variable_name))
    6566         111 :     return _aux->number();
    6567             : 
    6568           0 :   mooseError("Variable '",
    6569             :              variable_name,
    6570             :              "' was not found in any solver (nonlinear/linear) or auxiliary system");
    6571             : }
    6572             : 
    6573             : void
    6574      347664 : FEProblemBase::solve(const unsigned int nl_sys_num)
    6575             : {
    6576     1738320 :   TIME_SECTION("solve", 1, "Solving", false);
    6577             : 
    6578      347664 :   setCurrentNonlinearSystem(nl_sys_num);
    6579             : 
    6580             :   // This prevents stale dof indices from lingering around and possibly leading to invalid reads
    6581             :   // and writes. Dof indices may be made stale through operations like mesh adaptivity
    6582      347664 :   clearAllDofIndices();
    6583      347664 :   if (_displaced_problem)
    6584       35869 :     _displaced_problem->clearAllDofIndices();
    6585             : 
    6586             :   // Setup the output system for printing linear/nonlinear iteration information and some solver
    6587             :   // settings, including setting matrix prefixes. This must occur before petscSetOptions
    6588      347664 :   initPetscOutputAndSomeSolverSettings();
    6589             : 
    6590             : #if PETSC_RELEASE_LESS_THAN(3, 12, 0)
    6591             :   Moose::PetscSupport::petscSetOptions(
    6592             :       _petsc_options, _solver_params); // Make sure the PETSc options are setup for this app
    6593             : #else
    6594             :   // Now this database will be the default
    6595             :   // Each app should have only one database
    6596      347664 :   if (!_app.isUltimateMaster())
    6597       89156 :     LibmeshPetscCall(PetscOptionsPush(_petsc_option_data_base));
    6598             :   // We did not add PETSc options to database yet
    6599      347664 :   if (!_is_petsc_options_inserted)
    6600             :   {
    6601             :     // Insert options for all systems all at once
    6602       42085 :     Moose::PetscSupport::petscSetOptions(_petsc_options, _solver_params, this);
    6603       42085 :     _is_petsc_options_inserted = true;
    6604             :   }
    6605             : #endif
    6606             : 
    6607             :   // set up DM which is required if use a field split preconditioner
    6608             :   // We need to setup DM every "solve()" because libMesh destroy SNES after solve()
    6609             :   // Do not worry, DM setup is very cheap
    6610      347664 :   _current_nl_sys->setupDM();
    6611             : 
    6612      347664 :   possiblyRebuildGeomSearchPatches();
    6613             : 
    6614             :   // reset flag so that residual evaluation does not get skipped
    6615             :   // and the next non-linear iteration does not automatically fail with
    6616             :   // "DIVERGED_NANORINF", when we throw  an exception and stop solve
    6617      347664 :   _fail_next_system_convergence_check = false;
    6618             : 
    6619      347664 :   if (_solve)
    6620             :   {
    6621      316346 :     _current_nl_sys->solve();
    6622      316266 :     _current_nl_sys->update();
    6623             :   }
    6624             : 
    6625             :   // sync solutions in displaced problem
    6626      347584 :   if (_displaced_problem)
    6627       35865 :     _displaced_problem->syncSolutions();
    6628             : 
    6629             : #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
    6630      347584 :   if (!_app.isUltimateMaster())
    6631       89156 :     LibmeshPetscCall(PetscOptionsPop());
    6632             : #endif
    6633      347584 : }
    6634             : 
    6635             : void
    6636         214 : FEProblemBase::setException(const std::string & message)
    6637             : {
    6638         214 :   _has_exception = true;
    6639         214 :   _exception_message = message;
    6640         214 : }
    6641             : 
    6642             : void
    6643    21775153 : FEProblemBase::checkExceptionAndStopSolve(bool print_message)
    6644             : {
    6645    21775153 :   if (_skip_exception_check)
    6646         240 :     return;
    6647             : 
    6648    65324739 :   TIME_SECTION("checkExceptionAndStopSolve", 5);
    6649             : 
    6650             :   // See if any processor had an exception.  If it did, get back the
    6651             :   // processor that the exception occurred on.
    6652             :   unsigned int processor_id;
    6653             : 
    6654    21774913 :   _communicator.maxloc(_has_exception, processor_id);
    6655             : 
    6656    21774913 :   if (_has_exception)
    6657             :   {
    6658         337 :     _communicator.broadcast(_exception_message, processor_id);
    6659             : 
    6660         451 :     if (_current_execute_on_flag == EXEC_LINEAR || _current_execute_on_flag == EXEC_NONLINEAR ||
    6661         114 :         _current_execute_on_flag == EXEC_POSTCHECK)
    6662             :     {
    6663             :       // Print the message
    6664         337 :       if (_communicator.rank() == 0 && print_message)
    6665             :       {
    6666         197 :         _console << "\n" << _exception_message << "\n";
    6667         197 :         if (isTransient())
    6668             :           _console
    6669             :               << "To recover, the solution will fail and then be re-attempted with a reduced time "
    6670         180 :                  "step.\n"
    6671         180 :               << std::endl;
    6672             :       }
    6673             : 
    6674             :       // Stop the solve -- this entails setting
    6675             :       // SNESSetFunctionDomainError() or directly inserting NaNs in the
    6676             :       // residual vector to let PETSc >= 3.6 return DIVERGED_NANORINF.
    6677         337 :       if (_current_nl_sys)
    6678         337 :         _current_nl_sys->stopSolve(_current_execute_on_flag, _fe_vector_tags);
    6679             : 
    6680         337 :       if (_current_linear_sys)
    6681           0 :         _current_linear_sys->stopSolve(_current_execute_on_flag, _fe_vector_tags);
    6682             : 
    6683             :       // and close Aux system (we MUST do this here; see #11525)
    6684         337 :       _aux->solution().close();
    6685             : 
    6686             :       // We've handled this exception, so we no longer have one.
    6687         337 :       _has_exception = false;
    6688             : 
    6689             :       // Force the next non-linear convergence check to fail (and all further residual evaluation
    6690             :       // to be skipped).
    6691         337 :       _fail_next_system_convergence_check = true;
    6692             : 
    6693             :       // Repropagate the exception, so it can be caught at a higher level, typically
    6694             :       // this is NonlinearSystem::computeResidual().
    6695         337 :       throw MooseException(_exception_message);
    6696             :     }
    6697             :     else
    6698           0 :       mooseError("The following parallel-communicated exception was detected during " +
    6699           0 :                  Moose::stringify(_current_execute_on_flag) + " evaluation:\n" +
    6700           0 :                  _exception_message +
    6701             :                  "\nBecause this did not occur during residual evaluation, there"
    6702             :                  " is no way to handle this, so the solution is aborting.\n");
    6703             :   }
    6704    21774913 : }
    6705             : 
    6706             : void
    6707     3873537 : FEProblemBase::resetState()
    6708             : {
    6709             :   // Our default state is to allow computing derivatives
    6710     3873537 :   ADReal::do_derivatives = true;
    6711     3873537 :   _current_execute_on_flag = EXEC_NONE;
    6712             : 
    6713             :   // Clear the VectorTags and MatrixTags
    6714     3873537 :   clearCurrentResidualVectorTags();
    6715     3873537 :   clearCurrentJacobianMatrixTags();
    6716             : 
    6717     3873537 :   _safe_access_tagged_vectors = true;
    6718     3873537 :   _safe_access_tagged_matrices = true;
    6719             : 
    6720     3873537 :   setCurrentlyComputingResidual(false);
    6721     3873537 :   setCurrentlyComputingJacobian(false);
    6722     3873537 :   setCurrentlyComputingResidualAndJacobian(false);
    6723     3873537 :   if (_displaced_problem)
    6724             :   {
    6725      160528 :     _displaced_problem->setCurrentlyComputingResidual(false);
    6726      160528 :     _displaced_problem->setCurrentlyComputingJacobian(false);
    6727      160528 :     _displaced_problem->setCurrentlyComputingResidualAndJacobian(false);
    6728             :   }
    6729     3873537 : }
    6730             : 
    6731             : void
    6732        5648 : FEProblemBase::solveLinearSystem(const unsigned int linear_sys_num,
    6733             :                                  const Moose::PetscSupport::PetscOptions * po)
    6734             : {
    6735       28240 :   TIME_SECTION("solve", 1, "Solving", false);
    6736             : 
    6737        5648 :   setCurrentLinearSystem(linear_sys_num);
    6738             : 
    6739        5648 :   const Moose::PetscSupport::PetscOptions & options = po ? *po : _petsc_options;
    6740        5648 :   auto & solver_params = _solver_params[numNonlinearSystems() + linear_sys_num];
    6741             : 
    6742             :   // Set custom convergence criteria
    6743        5648 :   Moose::PetscSupport::petscSetDefaults(*this);
    6744             : 
    6745             : #if PETSC_RELEASE_LESS_THAN(3, 12, 0)
    6746             :   LibmeshPetscCall(Moose::PetscSupport::petscSetOptions(
    6747             :       options, solver_params)); // Make sure the PETSc options are setup for this app
    6748             : #else
    6749             :   // Now this database will be the default
    6750             :   // Each app should have only one database
    6751        5648 :   if (!_app.isUltimateMaster())
    6752         235 :     LibmeshPetscCall(PetscOptionsPush(_petsc_option_data_base));
    6753             : 
    6754             :   // We did not add PETSc options to database yet
    6755        5648 :   if (!_is_petsc_options_inserted)
    6756             :   {
    6757        1257 :     Moose::PetscSupport::petscSetOptions(options, solver_params, this);
    6758        1257 :     _is_petsc_options_inserted = true;
    6759             :   }
    6760             : #endif
    6761             : 
    6762        5648 :   if (_solve)
    6763        5636 :     _current_linear_sys->solve();
    6764             : 
    6765             : #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
    6766        5648 :   if (!_app.isUltimateMaster())
    6767         235 :     LibmeshPetscCall(PetscOptionsPop());
    6768             : #endif
    6769        5648 : }
    6770             : 
    6771             : bool
    6772      345187 : FEProblemBase::solverSystemConverged(const unsigned int sys_num)
    6773             : {
    6774      345187 :   if (_solve)
    6775      345163 :     return _solver_systems[sys_num]->converged();
    6776             :   else
    6777          24 :     return true;
    6778             : }
    6779             : 
    6780             : unsigned int
    6781        6328 : FEProblemBase::nNonlinearIterations(const unsigned int nl_sys_num) const
    6782             : {
    6783        6328 :   return _nl[nl_sys_num]->nNonlinearIterations();
    6784             : }
    6785             : 
    6786             : unsigned int
    6787        5425 : FEProblemBase::nLinearIterations(const unsigned int nl_sys_num) const
    6788             : {
    6789        5425 :   return _nl[nl_sys_num]->nLinearIterations();
    6790             : }
    6791             : 
    6792             : Real
    6793         258 : FEProblemBase::finalNonlinearResidual(const unsigned int nl_sys_num) const
    6794             : {
    6795         258 :   return _nl[nl_sys_num]->finalNonlinearResidual();
    6796             : }
    6797             : 
    6798             : bool
    6799      845824 : FEProblemBase::computingPreSMOResidual(const unsigned int nl_sys_num) const
    6800             : {
    6801      845824 :   return _nl[nl_sys_num]->computingPreSMOResidual();
    6802             : }
    6803             : 
    6804             : void
    6805       57031 : FEProblemBase::copySolutionsBackwards()
    6806             : {
    6807      285155 :   TIME_SECTION("copySolutionsBackwards", 3, "Copying Solutions Backward");
    6808             : 
    6809      114319 :   for (auto & sys : _solver_systems)
    6810       57288 :     sys->copySolutionsBackwards();
    6811       57031 :   _aux->copySolutionsBackwards();
    6812       57031 : }
    6813             : 
    6814             : void
    6815      249256 : FEProblemBase::advanceState()
    6816             : {
    6817     1246280 :   TIME_SECTION("advanceState", 5, "Advancing State");
    6818             : 
    6819      502171 :   for (auto & sys : _solver_systems)
    6820      252915 :     sys->copyOldSolutions();
    6821      249256 :   _aux->copyOldSolutions();
    6822             : 
    6823      249256 :   if (_displaced_problem)
    6824             :   {
    6825       67642 :     for (const auto i : index_range(_solver_systems))
    6826       33821 :       _displaced_problem->solverSys(i).copyOldSolutions();
    6827       33821 :     _displaced_problem->auxSys().copyOldSolutions();
    6828             :   }
    6829             : 
    6830      249256 :   _reporter_data.copyValuesBack();
    6831             : 
    6832      249256 :   getMooseApp().getChainControlDataSystem().copyValuesBack();
    6833             : 
    6834      249256 :   if (_material_props.hasStatefulProperties())
    6835        1970 :     _material_props.shift();
    6836             : 
    6837      249256 :   if (_bnd_material_props.hasStatefulProperties())
    6838        1816 :     _bnd_material_props.shift();
    6839             : 
    6840      249256 :   if (_neighbor_material_props.hasStatefulProperties())
    6841        1682 :     _neighbor_material_props.shift();
    6842             : 
    6843             : #ifdef MOOSE_KOKKOS_ENABLED
    6844      163736 :   if (_kokkos_material_props.hasStatefulProperties())
    6845         376 :     _kokkos_material_props.shift();
    6846             : 
    6847      163736 :   if (_kokkos_bnd_material_props.hasStatefulProperties())
    6848         426 :     _kokkos_bnd_material_props.shift();
    6849             : 
    6850      163736 :   if (_kokkos_neighbor_material_props.hasStatefulProperties())
    6851         376 :     _kokkos_neighbor_material_props.shift();
    6852             : #endif
    6853      249256 : }
    6854             : 
    6855             : void
    6856        5360 : FEProblemBase::restoreSolutions()
    6857             : {
    6858       26800 :   TIME_SECTION("restoreSolutions", 5, "Restoring Solutions");
    6859             : 
    6860        5360 :   if (!_not_zeroed_tagged_vectors.empty())
    6861           0 :     paramError("not_zeroed_tag_vectors",
    6862             :                "There is currently no way to restore not-zeroed vectors.");
    6863             : 
    6864       10722 :   for (auto & sys : _solver_systems)
    6865             :   {
    6866        5362 :     if (_verbose_restore)
    6867         395 :       _console << "Restoring solutions on system " << sys->name() << "..." << std::endl;
    6868        5362 :     sys->restoreSolutions();
    6869             :   }
    6870             : 
    6871        5360 :   if (_verbose_restore)
    6872         394 :     _console << "Restoring solutions on Auxiliary system..." << std::endl;
    6873        5360 :   _aux->restoreSolutions();
    6874             : 
    6875        5360 :   if (_verbose_restore)
    6876         394 :     _console << "Restoring postprocessor, vector-postprocessor, and reporter data..." << std::endl;
    6877        5360 :   _reporter_data.restoreState(_verbose_restore);
    6878             : 
    6879        5360 :   if (_displaced_problem)
    6880         136 :     _displaced_problem->updateMesh();
    6881        5360 : }
    6882             : 
    6883             : void
    6884         115 : FEProblemBase::saveOldSolutions()
    6885             : {
    6886         575 :   TIME_SECTION("saveOldSolutions", 5, "Saving Old Solutions");
    6887             : 
    6888         230 :   for (auto & sys : _solver_systems)
    6889         115 :     sys->saveOldSolutions();
    6890         115 :   _aux->saveOldSolutions();
    6891         115 : }
    6892             : 
    6893             : void
    6894         115 : FEProblemBase::restoreOldSolutions()
    6895             : {
    6896         575 :   TIME_SECTION("restoreOldSolutions", 5, "Restoring Old Solutions");
    6897             : 
    6898         230 :   for (auto & sys : _solver_systems)
    6899         115 :     sys->restoreOldSolutions();
    6900         115 :   _aux->restoreOldSolutions();
    6901         115 : }
    6902             : 
    6903             : void
    6904     1332410 : FEProblemBase::outputStep(ExecFlagType type)
    6905             : {
    6906     6662050 :   TIME_SECTION("outputStep", 1, "Outputting");
    6907             : 
    6908     1332410 :   setCurrentExecuteOnFlag(type);
    6909             : 
    6910     2680264 :   for (auto & sys : _solver_systems)
    6911     1347854 :     sys->update();
    6912     1332410 :   _aux->update();
    6913             : 
    6914     1332410 :   if (_displaced_problem)
    6915      138047 :     _displaced_problem->syncSolutions();
    6916     1332410 :   _app.getOutputWarehouse().outputStep(type);
    6917             : 
    6918     1332398 :   setCurrentExecuteOnFlag(EXEC_NONE);
    6919     1332398 : }
    6920             : 
    6921             : void
    6922       89528 : FEProblemBase::allowOutput(bool state)
    6923             : {
    6924       89528 :   _app.getOutputWarehouse().allowOutput(state);
    6925       89528 : }
    6926             : 
    6927             : void
    6928          25 : FEProblemBase::forceOutput()
    6929             : {
    6930          25 :   _app.getOutputWarehouse().forceOutput();
    6931          25 : }
    6932             : 
    6933             : void
    6934      368668 : FEProblemBase::initPetscOutputAndSomeSolverSettings()
    6935             : {
    6936      368668 :   _app.getOutputWarehouse().solveSetup();
    6937      368668 :   Moose::PetscSupport::petscSetDefaults(*this);
    6938      368668 : }
    6939             : 
    6940             : void
    6941      258829 : FEProblemBase::onTimestepBegin()
    6942             : {
    6943      776487 :   TIME_SECTION("onTimestepBegin", 2);
    6944             : 
    6945      521030 :   for (auto & nl : _nl)
    6946      262201 :     nl->onTimestepBegin();
    6947      258829 : }
    6948             : 
    6949             : void
    6950      334105 : FEProblemBase::onTimestepEnd()
    6951             : {
    6952      334105 : }
    6953             : 
    6954             : Real
    6955     8145249 : FEProblemBase::getTimeFromStateArg(const Moose::StateArg & state) const
    6956             : {
    6957     8145249 :   if (state.iteration_type != Moose::SolutionIterationType::Time)
    6958             :     // If we are any iteration type other than time (e.g. nonlinear), then temporally we are still
    6959             :     // in the present time
    6960           0 :     return time();
    6961             : 
    6962     8145249 :   switch (state.state)
    6963             :   {
    6964     8145249 :     case 0:
    6965     8145249 :       return time();
    6966             : 
    6967           0 :     case 1:
    6968           0 :       return timeOld();
    6969             : 
    6970           0 :     default:
    6971           0 :       mooseError("Unhandled state ", state.state, " in FEProblemBase::getTimeFromStateArg");
    6972             :   }
    6973             : }
    6974             : 
    6975             : void
    6976       31867 : FEProblemBase::addTimeIntegrator(const std::string & type,
    6977             :                                  const std::string & name,
    6978             :                                  InputParameters & parameters)
    6979             : {
    6980             :   parallel_object_only();
    6981             : 
    6982       95601 :   parameters.set<SubProblem *>("_subproblem") = this;
    6983       31867 :   logAdd("TimeIntegrator", name, type, parameters);
    6984       31867 :   _aux->addTimeIntegrator(type, name + ":aux", parameters);
    6985       63768 :   for (auto & sys : _solver_systems)
    6986       31901 :     sys->addTimeIntegrator(type, name + ":" + sys->name(), parameters);
    6987       31867 :   _has_time_integrator = true;
    6988             : 
    6989             :   // add vectors to store u_dot, u_dotdot, udot_old, u_dotdot_old and
    6990             :   // solution vectors older than 2 time steps, if requested by the time
    6991             :   // integrator
    6992       31867 :   _aux->addDotVectors();
    6993       63742 :   for (auto & nl : _nl)
    6994             :   {
    6995       31875 :     nl->addDotVectors();
    6996             : 
    6997       31875 :     auto tag_udot = nl->getTimeIntegrators()[0]->uDotFactorTag();
    6998       31875 :     if (!nl->hasVector(tag_udot))
    6999       31817 :       nl->associateVectorToTag(*nl->solutionUDot(), tag_udot);
    7000       31875 :     auto tag_udotdot = nl->getTimeIntegrators()[0]->uDotDotFactorTag();
    7001       31875 :     if (!nl->hasVector(tag_udotdot) && uDotDotRequested())
    7002         164 :       nl->associateVectorToTag(*nl->solutionUDotDot(), tag_udotdot);
    7003             :   }
    7004             : 
    7005       31867 :   if (_displaced_problem)
    7006             :     // Time integrator does not exist when displaced problem is created.
    7007        1908 :     _displaced_problem->addTimeIntegrator();
    7008       31867 : }
    7009             : 
    7010             : void
    7011          24 : FEProblemBase::addPredictor(const std::string & type,
    7012             :                             const std::string & name,
    7013             :                             InputParameters & parameters)
    7014             : {
    7015             :   parallel_object_only();
    7016             : 
    7017          24 :   if (!numNonlinearSystems() && numLinearSystems())
    7018           0 :     mooseError("Vector bounds cannot be used with LinearSystems!");
    7019             : 
    7020          48 :   parameters.set<SubProblem *>("_subproblem") = this;
    7021          24 :   std::shared_ptr<Predictor> predictor = _factory.create<Predictor>(type, name, parameters);
    7022          24 :   logAdd("Predictor", name, type, parameters);
    7023             : 
    7024          48 :   for (auto & nl : _nl)
    7025          24 :     nl->setPredictor(predictor);
    7026          24 : }
    7027             : 
    7028             : Real
    7029       67294 : FEProblemBase::computeResidualL2Norm(NonlinearSystemBase & sys)
    7030             : {
    7031       67294 :   _current_nl_sys = &sys;
    7032       67294 :   computeResidual(*sys.currentSolution(), sys.RHS(), sys.number());
    7033       67294 :   return sys.RHS().l2_norm();
    7034             : }
    7035             : 
    7036             : Real
    7037         102 : FEProblemBase::computeResidualL2Norm(LinearSystem & sys)
    7038             : {
    7039         102 :   _current_linear_sys = &sys;
    7040             : 
    7041             :   // We assemble the current system to check the current residual
    7042         102 :   computeLinearSystemSys(sys.linearImplicitSystem(),
    7043         102 :                          *sys.linearImplicitSystem().matrix,
    7044         102 :                          *sys.linearImplicitSystem().rhs,
    7045             :                          /*compute fresh gradients*/ true);
    7046             : 
    7047             :   // Unfortunate, but we have to allocate a new vector for the residual
    7048         102 :   auto residual = sys.linearImplicitSystem().rhs->clone();
    7049         102 :   residual->scale(-1.0);
    7050         102 :   residual->add_vector(*sys.currentSolution(), *sys.linearImplicitSystem().matrix);
    7051         204 :   return residual->l2_norm();
    7052         102 : }
    7053             : 
    7054             : Real
    7055       67360 : FEProblemBase::computeResidualL2Norm()
    7056             : {
    7057      336800 :   TIME_SECTION("computeResidualL2Norm", 2, "Computing L2 Norm of Residual");
    7058             : 
    7059             :   // We use sum the squared norms of the individual systems and then take the square root of it
    7060       67360 :   Real l2_norm = 0.0;
    7061      134654 :   for (auto sys : _nl)
    7062             :   {
    7063       67294 :     const auto norm = computeResidualL2Norm(*sys);
    7064       67294 :     l2_norm += norm * norm;
    7065       67294 :   }
    7066             : 
    7067       67462 :   for (auto sys : _linear_systems)
    7068             :   {
    7069         102 :     const auto norm = computeResidualL2Norm(*sys);
    7070         102 :     l2_norm += norm * norm;
    7071         102 :   }
    7072             : 
    7073      134720 :   return std::sqrt(l2_norm);
    7074       67360 : }
    7075             : 
    7076             : void
    7077     3231076 : FEProblemBase::computeResidualSys(NonlinearImplicitSystem & sys,
    7078             :                                   const NumericVector<Number> & soln,
    7079             :                                   NumericVector<Number> & residual)
    7080             : {
    7081             :   parallel_object_only();
    7082             : 
    7083     9693228 :   TIME_SECTION("computeResidualSys", 5);
    7084             : 
    7085     3231076 :   computeResidual(soln, residual, sys.number());
    7086     3231032 : }
    7087             : 
    7088             : void
    7089           0 : FEProblemBase::computeResidual(NonlinearImplicitSystem & sys,
    7090             :                                const NumericVector<Number> & soln,
    7091             :                                NumericVector<Number> & residual)
    7092             : {
    7093           0 :   mooseDeprecated("Please use computeResidualSys");
    7094             : 
    7095           0 :   computeResidualSys(sys, soln, residual);
    7096           0 : }
    7097             : 
    7098             : void
    7099     3294204 : FEProblemBase::computeResidual(const NumericVector<Number> & soln,
    7100             :                                NumericVector<Number> & residual,
    7101             :                                const unsigned int nl_sys_num)
    7102             : {
    7103     3294204 :   setCurrentNonlinearSystem(nl_sys_num);
    7104             : 
    7105             :   // We associate the residual tag with the given residual vector to make sure we
    7106             :   // don't filter it out below
    7107     3294204 :   _current_nl_sys->associateVectorToTag(residual, _current_nl_sys->residualVectorTag());
    7108     3294204 :   const auto & residual_vector_tags = getVectorTags(Moose::VECTOR_TAG_RESIDUAL);
    7109             : 
    7110             :   mooseAssert(_fe_vector_tags.empty(), "This should be empty indicating a clean starting state");
    7111             :   // We filter out tags which do not have associated vectors in the current nonlinear
    7112             :   // system. This is essential to be able to use system-dependent residual tags.
    7113     3294204 :   selectVectorTagsFromSystem(*_current_nl_sys, residual_vector_tags, _fe_vector_tags);
    7114             : 
    7115     3294204 :   computeResidualInternal(soln, residual, _fe_vector_tags);
    7116     3294160 :   _fe_vector_tags.clear();
    7117     3294160 : }
    7118             : 
    7119             : void
    7120        3467 : FEProblemBase::computeResidualAndJacobian(const NumericVector<Number> & soln,
    7121             :                                           NumericVector<Number> & residual,
    7122             :                                           SparseMatrix<Number> & jacobian)
    7123             : {
    7124             :   try
    7125             :   {
    7126             :     try
    7127             :     {
    7128             :       // vector tags
    7129        3467 :       _current_nl_sys->associateVectorToTag(residual, _current_nl_sys->residualVectorTag());
    7130        3467 :       const auto & residual_vector_tags = getVectorTags(Moose::VECTOR_TAG_RESIDUAL);
    7131             : 
    7132             :       mooseAssert(_fe_vector_tags.empty(),
    7133             :                   "This should be empty indicating a clean starting state");
    7134             :       // We filter out tags which do not have associated vectors in the current nonlinear
    7135             :       // system. This is essential to be able to use system-dependent residual tags.
    7136        3467 :       selectVectorTagsFromSystem(*_current_nl_sys, residual_vector_tags, _fe_vector_tags);
    7137             : 
    7138        3467 :       setCurrentResidualVectorTags(_fe_vector_tags);
    7139             : 
    7140             :       // matrix tags
    7141             :       {
    7142        3467 :         _fe_matrix_tags.clear();
    7143             : 
    7144        3467 :         auto & tags = getMatrixTags();
    7145       10401 :         for (auto & tag : tags)
    7146        6934 :           _fe_matrix_tags.insert(tag.second);
    7147             :       }
    7148             : 
    7149        3467 :       _current_nl_sys->setSolution(soln);
    7150             : 
    7151        3467 :       _current_nl_sys->associateVectorToTag(residual, _current_nl_sys->residualVectorTag());
    7152        3467 :       _current_nl_sys->associateMatrixToTag(jacobian, _current_nl_sys->systemMatrixTag());
    7153             : 
    7154       10401 :       for (const auto tag : _fe_matrix_tags)
    7155        6934 :         if (_current_nl_sys->hasMatrix(tag))
    7156             :         {
    7157        3467 :           auto & matrix = _current_nl_sys->getMatrix(tag);
    7158        3467 :           matrix.zero();
    7159        3467 :           if (haveADObjects() && !_current_nl_sys->system().has_static_condensation())
    7160             :             // PETSc algorithms require diagonal allocations regardless of whether there is non-zero
    7161             :             // diagonal dependence. With global AD indexing we only add non-zero
    7162             :             // dependence, so PETSc will scream at us unless we artificially add the diagonals.
    7163      139927 :             for (auto index : make_range(matrix.row_start(), matrix.row_stop()))
    7164      136580 :               matrix.add(index, index, 0);
    7165             :         }
    7166             : 
    7167        3467 :       _aux->zeroVariablesForResidual();
    7168             : 
    7169        3467 :       unsigned int n_threads = libMesh::n_threads();
    7170             : 
    7171        3467 :       _current_execute_on_flag = EXEC_LINEAR;
    7172             : 
    7173             :       // Random interface objects
    7174        3467 :       for (const auto & it : _random_data_objects)
    7175           0 :         it.second->updateSeeds(EXEC_LINEAR);
    7176             : 
    7177        3467 :       setCurrentlyComputingResidual(true);
    7178        3467 :       setCurrentlyComputingJacobian(true);
    7179        3467 :       setCurrentlyComputingResidualAndJacobian(true);
    7180        3467 :       if (_displaced_problem)
    7181             :       {
    7182        1172 :         _displaced_problem->setCurrentlyComputingResidual(true);
    7183        1172 :         _displaced_problem->setCurrentlyComputingJacobian(true);
    7184        1172 :         _displaced_problem->setCurrentlyComputingResidualAndJacobian(true);
    7185             :       }
    7186             : 
    7187        3467 :       execTransfers(EXEC_LINEAR);
    7188             : 
    7189        3467 :       execMultiApps(EXEC_LINEAR);
    7190             : 
    7191        7273 :       for (unsigned int tid = 0; tid < n_threads; tid++)
    7192        3806 :         reinitScalars(tid);
    7193             : 
    7194        3467 :       computeUserObjects(EXEC_LINEAR, Moose::PRE_AUX);
    7195             : 
    7196        3467 :       _aux->residualSetup();
    7197             : 
    7198        3467 :       if (_displaced_problem)
    7199             :       {
    7200        1172 :         computeSystems(EXEC_PRE_DISPLACE);
    7201        1172 :         _displaced_problem->updateMesh();
    7202        1172 :         if (_mortar_data.hasDisplacedObjects())
    7203        1172 :           updateMortarMesh();
    7204             :       }
    7205             : 
    7206        7273 :       for (THREAD_ID tid = 0; tid < n_threads; tid++)
    7207             :       {
    7208        3806 :         _all_materials.residualSetup(tid);
    7209        3806 :         _functions.residualSetup(tid);
    7210             :       }
    7211             : 
    7212        3467 :       computeSystems(EXEC_LINEAR);
    7213             : 
    7214        3467 :       computeUserObjects(EXEC_LINEAR, Moose::POST_AUX);
    7215             : 
    7216        3467 :       executeControls(EXEC_LINEAR);
    7217             : 
    7218        3467 :       _app.getOutputWarehouse().residualSetup();
    7219             : 
    7220        3467 :       _safe_access_tagged_vectors = false;
    7221        3467 :       _safe_access_tagged_matrices = false;
    7222             : 
    7223        3467 :       _current_nl_sys->computeResidualAndJacobianTags(_fe_vector_tags, _fe_matrix_tags);
    7224             : 
    7225        3467 :       _current_nl_sys->disassociateMatrixFromTag(jacobian, _current_nl_sys->systemMatrixTag());
    7226        3467 :       _current_nl_sys->disassociateVectorFromTag(residual, _current_nl_sys->residualVectorTag());
    7227             :     }
    7228           0 :     catch (...)
    7229             :     {
    7230           0 :       handleException("computeResidualAndJacobian");
    7231           0 :     }
    7232             :   }
    7233           0 :   catch (const MooseException &)
    7234             :   {
    7235             :     // The buck stops here, we have already handled the exception by
    7236             :     // calling the system's stopSolve() method, it is now up to PETSc to return a
    7237             :     // "diverged" reason during the next solve.
    7238           0 :   }
    7239           0 :   catch (...)
    7240             :   {
    7241           0 :     mooseError("Unexpected exception type");
    7242           0 :   }
    7243             : 
    7244        3467 :   resetState();
    7245        3467 :   _fe_vector_tags.clear();
    7246        3467 :   _fe_matrix_tags.clear();
    7247        3467 : }
    7248             : 
    7249             : void
    7250           0 : FEProblemBase::computeResidualTag(const NumericVector<Number> & soln,
    7251             :                                   NumericVector<Number> & residual,
    7252             :                                   TagID tag)
    7253             : {
    7254             :   try
    7255             :   {
    7256           0 :     _current_nl_sys->setSolution(soln);
    7257             : 
    7258           0 :     _current_nl_sys->associateVectorToTag(residual, tag);
    7259             : 
    7260           0 :     computeResidualTags({tag});
    7261             : 
    7262           0 :     _current_nl_sys->disassociateVectorFromTag(residual, tag);
    7263             :   }
    7264           0 :   catch (MooseException & e)
    7265             :   {
    7266             :     // If a MooseException propagates all the way to here, it means
    7267             :     // that it was thrown from a MOOSE system where we do not
    7268             :     // (currently) properly support the throwing of exceptions, and
    7269             :     // therefore we have no choice but to error out.  It may be
    7270             :     // *possible* to handle exceptions from other systems, but in the
    7271             :     // meantime, we don't want to silently swallow any unhandled
    7272             :     // exceptions here.
    7273           0 :     mooseError("An unhandled MooseException was raised during residual computation.  Please "
    7274             :                "contact the MOOSE team for assistance.");
    7275           0 :   }
    7276           0 : }
    7277             : 
    7278             : void
    7279     3299808 : FEProblemBase::computeResidualInternal(const NumericVector<Number> & soln,
    7280             :                                        NumericVector<Number> & residual,
    7281             :                                        const std::set<TagID> & tags)
    7282             : {
    7283             :   parallel_object_only();
    7284             : 
    7285     9899424 :   TIME_SECTION("computeResidualInternal", 1);
    7286             : 
    7287             :   try
    7288             :   {
    7289     3299808 :     _current_nl_sys->setSolution(soln);
    7290             : 
    7291     3299808 :     _current_nl_sys->associateVectorToTag(residual, _current_nl_sys->residualVectorTag());
    7292             : 
    7293     3299808 :     computeResidualTags(tags);
    7294             : 
    7295     3299764 :     _current_nl_sys->disassociateVectorFromTag(residual, _current_nl_sys->residualVectorTag());
    7296             :   }
    7297           0 :   catch (MooseException & e)
    7298             :   {
    7299             :     // If a MooseException propagates all the way to here, it means
    7300             :     // that it was thrown from a MOOSE system where we do not
    7301             :     // (currently) properly support the throwing of exceptions, and
    7302             :     // therefore we have no choice but to error out.  It may be
    7303             :     // *possible* to handle exceptions from other systems, but in the
    7304             :     // meantime, we don't want to silently swallow any unhandled
    7305             :     // exceptions here.
    7306           0 :     mooseError("An unhandled MooseException was raised during residual computation.  Please "
    7307             :                "contact the MOOSE team for assistance.");
    7308           0 :   }
    7309     3299764 : }
    7310             : 
    7311             : void
    7312           0 : FEProblemBase::computeResidualType(const NumericVector<Number> & soln,
    7313             :                                    NumericVector<Number> & residual,
    7314             :                                    TagID tag)
    7315             : {
    7316           0 :   TIME_SECTION("computeResidualType", 5);
    7317             : 
    7318             :   try
    7319             :   {
    7320           0 :     _current_nl_sys->setSolution(soln);
    7321             : 
    7322           0 :     _current_nl_sys->associateVectorToTag(residual, _current_nl_sys->residualVectorTag());
    7323             : 
    7324           0 :     computeResidualTags({tag, _current_nl_sys->residualVectorTag()});
    7325             : 
    7326           0 :     _current_nl_sys->disassociateVectorFromTag(residual, _current_nl_sys->residualVectorTag());
    7327             :   }
    7328           0 :   catch (MooseException & e)
    7329             :   {
    7330             :     // If a MooseException propagates all the way to here, it means
    7331             :     // that it was thrown from a MOOSE system where we do not
    7332             :     // (currently) properly support the throwing of exceptions, and
    7333             :     // therefore we have no choice but to error out.  It may be
    7334             :     // *possible* to handle exceptions from other systems, but in the
    7335             :     // meantime, we don't want to silently swallow any unhandled
    7336             :     // exceptions here.
    7337           0 :     mooseError("An unhandled MooseException was raised during residual computation.  Please "
    7338             :                "contact the MOOSE team for assistance.");
    7339           0 :   }
    7340           0 : }
    7341             : 
    7342             : void
    7343           4 : FEProblemBase::handleException(const std::string & calling_method)
    7344             : {
    7345             :   auto create_exception_message =
    7346           4 :       [&calling_method](const std::string & exception_type, const auto & exception)
    7347             :   {
    7348             :     return std::string("A " + exception_type + " was raised during FEProblemBase::" +
    7349           8 :                        calling_method + "\n" + std::string(exception.what()));
    7350           4 :   };
    7351             : 
    7352             :   try
    7353             :   {
    7354           4 :     throw;
    7355             :   }
    7356           4 :   catch (const libMesh::LogicError & e)
    7357             :   {
    7358           0 :     setException(create_exception_message("libMesh::LogicError", e));
    7359           0 :   }
    7360           0 :   catch (const MooseException & e)
    7361             :   {
    7362           0 :     setException(create_exception_message("MooseException", e));
    7363           0 :   }
    7364           0 :   catch (const MetaPhysicL::LogicError & e)
    7365             :   {
    7366           0 :     moose::translateMetaPhysicLError(e);
    7367           0 :   }
    7368           4 :   catch (const libMesh::PetscSolverException & e)
    7369             :   {
    7370             :     // One PETSc solver exception that we cannot currently recover from are new nonzero errors. In
    7371             :     // particular I have observed the following scenario in a parallel test:
    7372             :     // - Both processes throw because of a new nonzero during MOOSE's computeJacobianTags
    7373             :     // - We potentially handle the exceptions nicely here
    7374             :     // - When the matrix is closed in libMesh's libmesh_petsc_snes_solver, there is a new nonzero
    7375             :     //   throw which we do not catch here in MOOSE and the simulation terminates. This only appears
    7376             :     //   in parallel (and not all the time; a test I was examining threw with distributed mesh, but
    7377             :     //   not with replicated). In serial there are no new throws from libmesh_petsc_snes_solver.
    7378             :     // So for uniformity of behavior across serial/parallel, we will choose to abort here and always
    7379             :     // produce a non-zero exit code
    7380           8 :     mooseError(create_exception_message("libMesh::PetscSolverException", e));
    7381           0 :   }
    7382           0 :   catch (const std::exception & e)
    7383             :   {
    7384           0 :     const auto message = create_exception_message("std::exception", e);
    7385           0 :     if (_regard_general_exceptions_as_errors)
    7386           0 :       mooseError(message);
    7387             :     else
    7388           0 :       setException(message);
    7389           0 :   }
    7390             : 
    7391           0 :   checkExceptionAndStopSolve();
    7392           0 : }
    7393             : 
    7394             : void
    7395     3335851 : FEProblemBase::computeResidualTags(const std::set<TagID> & tags)
    7396             : {
    7397             :   parallel_object_only();
    7398             : 
    7399             :   try
    7400             :   {
    7401             :     try
    7402             :     {
    7403    16679255 :       TIME_SECTION("computeResidualTags", 5, "Computing Residual");
    7404             : 
    7405     3335851 :       ADReal::do_derivatives = false;
    7406             : 
    7407     3335851 :       setCurrentResidualVectorTags(tags);
    7408             : 
    7409     3335851 :       _aux->zeroVariablesForResidual();
    7410             : 
    7411     3335851 :       unsigned int n_threads = libMesh::n_threads();
    7412             : 
    7413     3335851 :       _current_execute_on_flag = EXEC_LINEAR;
    7414             : 
    7415             :       // Random interface objects
    7416     3351634 :       for (const auto & it : _random_data_objects)
    7417       15783 :         it.second->updateSeeds(EXEC_LINEAR);
    7418             : 
    7419     3335851 :       execTransfers(EXEC_LINEAR);
    7420             : 
    7421     3335851 :       execMultiApps(EXEC_LINEAR);
    7422             : 
    7423     6971049 :       for (unsigned int tid = 0; tid < n_threads; tid++)
    7424     3635198 :         reinitScalars(tid);
    7425             : 
    7426     3335851 :       computeUserObjects(EXEC_LINEAR, Moose::PRE_AUX);
    7427             : 
    7428     3335851 :       _aux->residualSetup();
    7429             : 
    7430     3335851 :       if (_displaced_problem)
    7431             :       {
    7432      136012 :         computeSystems(EXEC_PRE_DISPLACE);
    7433      136012 :         _displaced_problem->updateMesh();
    7434      136012 :         if (_mortar_data.hasDisplacedObjects())
    7435        2429 :           updateMortarMesh();
    7436             :       }
    7437             : 
    7438     6971049 :       for (THREAD_ID tid = 0; tid < n_threads; tid++)
    7439             :       {
    7440     3635198 :         _all_materials.residualSetup(tid);
    7441     3635198 :         _functions.residualSetup(tid);
    7442             :       }
    7443             : 
    7444     3335851 :       computeSystems(EXEC_LINEAR);
    7445             : 
    7446     3335851 :       computeUserObjects(EXEC_LINEAR, Moose::POST_AUX);
    7447             : 
    7448     3335851 :       executeControls(EXEC_LINEAR);
    7449             : 
    7450     3335851 :       _app.getOutputWarehouse().residualSetup();
    7451             : 
    7452     3335851 :       _safe_access_tagged_vectors = false;
    7453     3335851 :       _current_nl_sys->computeResidualTags(tags);
    7454     3335807 :     }
    7455           0 :     catch (...)
    7456             :     {
    7457           0 :       handleException("computeResidualTags");
    7458           0 :     }
    7459             :   }
    7460           0 :   catch (const MooseException &)
    7461             :   {
    7462             :     // The buck stops here, we have already handled the exception by
    7463             :     // calling the system's stopSolve() method, it is now up to PETSc to return a
    7464             :     // "diverged" reason during the next solve.
    7465           0 :   }
    7466           0 :   catch (...)
    7467             :   {
    7468           0 :     mooseError("Unexpected exception type");
    7469           0 :   }
    7470             : 
    7471     3335807 :   resetState();
    7472     3335807 : }
    7473             : 
    7474             : void
    7475      525320 : FEProblemBase::computeJacobianSys(NonlinearImplicitSystem & sys,
    7476             :                                   const NumericVector<Number> & soln,
    7477             :                                   SparseMatrix<Number> & jacobian)
    7478             : {
    7479      525320 :   computeJacobian(soln, jacobian, sys.number());
    7480      525300 : }
    7481             : 
    7482             : void
    7483        4863 : FEProblemBase::computeJacobianTag(const NumericVector<Number> & soln,
    7484             :                                   SparseMatrix<Number> & jacobian,
    7485             :                                   TagID tag)
    7486             : {
    7487        4863 :   _current_nl_sys->setSolution(soln);
    7488             : 
    7489        4863 :   _current_nl_sys->associateMatrixToTag(jacobian, tag);
    7490             : 
    7491        9726 :   computeJacobianTags({tag});
    7492             : 
    7493        4863 :   _current_nl_sys->disassociateMatrixFromTag(jacobian, tag);
    7494        4863 : }
    7495             : 
    7496             : void
    7497      524488 : FEProblemBase::computeJacobian(const NumericVector<Number> & soln,
    7498             :                                SparseMatrix<Number> & jacobian,
    7499             :                                const unsigned int nl_sys_num)
    7500             : {
    7501      524488 :   setCurrentNonlinearSystem(nl_sys_num);
    7502             : 
    7503      524488 :   _fe_matrix_tags.clear();
    7504             : 
    7505      524488 :   auto & tags = getMatrixTags();
    7506     1573736 :   for (auto & tag : tags)
    7507     1049248 :     _fe_matrix_tags.insert(tag.second);
    7508             : 
    7509      524488 :   computeJacobianInternal(soln, jacobian, _fe_matrix_tags);
    7510      524468 : }
    7511             : 
    7512             : void
    7513      524488 : FEProblemBase::computeJacobianInternal(const NumericVector<Number> & soln,
    7514             :                                        SparseMatrix<Number> & jacobian,
    7515             :                                        const std::set<TagID> & tags)
    7516             : {
    7517     1573464 :   TIME_SECTION("computeJacobianInternal", 1);
    7518             : 
    7519      524488 :   _current_nl_sys->setSolution(soln);
    7520             : 
    7521      524488 :   _current_nl_sys->associateMatrixToTag(jacobian, _current_nl_sys->systemMatrixTag());
    7522             : 
    7523      524488 :   computeJacobianTags(tags);
    7524             : 
    7525      524468 :   _current_nl_sys->disassociateMatrixFromTag(jacobian, _current_nl_sys->systemMatrixTag());
    7526      524468 : }
    7527             : 
    7528             : void
    7529      534283 : FEProblemBase::computeJacobianTags(const std::set<TagID> & tags)
    7530             : {
    7531             :   try
    7532             :   {
    7533             :     try
    7534             :     {
    7535      534283 :       if (!_has_jacobian || !_const_jacobian)
    7536             :       {
    7537     2635650 :         TIME_SECTION("computeJacobianTags", 5, "Computing Jacobian");
    7538             : 
    7539     1573583 :         for (auto tag : tags)
    7540     1046453 :           if (_current_nl_sys->hasMatrix(tag))
    7541             :           {
    7542      529118 :             auto & matrix = _current_nl_sys->getMatrix(tag);
    7543      529118 :             if (_restore_original_nonzero_pattern)
    7544        8195 :               matrix.restore_original_nonzero_pattern();
    7545             :             else
    7546      520923 :               matrix.zero();
    7547      529118 :             if (haveADObjects() && !_current_nl_sys->system().has_static_condensation())
    7548             :               // PETSc algorithms require diagonal allocations regardless of whether there is
    7549             :               // non-zero diagonal dependence. With global AD indexing we only add non-zero
    7550             :               // dependence, so PETSc will scream at us unless we artificially add the diagonals.
    7551     8312083 :               for (auto index : make_range(matrix.row_start(), matrix.row_stop()))
    7552     8254004 :                 matrix.add(index, index, 0);
    7553             :           }
    7554             : 
    7555      527130 :         _aux->zeroVariablesForJacobian();
    7556             : 
    7557      527130 :         unsigned int n_threads = libMesh::n_threads();
    7558             : 
    7559             :         // Random interface objects
    7560      529638 :         for (const auto & it : _random_data_objects)
    7561        2508 :           it.second->updateSeeds(EXEC_NONLINEAR);
    7562             : 
    7563      527130 :         _current_execute_on_flag = EXEC_NONLINEAR;
    7564      527130 :         _currently_computing_jacobian = true;
    7565      527130 :         if (_displaced_problem)
    7566       23348 :           _displaced_problem->setCurrentlyComputingJacobian(true);
    7567             : 
    7568      527130 :         execTransfers(EXEC_NONLINEAR);
    7569      527130 :         execMultiApps(EXEC_NONLINEAR);
    7570             : 
    7571     1103004 :         for (unsigned int tid = 0; tid < n_threads; tid++)
    7572      575874 :           reinitScalars(tid);
    7573             : 
    7574      527130 :         computeUserObjects(EXEC_NONLINEAR, Moose::PRE_AUX);
    7575             : 
    7576      527130 :         _aux->jacobianSetup();
    7577             : 
    7578      527130 :         if (_displaced_problem)
    7579             :         {
    7580       23348 :           computeSystems(EXEC_PRE_DISPLACE);
    7581       23348 :           _displaced_problem->updateMesh();
    7582             :         }
    7583             : 
    7584     1102995 :         for (unsigned int tid = 0; tid < n_threads; tid++)
    7585             :         {
    7586      575869 :           _all_materials.jacobianSetup(tid);
    7587      575869 :           _functions.jacobianSetup(tid);
    7588             :         }
    7589             : 
    7590      527126 :         computeSystems(EXEC_NONLINEAR);
    7591             : 
    7592      527126 :         computeUserObjects(EXEC_NONLINEAR, Moose::POST_AUX);
    7593             : 
    7594      527126 :         executeControls(EXEC_NONLINEAR);
    7595             : 
    7596      527126 :         _app.getOutputWarehouse().jacobianSetup();
    7597             : 
    7598      527126 :         _safe_access_tagged_matrices = false;
    7599             : 
    7600      527126 :         _current_nl_sys->computeJacobianTags(tags);
    7601             : 
    7602             :         // For explicit Euler calculations for example we often compute the Jacobian one time and
    7603             :         // then re-use it over and over. If we're performing automatic scaling, we don't want to
    7604             :         // use that kernel, diagonal-block only Jacobian for our actual matrix when performing
    7605             :         // solves!
    7606      527110 :         if (!_current_nl_sys->computingScalingJacobian())
    7607      526508 :           _has_jacobian = true;
    7608      527114 :       }
    7609             :     }
    7610           4 :     catch (...)
    7611             :     {
    7612           4 :       handleException("computeJacobianTags");
    7613           0 :     }
    7614             :   }
    7615           0 :   catch (const MooseException &)
    7616             :   {
    7617             :     // The buck stops here, we have already handled the exception by
    7618             :     // calling the system's stopSolve() method, it is now up to PETSc to return a
    7619             :     // "diverged" reason during the next solve.
    7620           0 :   }
    7621           0 :   catch (...)
    7622             :   {
    7623           0 :     mooseError("Unexpected exception type");
    7624           0 :   }
    7625             : 
    7626      534263 :   resetState();
    7627      534263 : }
    7628             : 
    7629             : void
    7630         302 : FEProblemBase::computeJacobianBlocks(std::vector<JacobianBlock *> & blocks,
    7631             :                                      const unsigned int nl_sys_num)
    7632             : {
    7633         906 :   TIME_SECTION("computeTransientImplicitJacobian", 2);
    7634         302 :   setCurrentNonlinearSystem(nl_sys_num);
    7635             : 
    7636         302 :   if (_displaced_problem)
    7637             :   {
    7638           0 :     computeSystems(EXEC_PRE_DISPLACE);
    7639           0 :     _displaced_problem->updateMesh();
    7640             :   }
    7641             : 
    7642         302 :   computeSystems(EXEC_NONLINEAR);
    7643             : 
    7644         302 :   _currently_computing_jacobian = true;
    7645         302 :   _current_nl_sys->computeJacobianBlocks(blocks);
    7646         302 :   _currently_computing_jacobian = false;
    7647         302 : }
    7648             : 
    7649             : void
    7650           0 : FEProblemBase::computeJacobianBlock(SparseMatrix<Number> & jacobian,
    7651             :                                     libMesh::System & precond_system,
    7652             :                                     unsigned int ivar,
    7653             :                                     unsigned int jvar)
    7654             : {
    7655           0 :   JacobianBlock jac_block(precond_system, jacobian, ivar, jvar);
    7656           0 :   std::vector<JacobianBlock *> blocks = {&jac_block};
    7657             :   mooseAssert(_current_nl_sys, "This should be non-null");
    7658           0 :   computeJacobianBlocks(blocks, _current_nl_sys->number());
    7659           0 : }
    7660             : 
    7661             : void
    7662         778 : FEProblemBase::computeBounds(NonlinearImplicitSystem & libmesh_dbg_var(sys),
    7663             :                              NumericVector<Number> & lower,
    7664             :                              NumericVector<Number> & upper)
    7665             : {
    7666             :   try
    7667             :   {
    7668             :     try
    7669             :     {
    7670             :       mooseAssert(_current_nl_sys && (sys.number() == _current_nl_sys->number()),
    7671             :                   "I expect these system numbers to be the same");
    7672             : 
    7673        3890 :       if (!_current_nl_sys->hasVector("lower_bound") || !_current_nl_sys->hasVector("upper_bound"))
    7674           0 :         return;
    7675             : 
    7676        3890 :       TIME_SECTION("computeBounds", 1, "Computing Bounds");
    7677             : 
    7678        1556 :       NumericVector<Number> & _lower = _current_nl_sys->getVector("lower_bound");
    7679        1556 :       NumericVector<Number> & _upper = _current_nl_sys->getVector("upper_bound");
    7680         778 :       _lower.swap(lower);
    7681         778 :       _upper.swap(upper);
    7682        1620 :       for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
    7683         842 :         _all_materials.residualSetup(tid);
    7684             : 
    7685         778 :       _aux->residualSetup();
    7686         778 :       computeSystems(EXEC_LINEAR);
    7687         778 :       _lower.swap(lower);
    7688         778 :       _upper.swap(upper);
    7689         778 :     }
    7690           0 :     catch (...)
    7691             :     {
    7692           0 :       handleException("computeBounds");
    7693           0 :     }
    7694             :   }
    7695           0 :   catch (MooseException & e)
    7696             :   {
    7697           0 :     mooseError("Irrecoverable exception: " + std::string(e.what()));
    7698           0 :   }
    7699           0 :   catch (...)
    7700             :   {
    7701           0 :     mooseError("Unexpected exception type");
    7702           0 :   }
    7703             : }
    7704             : 
    7705             : void
    7706        5738 : FEProblemBase::computeLinearSystemSys(LinearImplicitSystem & sys,
    7707             :                                       SparseMatrix<Number> & system_matrix,
    7708             :                                       NumericVector<Number> & rhs,
    7709             :                                       const bool compute_gradients)
    7710             : {
    7711       17214 :   TIME_SECTION("computeLinearSystemSys", 5);
    7712             : 
    7713        5738 :   setCurrentLinearSystem(linearSysNum(sys.name()));
    7714             : 
    7715        5738 :   _current_linear_sys->associateVectorToTag(rhs, _current_linear_sys->rightHandSideVectorTag());
    7716        5738 :   _current_linear_sys->associateMatrixToTag(system_matrix, _current_linear_sys->systemMatrixTag());
    7717             : 
    7718             :   // We are using the residual tag system for right hand sides so we fetch everything
    7719        5738 :   const auto & vector_tags = getVectorTags(Moose::VECTOR_TAG_RESIDUAL);
    7720             : 
    7721             :   // We filter out tags which do not have associated vectors in the current
    7722             :   // system. This is essential to be able to use system-dependent vector tags.
    7723        5738 :   selectVectorTagsFromSystem(*_current_linear_sys, vector_tags, _linear_vector_tags);
    7724        5738 :   selectMatrixTagsFromSystem(*_current_linear_sys, getMatrixTags(), _linear_matrix_tags);
    7725             : 
    7726        5738 :   computeLinearSystemTags(*(_current_linear_sys->currentSolution()),
    7727        5738 :                           _linear_vector_tags,
    7728        5738 :                           _linear_matrix_tags,
    7729             :                           compute_gradients);
    7730             : 
    7731        5738 :   _current_linear_sys->disassociateMatrixFromTag(system_matrix,
    7732        5738 :                                                  _current_linear_sys->systemMatrixTag());
    7733        5738 :   _current_linear_sys->disassociateVectorFromTag(rhs,
    7734        5738 :                                                  _current_linear_sys->rightHandSideVectorTag());
    7735             :   // We reset the tags to the default containers for further operations
    7736        5738 :   _current_linear_sys->associateVectorToTag(_current_linear_sys->getRightHandSideVector(),
    7737        5738 :                                             _current_linear_sys->rightHandSideVectorTag());
    7738        5738 :   _current_linear_sys->associateMatrixToTag(_current_linear_sys->getSystemMatrix(),
    7739        5738 :                                             _current_linear_sys->systemMatrixTag());
    7740        5738 : }
    7741             : 
    7742             : void
    7743        5738 : FEProblemBase::computeLinearSystemTags(const NumericVector<Number> & soln,
    7744             :                                        const std::set<TagID> & vector_tags,
    7745             :                                        const std::set<TagID> & matrix_tags,
    7746             :                                        const bool compute_gradients)
    7747             : {
    7748       28690 :   TIME_SECTION("computeLinearSystemTags", 5, "Computing Linear System");
    7749             : 
    7750        5738 :   _current_linear_sys->setSolution(soln);
    7751             : 
    7752       11500 :   for (auto tag : matrix_tags)
    7753             :   {
    7754        5762 :     auto & matrix = _current_linear_sys->getMatrix(tag);
    7755        5762 :     matrix.zero();
    7756             :   }
    7757             : 
    7758        5738 :   unsigned int n_threads = libMesh::n_threads();
    7759             : 
    7760        5738 :   _current_execute_on_flag = EXEC_NONLINEAR;
    7761             : 
    7762             :   // Random interface objects
    7763        5738 :   for (const auto & it : _random_data_objects)
    7764           0 :     it.second->updateSeeds(EXEC_NONLINEAR);
    7765             : 
    7766        5738 :   execTransfers(EXEC_NONLINEAR);
    7767        5738 :   execMultiApps(EXEC_NONLINEAR);
    7768             : 
    7769        5738 :   computeUserObjects(EXEC_NONLINEAR, Moose::PRE_AUX);
    7770             : 
    7771        5738 :   _aux->jacobianSetup();
    7772             : 
    7773       11476 :   for (THREAD_ID tid = 0; tid < n_threads; tid++)
    7774             :   {
    7775        5738 :     _functions.jacobianSetup(tid);
    7776             :   }
    7777             : 
    7778             :   try
    7779             :   {
    7780        5738 :     computeSystems(EXEC_NONLINEAR);
    7781             :   }
    7782           0 :   catch (MooseException & e)
    7783             :   {
    7784           0 :     _console << "\nA MooseException was raised during Auxiliary variable computation.\n"
    7785           0 :              << "The next solve will fail, the timestep will be reduced, and we will try again.\n"
    7786           0 :              << std::endl;
    7787             : 
    7788             :     // We know the next solve is going to fail, so there's no point in
    7789             :     // computing anything else after this.  Plus, using incompletely
    7790             :     // computed AuxVariables in subsequent calculations could lead to
    7791             :     // other errors or unhandled exceptions being thrown.
    7792           0 :     return;
    7793           0 :   }
    7794             : 
    7795        5738 :   computeUserObjects(EXEC_NONLINEAR, Moose::POST_AUX);
    7796        5738 :   executeControls(EXEC_NONLINEAR);
    7797             : 
    7798        5738 :   _app.getOutputWarehouse().jacobianSetup();
    7799             : 
    7800        5738 :   _current_linear_sys->computeLinearSystemTags(vector_tags, matrix_tags, compute_gradients);
    7801             : 
    7802             :   // Reset execution flag as after this point we are no longer on LINEAR
    7803        5738 :   _current_execute_on_flag = EXEC_NONE;
    7804             : 
    7805             :   // These are the relevant parts of resetState()
    7806        5738 :   _safe_access_tagged_vectors = true;
    7807        5738 :   _safe_access_tagged_matrices = true;
    7808        5738 : }
    7809             : 
    7810             : void
    7811      324273 : FEProblemBase::computeNearNullSpace(NonlinearImplicitSystem & libmesh_dbg_var(sys),
    7812             :                                     std::vector<NumericVector<Number> *> & sp)
    7813             : {
    7814             :   mooseAssert(_current_nl_sys && (sys.number() == _current_nl_sys->number()),
    7815             :               "I expect these system numbers to be the same");
    7816             : 
    7817      324273 :   sp.clear();
    7818      972819 :   for (unsigned int i = 0; i < subspaceDim("NearNullSpace"); ++i)
    7819             :   {
    7820           0 :     std::stringstream postfix;
    7821           0 :     postfix << "_" << i;
    7822           0 :     std::string modename = "NearNullSpace" + postfix.str();
    7823           0 :     sp.push_back(&_current_nl_sys->getVector(modename));
    7824           0 :   }
    7825      324273 : }
    7826             : 
    7827             : void
    7828      324273 : FEProblemBase::computeNullSpace(NonlinearImplicitSystem & libmesh_dbg_var(sys),
    7829             :                                 std::vector<NumericVector<Number> *> & sp)
    7830             : {
    7831             :   mooseAssert(_current_nl_sys && (sys.number() == _current_nl_sys->number()),
    7832             :               "I expect these system numbers to be the same");
    7833      324273 :   sp.clear();
    7834      972891 :   for (unsigned int i = 0; i < subspaceDim("NullSpace"); ++i)
    7835             :   {
    7836          24 :     std::stringstream postfix;
    7837          24 :     postfix << "_" << i;
    7838          24 :     sp.push_back(&_current_nl_sys->getVector("NullSpace" + postfix.str()));
    7839          24 :   }
    7840      324273 : }
    7841             : 
    7842             : void
    7843      324273 : FEProblemBase::computeTransposeNullSpace(NonlinearImplicitSystem & libmesh_dbg_var(sys),
    7844             :                                          std::vector<NumericVector<Number> *> & sp)
    7845             : {
    7846             :   mooseAssert(_current_nl_sys && (sys.number() == _current_nl_sys->number()),
    7847             :               "I expect these system numbers to be the same");
    7848      324273 :   sp.clear();
    7849      972855 :   for (unsigned int i = 0; i < subspaceDim("TransposeNullSpace"); ++i)
    7850             :   {
    7851          12 :     std::stringstream postfix;
    7852          12 :     postfix << "_" << i;
    7853          12 :     sp.push_back(&_current_nl_sys->getVector("TransposeNullSpace" + postfix.str()));
    7854          12 :   }
    7855      324273 : }
    7856             : 
    7857             : void
    7858        1976 : FEProblemBase::computePostCheck(NonlinearImplicitSystem & sys,
    7859             :                                 const NumericVector<Number> & old_soln,
    7860             :                                 NumericVector<Number> & search_direction,
    7861             :                                 NumericVector<Number> & new_soln,
    7862             :                                 bool & changed_search_direction,
    7863             :                                 bool & changed_new_soln)
    7864             : {
    7865             :   mooseAssert(_current_nl_sys && (sys.number() == _current_nl_sys->number()),
    7866             :               "I expect these system numbers to be the same");
    7867             : 
    7868             :   // This function replaces the old PetscSupport::dampedCheck() function.
    7869             :   //
    7870             :   // 1.) Recreate code in PetscSupport::dampedCheck() for constructing
    7871             :   //     ghosted "soln" and "update" vectors.
    7872             :   // 2.) Call FEProblemBase::computeDamping() with these ghost vectors.
    7873             :   // 3.) Recreate the code in PetscSupport::dampedCheck() to actually update
    7874             :   //     the solution vector based on the damping, and set the "changed" flags
    7875             :   //     appropriately.
    7876             : 
    7877        9880 :   TIME_SECTION("computePostCheck", 2, "Computing Post Check");
    7878             : 
    7879        1976 :   _current_execute_on_flag = EXEC_POSTCHECK;
    7880             : 
    7881             :   // MOOSE's FEProblemBase doesn't update the solution during the
    7882             :   // postcheck, but FEProblemBase-derived classes might.
    7883        1976 :   if (_has_dampers || shouldUpdateSolution())
    7884             :   {
    7885             :     // We need ghosted versions of new_soln and search_direction (the
    7886             :     // ones we get from libmesh/PETSc are PARALLEL vectors.  To make
    7887             :     // our lives simpler, we use the same ghosting pattern as the
    7888             :     // system's current_local_solution to create new ghosted vectors.
    7889             : 
    7890             :     // Construct zeroed-out clones with the same ghosted dofs as the
    7891             :     // System's current_local_solution.
    7892             :     std::unique_ptr<NumericVector<Number>> ghosted_solution =
    7893        1420 :                                                sys.current_local_solution->zero_clone(),
    7894             :                                            ghosted_search_direction =
    7895        1420 :                                                sys.current_local_solution->zero_clone();
    7896             : 
    7897             :     // Copy values from input vectors into clones with ghosted values.
    7898        1420 :     *ghosted_solution = new_soln;
    7899        1420 :     *ghosted_search_direction = search_direction;
    7900             : 
    7901        1420 :     if (_has_dampers)
    7902             :     {
    7903             :       // Compute the damping coefficient using the ghosted vectors
    7904        1420 :       Real damping = computeDamping(*ghosted_solution, *ghosted_search_direction);
    7905             : 
    7906             :       // If some non-trivial damping was computed, update the new_soln
    7907             :       // vector accordingly.
    7908        1420 :       if (damping < 1.0)
    7909             :       {
    7910         995 :         new_soln = old_soln;
    7911         995 :         new_soln.add(-damping, search_direction);
    7912         995 :         changed_new_soln = true;
    7913             :       }
    7914             :     }
    7915             : 
    7916        1420 :     if (shouldUpdateSolution())
    7917             :     {
    7918             :       // Update the ghosted copy of the new solution, if necessary.
    7919           0 :       if (changed_new_soln)
    7920           0 :         *ghosted_solution = new_soln;
    7921             : 
    7922           0 :       bool updated_solution = updateSolution(new_soln, *ghosted_solution);
    7923           0 :       if (updated_solution)
    7924           0 :         changed_new_soln = true;
    7925             :     }
    7926        1420 :   }
    7927             : 
    7928        1976 :   if (vectorTagExists(Moose::PREVIOUS_NL_SOLUTION_TAG))
    7929             :   {
    7930         556 :     _current_nl_sys->setPreviousNewtonSolution(old_soln);
    7931         556 :     _aux->copyCurrentIntoPreviousNL();
    7932             :   }
    7933             : 
    7934             :   // MOOSE doesn't change the search_direction
    7935        1976 :   changed_search_direction = false;
    7936             : 
    7937        1976 :   _current_execute_on_flag = EXEC_NONE;
    7938        1976 : }
    7939             : 
    7940             : Real
    7941        1420 : FEProblemBase::computeDamping(const NumericVector<Number> & soln,
    7942             :                               const NumericVector<Number> & update)
    7943             : {
    7944             :   // Default to no damping
    7945        1420 :   Real damping = 1.0;
    7946             : 
    7947        1420 :   if (_has_dampers)
    7948             :   {
    7949        7100 :     TIME_SECTION("computeDamping", 1, "Computing Damping");
    7950             : 
    7951             :     // Save pointer to the current solution
    7952        1420 :     const NumericVector<Number> * _saved_current_solution = _current_nl_sys->currentSolution();
    7953             : 
    7954        1420 :     _current_nl_sys->setSolution(soln);
    7955             :     // For now, do not re-compute auxiliary variables.  Doing so allows a wild solution increment
    7956             :     //   to get to the material models, which may not be able to cope with drastically different
    7957             :     //   values.  Once more complete dependency checking is in place, auxiliary variables (and
    7958             :     //   material properties) will be computed as needed by dampers.
    7959             :     //    _aux.compute();
    7960        1420 :     damping = _current_nl_sys->computeDamping(soln, update);
    7961             : 
    7962             :     // restore saved solution
    7963        1420 :     _current_nl_sys->setSolution(*_saved_current_solution);
    7964        1420 :   }
    7965             : 
    7966        1420 :   return damping;
    7967             : }
    7968             : 
    7969             : bool
    7970      317921 : FEProblemBase::shouldUpdateSolution()
    7971             : {
    7972      317921 :   return false;
    7973             : }
    7974             : 
    7975             : bool
    7976           0 : FEProblemBase::updateSolution(NumericVector<Number> & /*vec_solution*/,
    7977             :                               NumericVector<Number> & /*ghosted_solution*/)
    7978             : {
    7979           0 :   return false;
    7980             : }
    7981             : 
    7982             : void
    7983         223 : FEProblemBase::predictorCleanup(NumericVector<Number> & /*ghosted_solution*/)
    7984             : {
    7985         223 : }
    7986             : 
    7987             : void
    7988        2246 : FEProblemBase::addDisplacedProblem(std::shared_ptr<DisplacedProblem> displaced_problem)
    7989             : {
    7990             :   parallel_object_only();
    7991             : 
    7992        2246 :   _displaced_mesh = &displaced_problem->mesh();
    7993        2246 :   _displaced_problem = displaced_problem;
    7994        2246 : }
    7995             : 
    7996             : void
    7997      124345 : FEProblemBase::updateGeomSearch(GeometricSearchData::GeometricSearchType type)
    7998             : {
    7999      621725 :   TIME_SECTION("updateGeometricSearch", 3, "Updating Geometric Search");
    8000             : 
    8001      124345 :   _geometric_search_data.update(type);
    8002             : 
    8003      124345 :   if (_displaced_problem)
    8004        4669 :     _displaced_problem->updateGeomSearch(type);
    8005      124345 : }
    8006             : 
    8007             : void
    8008       73799 : FEProblemBase::updateMortarMesh()
    8009             : {
    8010      368995 :   TIME_SECTION("updateMortarMesh", 5, "Updating Mortar Mesh");
    8011             : 
    8012       73799 :   FloatingPointExceptionGuard fpe_guard(_app);
    8013             : 
    8014       73799 :   _mortar_data.update();
    8015       73799 : }
    8016             : 
    8017             : void
    8018        1448 : FEProblemBase::createMortarInterface(
    8019             :     const std::pair<BoundaryID, BoundaryID> & primary_secondary_boundary_pair,
    8020             :     const std::pair<SubdomainID, SubdomainID> & primary_secondary_subdomain_pair,
    8021             :     bool on_displaced,
    8022             :     bool periodic,
    8023             :     const bool debug,
    8024             :     const bool correct_edge_dropping,
    8025             :     const Real minimum_projection_angle)
    8026             : {
    8027        1448 :   _has_mortar = true;
    8028             : 
    8029        1448 :   if (on_displaced)
    8030         138 :     return _mortar_data.createMortarInterface(primary_secondary_boundary_pair,
    8031             :                                               primary_secondary_subdomain_pair,
    8032         138 :                                               *_displaced_problem,
    8033             :                                               on_displaced,
    8034             :                                               periodic,
    8035             :                                               debug,
    8036             :                                               correct_edge_dropping,
    8037         138 :                                               minimum_projection_angle);
    8038             :   else
    8039        1310 :     return _mortar_data.createMortarInterface(primary_secondary_boundary_pair,
    8040             :                                               primary_secondary_subdomain_pair,
    8041             :                                               *this,
    8042             :                                               on_displaced,
    8043             :                                               periodic,
    8044             :                                               debug,
    8045             :                                               correct_edge_dropping,
    8046        1310 :                                               minimum_projection_angle);
    8047             : }
    8048             : 
    8049             : const AutomaticMortarGeneration &
    8050           0 : FEProblemBase::getMortarInterface(
    8051             :     const std::pair<BoundaryID, BoundaryID> & primary_secondary_boundary_pair,
    8052             :     const std::pair<SubdomainID, SubdomainID> & primary_secondary_subdomain_pair,
    8053             :     bool on_displaced) const
    8054             : {
    8055           0 :   return _mortar_data.getMortarInterface(
    8056           0 :       primary_secondary_boundary_pair, primary_secondary_subdomain_pair, on_displaced);
    8057             : }
    8058             : 
    8059             : AutomaticMortarGeneration &
    8060      258234 : FEProblemBase::getMortarInterface(
    8061             :     const std::pair<BoundaryID, BoundaryID> & primary_secondary_boundary_pair,
    8062             :     const std::pair<SubdomainID, SubdomainID> & primary_secondary_subdomain_pair,
    8063             :     bool on_displaced)
    8064             : {
    8065      258234 :   return _mortar_data.getMortarInterface(
    8066      258234 :       primary_secondary_boundary_pair, primary_secondary_subdomain_pair, on_displaced);
    8067             : }
    8068             : 
    8069             : const std::unordered_map<std::pair<BoundaryID, BoundaryID>, AutomaticMortarGeneration> &
    8070      121028 : FEProblemBase::getMortarInterfaces(bool on_displaced) const
    8071             : {
    8072      121028 :   return _mortar_data.getMortarInterfaces(on_displaced);
    8073             : }
    8074             : 
    8075             : void
    8076      347664 : FEProblemBase::possiblyRebuildGeomSearchPatches()
    8077             : {
    8078      347664 :   if (_displaced_problem) // Only need to do this if things are moving...
    8079             :   {
    8080      179345 :     TIME_SECTION("possiblyRebuildGeomSearchPatches", 5, "Rebuilding Geometric Search Patches");
    8081             : 
    8082       35869 :     switch (_mesh.getPatchUpdateStrategy())
    8083             :     {
    8084       34675 :       case Moose::Never:
    8085       34675 :         break;
    8086         398 :       case Moose::Iteration:
    8087             :         // Update the list of ghosted elements at the start of the time step
    8088         398 :         _geometric_search_data.updateGhostedElems();
    8089         398 :         _mesh.updateActiveSemiLocalNodeRange(_ghosted_elems);
    8090             : 
    8091         398 :         _displaced_problem->geomSearchData().updateGhostedElems();
    8092         398 :         _displaced_mesh->updateActiveSemiLocalNodeRange(_ghosted_elems);
    8093             : 
    8094             :         // The commands below ensure that the sparsity of the Jacobian matrix is
    8095             :         // augmented at the start of the time step using neighbor nodes from the end
    8096             :         // of the previous time step.
    8097             : 
    8098         398 :         reinitBecauseOfGhostingOrNewGeomObjects();
    8099             : 
    8100             :         // This is needed to reinitialize PETSc output
    8101         398 :         initPetscOutputAndSomeSolverSettings();
    8102             : 
    8103         398 :         break;
    8104             : 
    8105         361 :       case Moose::Auto:
    8106             :       {
    8107         361 :         Real max = _displaced_problem->geomSearchData().maxPatchPercentage();
    8108         361 :         _communicator.max(max);
    8109             : 
    8110             :         // If we haven't moved very far through the patch
    8111         361 :         if (max < 0.4)
    8112         325 :           break;
    8113             :       }
    8114             :         libmesh_fallthrough();
    8115             : 
    8116             :       // Let this fall through if things do need to be updated...
    8117             :       case Moose::Always:
    8118             :         // Flush output here to see the message before the reinitialization, which could take a
    8119             :         // while
    8120         471 :         _console << "\n\nUpdating geometric search patches\n" << std::endl;
    8121             : 
    8122         471 :         _geometric_search_data.clearNearestNodeLocators();
    8123         471 :         _mesh.updateActiveSemiLocalNodeRange(_ghosted_elems);
    8124             : 
    8125         471 :         _displaced_problem->geomSearchData().clearNearestNodeLocators();
    8126         471 :         _displaced_mesh->updateActiveSemiLocalNodeRange(_ghosted_elems);
    8127             : 
    8128         471 :         reinitBecauseOfGhostingOrNewGeomObjects();
    8129             : 
    8130             :         // This is needed to reinitialize PETSc output
    8131         471 :         initPetscOutputAndSomeSolverSettings();
    8132             :     }
    8133       35869 :   }
    8134      347664 : }
    8135             : 
    8136             : #ifdef LIBMESH_ENABLE_AMR
    8137             : void
    8138       57567 : FEProblemBase::initialAdaptMesh()
    8139             : {
    8140       57567 :   unsigned int n = adaptivity().getInitialSteps();
    8141       57567 :   _cycles_completed = 0;
    8142       57567 :   if (n)
    8143             :   {
    8144         695 :     if (!_mesh.interiorLowerDBlocks().empty() || !_mesh.boundaryLowerDBlocks().empty())
    8145           4 :       mooseError("HFEM does not support mesh adaptivity currently.");
    8146             : 
    8147        3455 :     TIME_SECTION("initialAdaptMesh", 2, "Performing Initial Adaptivity");
    8148             : 
    8149        1667 :     for (unsigned int i = 0; i < n; i++)
    8150             :     {
    8151        1169 :       computeIndicators();
    8152        1169 :       computeMarkers();
    8153             : 
    8154        1169 :       if (_adaptivity.initialAdaptMesh())
    8155             :       {
    8156         976 :         meshChanged(
    8157             :             /*intermediate_change=*/false, /*contract_mesh=*/true, /*clean_refinement_flags=*/true);
    8158             : 
    8159             :         // reproject the initial condition
    8160         976 :         projectSolution();
    8161             : 
    8162         976 :         _cycles_completed++;
    8163             :       }
    8164             :       else
    8165             :       {
    8166         193 :         _console << "Mesh unchanged, skipping remaining steps..." << std::endl;
    8167         193 :         return;
    8168             :       }
    8169             :     }
    8170         691 :   }
    8171             : }
    8172             : 
    8173             : bool
    8174      181980 : FEProblemBase::adaptMesh()
    8175             : {
    8176             :   // reset cycle counter
    8177      181980 :   _cycles_completed = 0;
    8178             : 
    8179      181980 :   if (!_adaptivity.isAdaptivityDue())
    8180      177044 :     return false;
    8181             : 
    8182       24680 :   TIME_SECTION("adaptMesh", 3, "Adapting Mesh");
    8183             : 
    8184        4936 :   unsigned int cycles_per_step = _adaptivity.getCyclesPerStep();
    8185             : 
    8186        4936 :   bool mesh_changed = false;
    8187             : 
    8188        8674 :   for (unsigned int i = 0; i < cycles_per_step; ++i)
    8189             :   {
    8190        5102 :     if (!_mesh.interiorLowerDBlocks().empty() || !_mesh.boundaryLowerDBlocks().empty())
    8191           0 :       mooseError("HFEM does not support mesh adaptivity currently.");
    8192             : 
    8193             :     // Markers were already computed once by Executioner
    8194        5102 :     if (_adaptivity.getRecomputeMarkersFlag() && i > 0)
    8195          24 :       computeMarkers();
    8196             : 
    8197             :     bool mesh_changed_this_step;
    8198        5102 :     mesh_changed_this_step = _adaptivity.adaptMesh();
    8199             : 
    8200        5102 :     if (mesh_changed_this_step)
    8201             :     {
    8202        3738 :       mesh_changed = true;
    8203             : 
    8204        3738 :       meshChanged(
    8205             :           /*intermediate_change=*/true, /*contract_mesh=*/true, /*clean_refinement_flags=*/true);
    8206        3738 :       _cycles_completed++;
    8207             :     }
    8208             :     else
    8209             :     {
    8210             :       // If the mesh didn't change, we still need to update the displaced mesh
    8211             :       // to undo the undisplacement performed in Adaptivity::adaptMesh
    8212        1364 :       if (_displaced_problem)
    8213          48 :         _displaced_problem->updateMesh();
    8214             : 
    8215        1364 :       _console << "Mesh unchanged, skipping remaining steps..." << std::endl;
    8216        1364 :       break;
    8217             :     }
    8218             : 
    8219             :     // Show adaptivity progress
    8220        3738 :     _console << std::flush;
    8221             :   }
    8222             : 
    8223             :   // We're done with all intermediate changes; now get systems ready
    8224             :   // for real if necessary.
    8225        4936 :   if (mesh_changed)
    8226        3584 :     es().reinit_systems();
    8227             : 
    8228             :   // Execute multi-apps that need to run after adaptivity, but before the next timestep.
    8229        4936 :   execMultiApps(EXEC_POST_ADAPTIVITY);
    8230             : 
    8231        4936 :   return mesh_changed;
    8232        4936 : }
    8233             : #endif // LIBMESH_ENABLE_AMR
    8234             : 
    8235             : void
    8236           0 : FEProblemBase::initXFEM(std::shared_ptr<XFEMInterface> xfem)
    8237             : {
    8238           0 :   _xfem = xfem;
    8239           0 :   _xfem->setMesh(&_mesh);
    8240           0 :   if (_displaced_mesh)
    8241           0 :     _xfem->setDisplacedMesh(_displaced_mesh);
    8242             : 
    8243           0 :   auto fill_data = [](auto & storage)
    8244             :   {
    8245           0 :     std::vector<MaterialData *> data(libMesh::n_threads());
    8246           0 :     for (const auto tid : make_range(libMesh::n_threads()))
    8247           0 :       data[tid] = &storage.getMaterialData(tid);
    8248           0 :     return data;
    8249           0 :   };
    8250           0 :   _xfem->setMaterialData(fill_data(_material_props));
    8251           0 :   _xfem->setBoundaryMaterialData(fill_data(_bnd_material_props));
    8252             : 
    8253           0 :   unsigned int n_threads = libMesh::n_threads();
    8254           0 :   for (unsigned int i = 0; i < n_threads; ++i)
    8255           0 :     for (const auto nl_sys_num : index_range(_nl))
    8256             :     {
    8257           0 :       _assembly[i][nl_sys_num]->setXFEM(_xfem);
    8258           0 :       if (_displaced_problem)
    8259           0 :         _displaced_problem->assembly(i, nl_sys_num).setXFEM(_xfem);
    8260             :     }
    8261           0 : }
    8262             : 
    8263             : bool
    8264           0 : FEProblemBase::updateMeshXFEM()
    8265             : {
    8266           0 :   TIME_SECTION("updateMeshXFEM", 5, "Updating XFEM");
    8267             : 
    8268           0 :   bool updated = false;
    8269           0 :   if (haveXFEM())
    8270             :   {
    8271           0 :     if (_xfem->updateHeal())
    8272             :       // XFEM exodiff tests rely on a given numbering because they cannot use map = true due to
    8273             :       // having coincident elements. While conceptually speaking we do not need to contract the
    8274             :       // mesh, we need its call to renumber_nodes_and_elements in order to preserve these tests
    8275           0 :       meshChanged(
    8276             :           /*intermediate_change=*/false, /*contract_mesh=*/true, /*clean_refinement_flags=*/false);
    8277             : 
    8278           0 :     updated = _xfem->update(_time, _nl, *_aux);
    8279           0 :     if (updated)
    8280             :     {
    8281           0 :       meshChanged(
    8282             :           /*intermediate_change=*/false, /*contract_mesh=*/true, /*clean_refinement_flags=*/false);
    8283           0 :       _xfem->initSolution(_nl, *_aux);
    8284           0 :       restoreSolutions();
    8285           0 :       _console << "\nXFEM update complete: Mesh modified" << std::endl;
    8286             :     }
    8287             :     else
    8288           0 :       _console << "\nXFEM update complete: Mesh not modified" << std::endl;
    8289             :   }
    8290           0 :   return updated;
    8291           0 : }
    8292             : 
    8293             : void
    8294        7587 : FEProblemBase::meshChanged(const bool intermediate_change,
    8295             :                            const bool contract_mesh,
    8296             :                            const bool clean_refinement_flags)
    8297             : {
    8298       37935 :   TIME_SECTION("meshChanged", 3, "Handling Mesh Changes");
    8299             : 
    8300       14942 :   if (_material_props.hasStatefulProperties() || _bnd_material_props.hasStatefulProperties() ||
    8301        7355 :       _neighbor_material_props.hasStatefulProperties())
    8302         232 :     _mesh.cacheChangedLists(); // Currently only used with adaptivity and stateful material
    8303             :                                // properties
    8304             : 
    8305             :   // Clear these out because they corresponded to the old mesh
    8306        7587 :   _ghosted_elems.clear();
    8307        7587 :   ghostGhostedBoundaries();
    8308             : 
    8309             :   // The mesh changed.  We notify the MooseMesh first, because
    8310             :   // callbacks (e.g. for sparsity calculations) triggered by the
    8311             :   // EquationSystems reinit may require up-to-date MooseMesh caches.
    8312        7587 :   _mesh.meshChanged();
    8313             : 
    8314             :   // If we're just going to alter the mesh again, all we need to
    8315             :   // handle here is AMR and projections, not full system reinit
    8316        7587 :   if (intermediate_change)
    8317        3773 :     es().reinit_solutions();
    8318             :   else
    8319        3814 :     es().reinit();
    8320             : 
    8321        7587 :   if (contract_mesh)
    8322             :     // Once vectors are restricted, we can delete children of coarsened elements
    8323        4817 :     _mesh.getMesh().contract();
    8324        7587 :   if (clean_refinement_flags)
    8325             :   {
    8326             :     // Finally clear refinement flags so that if someone tries to project vectors again without
    8327             :     // an intervening mesh refinement to clear flags they won't run into trouble
    8328        4817 :     MeshRefinement refinement(_mesh.getMesh());
    8329        4817 :     refinement.clean_refinement_flags();
    8330        4817 :   }
    8331             : 
    8332        7587 :   if (!intermediate_change)
    8333             :   {
    8334             :     // Since the mesh has changed, we need to make sure that we update any of our
    8335             :     // MOOSE-system specific data.
    8336        7628 :     for (auto & sys : _solver_systems)
    8337        3814 :       sys->reinit();
    8338        3814 :     _aux->reinit();
    8339             :   }
    8340             : 
    8341             :   // Updating MooseMesh first breaks other adaptivity code, unless we
    8342             :   // then *again* update the MooseMesh caches.  E.g. the definition of
    8343             :   // "active" and "local" may have been *changed* by refinement and
    8344             :   // repartitioning done in EquationSystems::reinit().
    8345        7587 :   _mesh.meshChanged();
    8346             : 
    8347             :   // If we have finite volume variables, we will need to recompute additional elemental/face
    8348             :   // quantities
    8349        7587 :   if (haveFV() && _mesh.isFiniteVolumeInfoDirty())
    8350         384 :     _mesh.setupFiniteVolumeMeshData();
    8351             : 
    8352             :   // Let the meshChangedInterface notify the mesh changed event before we update the active
    8353             :   // semilocal nodes, because the set of ghosted elements may potentially be updated during a mesh
    8354             :   // changed event.
    8355      133674 :   for (const auto & mci : _notify_when_mesh_changes)
    8356      126087 :     mci->meshChanged();
    8357             : 
    8358             :   // Since the Mesh changed, update the PointLocator object used by DiracKernels.
    8359        7587 :   _dirac_kernel_info.updatePointLocator(_mesh);
    8360             : 
    8361             :   // Need to redo ghosting
    8362        7587 :   _geometric_search_data.reinit();
    8363             : 
    8364        7587 :   if (_displaced_problem)
    8365             :   {
    8366         633 :     _displaced_problem->meshChanged(contract_mesh, clean_refinement_flags);
    8367         633 :     _displaced_mesh->updateActiveSemiLocalNodeRange(_ghosted_elems);
    8368             :   }
    8369             : 
    8370        7587 :   _mesh.updateActiveSemiLocalNodeRange(_ghosted_elems);
    8371             : 
    8372        7587 :   _evaluable_local_elem_range.reset();
    8373        7587 :   _nl_evaluable_local_elem_range.reset();
    8374             : 
    8375             :   // Just like we reinitialized our geometric search objects, we also need to reinitialize our
    8376             :   // mortar meshes. Note that this needs to happen after DisplacedProblem::meshChanged because the
    8377             :   // mortar mesh discretization will depend necessarily on the displaced mesh being re-displaced
    8378        7587 :   updateMortarMesh();
    8379             : 
    8380             :   // Nonlinear systems hold the mortar mesh functors. The domains of definition of the mortar
    8381             :   // functors might have changed when the mesh changed.
    8382       15162 :   for (auto & nl_sys : _nl)
    8383        7575 :     nl_sys->reinitMortarFunctors();
    8384             : 
    8385        7587 :   reinitBecauseOfGhostingOrNewGeomObjects(/*mortar_changed=*/true);
    8386             : 
    8387             :   // We need to create new storage for newly active elements, and copy
    8388             :   // stateful properties from the old elements.
    8389        7819 :   if (_has_initialized_stateful &&
    8390         232 :       (_material_props.hasStatefulProperties() || _bnd_material_props.hasStatefulProperties()))
    8391             :   {
    8392         232 :     if (havePRefinement())
    8393          72 :       _mesh.buildPRefinementAndCoarseningMaps(_assembly[0][0].get());
    8394             : 
    8395             :     // Prolong properties onto newly refined elements' children
    8396             :     {
    8397             :       ProjectMaterialProperties pmp(
    8398         232 :           /* refine = */ true, *this, _material_props, _bnd_material_props, _assembly);
    8399         232 :       const auto & range = *_mesh.refinedElementRange();
    8400         232 :       Threads::parallel_reduce(range, pmp);
    8401             : 
    8402             :       // Concurrent erasure from the shared hash map is not safe while we are reading from it in
    8403             :       // ProjectMaterialProperties, so we handle erasure here. Moreover, erasure based on key is
    8404             :       // not thread safe in and of itself because it is a read-write operation. Note that we do not
    8405             :       // do the erasure for p-refinement because the coarse level element is the same as our active
    8406             :       // refined level element
    8407         232 :       if (!doingPRefinement())
    8408        3758 :         for (const auto & elem : range)
    8409             :         {
    8410        3598 :           _material_props.eraseProperty(elem);
    8411        3598 :           _bnd_material_props.eraseProperty(elem);
    8412        3598 :           _neighbor_material_props.eraseProperty(elem);
    8413             :         }
    8414         232 :     }
    8415             : 
    8416             :     // Restrict properties onto newly coarsened elements
    8417             :     {
    8418             :       ProjectMaterialProperties pmp(
    8419         232 :           /* refine = */ false, *this, _material_props, _bnd_material_props, _assembly);
    8420         232 :       const auto & range = *_mesh.coarsenedElementRange();
    8421         232 :       Threads::parallel_reduce(range, pmp);
    8422             :       // Note that we do not do the erasure for p-refinement because the coarse level element is the
    8423             :       // same as our active refined level element
    8424         232 :       if (!doingPRefinement())
    8425        1525 :         for (const auto & elem : range)
    8426             :         {
    8427        1365 :           auto && coarsened_children = _mesh.coarsenedElementChildren(elem);
    8428        8861 :           for (auto && child : coarsened_children)
    8429             :           {
    8430        7496 :             _material_props.eraseProperty(child);
    8431        7496 :             _bnd_material_props.eraseProperty(child);
    8432        7496 :             _neighbor_material_props.eraseProperty(child);
    8433             :           }
    8434             :         }
    8435         232 :     }
    8436             :   }
    8437             : 
    8438        7587 :   if (_calculate_jacobian_in_uo)
    8439           0 :     setVariableAllDoFMap(_uo_jacobian_moose_vars[0]);
    8440             : 
    8441        7587 :   _has_jacobian = false; // we have to recompute jacobian when mesh changed
    8442             : 
    8443             :   // Now for backwards compatibility with user code that overrode the old no-arg meshChanged we must
    8444             :   // call it here
    8445        7587 :   meshChanged();
    8446        7587 : }
    8447             : 
    8448             : void
    8449      970695 : FEProblemBase::notifyWhenMeshChanges(MeshChangedInterface * mci)
    8450             : {
    8451      970695 :   _notify_when_mesh_changes.push_back(mci);
    8452      970695 : }
    8453             : 
    8454             : void
    8455       84979 : FEProblemBase::notifyWhenMeshDisplaces(MeshDisplacedInterface * mdi)
    8456             : {
    8457       84979 :   _notify_when_mesh_displaces.push_back(mdi);
    8458       84979 : }
    8459             : 
    8460             : void
    8461       70072 : FEProblemBase::meshDisplaced()
    8462             : {
    8463      101233 :   for (const auto & mdi : _notify_when_mesh_displaces)
    8464       31161 :     mdi->meshDisplaced();
    8465       70072 : }
    8466             : 
    8467             : void
    8468       10097 : FEProblemBase::initElementStatefulProps(const ConstElemRange & elem_range, const bool threaded)
    8469             : {
    8470             :   ComputeMaterialsObjectThread cmt(
    8471       10097 :       *this, _material_props, _bnd_material_props, _neighbor_material_props, _assembly);
    8472       10097 :   if (threaded)
    8473       10097 :     Threads::parallel_reduce(elem_range, cmt);
    8474             :   else
    8475           0 :     cmt(elem_range, true);
    8476             : 
    8477             : #ifdef MOOSE_KOKKOS_ENABLED
    8478        6781 :   if (_has_kokkos_objects)
    8479         200 :     initKokkosStatefulProps();
    8480             : #endif
    8481       10097 : }
    8482             : 
    8483             : void
    8484       62422 : FEProblemBase::checkProblemIntegrity()
    8485             : {
    8486      187266 :   TIME_SECTION("checkProblemIntegrity", 5);
    8487             : 
    8488             :   // Subdomains specified by the "Problem/block" parameter
    8489      124844 :   const auto & subdomain_names = getParam<std::vector<SubdomainName>>("block");
    8490       62422 :   auto mesh_subdomains_vec = MooseMeshUtils::getSubdomainIDs(_mesh, subdomain_names);
    8491       62422 :   std::set<SubdomainID> mesh_subdomains(mesh_subdomains_vec.begin(), mesh_subdomains_vec.end());
    8492             : 
    8493             :   // Check kernel coverage of subdomains (blocks) in the mesh
    8494       62422 :   if (!_skip_nl_system_check && _solve && _kernel_coverage_check != CoverageCheckMode::FALSE &&
    8495       44972 :       _kernel_coverage_check != CoverageCheckMode::OFF)
    8496             :   {
    8497       44959 :     std::set<SubdomainID> blocks;
    8498       44959 :     if (_kernel_coverage_check == CoverageCheckMode::TRUE ||
    8499         237 :         _kernel_coverage_check == CoverageCheckMode::ON)
    8500       44722 :       blocks = mesh_subdomains;
    8501         237 :     else if (_kernel_coverage_check == CoverageCheckMode::SKIP_LIST)
    8502             :     {
    8503          13 :       blocks = mesh_subdomains;
    8504          26 :       for (const auto & subdomain_name : _kernel_coverage_blocks)
    8505             :       {
    8506          13 :         const auto id = _mesh.getSubdomainID(subdomain_name);
    8507          13 :         if (id == Moose::INVALID_BLOCK_ID)
    8508           0 :           paramError("kernel_coverage_block_list",
    8509             :                      "Subdomain \"",
    8510             :                      subdomain_name,
    8511             :                      "\" not found in mesh.");
    8512          13 :         blocks.erase(id);
    8513             :       }
    8514             :     }
    8515         224 :     else if (_kernel_coverage_check == CoverageCheckMode::ONLY_LIST)
    8516         448 :       for (const auto & subdomain_name : _kernel_coverage_blocks)
    8517             :       {
    8518         224 :         const auto id = _mesh.getSubdomainID(subdomain_name);
    8519         224 :         if (id == Moose::INVALID_BLOCK_ID)
    8520           0 :           paramError("kernel_coverage_block_list",
    8521             :                      "Subdomain \"",
    8522             :                      subdomain_name,
    8523             :                      "\" not found in mesh.");
    8524         224 :         blocks.insert(id);
    8525             :       }
    8526       44959 :     if (!blocks.empty())
    8527       88824 :       for (auto & nl : _nl)
    8528       43881 :         nl->checkKernelCoverage(blocks);
    8529       44943 :   }
    8530             : 
    8531             :   // Check materials
    8532             :   {
    8533             : #ifdef LIBMESH_ENABLE_AMR
    8534       64826 :     if ((_adaptivity.isOn() || _num_grid_steps) &&
    8535        2420 :         (_material_props.hasStatefulProperties() || _bnd_material_props.hasStatefulProperties() ||
    8536        2349 :          _neighbor_material_props.hasStatefulProperties()))
    8537             :     {
    8538          71 :       _console << "Using EXPERIMENTAL Stateful Material Property projection with Adaptivity!\n"
    8539          71 :                << std::flush;
    8540             :     }
    8541             : #endif
    8542             : 
    8543       62406 :     std::set<SubdomainID> local_mesh_subs(mesh_subdomains);
    8544             : 
    8545       62406 :     if (_material_coverage_check != CoverageCheckMode::FALSE &&
    8546       62314 :         _material_coverage_check != CoverageCheckMode::OFF)
    8547             :     {
    8548             :       /**
    8549             :        * If a material is specified for any block in the simulation, then all blocks must
    8550             :        * have a material specified.
    8551             :        */
    8552       62314 :       bool check_material_coverage = false;
    8553       62314 :       std::set<SubdomainID> ids = _all_materials.getActiveBlocks();
    8554       75489 :       for (const auto & id : ids)
    8555             :       {
    8556       13175 :         local_mesh_subs.erase(id);
    8557       13175 :         check_material_coverage = true;
    8558             :       }
    8559             : 
    8560             :       // did the user limit the subdomains to be checked?
    8561       62314 :       if (_material_coverage_check == CoverageCheckMode::SKIP_LIST)
    8562             :       {
    8563          26 :         for (const auto & subdomain_name : _material_coverage_blocks)
    8564             :         {
    8565          13 :           const auto id = _mesh.getSubdomainID(subdomain_name);
    8566          13 :           if (id == Moose::INVALID_BLOCK_ID)
    8567           0 :             paramError("material_coverage_block_list",
    8568           0 :                        "Subdomain \"" + subdomain_name + "\" not found in mesh.");
    8569          13 :           local_mesh_subs.erase(id);
    8570             :         }
    8571             :       }
    8572       62301 :       else if (_material_coverage_check == CoverageCheckMode::ONLY_LIST)
    8573             :       {
    8574         224 :         std::set<SubdomainID> blocks(local_mesh_subs);
    8575         448 :         for (const auto & subdomain_name : _material_coverage_blocks)
    8576             :         {
    8577         224 :           const auto id = _mesh.getSubdomainID(subdomain_name);
    8578         224 :           if (id == Moose::INVALID_BLOCK_ID)
    8579           0 :             paramError("material_coverage_block_list",
    8580           0 :                        "Subdomain \"" + subdomain_name + "\" not found in mesh.");
    8581         224 :           blocks.erase(id);
    8582             :         }
    8583         237 :         for (const auto id : blocks)
    8584          13 :           local_mesh_subs.erase(id);
    8585         224 :       }
    8586             : 
    8587             :       // also exclude mortar spaces from the material check
    8588       62314 :       auto && mortar_subdomain_ids = _mortar_data.getMortarSubdomainIDs();
    8589       64354 :       for (auto subdomain_id : mortar_subdomain_ids)
    8590        2040 :         local_mesh_subs.erase(subdomain_id);
    8591             : 
    8592             :       // Check Material Coverage
    8593       62314 :       if (check_material_coverage && !local_mesh_subs.empty())
    8594             :       {
    8595           8 :         std::stringstream extra_subdomain_ids;
    8596             :         /// unsigned int is necessary to print SubdomainIDs in the statement below
    8597           8 :         std::copy(local_mesh_subs.begin(),
    8598             :                   local_mesh_subs.end(),
    8599          16 :                   std::ostream_iterator<unsigned int>(extra_subdomain_ids, " "));
    8600             :         /// vector is necessary to get the subdomain names
    8601             :         std::vector<SubdomainID> local_mesh_subs_vec(local_mesh_subs.begin(),
    8602           8 :                                                      local_mesh_subs.end());
    8603             : 
    8604          24 :         mooseError("The following blocks from your input mesh do not contain an active material: " +
    8605          16 :                    extra_subdomain_ids.str() +
    8606          24 :                    "(names: " + Moose::stringify(_mesh.getSubdomainNames(local_mesh_subs_vec)) +
    8607             :                    ")\nWhen ANY mesh block contains a Material object, "
    8608             :                    "all blocks must contain a Material object.\n");
    8609           0 :       }
    8610       62306 :     }
    8611             : 
    8612             :     // Check material properties on blocks and boundaries
    8613       62398 :     checkBlockMatProps();
    8614       62356 :     checkBoundaryMatProps();
    8615             : 
    8616             :     // Check that material properties exist when requested by other properties on a given block
    8617       62344 :     const auto & materials = _all_materials.getActiveObjects();
    8618       77069 :     for (const auto & material : materials)
    8619       14725 :       material->checkStatefulSanity();
    8620             : 
    8621             :     // auto mats_to_check = _materials.getActiveBlockObjects();
    8622             :     // const auto & discrete_materials = _discrete_materials.getActiveBlockObjects();
    8623             :     // for (const auto & map_it : discrete_materials)
    8624             :     //   for (const auto & container_element : map_it.second)
    8625             :     //     mats_to_check[map_it.first].push_back(container_element);
    8626       62344 :     if (_material_dependency_check)
    8627       62318 :       checkDependMaterialsHelper(_all_materials.getActiveBlockObjects());
    8628       62328 :   }
    8629             : 
    8630       62328 :   checkUserObjects();
    8631             : 
    8632             :   // Verify that we don't have any Element type/Coordinate Type conflicts
    8633       62328 :   checkCoordinateSystems();
    8634             : 
    8635             :   // Coordinate transforms are only intended for use with MultiApps at this time. If you are not
    8636             :   // using multiapps but still require these, contact a moose developer
    8637       62479 :   if (_mesh.coordTransform().hasScalingOrRotationTransformation() && _app.isUltimateMaster() &&
    8638         155 :       !hasMultiApps())
    8639           4 :     mooseError("Coordinate transformation parameters, listed below, are only to be used in the "
    8640             :                "context of application to application field transfers at this time. The mesh is "
    8641             :                "not modified by these parameters within an application.\n"
    8642             :                "You should likely use a 'TransformGenerator' in the [Mesh] block to achieve the "
    8643             :                "desired mesh modification.\n\n",
    8644           4 :                Moose::stringify(MooseAppCoordTransform::validParams()));
    8645             : 
    8646             :   // If using displacements, verify that the order of the displacement
    8647             :   // variables matches the order of the elements in the displaced
    8648             :   // mesh.
    8649       62320 :   checkDisplacementOrders();
    8650             : 
    8651             :   // Check for postprocessor names with same name as a scalar variable
    8652       62316 :   checkDuplicatePostprocessorVariableNames();
    8653       62316 : }
    8654             : 
    8655             : void
    8656       62320 : FEProblemBase::checkDisplacementOrders()
    8657             : {
    8658       62320 :   if (_displaced_problem)
    8659             :   {
    8660        2246 :     bool mesh_has_second_order_elements = false;
    8661        4492 :     for (const auto & elem : as_range(_displaced_mesh->activeLocalElementsBegin(),
    8662      535056 :                                       _displaced_mesh->activeLocalElementsEnd()))
    8663             :     {
    8664      264537 :       if (elem->default_order() == SECOND)
    8665             :       {
    8666         378 :         mesh_has_second_order_elements = true;
    8667         378 :         break;
    8668             :       }
    8669        2246 :     }
    8670             : 
    8671             :     // We checked our local elements, so take the max over all processors.
    8672        2246 :     _displaced_mesh->comm().max(mesh_has_second_order_elements);
    8673             : 
    8674             :     // If the Mesh has second order elements, make sure the
    8675             :     // displacement variables are second-order.
    8676        2246 :     if (mesh_has_second_order_elements)
    8677             :     {
    8678             :       const std::vector<std::string> & displacement_variables =
    8679         378 :           _displaced_problem->getDisplacementVarNames();
    8680             : 
    8681        1242 :       for (const auto & var_name : displacement_variables)
    8682             :       {
    8683             :         MooseVariableFEBase & mv =
    8684         868 :             _displaced_problem->getVariable(/*tid=*/0,
    8685             :                                             var_name,
    8686             :                                             Moose::VarKindType::VAR_ANY,
    8687             :                                             Moose::VarFieldType::VAR_FIELD_STANDARD);
    8688         868 :         if (mv.order() != SECOND)
    8689           4 :           mooseError("Error: mesh has SECOND order elements, so all displacement variables must be "
    8690             :                      "SECOND order.");
    8691             :       }
    8692             :     }
    8693             :   }
    8694       62316 : }
    8695             : 
    8696             : void
    8697       62328 : FEProblemBase::checkUserObjects()
    8698             : {
    8699             :   // Check user_objects block coverage
    8700       62328 :   std::set<SubdomainID> mesh_subdomains = _mesh.meshSubdomains();
    8701       62328 :   std::set<SubdomainID> user_objects_blocks;
    8702             : 
    8703             :   // gather names of all user_objects that were defined in the input file
    8704             :   // and the blocks that they are defined on
    8705       62328 :   std::set<std::string> names;
    8706             : 
    8707       62328 :   std::vector<UserObject *> objects;
    8708       62328 :   theWarehouse().query().condition<AttribInterfaces>(Interfaces::UserObject).queryInto(objects);
    8709             : 
    8710      143753 :   for (const auto & obj : objects)
    8711       81425 :     names.insert(obj->name());
    8712             : 
    8713             :   // See if all referenced blocks are covered
    8714       62328 :   std::set<SubdomainID> difference;
    8715       62328 :   std::set_difference(user_objects_blocks.begin(),
    8716             :                       user_objects_blocks.end(),
    8717             :                       mesh_subdomains.begin(),
    8718             :                       mesh_subdomains.end(),
    8719             :                       std::inserter(difference, difference.end()));
    8720             : 
    8721       62328 :   if (!difference.empty())
    8722             :   {
    8723           0 :     std::ostringstream oss;
    8724           0 :     oss << "One or more UserObjects is referencing a nonexistent block:\n";
    8725           0 :     for (const auto & id : difference)
    8726           0 :       oss << id << "\n";
    8727           0 :     mooseError(oss.str());
    8728           0 :   }
    8729       62328 : }
    8730             : 
    8731             : void
    8732       62318 : FEProblemBase::checkDependMaterialsHelper(
    8733             :     const std::map<SubdomainID, std::vector<std::shared_ptr<MaterialBase>>> & materials_map)
    8734             : {
    8735       75420 :   for (const auto & it : materials_map)
    8736             :   {
    8737             :     /// These two sets are used to make sure that all dependent props on a block are actually supplied
    8738       13112 :     std::set<std::string> block_depend_props, block_supplied_props;
    8739             : 
    8740       32495 :     for (const auto & mat1 : it.second)
    8741             :     {
    8742       19383 :       auto & alldeps = mat1->getMatPropDependencies(); // includes requested stateful props
    8743       21835 :       for (auto & dep : alldeps)
    8744        2452 :         block_depend_props.insert(_material_prop_registry.getName(dep));
    8745             : 
    8746             :       // See if any of the active materials supply this property
    8747       59962 :       for (const auto & mat2 : it.second)
    8748             :       {
    8749       40579 :         const std::set<std::string> & supplied_props = mat2->MaterialBase::getSuppliedItems();
    8750       40579 :         block_supplied_props.insert(supplied_props.begin(), supplied_props.end());
    8751             :       }
    8752             :     }
    8753             : 
    8754             :     // Add zero material properties specific to this block and unrestricted
    8755       13112 :     block_supplied_props.insert(_zero_block_material_props[it.first].begin(),
    8756       13112 :                                 _zero_block_material_props[it.first].end());
    8757             : 
    8758             :     // Error check to make sure all properties consumed by materials are supplied on this block
    8759       13112 :     std::set<std::string> difference;
    8760       13112 :     std::set_difference(block_depend_props.begin(),
    8761             :                         block_depend_props.end(),
    8762             :                         block_supplied_props.begin(),
    8763             :                         block_supplied_props.end(),
    8764             :                         std::inserter(difference, difference.end()));
    8765             : 
    8766       13112 :     if (!difference.empty())
    8767             :     {
    8768          10 :       std::ostringstream oss;
    8769          10 :       oss << "One or more Material Properties were not supplied on block ";
    8770          10 :       const std::string & subdomain_name = _mesh.getSubdomainName(it.first);
    8771          10 :       if (subdomain_name.length() > 0)
    8772           0 :         oss << subdomain_name << " (" << it.first << ")";
    8773             :       else
    8774          10 :         oss << it.first;
    8775          10 :       oss << ":\n";
    8776          20 :       for (const auto & name : difference)
    8777          10 :         oss << name << "\n";
    8778          10 :       mooseError(oss.str());
    8779           0 :     }
    8780       13102 :   }
    8781             : 
    8782             :   // This loop checks that materials are not supplied by multiple Material objects
    8783       75404 :   for (const auto & it : materials_map)
    8784             :   {
    8785       13102 :     const auto & materials = it.second;
    8786       13102 :     std::set<std::string> inner_supplied, outer_supplied;
    8787             : 
    8788       32461 :     for (const auto & outer_mat : materials)
    8789             :     {
    8790             :       // Storage for properties for this material (outer) and all other materials (inner)
    8791       19365 :       outer_supplied = outer_mat->getSuppliedItems();
    8792       19365 :       inner_supplied.clear();
    8793             : 
    8794             :       // Property to material map for error reporting
    8795       19365 :       std::map<std::string, std::set<std::string>> prop_to_mat;
    8796       40535 :       for (const auto & name : outer_supplied)
    8797       21170 :         prop_to_mat[name].insert(outer_mat->name());
    8798             : 
    8799       59916 :       for (const auto & inner_mat : materials)
    8800             :       {
    8801       40551 :         if (outer_mat == inner_mat)
    8802       19365 :           continue;
    8803             : 
    8804             :         // Check whether these materials are an AD pair
    8805       21186 :         auto outer_mat_type = outer_mat->type();
    8806       21186 :         auto inner_mat_type = inner_mat->type();
    8807       42372 :         removeSubstring(outer_mat_type, "<RESIDUAL>");
    8808       42372 :         removeSubstring(outer_mat_type, "<JACOBIAN>");
    8809       42372 :         removeSubstring(inner_mat_type, "<RESIDUAL>");
    8810       21186 :         removeSubstring(inner_mat_type, "<JACOBIAN>");
    8811       21186 :         if (outer_mat_type == inner_mat_type && outer_mat_type != outer_mat->type() &&
    8812           0 :             inner_mat_type != inner_mat->type())
    8813           0 :           continue;
    8814             : 
    8815       21186 :         inner_supplied.insert(inner_mat->getSuppliedItems().begin(),
    8816       21186 :                               inner_mat->getSuppliedItems().end());
    8817             : 
    8818      123824 :         for (const auto & inner_supplied_name : inner_supplied)
    8819      102638 :           prop_to_mat[inner_supplied_name].insert(inner_mat->name());
    8820       21186 :       }
    8821             : 
    8822             :       // Test that a property isn't supplied on multiple blocks
    8823       19365 :       std::set<std::string> intersection;
    8824       19365 :       std::set_intersection(outer_supplied.begin(),
    8825             :                             outer_supplied.end(),
    8826             :                             inner_supplied.begin(),
    8827             :                             inner_supplied.end(),
    8828             :                             std::inserter(intersection, intersection.end()));
    8829             : 
    8830       19365 :       if (!intersection.empty())
    8831             :       {
    8832           6 :         std::ostringstream oss;
    8833           6 :         oss << "The following material properties are declared on block " << it.first
    8834           6 :             << " by multiple materials:\n";
    8835          12 :         oss << ConsoleUtils::indent(2) << std::setw(30) << std::left << "Material Property"
    8836           6 :             << "Material Objects\n";
    8837          24 :         for (const auto & outer_name : intersection)
    8838             :         {
    8839          18 :           oss << ConsoleUtils::indent(2) << std::setw(30) << std::left << outer_name;
    8840          54 :           for (const auto & inner_name : prop_to_mat[outer_name])
    8841          36 :             oss << inner_name << " ";
    8842          18 :           oss << '\n';
    8843             :         }
    8844             : 
    8845           6 :         mooseError(oss.str());
    8846             :         break;
    8847           0 :       }
    8848       19359 :     }
    8849       13096 :   }
    8850       62302 : }
    8851             : 
    8852             : void
    8853       62328 : FEProblemBase::checkCoordinateSystems()
    8854             : {
    8855       62328 :   _mesh.checkCoordinateSystems();
    8856       62324 : }
    8857             : 
    8858             : void
    8859         509 : FEProblemBase::setRestartFile(const std::string & file_name)
    8860             : {
    8861         509 :   if (_app.isRecovering())
    8862             :   {
    8863          23 :     mooseInfo("Restart file ", file_name, " is NOT being used since we are performing recovery.");
    8864             :   }
    8865             :   else
    8866             :   {
    8867         486 :     _app.setRestart(true);
    8868         486 :     _app.setRestartRecoverFileBase(file_name);
    8869         486 :     mooseInfo("Using ", file_name, " for restart.");
    8870             :   }
    8871         509 : }
    8872             : 
    8873             : std::vector<VariableName>
    8874      379818 : FEProblemBase::getVariableNames()
    8875             : {
    8876      379818 :   std::vector<VariableName> names;
    8877             : 
    8878      764144 :   for (auto & sys : _solver_systems)
    8879             :   {
    8880      384326 :     const std::vector<VariableName> & var_names = sys->getVariableNames();
    8881      384326 :     names.insert(names.end(), var_names.begin(), var_names.end());
    8882             :   }
    8883             : 
    8884      379818 :   const std::vector<VariableName> & aux_var_names = _aux->getVariableNames();
    8885      379818 :   names.insert(names.end(), aux_var_names.begin(), aux_var_names.end());
    8886             : 
    8887      379818 :   return names;
    8888           0 : }
    8889             : 
    8890             : SolverParams &
    8891     1702522 : FEProblemBase::solverParams(const unsigned int solver_sys_num)
    8892             : {
    8893             :   mooseAssert(solver_sys_num < numSolverSystems(),
    8894             :               "Solver system number '" << solver_sys_num << "' is out of bounds. We have '"
    8895             :                                        << numSolverSystems() << "' solver systems");
    8896     1702522 :   return _solver_params[solver_sys_num];
    8897             : }
    8898             : 
    8899             : const SolverParams &
    8900       12911 : FEProblemBase::solverParams(const unsigned int solver_sys_num) const
    8901             : {
    8902       12911 :   return const_cast<FEProblemBase *>(this)->solverParams(solver_sys_num);
    8903             : }
    8904             : 
    8905             : void
    8906         456 : FEProblemBase::registerRandomInterface(RandomInterface & random_interface, const std::string & name)
    8907             : {
    8908         456 :   auto insert_pair = moose_try_emplace(
    8909         456 :       _random_data_objects, name, std::make_unique<RandomData>(*this, random_interface));
    8910             : 
    8911         456 :   auto random_data_ptr = insert_pair.first->second.get();
    8912         456 :   random_interface.setRandomDataPointer(random_data_ptr);
    8913         456 : }
    8914             : 
    8915             : bool
    8916     1906873 : FEProblemBase::needBoundaryMaterialOnSide(BoundaryID bnd_id, const THREAD_ID tid)
    8917             : {
    8918     1906873 :   if (_bnd_mat_side_cache[tid].find(bnd_id) == _bnd_mat_side_cache[tid].end())
    8919             :   {
    8920       31099 :     auto & bnd_mat_side_cache = _bnd_mat_side_cache[tid][bnd_id];
    8921       31099 :     bnd_mat_side_cache = false;
    8922             : 
    8923             :     // Check systems
    8924       31099 :     if (_aux->needMaterialOnSide(bnd_id))
    8925             :     {
    8926         578 :       bnd_mat_side_cache = true;
    8927         578 :       return true;
    8928             :     }
    8929       57916 :     for (auto & nl : _nl)
    8930       30195 :       if (nl->needBoundaryMaterialOnSide(bnd_id, tid))
    8931             :       {
    8932        2800 :         bnd_mat_side_cache = true;
    8933        2800 :         return true;
    8934             :       }
    8935             : 
    8936             :     // TODO: these objects should be checked for whether they actually consume materials
    8937             :     // NOTE: InterfaceUO can use use boundary properties too
    8938       27721 :     if (theWarehouse()
    8939       55442 :             .query()
    8940       27721 :             .condition<AttribThread>(tid)
    8941       27721 :             .condition<AttribInterfaces>(Interfaces::SideUserObject | Interfaces::DomainUserObject |
    8942             :                                          Interfaces::InterfaceUserObject)
    8943       27721 :             .condition<AttribBoundaries>(bnd_id)
    8944       27721 :             .count() > 0)
    8945             :     {
    8946         634 :       bnd_mat_side_cache = true;
    8947         634 :       return true;
    8948             :     }
    8949             :   }
    8950             : 
    8951     1902861 :   return _bnd_mat_side_cache[tid][bnd_id];
    8952             : }
    8953             : 
    8954             : bool
    8955      455392 : FEProblemBase::needInterfaceMaterialOnSide(BoundaryID bnd_id, const THREAD_ID tid)
    8956             : {
    8957      455392 :   if (_interface_mat_side_cache[tid].find(bnd_id) == _interface_mat_side_cache[tid].end())
    8958             :   {
    8959        3173 :     auto & interface_mat_side_cache = _interface_mat_side_cache[tid][bnd_id];
    8960        3173 :     interface_mat_side_cache = false;
    8961             : 
    8962             :     // Aux-system has not needed interface materials so far
    8963        6076 :     for (auto & nl : _nl)
    8964        3173 :       if (nl->needInterfaceMaterialOnSide(bnd_id, tid))
    8965             :       {
    8966         270 :         interface_mat_side_cache = true;
    8967         270 :         return true;
    8968             :       }
    8969             : 
    8970             :     // TODO: these objects should be checked for whether they actually consume materials
    8971        2903 :     if (theWarehouse()
    8972        5806 :             .query()
    8973        2903 :             .condition<AttribThread>(tid)
    8974        2903 :             .condition<AttribInterfaces>(Interfaces::InterfaceUserObject |
    8975             :                                          Interfaces::DomainUserObject)
    8976        2903 :             .condition<AttribBoundaries>(bnd_id)
    8977        2903 :             .count() > 0)
    8978             :     {
    8979          90 :       interface_mat_side_cache = true;
    8980          90 :       return true;
    8981             :     }
    8982        2813 :     else if (_interface_materials.hasActiveBoundaryObjects(bnd_id, tid))
    8983             :     {
    8984          11 :       interface_mat_side_cache = true;
    8985          11 :       return true;
    8986             :     }
    8987             :   }
    8988      455021 :   return _interface_mat_side_cache[tid][bnd_id];
    8989             : }
    8990             : 
    8991             : bool
    8992      443075 : FEProblemBase::needInternalNeighborSideMaterial(SubdomainID subdomain_id, const THREAD_ID tid)
    8993             : {
    8994      443075 :   if (_block_mat_side_cache[tid].find(subdomain_id) == _block_mat_side_cache[tid].end())
    8995             :   {
    8996       13419 :     _block_mat_side_cache[tid][subdomain_id] = false;
    8997             : 
    8998       26260 :     for (auto & nl : _nl)
    8999       13336 :       if (nl->needInternalNeighborSideMaterial(subdomain_id, tid))
    9000             :       {
    9001         495 :         _block_mat_side_cache[tid][subdomain_id] = true;
    9002         495 :         return true;
    9003             :       }
    9004             : 
    9005             :     // TODO: these objects should be checked for whether they actually consume materials
    9006       12924 :     if (theWarehouse()
    9007       25848 :             .query()
    9008       12924 :             .condition<AttribThread>(tid)
    9009       12924 :             .condition<AttribInterfaces>(Interfaces::InternalSideUserObject |
    9010             :                                          Interfaces::DomainUserObject)
    9011       12924 :             .condition<AttribSubdomains>(subdomain_id)
    9012       12924 :             .count() > 0)
    9013             :     {
    9014          38 :       _block_mat_side_cache[tid][subdomain_id] = true;
    9015          38 :       return true;
    9016             :     }
    9017             :   }
    9018             : 
    9019      442542 :   return _block_mat_side_cache[tid][subdomain_id];
    9020             : }
    9021             : 
    9022             : bool
    9023      315945 : FEProblemBase::needsPreviousNewtonIteration() const
    9024             : {
    9025      315945 :   return vectorTagExists(Moose::PREVIOUS_NL_SOLUTION_TAG);
    9026             : }
    9027             : 
    9028             : void
    9029          82 : FEProblemBase::needsPreviousNewtonIteration(bool state)
    9030             : {
    9031          82 :   if (state && !vectorTagExists(Moose::PREVIOUS_NL_SOLUTION_TAG))
    9032           0 :     mooseError("Previous nonlinear solution is required but not added through "
    9033             :                "Problem/previous_nl_solution_required=true");
    9034          82 : }
    9035             : 
    9036             : bool
    9037     8536346 : FEProblemBase::hasJacobian() const
    9038             : {
    9039     8536346 :   return _has_jacobian;
    9040             : }
    9041             : 
    9042             : bool
    9043     7990258 : FEProblemBase::constJacobian() const
    9044             : {
    9045     7990258 :   return _const_jacobian;
    9046             : }
    9047             : 
    9048             : void
    9049      296843 : FEProblemBase::addOutput(const std::string & object_type,
    9050             :                          const std::string & object_name,
    9051             :                          InputParameters & parameters)
    9052             : {
    9053             :   parallel_object_only();
    9054             : 
    9055             :   // Get a reference to the OutputWarehouse
    9056      296843 :   OutputWarehouse & output_warehouse = _app.getOutputWarehouse();
    9057             : 
    9058             :   // Reject the reserved names for objects not built by MOOSE
    9059      296843 :   if (!parameters.get<bool>("_built_by_moose") && output_warehouse.isReservedName(object_name))
    9060           8 :     mooseError("The name '", object_name, "' is a reserved name for output objects");
    9061             : 
    9062             :   // Check that an object by the same name does not already exist; this must be done before the
    9063             :   // object is created to avoid getting misleading errors from the Parser
    9064      296835 :   if (output_warehouse.hasOutput(object_name))
    9065           4 :     mooseError("An output object named '", object_name, "' already exists");
    9066             : 
    9067             :   // Add a pointer to the FEProblemBase class
    9068      593662 :   parameters.addPrivateParam<FEProblemBase *>("_fe_problem_base", this);
    9069             : 
    9070             :   // Create common parameter exclude list
    9071      296831 :   std::vector<std::string> exclude;
    9072      296831 :   if (object_type == "Console")
    9073             :   {
    9074       63123 :     exclude.push_back("execute_on");
    9075             : 
    9076             :     // --show-input should enable the display of the input file on the screen
    9077      189369 :     if (_app.getParam<bool>("show_input") && parameters.get<bool>("output_screen"))
    9078          60 :       parameters.set<ExecFlagEnum>("execute_input_on") = EXEC_INITIAL;
    9079             :   }
    9080             :   // Need this because Checkpoint::validParams changes the default value of
    9081             :   // execute_on
    9082      233708 :   else if (object_type == "Checkpoint")
    9083      101514 :     exclude.push_back("execute_on");
    9084             : 
    9085             :   // Apply the common parameters loaded with Outputs input syntax
    9086      296831 :   const InputParameters * common = output_warehouse.getCommonParameters();
    9087      296831 :   if (common)
    9088      296831 :     parameters.applyParameters(*common, exclude);
    9089      296831 :   if (common && std::find(exclude.begin(), exclude.end(), "execute_on") != exclude.end() &&
    9090      821422 :       common->isParamSetByUser("execute_on") && object_type != "Console")
    9091        7070 :     mooseInfoRepeated(
    9092       14140 :         "'execute_on' parameter specified in [Outputs] block is ignored for object '" +
    9093       21210 :         object_name +
    9094             :         "'.\nDefine this object in its own sub-block of [Outputs] to modify its "
    9095             :         "execution schedule.");
    9096             : 
    9097             :   // Set the correct value for the binary flag for XDA/XDR output
    9098      296831 :   if (object_type == "XDR")
    9099         130 :     parameters.set<bool>("_binary") = true;
    9100      296766 :   else if (object_type == "XDA")
    9101         242 :     parameters.set<bool>("_binary") = false;
    9102             : 
    9103             :   // Adjust the checkpoint suffix if auto recovery was enabled
    9104      296831 :   if (object_name == "auto_recovery_checkpoint")
    9105           0 :     parameters.set<std::string>("suffix") = "auto_recovery";
    9106             : 
    9107             :   // Create the object and add it to the warehouse
    9108      296831 :   std::shared_ptr<Output> output = _factory.create<Output>(object_type, object_name, parameters);
    9109      296815 :   logAdd("Output", object_name, object_type, parameters);
    9110      296815 :   output_warehouse.addOutput(output);
    9111      296815 : }
    9112             : 
    9113             : void
    9114       27963 : FEProblemBase::haveADObjects(const bool have_ad_objects)
    9115             : {
    9116       27963 :   _have_ad_objects = have_ad_objects;
    9117       27963 :   if (_displaced_problem)
    9118         247 :     _displaced_problem->SubProblem::haveADObjects(have_ad_objects);
    9119       27963 : }
    9120             : 
    9121             : const SystemBase &
    9122           0 : FEProblemBase::getSystemBase(const unsigned int sys_num) const
    9123             : {
    9124           0 :   if (sys_num < _solver_systems.size())
    9125           0 :     return *_solver_systems[sys_num];
    9126             : 
    9127           0 :   return *_aux;
    9128             : }
    9129             : 
    9130             : SystemBase &
    9131         863 : FEProblemBase::getSystemBase(const std::string & sys_name)
    9132             : {
    9133         863 :   if (std::find(_solver_sys_names.begin(), _solver_sys_names.end(), sys_name) !=
    9134        1726 :       _solver_sys_names.end())
    9135         863 :     return getSystemBase(solverSysNum(sys_name));
    9136           0 :   else if (sys_name == "aux0")
    9137           0 :     return *_aux;
    9138             :   else
    9139           0 :     mooseError("System '" + sys_name + "' was requested from problem but does not exist.");
    9140             : }
    9141             : 
    9142             : SystemBase &
    9143        2504 : FEProblemBase::getSystemBase(const unsigned int sys_num)
    9144             : {
    9145        2504 :   if (sys_num < _solver_systems.size())
    9146        2393 :     return *_solver_systems[sys_num];
    9147             : 
    9148         111 :   return *_aux;
    9149             : }
    9150             : 
    9151             : const SystemBase &
    9152       14531 : FEProblemBase::systemBaseNonlinear(const unsigned int sys_num) const
    9153             : {
    9154             :   mooseAssert(sys_num < _nl.size(), "System number greater than the number of nonlinear systems");
    9155       14531 :   return *_nl[sys_num];
    9156             : }
    9157             : 
    9158             : SystemBase &
    9159     1395284 : FEProblemBase::systemBaseNonlinear(const unsigned int sys_num)
    9160             : {
    9161             :   mooseAssert(sys_num < _nl.size(), "System number greater than the number of nonlinear systems");
    9162     1395284 :   return *_nl[sys_num];
    9163             : }
    9164             : 
    9165             : const SystemBase &
    9166           0 : FEProblemBase::systemBaseLinear(const unsigned int sys_num) const
    9167             : {
    9168             :   mooseAssert(sys_num < _linear_systems.size(),
    9169             :               "System number greater than the number of linear systems");
    9170           0 :   return *_linear_systems[sys_num];
    9171             : }
    9172             : 
    9173             : SystemBase &
    9174           0 : FEProblemBase::systemBaseLinear(const unsigned int sys_num)
    9175             : {
    9176             :   mooseAssert(sys_num < _linear_systems.size(),
    9177             :               "System number greater than the number of linear systems");
    9178           0 :   return *_linear_systems[sys_num];
    9179             : }
    9180             : 
    9181             : const SystemBase &
    9182           0 : FEProblemBase::systemBaseSolver(const unsigned int sys_num) const
    9183             : {
    9184             :   mooseAssert(sys_num < _solver_systems.size(),
    9185             :               "System number greater than the number of solver systems");
    9186           0 :   return *_solver_systems[sys_num];
    9187             : }
    9188             : 
    9189             : SystemBase &
    9190     7395116 : FEProblemBase::systemBaseSolver(const unsigned int sys_num)
    9191             : {
    9192             :   mooseAssert(sys_num < _solver_systems.size(),
    9193             :               "System number greater than the number of solver systems");
    9194     7395116 :   return *_solver_systems[sys_num];
    9195             : }
    9196             : 
    9197             : const SystemBase &
    9198          18 : FEProblemBase::systemBaseAuxiliary() const
    9199             : {
    9200          18 :   return *_aux;
    9201             : }
    9202             : 
    9203             : SystemBase &
    9204     9403603 : FEProblemBase::systemBaseAuxiliary()
    9205             : {
    9206     9403603 :   return *_aux;
    9207             : }
    9208             : 
    9209             : void
    9210     4321794 : FEProblemBase::computingNonlinearResid(bool computing_nonlinear_residual)
    9211             : {
    9212             :   parallel_object_only();
    9213             : 
    9214     4321794 :   if (_displaced_problem)
    9215      212324 :     _displaced_problem->computingNonlinearResid(computing_nonlinear_residual);
    9216     4321794 :   _computing_nonlinear_residual = computing_nonlinear_residual;
    9217     4321794 : }
    9218             : 
    9219             : void
    9220    10548874 : FEProblemBase::setCurrentlyComputingResidual(bool currently_computing_residual)
    9221             : {
    9222    10548874 :   if (_displaced_problem)
    9223      433724 :     _displaced_problem->setCurrentlyComputingResidual(currently_computing_residual);
    9224    10548874 :   _currently_computing_residual = currently_computing_residual;
    9225    10548874 : }
    9226             : 
    9227             : void
    9228          57 : FEProblemBase::uniformRefine()
    9229             : {
    9230             :   // ResetDisplacedMeshThread::onNode looks up the reference mesh by ID, so we need to make sure
    9231             :   // we undisplace before adapting the reference mesh
    9232          57 :   if (_displaced_problem)
    9233          37 :     _displaced_problem->undisplaceMesh();
    9234             : 
    9235          57 :   Adaptivity::uniformRefine(&_mesh, 1);
    9236          57 :   if (_displaced_problem)
    9237          37 :     Adaptivity::uniformRefine(&_displaced_problem->mesh(), 1);
    9238             : 
    9239          57 :   meshChanged(
    9240             :       /*intermediate_change=*/false, /*contract_mesh=*/true, /*clean_refinement_flags=*/true);
    9241          57 : }
    9242             : 
    9243             : void
    9244       63660 : FEProblemBase::automaticScaling(bool automatic_scaling)
    9245             : {
    9246       63660 :   if (_displaced_problem)
    9247        2246 :     _displaced_problem->automaticScaling(automatic_scaling);
    9248             : 
    9249       63660 :   SubProblem::automaticScaling(automatic_scaling);
    9250       63660 : }
    9251             : 
    9252             : void
    9253      284381 : FEProblemBase::reinitElemFaceRef(const Elem * elem,
    9254             :                                  unsigned int side,
    9255             :                                  Real tolerance,
    9256             :                                  const std::vector<Point> * const pts,
    9257             :                                  const std::vector<Real> * const weights,
    9258             :                                  const THREAD_ID tid)
    9259             : {
    9260      284381 :   SubProblem::reinitElemFaceRef(elem, side, tolerance, pts, weights, tid);
    9261             : 
    9262      284381 :   if (_displaced_problem)
    9263       22778 :     _displaced_problem->reinitElemFaceRef(
    9264       22778 :         _displaced_mesh->elemPtr(elem->id()), side, tolerance, pts, weights, tid);
    9265      284381 : }
    9266             : 
    9267             : void
    9268      284381 : FEProblemBase::reinitNeighborFaceRef(const Elem * neighbor_elem,
    9269             :                                      unsigned int neighbor_side,
    9270             :                                      Real tolerance,
    9271             :                                      const std::vector<Point> * const pts,
    9272             :                                      const std::vector<Real> * const weights,
    9273             :                                      const THREAD_ID tid)
    9274             : {
    9275      284381 :   SubProblem::reinitNeighborFaceRef(neighbor_elem, neighbor_side, tolerance, pts, weights, tid);
    9276             : 
    9277      284381 :   if (_displaced_problem)
    9278       22778 :     _displaced_problem->reinitNeighborFaceRef(
    9279       22778 :         _displaced_mesh->elemPtr(neighbor_elem->id()), neighbor_side, tolerance, pts, weights, tid);
    9280      284381 : }
    9281             : 
    9282             : void
    9283     3857812 : FEProblemBase::getFVMatsAndDependencies(
    9284             :     const SubdomainID blk_id,
    9285             :     std::vector<std::shared_ptr<MaterialBase>> & face_materials,
    9286             :     std::vector<std::shared_ptr<MaterialBase>> & neighbor_materials,
    9287             :     std::set<MooseVariableFieldBase *> & variables,
    9288             :     const THREAD_ID tid)
    9289             : {
    9290     3857812 :   if (_materials[Moose::FACE_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    9291             :   {
    9292             :     auto & this_face_mats =
    9293        3996 :         _materials[Moose::FACE_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid);
    9294        8196 :     for (std::shared_ptr<MaterialBase> face_mat : this_face_mats)
    9295        4200 :       if (face_mat->ghostable())
    9296             :       {
    9297        4200 :         face_materials.push_back(face_mat);
    9298        4200 :         auto & var_deps = face_mat->getMooseVariableDependencies();
    9299        4608 :         for (auto * var : var_deps)
    9300             :         {
    9301         408 :           if (!var->isFV())
    9302           0 :             mooseError(
    9303             :                 "Ghostable materials should only have finite volume variables coupled into them.");
    9304         408 :           else if (face_mat->hasStatefulProperties())
    9305           0 :             mooseError("Finite volume materials do not currently support stateful properties.");
    9306         408 :           variables.insert(var);
    9307             :         }
    9308        4200 :       }
    9309             :   }
    9310             : 
    9311     3857812 :   if (_materials[Moose::NEIGHBOR_MATERIAL_DATA].hasActiveBlockObjects(blk_id, tid))
    9312             :   {
    9313             :     auto & this_neighbor_mats =
    9314        3996 :         _materials[Moose::NEIGHBOR_MATERIAL_DATA].getActiveBlockObjects(blk_id, tid);
    9315        8196 :     for (std::shared_ptr<MaterialBase> neighbor_mat : this_neighbor_mats)
    9316        4200 :       if (neighbor_mat->ghostable())
    9317             :       {
    9318        4200 :         neighbor_materials.push_back(neighbor_mat);
    9319             : #ifndef NDEBUG
    9320             :         auto & var_deps = neighbor_mat->getMooseVariableDependencies();
    9321             :         for (auto * var : var_deps)
    9322             :         {
    9323             :           if (!var->isFV())
    9324             :             mooseError(
    9325             :                 "Ghostable materials should only have finite volume variables coupled into them.");
    9326             :           else if (neighbor_mat->hasStatefulProperties())
    9327             :             mooseError("Finite volume materials do not currently support stateful properties.");
    9328             :           auto pr = variables.insert(var);
    9329             :           mooseAssert(!pr.second,
    9330             :                       "We should not have inserted any new variables dependencies from our "
    9331             :                       "neighbor materials that didn't exist for our face materials");
    9332             :         }
    9333             : #endif
    9334        4200 :       }
    9335             :   }
    9336     3857812 : }
    9337             : 
    9338             : void
    9339    48898539 : FEProblemBase::resizeMaterialData(const Moose::MaterialDataType data_type,
    9340             :                                   const unsigned int nqp,
    9341             :                                   const THREAD_ID tid)
    9342             : {
    9343    48898539 :   getMaterialData(data_type, tid).resize(nqp);
    9344    48898539 : }
    9345             : 
    9346             : void
    9347       63580 : FEProblemBase::setNonlinearConvergenceNames(const std::vector<ConvergenceName> & convergence_names)
    9348             : {
    9349       63580 :   if (convergence_names.size() != numNonlinearSystems())
    9350           0 :     paramError("nonlinear_convergence",
    9351             :                "There must be one convergence object per nonlinear system");
    9352       63580 :   _nonlinear_convergence_names = convergence_names;
    9353       63580 : }
    9354             : 
    9355             : void
    9356       63901 : FEProblemBase::setMultiAppFixedPointConvergenceName(const ConvergenceName & convergence_name)
    9357             : {
    9358       63901 :   _multiapp_fixed_point_convergence_name = convergence_name;
    9359       63901 : }
    9360             : 
    9361             : void
    9362       31769 : FEProblemBase::setSteadyStateConvergenceName(const ConvergenceName & convergence_name)
    9363             : {
    9364       31769 :   _steady_state_convergence_name = convergence_name;
    9365       31769 : }
    9366             : 
    9367             : const std::vector<ConvergenceName> &
    9368     1076662 : FEProblemBase::getNonlinearConvergenceNames() const
    9369             : {
    9370     1076662 :   if (_nonlinear_convergence_names)
    9371     1076662 :     return *_nonlinear_convergence_names;
    9372           0 :   mooseError("The nonlinear system convergence name(s) have not been set.");
    9373             : }
    9374             : 
    9375             : bool
    9376        6097 : FEProblemBase::hasLinearConvergenceObjects() const
    9377             : {
    9378             :   // If false,this means we have not set one, not that we are querying this too early
    9379             :   // TODO: once there is a default linear CV object, error on the 'not set' case
    9380        6097 :   return _linear_convergence_names.has_value();
    9381             : }
    9382             : 
    9383             : void
    9384         181 : FEProblemBase::setLinearConvergenceNames(const std::vector<ConvergenceName> & convergence_names)
    9385             : {
    9386         181 :   if (convergence_names.size() != numLinearSystems())
    9387           0 :     paramError("linear_convergence", "There must be one convergence object per linear system");
    9388         181 :   _linear_convergence_names = convergence_names;
    9389         181 : }
    9390             : 
    9391             : const std::vector<ConvergenceName> &
    9392        2634 : FEProblemBase::getLinearConvergenceNames() const
    9393             : {
    9394        2634 :   if (_linear_convergence_names)
    9395        2634 :     return *_linear_convergence_names;
    9396           0 :   mooseError("The linear convergence name(s) have not been set.");
    9397             : }
    9398             : 
    9399             : const ConvergenceName &
    9400      264421 : FEProblemBase::getMultiAppFixedPointConvergenceName() const
    9401             : {
    9402      264421 :   if (_multiapp_fixed_point_convergence_name)
    9403      264421 :     return _multiapp_fixed_point_convergence_name.value();
    9404             :   else
    9405           0 :     mooseError("The fixed point convergence name has not been set.");
    9406             : }
    9407             : 
    9408             : const ConvergenceName &
    9409      108349 : FEProblemBase::getSteadyStateConvergenceName() const
    9410             : {
    9411      108349 :   if (_steady_state_convergence_name)
    9412      108349 :     return _steady_state_convergence_name.value();
    9413             :   else
    9414           0 :     mooseError("The steady convergence name has not been set.");
    9415             : }
    9416             : 
    9417             : void
    9418     3339449 : FEProblemBase::residualSetup()
    9419             : {
    9420     3339449 :   SubProblem::residualSetup();
    9421             :   // We need to setup all the nonlinear systems other than our current one which actually called
    9422             :   // this method (so we have to make sure we don't go in a circle)
    9423     6771438 :   for (const auto i : make_range(numNonlinearSystems()))
    9424     3431989 :     if (i != currentNlSysNum())
    9425       92540 :       _nl[i]->residualSetup();
    9426             :   // We don't setup the aux sys because that's been done elsewhere
    9427     3339449 :   if (_displaced_problem)
    9428      137184 :     _displaced_problem->residualSetup();
    9429     3339449 : }
    9430             : 
    9431             : void
    9432      527126 : FEProblemBase::jacobianSetup()
    9433             : {
    9434      527126 :   SubProblem::jacobianSetup();
    9435             :   // We need to setup all the nonlinear systems other than our current one which actually called
    9436             :   // this method (so we have to make sure we don't go in a circle)
    9437     1070312 :   for (const auto i : make_range(numNonlinearSystems()))
    9438      543186 :     if (i != currentNlSysNum())
    9439       16060 :       _nl[i]->jacobianSetup();
    9440             :   // We don't setup the aux sys because that's been done elsewhere
    9441      527126 :   if (_displaced_problem)
    9442       23344 :     _displaced_problem->jacobianSetup();
    9443      527126 : }
    9444             : 
    9445             : MooseAppCoordTransform &
    9446      104848 : FEProblemBase::coordTransform()
    9447             : {
    9448      104848 :   return mesh().coordTransform();
    9449             : }
    9450             : 
    9451             : unsigned int
    9452   594579378 : FEProblemBase::currentNlSysNum() const
    9453             : {
    9454             :   // If we don't have nonlinear systems this should be an invalid number
    9455   594579378 :   unsigned int current_nl_sys_num = libMesh::invalid_uint;
    9456   594579378 :   if (_nl.size())
    9457   594575282 :     current_nl_sys_num = currentNonlinearSystem().number();
    9458             : 
    9459   594579378 :   return current_nl_sys_num;
    9460             : }
    9461             : 
    9462             : unsigned int
    9463           0 : FEProblemBase::currentLinearSysNum() const
    9464             : {
    9465             :   // If we don't have linear systems this should be an invalid number
    9466           0 :   unsigned int current_linear_sys_num = libMesh::invalid_uint;
    9467           0 :   if (_linear_systems.size())
    9468           0 :     current_linear_sys_num = currentLinearSystem().number();
    9469             : 
    9470           0 :   return current_linear_sys_num;
    9471             : }
    9472             : 
    9473             : bool
    9474   139418631 : FEProblemBase::shouldPrintExecution(const THREAD_ID tid) const
    9475             : {
    9476             :   // For now, only support printing from thread 0
    9477   139418631 :   if (tid != 0)
    9478     8138889 :     return false;
    9479             : 
    9480   262272222 :   if (_print_execution_on.isValueSet(_current_execute_on_flag) ||
    9481   130992480 :       _print_execution_on.isValueSet(EXEC_ALWAYS))
    9482      376597 :     return true;
    9483             :   else
    9484   130903145 :     return false;
    9485             : }
    9486             : 
    9487             : std::vector<MortarUserObject *>
    9488      283049 : FEProblemBase::getMortarUserObjects(const BoundaryID primary_boundary_id,
    9489             :                                     const BoundaryID secondary_boundary_id,
    9490             :                                     const bool displaced,
    9491             :                                     const std::vector<MortarUserObject *> & mortar_uo_superset)
    9492             : {
    9493      283049 :   std::vector<MortarUserObject *> mortar_uos;
    9494      283049 :   auto * const subproblem = displaced ? static_cast<SubProblem *>(_displaced_problem.get())
    9495      283049 :                                       : static_cast<SubProblem *>(this);
    9496      283073 :   for (auto * const obj : mortar_uo_superset)
    9497          48 :     if (obj->onInterface(primary_boundary_id, secondary_boundary_id) &&
    9498          24 :         (&obj->getSubProblem() == subproblem))
    9499          24 :       mortar_uos.push_back(obj);
    9500             : 
    9501      283049 :   return mortar_uos;
    9502           0 : }
    9503             : 
    9504             : std::vector<MortarUserObject *>
    9505      283025 : FEProblemBase::getMortarUserObjects(const BoundaryID primary_boundary_id,
    9506             :                                     const BoundaryID secondary_boundary_id,
    9507             :                                     const bool displaced)
    9508             : {
    9509      283025 :   std::vector<MortarUserObject *> mortar_uos;
    9510      283025 :   theWarehouse()
    9511      283025 :       .query()
    9512      566050 :       .condition<AttribInterfaces>(Interfaces::MortarUserObject)
    9513      283025 :       .queryInto(mortar_uos);
    9514      566050 :   return getMortarUserObjects(primary_boundary_id, secondary_boundary_id, displaced, mortar_uos);
    9515      283025 : }
    9516             : 
    9517             : void
    9518      283025 : FEProblemBase::reinitMortarUserObjects(const BoundaryID primary_boundary_id,
    9519             :                                        const BoundaryID secondary_boundary_id,
    9520             :                                        const bool displaced)
    9521             : {
    9522             :   const auto mortar_uos =
    9523      283025 :       getMortarUserObjects(primary_boundary_id, secondary_boundary_id, displaced);
    9524      283025 :   for (auto * const mortar_uo : mortar_uos)
    9525             :   {
    9526           0 :     mortar_uo->setNormals();
    9527           0 :     mortar_uo->reinit();
    9528             :   }
    9529      283025 : }
    9530             : 
    9531             : void
    9532        1154 : FEProblemBase::setVerboseProblem(bool verbose)
    9533             : {
    9534        1154 :   _verbose_setup = verbose ? "true" : "false";
    9535        1154 :   _verbose_multiapps = verbose;
    9536        1154 :   _verbose_restore = verbose;
    9537        1154 : }
    9538             : 
    9539             : void
    9540      126057 : FEProblemBase::setCurrentLowerDElem(const Elem * const lower_d_elem, const THREAD_ID tid)
    9541             : {
    9542      126057 :   SubProblem::setCurrentLowerDElem(lower_d_elem, tid);
    9543      126057 :   if (_displaced_problem)
    9544       31448 :     _displaced_problem->setCurrentLowerDElem(
    9545           0 :         lower_d_elem ? _displaced_mesh->elemPtr(lower_d_elem->id()) : nullptr, tid);
    9546      126057 : }
    9547             : 
    9548             : void
    9549   135765054 : FEProblemBase::setCurrentBoundaryID(BoundaryID bid, const THREAD_ID tid)
    9550             : {
    9551   135765054 :   SubProblem::setCurrentBoundaryID(bid, tid);
    9552   135765054 :   if (_displaced_problem)
    9553    10148584 :     _displaced_problem->setCurrentBoundaryID(bid, tid);
    9554   135765054 : }
    9555             : 
    9556             : void
    9557     8130481 : FEProblemBase::setCurrentNonlinearSystem(const unsigned int nl_sys_num)
    9558             : {
    9559             :   mooseAssert(nl_sys_num < _nl.size(),
    9560             :               "System number greater than the number of nonlinear systems");
    9561     8130481 :   _current_nl_sys = _nl[nl_sys_num].get();
    9562     8130481 :   _current_solver_sys = _current_nl_sys;
    9563     8130481 : }
    9564             : 
    9565             : void
    9566       17124 : FEProblemBase::setCurrentLinearSystem(const unsigned int sys_num)
    9567             : {
    9568             :   mooseAssert(sys_num < _linear_systems.size(),
    9569             :               "System number greater than the number of linear systems");
    9570       17124 :   _current_linear_sys = _linear_systems[sys_num].get();
    9571       17124 :   _current_solver_sys = _current_linear_sys;
    9572       17124 : }
    9573             : 
    9574             : void
    9575     6350611 : FEProblemBase::computeSystems(const ExecFlagType & type)
    9576             : {
    9577             :   // When performing an adjoint solve in the optimization module, the current solver system is the
    9578             :   // adjoint. However, the adjoint solve requires having accurate time derivative calculations for
    9579             :   // the forward system. The cleanest way to handle such uses is just to compute the time
    9580             :   // derivatives for all solver systems instead of trying to guess which ones we need and don't need
    9581    12856991 :   for (auto & solver_sys : _solver_systems)
    9582     6506380 :     solver_sys->compute(type);
    9583             : 
    9584     6350611 :   _aux->compute(type);
    9585     6350566 : }
    9586             : 
    9587             : const ConstElemRange &
    9588     3868379 : FEProblemBase::getCurrentAlgebraicElementRange()
    9589             : {
    9590     3868379 :   if (!_current_algebraic_elem_range)
    9591     3868379 :     return *_mesh.getActiveLocalElementRange();
    9592             : 
    9593           0 :   return *_current_algebraic_elem_range;
    9594             : }
    9595             : const ConstNodeRange &
    9596       20118 : FEProblemBase::getCurrentAlgebraicNodeRange()
    9597             : {
    9598       20118 :   if (!_current_algebraic_node_range)
    9599       20118 :     return *_mesh.getLocalNodeRange();
    9600             : 
    9601           0 :   return *_current_algebraic_node_range;
    9602             : }
    9603             : const ConstBndNodeRange &
    9604     3638609 : FEProblemBase::getCurrentAlgebraicBndNodeRange()
    9605             : {
    9606     3638609 :   if (!_current_algebraic_bnd_node_range)
    9607     3638609 :     return *_mesh.getBoundaryNodeRange();
    9608             : 
    9609           0 :   return *_current_algebraic_bnd_node_range;
    9610             : }
    9611             : 
    9612             : void
    9613           0 : FEProblemBase::setCurrentAlgebraicElementRange(ConstElemRange * range)
    9614             : {
    9615           0 :   if (!range)
    9616             :   {
    9617           0 :     _current_algebraic_elem_range = nullptr;
    9618           0 :     return;
    9619             :   }
    9620             : 
    9621           0 :   _current_algebraic_elem_range = std::make_unique<ConstElemRange>(*range);
    9622             : }
    9623             : void
    9624           0 : FEProblemBase::setCurrentAlgebraicNodeRange(ConstNodeRange * range)
    9625             : {
    9626           0 :   if (!range)
    9627             :   {
    9628           0 :     _current_algebraic_node_range = nullptr;
    9629           0 :     return;
    9630             :   }
    9631             : 
    9632           0 :   _current_algebraic_node_range = std::make_unique<ConstNodeRange>(*range);
    9633             : }
    9634             : void
    9635           0 : FEProblemBase::setCurrentAlgebraicBndNodeRange(ConstBndNodeRange * range)
    9636             : {
    9637           0 :   if (!range)
    9638             :   {
    9639           0 :     _current_algebraic_bnd_node_range = nullptr;
    9640           0 :     return;
    9641             :   }
    9642             : 
    9643           0 :   _current_algebraic_bnd_node_range = std::make_unique<ConstBndNodeRange>(*range);
    9644             : }
    9645             : 
    9646             : unsigned short
    9647       65732 : FEProblemBase::getCurrentICState()
    9648             : {
    9649       65732 :   return _current_ic_state;
    9650             : }
    9651             : 
    9652             : std::string
    9653       55892 : FEProblemBase::solverTypeString(const unsigned int solver_sys_num)
    9654             : {
    9655       55892 :   return Moose::stringify(solverParams(solver_sys_num)._type);
    9656             : }
    9657             : 
    9658             : SolverParams
    9659        1340 : FEProblemBase::makeLinearSolverParams()
    9660             : {
    9661        1340 :   SolverParams solver_params;
    9662        1340 :   solver_params._type = Moose::SolveType::ST_LINEAR;
    9663        1340 :   solver_params._line_search = Moose::LineSearchType::LS_NONE;
    9664        1340 :   return solver_params;
    9665             : }
    9666             : 
    9667             : const libMesh::CouplingMatrix &
    9668       73595 : FEProblemBase::nonlocalCouplingMatrix(const unsigned i) const
    9669             : {
    9670       73595 :   return _nonlocal_cm[i];
    9671             : }
    9672             : 
    9673             : bool
    9674   105809013 : FEProblemBase::checkNonlocalCouplingRequirement() const
    9675             : {
    9676   105809013 :   return _requires_nonlocal_coupling;
    9677             : }

Generated by: LCOV version 1.14