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 3803 : BreakBoundaryOnSubdomainGenerator::validParams() 22 : { 23 3803 : InputParameters params = MeshGenerator::validParams(); 24 : 25 15212 : params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify"); 26 7606 : 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 11409 : params.addParam<std::vector<BoundaryName>>( 30 : "boundaries", "Boundaries to be broken. Default means to break all boundaries"); 31 : 32 3803 : return params; 33 0 : } 34 : 35 371 : BreakBoundaryOnSubdomainGenerator::BreakBoundaryOnSubdomainGenerator( 36 371 : const InputParameters & parameters) 37 742 : : MeshGenerator(parameters), _input(getMesh("input")) 38 : { 39 371 : } 40 : 41 : std::unique_ptr<MeshBase> 42 344 : BreakBoundaryOnSubdomainGenerator::generate() 43 : { 44 : // get the mesh and boundary info 45 344 : std::unique_ptr<MeshBase> mesh = std::move(_input); 46 344 : auto & boundary_info = mesh->get_boundary_info(); 47 : 48 : // get IDs of all boundaries to be broken 49 344 : std::set<boundary_id_type> breaking_boundary_ids; 50 1032 : if (isParamValid("boundaries")) 51 : { 52 44 : auto & boundary_names = getParam<std::vector<BoundaryName>>("boundaries"); 53 60 : for (auto & boundary_name : boundary_names) 54 : { 55 : // check that the boundary exists in the mesh 56 41 : if (!MooseMeshUtils::hasBoundaryName(*mesh, boundary_name)) 57 6 : 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 322 : breaking_boundary_ids = boundary_info.get_boundary_ids(); 65 : 66 : // We might be on a distributed mesh with remote boundary ids 67 322 : if (!mesh->is_replicated()) 68 40 : this->comm().set_union(breaking_boundary_ids); 69 : } 70 : 71 : // create a list of new boundary names 72 341 : std::set<std::string> new_boundary_name_set; 73 341 : std::vector<boundary_id_type> side_boundary_ids; 74 5028 : for (const auto & elem : mesh->active_element_ptr_range()) 75 : { 76 4687 : auto subdomain_id = elem->subdomain_id(); 77 4687 : auto subdomain_name = mesh->subdomain_name(subdomain_id); 78 4687 : if (subdomain_name == "") 79 4687 : subdomain_name = std::to_string(subdomain_id); 80 24299 : for (unsigned int side = 0; side < elem->n_sides(); ++side) 81 : { 82 19612 : boundary_info.boundary_ids(elem, side, side_boundary_ids); 83 25196 : for (auto boundary_id : side_boundary_ids) 84 5584 : if (breaking_boundary_ids.count(boundary_id) > 0) 85 5116 : new_boundary_name_set.emplace(boundary_info.sideset_name(boundary_id) + "_to_" + 86 : subdomain_name); 87 : } 88 5028 : } 89 : 90 : // We might be on a distributed mesh with remote elements that had 91 : // new boundary ids added 92 341 : 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 341 : new_boundary_name_set.end()); 98 341 : 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 2906 : for (MooseIndex(new_boundary_ids) i = 0; i < new_boundary_ids.size(); ++i) 104 : { 105 2565 : boundary_info.sideset_name(new_boundary_ids[i]) = new_boundary_names[i]; 106 2565 : boundary_info.nodeset_name(new_boundary_ids[i]) = new_boundary_names[i]; 107 : } 108 : 109 : // add sides into the side sets 110 5028 : for (const auto & elem : mesh->active_element_ptr_range()) 111 : { 112 4687 : auto subdomain_id = elem->subdomain_id(); 113 4687 : auto subdomain_name = mesh->subdomain_name(subdomain_id); 114 4687 : if (subdomain_name == "") 115 4687 : subdomain_name = std::to_string(subdomain_id); 116 24299 : for (MooseIndex(elem->n_sides()) side = 0; side < elem->n_sides(); ++side) 117 : { 118 19612 : std::vector<boundary_id_type> side_boundary_ids; 119 19612 : boundary_info.boundary_ids(elem, side, side_boundary_ids); 120 25196 : for (auto boundary_id : side_boundary_ids) 121 : { 122 5584 : if (breaking_boundary_ids.count(boundary_id) > 0) 123 : { 124 5116 : BoundaryName bname = boundary_info.sideset_name(boundary_id) + "_to_" + subdomain_name; 125 5116 : auto bid = boundary_info.get_id_by_name(bname); 126 5116 : boundary_info.add_side(elem, side, bid); 127 5116 : } 128 : } 129 19612 : } 130 5028 : } 131 : 132 341 : mesh->unset_is_prepared(); 133 : 134 682 : return dynamic_pointer_cast<MeshBase>(mesh); 135 341 : }