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

Generated by: LCOV version 1.14