LCOV - code coverage report
Current view: top level - src/meshgenerators - SideSetsFromNormalsGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 47 51 92.2 %
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 "SideSetsFromNormalsGenerator.h"
      11             : #include "Parser.h"
      12             : #include "InputParameters.h"
      13             : #include "MooseMeshUtils.h"
      14             : #include "CastUniquePointer.h"
      15             : #include "MooseApp.h"
      16             : #include "MeshGeneratorSystem.h"
      17             : 
      18             : #include "libmesh/mesh_generation.h"
      19             : #include "libmesh/mesh.h"
      20             : #include "libmesh/string_to_enum.h"
      21             : #include "libmesh/quadrature_gauss.h"
      22             : #include "libmesh/point_locator_base.h"
      23             : #include "libmesh/distributed_mesh.h"
      24             : #include "libmesh/elem.h"
      25             : #include "libmesh/fe_base.h"
      26             : 
      27             : #include <typeinfo>
      28             : 
      29             : registerMooseObject("MooseApp", SideSetsFromNormalsGenerator);
      30             : 
      31             : InputParameters
      32       14357 : SideSetsFromNormalsGenerator::validParams()
      33             : {
      34       14357 :   InputParameters params = SideSetsGeneratorBase::validParams();
      35             : 
      36       14357 :   params.addClassDescription(
      37             :       "Adds a new named sideset to the mesh for all faces matching the specified normal.");
      38       14357 :   params.addRequiredParam<std::vector<Point>>(
      39             :       "normals", "A list of normals for which to start painting sidesets");
      40       14357 :   params.addParam<Real>("tolerance", "Tolerance for comparing the face normal");
      41       14357 :   params.deprecateParam("tolerance", "normal_tol", "4/01/2025");
      42             : 
      43             :   // We want to use a different normal_tol for this generator than from the base class to preserve
      44             :   // old behavior.
      45       14357 :   params.setParameters("normal_tol", 1e-5);
      46             : 
      47             :   // We are using 'normals' instead
      48       14357 :   params.suppressParameter<Point>("normal");
      49             : 
      50             :   // It doesn't make sense to allow internal sides for this side set generator.
      51       14357 :   params.setParameters("include_only_external_sides", true);
      52       14357 :   params.suppressParameter<bool>("include_only_external_sides");
      53             : 
      54       14357 :   return params;
      55           0 : }
      56             : 
      57          46 : SideSetsFromNormalsGenerator::SideSetsFromNormalsGenerator(const InputParameters & parameters)
      58             :   : SideSetsGeneratorBase(parameters),
      59          46 :     _normals(getParam<std::vector<Point>>("normals")),
      60          46 :     _boundary_to_normal_map(
      61          92 :         declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals"))
      62             : {
      63             :   // Get the BoundaryIDs from the mesh
      64          46 :   if (_normals.size() != _boundary_names.size())
      65           0 :     mooseError("normal list and boundary list are not the same length");
      66             : 
      67             :   // Make sure that the normals are normalized
      68         146 :   for (auto & normal : _normals)
      69             :   {
      70         100 :     if (normal.norm() < 1e-5)
      71           0 :       mooseError("Normal is zero");
      72         100 :     normal /= normal.norm();
      73             :   }
      74             : 
      75          46 :   _using_normal = true;
      76          46 : }
      77             : 
      78             : std::unique_ptr<MeshBase>
      79          45 : SideSetsFromNormalsGenerator::generate()
      80             : {
      81          45 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      82          45 :   if (!_fixed_normal && !mesh->is_replicated())
      83           0 :     mooseError("SideSetsFromNormalsGenerator is not implemented for distributed meshes when "
      84             :                "fixed_normal = false");
      85             : 
      86             :   std::vector<BoundaryID> boundary_ids =
      87          45 :       MooseMeshUtils::getBoundaryIDs(*mesh, _boundary_names, true);
      88             : 
      89          45 :   setup(*mesh);
      90             : 
      91          45 :   _visited.clear();
      92             : 
      93             :   // Request to compute normal vectors
      94          45 :   const std::vector<Point> & face_normals = _fe_face->get_normals();
      95             : 
      96             :   // We'll need to loop over all of the elements to find ones that match this normal.
      97             :   // We can't rely on flood catching them all here...
      98       71965 :   for (const auto & elem : mesh->element_ptr_range())
      99      230072 :     for (const auto side : make_range(elem->n_sides()))
     100             :     {
     101      194112 :       if (elem->neighbor_ptr(side))
     102      177164 :         continue;
     103             : 
     104       16948 :       _fe_face->reinit(elem, side);
     105             : 
     106             :       // We'll just use the normal of the first qp
     107       16948 :       const Point & face_normal = face_normals[0];
     108             : 
     109       57484 :       for (const auto i : make_range(boundary_ids.size()))
     110             :       {
     111       40536 :         if (normalsWithinTol(_normals[i], face_normal, _normal_tol))
     112        6002 :           flood(elem, _normals[i], boundary_ids[i], *mesh);
     113             :       }
     114          45 :     }
     115             : 
     116          45 :   finalize();
     117             : 
     118          45 :   BoundaryInfo & boundary_info = mesh->get_boundary_info();
     119         143 :   for (const auto i : make_range(boundary_ids.size()))
     120             :   {
     121          98 :     boundary_info.sideset_name(boundary_ids[i]) = _boundary_names[i];
     122          98 :     _boundary_to_normal_map[boundary_ids[i]] = _normals[i];
     123             :   }
     124             : 
     125             :   // This is a terrible hack that we'll want to remove once BMBBG isn't terrible
     126          45 :   if (!_app.getMeshGeneratorSystem().hasBreakMeshByBlockGenerator())
     127          45 :     mesh->set_isnt_prepared();
     128          90 :   return dynamic_pointer_cast<MeshBase>(mesh);
     129          45 : }

Generated by: LCOV version 1.14