LCOV - code coverage report
Current view: top level - src/meshgenerators - SideSetsFromAllNormalsGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 46 48 95.8 %
Date: 2026-05-29 20:35:17 Functions: 4 4 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 "SideSetsFromAllNormalsGenerator.h"
      11             : #include "Parser.h"
      12             : #include "InputParameters.h"
      13             : #include "CastUniquePointer.h"
      14             : #include "MeshTraversingUtils.h"
      15             : 
      16             : #include "libmesh/fe_base.h"
      17             : #include "libmesh/mesh_generation.h"
      18             : #include "libmesh/mesh.h"
      19             : #include "libmesh/string_to_enum.h"
      20             : #include "libmesh/quadrature_gauss.h"
      21             : #include "libmesh/point_locator_base.h"
      22             : #include "libmesh/distributed_mesh.h"
      23             : #include "libmesh/elem.h"
      24             : 
      25             : #include <typeinfo>
      26             : 
      27             : registerMooseObject("MooseApp", SideSetsFromAllNormalsGenerator);
      28             : registerMooseObjectRenamed("MooseApp",
      29             :                            AllSideSetsByNormalsGenerator,
      30             :                            "06/30/2027 24:00",
      31             :                            SideSetsFromAllNormalsGenerator);
      32             : 
      33             : InputParameters
      34        6200 : SideSetsFromAllNormalsGenerator::validParams()
      35             : {
      36        6200 :   InputParameters params = SideSetsGeneratorBase::validParams();
      37             : 
      38             :   // This is the expected behavior of this sideset generator
      39       18600 :   params.setParameters("include_only_external_sides", true);
      40       12400 :   params.suppressParameter<bool>("include_only_external_sides");
      41             : 
      42             :   // The normals are found from the actual orientation of sidesets, not user-specified
      43       12400 :   params.suppressParameter<bool>("fixed_normal");
      44       12400 :   params.suppressParameter<Point>("normal");
      45       12400 :   params.suppressParameter<Real>("normal_tol");
      46       12400 :   params.suppressParameter<std::vector<BoundaryName>>("new_boundary");
      47             : 
      48        6200 :   params.addClassDescription("Adds sidesets to the entire mesh based on unique normals.");
      49        6200 :   return params;
      50           0 : }
      51             : 
      52          39 : SideSetsFromAllNormalsGenerator::SideSetsFromAllNormalsGenerator(const InputParameters & parameters)
      53             :   : SideSetsGeneratorBase(parameters),
      54          39 :     _boundary_to_normal_map(
      55          78 :         declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals"))
      56             : {
      57          39 : }
      58             : 
      59             : std::unique_ptr<MeshBase>
      60          39 : SideSetsFromAllNormalsGenerator::generate()
      61             : {
      62          39 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      63          39 :   if (!mesh->is_replicated())
      64           0 :     mooseError("SideSetsFromAllNormalsGenerator is not implemented for distributed meshes");
      65          39 :   setup(*mesh);
      66             : 
      67             :   // Get the current list of boundaries so we can generate new ones that won't conflict
      68          39 :   _mesh_boundary_ids = mesh->get_boundary_info().get_boundary_ids();
      69             : 
      70          39 :   _visited.clear();
      71             : 
      72             :   // We'll need to loop over all of the elements to find ones that match this normal.
      73             :   // We can't rely on flood catching them all here...
      74      164127 :   for (const auto & elem : mesh->element_ptr_range())
      75      491868 :     for (const auto side : make_range(elem->n_sides()))
      76             :     {
      77      409824 :       const std::vector<Point> & normals = _fe_face->get_normals();
      78      409824 :       _fe_face->reinit(elem, side);
      79             : 
      80             :       {
      81             :         // See if we've seen this normal before (linear search)
      82      409824 :         const std::map<BoundaryID, RealVectorValue>::value_type * item = nullptr;
      83     1996920 :         for (const auto & id_pair : _boundary_to_normal_map)
      84     1996652 :           if (MeshTraversingUtils::normalsWithinTol(id_pair.second, normals[0], 1e-5))
      85             :           {
      86      409556 :             item = &id_pair;
      87      409556 :             break;
      88             :           }
      89             : 
      90      409824 :         if (item)
      91      409556 :           flood(elem, normals[0], item->first, *mesh);
      92             :         else
      93             :         {
      94         268 :           boundary_id_type id = getNextBoundaryID();
      95         268 :           _boundary_to_normal_map[id] = normals[0];
      96         268 :           flood(elem, normals[0], id, *mesh);
      97             :         }
      98             :       }
      99          39 :     }
     100             : 
     101          39 :   finalize();
     102             : 
     103          39 :   mesh->unset_is_prepared();
     104          78 :   return dynamic_pointer_cast<MeshBase>(mesh);
     105          39 : }
     106             : 
     107             : boundary_id_type
     108         268 : SideSetsFromAllNormalsGenerator::getNextBoundaryID()
     109             : {
     110         268 :   std::set<boundary_id_type>::iterator it;
     111         268 :   boundary_id_type next_id = 1;
     112             : 
     113        3138 :   while ((it = _mesh_boundary_ids.find(next_id)) != _mesh_boundary_ids.end())
     114        2870 :     ++next_id;
     115             : 
     116         268 :   _mesh_boundary_ids.insert(next_id);
     117             : 
     118         268 :   return next_id;
     119             : }

Generated by: LCOV version 1.14