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

Generated by: LCOV version 1.14