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

Generated by: LCOV version 1.14