LCOV - code coverage report
Current view: top level - src/meshgenerators - DeleteElementsNearMeshGenerator.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 55 55 100.0 %
Date: 2026-05-29 20:35:17 Functions: 5 5 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 "DeleteElementsNearMeshGenerator.h"
      11             : #include "SetupQuadratureAction.h"
      12             : #include "KDTree.h"
      13             : 
      14             : #include "libmesh/type_vector.h"
      15             : #include "libmesh/point.h"
      16             : #include "libmesh/elem.h"
      17             : #include "libmesh/fe_base.h"
      18             : #include "libmesh/quadrature_gauss.h"
      19             : 
      20             : registerMooseObject("MooseApp", DeleteElementsNearMeshGenerator);
      21             : 
      22             : InputParameters
      23        3077 : DeleteElementsNearMeshGenerator::validParams()
      24             : {
      25        3077 :   InputParameters params = ElementDeletionGeneratorBase::validParams();
      26             : 
      27        6154 :   params.addClassDescription(
      28             :       "Removes elements lying \"near\" another mesh. The proximity is examined by the distance "
      29             :       "from "
      30             :       "the element's centroid to the faces of elements of the \"proximity_mesh\"");
      31       12308 :   params.addRequiredParam<MeshGeneratorName>("proximity_mesh",
      32             :                                              "Mesh providing the deletion criterion");
      33       15385 :   params.addRequiredRangeCheckedParam<Real>(
      34             :       "distance",
      35             :       "distance>0",
      36             :       "The distance from the centroid of elements in the 'input' mesh to elements in the "
      37             :       "'proximity_mesh' under which they are marked for deletion");
      38        3077 :   auto options_order = SetupQuadratureAction::getQuadratureOrderEnum();
      39        3077 :   options_order.assign(CONSTANT);
      40        9231 :   params.addParam<MooseEnum>("side_order",
      41             :                              options_order,
      42             :                              "Order of the face quadrature used to find the nearest face in the "
      43             :                              "'proximity_mesh'. Default is CONSTANT");
      44             : 
      45        6154 :   return params;
      46        3077 : }
      47             : 
      48           8 : DeleteElementsNearMeshGenerator::DeleteElementsNearMeshGenerator(const InputParameters & parameters)
      49             :   : ElementDeletionGeneratorBase(parameters),
      50           8 :     _proximity_mesh(getMesh("proximity_mesh")),
      51          24 :     _distance(getParam<Real>("distance"))
      52             : {
      53           8 : }
      54             : 
      55             : std::unique_ptr<MeshBase>
      56           8 : DeleteElementsNearMeshGenerator::generate()
      57             : {
      58             :   // Build the point locator to detect elements inside
      59           8 :   _pl = _proximity_mesh->sub_point_locator();
      60           8 :   _pl->enable_out_of_mesh_mode();
      61             : 
      62             :   // Build a KNN with side Qps. This will help locate the nearest side if known to be outside
      63             :   // NOTE: side Qps are just one option. We could have done nodes, side centroids (~ side Qp at
      64             :   // order 0)
      65           8 :   std::vector<Point> all_side_qps;
      66          16 :   const auto & order = getParam<MooseEnum>("side_order");
      67           8 :   const auto order_enum = Moose::stringToEnum<Order>(order);
      68          24 :   for (const auto * const elem : _proximity_mesh->element_ptr_range())
      69             :   {
      70             :     // Build side then side Qps
      71          16 :     const auto dim = elem->dim();
      72          80 :     for (const auto side_i : make_range(elem->n_sides()))
      73             :     {
      74             :       // Internal sides cannot be closest to an external point
      75          64 :       if (elem->neighbor_ptr(side_i))
      76          16 :         continue;
      77          48 :       const std::unique_ptr<const Elem> face = elem->build_side_ptr(side_i);
      78             :       std::unique_ptr<libMesh::FEBase> fe(
      79          48 :           libMesh::FEBase::build(dim, libMesh::FEType(elem->default_order())));
      80          48 :       libMesh::QGauss qface(dim - 1, order_enum);
      81          48 :       fe->attach_quadrature_rule(&qface);
      82          48 :       const auto & qpoints = fe->get_xyz();
      83          48 :       fe->reinit(elem, side_i);
      84          48 :       all_side_qps.insert(all_side_qps.end(), qpoints.begin(), qpoints.end());
      85          48 :     }
      86           8 :   }
      87             :   mooseAssert(!all_side_qps.empty(), "Should have found side Qps");
      88           8 :   _kd_tree = std::make_unique<KDTree>(all_side_qps, /*max leaf size*/ 1);
      89             : 
      90             :   // Abide by the rules
      91             :   // NOTE: don't use _proximity_mesh in shouldDelete()! It won't work, it's gone
      92           8 :   const auto prox_mg = std::move(_proximity_mesh);
      93             : 
      94             :   // Perform the deletions
      95          16 :   return ElementDeletionGeneratorBase::generate();
      96           8 : }
      97             : 
      98             : bool
      99         288 : DeleteElementsNearMeshGenerator::shouldDelete(const Elem * elem)
     100             : {
     101        1224 :   const auto delete_due_to_point = [this](const Point & pt) -> bool
     102             :   {
     103             :     // Proximity mesh contains the point, distance is zero
     104        1224 :     if ((*_pl)(pt))
     105         104 :       return true;
     106             : 
     107             :     // Use the KNN to get the distance
     108        2240 :     std::vector<Real> distance_sqr(2);
     109        1120 :     std::vector<std::size_t> return_indices(2);
     110        1120 :     _kd_tree->neighborSearch(pt, /*num_search*/ 1, return_indices, distance_sqr);
     111             :     const auto distance =
     112        1120 :         distance_sqr.empty() ? std::numeric_limits<Real>::max() : std::sqrt(distance_sqr[0]);
     113             : 
     114        1120 :     return distance < _distance;
     115        1120 :   };
     116             : 
     117             :   // Check element centroid
     118         288 :   const auto centroid = elem->vertex_average();
     119         288 :   if (delete_due_to_point(centroid))
     120          32 :     return true;
     121             : 
     122             :   // Then its nodes. For convex elements, this should be enough
     123        1120 :   for (const auto & node : elem->node_ref_range())
     124         936 :     if (delete_due_to_point(node))
     125          72 :       return true;
     126             : 
     127         184 :   return false;
     128             : }

Generated by: LCOV version 1.14