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 : }