LCOV - code coverage report
Current view: top level - src/meshgenerators - SideSetsFromPointsGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 53 55 96.4 %
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 "SideSetsFromPointsGenerator.h"
      11             : #include "Parser.h"
      12             : #include "InputParameters.h"
      13             : #include "MooseMeshUtils.h"
      14             : #include "CastUniquePointer.h"
      15             : 
      16             : #include "libmesh/mesh.h"
      17             : #include "libmesh/mesh_generation.h"
      18             : #include "libmesh/mesh_serializer.h"
      19             : #include "libmesh/string_to_enum.h"
      20             : #include "libmesh/quadrature_gauss.h"
      21             : #include "libmesh/point_locator_base.h"
      22             : #include "libmesh/enum_point_locator_type.h"
      23             : #include "libmesh/distributed_mesh.h"
      24             : #include "libmesh/elem.h"
      25             : #include "libmesh/fe_base.h"
      26             : #include "libmesh/mesh_tools.h"
      27             : 
      28             : #include <typeinfo>
      29             : 
      30             : registerMooseObject("MooseApp", SideSetsFromPointsGenerator);
      31             : 
      32             : InputParameters
      33       14309 : SideSetsFromPointsGenerator::validParams()
      34             : {
      35       14309 :   InputParameters params = SideSetsGeneratorBase::validParams();
      36             : 
      37       14309 :   params.addClassDescription("Adds a new sideset starting at the specified point containing all "
      38             :                              "connected element faces with the same normal.");
      39       14309 :   params.addRequiredParam<std::vector<Point>>(
      40             :       "points", "A list of points from which to start painting sidesets");
      41             : 
      42       14309 :   params.suppressParameter<Point>("normal");
      43       14309 :   params.suppressParameter<Real>("normal_tol");
      44             : 
      45             :   // It doesn't make sense to allow internal sides for this side set generator.
      46       14309 :   params.setParameters("include_only_external_sides", true);
      47       14309 :   params.suppressParameter<bool>("include_only_external_sides");
      48             : 
      49       14309 :   return params;
      50           0 : }
      51             : 
      52          22 : SideSetsFromPointsGenerator::SideSetsFromPointsGenerator(const InputParameters & parameters)
      53          22 :   : SideSetsGeneratorBase(parameters), _points(getParam<std::vector<Point>>("points"))
      54             : {
      55          22 :   if (_points.size() != _boundary_names.size())
      56           0 :     mooseError("point list and boundary list are not the same length");
      57          22 :   _using_normal = true;
      58          22 : }
      59             : 
      60             : std::unique_ptr<MeshBase>
      61          21 : SideSetsFromPointsGenerator::generate()
      62             : {
      63          21 :   std::unique_ptr<MeshBase> mesh = std::move(_input);
      64             : 
      65             :   // Our flood fill doesn't do any communication, so it requires a
      66             :   // serialized mesh
      67          21 :   libMesh::MeshSerializer serial(*mesh);
      68             : 
      69             :   // Get the BoundaryIDs from the mesh
      70             :   std::vector<BoundaryID> boundary_ids =
      71          21 :       MooseMeshUtils::getBoundaryIDs(*mesh, _boundary_names, true);
      72             : 
      73          21 :   setup(*mesh);
      74             : 
      75          21 :   _visited.clear();
      76             : 
      77             :   std::unique_ptr<libMesh::PointLocatorBase> pl =
      78          21 :       libMesh::PointLocatorBase::build(libMesh::TREE, *mesh);
      79             : 
      80          81 :   for (const auto i : index_range(boundary_ids))
      81             :   {
      82          64 :     std::set<const Elem *> candidate_elements;
      83          64 :     (*pl)(_points[i], candidate_elements);
      84             : 
      85          64 :     const Elem * elem_to_flood = nullptr;
      86          64 :     Point normal_to_flood;
      87             : 
      88         168 :     for (const Elem * elem : candidate_elements)
      89         592 :       for (const auto side : make_range(elem->n_sides()))
      90             :       {
      91         488 :         if (elem->neighbor_ptr(side))
      92         376 :           continue;
      93             : 
      94             :         // See if this point is on this side
      95         112 :         std::unique_ptr<const Elem> elem_side = elem->side_ptr(side);
      96             : 
      97         112 :         if (elem_side->contains_point(_points[i]))
      98             :         {
      99             :           // This is a good side to paint our sideset with.
     100             :           // Get the normal.
     101         112 :           const std::vector<Point> & normals = _fe_face->get_normals();
     102         112 :           _fe_face->reinit(elem, side);
     103             : 
     104             :           // If we *already* found a good but different side to paint
     105             :           // our sideset with, we've got an ambiguity here.
     106         156 :           if (elem_to_flood && (!normalsWithinTol(normal_to_flood, normals[0], _normal_tol) ||
     107          44 :                                 elem_to_flood->which_neighbor_am_i(elem) == libMesh::invalid_uint))
     108           4 :             mooseError("Two ambiguous potential sideset sources found for boundary `",
     109           4 :                        _boundary_names[i],
     110             :                        "' at ",
     111           4 :                        _points[i],
     112             :                        ":\nElement ",
     113           4 :                        elem_to_flood->id(),
     114             :                        " normal ",
     115             :                        normal_to_flood,
     116             :                        " and\n",
     117             :                        ":\nElement ",
     118           4 :                        elem->id(),
     119             :                        " normal ",
     120           4 :                        normals[0]);
     121             : 
     122         108 :           elem_to_flood = elem;
     123         108 :           normal_to_flood = normals[0];
     124             :           // Don't just flood here; keep looking for possible ambiguity
     125             :         }
     126         108 :       }
     127             : 
     128          60 :     flood(elem_to_flood, normal_to_flood, boundary_ids[i], *mesh);
     129          60 :   }
     130             : 
     131             : #ifdef DEBUG
     132             :   MeshTools::libmesh_assert_valid_boundary_ids(*mesh);
     133             : #endif
     134             : 
     135          17 :   finalize();
     136             : 
     137          77 :   for (const auto i : index_range(boundary_ids))
     138          60 :     mesh->get_boundary_info().sideset_name(boundary_ids[i]) = _boundary_names[i];
     139             : 
     140          17 :   mesh->set_isnt_prepared();
     141          34 :   return dynamic_pointer_cast<MeshBase>(mesh);
     142          17 : }

Generated by: LCOV version 1.14