18#include "libmesh/int_range.h"
19#include "libmesh/mesh_modification.h"
20#include "libmesh/mesh_serializer.h"
21#include "libmesh/unstructured_mesh.h"
32 MooseEnum algorithm(
"BINARY EXHAUSTIVE",
"BINARY");
33 MooseEnum tri_elem_type(
"TRI3 TRI6 TRI7 DEFAULT",
"DEFAULT");
35 params.
addParam<
SubdomainID>(
"output_subdomain_id",
"Subdomain id to set on new triangles.");
37 params.
addParam<
bool>(
"smooth_triangulation",
39 "Whether to do Laplacian mesh smoothing on the generated triangles.");
44 "Control the use of binary search for the nodes of the stitched surfaces.");
46 "tri_element_type", tri_elem_type,
"Type of the triangular elements to be generated.");
48 "verbose_stitching",
false,
"Whether mesh stitching should have verbose output.");
49 params.
addParam<std::vector<Point>>(
"interior_points",
51 "Interior node locations, if no smoothing is used. Any point "
52 "outside the surface will not be meshed.");
53 params.
addParam<std::vector<FileName>>(
54 "interior_point_files", {},
"Text file(s) with the interior points, one per line");
55 params.
addClassDescription(
"Triangulates meshes within boundaries defined by input meshes.");
59 "outer_boundary_layer_thickness>=0",
60 "Thickness of the outer boundary layer to be added.");
62 "outer_boundary_layer_num", 0,
"Number of layers for the outer boundary layer.");
64 "outer_boundary_layer_bias",
66 "outer_boundary_layer_bias>0",
67 "Bias factor for the thickness of each layer in the outer boundary layer.");
70 "holes_boundary_layer_thickness",
71 "holes_boundary_layer_thickness>=0",
72 "Thickness of the hole boundary layers to be added.");
73 params.
addParam<std::vector<unsigned int>>(
"holes_boundary_layer_num",
74 "Numbers of layers for the hole boundary layers.");
76 "holes_boundary_layer_bias",
77 "holes_boundary_layer_bias>0",
78 "Bias factors for the thickness of each layer in the hole boundary layers.");
81 "Mandatory mesh interior nodes");
84 "outer_boundary_layer_bias holes_boundary_layer_thickness "
85 "holes_boundary_layer_num holes_boundary_layer_bias",
93 _bdy_ptr(getMesh(
"boundary")),
94 _add_nodes_per_boundary_segment(getParam<unsigned
int>(
"add_nodes_per_boundary_segment")),
95 _refine_bdy(getParam<bool>(
"refine_boundary")),
96 _output_subdomain_id(0),
97 _smooth_tri(getParam<bool>(
"smooth_triangulation")),
98 _hole_ptrs(getMeshes(
"holes")),
99 _stitch_holes(getParam<
std::vector<bool>>(
"stitch_holes")),
100 _refine_holes(getParam<
std::vector<bool>>(
"refine_holes")),
101 _algorithm(parameters.get<
MooseEnum>(
"algorithm")),
102 _tri_elem_type(parameters.get<
MooseEnum>(
"tri_element_type")),
103 _verbose_stitching(parameters.get<bool>(
"verbose_stitching")),
104 _interior_points(getParam<
std::vector<Point>>(
"interior_points")),
105 _outer_boundary_layer_thickness(getParam<Real>(
"outer_boundary_layer_thickness")),
106 _outer_boundary_layer_num(getParam<unsigned
int>(
"outer_boundary_layer_num")),
107 _outer_boundary_layer_bias(getParam<Real>(
"outer_boundary_layer_bias")),
108 _holes_boundary_layer_thickness(
109 isParamValid(
"holes_boundary_layer_thickness")
110 ? getParam<
std::vector<Real>>(
"holes_boundary_layer_thickness")
111 :
std::vector<Real>()),
112 _holes_boundary_layer_num(isParamValid(
"holes_boundary_layer_num")
113 ? getParam<
std::vector<unsigned
int>>(
"holes_boundary_layer_num")
114 :
std::vector<unsigned
int>()),
115 _holes_boundary_layer_bias(isParamValid(
"holes_boundary_layer_bias")
116 ? getParam<
std::vector<Real>>(
"holes_boundary_layer_bias")
117 :
std::vector<Real>())
122 const auto & positions_files = getParam<std::vector<FileName>>(
"interior_point_files");
123 for (
const auto p_file_it : index_range(positions_files))
125 const std::string positions_file = positions_files[p_file_it];
131 for (
const auto & d : data)
139 "outer_boundary_layer_thickness",
140 "this parameter must be set as non-zero along with a non-zero outer_boundary_layer_num.");
146 "Cannot add nodes per boundary segment when using an outer boundary layer.");
148 paramError(
"refine_boundary",
"Cannot refine boundary when using an outer boundary layer.");
156 "holes_boundary_layer_thickness, holes_boundary_layer_bias and this parameter must "
157 "be specified or not specified together.");
161 "If specified, this parameter must have the same length as 'holes'.");
164 "If specified, this parameter must have the same length as 'holes'.");
167 "If specified, this parameter must have the same length as 'holes'.");
173 "holes_boundary_layer_thickness",
174 "entry " + std::to_string(i) +
175 " must be set as non-zero along with a non-zero holes_boundary_layer_num entry.");
179 paramError(
"refine_holes",
"Cannot refine hole boundary when using a hole boundary layer.");
184std::unique_ptr<MeshBase>
200 std::vector<std::unique_ptr<MeshBase>> hole_meshes(
_hole_ptrs.size());
202 hole_meshes[hole_i] = std::move(*
_hole_ptrs[hole_i]);
204 std::unique_ptr<MeshBase> boundary_mesh = std::move(
_bdy_ptr);
210 const BoundaryName tmp_outer_name(
"__xyd_bdry_layer_tmp_outer__");
215 const SubdomainName layer_sd_name =
221 std::unique_ptr<MeshBase> outer_ring_clone;
222 if (using_outer_layer)
234 outer_ring_clone = outer_ring->clone();
235 boundary_mesh = std::move(outer_ring);
250 *hole_meshes[hole_i],
251 std::vector<BoundaryName>(),
263 auto & ring_u =
dynamic_cast<UnstructuredMesh &
>(*hole_ring);
264 auto & inp_u =
dynamic_cast<UnstructuredMesh &
>(*hole_meshes[hole_i]);
266 if (!ring_u.is_prepared())
267 ring_u.prepare_for_use();
268 if (!inp_u.is_prepared())
269 inp_u.prepare_for_use();
273 const auto & ring_bids = ring_u.get_boundary_info().get_global_boundary_ids();
274 const auto inp_bids = inp_u.get_boundary_info().get_global_boundary_ids();
275 const auto max_bid = std::max(*ring_bids.rbegin(),
276 inp_bids.empty() ? boundary_id_type(0) : *inp_bids.rbegin());
278 bool overlap =
false;
279 for (
auto b : inp_bids)
280 if (ring_bids.count(b))
285 for (
auto b : inp_bids)
287 const auto new_b = max_bid + (idx++);
288 inp_u.get_boundary_info().renumber_id(b, new_b);
290 ext_id = max_bid + idx;
293 ext_id = max_bid + 1;
294 inp_u.comm().max(ext_id);
295 bool has_ext =
false;
297 mooseAssert(has_ext,
"A 2D-XY mesh should have an external boundary.");
298 const auto ring_u_ext_id =
305 ring_u.stitch_meshes(inp_u,
317 hole_meshes[hole_i] = std::move(hole_ring);
331 *
this, std::move(boundary_mesh), std::move(hole_meshes), xyd_opts);
334 if (outer_ring_clone)
337 const boundary_id_type sentinel_id = sentinel_ids[0];
341 const boundary_id_type ring_outermost_orig =
346 const boundary_id_type ring_outermost_temp =
350 *outer_ring_clone, ring_outermost_orig, ring_outermost_temp);
352 auto & result_u =
dynamic_cast<UnstructuredMesh &
>(*result);
353 auto & clone_u =
dynamic_cast<UnstructuredMesh &
>(*outer_ring_clone);
355 result_u.stitch_meshes(clone_u,
365 if (user_has_output_boundary)
368 if (user_id != sentinel_id)
370 result->get_boundary_info().sideset_name(user_id) = user_output_boundary;
373 result->unset_is_prepared();
boundary_id_type BoundaryID
subdomain_id_type SubdomainID
registerMooseObject("MooseApp", XYDelaunayGenerator)
void ErrorVector unsigned int
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Utility class for reading delimited data (e.g., CSV data).
const std::vector< Point > getDataAsPoints() const
Get the data in Point format.
void setFormatFlag(FormatFlag value)
void read()
Perform the actual data reading.
Base class for Delaunay mesh generators applied to a surface.
void checkInteriorPoints(const std::vector< Point > &interior_points) const
Errors if a point was given twice as an interior point, which the triangulation cannot honor.
static InputParameters validParams()
void fillDelaunayOptions(MeshTriangulationUtils::XYDelaunayOptions &opts) const
Fills the triangulation options that follow from the parameters boundaryAndHolesParams() adds,...
static InputParameters boundaryAndHolesParams()
The parameters that select the outer boundary to triangulate within and the holes to leave out of the...
void checkBoundaryAndHolesParams(const std::vector< std::unique_ptr< MeshBase > * > &hole_ptrs) const
Errors if the parameters boundaryAndHolesParams() adds contradict each other or the holes they refer ...
Generates a triangulation in the XY plane, based on an input mesh defining the outer boundary (as wel...
const bool _smooth_tri
Whether to do Laplacian mesh smoothing on the generated triangles.
const std::vector< unsigned int > _holes_boundary_layer_num
Per-hole boundary-layer ring layer counts.
std::unique_ptr< MeshBase > & _bdy_ptr
Input mesh defining the boundary to triangulate within.
const std::vector< Real > _holes_boundary_layer_bias
Per-hole boundary-layer ring bias factors.
const bool _refine_bdy
Whether to allow automatically refining the outer boundary.
const unsigned int _outer_boundary_layer_num
Number of element layers in the outer boundary-layer ring.
const std::vector< std::unique_ptr< MeshBase > * > _hole_ptrs
Holds pointers to the pointers to input meshes defining holes.
const std::vector< bool > _stitch_holes
Whether to stitch to the mesh defining each hole.
XYDelaunayGenerator(const InputParameters ¶meters)
const Real _outer_boundary_layer_thickness
Thickness of an optional boundary-layer ring grown inward from the outer boundary.
const MooseEnum _tri_elem_type
Type of triangular elements to be generated.
const MooseEnum _algorithm
Type of algorithm used to find matching nodes (binary or exhaustive)
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
const std::vector< bool > _refine_holes
Whether to allow automatically refining each hole boundary.
static InputParameters validParams()
std::vector< Point > _interior_points
Desired interior node locations.
const unsigned int _add_nodes_per_boundary_segment
How many more nodes to add in each outer boundary segment.
const Real _outer_boundary_layer_bias
Bias factor for the layer thicknesses in the outer boundary-layer ring.
const std::vector< Real > _holes_boundary_layer_thickness
Per-hole boundary-layer ring thicknesses (grown outward from each hole)
const bool _verbose_stitching
Whether mesh stitching should have verbose output.
const Parallel::Communicator & _communicator
std::unique_ptr< MeshBase > buildBoundaryLayerRing(MeshGenerator &mg, MeshBase &input_mesh, const std::vector< BoundaryName > &boundary_names, unsigned int num_layers, Real thickness, Real layer_bias, bool outward, const MooseEnum &tri_elem_type, SubdomainID output_subdomain_id, const SubdomainName &output_subdomain_name)
Builds a conformal boundary-layer ring of triangulated annuli along a boundary of an input 2D mesh (o...
std::unique_ptr< MeshBase > triangulateWithDelaunay(MeshGenerator &mg, std::unique_ptr< MeshBase > boundary_mesh, std::vector< std::unique_ptr< MeshBase > > hole_meshes, const XYDelaunayOptions &xyd_opts)
Performs a 2D Delaunay triangulation (via libMesh::Poly2TriTriangulator) inside a closed boundary mes...
void changeBoundaryId(MeshBase &mesh, const libMesh::boundary_id_type old_id, const libMesh::boundary_id_type new_id, bool delete_prev)
Changes the old boundary ID to a new ID in the mesh.
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
BoundaryID getNextFreeBoundaryID(MeshBase &input_mesh)
Checks input mesh and returns the largest boundary ID in the mesh plus one, which is a boundary ID in...
void addExternalBoundary(MeshBase &mesh, const BoundaryID extern_bid, bool &has_external_bid)
Adds a sideset for the external boundary of the mesh (e.g.
Bundle of inputs for triangulateWithDelaunay.
std::vector< Point > interior_points
SubdomainName output_subdomain_name
std::vector< std::set< std::size_t > > hole_boundary_id_filters
std::vector< std::set< BoundaryID > > hole_boundary_inner_id_defaults
std::string tri_elem_type
std::vector< bool > stitch_holes
BoundaryName output_boundary
std::vector< BoundaryName > input_boundary_names
bool has_output_subdomain_name
bool has_output_subdomain_id
SubdomainID output_subdomain_id