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 "UniqueExtraIDMeshGenerator.h" 11 : #include "MooseMeshUtils.h" 12 : #include "libmesh/elem.h" 13 : 14 : registerMooseObject("MooseApp", UniqueExtraIDMeshGenerator); 15 : 16 : InputParameters 17 3141 : UniqueExtraIDMeshGenerator::validParams() 18 : { 19 3141 : InputParameters params = MeshGenerator::validParams(); 20 12564 : params.addRequiredParam<MeshGeneratorName>( 21 : "input", "Name of an existing mesh generator to which we assign extra element IDs"); 22 12564 : params.addRequiredParam<std::vector<ExtraElementIDName>>( 23 : "id_name", 24 : "Existing extra integer ID names that is used to generate a new extra integer ID by finding " 25 : "unique combinations of their values"); 26 12564 : params.addRequiredParam<ExtraElementIDName>("new_id_name", "New extra integer ID name"); 27 12564 : params.addParam<std::vector<unsigned int>>( 28 : "new_id_rule", 29 : "Vector of unsigned integers to determine new integer ID values by multiplying the provided " 30 : "integers to the corresponding existing ID values and then summing the resulting values"); 31 12564 : params.addParam<std::vector<SubdomainName>>( 32 : "restricted_subdomains", "Only set new extra element id for elements in given subdomains"); 33 3141 : params.addClassDescription("Add a new extra element integer ID by finding unique combinations of " 34 : "the existing extra element integer ID values"); 35 3141 : return params; 36 0 : } 37 : 38 40 : UniqueExtraIDMeshGenerator::UniqueExtraIDMeshGenerator(const InputParameters & params) 39 : : MeshGenerator(params), 40 40 : _input(getMesh("input")), 41 80 : _extra_ids(getParam<std::vector<ExtraElementIDName>>("id_name")), 42 80 : _use_new_id_rule(isParamValid("new_id_rule")), 43 120 : _has_restriction(isParamValid("restricted_subdomains")) 44 : { 45 50 : if (_use_new_id_rule && 46 70 : getParam<std::vector<unsigned int>>("new_id_rule").size() != _extra_ids.size()) 47 0 : paramError("new_id_rule", 48 : "This parameter, if provided, must have a length equal to length of id_name."); 49 40 : } 50 : 51 : std::unique_ptr<MeshBase> 52 40 : UniqueExtraIDMeshGenerator::generate() 53 : { 54 40 : std::unique_ptr<MeshBase> mesh = std::move(_input); 55 : 56 : // Make sure subdomain caches are up to date 57 40 : if (!mesh->preparation().has_cached_elem_data) 58 10 : mesh->cache_elem_data(); 59 : 60 40 : std::set<SubdomainID> restricted_ids; 61 40 : if (_has_restriction) 62 : { 63 20 : auto names = getParam<std::vector<SubdomainName>>("restricted_subdomains"); 64 20 : for (auto & name : names) 65 : { 66 : // check that the subdomain exists in the mesh 67 10 : if (!MooseMeshUtils::hasSubdomainName(*mesh, name)) 68 0 : paramError("restricted_subdomains", "The block '", name, "' was not found in the mesh"); 69 : 70 10 : restricted_ids.insert(MooseMeshUtils::getSubdomainID(name, *mesh)); 71 : } 72 10 : } 73 : 74 : auto parsed_ids = 75 40 : MooseMeshUtils::getExtraIDUniqueCombinationMap(*mesh, restricted_ids, _extra_ids); 76 : 77 : // override the extra ID values from MooseMeshUtils::getExtraIDUniqueCombinationMap by using 78 : // new_id_rule 79 40 : if (_use_new_id_rule) 80 : { 81 20 : std::vector<unsigned int> new_id_rule = getParam<std::vector<unsigned int>>("new_id_rule"); 82 10 : std::vector<unsigned int> existing_extra_id_index; 83 30 : for (const auto & id_name : _extra_ids) 84 20 : existing_extra_id_index.push_back(mesh->get_elem_integer_index(id_name)); 85 458 : for (auto & elem : mesh->active_local_element_ptr_range()) 86 : { 87 448 : dof_id_type new_id_value = 0; 88 1344 : for (unsigned int i = 0; i < _extra_ids.size(); ++i) 89 896 : new_id_value += new_id_rule[i] * elem->get_extra_integer(existing_extra_id_index[i]); 90 448 : parsed_ids[elem->id()] = new_id_value; 91 10 : } 92 10 : } 93 80 : auto new_id_name = getParam<ExtraElementIDName>("new_id_name"); 94 : unsigned int extra_id_index; 95 40 : if (!mesh->has_elem_integer(new_id_name)) 96 40 : extra_id_index = mesh->add_elem_integer(new_id_name); 97 : else 98 : { 99 0 : extra_id_index = mesh->get_elem_integer_index(new_id_name); 100 0 : paramWarning( 101 : "new_id_name", "An element integer with the name '", new_id_name, "' already exists"); 102 : } 103 : 104 19880 : for (auto & elem : mesh->active_element_ptr_range()) 105 : { 106 19840 : if (_has_restriction && restricted_ids.count(elem->subdomain_id()) == 0) 107 480 : continue; 108 19360 : elem->set_extra_integer(extra_id_index, parsed_ids.at(elem->id())); 109 40 : } 110 80 : return mesh; 111 40 : }