LCOV - code coverage report
Current view: top level - src/meshgenerators - SideSetsFromNodeSetsGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 6f668f Lines: 45 51 88.2 %
Date: 2025-09-22 20:01:15 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 "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             : }

Generated by: LCOV version 1.14