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

Generated by: LCOV version 1.14