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