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 "BreakBoundaryOnSubdomainGenerator.h" 11 : #include "CastUniquePointer.h" 12 : 13 : #include "MooseUtils.h" 14 : #include "MooseMeshUtils.h" 15 : 16 : #include "libmesh/elem.h" 17 : 18 : registerMooseObject("MooseApp", BreakBoundaryOnSubdomainGenerator); 19 : 20 : InputParameters 21 15053 : BreakBoundaryOnSubdomainGenerator::validParams() 22 : { 23 15053 : InputParameters params = MeshGenerator::validParams(); 24 : 25 15053 : params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify"); 26 15053 : params.addClassDescription("Break boundaries based on the subdomains to which their sides are " 27 : "attached. Naming convention for the new boundaries will be the old " 28 : "boundary name plus \"_to_\" plus the subdomain name"); 29 15053 : params.addParam<std::vector<BoundaryName>>( 30 : "boundaries", "Boundaries to be broken. Default means to break all boundaries"); 31 : 32 15053 : return params; 33 0 : } 34 : 35 394 : BreakBoundaryOnSubdomainGenerator::BreakBoundaryOnSubdomainGenerator( 36 394 : const InputParameters & parameters) 37 394 : : MeshGenerator(parameters), _input(getMesh("input")) 38 : { 39 394 : } 40 : 41 : std::unique_ptr<MeshBase> 42 367 : BreakBoundaryOnSubdomainGenerator::generate() 43 : { 44 : // get the mesh and boundary info 45 367 : std::unique_ptr<MeshBase> mesh = std::move(_input); 46 367 : auto & boundary_info = mesh->get_boundary_info(); 47 : 48 : // get IDs of all boundaries to be broken 49 367 : std::set<boundary_id_type> breaking_boundary_ids; 50 367 : if (isParamValid("boundaries")) 51 : { 52 23 : auto & boundary_names = getParam<std::vector<BoundaryName>>("boundaries"); 53 61 : for (auto & boundary_name : boundary_names) 54 : { 55 : // check that the boundary exists in the mesh 56 42 : if (!MooseMeshUtils::hasBoundaryName(*mesh, boundary_name)) 57 4 : paramError("boundaries", "The boundary '", boundary_name, "' was not found in the mesh"); 58 : 59 38 : breaking_boundary_ids.insert(boundary_info.get_id_by_name(boundary_name)); 60 : } 61 : } 62 : else 63 : { 64 344 : breaking_boundary_ids = boundary_info.get_boundary_ids(); 65 : 66 : // We might be on a distributed mesh with remote boundary ids 67 344 : if (!mesh->is_replicated()) 68 40 : this->comm().set_union(breaking_boundary_ids); 69 : } 70 : 71 : // create a list of new boundary names 72 363 : std::set<std::string> new_boundary_name_set; 73 363 : std::vector<boundary_id_type> side_boundary_ids; 74 10207 : for (const auto & elem : mesh->active_element_ptr_range()) 75 : { 76 4922 : auto subdomain_id = elem->subdomain_id(); 77 4922 : auto subdomain_name = mesh->subdomain_name(subdomain_id); 78 4922 : if (subdomain_name == "") 79 4922 : subdomain_name = std::to_string(subdomain_id); 80 25474 : for (unsigned int side = 0; side < elem->n_sides(); ++side) 81 : { 82 20552 : boundary_info.boundary_ids(elem, side, side_boundary_ids); 83 26426 : for (auto boundary_id : side_boundary_ids) 84 5874 : if (breaking_boundary_ids.count(boundary_id) > 0) 85 5406 : new_boundary_name_set.emplace(boundary_info.sideset_name(boundary_id) + "_to_" + 86 : subdomain_name); 87 : } 88 5285 : } 89 : 90 : // We might be on a distributed mesh with remote elements that had 91 : // new boundary ids added 92 363 : if (!mesh->is_replicated()) 93 42 : this->comm().set_union(new_boundary_name_set); 94 : 95 : // assign boundary IDs to the boundaries to be added 96 : std::vector<BoundaryName> new_boundary_names(new_boundary_name_set.begin(), 97 363 : new_boundary_name_set.end()); 98 363 : auto new_boundary_ids = MooseMeshUtils::getBoundaryIDs(*mesh, new_boundary_names, true); 99 : 100 : // assign boundary names to the new boundaries 101 : mooseAssert(new_boundary_ids.size() == new_boundary_names.size(), 102 : "sizes of boundary names and boundary IDs mismatch"); 103 3089 : for (MooseIndex(new_boundary_ids) i = 0; i < new_boundary_ids.size(); ++i) 104 : { 105 2726 : boundary_info.sideset_name(new_boundary_ids[i]) = new_boundary_names[i]; 106 2726 : boundary_info.nodeset_name(new_boundary_ids[i]) = new_boundary_names[i]; 107 : } 108 : 109 : // add sides into the side sets 110 10207 : for (const auto & elem : mesh->active_element_ptr_range()) 111 : { 112 4922 : auto subdomain_id = elem->subdomain_id(); 113 4922 : auto subdomain_name = mesh->subdomain_name(subdomain_id); 114 4922 : if (subdomain_name == "") 115 4922 : subdomain_name = std::to_string(subdomain_id); 116 25474 : for (MooseIndex(elem->n_sides()) side = 0; side < elem->n_sides(); ++side) 117 : { 118 20552 : std::vector<boundary_id_type> side_boundary_ids; 119 20552 : boundary_info.boundary_ids(elem, side, side_boundary_ids); 120 26426 : for (auto boundary_id : side_boundary_ids) 121 : { 122 5874 : if (breaking_boundary_ids.count(boundary_id) > 0) 123 : { 124 5406 : BoundaryName bname = boundary_info.sideset_name(boundary_id) + "_to_" + subdomain_name; 125 5406 : auto bid = boundary_info.get_id_by_name(bname); 126 5406 : boundary_info.add_side(elem, side, bid); 127 5406 : } 128 : } 129 20552 : } 130 5285 : } 131 : 132 363 : mesh->set_isnt_prepared(); 133 : 134 726 : return dynamic_pointer_cast<MeshBase>(mesh); 135 363 : }