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.
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:
Specification of the element sizes in the mesh,
Coarse linear mesh generation of the domain,
Generation of optimised high-order surface on the geometric boundary,
and are outlined in more detail in the following sections.
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.
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
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.
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.
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.16.
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> 3 4 <INFORMATION> 5 <I PROPERTY="CADFile" VALUE="6412" /> 6 <I PROPERTY="MeshType" VALUE="2D" /> 7 </INFORMATION> 8 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" /> 14 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> 22 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> 3 4 <INFORMATION> 5 <I PROPERTY="CADFile" VALUE="6412" /> 6 <I PROPERTY="MeshType" VALUE="2DBndLayer" /> 7 </INFORMATION> 8 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" /> 14 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" /> 20 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> 28 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.
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>
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:
//
and /* */
(i.e. comments)
Point
Line
Spline
(through points)
BSpline
(i.e. a Bézier curve)
Ellipse
(arc): as defined in Gmsh’s OpenCASCADE kernel, the first point defines
the start of the arc, the second point the centre and the fourth point the end. The
third point is not used. The start point along with the centre point form the major
axis and the minor axis is then computed so that the end point falls onto the arc.
The major axis must always be greater or equal to the minor axis.
Circle
(arc): the circle is a special case of the ellipse where the third point is
skipped. The distances between the start and end points and the centre point must
be equal or an error will be thrown.
Line Loop
Plane Surface
Ruled Surface
or, in newer versions of Gmsh, Surface
Surface Loop
Volume
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.
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 :
Tetrahedron
Prism
Pyramid
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.7. 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.