Boundary2DDelaunayGenerator

Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into a 2D mesh using Delaunay triangulation.

Overview

This Boundary2DDelaunayGenerator utilizes the 2D triangulation capabilities in the XY-plane, which is adopted by XYDelaunayGenerator and extends it to support more generalized 2D surface cases. The input of this generator is not limited to a 2D mesh residing in the XY-plane. Instead, it can accept a 2D mesh with curvature in the 3D space.

The input of this mesh generator is defined by a mesh name ("input") along with a list of boundary names ("boundary_names") within it. The generator will extract the specified boundaries from the input mesh and generate a 2D mesh through Delaunay triangulation based on them. The output mesh can be further processed and then used as input for 3D Delaunay mesh generation (XYZelaunayGenerator). This mesh generator also supports hole meshes defined as boundaries ("hole_boundary_names") in the input mesh as well as the automatic area control ("use_auto_area_func").

Methods

The same methods adopted by XYDelaunayGenerator are called by this mesh generator. To support a generalized 2D surface (see Figure 1a), the following approaches are implemented:

  • An average normal vector of the given 2D surface is computed based on the normal vectors of the elements weighted by their areas.

  • The 2D surface is then rotated and translated so that its centroid is on the XY-plane and the average normal vector is aligned with the Z-axis (see Figure 1b).

  • The 2D surface is projected onto the XY-plane so that the triangulation method can be applied (see Figure 1c).

  • The new 2D mesh in the XY-plane is generated through Delaunay triangulation (same as XYDelaunayGenerator)(see Figure 1d).

  • The new 2D mesh is reversely projected back to the original 3D space based on the original 2D surface.

  • The new 2D mesh is translated and rotated back to the original position of the 2D surface (see Figure 1e).

  • Optionally, the nodes in the new 2D mesh can be corrected using a provided level set function of the surface ("level_set")(see Figure 1f).

Figure 1: The workflow of the Boundary2DDelaunayGenerator mesh generator.

As projection is used to enable the triangulation of the 2D surface, it is crucial to limit the angle deviation of the element normals in the 2D mesh from the average normal vector of the surface. This is controlled by the "max_angle_deviation" parameter. Deviation must be less than 90 degrees to avert overlapping elements. The projection also introduces errors in the element area control. The actual element area to be controlled are the projected areas of the elements in the 2D mesh. A projection correction method will potentially be developed in the future.

Application

One common application of this mesh generator is to prepare 2D surface meshes to be used as input for 3D Delaunay mesh generation(XYZelaunayGenerator). For a raw 3D mesh with a closed 2D surface, the 2D surface can be divided into multiple regions to be compatible with the triangulation method with projection. Boundary2DDelaunayGenerator can be used to generate the 2D surface mesh with better mesh density and quality control. Especially, the surface generated by mesh cutting (e.g., CutMeshByPlaneGenerator and CutMeshByLevelSetGenerator) can be improved. The generated 2D surfaces can then be stitched together to form a closed surface mesh for 3D Delaunay mesh generation. An example is give in Listing 1 with visualization in Figure 2.

Listing 1: Example input file to use Boundary2DDelaunayGenerator to prepare a cylinder surface mesh for 3D Delaunay mesh generation.

[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
  [circle]
    type = ConcentricCircleMeshGenerator<<<{"description": "This ConcentricCircleMeshGenerator source code is to generate concentric circle meshes.", "href": "ConcentricCircleMeshGenerator.html"}>>>
    has_outer_square<<<{"description": "It determines if meshes for a outer square are added to concentric circle meshes."}>>> = false
    radii<<<{"description": "Radii of major concentric circles"}>>> = 1
    num_sectors<<<{"description": "num_sectors % 2 = 0, num_sectors > 0Number of azimuthal sectors in each quadrant'num_sectors' must be an even number."}>>> = 4
    rings<<<{"description": "Number of rings in each circle or in the enclosing square"}>>> = 1
    preserve_volumes<<<{"description": "Volume of concentric circles can be preserved using this function."}>>> = false
  []
  [side]
    type = SideSetsAroundSubdomainGenerator<<<{"description": "Adds element faces that are on the exterior of the given block to the sidesets specified", "href": "SideSetsAroundSubdomainGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = circle
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = side
    block<<<{"description": "The blocks around which to create sidesets"}>>> = 1
  []
  [extrude]
    type = AdvancedExtruderGenerator<<<{"description": "Extrudes a 1D mesh into 2D, or a 2D mesh into 3D, can have a variable height for each elevation, variable number of layers within each elevation, variable growth factors of axial element sizes within each elevation and remap subdomain_ids, boundary_ids and element extra integers within each elevation as well as interface boundaries between neighboring elevation layers.", "href": "AdvancedExtruderGenerator.html"}>>>
    input<<<{"description": "The mesh to extrude"}>>> = side
    heights<<<{"description": "The height of each elevation"}>>> = '2'
    num_layers<<<{"description": "The number of layers for each elevation - must be num_elevations in length!"}>>> = '3'
    direction<<<{"description": "A vector that points in the direction to extrude (note, this will be normalized internally - so don't worry about it here)"}>>> = '0 0 1'
  []
  [side_1]
    type = ParsedGenerateSideset<<<{"description": "A MeshGenerator that adds element sides to a sideset if the centroid of the side satisfies the `combinatorial_geometry` expression.", "href": "ParsedGenerateSideset.html"}>>>
    combinatorial_geometry<<<{"description": "Function expression encoding a combinatorial geometry"}>>> = 'x>=0&y>=0'
    new_sideset_name<<<{"description": "The name of the new sideset"}>>> = 'side_1'
    input<<<{"description": "The mesh we want to modify"}>>> = 'extrude'
    included_boundaries<<<{"description": "A set of boundary names or ids whose sides will be included in the new sidesets.  A side is only added if it also belongs to one of these boundaries."}>>> = 'side'
  []
  [bd_1]
    type = Boundary2DDelaunayGenerator<<<{"description": "Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into a 2D mesh using Delaunay triangulation.", "href": "Boundary2DDelaunayGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = side_1
    boundary_names<<<{"description": "The boundaries to be used"}>>> = 'side_1'
    use_auto_area_func<<<{"description": "Use the automatic area function for the triangle meshing region."}>>> = true
  []
  [side_2]
    type = ParsedGenerateSideset<<<{"description": "A MeshGenerator that adds element sides to a sideset if the centroid of the side satisfies the `combinatorial_geometry` expression.", "href": "ParsedGenerateSideset.html"}>>>
    combinatorial_geometry<<<{"description": "Function expression encoding a combinatorial geometry"}>>> = 'x<0&y>=0'
    new_sideset_name<<<{"description": "The name of the new sideset"}>>> = 'side_2'
    input<<<{"description": "The mesh we want to modify"}>>> = 'extrude'
    included_boundaries<<<{"description": "A set of boundary names or ids whose sides will be included in the new sidesets.  A side is only added if it also belongs to one of these boundaries."}>>> = 'side'
  []
  [bd_2]
    type = Boundary2DDelaunayGenerator<<<{"description": "Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into a 2D mesh using Delaunay triangulation.", "href": "Boundary2DDelaunayGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = side_2
    boundary_names<<<{"description": "The boundaries to be used"}>>> = 'side_2'
    use_auto_area_func<<<{"description": "Use the automatic area function for the triangle meshing region."}>>> = true
  []
  [side_3]
    type = ParsedGenerateSideset<<<{"description": "A MeshGenerator that adds element sides to a sideset if the centroid of the side satisfies the `combinatorial_geometry` expression.", "href": "ParsedGenerateSideset.html"}>>>
    combinatorial_geometry<<<{"description": "Function expression encoding a combinatorial geometry"}>>> = 'x<0&y<0'
    new_sideset_name<<<{"description": "The name of the new sideset"}>>> = 'side_3'
    input<<<{"description": "The mesh we want to modify"}>>> = 'extrude'
    included_boundaries<<<{"description": "A set of boundary names or ids whose sides will be included in the new sidesets.  A side is only added if it also belongs to one of these boundaries."}>>> = 'side'
  []
  [bd_3]
    type = Boundary2DDelaunayGenerator<<<{"description": "Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into a 2D mesh using Delaunay triangulation.", "href": "Boundary2DDelaunayGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = side_3
    boundary_names<<<{"description": "The boundaries to be used"}>>> = 'side_3'
    use_auto_area_func<<<{"description": "Use the automatic area function for the triangle meshing region."}>>> = true
  []
  [side_4]
    type = ParsedGenerateSideset<<<{"description": "A MeshGenerator that adds element sides to a sideset if the centroid of the side satisfies the `combinatorial_geometry` expression.", "href": "ParsedGenerateSideset.html"}>>>
    combinatorial_geometry<<<{"description": "Function expression encoding a combinatorial geometry"}>>> = 'x>=0&y<0'
    new_sideset_name<<<{"description": "The name of the new sideset"}>>> = 'side_4'
    input<<<{"description": "The mesh we want to modify"}>>> = 'extrude'
    included_boundaries<<<{"description": "A set of boundary names or ids whose sides will be included in the new sidesets.  A side is only added if it also belongs to one of these boundaries."}>>> = 'side'
  []
  [bd_4]
    type = Boundary2DDelaunayGenerator<<<{"description": "Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into a 2D mesh using Delaunay triangulation.", "href": "Boundary2DDelaunayGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = side_4
    boundary_names<<<{"description": "The boundaries to be used"}>>> = 'side_4'
    use_auto_area_func<<<{"description": "Use the automatic area function for the triangle meshing region."}>>> = true
  []
  [bd_bot]
    type = Boundary2DDelaunayGenerator<<<{"description": "Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into a 2D mesh using Delaunay triangulation.", "href": "Boundary2DDelaunayGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = extrude
    boundary_names<<<{"description": "The boundaries to be used"}>>> = '2'
    use_auto_area_func<<<{"description": "Use the automatic area function for the triangle meshing region."}>>> = true
  []
  [bd_top]
    type = Boundary2DDelaunayGenerator<<<{"description": "Mesh generator that convert a 2D surface given as one or a few boundaries of a 3D mesh into a 2D mesh using Delaunay triangulation.", "href": "Boundary2DDelaunayGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = extrude
    boundary_names<<<{"description": "The boundaries to be used"}>>> = '3'
    use_auto_area_func<<<{"description": "Use the automatic area function for the triangle meshing region."}>>> = true
  []
  [smg]
    type = StitchMeshGenerator<<<{"description": "Allows multiple mesh files to be stitched together to form a single mesh.", "href": "StitchMeshGenerator.html"}>>>
    inputs<<<{"description": "The input MeshGenerators."}>>> = 'bd_1 bd_2 bd_3 bd_4 bd_top bd_bot'
    clear_stitched_boundary_ids<<<{"description": "Whether or not to clear the stitched boundary IDs"}>>> = true
    stitch_boundaries_pairs<<<{"description": "Pairs of boundaries to be stitched together between the 1st mesh in inputs and each consecutive mesh"}>>> = '0 0;0 0;0 0;0 0;0 0'
    merge_boundaries_with_same_name<<<{"description": "If the input meshes have boundaries with the same name (but different IDs), merge them"}>>> = true
    prevent_boundary_ids_overlap<<<{"description": "Whether to re-number boundaries in stitched meshes to prevent merging of unrelated boundaries"}>>> = false
  []
  [xyzd]
    type = XYZDelaunayGenerator<<<{"description": "Creates tetrahedral 3D meshes within boundaries defined by input meshes.", "href": "XYZDelaunayGenerator.html"}>>>
    boundary<<<{"description": "The input MeshGenerator defining the output outer boundary. The input mesh (the output mesh of the input mesh generator) can either include 3D volume elements or 2D surface elements."}>>> = smg
    desired_volume<<<{"description": "Desired (maximum) tetrahedral volume, or 0 to skip uniform refinement"}>>> = 1
    output_subdomain_name<<<{"description": "Subdomain name to set on new triangles."}>>> = 'matrix'
  []
[]
(test/tests/meshgenerators/boundary_2d_delaunay_generator/cylinder.i)

Figure 2: The workflow of the Boundary2DDelaunayGenerator mesh generator.

Input Parameters

  • boundary_namesThe boundaries to be used

    C++ Type:std::vector<BoundaryName>

    Controllable:No

    Description:The boundaries to be used

  • inputThe mesh we want to modify

    C++ Type:MeshGeneratorName

    Controllable:No

    Description:The mesh we want to modify

Required Parameters

  • epsilon0Fuzzy comparison tolerance

    Default:0

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Fuzzy comparison tolerance

  • hole_boundary_namesThe optional boundaries to be used as the holes in the mesh during triangulation. Note that this is a vector of vectors, which allows each hole to be defined as a combination of multiple boundaries.

    C++ Type:std::vector<std::vector<BoundaryName>>

    Controllable:No

    Description:The optional boundaries to be used as the holes in the mesh during triangulation. Note that this is a vector of vectors, which allows each hole to be defined as a combination of multiple boundaries.

  • level_setLevel set used to achieve more accurate reverse projection compared to interpolation.

    C++ Type:std::string

    Controllable:No

    Description:Level set used to achieve more accurate reverse projection compared to interpolation.

  • max_angle_deviation60Maximum angle deviation from the global average normal vector in the input mesh.

    Default:60

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Maximum angle deviation from the global average normal vector in the input mesh.

  • max_level_set_correction_iterations3Maximum number of iterations to correct the nodes based on the level set function.

    Default:3

    C++ Type:unsigned int

    Controllable:No

    Description:Maximum number of iterations to correct the nodes based on the level set function.

  • output_external_boundary_nameThe optional name of the external boundary of the mesh to generate. If not provided, the external boundary will be have a trivial id of 0.

    C++ Type:BoundaryName

    Controllable:No

    Description:The optional name of the external boundary of the mesh to generate. If not provided, the external boundary will be have a trivial id of 0.

Optional Parameters

  • auto_area_func_default_size0Background size for automatic area function, or 0 to use non background size

    Default:0

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Background size for automatic area function, or 0 to use non background size

  • auto_area_func_default_size_dist-1Effective distance of background size for automatic area function, or negative to use non background size

    Default:-1

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Effective distance of background size for automatic area function, or negative to use non background size

  • auto_area_function_num_points10Maximum number of nearest points used for the inverse distance interpolation algorithm for automatic area function calculation.

    Default:10

    C++ Type:unsigned int

    Controllable:No

    Description:Maximum number of nearest points used for the inverse distance interpolation algorithm for automatic area function calculation.

  • auto_area_function_power1Polynomial power of the inverse distance interpolation algorithm for automatic area function calculation.

    Default:1

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Polynomial power of the inverse distance interpolation algorithm for automatic area function calculation.

  • use_auto_area_funcFalseUse the automatic area function for the triangle meshing region.

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Use the automatic area function for the triangle meshing region.

Automatic Triangle Meshing Area Control Parameters

  • disable_fpoptimizerFalseDisable the function parser algebraic optimizer

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Disable the function parser algebraic optimizer

  • enable_ad_cacheTrueEnable caching of function derivatives for faster startup time

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Enable caching of function derivatives for faster startup time

  • enable_auto_optimizeTrueEnable automatic immediate optimization of derivatives

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Enable automatic immediate optimization of derivatives

  • enable_jitTrueEnable just-in-time compilation of function expressions for faster evaluation

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Enable just-in-time compilation of function expressions for faster evaluation

  • evalerror_behaviornanWhat to do if evaluation error occurs. Options are to pass a nan, pass a nan with a warning, throw a error, or throw an exception

    Default:nan

    C++ Type:MooseEnum

    Options:nan, nan_warning, error, exception

    Controllable:No

    Description:What to do if evaluation error occurs. Options are to pass a nan, pass a nan with a warning, throw a error, or throw an exception

Parsed Expression Advanced Parameters

  • enableTrueSet the enabled status of the MooseObject.

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Set the enabled status of the MooseObject.

  • save_with_nameKeep the mesh from this mesh generator in memory with the name specified

    C++ Type:std::string

    Controllable:No

    Description:Keep the mesh from this mesh generator in memory with the name specified

Advanced Parameters

  • nemesisFalseWhether or not to output the mesh file in the nemesisformat (only if output = true)

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Whether or not to output the mesh file in the nemesisformat (only if output = true)

  • outputFalseWhether or not to output the mesh file after generating the mesh

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Whether or not to output the mesh file after generating the mesh

  • show_infoFalseWhether or not to show mesh info after generating the mesh (bounding box, element types, sidesets, nodesets, subdomains, etc)

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Whether or not to show mesh info after generating the mesh (bounding box, element types, sidesets, nodesets, subdomains, etc)

Debugging Parameters

Input Files