https://mooseframework.inl.gov
Loading...
Searching...
No Matches
XYDelaunayGenerator.C
Go to the documentation of this file.
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 "XYDelaunayGenerator.h"
11
12#include "CastUniquePointer.h"
13#include "MooseMeshUtils.h"
15#include "BoundaryLayerUtils.h"
16#include "MooseUtils.h"
17
18#include "libmesh/int_range.h"
19#include "libmesh/mesh_modification.h"
20#include "libmesh/mesh_serializer.h"
21#include "libmesh/unstructured_mesh.h"
22#include "DelimitedFileReader.h"
23
25
28{
30
31 MooseEnum algorithm("BINARY EXHAUSTIVE", "BINARY");
32 MooseEnum tri_elem_type("TRI3 TRI6 TRI7 DEFAULT", "DEFAULT");
33
34 params.addRequiredParam<MeshGeneratorName>(
35 "boundary",
36 "The input MeshGenerator defining the output outer boundary and required Steiner points.");
37 params.addParam<std::vector<BoundaryName>>(
38 "input_boundary_names", "2D-input-mesh boundaries defining the output mesh outer boundary");
39 params.addParam<std::vector<SubdomainName>>(
40 "input_subdomain_names", "1D-input-mesh subdomains defining the output mesh outer boundary");
41 params.addParam<unsigned int>("add_nodes_per_boundary_segment",
42 0,
43 "How many more nodes to add in each outer boundary segment.");
44 params.addParam<bool>(
45 "refine_boundary", true, "Whether to allow automatically refining the outer boundary.");
46
47 params.addParam<SubdomainName>("output_subdomain_name",
48 "Subdomain name to set on new triangles.");
49 params.addParam<SubdomainID>("output_subdomain_id", "Subdomain id to set on new triangles.");
50
51 params.addParam<BoundaryName>(
52 "output_boundary",
53 "Boundary name to set on new outer boundary. Default ID: 0 if no hole meshes are stitched; "
54 "or maximum boundary ID of all the stitched hole meshes + 1.");
55 params.addParam<std::vector<BoundaryName>>(
56 "hole_boundaries",
57 "Boundary names to set on holes. Default IDs are numbered up from 1 if no hole meshes are "
58 "stitched; or from maximum boundary ID of all the stitched hole meshes + 2.");
59
60 params.addParam<bool>(
61 "verify_holes",
62 true,
63 "Verify holes do not intersect boundary or each other. Asymptotically costly.");
64
65 params.addParam<bool>("smooth_triangulation",
66 false,
67 "Whether to do Laplacian mesh smoothing on the generated triangles.");
68 params.addParam<std::vector<MeshGeneratorName>>(
69 "holes", std::vector<MeshGeneratorName>(), "The MeshGenerators that define mesh holes.");
70 params.addParam<std::vector<bool>>(
71 "stitch_holes", std::vector<bool>(), "Whether to stitch to the mesh defining each hole.");
72 params.addParam<std::vector<bool>>("refine_holes",
73 std::vector<bool>(),
74 "Whether to allow automatically refining each hole boundary.");
75 params.addRangeCheckedParam<Real>(
76 "desired_area",
77 0,
78 "desired_area>=0",
79 "Desired (maximum) triangle area, or 0 to skip uniform refinement");
80 params.addParam<std::string>(
81 "desired_area_func",
82 std::string(),
83 "Desired area as a function of x,y; omit to skip non-uniform refinement");
84
85 params.addParam<MooseEnum>(
86 "algorithm",
87 algorithm,
88 "Control the use of binary search for the nodes of the stitched surfaces.");
89 params.addParam<MooseEnum>(
90 "tri_element_type", tri_elem_type, "Type of the triangular elements to be generated.");
91 params.addParam<bool>(
92 "verbose_stitching", false, "Whether mesh stitching should have verbose output.");
93 params.addParam<std::vector<Point>>("interior_points",
94 {},
95 "Interior node locations, if no smoothing is used. Any point "
96 "outside the surface will not be meshed.");
97 params.addParam<std::vector<FileName>>(
98 "interior_point_files", {}, "Text file(s) with the interior points, one per line");
99 params.addClassDescription("Triangulates meshes within boundaries defined by input meshes.");
100
101 params.addRangeCheckedParam<Real>("outer_boundary_layer_thickness",
102 0,
103 "outer_boundary_layer_thickness>=0",
104 "Thickness of the outer boundary layer to be added.");
105 params.addParam<unsigned int>(
106 "outer_boundary_layer_num", 0, "Number of layers for the outer boundary layer.");
107 params.addRangeCheckedParam<Real>(
108 "outer_boundary_layer_bias",
109 1.0,
110 "outer_boundary_layer_bias>0",
111 "Bias factor for the thickness of each layer in the outer boundary layer.");
112
113 params.addRangeCheckedParam<std::vector<Real>>(
114 "holes_boundary_layer_thickness",
115 "holes_boundary_layer_thickness>=0",
116 "Thickness of the hole boundary layers to be added.");
117 params.addParam<std::vector<unsigned int>>("holes_boundary_layer_num",
118 "Numbers of layers for the hole boundary layers.");
119 params.addRangeCheckedParam<std::vector<Real>>(
120 "holes_boundary_layer_bias",
121 "holes_boundary_layer_bias>0",
122 "Bias factors for the thickness of each layer in the hole boundary layers.");
123
124 params.addParamNamesToGroup("interior_points interior_point_files",
125 "Mandatory mesh interior nodes");
126
127 params.addParamNamesToGroup("outer_boundary_layer_thickness outer_boundary_layer_num "
128 "outer_boundary_layer_bias holes_boundary_layer_thickness "
129 "holes_boundary_layer_num holes_boundary_layer_bias",
130 "Boundary layer");
131
132 return params;
133}
134
136 : SurfaceDelaunayGeneratorBase(parameters),
137 _bdy_ptr(getMesh("boundary")),
138 _add_nodes_per_boundary_segment(getParam<unsigned int>("add_nodes_per_boundary_segment")),
139 _refine_bdy(getParam<bool>("refine_boundary")),
140 _output_subdomain_id(0),
141 _smooth_tri(getParam<bool>("smooth_triangulation")),
142 _verify_holes(getParam<bool>("verify_holes")),
143 _hole_ptrs(getMeshes("holes")),
144 _stitch_holes(getParam<std::vector<bool>>("stitch_holes")),
145 _refine_holes(getParam<std::vector<bool>>("refine_holes")),
146 _desired_area(getParam<Real>("desired_area")),
147 _desired_area_func(getParam<std::string>("desired_area_func")),
148 _algorithm(parameters.get<MooseEnum>("algorithm")),
149 _tri_elem_type(parameters.get<MooseEnum>("tri_element_type")),
150 _verbose_stitching(parameters.get<bool>("verbose_stitching")),
151 _interior_points(getParam<std::vector<Point>>("interior_points")),
152 _outer_boundary_layer_thickness(getParam<Real>("outer_boundary_layer_thickness")),
153 _outer_boundary_layer_num(getParam<unsigned int>("outer_boundary_layer_num")),
154 _outer_boundary_layer_bias(getParam<Real>("outer_boundary_layer_bias")),
155 _holes_boundary_layer_thickness(
156 isParamValid("holes_boundary_layer_thickness")
157 ? getParam<std::vector<Real>>("holes_boundary_layer_thickness")
158 : std::vector<Real>()),
159 _holes_boundary_layer_num(isParamValid("holes_boundary_layer_num")
160 ? getParam<std::vector<unsigned int>>("holes_boundary_layer_num")
161 : std::vector<unsigned int>()),
162 _holes_boundary_layer_bias(isParamValid("holes_boundary_layer_bias")
163 ? getParam<std::vector<Real>>("holes_boundary_layer_bias")
164 : std::vector<Real>())
165{
166 if ((_desired_area > 0.0 && !_desired_area_func.empty()) ||
169 paramError("desired_area_func",
170 "Only one of the three methods ('desired_area', 'desired_area_func', and "
171 "'_use_auto_area_func') to set element area limit should be used.");
172
174 if (isParamSetByUser("auto_area_func_default_size") ||
175 isParamSetByUser("auto_area_func_default_size_dist") ||
176 isParamSetByUser("auto_area_function_num_points") ||
177 isParamSetByUser("auto_area_function_power"))
178 paramError("use_auto_area_func",
179 "If this parameter is set to false, the following parameters should not be set: "
180 "'auto_area_func_default_size', 'auto_area_func_default_size_dist', "
181 "'auto_area_function_num_points', 'auto_area_function_power'.");
182
183 if (!_stitch_holes.empty() && _stitch_holes.size() != _hole_ptrs.size())
184 paramError("stitch_holes", "Need one stitch_holes entry per hole, if specified.");
185
186 for (auto hole_i : index_range(_stitch_holes))
187 if (_stitch_holes[hole_i] && (hole_i >= _refine_holes.size() || _refine_holes[hole_i]))
188 paramError("refine_holes", "Disable auto refine of any hole boundary to be stitched.");
189
190 if (isParamValid("hole_boundaries"))
191 {
192 auto & hole_boundaries = getParam<std::vector<BoundaryName>>("hole_boundaries");
193 if (hole_boundaries.size() != _hole_ptrs.size())
194 paramError("hole_boundaries", "Need one hole_boundaries entry per hole, if specified.");
195 }
196 // Copied from MultiApp.C
197 const auto & positions_files = getParam<std::vector<FileName>>("interior_point_files");
198 for (const auto p_file_it : index_range(positions_files))
199 {
200 const std::string positions_file = positions_files[p_file_it];
201 MooseUtils::DelimitedFileReader file(positions_file, &_communicator);
203 file.read();
204
205 const std::vector<Point> & data = file.getDataAsPoints();
206 for (const auto & d : data)
207 _interior_points.push_back(d);
208 }
209 bool has_duplicates =
210 std::any_of(_interior_points.begin(),
211 _interior_points.end(),
212 [&](const Point & p)
213 { return std::count(_interior_points.begin(), _interior_points.end(), p) > 1; });
214 if (has_duplicates)
215 paramError("interior_points", "Duplicate points were found in the provided interior points.");
216
220 "outer_boundary_layer_thickness",
221 "this parameter must be set as non-zero along with a non-zero outer_boundary_layer_num.");
222
224 {
226 paramError("add_nodes_per_boundary_segment",
227 "Cannot add nodes per boundary segment when using an outer boundary layer.");
228 if (_refine_bdy)
229 paramError("refine_boundary", "Cannot refine boundary when using an outer boundary layer.");
230 }
231
236 paramError("holes_boundary_layer_num",
237 "holes_boundary_layer_thickness, holes_boundary_layer_bias and this parameter must "
238 "be specified or not specified together.");
241 paramError("holes_boundary_layer_thickness",
242 "If specified, this parameter must have the same length as 'holes'.");
244 paramError("holes_boundary_layer_num",
245 "If specified, this parameter must have the same length as 'holes'.");
247 paramError("holes_boundary_layer_bias",
248 "If specified, this parameter must have the same length as 'holes'.");
249 for (const auto & i : index_range(_holes_boundary_layer_thickness))
250 {
254 "holes_boundary_layer_thickness",
255 "entry " + std::to_string(i) +
256 " must be set as non-zero along with a non-zero holes_boundary_layer_num entry.");
258 {
259 if ((_refine_holes.size() > i && _refine_holes[i]) || _refine_holes.empty())
260 paramError("refine_holes", "Cannot refine hole boundary when using a hole boundary layer.");
261 }
262 }
263}
264
265std::unique_ptr<MeshBase>
267{
269 if (isParamValid("input_boundary_names"))
270 xyd_opts.input_boundary_names = getParam<std::vector<BoundaryName>>("input_boundary_names");
271 if (isParamValid("input_subdomain_names"))
272 xyd_opts.input_subdomain_names = getParam<std::vector<SubdomainName>>("input_subdomain_names");
274 xyd_opts.refine_bdy = _refine_bdy;
275 xyd_opts.verify_holes = _verify_holes;
276 xyd_opts.smooth_tri = _smooth_tri;
277 xyd_opts.desired_area = _desired_area;
285 xyd_opts.tri_elem_type = std::string(_tri_elem_type);
286 xyd_opts.stitch_holes = _stitch_holes;
287 xyd_opts.refine_holes = _refine_holes;
288 xyd_opts.use_binary_search = (_algorithm == "BINARY");
290 if (isParamValid("output_subdomain_id"))
291 {
292 xyd_opts.has_output_subdomain_id = true;
293 xyd_opts.output_subdomain_id = getParam<SubdomainID>("output_subdomain_id");
294 }
295 if (isParamValid("output_subdomain_name"))
296 {
297 xyd_opts.has_output_subdomain_name = true;
298 xyd_opts.output_subdomain_name = getParam<SubdomainName>("output_subdomain_name");
299 }
300 if (isParamValid("output_boundary"))
301 {
302 xyd_opts.has_output_boundary = true;
303 xyd_opts.output_boundary = getParam<BoundaryName>("output_boundary");
304 }
305 if (isParamValid("hole_boundaries"))
306 xyd_opts.hole_boundaries = getParam<std::vector<BoundaryName>>("hole_boundaries");
307
308 std::vector<std::unique_ptr<MeshBase>> hole_meshes(_hole_ptrs.size());
309 for (auto hole_i : index_range(_hole_ptrs))
310 hole_meshes[hole_i] = std::move(*_hole_ptrs[hole_i]);
311
312 std::unique_ptr<MeshBase> boundary_mesh = std::move(_bdy_ptr);
313
314 // Preserve the user-facing output_boundary so we can restore it after the outer-ring stitch-back
315 // (we'll temporarily replace it with a sentinel name to locate the seam).
316 const bool user_has_output_boundary = xyd_opts.has_output_boundary;
317 const BoundaryName user_output_boundary = xyd_opts.output_boundary;
318 const BoundaryName tmp_outer_name("__xyd_bdry_layer_tmp_outer__");
319
320 const bool using_outer_layer = (_outer_boundary_layer_num > 0);
321 const SubdomainID layer_sd_id =
323 const SubdomainName layer_sd_name =
324 xyd_opts.has_output_subdomain_name ? xyd_opts.output_subdomain_name : SubdomainName();
325
326 // Build outer boundary-layer ring if requested. The ring's innermost side (bcid 1) becomes the
327 // outer constraint for the interior triangulation; we then stitch a clone of the ring back onto
328 // the result at that seam.
329 std::unique_ptr<MeshBase> outer_ring_clone;
330 if (using_outer_layer)
331 {
332 auto outer_ring = BoundaryLayerUtils::buildBoundaryLayerRing(*this,
333 *boundary_mesh,
334 xyd_opts.input_boundary_names,
338 /*outward=*/false,
340 layer_sd_id,
341 layer_sd_name);
342 outer_ring_clone = outer_ring->clone();
343 boundary_mesh = std::move(outer_ring);
344 xyd_opts.input_boundary_names = {BoundaryName("1")};
345 xyd_opts.has_output_boundary = true;
346 xyd_opts.output_boundary = tmp_outer_name;
347 }
348
349 // Build hole boundary-layer rings if requested. Each ring is stitched into the result by the
350 // standard hole-stitching path in triangulateWithDelaunay (with stitch_holes forced true).
351 for (auto hole_i : index_range(_hole_ptrs))
352 {
353 if (hole_i < _holes_boundary_layer_num.size() && _holes_boundary_layer_num[hole_i] > 0)
354 {
355 const bool keep_input = (hole_i < _stitch_holes.size() && _stitch_holes[hole_i]);
356 auto hole_ring =
358 *hole_meshes[hole_i],
359 std::vector<BoundaryName>(),
363 /*outward=*/true,
365 layer_sd_id,
366 layer_sd_name);
367
368 if (keep_input)
369 {
370 // Stitch the original hole mesh into the ring at ring's innermost side (bcid 1).
371 auto & ring_u = dynamic_cast<UnstructuredMesh &>(*hole_ring);
372 auto & inp_u = dynamic_cast<UnstructuredMesh &>(*hole_meshes[hole_i]);
373 libMesh::MeshSerializer s1(ring_u), s2(inp_u);
374 if (!ring_u.is_prepared())
375 ring_u.prepare_for_use();
376 if (!inp_u.is_prepared())
377 inp_u.prepare_for_use();
378 // Renumber input mesh boundary ids so they don't overlap with the ring's, mirroring the
379 // approach in StitchMeshGenerator. This avoids degenerate stitching when both meshes
380 // contain the same bcids on different sides.
381 const auto & ring_bids = ring_u.get_boundary_info().get_global_boundary_ids();
382 const auto inp_bids = inp_u.get_boundary_info().get_global_boundary_ids();
383 const auto max_bid = std::max(*ring_bids.rbegin(),
384 inp_bids.empty() ? boundary_id_type(0) : *inp_bids.rbegin());
385 BoundaryID ext_id = 1;
386 bool overlap = false;
387 for (auto b : inp_bids)
388 if (ring_bids.count(b))
389 overlap = true;
390 if (overlap)
391 {
392 BoundaryID idx = 1;
393 for (auto b : inp_bids)
394 {
395 const auto new_b = max_bid + (idx++);
396 inp_u.get_boundary_info().renumber_id(b, new_b);
397 }
398 ext_id = max_bid + idx;
399 }
400 else
401 ext_id = max_bid + 1;
402 inp_u.comm().max(ext_id);
403 bool has_ext = false;
404 MooseMeshUtils::addExternalBoundary(inp_u, ext_id, has_ext);
405 mooseAssert(has_ext, "A 2D-XY mesh should have an external boundary.");
406 const auto ring_u_ext_id =
407 std::max(MooseMeshUtils::getNextFreeBoundaryID(ring_u), BoundaryID(ext_id + 1));
408 MooseMeshUtils::changeBoundaryId(ring_u, 1, ring_u_ext_id, false);
409 if (xyd_opts.hole_boundary_inner_id_defaults.size() <= hole_i)
410 xyd_opts.hole_boundary_inner_id_defaults.resize(_hole_ptrs.size());
411 xyd_opts.hole_boundary_inner_id_defaults[hole_i] = {ring_u_ext_id};
412 // we want to keep the ring's original inner bcid (1) for later use.
413 ring_u.stitch_meshes(inp_u,
414 1,
415 ext_id,
416 TOLERANCE,
417 /*clear_stitched_bcids=*/true,
419 _algorithm == "BINARY",
420 /*enforce_all_nodes_match_on_boundaries=*/false,
421 /*merge_boundary_nodes_all_or_nothing=*/false,
422 /*remap_subdomain_ids=*/false);
423 }
424
425 hole_meshes[hole_i] = std::move(hole_ring);
426 if (xyd_opts.stitch_holes.size() <= hole_i)
427 xyd_opts.stitch_holes.resize(_hole_ptrs.size(), false);
428 xyd_opts.stitch_holes[hole_i] = true;
429 // The ring presents multiple external manifolds; tell triangulateWithDelaunay to use the
430 // outermost (bcid (num_layers - 1) * 2) as the hole's outer boundary.
431 if (xyd_opts.hole_boundary_id_filters.size() <= hole_i)
432 xyd_opts.hole_boundary_id_filters.resize(_hole_ptrs.size());
433 xyd_opts.hole_boundary_id_filters[hole_i] = {
434 std::size_t((_holes_boundary_layer_num[hole_i] - 1) * 2)};
435 }
436 }
437
439 *this, std::move(boundary_mesh), std::move(hole_meshes), xyd_opts);
440
441 // Stitch the outer ring clone back onto the interior triangulation at the recorded seam.
442 if (outer_ring_clone)
443 {
444 auto sentinel_ids = MooseMeshUtils::getBoundaryIDs(*result, {tmp_outer_name}, false);
445 const boundary_id_type sentinel_id = sentinel_ids[0];
446
447 // Preserve the ring's outermost bcid (= (num_layers - 1) * 2) by renaming it to a high temp
448 // value so the post-stitch rename can recover it as the final outer bcid.
449 const boundary_id_type ring_outermost_orig =
450 boundary_id_type((_outer_boundary_layer_num - 1) * 2);
451 // The maximum boundary ID in the outer ring is _outer_boundary_layer_num * 2 - 1, so
452 // _outer_boundary_layer_num * 2 is safe for itself. We need the maximum boundary ID of the
453 // result mesh too.
454 const boundary_id_type ring_outermost_temp =
455 std::max(boundary_id_type(_outer_boundary_layer_num * 2),
458 *outer_ring_clone, ring_outermost_orig, ring_outermost_temp);
459
460 auto & result_u = dynamic_cast<UnstructuredMesh &>(*result);
461 auto & clone_u = dynamic_cast<UnstructuredMesh &>(*outer_ring_clone);
462 libMesh::MeshSerializer s1(result_u), s2(clone_u);
463 result_u.stitch_meshes(clone_u,
464 sentinel_id,
465 1,
466 TOLERANCE,
467 /*clear_stitched_bcids=*/true,
469 _algorithm == "BINARY");
470
471 libMesh::MeshTools::Modification::change_boundary_id(*result, ring_outermost_temp, sentinel_id);
472
473 if (user_has_output_boundary)
474 {
475 auto user_id = MooseMeshUtils::getBoundaryIDs(*result, {user_output_boundary}, true).front();
476 if (user_id != sentinel_id)
477 libMesh::MeshTools::Modification::change_boundary_id(*result, sentinel_id, user_id);
478 result->get_boundary_info().sideset_name(user_id) = user_output_boundary;
479 }
480
481 result->unset_is_prepared();
482 }
483
484 return result;
485}
boundary_id_type BoundaryID
subdomain_id_type SubdomainID
registerMooseObject("MooseApp", XYDelaunayGenerator)
void ErrorVector unsigned int
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition MooseBase.h:205
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition MooseBase.h:406
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
Utility class for reading delimited data (e.g., CSV data).
const std::vector< Point > getDataAsPoints() const
Get the data in Point format.
void read()
Perform the actual data reading.
Base class for Delaunay mesh generators applied to a surface.
const Real _auto_area_func_default_size_dist
Background size's effective distance for automatic desired area function.
const Real _auto_area_func_default_size
Background size for automatic desired area function.
const bool _use_auto_area_func
Whether to use automatic desired area function.
const Real _auto_area_function_power
Power of the polynomial used in the inverse distance interpolation for automatic area function.
const unsigned int _auto_area_function_num_points
Maximum number of points to use for the inverse distance interpolation for automatic area function.
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 _verify_holes
Whether to verify holes do not intersect boundary or each other.
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.
const Real _desired_area
Desired (maximum) triangle area.
XYDelaunayGenerator(const InputParameters &parameters)
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::string _desired_area_func
Desired triangle area as a (fparser-compatible) function of x,y.
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.
void change_boundary_id(MeshBase &mesh, const boundary_id_type old_id, const boundary_id_type new_id)
Bundle of inputs for triangulateWithDelaunay.
std::vector< SubdomainName > input_subdomain_names
std::vector< std::set< std::size_t > > hole_boundary_id_filters
std::vector< std::set< BoundaryID > > hole_boundary_inner_id_defaults