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

Generated by: LCOV version 1.14