12#include "libmesh/int_range.h"
13#include "libmesh/parallel_implementation.h"
14#include "libmesh/parallel_algebra.h"
23 params.
addParam<
bool>(
"use_auto_area_func",
25 "Use the automatic area function for the triangle meshing region.");
27 "auto_area_func_default_size",
29 "Background size for automatic area function, or 0 to use non background size");
30 params.
addParam<Real>(
"auto_area_func_default_size_dist",
32 "Effective distance of background size for automatic area "
33 "function, or negative to use non background size");
34 params.
addParam<
unsigned int>(
"auto_area_function_num_points",
36 "Maximum number of nearest points used for the inverse distance "
37 "interpolation algorithm for automatic area function calculation.");
39 "auto_area_function_power",
41 "auto_area_function_power>0",
42 "Polynomial power of the inverse distance interpolation algorithm for automatic area "
43 "function calculation.");
45 params.
addClassDescription(
"Base class for Delaunay mesh generators applied to a surface.");
48 "use_auto_area_func auto_area_func_default_size auto_area_func_default_size_dist "
49 "auto_area_function_num_points auto_area_function_power",
50 "Automatic triangle meshing area control");
53 "max_angle_deviation",
55 "max_angle_deviation>0 & max_angle_deviation<90",
56 "Maximum angle deviation from the global average normal vector in the input mesh.");
58 "verbose",
false,
"Whether the generator should output additional information");
69 "The input MeshGenerator defining the output outer boundary and required Steiner points.");
70 params.
addParam<std::vector<BoundaryName>>(
71 "input_boundary_names",
"2D-input-mesh boundaries defining the output mesh outer boundary");
72 params.
addParam<std::vector<SubdomainName>>(
73 "input_subdomain_names",
"1D-input-mesh subdomains defining the output mesh outer boundary");
74 params.
addParam<
unsigned int>(
"add_nodes_per_boundary_segment",
76 "How many more nodes to add in each outer boundary segment.");
78 "refine_boundary",
true,
"Whether to allow automatically refining the outer boundary.");
80 params.
addParam<SubdomainName>(
"output_subdomain_name",
81 "Subdomain name to set on new triangles.");
85 "Boundary name to set on new outer boundary. Default ID: 0 if no hole meshes are stitched; "
86 "or maximum boundary ID of all the stitched hole meshes + 1.");
87 params.
addParam<std::vector<BoundaryName>>(
89 "Boundary names to set on holes. Default IDs are numbered up from 1 if no hole meshes are "
90 "stitched; or from maximum boundary ID of all the stitched hole meshes + 2.");
95 "Verify holes do not intersect boundary or each other. Asymptotically costly.");
97 params.
addParam<std::vector<MeshGeneratorName>>(
98 "holes", std::vector<MeshGeneratorName>(),
"The MeshGenerators that define mesh holes.");
100 "stitch_holes", std::vector<bool>(),
"Whether to stitch to the mesh defining each hole.");
101 params.
addParam<std::vector<bool>>(
"refine_holes",
103 "Whether to allow automatically refining each hole boundary.");
108 "Desired (maximum) triangle area, or 0 to skip uniform refinement");
112 "Desired area as a function of x,y; omit to skip non-uniform refinement");
119 _use_auto_area_func(getParam<bool>(
"use_auto_area_func")),
120 _auto_area_func_default_size(getParam<Real>(
"auto_area_func_default_size")),
121 _auto_area_func_default_size_dist(getParam<Real>(
"auto_area_func_default_size_dist")),
122 _auto_area_function_num_points(getParam<unsigned
int>(
"auto_area_function_num_points")),
123 _auto_area_function_power(getParam<Real>(
"auto_area_function_power")),
124 _max_angle_deviation(getParam<Real>(
"max_angle_deviation")),
125 _verbose(getParam<bool>(
"verbose"))
131 const std::vector<std::unique_ptr<MeshBase> *> & hole_ptrs)
const
133 const auto desired_area = getParam<Real>(
"desired_area");
134 const auto & desired_area_func = getParam<std::string>(
"desired_area_func");
136 if ((desired_area > 0.0 && !desired_area_func.empty()) ||
140 "Only one of the three methods ('desired_area', 'desired_area_func', and "
141 "'use_auto_area_func') to set element area limit should be used.");
149 "If this parameter is set to false, the following parameters should not be set: "
150 "'auto_area_func_default_size', 'auto_area_func_default_size_dist', "
151 "'auto_area_function_num_points', 'auto_area_function_power'.");
153 const auto & stitch_holes = getParam<std::vector<bool>>(
"stitch_holes");
154 const auto & refine_holes = getParam<std::vector<bool>>(
"refine_holes");
156 if (!stitch_holes.empty() && stitch_holes.size() != hole_ptrs.size())
157 paramError(
"stitch_holes",
"Need one stitch_holes entry per hole, if specified.");
159 for (
const auto hole_i : index_range(stitch_holes))
160 if (stitch_holes[hole_i] && (hole_i >= refine_holes.size() || refine_holes[hole_i]))
161 paramError(
"refine_holes",
"Disable auto refine of any hole boundary to be stitched.");
164 if (
getParam<std::vector<BoundaryName>>(
"hole_boundaries").size() != hole_ptrs.size())
165 paramError(
"hole_boundaries",
"Need one hole_boundaries entry per hole, if specified.");
171 std::vector<Point> sorted_points(interior_points);
172 std::sort(sorted_points.begin(), sorted_points.end());
173 const bool has_duplicates =
174 std::adjacent_find(sorted_points.begin(), sorted_points.end()) != sorted_points.end();
176 paramError(
"interior_points",
"Duplicate points were found in the provided interior points.");
188 opts.
refine_bdy = getParam<bool>(
"refine_boundary");
197 opts.
stitch_holes = getParam<std::vector<bool>>(
"stitch_holes");
198 opts.
refine_holes = getParam<std::vector<bool>>(
"refine_holes");
211 opts.
hole_boundaries = getParam<std::vector<BoundaryName>>(
"hole_boundaries");
217 mooseAssert(elem.n_vertices() == 3 || elem.n_vertices() == 4,
"unsupported element type.");
219 const Point & p0 = *elem.node_ptr(0);
220 const Point & p1 = *elem.node_ptr(1);
221 const Point & p2 = *elem.node_ptr(2);
223 if (elem.n_vertices() == 4)
225 const Point & p3 = *elem.node_ptr(3);
226 return ((p2 - p0).cross(p3 - p1)).unit();
229 return ((p2 - p1).cross(p0 - p1)).unit();
235 Point mesh_norm = Point(0.0, 0.0, 0.0);
236 Real mesh_area = 0.0;
239 for (
const auto & elem :
mesh.active_local_element_ptr_range())
241 const Real elem_area = elem->volume();
243 mesh_area += elem_area;
245 mesh.comm().sum(mesh_norm);
246 mesh.comm().sum(mesh_area);
247 mesh_norm /= mesh_area;
248 return mesh_norm.unit();
253 const Point & global_norm)
255 Real max_deviation(0.0);
257 for (
const auto & elem :
mesh.active_local_element_ptr_range())
259 const Real elem_deviation = std::acos(global_norm *
elemNormal(*elem)) / M_PI * 180.0;
260 max_deviation = std::max(max_deviation, elem_deviation);
262 _console <<
"Element " << elem->id() <<
" from subdomain ID " << elem->subdomain_id()
263 <<
" has normal deviation: " << elem_deviation << std::endl;
265 mesh.comm().max(max_deviation);
266 return max_deviation;
void ErrorVector unsigned int
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
MeshGenerators are objects that can modify or add to an existing mesh.
static InputParameters validParams()
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 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.
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
const bool _verbose
Whether the generator should be verbose.
Real meshNormalDeviation2D(const MeshBase &mesh, const Point &global_norm)
Calculate the maximum deviation of the normal vectors in a given mesh from a global average normal ve...
Point meshNormal2D(const MeshBase &mesh)
Calculate the average normal vector of a 2D mesh based on the normal vectors of its elements using th...
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.
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()
Point elemNormal(const Elem &elem)
Calculate the normal vector of a 2D element based the first three vertices.
SurfaceDelaunayGeneratorBase(const InputParameters ¶meters)
const Real _max_angle_deviation
Max angle deviation from the global average normal vector in the input mesh.
void fillDelaunayOptions(MeshTriangulationUtils::XYDelaunayOptions &opts) const
Fills the triangulation options that follow from the parameters boundaryAndHolesParams() adds,...
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.
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 ...
const unsigned int _auto_area_function_num_points
Maximum number of points to use for the inverse distance interpolation for automatic area function.
Bundle of inputs for triangulateWithDelaunay.
Real auto_area_func_default_size
SubdomainName output_subdomain_name
std::vector< SubdomainName > input_subdomain_names
unsigned int auto_area_function_num_points
std::vector< BoundaryName > hole_boundaries
Real auto_area_func_default_size_dist
std::vector< bool > stitch_holes
BoundaryName output_boundary
Real auto_area_function_power
std::vector< BoundaryName > input_boundary_names
std::vector< bool > refine_holes
bool has_output_subdomain_name
std::string desired_area_func
unsigned int add_nodes_per_boundary_segment