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 : #pragma once 11 : 12 : #include "GeneralUserObject.h" 13 : #include "libmesh/mesh.h" 14 : #include "KDTree.h" 15 : #include "SBMBndElementBase.h" 16 : 17 : class SBMSurfaceMeshBuilder : public GeneralUserObject 18 : { 19 : public: 20 : static InputParameters validParams(); 21 : SBMSurfaceMeshBuilder(const InputParameters & parameters); 22 : 23 : virtual void initialSetup() override; 24 94 : virtual void initialize() override {} 25 94 : virtual void execute() override {} 26 94 : virtual void finalize() override {} 27 : 28 : /// Returns a mutable reference because KDTree::neighborSearch is non-const (nanoflann's 29 : /// knnSearch threads internal scratch state through the call). The operation is logically 30 : /// read-only and knnSearch is re-entrant, so the same tree can be safely shared across 31 : /// threads without a const_cast at the call site. 32 : /// Callers must check hasKDTree() first; this is asserted in debug builds. 33 : KDTree & getKDTree() const; 34 : 35 : /// Whether this builder has a KDTree available. Consumers that require the tree should 36 : /// check this in initialSetup and mooseError with a friendly message naming both objects. 37 : bool hasKDTree() const { return _kd_tree != nullptr; } 38 : 39 : /// Get the SBM boundary elements 40 : const std::vector<std::unique_ptr<SBMBndElementBase>> & getBoundaryElements() const; 41 : 42 : /// Get the centroids of the boundary elements 43 : const std::vector<Point> & getCentroids() const; 44 : 45 : /** 46 : * @brief Checks whether the boundary mesh is "closed" -- i.e. has no open 47 : * edges or faces. 48 : * 49 : * The implementation walks every side of every boundary element and returns 50 : * false as soon as it finds a side with no neighbor. On a manifold surface 51 : * mesh this is equivalent to watertightness; non-manifold input 52 : * (e.g. T-junctions, three faces sharing an edge) is not validated here 53 : * because the SBM workflow expects boundary meshes extracted from manifold 54 : * sidesets. 55 : * 56 : * @return true if every side has a neighbor; false otherwise. 57 : */ 58 : bool checkWatertightness() const; 59 : 60 : protected: 61 : /// Holds the mesh to ensure boundary element pointers remain valid. 62 : /// Avoid extracting raw MeshBase* from a function returning std::unique_ptr<MeshBase>, 63 : /// as it can lead to dangling pointers. Use std::unique_ptr to manage ownership safely. 64 : std::unique_ptr<MeshBase> _mesh; 65 : 66 : /// The KDTree is constructed using the centroids of the elements in the boundary mesh. 67 : std::unique_ptr<KDTree> _kd_tree; 68 : 69 : /// The boundary elements are stored in a vector of unique pointers to SBMBndElementBase. 70 : std::vector<std::unique_ptr<SBMBndElementBase>> _boundary_elements; 71 : 72 : /// The centroids of the elements in the boundary mesh are stored in a vector of Points. The sequence is the same as in _boundary_elements. 73 : std::vector<Point> _centroids; 74 : 75 : /// Configures KDTree leaf node size for performance tuning. 76 : const int _leaf_max_size; 77 : 78 : /// The name of a mesh saved via MeshGenerator `save_mesh_as` parameter. 79 : const std::string _bnd_mesh_name; 80 : 81 : /// The flag to check the watertightness of the mesh. 82 : const bool _check_watertightness; 83 : 84 : /// whether we want to build a kd-tree or not 85 : const bool _build_kd_tree; 86 : 87 : private: 88 : /// The dimension of the embedding mesh (2D or 3D). 89 : const unsigned int _dim_embedding_mesh; 90 : };