In this document we demonstrate how to generate unstructured tetrahedral meshes for oomph-lib, based on the output from Hang Si's open-source mesh generator Tetgen . The mesh generation is performed in a two-stage process. First we use Tetgen to generate the mesh "offline". Then we process the output files generated by Tetgen to generate an oomph-lib mesh.
The Tetgen home page contains a comprehensive User's Guide for the code and its many options, therefore we only present a brief overview of the code's most basic usage.
Tetgen creates the mesh based on the information about the mesh boundaries provided in an input file, filename.poly, say. By default, three output files, filename.1.node, filename.1.ele, and filename.1.face are created. They contain the information about the nodal positions, the element connectivity lists and the boundary faces respectively.
The input file for Tetgen usually has the extension *.poly and has the following format:
|
Node list First line: [number of nodes] [dimension (must be 3)] [number of attributes] [number of boundary markers (0 or 1)] One line: [number of facets] [boundary markers (0 or 1)] One line: [number of holes] Region attributes list One line: [number of region] |
Comments:
b+1 should be used to indicate that a node is located on the mesh boundary b in the final oomph-lib mesh.oomph-lib does not use the "attributes" so their number should be set to zero.See the Tetgen home page for further information.
To create the mesh from a given input file the command is
With these commands, Tetgen will generate as few tetrahedra as possible. Finer meshes may be generated by imposing additional constraints via command line arguments. For instance
-an where n is the maximal volume wanted. (There is no space between -a and the number specifying the volume!)Again, we refer to the Tetgen home page for a comprehensive listing of all available options.
To visualise the mesh, the program tetview (distributed with Tetgen ) can be used.
To illustrate the procedure, we demonstrate how to generate a mesh for the cube domain with a hole shown in the figure below. Note that the node numbers correspond to those in the Tetgen input file. Boundary 1 is shown in blue; boundary 2 in magenta. In the corresponding oomph-lib mesh, the boundaries are numbered from zero.
Here is a listing of the corresponding input file, cube_hole.poly:
The output files that Tetgen creates with the command
are cube_hole.1.node , cube_hole.1.ele and cube_hole.1.face.
Here is a sketch of the resulting discretisation, as displayed by tetview :
oomph-lib provides a mesh, TetgenMesh, that uses the output from Tetgen to generate an unstructured oomph-lib Mesh containing elements from the TElement<3,NNODE_1D> family of the tetrahedral elements. The relevant interface is:
The driver code mesh_from_tetgen_poisson.cc demonstrates the use of this mesh for the solution of a 3D Poisson problem in the "cube domain with a hole", described in the previous section.
The code expects the names of *.node, *.ele and *.face files generated by Tetgen as command line arguments and stores them in the namespace CommandLineArgs
The names of these files are then passed to the mesh constructor. Since the rest of the driver code is identical to that in the corresponding example with a structured mesh, we do not provide a detailed listing but simply show the plot of the computed results, together with a plot of the exact solution, for linear (four-noded) elements
The driver code mesh_from_tetgen_navier_stokes.cc demonstrates the use of a TetgenMesh for the solution of a 3D Navier-Stokes problem in the same geometry as in the previous example. We apply no-slip boundary conditions on the central hole and impose a unit vertical velocity. On the outer boundaries we pin the
and
velocity components and set them to zero, while leaving the axial velocity unspecified. The resulting flow field, shown in the figure below, corresponds to the flow that is generated when the rigid block in the centre of the domain rises vertically inside a rigid duct with "slippery walls". The duct is open at the ends
, where parallel, axially-traction free outflow is imposed. The various slices show pressure contours and the in-plane velocity vectors.
We re-iterate that Tetgen does not allow nodes to be located on multiple boundaries. It is therefore important to check the boundary numbers allocated by Tetgen , e.g. by using the function Mesh::output_boundaries(...). Boundary nodes should always be placed on the boundary with the most restrictive boundary conditions. If this is not possible, some post-processing of the mesh may be required.
Currently, TetgenMesh can only be used to generate four and ten-node tets (i.e. tets with tri-linear and tri-quadratic shape functions). It should be easy to generalise the "scaffold-mesh"-based mesh generation procedure to higher-order elements but this has not been done yet. Any volunteers?
Tetgen, , and create your own meshes.A pdf version of this document is available.