LCOV - code coverage report
Current view: top level - src/userobjects - SBMSurfaceMeshBuilder.C (source / functions) Hit Total Coverage
Test: idaholab/moose shifted_boundary_method: #33416 (b10b36) with base 9fbd27 Lines: 59 60 98.3 %
Date: 2026-07-23 16:20:15 Functions: 7 7 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 "SBMSurfaceMeshBuilder.h"
      11             : #include "InputParameters.h"
      12             : #include "SBMBndEdge2.h"
      13             : #include "SBMBndTri3.h"
      14             : #include "SBMUtils.h"
      15             : 
      16             : // Register object
      17             : registerMooseObject("ShiftedBoundaryMethodApp", SBMSurfaceMeshBuilder);
      18             : 
      19             : InputParameters
      20         102 : SBMSurfaceMeshBuilder::validParams()
      21             : {
      22         102 :   InputParameters params = GeneralUserObject::validParams();
      23         102 :   params.addClassDescription(
      24             :       "Constructs a KDTree and boundary elements from a pre-existing surface mesh. "
      25             :       "The surface mesh is specified in the Mesh block.");
      26             : 
      27         204 :   params.addRequiredParam<std::string>(
      28             :       "surface_mesh",
      29             :       "The name of the surface mesh saved via the MeshGenerator's `save_mesh_as` parameter.");
      30             : 
      31             :   /// Add a parameter for leaf_max_size for nanoflann
      32         204 :   params.addParam<int>(
      33             :       "leaf_max_size",
      34         204 :       10,
      35             :       "Maximum number of points allowed in a leaf node of the KDTree. "
      36             :       "Smaller values yield deeper trees with faster queries but slower build times; "
      37             :       "larger values result in shallower trees with faster builds but slower queries. "
      38             :       "Benchmarking is recommended to find an optimal tradeoff for your use case.");
      39             : 
      40             :   /// Checking watertightness is not mandatory, but it is a good practice to ensure the mesh is valid for In-Out test.
      41         204 :   params.addParam<bool>(
      42             :       "check_watertightness",
      43         204 :       false,
      44             :       "Check if the mesh is watertight. If false, the mesh may not be suitable for In-Out tests.");
      45             : 
      46             :   /// Add a parameter to control whether to build a kd-tree or not
      47         204 :   params.addParam<bool>(
      48             :       "build_kd_tree",
      49         204 :       true,
      50             :       "Whether to build a kd-tree or not. If false, the kd-tree will not be built, "
      51             :       "and the mesh will be used directly for queries.");
      52             : 
      53         102 :   return params;
      54           0 : }
      55             : 
      56          51 : SBMSurfaceMeshBuilder::SBMSurfaceMeshBuilder(const InputParameters & parameters)
      57             :   : GeneralUserObject(parameters),
      58         102 :     _leaf_max_size(getParam<int>("leaf_max_size")),
      59         102 :     _bnd_mesh_name(getParam<std::string>("surface_mesh")),
      60         102 :     _check_watertightness(getParam<bool>("check_watertightness")),
      61         102 :     _build_kd_tree(getParam<bool>("build_kd_tree")),
      62         102 :     _dim_embedding_mesh(_fe_problem.mesh().dimension() /*MooseMesh*/)
      63             : {
      64          51 : }
      65             : 
      66             : void
      67          47 : SBMSurfaceMeshBuilder::initialSetup()
      68             : {
      69          47 :   auto & mesh_generator_system = _app.getMeshGeneratorSystem();
      70             : 
      71          94 :   _mesh = mesh_generator_system.getSavedMesh(_bnd_mesh_name);
      72             : 
      73          47 :   const auto expected_dim_embedding_mesh = _mesh->mesh_dimension() + 1;
      74             : 
      75          47 :   if (!_mesh->is_replicated())
      76           2 :     mooseError(
      77             :         "The mesh is distributed. Please use a serial mesh for SBMSurfaceMeshBuilder, which is "
      78             :         "important for our In-Out test later.");
      79             : 
      80          45 :   if (_dim_embedding_mesh != expected_dim_embedding_mesh)
      81           2 :     mooseError("The original mesh dimension (",
      82           2 :                _dim_embedding_mesh,
      83             :                ") does not match the expected mesh dimension (",
      84             :                expected_dim_embedding_mesh,
      85             :                ").");
      86             : 
      87          43 :   const std::size_t num_elems = _mesh->n_elem();
      88             : 
      89          43 :   _centroids.resize(num_elems);
      90          43 :   _boundary_elements.resize(num_elems);
      91             : 
      92             :   int i = 0;
      93         576 :   for (auto elem_it = _mesh->active_elements_begin(); elem_it != _mesh->active_elements_end();
      94         245 :        ++elem_it)
      95             :   {
      96         247 :     const Elem * elem = *elem_it;
      97             : 
      98         247 :     const auto centroid = elem->vertex_average();
      99         247 :     if (_build_kd_tree)
     100         219 :       _centroids[i] = centroid;
     101             : 
     102         247 :     if (elem->type() == EDGE2)
     103         125 :       _boundary_elements[i] = std::make_unique<SBMBndEdge2>(elem);
     104         122 :     else if (elem->type() == TRI3)
     105         120 :       _boundary_elements[i] = std::make_unique<SBMBndTri3>(elem);
     106             :     else
     107           2 :       mooseError("Unsupported element type in SBMSurfaceMeshBuilder::initialSetup()");
     108             : 
     109         245 :     ++i;
     110             :   }
     111             : 
     112          41 :   if (_build_kd_tree)
     113          68 :     _kd_tree = std::make_unique<KDTree>(_centroids, _leaf_max_size);
     114             : 
     115          41 :   if (_check_watertightness)
     116             :   {
     117           9 :     bool watertight = checkWatertightness();
     118           9 :     if (!watertight)
     119           4 :       mooseInfo("The mesh is not watertight. It may not be suitable for In-Out tests.");
     120             :     else
     121           5 :       mooseInfo("The mesh is watertight. It is suitable for In-Out tests.");
     122             :   }
     123          41 : }
     124             : 
     125             : bool
     126           9 : SBMSurfaceMeshBuilder::checkWatertightness() const
     127             : {
     128           9 :   return SBMUtils::checkWatertightnessFromRawElems(std::vector<const Elem *>(
     129          27 :       _mesh->active_element_ptr_range().begin(), _mesh->active_element_ptr_range().end()));
     130             : }
     131             : 
     132             : KDTree &
     133          36 : SBMSurfaceMeshBuilder::getKDTree() const
     134             : {
     135             :   mooseAssert(_kd_tree, "KDTree not built; callers must guard with hasKDTree() first.");
     136          36 :   return *_kd_tree;
     137             : }
     138             : 
     139             : const std::vector<std::unique_ptr<SBMBndElementBase>> &
     140          36 : SBMSurfaceMeshBuilder::getBoundaryElements() const
     141             : {
     142          36 :   return _boundary_elements;
     143             : }
     144             : 
     145             : const std::vector<Point> &
     146           6 : SBMSurfaceMeshBuilder::getCentroids() const
     147             : {
     148           6 :   return _centroids;
     149             : }

Generated by: LCOV version 1.14