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 "SubdomainExtraElementIDGenerator.h" 11 : 12 : registerMooseObject("ReactorApp", SubdomainExtraElementIDGenerator); 13 : 14 : #include "MooseMeshUtils.h" 15 : 16 : #include "libmesh/elem.h" 17 : 18 : InputParameters 19 72 : SubdomainExtraElementIDGenerator::validParams() 20 : { 21 72 : InputParameters params = MeshGenerator::validParams(); 22 144 : params.addRequiredParam<MeshGeneratorName>( 23 : "input", "Name of an existing mesh generator to which we assign element IDs"); 24 144 : params.addRequiredParam<std::vector<SubdomainName>>("subdomains", 25 : "Subdomain names present in the input mesh"); 26 144 : params.addRequiredParam<std::vector<std::string>>("extra_element_id_names", 27 : "List of user-defined extra element ID names"); 28 144 : params.addRequiredParam<std::vector<std::vector<dof_id_type>>>( 29 : "extra_element_ids", 30 : "User-defined extra element IDs corresponding to 'subdomains' in the same order"); 31 : 32 144 : params.addParam<std::vector<dof_id_type>>( 33 : "default_extra_element_ids", "Default extra element IDs for elements not in 'subdomains'"); 34 : 35 72 : params.addClassDescription( 36 : "Assign extra element IDs for elements on a mesh based on mesh subdomains."); 37 72 : return params; 38 0 : } 39 : 40 40 : SubdomainExtraElementIDGenerator::SubdomainExtraElementIDGenerator(const InputParameters & params) 41 : : MeshGenerator(params), 42 40 : _input(getMesh("input")), 43 80 : _subdomain_names(getParam<std::vector<SubdomainName>>("subdomains")), 44 80 : _id_names(getParam<std::vector<std::string>>("extra_element_id_names")), 45 80 : _ids(getParam<std::vector<std::vector<dof_id_type>>>("extra_element_ids")), 46 80 : _defaults(queryParam<std::vector<dof_id_type>>("default_extra_element_ids")) 47 : { 48 40 : if (_subdomain_names.size() == 0) 49 2 : paramError("subdomains", "Empty subdomain vector provided!"); 50 38 : if (_id_names.size() != _ids.size()) 51 4 : paramError("extra_element_ids", 52 : "Inconsistent vector size for element IDs (must have same size as " 53 : "'extra_element_id_names')"); 54 94 : for (const auto i : index_range(_ids)) 55 60 : if (_subdomain_names.size() != _ids[i].size()) 56 0 : paramError("extra_element_ids", 57 0 : "Inconsistent vector size for element IDs at index " + std::to_string(i) + 58 : " (must have same size as 'subdomains')"); 59 34 : if (_defaults && _defaults->size() != _id_names.size()) 60 2 : paramError("default_extra_element_ids", 61 : "Inconsistent vector size for default element IDs (must have same size as " 62 : "'extra_element_id_names')"); 63 32 : } 64 : 65 : std::unique_ptr<MeshBase> 66 32 : SubdomainExtraElementIDGenerator::generate() 67 : { 68 32 : std::unique_ptr<MeshBase> mesh = std::move(_input); 69 : 70 : // We'll be querying the mesh for subdomain ids 71 32 : if (!mesh->preparation().has_cached_elem_data) 72 32 : mesh->cache_elem_data(); 73 : 74 : // construct a map from the subdomain ID to the index in 'subdomains' 75 32 : const auto subdomain_ids = MooseMeshUtils::getSubdomainIDs(*mesh, _subdomain_names); 76 : 77 : // check that all subdomains are present 78 201 : for (const auto & name : _subdomain_names) 79 171 : if (!MooseMeshUtils::hasSubdomainName(*mesh, name)) 80 4 : paramError("subdomains", "Subdomain " + name + " does not exist in the mesh"); 81 : 82 : // check to make sure no duplicated subdomain ids 83 : std::set<SubdomainID> unique_subdomain_ids; 84 193 : for (const auto & id : subdomain_ids) 85 : if (unique_subdomain_ids.count(id) > 0) 86 2 : paramError("subdomains", "Cannot have subdomain with ID ", id, " listed more than once!"); 87 : else 88 163 : unique_subdomain_ids.insert(id); 89 : 90 : std::map<SubdomainID, unsigned int> subdomains; 91 189 : for (const auto i : index_range(_subdomain_names)) 92 161 : subdomains[subdomain_ids[i]] = i; 93 : 94 : // get indices for all extra element integers 95 : std::vector<unsigned int> extra_id_indices; 96 70 : for (const auto & id_name : _id_names) 97 : { 98 42 : if (!mesh->has_elem_integer(id_name)) 99 84 : extra_id_indices.push_back(mesh->add_elem_integer(id_name)); 100 : else 101 0 : extra_id_indices.push_back(mesh->get_elem_integer_index(id_name)); 102 : } 103 : 104 15470 : for (auto & elem : mesh->element_ptr_range()) 105 : { 106 7707 : if (const auto it = subdomains.find(elem->subdomain_id()); it != subdomains.end()) 107 : { 108 16254 : for (const auto i : index_range(_ids)) 109 8687 : elem->set_extra_integer(extra_id_indices[i], _ids[i][it->second]); 110 : } 111 140 : else if (_defaults) 112 : { 113 560 : for (const auto i : index_range(_ids)) 114 420 : elem->set_extra_integer(extra_id_indices[i], (*_defaults)[i]); 115 : } 116 28 : } 117 : 118 28 : return mesh; 119 56 : }