In this document we demonstrate how to generate unstructured triangular meshes for
oomph-lib, based on the output from Jonathan Shewchuk's open-source mesh generator
Triangle. The mesh generation is performed in a two-stage process. First we use
Triangle to generate the mesh "offline". Then we process the output files generated by
Triangle to generate an
You should also consult another tutorial where we discuss how to generate (and adapt) unstructured meshes from within
oomph-lib driver codes.
Triangle 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.
Triangle 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.ele are created. They contain the information about the polygonal mesh boundaries, the nodal positions and the element connectivity lists, respectively.
The input file for
Triangle (usually a file with the extension
poly) has the following format:
First line: [number of vertices] [dimension (must be 2)] [number of attributes for nodes] [number of boundary markers for nodes (0 or 1)]
One line: [number of segments] [number of boundary markers for segments (0 or 1)]
One line: [number of holes]
Trianglemay triangulate regions that are not part of the domain.
oomph-libdriver codes tend to require this information to apply boundary conditions), the number of boundary markers should be set to 1, otherwise it must be set to zero.
oomph-lib's(zero-based) boundary numbering schemes, a boundary marker 0 should be used for nodes that are not located on domain boundaries; a boundary marker
b+1should be used to indicate that a node is located on the mesh boundary
bin the final
oomph-libdoes not currently use the "attributes" so their number should be set to zero. [Note: The attributes are likely to be used to define boundary coordinates in future releases of
Triangleassigns the boundary marker for the node arbitrarily.
Trianglemay contain optional additional lines which specify, e.g. area constraints. See the
Trianglehome page for further information.
To create the mesh from a given input file the command is
If the domain contains a hole the argument
-pc must be added, i.e.
With these commands,
Triangle will generate as few triangles as possible. Finer meshes may be generated by imposing additional constraints via command line arguments. For instance:
-an where n is the maximum permitted area. (There is no space between
-aand the number specifying the area!)
-qto avoid angles smaller than 20 degree or
-qn where n is the minimum permitted angle.
Again, we refer to the
Triangle home page for a comprehensive listing of all available options.
When run with an input file
Triangle generates output files called
filename.1.node which can be processed to generate an
To visualise the mesh, the program
showme (distributed with
Triangle ) can be used.
To illustrate the procedure, we demonstrate how to generate a mesh for the rectangular domain with a hole shown in the figure below. The domain is defined by two boundary segments, each of which connect four points. Note that the node and boundary numbers correspond to those in the
Triangle input file. In the corresponding
oomph-lib mesh, the boundaries are numbered from zero.
The input file,
box_hole.poly, for this domain is:
When run as
./triangle -pc -a0.1 -q35 box_hole.poly
Triangle creates the output files
box_hole.1.ele and box_hole.1.poly. Here is a sketch of the resulting triangulation, as displayed by
oomph-lib provides a mesh,
TriangleMesh, that uses the output from
Triangle to generate an
oomph-lib Mesh containing elements from the
TElement<2,NNODE_1D> family of the triangular elements. The relevant interface is:
The driver code mesh_from_triangle_poisson.cc demonstrates the use of this mesh for the solution of a 2D Poisson problem in the "rectangular domain with a hole", described in the previous section.
The code expects the names of
ele and *.
poly files generated by
Triangle as command line arguments and stores them in the namespace
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 the tanh-shaped exact solution of the problem:
The driver code mesh_from_triangle_navier_stokes.cc demonstrates the use of a
TriangleMesh for the solution of a 2D Navier-Stokes problem. The file
flow_past_box.poly describes a slightly longer box-shaped domain with a hole – representing a 2D channel with an obstruction. In this example the four straight line segments that bound the outer box are given distinct boundary numbers to allow the application of different boundary conditions at the inflow, the outflow, and on the upper and lower no-slip walls.
Here is the mesh, generated by
...and here is a plot of the flow field (velocity vectors, streamlines and pressure contours) computed with 2D triangular Taylor-Hood elements:
We re-iterate that
Triangle does not allow nodes to be located on multiple boundaries. It is therefore important to check the boundary numbers allocated by
Triangle , 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.
TriangleMesh can be used to generate three, six and ten-node triangles (i.e. triangles with bi-linear, bi-quadratic and bi-cubic shape functions). The generation of ten-node triangles is currently performed somewhat inefficiently and a warning is issued. Developing a more efficient implementation should be straightforward and you are invited to perform this as an exercise.
Triangle, and create your own meshes.
A pdf version of this document is available.