4.6 Mesh generation

In addition to the functionality described previously, NekMesh is capable of generating high-order meshes directly from a CAD definition. By default this functionality is not activated, a user wishing to utilise the mesh generation capability of NekMesh must compile Nektar++ with the NEKTAR_USE_MESHGEN option on. As well as compiling the relevant routines into NekMesh it will also download a number of other packages which are required.

The most critical dependancy of the mesh generation routines is OpenCascade which powers the CAD engine. NekMesh is capable of finding and using existing installations of OpenCascade 6.8 or OCE 0.17. If either are not present on the installation machine NekMesh will install OCE 0.17 from source. This is a very big installation and will take some time so it is advised that the user ensures OpenCascade is availble on the machine.

As with all tasks within NekMesh the mesh generation capability exists as its own separate module which is of type Input. Due to the vast amount of code associated with the generation of high-order meshes and the comparatively small nature of modules in the NekMesh program a new library has been created for Nektar++ called NekMeshUtils, which contains all the core routines and classes for the NekMesh mesh format as well as a series of classes for the generation of meshes. This library also contains the CAD API for Nektar++ which is used to generate the meshes.

4.6.1 Methodology

This section outlines the approach taken by NekMesh to generate high-order meshes. To simplify the sometimes very complicated high-order mesh generation processes in other programs, NekMesh executes all the stages required to produce a high-order mesh in one single pipeline which once started requires no interaction from the user. In broad terms these stages are:

and are outlined in more detail in the following sections. CAD Interaction

At the core of all the ideas in the NekMesh generator is that the final mesh is a high quality representation of the underlying geometry. As such all of the entities in the mesh must know where they are located with respect to the CAD and the system to be able to query any geometric information at any point in the domain easily and with accuracy. To handle this NekMesh has been interfaced with the third-party suite of CAD libraries called OpenCascade. In its normal state OpenCascade is a very large collection of libraries with tens of thousands of functions which are simply not needed for our purposes, because of this its installation is a very arduous and long process. Combine this with the fact that there are dozens of versions and types of OpenCascade, such as OpenCascade Community Edition, it is simply impossible for NekMesh to use already existing OpenCascade installations on a given machine. To solve these issues, when installing Nektar++ with the mesh generator it will download pre-compiled binaries for the relevant OS and link against those, any previously installed versions of OpenCascade will not be searched for and therefore ignored. To reduce the massively complex libraries in OpenCascade down to a manageable set of functions to be used in NekMesh a set of interface classes have been created which act as buffer between it and Nektar++. These CAD classes mean that development of mesh generation routines is significantly easier and in the future Nektar++ developers will be able to utilise CAD information in all aspects of the framework without having to learn OpenCascade. Another advantage with this approach is that adding support for other CAD engines, as well as OpenCascade, in the future should be relativity simple and will not require the rewriting of any of the NekMesh code. Automatic specification of the mesh

One of the key challenges of generating a high-order mesh is the creation of a suitable coarse linear mesh. It is quite difficult for a user to define a full set spacings over a whole domain which will produce a good quality especially when aiming for coarseness. This is tackled in NekMesh with a system for automatically defining a set of smooth and coarse mesh spacings throughout the whole domain. This is achieved using an octree description of the domain. The domain is recursively subdivided into octants which each describe a small portion of the domain. The level to which the domain subdivides is based on the curvature of the geometric boundary. Higher curvature regions will subdivide to a finer level allowing for increased control on the mesh specification and smoothness. The geometric curvature is then related to a mesh sizing parameter and propagated throughout the domain ensuring a smooth mesh. For those unfamiliar with octrees, it is best to think of it as a non-conforming hexahedral mesh Linear Mesh Generation

The first challenge mentioned in the previous section is addressed with the NekMesh approach to linear mesh generation. Primarily because of the difficulties in interfacing existing linear mesh generators for high-order applications the decision was made to include a bespoke linear mesh generator within the program. Compared with the mesh generators included in commercial packages this linear mesh generator takes the quite unconventional and more historic approach in building the mesh in a bottom up fashion from 0D to 3D. Using this approach means it is possible to guarantee a level of boundary conformity which direct to 3D approaches cannot at the desired level of coarseness. In this approach, first mesh nodes are placed on the vertices of the CAD model (0D), then the curves in the CAD are meshed in 1D using the vertex nodes as boundaries, then the surfaces are meshed in their 2D parameter plane using the curve meshes as boundaries and finally the 3D volume is meshed using the surface mesh as the boundary to complete the linear mesh. In NekMesh, to achieve greater robustness, the 2D mesh generation library Triangle is used and the TetGen library for the 3D. Both of which are highly developed Delaunay based mesh generators. As with all additional libraies in Nektar++ these are automatically downloaded and installed if needed. High-order Surface Generation

Addition of the high-order nodes to and the curving of the mesh is very open problem, no high-order mesh generator has solved this and while the methods used in NekMesh are not 100% full-proof, the system currently in place can create good quality high-order curved meshes with a reasonable robustness. This area will receive the greatest level of development in the future. The most critical part of defining the high-order mesh is the addition of high-order nodes on the geometric surface. The mesh generator must achieve the greatest level of geometric accuracy as it can otherwise it will greatly affect the final flow solutions. If the linear surface triangulation is taken to be fixed during this process, the problem can be addressed in a element by element fashion. If the high-order nodes are placed by simply using an affine mapping to the CAD surface and back the resulting high-order triangle will inherit the same distortions as the CAD surface. To solve this NekMesh uses a system node location optimisation in the parameter plane of the CAD surface to ensure the high-order triangles have as little distortion as possible while remaining exactly on the geometric surface. To do this the system models the high-order edges and triangles as a network of springs with an associated spring energy which is minimised using a multidimensional Newton type optimisation procedure with a Gauss-Seidel matrix solver. Mesh Correction

Due to the fact that, for the time being, no consideration is given to the curving of mesh interior entities explicitly in the mesh generation process, the curving the geometric surface can produce meshes with invalid elements, especially in the case of Euler type (Tetrahedra only) meshes. Three strategies exist within Nektar++ to correct these elements. Firstly removing the curvature, by removing the curvature of invalid elements they become valid. However this has the massive downside of compromising the geometric accuracy of the mesh but is quick and effective, this can be enacted using the command:

NekMesh -m linearise:invalid invalidMesh.xml validMesh.xml

An alternative to this is to use the linear elastic solver within Nektar++ to deform the mesh interior entities. Its use is very computationally expensive, as with all PDE solvers, and is also not particularly robust. It can be used with the set of commands outlined in the FieldConvert deform and displacement modules and the section on the Linear Elastic Solver.

The final and possibly most useful approach is to use the Variational Optimsation module to curve the interior of the domain. This is explained in 4.5.15.

4.6.2 Mesh generation manual

The mesh generation is executed with the command:

NekMesh session.mcf mesh.xml

where session.mcf is a mesh configuration file which contains all the options and parameters needed for mesh generation. Below is an example of a simple example which generates a 2D NACA wing.

1    <NEKTAR> 
2        <MESHING> 
4            <INFORMATION> 
5                <I PROPERTY="CADFile"   VALUE="6412"  /> 
6                <I PROPERTY="MeshType"  VALUE="2D"    /> 
7            </INFORMATION> 
9            <PARAMETERS> 
10                <P PARAM="MinDelta"     VALUE="0.01"  /> 
11                <P PARAM="MaxDelta"     VALUE="1.0"   /> 
12                <P PARAM="EPS"          VALUE="0.1"   /> 
13                <P PARAM="Order"        VALUE="4"     /> 
15                <!-- 2D Domain !--> 
16                <P PARAM="Xmin"         VALUE="-1.0"  /> 
17                <P PARAM="Ymin"         VALUE="-2.0"  /> 
18                <P PARAM="Xmax"         VALUE="3.0"   /> 
19                <P PARAM="Ymax"         VALUE="2.0"   /> 
20                <P PARAM="AOA"          VALUE="15.0"  /> 
21            </PARAMETERS> 
23        </MESHING> 
24    </NEKTAR>

In all cases the mesh generator needs two pieces of information and four parameters. It firstly needs to know the CAD file with which to work. In the example above this is listed as a 4 digit number, this is because the mesh generator is equiped with a NACA wing generator. In all other cases this parameter would be the name of a CAD file (in either STEP or GEO format). Secondly, what type of mesh to make, the options are EULER and BndLayer for 3D meshes and 2D and 2DBndLayer for 2D meshes. In the case of EULER the mesh will be made with only tetrahedra. For BndLayer the mesh generator will attempt to insert a single macro prism layer onto the geometry surface. This option requires additional parameters. This is similar for the 2D scenarios. The automatic mesh specification system requires three parameters to build the specification of a smooth, curvature refined mesh. Firstly MinDelta which is the size of the smallest element to be found in the final mesh. Secondly MaxDelta which is the maximum size of an element in the mesh and lastly EPS which is a sensitivity to curvature parameter with a range 1 ≥ ε > 0 which heuristically controls the size of the elements for a given degree of curvature on the geometric surface. Order is the polynomial order of the mesh to be generated. When generating a boundary layer mesh a few additional parameters must be given. An example is shown.

1    <NEKTAR> 
2        <MESHING> 
4            <INFORMATION> 
5                <I PROPERTY="CADFile"           VALUE="6412"        /> 
6                <I PROPERTY="MeshType"          VALUE="2DBndLayer"  /> 
7            </INFORMATION> 
9            <PARAMETERS> 
10                <P PARAM="MinDelta"             VALUE="0.01"        /> 
11                <P PARAM="MaxDelta"             VALUE="1.0"         /> 
12                <P PARAM="EPS"                  VALUE="0.1"         /> 
13                <P PARAM="Order"                VALUE="4"           /> 
15                <!-- Boundary layer !--> 
16                <P PARAM="BndLayerSurfaces"     VALUE="5,6"         /> 
17                <P PARAM="BndLayerThickness"    VALUE="0.03"        /> 
18                <P PARAM="BndLayerLayers"       VALUE="4"           /> 
19                <P PARAM="BndLayerProgression"  VALUE="2.0"         /> 
21                <!-- 2D Domain !--> 
22                <P PARAM="Xmin"                 VALUE="-1.0"        /> 
23                <P PARAM="Ymin"                 VALUE="-2.0"        /> 
24                <P PARAM="Xmax"                 VALUE="3.0"         /> 
25                <P PARAM="Ymax"                 VALUE="2.0"         /> 
26                <P PARAM="AOA"                  VALUE="15.0"        /> 
27            </PARAMETERS> 
29        </MESHING> 
30    </NEKTAR>

A list of the CAD surfaces which will have a prism generated on is described by BndLayerSurfaces and the thickness of the boundary to aim for is BndLayerThickness. The mesh generator has been created with a range of error messages to aid in debugging. If you encounter an error and the mesh generator fails, run NekMesh with the verbose -v flag and send the stdout with the .mcf and .step files to d.moxey@exeter.ac.uk. Without the feedback this functionality cannot improve. Handling 3D geometries with voids

Although NekMesh supports the definition of 3D geometries that contain voids – for example, a sphere contained within a cube – at present it does require the definition of a point per-void that lies strictly on the interior of the void. This is so that tetrahedra on the interior of the void can be removed before the mesh is generated. For example, if one defines a geometry where two spheres of radius 1, centred at (0,0,0) and (2,0,0), were contained within a larger domain, the void points can be specified through the VOIDPOINTS tag in the MCF as follows:

1    <NEKTAR> 
2        <MESHING> 
3            <!-- other parameters here... --> 
4            <VOIDPOINTS> 
5                <V> 0 0 0 </V> 
6                <V> 2 0 0 </V> 
7            </VOIDPOINTS> 
8       </MESHING> 
9    </NEKTAR> GEO format

Recent developments have been made to facilitate the generation of meshes from simple 2D and 3D geometries. The GEO file format, used by Gmsh, is a popular option that allows the user to script geometrical and meshing operations without the need of a GUI. A simplified reader has been implemented in NekMesh for 2D and 3D geometries. Although very basic this reader may be extended in the future to cover a wider range of geometrical features.

For a full description of the GEO format the user should refer to Gmsh’s documentation. The following commands are currently supported:

At the present time, NekMesh does not support the full scripting capabilities of the GEO format, but the evaluation of simple variables is supported. The used GEO files should be a straightforward succession of entity creations (see list above). This should however allow for the creation of quite a wide range of 2D and 3D geometries by transformation of arbitrary curves into generic splines and arcs. CCM format

For very complex 3D geometries with manifold bodies, Nektar++ can take advantage of the meshing tool embedded in the Star-CCM package. NekMesh projects linear meshes generated in Star-CCM on the CAD definition to generate high-order meshes. Nektar++ must be built NEKTAR_USE_CCM in conjunction with the ccmio package to use this functionality. Projection is performed by specifying the option projectcad.

The supported element types for the linear mesh are :

Therefore it is recommended to use the Surface Remesher, the Tetrahedral Mesher and the Prism Layer Mesher in Star-CCM. The CAD Projection and Generate Only Standard Prismatic Cells options should be activated. The prismatic layer for the linear mesh in Star-CCM should not be splitted e.g. there should be only one layer with the total thickness of the boundary layer (see figure 4.6. Splitting will then be perfomed directly by NekMesh on surfaces specified by the argument surf and the number of layers (layers argument) and growth rate (r argument) are specified during the mesh conversion process with the bl option. Surfaces correspond to the regions created in Star-CCM and the reference index is displayed when running NekMesh with verbosity (-v option).

NekMesh -m projectcad:file=cadFile.STEP:order=meshOrder -m bl:surf=surf1,surf2,surf3:r=growthRate:layers=nLayers linearMesh.ccm outputMesh.xml

The command linearise can be added to correct bad elements.


Figure 4.6: Linear mesh generated in Star-CCM (visualised with ParaView) showing the one-layer prismatic cells layer