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 "SideSetsFromNodeSetsGenerator.h" 11 : 12 : #include "CastUniquePointer.h" 13 : #include "libmesh/boundary_info.h" 14 : #include "libmesh/elem_side_builder.h" 15 : 16 : registerMooseObject("MooseApp", SideSetsFromNodeSetsGenerator); 17 : 18 : InputParameters 19 14789 : SideSetsFromNodeSetsGenerator::validParams() 20 : { 21 14789 : InputParameters params = MeshGenerator::validParams(); 22 : 23 29578 : params.addClassDescription("Mesh generator which constructs side sets from node sets"); 24 59156 : params.addRequiredParam<MeshGeneratorName>("input", 25 : "Input mesh the operation will be applied to"); 26 44367 : params.addParam<std::vector<BoundaryName>>( 27 : "nodesets_to_convert", 28 : "If specified, list of nodesets to convert. If not specified, all nodesets are converted"); 29 14789 : return params; 30 0 : } 31 : 32 22 : SideSetsFromNodeSetsGenerator::SideSetsFromNodeSetsGenerator(const InputParameters & parameters) 33 44 : : MeshGenerator(parameters), _input(getMesh("input")) 34 : { 35 22 : } 36 : 37 : std::unique_ptr<MeshBase> 38 22 : SideSetsFromNodeSetsGenerator::generate() 39 : { 40 66 : if (!isParamValid("nodesets_to_convert")) 41 11 : _input->get_boundary_info().build_side_list_from_node_list(); 42 : else 43 : { 44 22 : const auto & nodeset_names = getParam<std::vector<BoundaryName>>("nodesets_to_convert"); 45 11 : auto & binfo = _input->get_boundary_info(); 46 : 47 11 : std::map<BoundaryName, BoundaryID> new_nodeset_ids; 48 11 : std::set<BoundaryID> nodeset_ids; 49 : 50 22 : for (const auto & nodeset_name : nodeset_names) 51 : { 52 : // Look through the nodeset map. 53 11 : BoundaryID nodeset_id = std::numeric_limits<BoundaryID>::max(); 54 77 : for (const auto & [id, name] : binfo.get_nodeset_name_map()) 55 66 : if (name == nodeset_name) 56 11 : nodeset_id = id; 57 11 : if (MooseUtils::isDigits(nodeset_name)) 58 0 : nodeset_id = std::stoi(nodeset_name); 59 11 : if (nodeset_id == std::numeric_limits<BoundaryID>::max()) 60 0 : paramError("nodesets_to_convert", 61 0 : "Nodeset '" + nodeset_name + "' does not exist in the input mesh"); 62 11 : nodeset_ids.insert(nodeset_id); 63 : 64 : // Find the target ID if there is already a sideset with that name 65 11 : if (MooseUtils::isDigits(nodeset_name)) 66 0 : new_nodeset_ids[nodeset_name] = nodeset_id; 67 11 : else if (binfo.get_sideset_name(nodeset_id) == nodeset_name) 68 0 : new_nodeset_ids[nodeset_name] = binfo.get_id_by_name(nodeset_name); 69 : else 70 11 : new_nodeset_ids[nodeset_name] = nodeset_id; 71 : } 72 : 73 : // Copy pasted from libMesh's build_side_list_from_node_list 74 : // For avoiding extraneous element side construction 75 11 : libMesh::ElemSideBuilder side_builder; 76 : // Pull objects out of the loop to reduce heap operations 77 : const Elem * side_elem; 78 11 : const auto & boundary_node_ids = binfo.get_nodeset_map(); 79 : 80 179 : for (const auto & elem : _input->active_element_ptr_range()) 81 840 : for (auto side : elem->side_index_range()) 82 : { 83 672 : side_elem = &side_builder(*elem, side); 84 : 85 : // map from nodeset_id to count for that ID 86 672 : std::map<boundary_id_type, unsigned> nodesets_node_count; 87 : 88 : // For each nodeset that this node is a member of, increment the associated 89 : // nodeset ID count 90 2016 : for (const auto & node : side_elem->node_ref_range()) 91 2688 : for (const auto & pr : as_range(boundary_node_ids.equal_range(&node))) 92 : // Single added new line 93 1344 : if (nodeset_ids.count(pr.second)) 94 352 : nodesets_node_count[pr.second]++; 95 : 96 : // Now check to see what nodeset_counts have the correct 97 : // number of nodes in them. For any that do, add this side to 98 : // the sideset, making sure the sideset inherits the 99 : // nodeset's name, if there is one. 100 936 : for (const auto & pr : nodesets_node_count) 101 264 : if (pr.second == side_elem->n_nodes()) 102 88 : binfo.add_side(elem, side, pr.first); 103 : 104 : // Add nodeset name in case it does not exist yet 105 1344 : for (const auto & [nodeset_name, new_nodeset_id] : new_nodeset_ids) 106 672 : binfo.sideset_name(new_nodeset_id) = nodeset_name; 107 683 : } 108 11 : } 109 : 110 22 : return dynamic_pointer_cast<MeshBase>(_input); 111 : }