LCOV - code coverage report
Current view: top level - src/problems - SubProblem.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 593 661 89.7 %
Date: 2025-08-08 20:01:16 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      357765 : SubProblem::validParams()
      37             : {
      38      357765 :   InputParameters params = Problem::validParams();
      39             : 
      40     1073295 :   params.addParam<bool>(
      41             :       "default_ghosting",
      42      715530 :       false,
      43             :       "Whether or not to use libMesh's default amount of algebraic and geometric ghosting");
      44             : 
      45      357765 :   params.addParamNamesToGroup("default_ghosting", "Advanced");
      46             : 
      47      357765 :   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       64731 : SubProblem::SubProblem(const InputParameters & parameters)
      61             :   : Problem(parameters),
      62       64731 :     _factory(_app.getFactory()),
      63       64731 :     _default_ghosting(getParam<bool>("default_ghosting")),
      64       64731 :     _currently_computing_jacobian(false),
      65       64731 :     _currently_computing_residual_and_jacobian(false),
      66       64731 :     _computing_nonlinear_residual(false),
      67       64731 :     _currently_computing_residual(false),
      68       64731 :     _safe_access_tagged_matrices(false),
      69       64731 :     _safe_access_tagged_vectors(false),
      70       64731 :     _have_ad_objects(false),
      71       64731 :     _output_functors(false),
      72       64731 :     _typed_vector_tags(2),
      73      258924 :     _have_p_refinement(false)
      74             : {
      75       64731 :   unsigned int n_threads = libMesh::n_threads();
      76       64731 :   _active_elemental_moose_variables.resize(n_threads);
      77       64731 :   _has_active_elemental_moose_variables.resize(n_threads);
      78             : 
      79       64731 :   _active_fe_var_coupleable_matrix_tags.resize(n_threads);
      80       64731 :   _active_fe_var_coupleable_vector_tags.resize(n_threads);
      81       64731 :   _active_sc_var_coupleable_matrix_tags.resize(n_threads);
      82       64731 :   _active_sc_var_coupleable_vector_tags.resize(n_threads);
      83             : 
      84       64731 :   _functors.resize(n_threads);
      85       64731 :   _pbblf_functors.resize(n_threads);
      86       64731 :   _functor_to_request_info.resize(n_threads);
      87       64731 : }
      88             : 
      89       60383 : SubProblem::~SubProblem() {}
      90             : 
      91             : TagID
      92      483889 : SubProblem::addVectorTag(const TagName & tag_name,
      93             :                          const Moose::VectorTagType type /* = Moose::VECTOR_TAG_RESIDUAL */)
      94             : {
      95      483889 :   if (type == Moose::VECTOR_TAG_ANY)
      96           0 :     mooseError("Vector tag type cannot be VECTOR_TAG_ANY");
      97             : 
      98      483889 :   const auto tag_name_upper = MooseUtils::toUpper(tag_name);
      99             : 
     100             :   // First, see if the tag exists already
     101     2145731 :   for (const auto & vector_tag : _vector_tags)
     102             :   {
     103             :     mooseAssert(_vector_tags[vector_tag._id] == vector_tag, "Vector tags index mismatch");
     104     1755586 :     if (vector_tag._name == tag_name_upper)
     105             :     {
     106       93744 :       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       93744 :       return vector_tag._id;
     116             :     }
     117             :   }
     118             : 
     119             :   // Doesn't exist - create it
     120      390145 :   const TagID new_tag_id = _vector_tags.size();
     121      390145 :   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      390145 :   _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      390145 :   _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      390145 :   _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      390145 :   verifyVectorTags();
     131             : 
     132      390145 :   return new_tag_id;
     133      483889 : }
     134             : 
     135             : bool
     136      326695 : SubProblem::vectorTagExists(const TagName & tag_name) const
     137             : {
     138             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     139             : 
     140      326695 :   const auto tag_name_upper = MooseUtils::toUpper(tag_name);
     141     3018729 :   for (const auto & vector_tag : _vector_tags)
     142     2706627 :     if (vector_tag._name == tag_name_upper)
     143       14593 :       return true;
     144             : 
     145      312102 :   return false;
     146      326695 : }
     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     9466836 : SubProblem::vectorTagNotZeroed(const TagID tag) const
     156             : {
     157     9466836 :   return _not_zeroed_tagged_vectors.count(tag);
     158             : }
     159             : 
     160             : const VectorTag &
     161   933508989 : SubProblem::getVectorTag(const TagID tag_id) const
     162             : {
     163             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     164             : 
     165   933508989 :   if (!vectorTagExists(tag_id))
     166           0 :     mooseError("Vector tag with ID ", tag_id, " does not exist");
     167             : 
     168   933508989 :   return _vector_tags[tag_id];
     169             : }
     170             : 
     171             : std::vector<VectorTag>
     172     6573130 : SubProblem::getVectorTags(const std::set<TagID> & tag_ids) const
     173             : {
     174             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     175             : 
     176     6573130 :   std::vector<VectorTag> tags;
     177     6573130 :   tags.reserve(tag_ids.size());
     178    25524013 :   for (const auto & tag_id : tag_ids)
     179    18950883 :     tags.push_back(getVectorTag(tag_id));
     180     6573130 :   return tags;
     181           0 : }
     182             : 
     183             : const std::vector<VectorTag> &
     184    11442069 : SubProblem::getVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
     185             : {
     186             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     187             : 
     188    11442069 :   if (type == Moose::VECTOR_TAG_ANY)
     189      550989 :     return _vector_tags;
     190             :   else
     191    10891080 :     return _typed_vector_tags[type];
     192             : }
     193             : 
     194             : unsigned int
     195     8080647 : SubProblem::numVectorTags(const Moose::VectorTagType type /* = Moose::VECTOR_TAG_ANY */) const
     196             : {
     197             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     198             : 
     199     8080647 :   return getVectorTags(type).size();
     200             : }
     201             : 
     202             : TagID
     203     6719334 : SubProblem::getVectorTagID(const TagName & tag_name) const
     204             : {
     205             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     206             : 
     207     6719334 :   const auto tag_name_upper = MooseUtils::toUpper(tag_name);
     208     6719334 :   const auto search = _vector_tags_name_map.find(tag_name_upper);
     209     6719334 :   if (search != _vector_tags_name_map.end())
     210    13438636 :     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     6719318 : }
     219             : 
     220             : TagName
     221      162614 : SubProblem::vectorTagName(const TagID tag_id) const
     222             : {
     223             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     224      162614 :   if (!vectorTagExists(tag_id))
     225           0 :     mooseError("Vector tag with ID ", tag_id, " does not exist");
     226             : 
     227      162614 :   return _vector_tags[tag_id]._name;
     228             : }
     229             : 
     230             : Moose::VectorTagType
     231  2507929963 : SubProblem::vectorTagType(const TagID tag_id) const
     232             : {
     233             :   mooseAssert(verifyVectorTags(), "Vector tag storage invalid");
     234  2507929963 :   if (!vectorTagExists(tag_id))
     235           0 :     mooseError("Vector tag with ID ", tag_id, " does not exist");
     236             : 
     237  2507929963 :   return _vector_tags[tag_id]._type;
     238             : }
     239             : 
     240             : bool
     241      390145 : SubProblem::verifyVectorTags() const
     242             : {
     243     1971120 :   for (TagID tag_id = 0; tag_id < _vector_tags.size(); ++tag_id)
     244             :   {
     245     1580975 :     const auto & vector_tag = _vector_tags[tag_id];
     246             : 
     247     1580975 :     if (vector_tag._id != tag_id)
     248           0 :       mooseError("Vector tag ", vector_tag._id, " id mismatch in _vector_tags");
     249     1580975 :     if (vector_tag._type == Moose::VECTOR_TAG_ANY)
     250           0 :       mooseError("Vector tag '", vector_tag._name, "' has type VECTOR_TAG_ANY");
     251             : 
     252     1580975 :     const auto search = _vector_tags_name_map.find(vector_tag._name);
     253     1580975 :     if (search == _vector_tags_name_map.end())
     254           0 :       mooseError("Vector tag ", vector_tag._id, " is not in _vector_tags_name_map");
     255     1580975 :     else if (search->second != tag_id)
     256           0 :       mooseError("Vector tag ", vector_tag._id, " has incorrect id in _vector_tags_name_map");
     257             : 
     258     1580975 :     unsigned int found_in_type = 0;
     259     6530176 :     for (TagTypeID tag_type_id = 0; tag_type_id < _typed_vector_tags[vector_tag._type].size();
     260             :          ++tag_type_id)
     261             :     {
     262     4949201 :       const auto & vector_tag_type = _typed_vector_tags[vector_tag._type][tag_type_id];
     263     4949201 :       if (vector_tag_type == vector_tag)
     264             :       {
     265     1580975 :         ++found_in_type;
     266     1580975 :         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     1580975 :     if (found_in_type == 0)
     272           0 :       mooseError("Vector tag ", tag_id, " not found in _typed_vector_tags");
     273     1580975 :     if (found_in_type > 1)
     274           0 :       mooseError("Vector tag ", tag_id, " found multiple times in _typed_vector_tags");
     275             :   }
     276             : 
     277      390145 :   unsigned int num_typed_vector_tags = 0;
     278     1170435 :   for (const auto & typed_vector_tags : _typed_vector_tags)
     279      780290 :     num_typed_vector_tags += typed_vector_tags.size();
     280      390145 :   if (num_typed_vector_tags != _vector_tags.size())
     281           0 :     mooseError("Size mismatch between _vector_tags and _typed_vector_tags");
     282      390145 :   if (_vector_tags_name_map.size() != _vector_tags.size())
     283           0 :     mooseError("Size mismatch between _vector_tags and _vector_tags_name_map");
     284             : 
     285      390145 :   return true;
     286             : }
     287             : 
     288             : void
     289     3252629 : SubProblem::selectVectorTagsFromSystem(const SystemBase & system,
     290             :                                        const std::vector<VectorTag> & input_vector_tags,
     291             :                                        std::set<TagID> & selected_tags)
     292             : {
     293     3252629 :   selected_tags.clear();
     294    12671440 :   for (const auto & vector_tag : input_vector_tags)
     295     9418811 :     if (system.hasVector(vector_tag._id))
     296     9418189 :       selected_tags.insert(vector_tag._id);
     297     3252629 : }
     298             : 
     299             : void
     300        5366 : SubProblem::selectMatrixTagsFromSystem(const SystemBase & system,
     301             :                                        const std::map<TagName, TagID> & input_matrix_tags,
     302             :                                        std::set<TagID> & selected_tags)
     303             : {
     304        5366 :   selected_tags.clear();
     305       10869 :   for (const auto & matrix_tag_pair : input_matrix_tags)
     306        5503 :     if (system.hasMatrix(matrix_tag_pair.second))
     307        5390 :       selected_tags.insert(matrix_tag_pair.second);
     308        5366 : }
     309             : 
     310             : TagID
     311      126332 : SubProblem::addMatrixTag(TagName tag_name)
     312             : {
     313      126332 :   auto tag_name_upper = MooseUtils::toUpper(tag_name);
     314      126332 :   auto existing_tag = _matrix_tag_name_to_tag_id.find(tag_name_upper);
     315      126332 :   if (existing_tag == _matrix_tag_name_to_tag_id.end())
     316             :   {
     317      125815 :     auto tag_id = _matrix_tag_name_to_tag_id.size();
     318             : 
     319      125815 :     _matrix_tag_name_to_tag_id[tag_name_upper] = tag_id;
     320             : 
     321      125815 :     _matrix_tag_id_to_tag_name[tag_id] = tag_name_upper;
     322             :   }
     323             : 
     324      252664 :   return _matrix_tag_name_to_tag_id.at(tag_name_upper);
     325      126332 : }
     326             : 
     327             : bool
     328      297957 : SubProblem::matrixTagExists(const TagName & tag_name) const
     329             : {
     330      297957 :   auto tag_name_upper = MooseUtils::toUpper(tag_name);
     331             : 
     332      595914 :   return _matrix_tag_name_to_tag_id.find(tag_name_upper) != _matrix_tag_name_to_tag_id.end();
     333      297957 : }
     334             : 
     335             : bool
     336     1636908 : SubProblem::matrixTagExists(TagID tag_id) const
     337             : {
     338     1636908 :   return _matrix_tag_id_to_tag_name.find(tag_id) != _matrix_tag_id_to_tag_name.end();
     339             : }
     340             : 
     341             : TagID
     342      296547 : SubProblem::getMatrixTagID(const TagName & tag_name) const
     343             : {
     344      296547 :   auto tag_name_upper = MooseUtils::toUpper(tag_name);
     345             : 
     346      296547 :   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      593086 :   return _matrix_tag_name_to_tag_id.at(tag_name_upper);
     354      296543 : }
     355             : 
     356             : TagName
     357         348 : SubProblem::matrixTagName(TagID tag)
     358             : {
     359         348 :   return _matrix_tag_id_to_tag_name[tag];
     360             : }
     361             : 
     362             : void
     363      635077 : SubProblem::setActiveFEVariableCoupleableMatrixTags(std::set<TagID> & mtags, const THREAD_ID tid)
     364             : {
     365      635077 :   _active_fe_var_coupleable_matrix_tags[tid] = mtags;
     366      635077 : }
     367             : 
     368             : void
     369     7415273 : SubProblem::setActiveFEVariableCoupleableVectorTags(std::set<TagID> & vtags, const THREAD_ID tid)
     370             : {
     371     7415273 :   _active_fe_var_coupleable_vector_tags[tid] = vtags;
     372    14962702 :   for (const auto sys_num : make_range(numSolverSystems()))
     373     7547429 :     systemBaseSolver(sys_num).setActiveVariableCoupleableVectorTags(vtags, tid);
     374     7415273 :   systemBaseAuxiliary().setActiveVariableCoupleableVectorTags(vtags, tid);
     375     7415273 : }
     376             : 
     377             : void
     378      296657 : SubProblem::clearActiveFEVariableCoupleableVectorTags(const THREAD_ID tid)
     379             : {
     380      296657 :   _active_fe_var_coupleable_vector_tags[tid].clear();
     381      296657 : }
     382             : 
     383             : void
     384      296657 : SubProblem::clearActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid)
     385             : {
     386      296657 :   _active_fe_var_coupleable_matrix_tags[tid].clear();
     387      296657 : }
     388             : 
     389             : const std::set<TagID> &
     390  1941354761 : SubProblem::getActiveFEVariableCoupleableMatrixTags(const THREAD_ID tid) const
     391             : {
     392  1941354761 :   return _active_fe_var_coupleable_matrix_tags[tid];
     393             : }
     394             : 
     395             : const std::set<TagID> &
     396         334 : SubProblem::getActiveFEVariableCoupleableVectorTags(const THREAD_ID tid) const
     397             : {
     398         334 :   return _active_fe_var_coupleable_vector_tags[tid];
     399             : }
     400             : 
     401             : void
     402       56031 : SubProblem::setActiveScalarVariableCoupleableMatrixTags(std::set<TagID> & mtags,
     403             :                                                         const THREAD_ID tid)
     404             : {
     405       56031 :   _active_sc_var_coupleable_matrix_tags[tid] = mtags;
     406       56031 : }
     407             : 
     408             : void
     409       56031 : SubProblem::setActiveScalarVariableCoupleableVectorTags(std::set<TagID> & vtags,
     410             :                                                         const THREAD_ID tid)
     411             : {
     412       56031 :   _active_sc_var_coupleable_vector_tags[tid] = vtags;
     413      112062 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     414       56031 :     systemBaseNonlinear(nl_sys_num).setActiveScalarVariableCoupleableVectorTags(vtags, tid);
     415       56031 :   systemBaseAuxiliary().setActiveScalarVariableCoupleableVectorTags(vtags, tid);
     416       56031 : }
     417             : 
     418             : void
     419       56031 : SubProblem::clearActiveScalarVariableCoupleableVectorTags(const THREAD_ID tid)
     420             : {
     421       56031 :   _active_sc_var_coupleable_vector_tags[tid].clear();
     422       56031 : }
     423             : 
     424             : void
     425       56031 : SubProblem::clearActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid)
     426             : {
     427       56031 :   _active_sc_var_coupleable_matrix_tags[tid].clear();
     428       56031 : }
     429             : 
     430             : const std::set<TagID> &
     431      573761 : SubProblem::getActiveScalarVariableCoupleableMatrixTags(const THREAD_ID tid) const
     432             : {
     433      573761 :   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    11402727 : SubProblem::setActiveElementalMooseVariables(const std::set<MooseVariableFEBase *> & moose_vars,
     444             :                                              const THREAD_ID tid)
     445             : {
     446    11402727 :   if (!moose_vars.empty())
     447             :   {
     448    11060248 :     _has_active_elemental_moose_variables[tid] = 1;
     449    11060248 :     _active_elemental_moose_variables[tid] = moose_vars;
     450             :   }
     451    11402727 : }
     452             : 
     453             : const std::set<MooseVariableFEBase *> &
     454  1274264875 : SubProblem::getActiveElementalMooseVariables(const THREAD_ID tid) const
     455             : {
     456  1274264875 :   return _active_elemental_moose_variables[tid];
     457             : }
     458             : 
     459             : bool
     460  1319349218 : SubProblem::hasActiveElementalMooseVariables(const THREAD_ID tid) const
     461             : {
     462  1319349218 :   return _has_active_elemental_moose_variables[tid];
     463             : }
     464             : 
     465             : void
     466     4850814 : SubProblem::clearActiveElementalMooseVariables(const THREAD_ID tid)
     467             : {
     468     4850814 :   _has_active_elemental_moose_variables[tid] = 0;
     469     4850814 :   _active_elemental_moose_variables[tid].clear();
     470     4850814 : }
     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         360 : SubProblem::hasBlockMaterialProperty(SubdomainID bid, const std::string & prop_name)
     512             : {
     513         360 :   auto it = _map_block_material_props.find(bid);
     514         360 :   if (it == _map_block_material_props.end())
     515           0 :     return false;
     516             : 
     517         360 :   if (it->second.count(prop_name) > 0)
     518         270 :     return true;
     519             :   else
     520          90 :     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       67510 : SubProblem::storeSubdomainMatPropName(SubdomainID block_id, const std::string & name)
     584             : {
     585       67510 :   _map_block_material_props[block_id].insert(name);
     586       67510 : }
     587             : 
     588             : void
     589       63542 : SubProblem::storeBoundaryMatPropName(BoundaryID boundary_id, const std::string & name)
     590             : {
     591       63542 :   _map_boundary_material_props[boundary_id].insert(name);
     592       63542 : }
     593             : 
     594             : void
     595        9522 : SubProblem::storeSubdomainZeroMatProp(SubdomainID block_id, const MaterialPropertyName & name)
     596             : {
     597        9522 :   _zero_block_material_props[block_id].insert(name);
     598        9522 : }
     599             : 
     600             : void
     601        9522 : SubProblem::storeBoundaryZeroMatProp(BoundaryID boundary_id, const MaterialPropertyName & name)
     602             : {
     603        9522 :   _zero_boundary_material_props[boundary_id].insert(name);
     604        9522 : }
     605             : 
     606             : void
     607       45359 : SubProblem::storeSubdomainDelayedCheckMatProp(const std::string & requestor,
     608             :                                               SubdomainID block_id,
     609             :                                               const std::string & name)
     610             : {
     611       45359 :   _map_block_material_props_check[block_id].insert(std::make_pair(requestor, name));
     612       45359 : }
     613             : 
     614             : void
     615        6131 : SubProblem::storeBoundaryDelayedCheckMatProp(const std::string & requestor,
     616             :                                              BoundaryID boundary_id,
     617             :                                              const std::string & name)
     618             : {
     619        6131 :   _map_boundary_material_props_check[boundary_id].insert(std::make_pair(requestor, name));
     620        6131 : }
     621             : 
     622             : void
     623       60531 : SubProblem::checkBlockMatProps()
     624             : {
     625             :   // Variable for storing all available blocks/boundaries from the mesh
     626       60531 :   std::set<SubdomainID> all_ids(mesh().meshSubdomains());
     627             : 
     628       60531 :   std::stringstream errors;
     629             : 
     630             :   // Loop through the properties to check
     631       66542 :   for (const auto & check_it : _map_block_material_props_check)
     632             :   {
     633             :     // The current id for the property being checked (BoundaryID || BlockID)
     634        6011 :     SubdomainID check_id = check_it.first;
     635             : 
     636        6011 :     std::set<SubdomainID> check_ids = {check_id};
     637             : 
     638             :     // Loop through all the block/boundary ids
     639       12022 :     for (const auto & id : check_ids)
     640             :     {
     641             :       // Loop through all the stored properties
     642       49143 :       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       43238 :         if (_map_block_material_props[id].count(prop_it.second) == 0 &&
     648       43238 :             _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        6011 :   }
     659             : 
     660       60531 :   if (!errors.str().empty())
     661          40 :     mooseError(errors.str());
     662       60491 : }
     663             : 
     664             : void
     665       60491 : SubProblem::checkBoundaryMatProps()
     666             : {
     667             :   // Variable for storing the value for ANY_BOUNDARY_ID
     668       60491 :   BoundaryID any_id = Moose::ANY_BOUNDARY_ID;
     669             : 
     670             :   // Variable for storing all available blocks/boundaries from the mesh
     671       60491 :   std::set<BoundaryID> all_ids(mesh().getBoundaryIDs());
     672             : 
     673       60491 :   std::stringstream errors;
     674             : 
     675             :   // Loop through the properties to check
     676       63082 :   for (const auto & check_it : _map_boundary_material_props_check)
     677             :   {
     678             :     // The current id for the property being checked (BoundaryID || BlockID)
     679        2591 :     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        2591 :     std::set<BoundaryID> check_ids{check_id};
     684        2591 :     if (check_id == any_id)
     685           0 :       check_ids = all_ids;
     686             : 
     687             :     // Loop through all the block/boundary ids
     688        5182 :     for (const auto & id : check_ids)
     689             :     {
     690             :       // Loop through all the stored properties
     691        8722 :       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        6131 :         if (_map_boundary_material_props[id].count(prop_it.second) == 0 &&
     697        4830 :             _map_boundary_material_props[any_id].count(prop_it.second) == 0 &&
     698       23238 :             _zero_boundary_material_props[id].count(prop_it.second) == 0 &&
     699        6146 :             _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        2591 :   }
     710             : 
     711       60491 :   if (!errors.str().empty())
     712          12 :     mooseError(errors.str());
     713       60479 : }
     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       64092 : SubProblem::markMatPropRequested(const std::string & prop_name)
     725             : {
     726       64092 :   _material_property_requested.insert(prop_name);
     727       64092 : }
     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       49906 : SubProblem::addConsumedPropertyName(const MooseObjectName & obj_name, const std::string & prop_name)
     737             : {
     738       49906 :   _consumed_material_properties[obj_name].insert(prop_name);
     739       49906 : }
     740             : 
     741             : const std::map<MooseObjectName, std::set<std::string>> &
     742         218 : SubProblem::getConsumedPropertyMap() const
     743             : {
     744         218 :   return _consumed_material_properties;
     745             : }
     746             : 
     747             : DiracKernelInfo &
     748         999 : SubProblem::diracKernelInfo()
     749             : {
     750         999 :   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   144883499 : SubProblem::setCurrentBoundaryID(BoundaryID bid, const THREAD_ID tid)
     790             : {
     791   291067649 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     792   146184150 :     assembly(tid, nl_sys_num).setCurrentBoundaryID(bid);
     793   144883499 : }
     794             : 
     795             : unsigned int
     796         216 : SubProblem::getAxisymmetricRadialCoord() const
     797             : {
     798         216 :   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          18 : SubProblem::hasAuxiliaryVariable(const std::string & var_name) const
     812             : {
     813          18 :   return systemBaseAuxiliary().hasVariable(var_name);
     814             : }
     815             : 
     816             : template <typename T>
     817             : MooseVariableFEBase &
     818     4738196 : 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     4738196 :   MooseVariableFEBase * var = nullptr;
     827             : 
     828     4738196 :   const auto [var_in_sys, sys_num] = determineSolverSystem(var_name);
     829             : 
     830             :   // First check that the variable is found on the expected system.
     831     4738196 :   if (expected_var_type == Moose::VarKindType::VAR_ANY)
     832             :   {
     833     2571579 :     if (var_in_sys)
     834     1166541 :       var = &(systems[sys_num]->getVariable(tid, var_name));
     835     1405038 :     else if (aux.hasVariable(var_name))
     836     1405038 :       var = &(aux.getVariable(tid, var_name));
     837             :     else
     838           0 :       mooseError("Unknown variable " + var_name);
     839             :   }
     840     2358363 :   else if (expected_var_type == Moose::VarKindType::VAR_SOLVER && var_in_sys &&
     841      191746 :            systems[sys_num]->hasVariable(var_name))
     842      191746 :     var = &(systems[sys_num]->getVariable(tid, var_name));
     843     1974871 :   else if (expected_var_type == Moose::VarKindType::VAR_AUXILIARY && aux.hasVariable(var_name))
     844     1974871 :     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     6967613 :   if ((expected_var_field_type == Moose::VarFieldType::VAR_FIELD_ANY) ||
     860     2229417 :       (expected_var_field_type == var->fieldType()))
     861     4738188 :     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      306709 : 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      613418 :   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      306709 :     assembly(tid, nl_sys_num).reinitElemFaceRef(elem, side, tolerance, pts, weights);
     897             : 
     898      306709 :     auto & nl = systemBaseNonlinear(nl_sys_num);
     899             : 
     900             :     // Actually get the dof indices in the moose variables
     901      306709 :     nl.prepare(tid);
     902             : 
     903             :     // Let's finally compute our variable values!
     904      306709 :     nl.reinitElemFace(elem, side, tid);
     905             :   }
     906             : 
     907             :   // do same for aux as for nl
     908      306709 :   systemBaseAuxiliary().prepare(tid);
     909      306709 :   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      306709 :   auto & current_assembly = assembly(tid, currentNlSysNum());
     914      306709 :   if (currentlyComputingJacobian() || currentlyComputingResidualAndJacobian())
     915      101151 :     current_assembly.prepareJacobianBlock();
     916      306709 :   if (!currentlyComputingJacobian())
     917      205558 :     current_assembly.prepareResidual();
     918      306709 : }
     919             : 
     920             : void
     921      306709 : 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      613418 :   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      306709 :     assembly(tid, nl_sys_num)
     936      306709 :         .reinitNeighborFaceRef(neighbor_elem, neighbor_side, tolerance, pts, weights);
     937             : 
     938      306709 :     auto & nl = systemBaseNonlinear(nl_sys_num);
     939             : 
     940             :     // Actually get the dof indices in the moose variables
     941      306709 :     nl.prepareNeighbor(tid);
     942             : 
     943             :     // Let's finally compute our variable values!
     944      306709 :     nl.reinitNeighborFace(neighbor_elem, neighbor_side, tid);
     945             :   }
     946             : 
     947             :   // do same for aux as for nl
     948      306709 :   systemBaseAuxiliary().prepareNeighbor(tid);
     949      306709 :   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      306709 :   assembly(tid, currentNlSysNum()).prepareNeighbor();
     954      306709 : }
     955             : 
     956             : void
     957      325712 : 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      651424 :   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      325712 :     assembly(tid, nl_sys_num).reinitLowerDElem(elem, pts, weights);
     967             : 
     968      325712 :     auto & nl = systemBaseNonlinear(nl_sys_num);
     969             : 
     970             :     // Actually get the dof indices in the moose variables
     971      325712 :     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      325712 :     assembly(tid, nl_sys_num).prepareLowerD();
     976             : 
     977             :     // Let's finally compute our variable values!
     978      325712 :     nl.reinitLowerD(tid);
     979             :   }
     980             : 
     981             :   // do same for aux as for nl
     982      325712 :   systemBaseAuxiliary().prepareLowerD(tid);
     983      325712 :   systemBaseAuxiliary().reinitLowerD(tid);
     984      325712 : }
     985             : 
     986             : void
     987      284081 : SubProblem::reinitNeighborLowerDElem(const Elem * elem, const THREAD_ID tid)
     988             : {
     989      568162 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     990      284081 :     assembly(tid, nl_sys_num).reinitNeighborLowerDElem(elem);
     991      284081 : }
     992             : 
     993             : void
     994      568162 : SubProblem::reinitMortarElem(const Elem * elem, const THREAD_ID tid)
     995             : {
     996     1136324 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
     997      568162 :     assembly(tid, nl_sys_num).reinitMortarElem(elem);
     998      568162 : }
     999             : 
    1000             : void
    1001       33595 : SubProblem::cloneAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf, bool to_mesh)
    1002             : {
    1003       33595 :   EquationSystems & eq = es();
    1004       33595 :   const auto n_sys = eq.n_systems();
    1005             : 
    1006       67190 :   auto pr = _root_alg_gf_to_sys_clones.emplace(
    1007       33595 :       &algebraic_gf, std::vector<std::shared_ptr<GhostingFunctor>>(n_sys - 1));
    1008             :   mooseAssert(pr.second, "We are adding a duplicate algebraic ghosting functor");
    1009       33595 :   auto & clones_vec = pr.first->second;
    1010             : 
    1011       67378 :   for (MooseIndex(n_sys) i = 1; i < n_sys; ++i)
    1012             :   {
    1013       33783 :     DofMap & dof_map = eq.get_system(i).get_dof_map();
    1014       33783 :     std::shared_ptr<GhostingFunctor> clone_alg_gf = algebraic_gf.clone();
    1015       67566 :     std::dynamic_pointer_cast<RelationshipManager>(clone_alg_gf)
    1016       33783 :         ->init(mesh(), *algebraic_gf.get_mesh(), &dof_map);
    1017       33783 :     dof_map.add_algebraic_ghosting_functor(clone_alg_gf, to_mesh);
    1018       33783 :     clones_vec[i - 1] = clone_alg_gf;
    1019       33783 :   }
    1020       33595 : }
    1021             : 
    1022             : void
    1023       33595 : SubProblem::addAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf, bool to_mesh)
    1024             : {
    1025       33595 :   EquationSystems & eq = es();
    1026       33595 :   const auto n_sys = eq.n_systems();
    1027       33595 :   if (!n_sys)
    1028           0 :     return;
    1029             : 
    1030       33595 :   eq.get_system(0).get_dof_map().add_algebraic_ghosting_functor(algebraic_gf, to_mesh);
    1031       33595 :   cloneAlgebraicGhostingFunctor(algebraic_gf, to_mesh);
    1032             : }
    1033             : 
    1034             : void
    1035       45486 : SubProblem::cloneCouplingGhostingFunctor(GhostingFunctor & coupling_gf, bool to_mesh)
    1036             : {
    1037       45486 :   const std::size_t num_nl_sys = numNonlinearSystems();
    1038             : 
    1039       90972 :   auto pr = _root_coupling_gf_to_sys_clones.emplace(
    1040       45486 :       &coupling_gf, std::vector<std::shared_ptr<GhostingFunctor>>(num_nl_sys - 1));
    1041             :   mooseAssert(pr.second, "We are adding a duplicate coupling functor");
    1042       45486 :   auto & clones_vec = pr.first->second;
    1043             : 
    1044       45685 :   for (const auto i : make_range(std::size_t(1), num_nl_sys))
    1045             :   {
    1046         199 :     DofMap & dof_map = systemBaseNonlinear(i).system().get_dof_map();
    1047         199 :     std::shared_ptr<GhostingFunctor> clone_coupling_gf = coupling_gf.clone();
    1048         398 :     std::dynamic_pointer_cast<RelationshipManager>(clone_coupling_gf)
    1049         199 :         ->init(mesh(), *coupling_gf.get_mesh(), &dof_map);
    1050         199 :     dof_map.add_coupling_functor(clone_coupling_gf, to_mesh);
    1051         199 :     clones_vec[i - 1] = clone_coupling_gf;
    1052         199 :   }
    1053       45486 : }
    1054             : 
    1055             : void
    1056       46750 : SubProblem::addCouplingGhostingFunctor(GhostingFunctor & coupling_gf, bool to_mesh)
    1057             : {
    1058       46750 :   const auto num_nl_sys = numNonlinearSystems();
    1059       46750 :   if (!num_nl_sys)
    1060        1264 :     return;
    1061             : 
    1062       45486 :   systemBaseNonlinear(0).system().get_dof_map().add_coupling_functor(coupling_gf, to_mesh);
    1063       45486 :   cloneCouplingGhostingFunctor(coupling_gf, to_mesh);
    1064             : }
    1065             : 
    1066             : void
    1067          30 : SubProblem::removeAlgebraicGhostingFunctor(GhostingFunctor & algebraic_gf)
    1068             : {
    1069          30 :   EquationSystems & eq = es();
    1070          30 :   const auto n_sys = eq.n_systems();
    1071          30 :   DofMap & nl_dof_map = eq.get_system(0).get_dof_map();
    1072             : 
    1073             :   const bool found_in_root_sys =
    1074          30 :       std::find(nl_dof_map.algebraic_ghosting_functors_begin(),
    1075             :                 nl_dof_map.algebraic_ghosting_functors_end(),
    1076          60 :                 &algebraic_gf) != nl_dof_map.algebraic_ghosting_functors_end();
    1077             : 
    1078             : #ifndef NDEBUG
    1079             :   const bool found_in_our_map =
    1080             :       _root_alg_gf_to_sys_clones.find(&algebraic_gf) != _root_alg_gf_to_sys_clones.end();
    1081             :   mooseAssert(found_in_root_sys == found_in_our_map,
    1082             :               "If the ghosting functor exists in the root DofMap, then we need to have a key for "
    1083             :               "it in our gf to clones map");
    1084             : #endif
    1085             : 
    1086          30 :   if (found_in_root_sys) // libMesh yells if we try to remove
    1087             :                          // something that's not there
    1088           0 :     nl_dof_map.remove_algebraic_ghosting_functor(algebraic_gf);
    1089             : 
    1090          30 :   auto it = _root_alg_gf_to_sys_clones.find(&algebraic_gf);
    1091          30 :   if (it == _root_alg_gf_to_sys_clones.end())
    1092          30 :     return;
    1093             : 
    1094           0 :   auto & clones_vec = it->second;
    1095             :   mooseAssert((n_sys - 1) == clones_vec.size(),
    1096             :               "The size of the gf clones vector doesn't match the number of systems minus one");
    1097           0 :   if (clones_vec.empty())
    1098             :   {
    1099             :     mooseAssert(n_sys == 1, "The clones vector should only be empty if there is only one system");
    1100           0 :     return;
    1101             :   }
    1102             : 
    1103           0 :   for (const auto i : make_range(n_sys))
    1104           0 :     eq.get_system(i + 1).get_dof_map().remove_algebraic_ghosting_functor(*clones_vec[i]);
    1105             : 
    1106           0 :   _root_alg_gf_to_sys_clones.erase(it->first);
    1107             : }
    1108             : 
    1109             : void
    1110          30 : SubProblem::removeCouplingGhostingFunctor(GhostingFunctor & coupling_gf)
    1111             : {
    1112          30 :   EquationSystems & eq = es();
    1113          30 :   const auto num_nl_sys = numNonlinearSystems();
    1114          30 :   if (!num_nl_sys)
    1115          30 :     return;
    1116             : 
    1117          30 :   DofMap & nl_dof_map = eq.get_system(0).get_dof_map();
    1118          30 :   const bool found_in_root_sys = std::find(nl_dof_map.coupling_functors_begin(),
    1119             :                                            nl_dof_map.coupling_functors_end(),
    1120          60 :                                            &coupling_gf) != nl_dof_map.coupling_functors_end();
    1121             : 
    1122             : #ifndef NDEBUG
    1123             :   const bool found_in_our_map =
    1124             :       _root_coupling_gf_to_sys_clones.find(&coupling_gf) != _root_coupling_gf_to_sys_clones.end();
    1125             :   mooseAssert(found_in_root_sys == found_in_our_map,
    1126             :               "If the ghosting functor exists in the root DofMap, then we need to have a key for "
    1127             :               "it in our gf to clones map");
    1128             : #endif
    1129             : 
    1130          30 :   if (found_in_root_sys) // libMesh yells if we try to remove
    1131             :                          // something that's not there
    1132          30 :     nl_dof_map.remove_coupling_functor(coupling_gf);
    1133             : 
    1134          30 :   auto it = _root_coupling_gf_to_sys_clones.find(&coupling_gf);
    1135          30 :   if (it == _root_coupling_gf_to_sys_clones.end())
    1136           0 :     return;
    1137             : 
    1138          30 :   auto & clones_vec = it->second;
    1139             :   mooseAssert((num_nl_sys - 1) == clones_vec.size(),
    1140             :               "The size of the gf clones vector doesn't match the number of systems minus one");
    1141          30 :   if (clones_vec.empty())
    1142             :   {
    1143             :     mooseAssert(num_nl_sys == 1,
    1144             :                 "The clones vector should only be empty if there is only one nonlinear system");
    1145          30 :     return;
    1146             :   }
    1147             : 
    1148           0 :   for (const auto i : make_range(num_nl_sys))
    1149           0 :     eq.get_system(i + 1).get_dof_map().remove_coupling_functor(*clones_vec[i]);
    1150             : 
    1151           0 :   _root_coupling_gf_to_sys_clones.erase(it->first);
    1152             : }
    1153             : 
    1154             : void
    1155       66379 : SubProblem::automaticScaling(bool automatic_scaling)
    1156             : {
    1157      131717 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
    1158       65338 :     systemBaseNonlinear(nl_sys_num).automaticScaling(automatic_scaling);
    1159       66379 : }
    1160             : 
    1161             : bool
    1162       14652 : SubProblem::automaticScaling() const
    1163             : {
    1164             :   // Currently going to assume that we are applying or not applying automatic scaling consistently
    1165             :   // across nonlinear systems
    1166       14652 :   return systemBaseNonlinear(0).automaticScaling();
    1167             : }
    1168             : 
    1169             : void
    1170         363 : SubProblem::hasScalingVector(const unsigned int nl_sys_num)
    1171             : {
    1172         786 :   for (const THREAD_ID tid : make_range(libMesh::n_threads()))
    1173         423 :     assembly(tid, nl_sys_num).hasScalingVector();
    1174         363 : }
    1175             : 
    1176             : void
    1177      377715 : SubProblem::clearAllDofIndices()
    1178             : {
    1179      768334 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
    1180      390619 :     systemBaseNonlinear(nl_sys_num).clearAllDofIndices();
    1181      377715 :   systemBaseAuxiliary().clearAllDofIndices();
    1182      377715 : }
    1183             : 
    1184             : void
    1185      316573 : SubProblem::timestepSetup()
    1186             : {
    1187      661129 :   for (auto & map : _pbblf_functors)
    1188      355986 :     for (auto & pr : map)
    1189       11430 :       pr.second->timestepSetup();
    1190      316573 : }
    1191             : 
    1192             : void
    1193     2039946 : SubProblem::customSetup(const ExecFlagType & exec_type)
    1194             : {
    1195     4261978 :   for (auto & map : _pbblf_functors)
    1196     2300751 :     for (auto & pr : map)
    1197       78719 :       pr.second->customSetup(exec_type);
    1198     2039946 : }
    1199             : 
    1200             : void
    1201     3418604 : SubProblem::residualSetup()
    1202             : {
    1203     7144304 :   for (auto & map : _pbblf_functors)
    1204     3823122 :     for (auto & pr : map)
    1205       97422 :       pr.second->residualSetup();
    1206     3418604 : }
    1207             : 
    1208             : void
    1209      540556 : SubProblem::jacobianSetup()
    1210             : {
    1211     1131041 :   for (auto & map : _pbblf_functors)
    1212      606971 :     for (auto & pr : map)
    1213       16486 :       pr.second->jacobianSetup();
    1214      540556 : }
    1215             : 
    1216             : void
    1217       62254 : SubProblem::initialSetup()
    1218             : {
    1219       62254 :   if (_output_functors)
    1220             :   {
    1221          36 :     showFunctors();
    1222          36 :     showFunctorRequestors();
    1223             :   }
    1224             : 
    1225      130263 :   for (const auto & functors : _functors)
    1226      375016 :     for (const auto & [functor_wrapper_name, functor_wrapper] : functors)
    1227             :     {
    1228      307007 :       const auto & [true_functor_type, non_ad_functor, ad_functor] = functor_wrapper;
    1229             :       mooseAssert(non_ad_functor->wrapsNull() == ad_functor->wrapsNull(), "These must agree");
    1230      307007 :       const auto functor_name = removeSubstring(functor_wrapper_name, "wraps_");
    1231      307007 :       if (non_ad_functor->wrapsNull())
    1232           0 :         mooseError(
    1233             :             "No functor ever provided with name '",
    1234             :             functor_name,
    1235             :             "', which was requested by '",
    1236           0 :             MooseUtils::join(libmesh_map_find(_functor_to_requestors, functor_wrapper_name), ","),
    1237             :             "'.");
    1238      489934 :       if (true_functor_type == TrueFunctorIs::NONAD ? non_ad_functor->ownsWrappedFunctor()
    1239      182927 :                                                     : ad_functor->ownsWrappedFunctor())
    1240           0 :         mooseError("Functor envelopes should not own the functors they wrap, but '",
    1241             :                    functor_name,
    1242             :                    "' is owned by the wrapper. Please open a MOOSE issue for help resolving this.");
    1243      307007 :     }
    1244       62254 : }
    1245             : 
    1246             : void
    1247          36 : SubProblem::showFunctors() const
    1248             : {
    1249          36 :   _console << "[DBG] Wrapped functors found in Subproblem" << std::endl;
    1250          36 :   std::string functor_names = "[DBG] ";
    1251         284 :   for (const auto & functor_pair : _functors[0])
    1252         248 :     functor_names += std::regex_replace(functor_pair.first, std::regex("wraps_"), "") + " ";
    1253          36 :   if (functor_names.size())
    1254          36 :     functor_names.pop_back();
    1255          36 :   _console << functor_names << std::endl;
    1256          36 : }
    1257             : 
    1258             : void
    1259          36 : SubProblem::showFunctorRequestors() const
    1260             : {
    1261         128 :   for (const auto & [functor, requestors] : _functor_to_requestors)
    1262             :   {
    1263          92 :     _console << "[DBG] Requestors for wrapped functor "
    1264          92 :              << std::regex_replace(functor, std::regex("wraps_"), "") << std::endl;
    1265          92 :     _console << "[DBG] " << MooseUtils::join(requestors, " ") << std::endl;
    1266             :   }
    1267          36 : }
    1268             : 
    1269             : bool
    1270         550 : SubProblem::hasFunctor(const std::string & name, const THREAD_ID tid) const
    1271             : {
    1272             :   mooseAssert(tid < _functors.size(), "Too large a thread ID");
    1273         550 :   auto & functors = _functors[tid];
    1274         550 :   return (functors.find("wraps_" + name) != functors.end());
    1275             : }
    1276             : 
    1277             : Moose::CoordinateSystemType
    1278   473324641 : SubProblem::getCoordSystem(SubdomainID sid) const
    1279             : {
    1280   473324641 :   return mesh().getCoordSystem(sid);
    1281             : }
    1282             : 
    1283             : void
    1284    25427893 : SubProblem::reinitFVFace(const THREAD_ID tid, const FaceInfo & fi)
    1285             : {
    1286    51947720 :   for (const auto nl : make_range(numNonlinearSystems()))
    1287    26519827 :     assembly(tid, nl).reinitFVFace(fi);
    1288    25427893 : }
    1289             : 
    1290             : void
    1291   374344236 : SubProblem::cacheResidual(const THREAD_ID tid)
    1292             : {
    1293   374344236 :   assembly(tid, currentNlSysNum())
    1294   374344236 :       .cacheResidual(Assembly::GlobalDataKey{}, currentResidualVectorTags());
    1295   374344236 : }
    1296             : 
    1297             : void
    1298    38414020 : SubProblem::cacheResidualNeighbor(const THREAD_ID tid)
    1299             : {
    1300    38414020 :   assembly(tid, currentNlSysNum())
    1301    38414020 :       .cacheResidualNeighbor(Assembly::GlobalDataKey{}, currentResidualVectorTags());
    1302    38414020 : }
    1303             : 
    1304             : void
    1305    57645873 : SubProblem::addCachedResidual(const THREAD_ID tid)
    1306             : {
    1307    57645873 :   assembly(tid, currentNlSysNum())
    1308    57645873 :       .addCachedResiduals(Assembly::GlobalDataKey{}, currentResidualVectorTags());
    1309    57645873 : }
    1310             : 
    1311             : void
    1312    56920459 : SubProblem::cacheJacobian(const THREAD_ID tid)
    1313             : {
    1314    56920459 :   assembly(tid, currentNlSysNum()).cacheJacobian(Assembly::GlobalDataKey{});
    1315    56920459 :   if (hasNonlocalCoupling())
    1316        5880 :     assembly(tid, currentNlSysNum()).cacheJacobianNonlocal(Assembly::GlobalDataKey{});
    1317    56920459 : }
    1318             : 
    1319             : void
    1320       10576 : SubProblem::cacheJacobianNeighbor(const THREAD_ID tid)
    1321             : {
    1322       10576 :   assembly(tid, currentNlSysNum()).cacheJacobianNeighbor(Assembly::GlobalDataKey{});
    1323       10576 : }
    1324             : 
    1325             : void
    1326     4209834 : SubProblem::addCachedJacobian(const THREAD_ID tid)
    1327             : {
    1328     4209834 :   assembly(tid, currentNlSysNum()).addCachedJacobian(Assembly::GlobalDataKey{});
    1329     4209830 : }
    1330             : 
    1331             : void
    1332         234 : SubProblem::preparePRefinement()
    1333             : {
    1334         234 :   std::unordered_set<FEFamily> disable_families;
    1335         663 :   for (const auto & [family, flag] : _family_for_p_refinement)
    1336         429 :     if (flag)
    1337         195 :       disable_families.insert(family);
    1338             : 
    1339         486 :   for (const auto tid : make_range(libMesh::n_threads()))
    1340         504 :     for (const auto s : make_range(numNonlinearSystems()))
    1341         252 :       assembly(tid, s).havePRefinement(disable_families);
    1342             : 
    1343         234 :   auto & eq = es();
    1344         429 :   for (const auto family : disable_families)
    1345         585 :     for (const auto i : make_range(eq.n_systems()))
    1346             :     {
    1347         390 :       auto & system = eq.get_system(i);
    1348         390 :       auto & dof_map = system.get_dof_map();
    1349         936 :       for (const auto vg : make_range(system.n_variable_groups()))
    1350             :       {
    1351         546 :         const auto & var_group = system.variable_group(vg);
    1352         546 :         if (var_group.type().family == family)
    1353         195 :           dof_map.should_p_refine(vg, false);
    1354             :       }
    1355             :     }
    1356             : 
    1357         234 :   _have_p_refinement = true;
    1358         234 : }
    1359             : 
    1360             : bool
    1361         464 : SubProblem::doingPRefinement() const
    1362             : {
    1363         464 :   return mesh().doingPRefinement();
    1364             : }
    1365             : 
    1366             : void
    1367      157903 : SubProblem::markFamilyPRefinement(const InputParameters & params)
    1368             : {
    1369      157903 :   auto family = Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family"));
    1370      157903 :   bool flag = _default_families_without_p_refinement.count(family);
    1371      157903 :   if (params.isParamValid("disable_p_refinement"))
    1372         143 :     flag = params.get<bool>("disable_p_refinement");
    1373             : 
    1374      157903 :   auto [it, inserted] = _family_for_p_refinement.emplace(family, flag);
    1375      157903 :   if (!inserted && flag != it->second)
    1376           0 :     mooseError("'disable_p_refinement' not set consistently for variables in ", family);
    1377      157903 : }
    1378             : 
    1379             : void
    1380      156189 : SubProblem::setCurrentLowerDElem(const Elem * const lower_d_elem, const THREAD_ID tid)
    1381             : {
    1382      312378 :   for (const auto nl_sys_num : make_range(numNonlinearSystems()))
    1383      156189 :     assembly(tid, nl_sys_num).setCurrentLowerDElem(lower_d_elem);
    1384      156189 : }
    1385             : 
    1386             : template MooseVariableFEBase &
    1387             : SubProblem::getVariableHelper(const THREAD_ID tid,
    1388             :                               const std::string & var_name,
    1389             :                               Moose::VarKindType expected_var_type,
    1390             :                               Moose::VarFieldType expected_var_field_type,
    1391             :                               const std::vector<std::shared_ptr<SolverSystem>> & nls,
    1392             :                               const SystemBase & aux) const;
    1393             : template MooseVariableFEBase &
    1394             : SubProblem::getVariableHelper(const THREAD_ID tid,
    1395             :                               const std::string & var_name,
    1396             :                               Moose::VarKindType expected_var_type,
    1397             :                               Moose::VarFieldType expected_var_field_type,
    1398             :                               const std::vector<std::unique_ptr<DisplacedSystem>> & nls,
    1399             :                               const SystemBase & aux) const;

Generated by: LCOV version 1.14