https://mooseframework.inl.gov
Boundary2DDelaunayGenerator.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
11 
12 #include "MooseMeshUtils.h"
13 #include "CastUniquePointer.h"
14 
15 #include "libmesh/boundary_info.h"
16 #include "libmesh/poly2tri_triangulator.h"
17 #include "libmesh/mesh_triangle_holes.h"
18 #include "libmesh/mesh_modification.h"
19 #include "libmesh/parallel_algebra.h"
20 
22 
25 {
28 
29  params.addClassDescription(
30  "Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into "
31  "a 2D mesh using Delaunay triangulation.");
32  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
33  params.addRequiredParam<std::vector<BoundaryName>>("boundary_names", "The boundaries to be used");
34  params.addParam<std::vector<std::vector<BoundaryName>>>(
35  "hole_boundary_names",
36  std::vector<std::vector<BoundaryName>>(),
37  "The optional boundaries to be used as the holes in the mesh during triangulation. Note that "
38  "this is a vector of vectors, which allows each hole to be defined as a combination of "
39  "multiple boundaries.");
40 
41  params.addParam<std::string>(
42  "level_set",
43  "Level set used to achieve more accurate reverse projection compared to interpolation.");
44  params.addParam<unsigned int>(
45  "max_level_set_correction_iterations",
46  3,
47  "Maximum number of iterations to correct the nodes based on the level set function.");
48  params.addRangeCheckedParam<Real>(
49  "max_angle_deviation",
50  60.0,
51  "max_angle_deviation>0 & max_angle_deviation<90",
52  "Maximum angle deviation from the global average normal vector in the input mesh.");
53 
54  params.addParam<BoundaryName>(
55  "output_external_boundary_name",
56  "",
57  "The optional name of the external boundary of the mesh to generate. If not provided, the "
58  "external boundary will be have a trivial id of 0.");
59 
60  return params;
61 }
62 
64  : SurfaceDelaunayGeneratorBase(parameters),
65  FunctionParserUtils<false>(parameters),
66  _input(getMesh("input")),
67  _boundary_names(getParam<std::vector<BoundaryName>>("boundary_names")),
68  _hole_boundary_names(getParam<std::vector<std::vector<BoundaryName>>>("hole_boundary_names")),
69  _max_level_set_correction_iterations(
70  getParam<unsigned int>("max_level_set_correction_iterations")),
71  _max_angle_deviation(getParam<Real>("max_angle_deviation")),
72  _output_external_boundary_name(getParam<BoundaryName>("output_external_boundary_name"))
73 {
74  if (isParamValid("level_set"))
75  {
76  _func_level_set = std::make_shared<SymFunction>();
77  // set FParser internal feature flags
79  if (isParamValid("constant_names") && isParamValid("constant_expressions"))
81  getParam<std::vector<std::string>>("constant_names"),
82  getParam<std::vector<std::string>>("constant_expressions"));
83  if (_func_level_set->Parse(getParam<std::string>("level_set"), "x,y,z") >= 0)
84  mooseError("Invalid function f(x,y,z)\n",
86  "\nin CutMeshByLevelSetGenerator ",
87  name(),
88  ".\n",
89  _func_level_set->ErrorMsg());
90 
91  _func_params.resize(3);
92  }
93 }
94 
95 std::unique_ptr<MeshBase>
97 {
98  std::unique_ptr<MeshBase> mesh_3d = std::move(_input);
99 
100  // Generate a new 2D block based on the sidesets
101  const auto new_block_id = MooseMeshUtils::getNextFreeSubdomainID(*mesh_3d);
102  try
103  {
105  mesh_3d, _boundary_names, new_block_id, SubdomainName(), type());
106  }
107  catch (MooseException & e)
108  {
109  if (((std::string)e.what()).compare(0, 12, "The sideset ") == 0)
110  paramError("boundary_names", e.what());
111  else
112  mooseError(e.what());
113  }
114 
115  // If holes are provided, we need to create new blocks for them too
116  std::vector<subdomain_id_type> hole_block_ids;
117  for (const auto & hole : _hole_boundary_names)
118  {
119  hole_block_ids.push_back(MooseMeshUtils::getNextFreeSubdomainID(*mesh_3d));
120  try
121  {
123  mesh_3d, hole, hole_block_ids.back(), SubdomainName(), type());
124  }
125  catch (MooseException & e)
126  {
127  if (((std::string)e.what()).compare(0, 12, "The sideset ") == 0)
128  paramError("hole_boundary_names", e.what());
129  else
130  mooseError(e.what());
131  }
132  }
133 
134  // Create a 2D mesh form the 2D block
135  auto mesh_2d = buildMeshBaseObject();
136  MooseMeshUtils::convertBlockToMesh(mesh_3d, mesh_2d, {std::to_string(new_block_id)});
137  // If holes are provided, we need to create a 2D mesh for each hole
138  std::vector<std::unique_ptr<MeshBase>> hole_meshes_2d;
139  for (const auto & hole_block_id : hole_block_ids)
140  {
141  hole_meshes_2d.push_back(buildMeshBaseObject());
143  mesh_3d, hole_meshes_2d.back(), {std::to_string(hole_block_id)});
144  }
145 
146  // We do not need the 3D mesh anymore
147  mesh_3d->clear();
148 
149  return General2DDelaunay(mesh_2d, hole_meshes_2d);
150 }
151 
152 Point
154 {
155  mooseAssert(elem.n_vertices() == 3 || elem.n_vertices() == 4, "unsupported element type.");
156  // Only the first three vertices are used to calculate the normal vector
157  const Point & p0 = *elem.node_ptr(0);
158  const Point & p1 = *elem.node_ptr(1);
159  const Point & p2 = *elem.node_ptr(2);
160 
161  if (elem.n_vertices() == 4)
162  {
163  const Point & p3 = *elem.node_ptr(3);
164  return ((p2 - p0).cross(p3 - p1)).unit();
165  }
166 
167  return ((p2 - p1).cross(p0 - p1)).unit();
168 }
169 
170 Point
172 {
173  Point mesh_norm = Point(0.0, 0.0, 0.0);
174  Real mesh_area = 0.0;
175 
176  // Check all the elements' normal vectors
177  for (const auto & elem : mesh.active_local_element_ptr_range())
178  {
179  const Real elem_area = elem->volume();
180  mesh_norm += elemNormal(*elem) * elem_area;
181  mesh_area += elem_area;
182  }
183  mesh.comm().sum(mesh_norm);
184  mesh.comm().sum(mesh_area);
185  mesh_norm /= mesh_area;
186  return mesh_norm.unit();
187 }
188 
189 Real
190 Boundary2DDelaunayGenerator::meshNormalDeviation2D(const MeshBase & mesh, const Point & global_norm)
191 {
192  Real max_deviation(0.0);
193  // Check all the elements' deviation from the global normal vector
194  for (const auto & elem : mesh.active_local_element_ptr_range())
195  {
196  const Real elem_deviation = std::acos(global_norm * elemNormal(*elem)) / M_PI * 180.0;
197  max_deviation = std::max(max_deviation, elem_deviation);
198  }
199  mesh.comm().max(max_deviation);
200  return max_deviation;
201 }
202 
203 Real
205 {
206  return evaluate(_func_level_set, std::vector<Real>({point(0), point(1), point(2), 0}));
207 }
208 
209 void
211 {
212  // Based on the given level set, we try to move the node in its normal direction
213  const Real diff = libMesh::TOLERANCE * 10.0; // A small value to perturb the node
214  const Real original_eval = levelSetEvaluator(node);
215  const Real xp_eval = levelSetEvaluator(node + Point(diff, 0.0, 0.0));
216  const Real yp_eval = levelSetEvaluator(node + Point(0.0, diff, 0.0));
217  const Real zp_eval = levelSetEvaluator(node + Point(0.0, 0.0, diff));
218  const Real xm_eval = levelSetEvaluator(node - Point(diff, 0.0, 0.0));
219  const Real ym_eval = levelSetEvaluator(node - Point(0.0, diff, 0.0));
220  const Real zm_eval = levelSetEvaluator(node - Point(0.0, 0.0, diff));
221  const Point grad = Point((xp_eval - xm_eval) / (2.0 * diff),
222  (yp_eval - ym_eval) / (2.0 * diff),
223  (zp_eval - zm_eval) / (2.0 * diff));
224  const Real xyz_diff = -original_eval / grad.contract(grad);
225  node(0) += xyz_diff * grad(0);
226  node(1) += xyz_diff * grad(1);
227  node(2) += xyz_diff * grad(2);
228 }
229 
230 std::unique_ptr<MeshBase>
232  std::unique_ptr<MeshBase> & mesh_2d, std::vector<std::unique_ptr<MeshBase>> & hole_meshes_2d)
233 {
234  // If a level set is provided, we need to check if the nodes in the original 2D mesh match the
235  // level set
236  if (_func_level_set)
237  {
238  for (const auto & node : mesh_2d->node_ptr_range())
239  {
241  {
242  paramError("level_set",
243  "The level set function does not match the nodes in the given boundary of the "
244  "input mesh.");
245  }
246  }
247  }
248 
249  // Easier to work with a TRI3 mesh
250  // all_tri() also prepares the mesh for use
251  mesh_2d->prepare_for_use();
252  MeshTools::Modification::all_tri(*mesh_2d);
253  const auto mesh_2d_ext_bdry = MooseMeshUtils::getNextFreeBoundaryID(*mesh_2d);
254  for (const auto & elem : mesh_2d->active_element_ptr_range())
255  for (const auto & i_side : elem->side_index_range())
256  if (elem->neighbor_ptr(i_side) == nullptr)
257  mesh_2d->get_boundary_info().add_side(elem, i_side, mesh_2d_ext_bdry);
258 
259  // Create a clone of the 2D mesh to be used for the 1D mesh generation
260  auto mesh_2d_dummy = dynamic_pointer_cast<MeshBase>(mesh_2d->clone());
261  // Generate a new 1D block based on the external boundary
262  const auto new_block_id_1d = MooseMeshUtils::getNextFreeSubdomainID(*mesh_2d_dummy);
263 
265  mesh_2d_dummy, {std::to_string(mesh_2d_ext_bdry)}, new_block_id_1d, SubdomainName(), type());
266 
267  // Create a 1D mesh form the 1D block
268  auto mesh_1d = buildMeshBaseObject();
269  MooseMeshUtils::convertBlockToMesh(mesh_2d_dummy, mesh_1d, {std::to_string(new_block_id_1d)});
270  mesh_2d_dummy->clear();
271 
272  // If we have holes, we need to create a 1D mesh for each hole
273  std::vector<std::unique_ptr<MeshBase>> hole_meshes_1d;
274  for (auto & hole_mesh_2d : hole_meshes_2d)
275  {
276  // As we do not need these holes for reverse projection, we do not need to convert them to TRI3
277  // meshes, but we still need to create a 1D mesh for each hole
278  hole_mesh_2d->find_neighbors();
279  const auto hole_mesh_2d_ext_bdry = MooseMeshUtils::getNextFreeBoundaryID(*hole_mesh_2d);
280  for (const auto & elem : hole_mesh_2d->active_element_ptr_range())
281  for (const auto & i_side : elem->side_index_range())
282  if (elem->neighbor_ptr(i_side) == nullptr)
283  hole_mesh_2d->get_boundary_info().add_side(elem, i_side, mesh_2d_ext_bdry);
284  const auto new_hole_block_id_1d = MooseMeshUtils::getNextFreeSubdomainID(*hole_mesh_2d);
286  {std::to_string(hole_mesh_2d_ext_bdry)},
287  new_hole_block_id_1d,
288  SubdomainName(),
289  type());
290  // Create a 1D mesh form the 1D block
291  hole_meshes_1d.push_back(buildMeshBaseObject());
293  hole_mesh_2d, hole_meshes_1d.back(), {std::to_string(new_hole_block_id_1d)});
294  hole_mesh_2d->clear();
295  }
296 
297  // Find centroid of the 2D mesh
298  const Point centroid = MooseMeshUtils::meshCentroidCalculator(*mesh_2d);
299  // calculate an average normal vector of the 2D mesh
300  const Point mesh_norm = meshNormal2D(*mesh_2d);
301  // Check the deviation of the mesh normal vector from the global average normal vector
302  if (meshNormalDeviation2D(*mesh_2d, mesh_norm) > _max_angle_deviation)
303  paramError("boundary_names",
304  "The normal vector of some elements in the 2D mesh deviates too much from the "
305  "global average normal vector. The maximum deviation is " +
306  std::to_string(_max_angle_deviation) +
307  ". Consider dividing the boundary into several parts to "
308  "reduce the angle deviation.");
309 
310  // Move both 2d and 1d meshes to the centroid of the 2D mesh
311  MeshTools::Modification::translate(*mesh_1d, -centroid(0), -centroid(1), -centroid(2));
312  MeshTools::Modification::translate(*mesh_2d, -centroid(0), -centroid(1), -centroid(2));
313  // Alsop need to translate the 1D hole meshes if applicable
314  for (auto & hole_mesh_1d : hole_meshes_1d)
315  MeshTools::Modification::translate(*hole_mesh_1d, -centroid(0), -centroid(1), -centroid(2));
316 
317  // Calculate the Euler angles to rotate the meshes so that the 2D mesh is close to the XY plane
318  // (i.e., the normal vector of the 2D mesh is aligned with the Z axis)
319  const Real theta = std::acos(mesh_norm(2)) / M_PI * 180.0;
320  const Real phi =
321  (MooseUtils::absoluteFuzzyLessThan(mesh_norm(2), 1.0) ? std::atan2(mesh_norm(1), mesh_norm(0))
322  : 0.0) /
323  M_PI * 180.0;
324  MeshTools::Modification::rotate(*mesh_1d, 90.0 - phi, theta, 0.0);
325  MeshTools::Modification::rotate(*mesh_2d, 90.0 - phi, theta, 0.0);
326  // Also rotate the 1D hole meshes if applicable
327  for (auto & hole_mesh_1d : hole_meshes_1d)
328  MeshTools::Modification::rotate(*hole_mesh_1d, 90.0 - phi, theta, 0.0);
329 
330  // Clone the 2D mesh to be used for reverse projection later
331  auto mesh_2d_xyz = dynamic_pointer_cast<MeshBase>(mesh_2d->clone());
332 
333  // Project the 2D mesh to the XY plane so that XYDelaunay can be used
334  for (const auto & node : mesh_2d->node_ptr_range())
335  (*node)(2) = 0;
336  // Project the 1D mesh to the XY plane as well
337  for (const auto & node : mesh_1d->node_ptr_range())
338  (*node)(2) = 0;
339  // Also project the 1D hole meshes to the XY plane if applicable
340  for (auto & hole_mesh_1d : hole_meshes_1d)
341  {
342  for (const auto & node : hole_mesh_1d->node_ptr_range())
343  (*node)(2) = 0;
344  }
345 
346  std::vector<libMesh::TriangulatorInterface::MeshedHole> meshed_holes;
347  std::vector<libMesh::TriangulatorInterface::Hole *> triangulator_hole_ptrs(hole_meshes_1d.size());
348  meshed_holes.reserve(hole_meshes_1d.size());
349  for (auto hole_i : index_range(hole_meshes_1d))
350  {
351  hole_meshes_1d[hole_i]->prepare_for_use();
352  meshed_holes.emplace_back(*hole_meshes_1d[hole_i]);
353  triangulator_hole_ptrs[hole_i] = &meshed_holes.back();
354  }
355 
356  // Finally, triangulation
357  std::unique_ptr<UnstructuredMesh> mesh =
358  dynamic_pointer_cast<UnstructuredMesh>(std::move(mesh_1d));
359 
360  Poly2TriTriangulator poly2tri(*mesh);
361  poly2tri.triangulation_type() = TriangulatorInterface::PSLG;
362 
363  poly2tri.set_interpolate_boundary_points(0);
364  poly2tri.set_refine_boundary_allowed(false);
365  poly2tri.set_verify_hole_boundaries(false);
366  poly2tri.desired_area() = 0;
367  poly2tri.minimum_angle() = 0; // Not yet supported
368  poly2tri.smooth_after_generating() = false;
369  if (!triangulator_hole_ptrs.empty())
370  poly2tri.attach_hole_list(&triangulator_hole_ptrs);
371  // Future TODO: correct the area function based on the local normal vector
373  poly2tri.set_auto_area_function(this->comm(),
378  poly2tri.triangulate();
379 
380  // Reverse the projection based on the original 2D mesh
381  for (const auto & node : mesh->node_ptr_range())
382  {
383  bool node_mod = false;
384  // Try to find the element in mesh_2d that contains the new node
385  for (const auto & elem : mesh_2d->active_element_ptr_range())
386  {
387  if (elem->contains_point(Point((*node)(0), (*node)(1), 0.0)))
388  {
389  // Element id
390  const auto elem_id = elem->id();
391  // element in xyz_in_xyz
392  const Elem & elem_xyz = *mesh_2d_xyz->elem_ptr(elem_id);
393 
394  const Point elem_normal = elemNormal(elem_xyz);
395  const Point & elem_p = *mesh_2d_xyz->elem_ptr(elem_id)->node_ptr(0);
396 
397  // if the x and y values of the node is the same as the elem_p's first node, we can just
398  // move it to that node's position
399  if (MooseUtils::absoluteFuzzyEqual((*node)(0), elem_p(0)) &&
400  MooseUtils::absoluteFuzzyEqual((*node)(1), elem_p(1)))
401  {
402  (*node)(2) = elem_p(2);
403  node_mod = true;
404  break;
405  }
406  // Otherwise, we need to find a position inside the 2D element
407  // It has the same x and y coordinates as the node in the projected mesh;
408  (*node)(2) = elem_p(2) - (((*node)(0) - elem_p(0)) * elem_normal(0) +
409  ((*node)(1) - elem_p(1)) * elem_normal(1)) /
410  elem_normal(2);
411  node_mod = true;
412  break;
413  }
414  }
415  if (!node_mod)
416  mooseError("Node not found in mesh_in_xy");
417  }
418 
419  // Rotate the mesh back
420  MeshTools::Modification::rotate(*mesh, 0.0, -theta, phi - 90.0);
421  // Translate the mesh back
422  MeshTools::Modification::translate(*mesh, centroid(0), centroid(1), centroid(2));
423 
424  // Correct the nodes based on the level set function
425  if (_func_level_set)
426  {
427  for (const auto & node : mesh->node_ptr_range())
428  {
429  unsigned int iter_ct = 0;
430  while (iter_ct < _max_level_set_correction_iterations &&
432  {
433  levelSetCorrection(*node);
434  ++iter_ct;
435  }
436  }
437  }
438 
439  // Assign the external boundary name if provided
440  if (!_output_external_boundary_name.empty())
441  {
442  const std::vector<BoundaryID> output_boundary_id =
444 
446  mesh->get_boundary_info().sideset_name(output_boundary_id[0]) = _output_external_boundary_name;
447  }
448 
449  mesh->set_isnt_prepared();
450 
451  return mesh;
452 }
GenericReal< is_ad > evaluate(SymFunctionPtr &, const std::string &object_name="")
Evaluate FParser object and check EvalError.
void addFParserConstants(SymFunctionPtr &parser, const std::vector< std::string > &constant_names, const std::vector< std::string > &constant_expressions) const
add constants (which can be complex expressions) to the parser object
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
Boundary2DDelaunayGenerator(const InputParameters &parameters)
virtual const char * what() const
Get out the error message.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
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:435
void createSubdomainFromSidesets(std::unique_ptr< MeshBase > &mesh, std::vector< BoundaryName > boundary_names, const SubdomainID new_subdomain_id, const SubdomainName new_subdomain_name, const std::string type_name)
Create a new subdomain by generating new side elements from a list of sidesets in a given mesh...
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseBase.h:384
const std::vector< std::vector< BoundaryName > > _hole_boundary_names
The boundaries to be used as holes.
static constexpr Real TOLERANCE
Base class for Delaunay mesh generators applied to a surface.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
BoundaryName _output_external_boundary_name
The name of the external boundary of the mesh to generate.
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
const unsigned int _max_level_set_correction_iterations
Maximum number of iterations to correct the nodes based on the level set function.
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...
auto max(const L &left, const R &right)
const bool _use_auto_area_func
Whether to use automatic desired area function.
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:99
std::unique_ptr< MeshBase > & _input
The input mesh name.
virtual std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
const Real _max_angle_deviation
Max angle deviation from the global average normal vector in the input mesh.
void change_boundary_id(MeshBase &mesh, const boundary_id_type old_id, const boundary_id_type new_id)
bool absoluteFuzzyLessThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether a variable is less than another variable within an absolute tolerance...
Definition: MooseUtils.h:475
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:89
std::unique_ptr< MeshBase > General2DDelaunay(std::unique_ptr< MeshBase > &mesh_2d, std::vector< std::unique_ptr< MeshBase >> &hole_meshes_2d)
Generate a 2D mesh using Delaunay triangulation based on the input 2D boundary mesh and the 2D hole m...
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.
const unsigned int _auto_area_function_num_points
Maximum number of points to use for the inverse distance interpolation for automatic area function...
Real levelSetEvaluator(const Point &point)
Evaluate the level set function at a given point.
const Real _auto_area_func_default_size_dist
Background size&#39;s effective distance for automatic desired area function.
SymFunctionPtr _func_level_set
function parser object describing the level set
registerMooseObject("MooseApp", Boundary2DDelaunayGenerator)
Provides a way for users to bail out of the current solve.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Point elemNormal(const Elem &elem)
Calculate the normal vector of a 2D element based the first three vertices.
const Real _auto_area_function_power
Power of the polynomial used in the inverse distance interpolation for automatic area function...
std::vector< GenericReal< is_ad > > _func_params
Array to stage the parameters passed to the functions when calling Eval.
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...
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:267
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...
static InputParameters validParams()
static InputParameters validParams()
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...
Point meshNormal2D(const MeshBase &mesh)
Calculate the average normal vector of a 2D mesh based on the normal vectors of its elements using th...
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
void levelSetCorrection(Node &node)
Correct the position of a node based on the level set function.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:195
Point meshCentroidCalculator(const MeshBase &mesh)
Calculates the centroid of a MeshBase.
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Build a MeshBase object whose underlying type will be determined by the Mesh input file block...
void convertBlockToMesh(std::unique_ptr< MeshBase > &source_mesh, std::unique_ptr< MeshBase > &target_mesh, const std::vector< SubdomainName > &target_blocks)
Convert a list of blocks in a given mesh to a standalone new mesh.
const Real _auto_area_func_default_size
Background size for automatic desired area function.
SubdomainID getNextFreeSubdomainID(MeshBase &input_mesh)
Checks input mesh and returns max(block ID) + 1, which represents a block ID that is not currently in...
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 ErrorVector unsigned int
auto index_range(const T &sizable)
const std::vector< BoundaryName > _boundary_names
The boundaries to be converted to a 2D mesh.
void setParserFeatureFlags(SymFunctionPtr &) const
apply input parameters to internal feature flags of the parser object