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

Generated by: LCOV version 1.14