# Mesh Formats

## MFEM mesh v1.0

This is the default format in GLVis. It can be used to describe simple (triangular, quadrilateral, tetrahedral and hexahedral meshes with straight edges) or complicated (curvilinear and more general) meshes.

### Straight meshes

In the simple case of a mesh with straight edges the format looks as follows

```
MFEM mesh v1.0
# Space dimension: 2 or 3
dimension
<dimension>
# Mesh elements, e.g. tetrahedrons (4)
elements
<number of elements>
<element attribute> <geometry type> <vertex index 1> ... <vertex index m>
...
# Mesh faces/edges on the boundary, e.g. triangles (2)
boundary
<number of boundary elements>
<boundary element attribute> <geometry type> <vertex index 1> ... <vertex index m>
...
# Vertex coordinates
vertices
<number of vertices>
<vdim>
<coordinate 1> ... <coordinate <vdim>>
...
```

Lines starting with "#" denote comments. The supported geometry types are:

- POINT = 0
- SEGMENT = 1
- TRIANGLE = 2
- SQUARE = 3
- TETRAHEDRON = 4
- CUBE = 5

see the comments in this source file for more details.

For example, the beam-quad.mesh file from the data directory looks like this:

```
MFEM mesh v1.0
dimension
2
elements
8
1 3 0 1 10 9
1 3 1 2 11 10
1 3 2 3 12 11
1 3 3 4 13 12
2 3 4 5 14 13
2 3 5 6 15 14
2 3 6 7 16 15
2 3 7 8 17 16
boundary
18
3 1 1 0
3 1 2 1
3 1 3 2
3 1 4 3
3 1 5 4
3 1 6 5
3 1 7 6
3 1 8 7
3 1 9 10
3 1 10 11
3 1 11 12
3 1 12 13
3 1 13 14
3 1 14 15
3 1 15 16
3 1 16 17
1 1 0 9
2 1 17 8
vertices
18
2
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
```

which corresponds to the mesh

visualized with

```
glvis -m beam-quad.mesh -k "Ame****"
```

### Curvilinear and more general meshes

The MFEM mesh v1.0 format also support the general description of meshes based on a vector finite element grid function with degrees of freedom in the "nodes" of the mesh. This general format is described briefly below, and in more details on the General Mesh Format page.

```
MFEM mesh v1.0
# Space dimension: 2 or 3
dimension
<dimension>
# Mesh elements, e.g. tetrahedrons (4)
elements
<number of elements>
<element attribute> <geometry type> <vertex index 1> ... <vertex index m>
...
# Mesh faces/edges on the boundary, e.g. triangles (2)
boundary
<number of boundary elements>
<boundary element attribute> <geometry type> <vertex index 1> ... <vertex index m>
...
# Number of vertices (no coordinates)
vertices
<number of vertices>
# Mesh nodes as degrees of freedom of a finite element grid function
nodes
FiniteElementSpace
FiniteElementCollection: <finite element collection>
VDim: <dimension>
Ordering: 0
<x-coordinate degrees of freedom>
...
<y-coordinate degrees of freedom>
...
<z-coordinate degrees of freedom>
...
```

Some possible finite element collection choices are: `Linear`

, `Quadratic`

and `Cubic`

corresponding to curvilinear P1/Q1, P2/Q2 and P3/Q3 meshes. The algorithm for the numbering of the degrees of freedom can be found in MFEM's source code.

For example, the escher-p3.mesh from MFEM's data directory describes a tetrahedral mesh with nodes given by a P3 vector Lagrangian finite element function. Visualizing this mesh with

```
glvis -m escher-p3.mesh -k "Aaaoooooooooo**************tt"
```

we get:

Topologically periodic meshes can also be described in this format, see for example the periodic-segment, periodic-square, and periodic-cube meshes in the data directory, as well as Example 9.

## MFEM mesh v1.1

This format adds support for non-conforming (AMR) meshes. The sections
`dimension`

, `elements`

, and `boundary`

are the same as in MFEM mesh v1.0 and
are followed by two new (optional) sections, `vertex_parents`

and
`coarse_elements`

:

```
# Vertex hierarchy
vertex_parents
<number of relations>
<vertex index> <parent 1 index> <parent 2 index>
...
# Element hierarchy
coarse_elements
<number of coarse elements>
<refinement type> <child index 1> ... <child index n>
...
```

These are followed by the standard sections `vertices`

and `nodes`

of the format
MFEM mesh v1.0.

The new section `vertex_parents`

identifies all vertices (by their zero-based
index) that have been created as new mid-edge vertices by adaptive refinement
of elements. Each such vertex has exactly two "parents" identified again by two
zero-based indices. This information is needed to construct constraining
relations in a mesh with hanging nodes. The order the vertex-parent relations
are stated in the file is not significant.

The second optional section `coarse_elements`

describes the element refinement
hierarchy. While the standard section `elements`

lists all leaf elements of the
refinement tree, this section describes all elements that have been refined and
are no longer active. Each line describes one such virtual element, its
refinement type and up to 8 children. Child indices between 0 and *N-1* refer
to the *N* active elements in the `elements`

section. A coarse element has an
implied index starting with *N*. A coarse element can refer to another coarse
element of *index >= N*, but only after such child has been defined in the
`coarse_elements`

section. The hierarchy is thus represented from the bottom
up. The refinement types are: 1=X, 2=Y, 4=Z, 3=XY, 5=XZ, 6=YZ, 7=XYZ, where X,
Y, Z refer to one or more splits in the respective axes of the element
reference domain. If the entire section is missing, MFEM will not be able to
derefine the mesh.

The files
amr-quad.mesh,
amr-hex.mesh and
fichera-amr.mesh
(above) in the `data`

directory are examples of AMR meshes.

## NURBS meshes

MFEM provides full support for meshes and discretization spaces based on Non-uniform Rational B-Splines (NURBS). These are treated similarly to general curvilinear meshes where the NURBS nodes are specified as a grid function at the end of the mesh file.

For example, here is a simple quadratic NURBS mesh for a square domain with a (perfectly) circular hole in the middle. (The exact representation of conical sections is a major advantage of the NURBS approach over high-order finite elements.)

```
MFEM NURBS mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# SEGMENT = 1
# SQUARE = 3
# CUBE = 5
#
dimension
2
elements
4
1 3 0 1 5 4
1 3 1 2 6 5
1 3 2 3 7 6
1 3 3 0 4 7
boundary
8
1 1 0 1
1 1 1 2
1 1 2 3
1 1 3 0
1 1 5 4
1 1 6 5
1 1 7 6
1 1 4 7
edges
12
0 0 1
0 4 5
1 1 2
1 5 6
2 2 3
2 6 7
3 3 0
3 7 4
4 0 4
4 1 5
4 2 6
4 3 7
vertices
8
knotvectors
5
2 3 0 0 0 1 1 1
2 3 0 0 0 1 1 1
2 3 0 0 0 1 1 1
2 3 0 0 0 1 1 1
2 3 0 0 0 1 1 1
weights
1
1
1
1
1
1
1
1
1
0.707106781
1
0.707106781
1
0.707106781
1
0.707106781
1
1
1
1
0.853553391
0.853553391
0.853553391
0.853553391
FiniteElementSpace
FiniteElementCollection: NURBS2
VDim: 2
Ordering: 1
0 0
1 0
1 1
0 1
0.358578644 0.358578644
0.641421356 0.358578644
0.641421356 0.641421356
0.358578644 0.641421356
0.5 0
0.5 0.217157288
1 0.5
0.782842712 0.5
0.5 1
0.5 0.782842712
0 0.5
0.217157288 0.5
0.15 0.15
0.85 0.15
0.85 0.85
0.15 0.85
0.5 0.108578644
0.891421356 0.5
0.5 0.891421356
0.108578644 0.5
```

This above file, as well as other examples of NURBS meshes, can be found in MFEM's data directory. It can be visualized directly with

```
glvis -m square-disc-nurbs.mesh
```

which after several refinements with the "`i`

" key looks like

To explain MFEM's NURBS mesh file format, we first note that the topological part of the mesh (the `elements`

and `boundary`

sections) describe the 4 NURBS patches visible above. We use the vertex numbers as labels, so we only need the number of vertices.

In the NURBS case we need to also provide description of the edges on the patch boundaries and associate a knot vector with each of them. This is done in the `edges`

section where the first index in each row refers to the knot vector id (from the following `knotvectors`

section), while the remaining two indexes are the edge vertex numbers.

The position of the NURBS nodes (control points) is given as a NURBS grid function at the end of the file, while the associated weights are listed in the preceding `weights`

section.

Some examples of VTK meshes can be found in MFEM's data directory. Here is one of the 3D NURBS meshes

The image above was produced with some refinement (key "`o`

") and mouse manipulations from

```
glvis -m pipe-nurbs.mesh
```

Solutions from NURBS discretization spaces are also natively supported. For example here is the approximation for the solution of a simple Poisson problem on a refined version of the above mesh.

```
glvis -m square-disc-nurbs.mesh -g sol.gf
```

## Curvilinear VTK meshes

MFEM also supports quadratic triangular, quadrilaterals, tetrahedral and hexahedral curvilinear meshes in VTK format. This format is described in the VTK file format documentation. The local numbering of degrees of freedom for the biquadratic quads and triquadratic hexes can be found in the Doxygen reference of the vtkBiQuadraticQuad and vtkTriQuadraticHexahedron classes. Currently VTK does not support cubic, and higher-order meshes.

As an example, consider a simple curved quadrilateral saved in a file `quad.vtk`

:

```
# vtk DataFile Version 3.0
Generated by MFEM
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 9 double
0 0 0
1 0 0
1 1 0
0.1 0.9 0
0.5 -0.05 0
0.9 0.5 0
0.5 1 0
0 0.5 0
0.45 0.55 0
CELLS 1 10
9 0 1 2 3 4 5 6 7 8
CELL_TYPES 1
28
CELL_DATA 1
SCALARS material int
LOOKUP_TABLE default
1
```

Visualizing it with "`glvis -m quad.vtk`

" and typing "`Aemiii`

" in the GLVis window we get:

The "`i`

" key increases the reference element subdivision which gives an increasingly better approximation of the actual curvature of the element. To view the curvature of the mapping inside the element we can use the "I" key, e.g.,

```
glvis -m quad.vtk -k "AemIIiii"
```

Here is a slightly more complicated quadratic quadrilateral mesh example (the different colors in the GLVis window are used to distinguish neighboring elements):

```
glvis -m star-q2.vtk -k "Am"
```

MFEM and GLVis can also handle quadratic triangular meshes:

```
glvis -m square-disc-p2.vtk -k "Am"
```

As well as quadratic tetrahedral and quadratic hexahedral VTK meshes:

```
glvis -m escher-p2.vtk -k "Aaaooooo**************"
```

```
glvis -m fichera-q2.vtk -k "Aaaooooo******"
```