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

Generated by: LCOV version 1.14