LCOV - code coverage report
Current view: top level - src/problems - SubProblem.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 586 653 89.7 %
Date: 2025-07-17 01:28:37 Functions: 97 105 92.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "SubProblem.h"
      11             : #include "Factory.h"
      12             : #include "MooseMesh.h"
      13             : #include "Conversion.h"
      14             : #include "Function.h"
      15             : #include "MooseApp.h"
      16             : #include "MooseVariableFE.h"
      17             : #include "MooseArray.h"
      18             : #include "Assembly.h"
      19             : #include "MooseObjectName.h"
      20             : #include "RelationshipManager.h"
      21             : #include "MooseUtils.h"
      22             : #include "DisplacedSystem.h"
      23             : #include "NonlinearSystemBase.h"
      24             : #include "LinearSystem.h"
      25             : 
      26             : #include "libmesh/equation_systems.h"
      27             : #include "libmesh/system.h"
      28             : #include "libmesh/dof_map.h"
      29             : #include "libmesh/string_to_enum.h"
      30             : 
      31             : #include <regex>
      32             : 
      33             : using namespace libMesh;
      34             : 
      35             : InputParameters
      36      346835 : SubProblem::validParams()
      37             : {
      38      346835 :   InputParameters params = Problem::validParams();
      39             : 
      40     1040505 :   params.addParam<bool>(
      41             :       "default_ghosting",
      42      693670 :       false,
      43             :       "Whether or not to use libMesh's default amount of algebraic and geometric ghosting");
      44             : 
      45      346835 :   params.addParamNamesToGroup("default_ghosting", "Advanced");
      46             : 
      47      346835 :   return params;
      48           0 : }
      49             : 
      50             : const std::unordered_set<FEFamily> SubProblem::_default_families_without_p_refinement = {
      51             :     libMesh::LAGRANGE,
      52             :     libMesh::NEDELEC_ONE,
      53             :     libMesh::RAVIART_THOMAS,
      54             :     libMesh::LAGRANGE_VEC,
      55             :     libMesh::CLOUGH,
      56             :     libMesh::BERNSTEIN,
      57             :     libMesh::RATIONAL_BERNSTEIN};
      58             : 
      59             : // SubProblem /////
      60       60037 : SubProblem::SubProblem(const InputParameters & parameters)
      61             :   : Problem(parameters),
      62       60037 :     _factory(_app.getFactory()),
      63       60037 :     _default_ghosting(getParam<bool>("default_ghosting")),
      64       60037 :     _currently_computing_jacobian(false),
      65       60037 :     _currently_computing_residual_and_jacobian(false),
      66       60037 :     _computing_nonlinear_residual(false),
      67       60037 :     _currently_computing_residual(false),
      68       60037 :     _safe_access_tagged_matrices(false),
      69       60037 :     _safe_access_tagged_vectors(false),
      70       60037 :     _have_ad_objects(false),
      71       60037 :     _output_functors(false),
      72       60037 :     _typed_vector_tags(2),
      73      240148 :     _have_p_refinement(false)
      74             : {
      75       60037 :   unsigned int n_threads = libMesh::n_threads();
      76       60037 :   _active_elemental_moose_variables.resize(n_threads);
      77       60037 :   _has_active_elemental_moose_variables.resize(n_threads);
      78             : 
      79       60037 :   _active_fe_var_coupleable_matrix_tags.resize(n_threads);
      80       60037 :   _active_fe_var_coupleable_vector_tags.resize(n_threads);
      81       60037 :   _active_sc_var_coupleable_matrix_tags.resize(n_threads);
      82       60037 :   _active_sc_var_coupleable_vector_tags.resize(n_threads);
      83             : 
      84       60037 :   _functors.resize(n_threads);
      85       60037 :   _pbblf_functors.resize(n_threads);
      86       60037 :   _functor_to_request_info.resize(n_threads);
      87       60037 : }
      88             : 
      89       55724 : SubProblem::~SubProblem() {}
      90             : 
      91             : TagID
      92      448918 : SubProblem::addVectorTag(const TagName & tag_name,
      93             :                          const Moose::VectorTagType type /* = Moose::VECTOR_TAG_RESIDUAL */)
      94             : {
      95      448918 :   if (type == Moose::VECTOR_TAG_ANY)
      96           0 :     mooseError("Vector tag type cannot be VECTOR_TAG_ANY");
      97             : 
      98      448918 :   const auto tag_name_upper = MooseUtils::toUpper(tag_name);
      99             : 
     100             :   // First, see if the tag exists already
     101     1990345 :   for (const auto & vector_tag : _vector_tags)
     102             :   {
     103             :     mooseAssert(_vector_tags[vector_tag._id] == vector_tag, "Vector tags index mismatch");
     104     1628431 :     if (vector_tag._name == tag_name_upper)
     105             :     {
     106       87004 :       if (vector_tag._type != type)
     107           0 :         mooseError("While attempting to add vector tag with name '",
     108             :                    tag_name_upper,
     109             :                    "' and type ",
     110             :                    type,
     111             :                    ",\na tag with the same name but type ",
     112           0 :                    vector_tag._type,
     113             :                    " was found.\n\nA tag can only exist with one type.");
     114             : 
     115       87004 :       return vector_tag._id;
     116             :     }
     117             :   }
     118             : 
     119             :   // Doesn't exist - create it
     120      361914 :   const TagID new_tag_id = _vector_tags.size();
     121      361914 :   const TagTypeID new_tag_type_id = _typed_vector_tags[type].size();
     122             :   // Primary storage for all tags where the index in the vector == the tag ID
     123      361914 :   _vector_tags.emplace_back(new_tag_id, new_tag_type_id, tag_name_upper, type);
     124             :   // Secondary storage for each type so that we can have quick access to all tags of a type
     125      361914 :   _typed_vector_tags[type].emplace_back(new_tag_id, new_tag_type_id, tag_name_upper, type);
     126             :   // Name map storage for quick name access
     127      361914 :   _vector_tags_name_map.emplace(tag_name_upper, new_tag_id);
     128             : 
     129             :   // Make sure that _vector_tags, _typed_vector_tags, and _vector_tags_name_map are sane
     130      361914 :   verifyVectorTags();
     131             : 
     132      361914 :   return new_tag_id;
     133      448918 : }
     134             : 
     135             : bool
     136      299537 : SubProblem::vectorTagExists(const TagName & tag_name) const
     137             : {
     138             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     139             : 
     140      299537 :   const auto tag_name_upper = MooseUtils::toUpper(tag_name);
     141     2768653 :   for (const auto & vector_tag : _vector_tags)
     142     2482512 :     if (vector_tag._name == tag_name_upper)
     143       13396 :       return true;
     144             : 
     145      286141 :   return false;
     146      299537 : }
     147             : 
     148             : void
     149          12 : SubProblem::addNotZeroedVectorTag(const TagID tag)
     150             : {
     151          12 :   _not_zeroed_tagged_vectors.insert(tag);
     152          12 : }
     153             : 
     154             : bool
     155     8774488 : SubProblem::vectorTagNotZeroed(const TagID tag) const
     156             : {
     157     8774488 :   return _not_zeroed_tagged_vectors.count(tag);
     158             : }
     159             : 
     160             : const VectorTag &
     161   852471610 : SubProblem::getVectorTag(const TagID tag_id) const
     162             : {
     163             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     164             : 
     165   852471610 :   if (!vectorTagExists(tag_id))
     166           0 :     mooseError("Vector tag with ID ", tag_id, " does not exist");
     167             : 
     168   852471610 :   return _vector_tags[tag_id];
     169             : }
     170             : 
     171             : std::vector<VectorTag>
     172     6097519 : SubProblem::getVectorTags(const std::set<TagID> & tag_ids) const
     173             : {
     174             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     175             : 
     176     6097519 :   std::vector<VectorTag> tags;
     177     6097519 :   tags.reserve(tag_ids.size());
     178    23663105 :   for (const auto & tag_id : tag_ids)
     179    17565586 :     tags.push_back(getVectorTag(tag_id));
     180     6097519 :   return tags;
     181           0 : }
     182             : 
     183             : const std::vector<VectorTag> &
     184    10640447 : SubProblem::getVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
     185             : {
     186             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     187             : 
     188    10640447 :   if (type == Moose::VECTOR_TAG_ANY)
     189      514197 :     return _vector_tags;
     190             :   else
     191    10126250 :     return _typed_vector_tags[type];
     192             : }
     193             : 
     194             : unsigned int
     195     7521731 : SubProblem::numVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
     196             : {
     197             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     198             : 
     199     7521731 :   return getVectorTags(type).size();
     200             : }
     201             : 
     202             : TagID
     203     6228134 : SubProblem::getVectorTagID(const TagName & tag_name) const
     204             : {
     205             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     206             : 
     207     6228134 :   const auto tag_name_upper = MooseUtils::toUpper(tag_name);
     208     6228134 :   const auto search = _vector_tags_name_map.find(tag_name_upper);
     209     6228134 :   if (search != _vector_tags_name_map.end())
     210    12456236 :     return search->second;
     211             : 
     212             :   std::string message =
     213          16 :       tag_name_upper == "TIME"
     214             :           ? ".\n\nThis may occur if "
     215             :             "you have a TimeKernel in your problem but did not specify a transient executioner."
     216          32 :           : "";
     217          16 :   mooseError("Vector tag '", tag_name_upper, "' does not exist", message);
     218     6228118 : }
     219             : 
     220             : TagName
     221      150955 : SubProblem::vectorTagName(const TagID tag_id) const
     222             : {
     223             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     224      150955 :   if (!vectorTagExists(tag_id))
     225           0 :     mooseError("Vector tag with ID ", tag_id, " does not exist");
     226             : 
     227      150955 :   return _vector_tags[tag_id]._name;
     228             : }
     229             : 
     230             : Moose::VectorTagType
     231  2249659875 : SubProblem::vectorTagType(const TagID tag_id) const
     232             : {
     233             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     234  2249659875 :   if (!vectorTagExists(tag_id))
     235           0 :     mooseError("Vector tag with ID ", tag_id, " does not exist");
     236             : 
     237  2249659875 :   return _vector_tags[tag_id]._type;
     238             : }
     239             : 
     240             : bool
     241      361914 : SubProblem::verifyVectorTags() const
     242             : {
     243     1828248 :   for (TagID tag_id = 0; tag_id < _vector_tags.size(); ++tag_id)
     244             :   {
     245     1466334 :     const auto & vector_tag = _vector_tags[tag_id];
     246             : 
     247     1466334 :     if (vector_tag._id != tag_id)
     248           0 :       mooseError("Vector tag ", vector_tag._id, " id mismatch in _vector_tags");
     249     1466334 :     if (vector_tag._type == Moose::VECTOR_TAG_ANY)
     250           0 :       mooseError("Vector tag '", vector_tag._name, "' has type VECTOR_TAG_ANY");
     251             : 
     252     1466334 :     const auto search = _vector_tags_name_map.find(vector_tag._name);
     253     1466334 :     if (search == _vector_tags_name_map.end())
     254           0 :       mooseError("Vector tag ", vector_tag._id, " is not in _vector_tags_name_map");
     255     1466334 :     else if (search->second != tag_id)
     256           0 :       mooseError("Vector tag ", vector_tag._id, " has incorrect id in _vector_tags_name_map");
     257             : 
     258     1466334 :     unsigned int found_in_type = 0;
     259     6055406 :     for (TagTypeID tag_type_id = 0; tag_type_id < _typed_vector_tags[vector_tag._type].size();
     260             :          ++tag_type_id)
     261             :     {
     262     4589072 :       const auto & vector_tag_type = _typed_vector_tags[vector_tag._type][tag_type_id];
     263     4589072 :       if (vector_tag_type == vector_tag)
     264             :       {
     265     1466334 :         ++found_in_type;
     266     1466334 :         if (vector_tag_type._type_id != tag_type_id)
     267           0 :           mooseError("Type ID for Vector tag ", tag_id, " is incorrect");
     268             :       }
     269             :     }
     270             : 
     271     1466334 :     if (found_in_type == 0)
     272           0 :       mooseError("Vector tag ", tag_id, " not found in _typed_vector_tags");
     273     1466334 :     if (found_in_type > 1)
     274           0 :       mooseError("Vector tag ", tag_id, " found multiple times in _typed_vector_tags");
     275             :   }
     276             : 
     277      361914 :   unsigned int num_typed_vector_tags = 0;
     278     1085742 :   for (const auto & typed_vector_tags : _typed_vector_tags)
     279      723828 :     num_typed_vector_tags += typed_vector_tags.size();
     280      361914 :   if (num_typed_vector_tags != _vector_tags.size())
     281           0 :     mooseError("Size mismatch between _vector_tags and _typed_vector_tags");
     282      361914 :   if (_vector_tags_name_map.size() != _vector_tags.size())
     283           0 :     mooseError("Size mismatch between _vector_tags and _vector_tags_name_map");
     284             : 
     285      361914 :   return true;
     286             : }
     287             : 
     288             : void
     289     3016381 : SubProblem::selectVectorTagsFromSystem(const SystemBase & system,
     290             :                                        const std::vector<VectorTag> & input_vector_tags,
     291             :                                        std::set<TagID> & selected_tags)
     292             : {
     293     3016381 :   selected_tags.clear();
     294    11745316 :   for (const auto & vector_tag : input_vector_tags)
     295     8728935 :     if (system.hasVector(vector_tag._id))
     296     8728533 :       selected_tags.insert(vector_tag._id);
     297     3016381 : }
     298             : 
     299             : void
     300        4957 : SubProblem::selectMatrixTagsFromSystem(const SystemBase & system,
     301             :                                        const std::map<TagName, TagID> & input_matrix_tags,
     302             :                                        std::set<TagID> & selected_tags)
     303             : {
     304        4957 :   selected_tags.clear();
     305       10028 :   for (const auto & matrix_tag_pair : input_matrix_tags)
     306        5071 :     if (system.hasMatrix(matrix_tag_pair.second))
     307        4979 :       selected_tags.insert(matrix_tag_pair.second);
     308        4957 : }
     309             : 
     310             : TagID
     311      117315 : SubProblem::addMatrixTag(TagName tag_name)
     312             : {
     313      117315 :   auto tag_name_upper = MooseUtils::toUpper(tag_name);
     314      117315 :   auto existing_tag = _matrix_tag_name_to_tag_id.find(tag_name_upper);
     315      117315 :   if (existing_tag == _matrix_tag_name_to_tag_id.end())
     316             :   {
     317      116841 :     auto tag_id = _matrix_tag_name_to_tag_id.size();
     318             : 
     319      116841 :     _matrix_tag_name_to_tag_id[tag_name_upper] = tag_id;
     320             : 
     321      116841 :     _matrix_tag_id_to_tag_name[tag_id] = tag_name_upper;
     322             :   }
     323             : 
     324      234630 :   return _matrix_tag_name_to_tag_id.at(tag_name_upper);
     325      117315 : }
     326             : 
     327             : bool
     328      277582 : SubProblem::matrixTagExists(const TagName & tag_name) const
     329             : {
     330      277582 :   auto tag_name_upper = MooseUtils::toUpper(tag_name);
     331             : 
     332      555164 :   return _matrix_tag_name_to_tag_id.find(tag_name_upper) != _matrix_tag_name_to_tag_id.end();
     333      277582 : }
     334             : 
     335             : bool
     336     1511780 : SubProblem::matrixTagExists(TagID tag_id) const
     337             : {
     338     1511780 :   return _matrix_tag_id_to_tag_name.find(tag_id) != _matrix_tag_id_to_tag_name.end();
     339             : }
     340             : 
     341             : TagID
     342      276310 : SubProblem::getMatrixTagID(const TagName & tag_name) const
     343             : {
     344      276310 :   auto tag_name_upper = MooseUtils::toUpper(tag_name);
     345             : 
     346      276310 :   if (!matrixTagExists(tag_name))
     347           4 :     mooseError("Matrix tag: ",
     348             :                tag_name,
     349             :                " does not exist. ",
     350             :                "If this is a TimeKernel then this may have happened because you didn't "
     351             :                "specify a Transient Executioner.");
     352             : 
     353      552612 :   return _matrix_tag_name_to_tag_id.at(tag_name_upper);
     354      276306 : }
     355             : 
     356             : TagName
     357         320 : SubProblem::matrixTagName(TagID tag)
     358             : {
     359         320 :   return _matrix_tag_id_to_tag_name[tag];
     360             : }
     361             : 
     362             : void
     363      578020 : SubProblem::setActiveFEVariableCoupleableMatrixTags(std::set<TagID> & mtags, const THREAD_ID tid)
     364             : {
     365      578020 :   _active_fe_var_coupleable_matrix_tags[tid] = mtags;
     366      578020 : }
     367             : 
     368             : void
     369     6812400 : SubProblem::setActiveFEVariableCoupleableVectorTags(std::set<TagID> & vtags, const THREAD_ID tid)
     370             : {
     371     6812400 :   _active_fe_var_coupleable_vector_tags[tid] = vtags;
     372    13746547 :   for (const auto sys_num : make_range(numSolverSystems()))
     373     6934147 :     systemBaseSolver(sys_num).setActiveVariableCoupleableVectorTags(vtags, tid);
     374     6812400 :   systemBaseAuxiliary().setActiveVariableCoupleableVectorTags(vtags, tid);
     375     6812400 : }
     376             : 
     377             : void
     378      271881 : SubProblem::clearActiveFEVariableCoupleableVectorTags(const THREAD_ID tid)
     379             : {
     380      271881 :   _active_fe_var_coupleable_vector_tags[tid].clear();
     381      271881 : }
     382             : 
     383             : void
     384      271881 : SubProblem::clearActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid)
     385             : {
     386      271881 :   _active_fe_var_coupleable_matrix_tags[tid].clear();
     387      271881 : }
     388             : 
     389             : const std::set<TagID> &
     390  1746655551 : SubProblem::getActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid) const
     391             : {
     392  1746655551 :   return _active_fe_var_coupleable_matrix_tags[tid];
     393             : }
     394             : 
     395             : const std::set<TagID> &
     396         292 : SubProblem::getActiveFEVariableCoupleableVectorTags(const THREAD_ID tid) const
     397             : {
     398         292 :   return _active_fe_var_coupleable_vector_tags[tid];
     399             : }
     400             : 
     401             : void
     402       49884 : SubProblem::setActiveScalarVariableCoupleableMatrixTags(std::set<TagID> & mtags,
     403             :                                                         const THREAD_ID tid)
     404             : {
     405       49884 :   _active_sc_var_coupleable_matrix_tags[tid] = mtags;
     406       49884 : }
     407             : 
     408             : void
     409       49884 : SubProblem::setActiveScalarVariableCoupleableVectorTags(std::set<TagID> & vtags,
     410             :                                                         const THREAD_ID tid)
     411             : {
     412       49884 :   _active_sc_var_coupleable_vector_tags[tid] = vtags;
     413       99768 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     414       49884 :     systemBaseNonlinear(nl_sys_num).setActiveScalarVariableCoupleableVectorTags(vtags, tid);
     415       49884 :   systemBaseAuxiliary().setActiveScalarVariableCoupleableVectorTags(vtags, tid);
     416       49884 : }
     417             : 
     418             : void
     419       49884 : SubProblem::clearActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid)
     420             : {
     421       49884 :   _active_sc_var_coupleable_vector_tags[tid].clear();
     422       49884 : }
     423             : 
     424             : void
     425       49884 : SubProblem::clearActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid)
     426             : {
     427       49884 :   _active_sc_var_coupleable_matrix_tags[tid].clear();
     428       49884 : }
     429             : 
     430             : const std::set<TagID> &
     431      520509 : SubProblem::getActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid) const
     432             : {
     433      520509 :   return _active_sc_var_coupleable_matrix_tags[tid];
     434             : }
     435             : 
     436             : const std::set<TagID> &
     437           0 : SubProblem::getActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid) const
     438             : {
     439           0 :   return _active_sc_var_coupleable_vector_tags[tid];
     440             : }
     441             : 
     442             : void
     443    10549638 : SubProblem::setActiveElementalMooseVariables(const std::set<MooseVariableFEBase *> & moose_vars,
     444             :                                              const THREAD_ID tid)
     445             : {
     446    10549638 :   if (!moose_vars.empty())
     447             :   {
     448    10238913 :     _has_active_elemental_moose_variables[tid] = 1;
     449    10238913 :     _active_elemental_moose_variables[tid] = moose_vars;
     450             :   }
     451    10549638 : }
     452             : 
     453             : const std::set<MooseVariableFEBase *> &
     454  1141584772 : SubProblem::getActiveElementalMooseVariables(const THREAD_ID tid) const
     455             : {
     456  1141584772 :   return _active_elemental_moose_variables[tid];
     457             : }
     458             : 
     459             : bool
     460  1182244439 : SubProblem::hasActiveElementalMooseVariables(const THREAD_ID tid) const
     461             : {
     462  1182244439 :   return _has_active_elemental_moose_variables[tid];
     463             : }
     464             : 
     465             : void
     466     4506287 : SubProblem::clearActiveElementalMooseVariables(const THREAD_ID tid)
     467             : {
     468     4506287 :   _has_active_elemental_moose_variables[tid] = 0;
     469     4506287 :   _active_elemental_moose_variables[tid].clear();
     470     4506287 : }
     471             : 
     472             : std::set<SubdomainID>
     473           8 : SubProblem::getMaterialPropertyBlocks(const std::string & prop_name)
     474             : {
     475           8 :   std::set<SubdomainID> blocks;
     476             : 
     477          24 :   for (const auto & it : _map_block_material_props)
     478             :   {
     479          16 :     const std::set<std::string> & prop_names = it.second;
     480          16 :     std::set<std::string>::iterator name_it = prop_names.find(prop_name);
     481          16 :     if (name_it != prop_names.end())
     482          16 :       blocks.insert(it.first);
     483             :   }
     484             : 
     485           8 :   return blocks;
     486           0 : }
     487             : 
     488             : std::vector<SubdomainName>
     489           8 : SubProblem::getMaterialPropertyBlockNames(const std::string & prop_name)
     490             : {
     491           8 :   std::set<SubdomainID> blocks = getMaterialPropertyBlocks(prop_name);
     492           8 :   std::vector<SubdomainName> block_names;
     493           8 :   block_names.reserve(blocks.size());
     494          24 :   for (const auto & block_id : blocks)
     495             :   {
     496          16 :     SubdomainName name;
     497          16 :     name = mesh().getMesh().subdomain_name(block_id);
     498          16 :     if (name.empty())
     499             :     {
     500           8 :       std::ostringstream oss;
     501           8 :       oss << block_id;
     502           8 :       name = oss.str();
     503           8 :     }
     504          16 :     block_names.push_back(name);
     505          16 :   }
     506             : 
     507          16 :   return block_names;
     508           8 : }
     509             : 
     510             : bool
     511         320 : SubProblem::hasBlockMaterialProperty(SubdomainID bid, const std::string & prop_name)
     512             : {
     513         320 :   auto it = _map_block_material_props.find(bid);
     514         320 :   if (it == _map_block_material_props.end())
     515           0 :     return false;
     516             : 
     517         320 :   if (it->second.count(prop_name) > 0)
     518         240 :     return true;
     519             :   else
     520          80 :     return false;
     521             : }
     522             : 
     523             : // TODO: remove code duplication by templating
     524             : std::set<BoundaryID>
     525           8 : SubProblem::getMaterialPropertyBoundaryIDs(const std::string & prop_name)
     526             : {
     527           8 :   std::set<BoundaryID> boundaries;
     528             : 
     529          20 :   for (const auto & it : _map_boundary_material_props)
     530             :   {
     531          12 :     const std::set<std::string> & prop_names = it.second;
     532          12 :     std::set<std::string>::iterator name_it = prop_names.find(prop_name);
     533          12 :     if (name_it != prop_names.end())
     534          12 :       boundaries.insert(it.first);
     535             :   }
     536             : 
     537           8 :   return boundaries;
     538           0 : }
     539             : 
     540             : std::vector<BoundaryName>
     541           8 : SubProblem::getMaterialPropertyBoundaryNames(const std::string & prop_name)
     542             : {
     543           8 :   std::set<BoundaryID> boundaries = getMaterialPropertyBoundaryIDs(prop_name);
     544           8 :   std::vector<BoundaryName> boundary_names;
     545           8 :   boundary_names.reserve(boundaries.size());
     546           8 :   const BoundaryInfo & boundary_info = mesh().getMesh().get_boundary_info();
     547             : 
     548          20 :   for (const auto & bnd_id : boundaries)
     549             :   {
     550          12 :     BoundaryName name;
     551          12 :     if (bnd_id == Moose::ANY_BOUNDARY_ID)
     552           4 :       name = "ANY_BOUNDARY_ID";
     553             :     else
     554             :     {
     555           8 :       name = boundary_info.get_sideset_name(bnd_id);
     556           8 :       if (name.empty())
     557             :       {
     558           0 :         std::ostringstream oss;
     559           0 :         oss << bnd_id;
     560           0 :         name = oss.str();
     561           0 :       }
     562             :     }
     563          12 :     boundary_names.push_back(name);
     564          12 :   }
     565             : 
     566          16 :   return boundary_names;
     567           8 : }
     568             : 
     569             : bool
     570           0 : SubProblem::hasBoundaryMaterialProperty(BoundaryID bid, const std::string & prop_name)
     571             : {
     572           0 :   auto it = _map_boundary_material_props.find(bid);
     573           0 :   if (it == _map_boundary_material_props.end())
     574           0 :     return false;
     575             : 
     576           0 :   if (it->second.count(prop_name) > 0)
     577           0 :     return true;
     578             :   else
     579           0 :     return false;
     580             : }
     581             : 
     582             : void
     583       63388 : SubProblem::storeSubdomainMatPropName(SubdomainID block_id, const std::string & name)
     584             : {
     585       63388 :   _map_block_material_props[block_id].insert(name);
     586       63388 : }
     587             : 
     588             : void
     589       59667 : SubProblem::storeBoundaryMatPropName(BoundaryID boundary_id, const std::string & name)
     590             : {
     591       59667 :   _map_boundary_material_props[boundary_id].insert(name);
     592       59667 : }
     593             : 
     594             : void
     595        8799 : SubProblem::storeSubdomainZeroMatProp(SubdomainID block_id, const MaterialPropertyName & name)
     596             : {
     597        8799 :   _zero_block_material_props[block_id].insert(name);
     598        8799 : }
     599             : 
     600             : void
     601        8799 : SubProblem::storeBoundaryZeroMatProp(BoundaryID boundary_id, const MaterialPropertyName & name)
     602             : {
     603        8799 :   _zero_boundary_material_props[boundary_id].insert(name);
     604        8799 : }
     605             : 
     606             : void
     607       42717 : SubProblem::storeSubdomainDelayedCheckMatProp(const std::string & requestor,
     608             :                                               SubdomainID block_id,
     609             :                                               const std::string & name)
     610             : {
     611       42717 :   _map_block_material_props_check[block_id].insert(std::make_pair(requestor, name));
     612       42717 : }
     613             : 
     614             : void
     615        5855 : SubProblem::storeBoundaryDelayedCheckMatProp(const std::string & requestor,
     616             :                                              BoundaryID boundary_id,
     617             :                                              const std::string & name)
     618             : {
     619        5855 :   _map_boundary_material_props_check[boundary_id].insert(std::make_pair(requestor, name));
     620        5855 : }
     621             : 
     622             : void
     623       56015 : SubProblem::checkBlockMatProps()
     624             : {
     625             :   // Variable for storing all available blocks/boundaries from the mesh
     626       56015 :   std::set<SubdomainID> all_ids(mesh().meshSubdomains());
     627             : 
     628       56015 :   std::stringstream errors;
     629             : 
     630             :   // Loop through the properties to check
     631       61591 :   for (const auto & check_it : _map_block_material_props_check)
     632             :   {
     633             :     // The current id for the property being checked (BoundaryID || BlockID)
     634        5576 :     SubdomainID check_id = check_it.first;
     635             : 
     636        5576 :     std::set<SubdomainID> check_ids = {check_id};
     637             : 
     638             :     // Loop through all the block/boundary ids
     639       11152 :     for (const auto & id : check_ids)
     640             :     {
     641             :       // Loop through all the stored properties
     642       46066 :       for (const auto & prop_it : check_it.second)
     643             :       {
     644             :         // Produce an error if the material property is not defined on the current block/boundary
     645             :         // and any block/boundary
     646             :         // and not is not a zero material property.
     647       40592 :         if (_map_block_material_props[id].count(prop_it.second) == 0 &&
     648       40592 :             _zero_block_material_props[id].count(prop_it.second) == 0)
     649             :         {
     650          50 :           std::string check_name = restrictionSubdomainCheckName(id);
     651          50 :           if (check_name.empty())
     652          45 :             check_name = std::to_string(id);
     653         100 :           errors << "Material property '" << prop_it.second << "', requested by '" << prop_it.first
     654          50 :                  << "' is not defined on block " << check_name << "\n";
     655          50 :         }
     656             :       }
     657             :     }
     658        5576 :   }
     659             : 
     660       56015 :   if (!errors.str().empty())
     661          40 :     mooseError(errors.str());
     662       55975 : }
     663             : 
     664             : void
     665       55975 : SubProblem::checkBoundaryMatProps()
     666             : {
     667             :   // Variable for storing the value for ANY_BOUNDARY_ID
     668       55975 :   BoundaryID any_id = Moose::ANY_BOUNDARY_ID;
     669             : 
     670             :   // Variable for storing all available blocks/boundaries from the mesh
     671       55975 :   std::set<BoundaryID> all_ids(mesh().getBoundaryIDs());
     672             : 
     673       55975 :   std::stringstream errors;
     674             : 
     675             :   // Loop through the properties to check
     676       58456 :   for (const auto & check_it : _map_boundary_material_props_check)
     677             :   {
     678             :     // The current id for the property being checked (BoundaryID || BlockID)
     679        2481 :     BoundaryID check_id = check_it.first;
     680             : 
     681             :     // In the case when the material being checked has an ID is set to ANY, then loop through all
     682             :     // the possible ids and verify that the material property is defined.
     683        2481 :     std::set<BoundaryID> check_ids{check_id};
     684        2481 :     if (check_id == any_id)
     685           0 :       check_ids = all_ids;
     686             : 
     687             :     // Loop through all the block/boundary ids
     688        4962 :     for (const auto & id : check_ids)
     689             :     {
     690             :       // Loop through all the stored properties
     691        8336 :       for (const auto & prop_it : check_it.second)
     692             :       {
     693             :         // Produce an error if the material property is not defined on the current block/boundary
     694             :         // and any block/boundary
     695             :         // and not is not a zero material property.
     696        5855 :         if (_map_boundary_material_props[id].count(prop_it.second) == 0 &&
     697        4651 :             _map_boundary_material_props[any_id].count(prop_it.second) == 0 &&
     698       22231 :             _zero_boundary_material_props[id].count(prop_it.second) == 0 &&
     699        5870 :             _zero_boundary_material_props[any_id].count(prop_it.second) == 0)
     700             :         {
     701          15 :           std::string check_name = restrictionBoundaryCheckName(id);
     702          15 :           if (check_name.empty())
     703           0 :             check_name = std::to_string(id);
     704          30 :           errors << "Material property '" << prop_it.second << "', requested by '" << prop_it.first
     705          15 :                  << "' is not defined on boundary " << check_name << "\n";
     706          15 :         }
     707             :       }
     708             :     }
     709        2481 :   }
     710             : 
     711       55975 :   if (!errors.str().empty())
     712          12 :     mooseError(errors.str());
     713       55963 : }
     714             : 
     715             : bool
     716           0 : SubProblem::nlConverged(const unsigned int nl_sys_num)
     717             : {
     718             :   mooseAssert(nl_sys_num < numNonlinearSystems(),
     719             :               "The nonlinear system number is higher than the number of systems we have!");
     720           0 :   return solverSystemConverged(nl_sys_num);
     721             : }
     722             : 
     723             : void
     724       60200 : SubProblem::markMatPropRequested(const std::string & prop_name)
     725             : {
     726       60200 :   _material_property_requested.insert(prop_name);
     727       60200 : }
     728             : 
     729             : bool
     730           0 : SubProblem::isMatPropRequested(const std::string & prop_name) const
     731             : {
     732           0 :   return _material_property_requested.find(prop_name) != _material_property_requested.end();
     733             : }
     734             : 
     735             : void
     736       47051 : SubProblem::addConsumedPropertyName(const MooseObjectName & obj_name, const std::string & prop_name)
     737             : {
     738       47051 :   _consumed_material_properties[obj_name].insert(prop_name);
     739       47051 : }
     740             : 
     741             : const std::map<MooseObjectName, std::set<std::string>> &
     742         202 : SubProblem::getConsumedPropertyMap() const
     743             : {
     744         202 :   return _consumed_material_properties;
     745             : }
     746             : 
     747             : DiracKernelInfo &
     748         950 : SubProblem::diracKernelInfo()
     749             : {
     750         950 :   return _dirac_kernel_info;
     751             : }
     752             : 
     753             : Real
     754           0 : SubProblem::finalNonlinearResidual(unsigned int) const
     755             : {
     756           0 :   return 0;
     757             : }
     758             : 
     759             : unsigned int
     760           0 : SubProblem::nNonlinearIterations(unsigned int) const
     761             : {
     762           0 :   return 0;
     763             : }
     764             : 
     765             : unsigned int
     766           0 : SubProblem::nLinearIterations(unsigned int) const
     767             : {
     768           0 :   return 0;
     769             : }
     770             : 
     771             : std::string
     772          50 : SubProblem::restrictionSubdomainCheckName(SubdomainID check_id)
     773             : {
     774             :   // TODO: Put a better a interface in MOOSE
     775          50 :   std::map<subdomain_id_type, std::string> & name_map = mesh().getMesh().set_subdomain_name_map();
     776          50 :   std::map<subdomain_id_type, std::string>::const_iterator pos = name_map.find(check_id);
     777          50 :   if (pos != name_map.end())
     778           5 :     return pos->second;
     779          45 :   return "";
     780             : }
     781             : 
     782             : std::string
     783          15 : SubProblem::restrictionBoundaryCheckName(BoundaryID check_id)
     784             : {
     785          15 :   return mesh().getMesh().get_boundary_info().sideset_name(check_id);
     786             : }
     787             : 
     788             : void
     789   129178178 : SubProblem::setCurrentBoundaryID(BoundaryID bid, const THREAD_ID tid)
     790             : {
     791   259524674 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     792   130346496 :     assembly(tid, nl_sys_num).setCurrentBoundaryID(bid);
     793   129178178 : }
     794             : 
     795             : unsigned int
     796         192 : SubProblem::getAxisymmetricRadialCoord() const
     797             : {
     798         192 :   return mesh().getAxisymmetricRadialCoord();
     799             : }
     800             : 
     801             : bool
     802           4 : SubProblem::hasLinearVariable(const std::string & var_name) const
     803             : {
     804           4 :   for (const auto i : make_range(numLinearSystems()))
     805           0 :     if (systemBaseLinear(i).hasVariable(var_name))
     806           0 :       return true;
     807           4 :   return false;
     808             : }
     809             : 
     810             : bool
     811          17 : SubProblem::hasAuxiliaryVariable(const std::string & var_name) const
     812             : {
     813          17 :   return systemBaseAuxiliary().hasVariable(var_name);
     814             : }
     815             : 
     816             : template <typename T>
     817             : MooseVariableFEBase &
     818     4319806 : SubProblem::getVariableHelper(const THREAD_ID tid,
     819             :                               const std::string & var_name,
     820             :                               Moose::VarKindType expected_var_type,
     821             :                               Moose::VarFieldType expected_var_field_type,
     822             :                               const std::vector<T> & systems,
     823             :                               const SystemBase & aux) const
     824             : {
     825             :   // Eventual return value
     826     4319806 :   MooseVariableFEBase * var = nullptr;
     827             : 
     828     4319806 :   const auto [var_in_sys, sys_num] = determineSolverSystem(var_name);
     829             : 
     830             :   // First check that the variable is found on the expected system.
     831     4319806 :   if (expected_var_type == Moose::VarKindType::VAR_ANY)
     832             :   {
     833     2383231 :     if (var_in_sys)
     834     1085117 :       var = &(systems[sys_num]->getVariable(tid, var_name));
     835     1298114 :     else if (aux.hasVariable(var_name))
     836     1298114 :       var = &(aux.getVariable(tid, var_name));
     837             :     else
     838           0 :       mooseError("Unknown variable " + var_name);
     839             :   }
     840     2115519 :   else if (expected_var_type == Moose::VarKindType::VAR_SOLVER && var_in_sys &&
     841      178944 :            systems[sys_num]->hasVariable(var_name))
     842      178944 :     var = &(systems[sys_num]->getVariable(tid, var_name));
     843     1757631 :   else if (expected_var_type == Moose::VarKindType::VAR_AUXILIARY && aux.hasVariable(var_name))
     844     1757631 :     var = &(aux.getVariable(tid, var_name));
     845             :   else
     846             :   {
     847           0 :     std::string expected_var_type_string =
     848             :         (expected_var_type == Moose::VarKindType::VAR_SOLVER ? "nonlinear" : "auxiliary");
     849           0 :     mooseError("No ",
     850             :                expected_var_type_string,
     851             :                " variable named ",
     852             :                var_name,
     853             :                " found. "
     854             :                "Did you specify an auxiliary variable when you meant to specify a nonlinear "
     855             :                "variable (or vice-versa)?");
     856           0 :   }
     857             : 
     858             :   // Now make sure the var found has the expected field type.
     859     6313965 :   if ((expected_var_field_type == Moose::VarFieldType::VAR_FIELD_ANY) ||
     860     1994159 :       (expected_var_field_type == var->fieldType()))
     861     4319798 :     return *var;
     862             :   else
     863             :   {
     864           8 :     std::string expected_var_field_type_string =
     865             :         MooseUtils::toLower(Moose::stringify(expected_var_field_type));
     866           8 :     std::string var_field_type_string = MooseUtils::toLower(Moose::stringify(var->fieldType()));
     867             : 
     868           8 :     mooseError("No ",
     869             :                expected_var_field_type_string,
     870             :                " variable named ",
     871             :                var_name,
     872             :                " found. "
     873             :                "Did you specify a ",
     874             :                var_field_type_string,
     875             :                " variable when you meant to specify a ",
     876             :                expected_var_field_type_string,
     877             :                " variable?");
     878           0 :   }
     879             : }
     880             : 
     881             : void
     882      283554 : SubProblem::reinitElemFaceRef(const Elem * elem,
     883             :                               unsigned int side,
     884             :                               Real tolerance,
     885             :                               const std::vector<Point> * const pts,
     886             :                               const std::vector<Real> * const weights,
     887             :                               const THREAD_ID tid)
     888             : {
     889      567108 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     890             :   {
     891             :     // - Set our _current_elem for proper dof index getting in the moose variables
     892             :     // - Reinitialize all of our FE objects so we have current phi, dphi, etc. data
     893             :     // Note that our number of shape functions will reflect the number of shapes associated with the
     894             :     // interior element while the number of quadrature points will be determined by the passed pts
     895             :     // parameter (which presumably will have a number of pts reflective of a facial quadrature rule)
     896      283554 :     assembly(tid, nl_sys_num).reinitElemFaceRef(elem, side, tolerance, pts, weights);
     897             : 
     898      283554 :     auto & nl = systemBaseNonlinear(nl_sys_num);
     899             : 
     900             :     // Actually get the dof indices in the moose variables
     901      283554 :     nl.prepare(tid);
     902             : 
     903             :     // Let's finally compute our variable values!
     904      283554 :     nl.reinitElemFace(elem, side, tid);
     905             :   }
     906             : 
     907             :   // do same for aux as for nl
     908      283554 :   systemBaseAuxiliary().prepare(tid);
     909      283554 :   systemBaseAuxiliary().reinitElemFace(elem, side, tid);
     910             : 
     911             :   // With the dof indices set in the moose variables, now let's properly size
     912             :   // our local residuals/Jacobians
     913      283554 :   auto & current_assembly = assembly(tid, currentNlSysNum());
     914      283554 :   if (currentlyComputingJacobian() || currentlyComputingResidualAndJacobian())
     915       92752 :     current_assembly.prepareJacobianBlock();
     916      283554 :   if (!currentlyComputingJacobian())
     917      190802 :     current_assembly.prepareResidual();
     918      283554 : }
     919             : 
     920             : void
     921      283554 : SubProblem::reinitNeighborFaceRef(const Elem * neighbor_elem,
     922             :                                   unsigned int neighbor_side,
     923             :                                   Real tolerance,
     924             :                                   const std::vector<Point> * const pts,
     925             :                                   const std::vector<Real> * const weights,
     926             :                                   const THREAD_ID tid)
     927             : {
     928      567108 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     929             :   {
     930             :     // - Set our _current_neighbor_elem for proper dof index getting in the moose variables
     931             :     // - Reinitialize all of our FE objects so we have current phi, dphi, etc. data
     932             :     // Note that our number of shape functions will reflect the number of shapes associated with the
     933             :     // interior element while the number of quadrature points will be determined by the passed pts
     934             :     // parameter (which presumably will have a number of pts reflective of a facial quadrature rule)
     935      283554 :     assembly(tid, nl_sys_num)
     936      283554 :         .reinitNeighborFaceRef(neighbor_elem, neighbor_side, tolerance, pts, weights);
     937             : 
     938      283554 :     auto & nl = systemBaseNonlinear(nl_sys_num);
     939             : 
     940             :     // Actually get the dof indices in the moose variables
     941      283554 :     nl.prepareNeighbor(tid);
     942             : 
     943             :     // Let's finally compute our variable values!
     944      283554 :     nl.reinitNeighborFace(neighbor_elem, neighbor_side, tid);
     945             :   }
     946             : 
     947             :   // do same for aux as for nl
     948      283554 :   systemBaseAuxiliary().prepareNeighbor(tid);
     949      283554 :   systemBaseAuxiliary().reinitNeighborFace(neighbor_elem, neighbor_side, tid);
     950             : 
     951             :   // With the dof indices set in the moose variables, now let's properly size
     952             :   // our local residuals/Jacobians
     953      283554 :   assembly(tid, currentNlSysNum()).prepareNeighbor();
     954      283554 : }
     955             : 
     956             : void
     957      299795 : SubProblem::reinitLowerDElem(const Elem * elem,
     958             :                              const THREAD_ID tid,
     959             :                              const std::vector<Point> * const pts,
     960             :                              const std::vector<Real> * const weights)
     961             : {
     962      599590 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     963             :   {
     964             :     // - Set our _current_lower_d_elem for proper dof index getting in the moose variables
     965             :     // - Reinitialize all of our lower-d FE objects so we have current phi, dphi, etc. data
     966      299795 :     assembly(tid, nl_sys_num).reinitLowerDElem(elem, pts, weights);
     967             : 
     968      299795 :     auto & nl = systemBaseNonlinear(nl_sys_num);
     969             : 
     970             :     // Actually get the dof indices in the moose variables
     971      299795 :     nl.prepareLowerD(tid);
     972             : 
     973             :     // With the dof indices set in the moose variables, now let's properly size
     974             :     // our local residuals/Jacobians
     975      299795 :     assembly(tid, nl_sys_num).prepareLowerD();
     976             : 
     977             :     // Let's finally compute our variable values!
     978      299795 :     nl.reinitLowerD(tid);
     979             :   }
     980             : 
     981             :   // do same for aux as for nl
     982      299795 :   systemBaseAuxiliary().prepareLowerD(tid);
     983      299795 :   systemBaseAuxiliary().reinitLowerD(tid);
     984      299795 : }
     985             : 
     986             : void
     987      263086 : SubProblem::reinitNeighborLowerDElem(const Elem * elem, const THREAD_ID tid)
     988             : {
     989      526172 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     990      263086 :     assembly(tid, nl_sys_num).reinitNeighborLowerDElem(elem);
     991      263086 : }
     992             : 
     993             : void
     994      526172 : SubProblem::reinitMortarElem(const Elem * elem, const THREAD_ID tid)
     995             : {
     996     1052344 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     997      526172 :     assembly(tid, nl_sys_num).reinitMortarElem(elem);
     998      526172 : }
     999             : 
    1000             : void
    1001       30994 : SubProblem::cloneAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf, bool to_mesh)
    1002             : {
    1003       30994 :   EquationSystems & eq = es();
    1004       30994 :   const auto n_sys = eq.n_systems();
    1005             : 
    1006       61988 :   auto pr = _root_alg_gf_to_sys_clones.emplace(
    1007       30994 :       &algebraic_gf, std::vector<std::shared_ptr<GhostingFunctor>>(n_sys - 1));
    1008             :   mooseAssert(pr.second, "We are adding a duplicate algebraic ghosting functor");
    1009       30994 :   auto & clones_vec = pr.first->second;
    1010             : 
    1011       62138 :   for (MooseIndex(n_sys) i = 1; i < n_sys; ++i)
    1012             :   {
    1013       31144 :     DofMap & dof_map = eq.get_system(i).get_dof_map();
    1014       31144 :     std::shared_ptr<GhostingFunctor> clone_alg_gf = algebraic_gf.clone();
    1015       62288 :     std::dynamic_pointer_cast<RelationshipManager>(clone_alg_gf)
    1016       31144 :         ->init(mesh(), *algebraic_gf.get_mesh(), &dof_map);
    1017       31144 :     dof_map.add_algebraic_ghosting_functor(clone_alg_gf, to_mesh);
    1018       31144 :     clones_vec[i - 1] = clone_alg_gf;
    1019       31144 :   }
    1020       30994 : }
    1021             : 
    1022             : void
    1023       30994 : SubProblem::addAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf, bool to_mesh)
    1024             : {
    1025       30994 :   EquationSystems & eq = es();
    1026       30994 :   const auto n_sys = eq.n_systems();
    1027       30994 :   if (!n_sys)
    1028           0 :     return;
    1029             : 
    1030       30994 :   eq.get_system(0).get_dof_map().add_algebraic_ghosting_functor(algebraic_gf, to_mesh);
    1031       30994 :   cloneAlgebraicGhostingFunctor(algebraic_gf, to_mesh);
    1032             : }
    1033             : 
    1034             : void
    1035       42328 : SubProblem::cloneCouplingGhostingFunctor(GhostingFunctor & coupling_gf, bool to_mesh)
    1036             : {
    1037       42328 :   const std::size_t num_nl_sys = numNonlinearSystems();
    1038             : 
    1039       84656 :   auto pr = _root_coupling_gf_to_sys_clones.emplace(
    1040       42328 :       &coupling_gf, std::vector<std::shared_ptr<GhostingFunctor>>(num_nl_sys - 1));
    1041             :   mooseAssert(pr.second, "We are adding a duplicate coupling functor");
    1042       42328 :   auto & clones_vec = pr.first->second;
    1043             : 
    1044       42514 :   for (const auto i : make_range(std::size_t(1), num_nl_sys))
    1045             :   {
    1046         186 :     DofMap & dof_map = systemBaseNonlinear(i).system().get_dof_map();
    1047         186 :     std::shared_ptr<GhostingFunctor> clone_coupling_gf = coupling_gf.clone();
    1048         372 :     std::dynamic_pointer_cast<RelationshipManager>(clone_coupling_gf)
    1049         186 :         ->init(mesh(), *coupling_gf.get_mesh(), &dof_map);
    1050         186 :     dof_map.add_coupling_functor(clone_coupling_gf, to_mesh);
    1051         186 :     clones_vec[i - 1] = clone_coupling_gf;
    1052         186 :   }
    1053       42328 : }
    1054             : 
    1055             : void
    1056       43413 : SubProblem::addCouplingGhostingFunctor(GhostingFunctor & coupling_gf, bool to_mesh)
    1057             : {
    1058       43413 :   const auto num_nl_sys = numNonlinearSystems();
    1059       43413 :   if (!num_nl_sys)
    1060        1085 :     return;
    1061             : 
    1062       42328 :   systemBaseNonlinear(0).system().get_dof_map().add_coupling_functor(coupling_gf, to_mesh);
    1063       42328 :   cloneCouplingGhostingFunctor(coupling_gf, to_mesh);
    1064             : }
    1065             : 
    1066             : void
    1067          27 : SubProblem::removeAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf)
    1068             : {
    1069          27 :   EquationSystems & eq = es();
    1070          27 :   const auto n_sys = eq.n_systems();
    1071             : 
    1072             : #ifndef NDEBUG
    1073             :   const DofMap & nl_dof_map = eq.get_system(0).get_dof_map();
    1074             :   const bool found_in_root_sys =
    1075             :       std::find(nl_dof_map.algebraic_ghosting_functors_begin(),
    1076             :                 nl_dof_map.algebraic_ghosting_functors_end(),
    1077             :                 &algebraic_gf) != nl_dof_map.algebraic_ghosting_functors_end();
    1078             :   const bool found_in_our_map =
    1079             :       _root_alg_gf_to_sys_clones.find(&algebraic_gf) != _root_alg_gf_to_sys_clones.end();
    1080             :   mooseAssert(found_in_root_sys == found_in_our_map,
    1081             :               "If the ghosting functor exists in the root DofMap, then we need to have a key for "
    1082             :               "it in our gf to clones map");
    1083             : #endif
    1084             : 
    1085          27 :   eq.get_system(0).get_dof_map().remove_algebraic_ghosting_functor(algebraic_gf);
    1086             : 
    1087          27 :   auto it = _root_alg_gf_to_sys_clones.find(&algebraic_gf);
    1088          27 :   if (it == _root_alg_gf_to_sys_clones.end())
    1089          27 :     return;
    1090             : 
    1091           0 :   auto & clones_vec = it->second;
    1092             :   mooseAssert((n_sys - 1) == clones_vec.size(),
    1093             :               "The size of the gf clones vector doesn't match the number of systems minus one");
    1094           0 :   if (clones_vec.empty())
    1095             :   {
    1096             :     mooseAssert(n_sys == 1, "The clones vector should only be empty if there is only one system");
    1097           0 :     return;
    1098             :   }
    1099             : 
    1100           0 :   for (const auto i : make_range(n_sys))
    1101           0 :     eq.get_system(i + 1).get_dof_map().remove_algebraic_ghosting_functor(*clones_vec[i]);
    1102             : 
    1103           0 :   _root_alg_gf_to_sys_clones.erase(it->first);
    1104             : }
    1105             : 
    1106             : void
    1107          27 : SubProblem::removeCouplingGhostingFunctor(GhostingFunctor & coupling_gf)
    1108             : {
    1109          27 :   EquationSystems & eq = es();
    1110          27 :   const auto num_nl_sys = numNonlinearSystems();
    1111          27 :   if (!num_nl_sys)
    1112          27 :     return;
    1113             : 
    1114             : #ifndef NDEBUG
    1115             :   const DofMap & nl_dof_map = eq.get_system(0).get_dof_map();
    1116             :   const bool found_in_root_sys = std::find(nl_dof_map.coupling_functors_begin(),
    1117             :                                            nl_dof_map.coupling_functors_end(),
    1118             :                                            &coupling_gf) != nl_dof_map.coupling_functors_end();
    1119             :   const bool found_in_our_map =
    1120             :       _root_coupling_gf_to_sys_clones.find(&coupling_gf) != _root_coupling_gf_to_sys_clones.end();
    1121             :   mooseAssert(found_in_root_sys == found_in_our_map,
    1122             :               "If the ghosting functor exists in the root DofMap, then we need to have a key for "
    1123             :               "it in our gf to clones map");
    1124             : #endif
    1125             : 
    1126          27 :   eq.get_system(0).get_dof_map().remove_coupling_functor(coupling_gf);
    1127             : 
    1128          27 :   auto it = _root_coupling_gf_to_sys_clones.find(&coupling_gf);
    1129          27 :   if (it == _root_coupling_gf_to_sys_clones.end())
    1130           0 :     return;
    1131             : 
    1132          27 :   auto & clones_vec = it->second;
    1133             :   mooseAssert((num_nl_sys - 1) == clones_vec.size(),
    1134             :               "The size of the gf clones vector doesn't match the number of systems minus one");
    1135          27 :   if (clones_vec.empty())
    1136             :   {
    1137             :     mooseAssert(num_nl_sys == 1,
    1138             :                 "The clones vector should only be empty if there is only one nonlinear system");
    1139          27 :     return;
    1140             :   }
    1141             : 
    1142           0 :   for (const auto i : make_range(num_nl_sys))
    1143           0 :     eq.get_system(i + 1).get_dof_map().remove_coupling_functor(*clones_vec[i]);
    1144             : 
    1145           0 :   _root_coupling_gf_to_sys_clones.erase(it->first);
    1146             : }
    1147             : 
    1148             : void
    1149       61617 : SubProblem::automaticScaling(bool automatic_scaling)
    1150             : {
    1151      122359 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
    1152       60742 :     systemBaseNonlinear(nl_sys_num).automaticScaling(automatic_scaling);
    1153       61617 : }
    1154             : 
    1155             : bool
    1156       13780 : SubProblem::automaticScaling() const
    1157             : {
    1158             :   // Currently going to assume that we are applying or not applying automatic scaling consistently
    1159             :   // across nonlinear systems
    1160       13780 :   return systemBaseNonlinear(0).automaticScaling();
    1161             : }
    1162             : 
    1163             : void
    1164         352 : SubProblem::hasScalingVector(const unsigned int nl_sys_num)
    1165             : {
    1166         764 :   for (const THREAD_ID tid : make_range(libMesh::n_threads()))
    1167         412 :     assembly(tid, nl_sys_num).hasScalingVector();
    1168         352 : }
    1169             : 
    1170             : void
    1171      346137 : SubProblem::clearAllDofIndices()
    1172             : {
    1173      704104 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
    1174      357967 :     systemBaseNonlinear(nl_sys_num).clearAllDofIndices();
    1175      346137 :   systemBaseAuxiliary().clearAllDofIndices();
    1176      346137 : }
    1177             : 
    1178             : void
    1179      289789 : SubProblem::timestepSetup()
    1180             : {
    1181      607509 :   for (auto & map : _pbblf_functors)
    1182      327336 :     for (auto & pr : map)
    1183        9616 :       pr.second->timestepSetup();
    1184      289789 : }
    1185             : 
    1186             : void
    1187     1869251 : SubProblem::customSetup(const ExecFlagType & exec_type)
    1188             : {
    1189     3920481 :   for (auto & map : _pbblf_functors)
    1190     2119343 :     for (auto & pr : map)
    1191       68113 :       pr.second->customSetup(exec_type);
    1192     1869251 : }
    1193             : 
    1194             : void
    1195     3170529 : SubProblem::residualSetup()
    1196             : {
    1197     6648525 :   for (auto & map : _pbblf_functors)
    1198     3569597 :     for (auto & pr : map)
    1199       91601 :       pr.second->residualSetup();
    1200     3170529 : }
    1201             : 
    1202             : void
    1203      498165 : SubProblem::jacobianSetup()
    1204             : {
    1205     1046382 :   for (auto & map : _pbblf_functors)
    1206      562709 :     for (auto & pr : map)
    1207       14492 :       pr.second->jacobianSetup();
    1208      498165 : }
    1209             : 
    1210             : void
    1211       57568 : SubProblem::initialSetup()
    1212             : {
    1213       57568 :   if (_output_functors)
    1214             :   {
    1215          34 :     showFunctors();
    1216          34 :     showFunctorRequestors();
    1217             :   }
    1218             : 
    1219      120844 :   for (const auto & functors : _functors)
    1220      348903 :     for (const auto & [functor_wrapper_name, functor_wrapper] : functors)
    1221             :     {
    1222      285627 :       const auto & [true_functor_type, non_ad_functor, ad_functor] = functor_wrapper;
    1223             :       mooseAssert(non_ad_functor->wrapsNull() == ad_functor->wrapsNull(), "These must agree");
    1224      285627 :       const auto functor_name = removeSubstring(functor_wrapper_name, "wraps_");
    1225      285627 :       if (non_ad_functor->wrapsNull())
    1226           0 :         mooseError(
    1227             :             "No functor ever provided with name '",
    1228             :             functor_name,
    1229             :             "', which was requested by '",
    1230           0 :             MooseUtils::join(libmesh_map_find(_functor_to_requestors, functor_wrapper_name), ","),
    1231             :             "'.");
    1232      455883 :       if (true_functor_type == TrueFunctorIs::NONAD ? non_ad_functor->ownsWrappedFunctor()
    1233      170256 :                                                     : ad_functor->ownsWrappedFunctor())
    1234           0 :         mooseError("Functor envelopes should not own the functors they wrap, but '",
    1235             :                    functor_name,
    1236             :                    "' is owned by the wrapper. Please open a MOOSE issue for help resolving this.");
    1237      285627 :     }
    1238       57568 : }
    1239             : 
    1240             : void
    1241          34 : SubProblem::showFunctors() const
    1242             : {
    1243          34 :   _console << "[DBG] Wrapped functors found in Subproblem" << std::endl;
    1244          34 :   std::string functor_names = "[DBG] ";
    1245         266 :   for (const auto & functor_pair : _functors[0])
    1246         232 :     functor_names += std::regex_replace(functor_pair.first, std::regex("wraps_"), "") + " ";
    1247          34 :   if (functor_names.size())
    1248          34 :     functor_names.pop_back();
    1249          34 :   _console << functor_names << std::endl;
    1250          34 : }
    1251             : 
    1252             : void
    1253          34 : SubProblem::showFunctorRequestors() const
    1254             : {
    1255         122 :   for (const auto & [functor, requestors] : _functor_to_requestors)
    1256             :   {
    1257          88 :     _console << "[DBG] Requestors for wrapped functor "
    1258          88 :              << std::regex_replace(functor, std::regex("wraps_"), "") << std::endl;
    1259          88 :     _console << "[DBG] " << MooseUtils::join(requestors, " ") << std::endl;
    1260             :   }
    1261          34 : }
    1262             : 
    1263             : bool
    1264         524 : SubProblem::hasFunctor(const std::string & name, const THREAD_ID tid) const
    1265             : {
    1266             :   mooseAssert(tid < _functors.size(), "Too large a thread ID");
    1267         524 :   auto & functors = _functors[tid];
    1268         524 :   return (functors.find("wraps_" + name) != functors.end());
    1269             : }
    1270             : 
    1271             : Moose::CoordinateSystemType
    1272   425951918 : SubProblem::getCoordSystem(SubdomainID sid) const
    1273             : {
    1274   425951918 :   return mesh().getCoordSystem(sid);
    1275             : }
    1276             : 
    1277             : void
    1278    23545598 : SubProblem::reinitFVFace(const THREAD_ID tid, const FaceInfo & fi)
    1279             : {
    1280    48061804 :   for (const auto nl : make_range(numNonlinearSystems()))
    1281    24516206 :     assembly(tid, nl).reinitFVFace(fi);
    1282    23545598 : }
    1283             : 
    1284             : void
    1285   338318018 : SubProblem::cacheResidual(const THREAD_ID tid)
    1286             : {
    1287   338318018 :   assembly(tid, currentNlSysNum())
    1288   338318018 :       .cacheResidual(Assembly::GlobalDataKey{}, currentResidualVectorTags());
    1289   338318018 : }
    1290             : 
    1291             : void
    1292    35615312 : SubProblem::cacheResidualNeighbor(const THREAD_ID tid)
    1293             : {
    1294    35615312 :   assembly(tid, currentNlSysNum())
    1295    35615312 :       .cacheResidualNeighbor(Assembly::GlobalDataKey{}, currentResidualVectorTags());
    1296    35615312 : }
    1297             : 
    1298             : void
    1299    53000396 : SubProblem::addCachedResidual(const THREAD_ID tid)
    1300             : {
    1301    53000396 :   assembly(tid, currentNlSysNum())
    1302    53000396 :       .addCachedResiduals(Assembly::GlobalDataKey{}, currentResidualVectorTags());
    1303    53000396 : }
    1304             : 
    1305             : void
    1306    51041992 : SubProblem::cacheJacobian(const THREAD_ID tid)
    1307             : {
    1308    51041992 :   assembly(tid, currentNlSysNum()).cacheJacobian(Assembly::GlobalDataKey{});
    1309    51041992 :   if (hasNonlocalCoupling())
    1310        5166 :     assembly(tid, currentNlSysNum()).cacheJacobianNonlocal(Assembly::GlobalDataKey{});
    1311    51041992 : }
    1312             : 
    1313             : void
    1314        9290 : SubProblem::cacheJacobianNeighbor(const THREAD_ID tid)
    1315             : {
    1316        9290 :   assembly(tid, currentNlSysNum()).cacheJacobianNeighbor(Assembly::GlobalDataKey{});
    1317        9290 : }
    1318             : 
    1319             : void
    1320     3819642 : SubProblem::addCachedJacobian(const THREAD_ID tid)
    1321             : {
    1322     3819642 :   assembly(tid, currentNlSysNum()).addCachedJacobian(Assembly::GlobalDataKey{});
    1323     3819638 : }
    1324             : 
    1325             : void
    1326         216 : SubProblem::preparePRefinement()
    1327             : {
    1328         216 :   std::unordered_set<FEFamily> disable_families;
    1329         612 :   for (const auto & [family, flag] : _family_for_p_refinement)
    1330         396 :     if (flag)
    1331         180 :       disable_families.insert(family);
    1332             : 
    1333         450 :   for (const auto tid : make_range(libMesh::n_threads()))
    1334         468 :     for (const auto s : make_range(numNonlinearSystems()))
    1335         234 :       assembly(tid, s).havePRefinement(disable_families);
    1336             : 
    1337         216 :   auto & eq = es();
    1338         396 :   for (const auto family : disable_families)
    1339         540 :     for (const auto i : make_range(eq.n_systems()))
    1340             :     {
    1341         360 :       auto & system = eq.get_system(i);
    1342         360 :       auto & dof_map = system.get_dof_map();
    1343         864 :       for (const auto vg : make_range(system.n_variable_groups()))
    1344             :       {
    1345         504 :         const auto & var_group = system.variable_group(vg);
    1346         504 :         if (var_group.type().family == family)
    1347         180 :           dof_map.should_p_refine(vg, false);
    1348             :       }
    1349             :     }
    1350             : 
    1351         216 :   _have_p_refinement = true;
    1352         216 : }
    1353             : 
    1354             : bool
    1355         424 : SubProblem::doingPRefinement() const
    1356             : {
    1357         424 :   return mesh().doingPRefinement();
    1358             : }
    1359             : 
    1360             : void
    1361      146529 : SubProblem::markFamilyPRefinement(const InputParameters & params)
    1362             : {
    1363      146529 :   auto family = Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family"));
    1364      146529 :   bool flag = _default_families_without_p_refinement.count(family);
    1365      146529 :   if (params.isParamValid("disable_p_refinement"))
    1366         132 :     flag = params.get<bool>("disable_p_refinement");
    1367             : 
    1368      146529 :   auto [it, inserted] = _family_for_p_refinement.emplace(family, flag);
    1369      146529 :   if (!inserted && flag != it->second)
    1370           0 :     mooseError("'disable_p_refinement' not set consistently for variables in ", family);
    1371      146529 : }
    1372             : 
    1373             : void
    1374      139290 : SubProblem::setCurrentLowerDElem(const Elem * const lower_d_elem, const THREAD_ID tid)
    1375             : {
    1376      278580 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
    1377      139290 :     assembly(tid, nl_sys_num).setCurrentLowerDElem(lower_d_elem);
    1378      139290 : }
    1379             : 
    1380             : template MooseVariableFEBase &
    1381             : SubProblem::getVariableHelper(const THREAD_ID tid,
    1382             :                               const std::string & var_name,
    1383             :                               Moose::VarKindType expected_var_type,
    1384             :                               Moose::VarFieldType expected_var_field_type,
    1385             :                               const std::vector<std::shared_ptr<SolverSystem>> & nls,
    1386             :                               const SystemBase & aux) const;
    1387             : template MooseVariableFEBase &
    1388             : SubProblem::getVariableHelper(const THREAD_ID tid,
    1389             :                               const std::string & var_name,
    1390             :                               Moose::VarKindType expected_var_type,
    1391             :                               Moose::VarFieldType expected_var_field_type,
    1392             :                               const std::vector<std::unique_ptr<DisplacedSystem>> & nls,
    1393             :                               const SystemBase & aux) const;

Generated by: LCOV version 1.14