LCOV - code coverage report
Current view: top level - src/outputs - BlockRestrictionDebugOutput.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 130 158 82.3 %
Date: 2026-05-29 20:35:17 Functions: 6 6 100.0 %
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             : // MOOSE includes
      11             : #include "BlockRestrictionDebugOutput.h"
      12             : #include "FEProblem.h"
      13             : #include "Material.h"
      14             : #include "ConsoleUtils.h"
      15             : #include "MooseMesh.h"
      16             : #include "MooseObjectName.h"
      17             : #include "NonlinearSystemBase.h"
      18             : #include "MooseVariableBase.h"
      19             : #include "BlockRestrictable.h"
      20             : #include "KernelBase.h"
      21             : #include "AuxiliarySystem.h"
      22             : #include "AuxKernel.h"
      23             : #include "UserObject.h"
      24             : 
      25             : #include "libmesh/transient_system.h"
      26             : 
      27             : using namespace libMesh;
      28             : 
      29             : registerMooseObject("MooseApp", BlockRestrictionDebugOutput);
      30             : 
      31             : InputParameters
      32        3097 : BlockRestrictionDebugOutput::validParams()
      33             : {
      34        3097 :   InputParameters params = Output::validParams();
      35             : 
      36        9291 :   params.addParam<MultiMooseEnum>("scope",
      37        9291 :                                   getScopes("all"),
      38             :                                   "The types of object to output block coverage for, if nothing is "
      39             :                                   "provided everything will be output.");
      40             : 
      41       12388 :   params.addParam<NonlinearSystemName>(
      42             :       "nl_sys", "nl0", "The nonlinear system that we should output information for.");
      43             : 
      44        6194 :   params.addClassDescription(
      45             :       "Debug output object for displaying information regarding block-restriction of objects.");
      46        3097 :   params.set<ExecFlagEnum>("execute_on") = EXEC_INITIAL;
      47        3097 :   return params;
      48           0 : }
      49             : 
      50             : MultiMooseEnum
      51        4816 : BlockRestrictionDebugOutput::getScopes(std::string default_scopes)
      52             : {
      53             :   return MultiMooseEnum("none all variables kernels auxvariables auxkernels materials userobjects",
      54       14448 :                         default_scopes);
      55             : }
      56             : 
      57          18 : BlockRestrictionDebugOutput::BlockRestrictionDebugOutput(const InputParameters & parameters)
      58             :   : Output(parameters),
      59          18 :     _scope(getParam<MultiMooseEnum>("scope")),
      60          18 :     _nl(_problem_ptr->getNonlinearSystemBase(
      61          18 :         _problem_ptr->nlSysNum(getParam<NonlinearSystemName>("nl_sys")))),
      62          36 :     _sys(_nl.system())
      63             : {
      64          18 : }
      65             : 
      66             : void
      67          18 : BlockRestrictionDebugOutput::output()
      68             : {
      69          18 :   printBlockRestrictionMap();
      70          18 : }
      71             : 
      72             : void
      73          18 : BlockRestrictionDebugOutput::printBlockRestrictionMap() const
      74             : {
      75             :   // is there anything to do?
      76          54 :   if (_scope.isValid() && _scope.contains("none"))
      77           0 :     return;
      78             : 
      79             :   // Build output stream
      80          18 :   std::stringstream out;
      81             : 
      82         396 :   auto printCategoryAndNames = [&out](std::string category, std::set<std::string> & names)
      83             :   {
      84         396 :     const auto n = names.size();
      85         396 :     if (n > 0)
      86             :     {
      87             :       // print the category and number of items
      88         108 :       out << "    " << category << " (" << n << " " << ((n == 1) ? "item" : "items") << "): ";
      89             : 
      90             :       // If we would just use Moose::stringify(names), the indention is not right.
      91             :       // So we are printing the names one by one and using ConsoleUtils::insertNewline.
      92         108 :       std::streampos begin_string_pos = out.tellp();
      93         108 :       std::streampos curr_string_pos = begin_string_pos;
      94         108 :       unsigned int i = 0;
      95         234 :       for (const auto & name : names)
      96             :       {
      97         126 :         out << Moose::stringify(name) << ((i++ < (n - 1)) ? ", " : "");
      98         126 :         curr_string_pos = out.tellp();
      99         126 :         ConsoleUtils::insertNewline(out, begin_string_pos, curr_string_pos);
     100             :       }
     101         108 :       out << '\n';
     102         108 :       return true;
     103             :     }
     104             :     else
     105             :     {
     106         288 :       return false;
     107             :     }
     108          18 :   };
     109             : 
     110             :   // Reference to mesh for getting block names
     111          18 :   MooseMesh & mesh = _problem_ptr->mesh();
     112             : 
     113             :   // set of all subdomains in the mesh
     114          18 :   const std::set<SubdomainID> & mesh_subdomains = mesh.meshSubdomains();
     115             : 
     116             :   // get kernels via reference to the Kernel warehouse
     117          18 :   const auto & kernel_warehouse = _nl.getKernelWarehouse();
     118          18 :   const auto & kernels = kernel_warehouse.getObjects(/*tid = */ 0);
     119             : 
     120             :   // AuxSystem
     121          18 :   const auto & auxSystem = _problem_ptr->getAuxiliarySystem();
     122             : 
     123             :   // Reference to the Material warehouse
     124          18 :   const auto & material_warehouse = _problem_ptr->getMaterialWarehouse();
     125             : 
     126             :   // get all user objects
     127          18 :   std::vector<UserObject *> userObjects;
     128          18 :   _problem_ptr->theWarehouse()
     129          18 :       .query()
     130          18 :       .condition<AttribSystem>("UserObject")
     131          36 :       .condition<AttribThread>(0)
     132          18 :       .queryIntoUnsorted(userObjects);
     133             : 
     134             :   // do we have to check all object types?
     135          36 :   const bool include_all = !_scope.isValid() || _scope.contains("all");
     136             : 
     137             :   // iterate all subdomains
     138          54 :   for (const auto & subdomain_id : mesh_subdomains)
     139             :   {
     140             :     // get the corresponding subdomain name
     141          36 :     const auto & subdomain_name = mesh.getSubdomainName(subdomain_id);
     142             : 
     143          36 :     out << "\n";
     144          36 :     out << "  Subdomain '" << subdomain_name << "' (id " << subdomain_id << "):\n";
     145             : 
     146          36 :     bool objectsFound = false;
     147             : 
     148             :     // Variables
     149          36 :     if (include_all || _scope.contains("variables"))
     150             :     {
     151          36 :       std::set<std::string> names;
     152          72 :       for (unsigned int var_num = 0; var_num < _sys.n_vars(); var_num++)
     153             :       {
     154          36 :         const auto & var_name = _sys.variable_name(var_num);
     155          36 :         if (_problem_ptr->hasVariable(var_name))
     156             :         {
     157             :           const MooseVariableBase & var =
     158          36 :               _problem_ptr->getVariable(/*tid = */ 0,
     159             :                                         var_name,
     160             :                                         Moose::VarKindType::VAR_ANY,
     161          36 :                                         Moose::VarFieldType::VAR_FIELD_ANY);
     162          36 :           if (var.hasBlocks(subdomain_id))
     163          36 :             names.insert(var_name);
     164             :         }
     165             :       }
     166          72 :       objectsFound = printCategoryAndNames("Variables", names) || objectsFound;
     167          36 :     }
     168             : 
     169             :     // Kernels
     170          36 :     if (include_all || _scope.contains("kernels"))
     171             :     {
     172          36 :       std::set<std::string> names;
     173          72 :       for (const auto & kernel : kernels)
     174             :       {
     175          36 :         if (kernel->hasBlocks(subdomain_id))
     176          36 :           names.insert(kernel->name());
     177             :       }
     178          72 :       objectsFound = printCategoryAndNames("Kernels", names) || objectsFound;
     179          36 :     }
     180             : 
     181             :     // AuxVariables
     182          36 :     if (include_all || _scope.contains("auxvariables"))
     183             :     {
     184          36 :       std::set<std::string> names;
     185          36 :       const auto & sys = auxSystem.system();
     186          36 :       for (unsigned int vg = 0; vg < sys.n_variable_groups(); vg++)
     187             :       {
     188           0 :         const VariableGroup & vg_description(sys.variable_group(vg));
     189           0 :         for (unsigned int vn = 0; vn < vg_description.n_variables(); vn++)
     190             :         {
     191           0 :           if (vg_description.active_on_subdomain(subdomain_id))
     192           0 :             names.insert(vg_description.name(vn));
     193             :         }
     194             :       }
     195          72 :       objectsFound = printCategoryAndNames("AuxVariables", names) || objectsFound;
     196          36 :     }
     197             : 
     198             :     // AuxKernels
     199          36 :     if (include_all || _scope.contains("auxkernels"))
     200             :     {
     201             : 
     202             :       {
     203          36 :         const auto & wh = auxSystem.nodalAuxWarehouse();
     204          36 :         std::set<std::string> names;
     205          36 :         if (wh.hasActiveBlockObjects(subdomain_id))
     206             :         {
     207           0 :           const auto & auxkernels = wh.getActiveBlockObjects(subdomain_id);
     208           0 :           for (auto & auxkernel : auxkernels)
     209           0 :             names.insert(auxkernel->name());
     210             :         }
     211          72 :         objectsFound = printCategoryAndNames("AuxKernels[nodal]", names) || objectsFound;
     212          36 :       }
     213             : 
     214             :       {
     215          36 :         const auto & wh = auxSystem.nodalVectorAuxWarehouse();
     216          36 :         std::set<std::string> names;
     217          36 :         if (wh.hasActiveBlockObjects(subdomain_id))
     218             :         {
     219           0 :           const auto & auxkernels = wh.getActiveBlockObjects(subdomain_id);
     220           0 :           for (auto & auxkernel : auxkernels)
     221           0 :             names.insert(auxkernel->name());
     222             :         }
     223          72 :         objectsFound = printCategoryAndNames("AuxKernels[nodalVector]", names) || objectsFound;
     224          36 :       }
     225             : 
     226             :       {
     227          36 :         const auto & wh = auxSystem.nodalArrayAuxWarehouse();
     228          36 :         std::set<std::string> names;
     229          36 :         if (wh.hasActiveBlockObjects(subdomain_id))
     230             :         {
     231           0 :           const auto & auxkernels = wh.getActiveBlockObjects(subdomain_id);
     232           0 :           for (auto & auxkernel : auxkernels)
     233           0 :             names.insert(auxkernel->name());
     234             :         }
     235          72 :         objectsFound = printCategoryAndNames("AuxKernels[nodalArray]", names) || objectsFound;
     236          36 :       }
     237             : 
     238             :       {
     239          36 :         const auto & wh = auxSystem.elemAuxWarehouse();
     240          36 :         std::set<std::string> names;
     241          36 :         if (wh.hasActiveBlockObjects(subdomain_id))
     242             :         {
     243           0 :           const auto & auxkernels = wh.getActiveBlockObjects(subdomain_id);
     244           0 :           for (auto & auxkernel : auxkernels)
     245           0 :             names.insert(auxkernel->name());
     246             :         }
     247          72 :         objectsFound = printCategoryAndNames("AuxKernels[elemAux]", names) || objectsFound;
     248          36 :       }
     249             : 
     250             :       {
     251          36 :         const auto & wh = auxSystem.elemVectorAuxWarehouse();
     252          36 :         std::set<std::string> names;
     253          36 :         if (wh.hasActiveBlockObjects(subdomain_id))
     254             :         {
     255           0 :           const auto & auxkernels = wh.getActiveBlockObjects(subdomain_id);
     256           0 :           for (auto & auxkernel : auxkernels)
     257           0 :             names.insert(auxkernel->name());
     258             :         }
     259          72 :         objectsFound = printCategoryAndNames("AuxKernels[elemVector]", names) || objectsFound;
     260          36 :       }
     261             : 
     262             :       {
     263          36 :         const auto & wh = auxSystem.elemArrayAuxWarehouse();
     264          36 :         std::set<std::string> names;
     265          36 :         if (wh.hasActiveBlockObjects(subdomain_id))
     266             :         {
     267           0 :           const auto & auxkernels = wh.getActiveBlockObjects(subdomain_id);
     268           0 :           for (auto & auxkernel : auxkernels)
     269           0 :             names.insert(auxkernel->name());
     270             :         }
     271          72 :         objectsFound = printCategoryAndNames("AuxKernels[elemArray]", names) || objectsFound;
     272          36 :       }
     273             :     }
     274             : 
     275             :     // Materials
     276          36 :     if (include_all || _scope.contains("materials"))
     277             :     {
     278          36 :       std::set<std::string> names;
     279          36 :       if (material_warehouse.hasActiveBlockObjects(subdomain_id))
     280             :       {
     281          36 :         auto const objs = material_warehouse.getBlockObjects(subdomain_id);
     282          90 :         for (const auto & mat : objs)
     283          54 :           names.insert(mat->name());
     284          36 :       }
     285          72 :       objectsFound = printCategoryAndNames("Materials", names) || objectsFound;
     286          36 :     }
     287             : 
     288             :     // UserObjects
     289          36 :     if (include_all || _scope.contains("userobjects"))
     290             :     {
     291          36 :       std::set<std::string> names;
     292          36 :       for (const auto & obj : userObjects)
     293           0 :         if (BlockRestrictable * blockrestrictable_obj = dynamic_cast<BlockRestrictable *>(obj))
     294           0 :           if (blockrestrictable_obj->hasBlocks(subdomain_id))
     295           0 :             names.insert(obj->name());
     296          72 :       objectsFound = printCategoryAndNames("UserObjects", names) || objectsFound;
     297          36 :     }
     298             : 
     299          36 :     if (!objectsFound)
     300           0 :       out << "    (no objects found)\n";
     301             :   }
     302             : 
     303          18 :   out << std::flush;
     304             : 
     305             :   // Write the stored string to the ConsoleUtils output objects
     306          18 :   _console << "\n[DBG] Block-Restrictions (" << mesh_subdomains.size()
     307          18 :            << " subdomains): showing active objects\n";
     308          18 :   _console << std::setw(ConsoleUtils::console_field_width) << out.str() << std::endl;
     309          18 : }

Generated by: LCOV version 1.14