LCOV - code coverage report
Current view: top level - src/meshgenerators - BreakBoundaryOnSubdomainGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 62 63 98.4 %
Date: 2025-07-17 01:28:37 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.14