LCOV - code coverage report
Current view: top level - src/meshgenerators - SideSetsFromNormalsGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #31730 (e8b711) with base e0c998 Lines: 45 49 91.8 %
Date: 2025-10-29 16:49:47 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       14965 : SideSetsFromNormalsGenerator::validParams()
      33             : {
      34       14965 :   InputParameters params = SideSetsGeneratorBase::validParams();
      35             : 
      36       29930 :   params.addClassDescription(
      37             :       "Adds a new named sideset to the mesh for all faces matching the specified normal.");
      38       44895 :   params.addRequiredParam<std::vector<Point>>(
      39             :       "normals", "A list of normals for which to start painting sidesets");
      40             : 
      41             :   // We want to use a different normal_tol for this generator than from the base class to preserve
      42             :   // old behavior.
      43       44895 :   params.setParameters("normal_tol", 1e-5);
      44             : 
      45             :   // We are using 'normals' instead
      46       14965 :   params.suppressParameter<Point>("normal");
      47             : 
      48             :   // It doesn't make sense to allow internal sides for this side set generator.
      49       44895 :   params.setParameters("include_only_external_sides", true);
      50       14965 :   params.suppressParameter<bool>("include_only_external_sides");
      51             : 
      52       14965 :   return params;
      53           0 : }
      54             : 
      55          49 : SideSetsFromNormalsGenerator::SideSetsFromNormalsGenerator(const InputParameters & parameters)
      56             :   : SideSetsGeneratorBase(parameters),
      57          49 :     _normals(getParam<std::vector<Point>>("normals")),
      58          49 :     _boundary_to_normal_map(
      59         147 :         declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals"))
      60             : {
      61             :   // Get the BoundaryIDs from the mesh
      62          49 :   if (_normals.size() != _boundary_names.size())
      63           0 :     mooseError("normal list and boundary list are not the same length");
      64             : 
      65             :   // Make sure that the normals are normalized
      66         156 :   for (auto & normal : _normals)
      67             :   {
      68         107 :     if (normal.norm() < 1e-5)
      69           0 :       mooseError("Normal is zero");
      70         107 :     normal /= normal.norm();
      71             :   }
      72             : 
      73          49 :   _using_normal = true;
      74          49 : }
      75             : 
      76             : std::unique_ptr<MeshBase>
      77          48 : SideSetsFromNormalsGenerator::generate()
      78             : {
      79          48 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      80          48 :   if (!_fixed_normal && !mesh->is_replicated())
      81           0 :     mooseError("SideSetsFromNormalsGenerator is not implemented for distributed meshes when "
      82             :                "fixed_normal = false");
      83             : 
      84             :   std::vector<BoundaryID> boundary_ids =
      85          48 :       MooseMeshUtils::getBoundaryIDs(*mesh, _boundary_names, true);
      86             : 
      87          48 :   setup(*mesh);
      88             : 
      89          48 :   _visited.clear();
      90             : 
      91             :   // Request to compute normal vectors
      92          48 :   const std::vector<Point> & face_normals = _fe_face->get_normals();
      93             : 
      94             :   // We'll need to loop over all of the elements to find ones that match this normal.
      95             :   // We can't rely on flood catching them all here...
      96       78840 :   for (const auto & elem : mesh->element_ptr_range())
      97      254116 :     for (const auto side : make_range(elem->n_sides()))
      98             :     {
      99      214720 :       if (elem->neighbor_ptr(side))
     100      196104 :         continue;
     101             : 
     102       18616 :       _fe_face->reinit(elem, side);
     103             : 
     104             :       // We'll just use the normal of the first qp
     105       18616 :       const Point & face_normal = face_normals[0];
     106             : 
     107       63318 :       for (const auto i : make_range(boundary_ids.size()))
     108             :       {
     109       44702 :         if (normalsWithinTol(_normals[i], face_normal, _normal_tol))
     110        6607 :           flood(elem, _normals[i], boundary_ids[i], *mesh);
     111             :       }
     112          48 :     }
     113             : 
     114          48 :   finalize();
     115             : 
     116          48 :   BoundaryInfo & boundary_info = mesh->get_boundary_info();
     117         153 :   for (const auto i : make_range(boundary_ids.size()))
     118             :   {
     119         105 :     boundary_info.sideset_name(boundary_ids[i]) = _boundary_names[i];
     120         105 :     _boundary_to_normal_map[boundary_ids[i]] = _normals[i];
     121             :   }
     122             : 
     123             :   // This is a terrible hack that we'll want to remove once BMBBG isn't terrible
     124          48 :   if (!_app.getMeshGeneratorSystem().hasBreakMeshByBlockGenerator())
     125          48 :     mesh->set_isnt_prepared();
     126          96 :   return dynamic_pointer_cast<MeshBase>(mesh);
     127          48 : }

Generated by: LCOV version 1.14