MIXD Format
MIXD flow field data, used by XNS and other programs, typically consists of separate files mien, mxyz and data. A boundary information file mrng is often required as well. These files are binary, with no Fortran control blocks included, and big-endian. Floating point files use standard IEEE 64-bit representation, while integer files use 4-byte integers. We will use these mesh parameters:
ne | number of elements |
nn | number of nodes |
nen | number of element nodes |
nef | number of element faces |
nsd | number of space dimensions |
ndf | number of degrees of freedom per node |
Not really part of the format, but a traditional name for a text file that lists the number of nodes and elements, each preceded by a keyword that is understood by XNS, Visual3, etc. An example:
ne 6000 nn 14322
This file is typically included (source minf) in the appropriate input file, e.g., xns.in or visual3.in.
This file contains the finite element connectivity array. There are nen entries for each element containing the global node number, from 1 to nn, of the element nodes. In the example shown, this file contains the following entries:
| element | node | node | node |
| 1 | 1 | 2 | 6 |
| 2 | 2 | 7 | 6 |
| 3 | 2 | 3 | 7 |
| 4 | 3 | 8 | 7 |
| 5 | 3 | 4 | 8 |
| 6 | 4 | 9 | 8 |
| 7 | 8 | 9 | 14 |
| 8 | 8 | 14 | 13 |
| 9 | 8 | 13 | 12 |
| 10 | 7 | 8 | 12 |
| 11 | 7 | 12 | 11 |
| 12 | 6 | 7 | 11 |
| 13 | 6 | 11 | 10 |
| 14 | 5 | 6 | 10 |
| 15 | 1 | 6 | 5 |
Note that the connectivity data implies a local ordering of element nodes, from 1 to nen. This numbering is not particularily important, except for the requirement that it be consistent. For a 2D mesh, all elements should adopt either clockwise or counter-clockwise local node ordering. For a 3D mesh, a consistent ordering is again necessary in order to avoid negative volume elements.
The file is integer binary, 4 bytes per integer, with no control blocks (also known as C-style binary). A typical way to read it in Fortran would be:
integer ien(nen,ne)
...
open (unit=1, file="mien", access="direct", recl=nen∗ne∗4)
read (unit=1, rec=1) ien
close (unit=1)
or using the EWD library:
call ewdreadint(ien, nen∗ne, "mien", 0, .false., .false.)
On Mac OS X, content of a connectivity file can be viewed using the octal dump command:
od -D mien | less
The command exists on most UNIX systems, but the specific option to interpret bytes as 32-bit integers may be different.
On little-endian Intel machines, the bytes need to be swapped first, e.g. using inline Perl code:
cat mien | perl -e ’while (sysread(STDIN,$d,4)){print pack("N",unpack("V",$d));}’ > mien.little
This file contains the nodal coordinates. There are nsd entries for each node containing the coordinates of that node. In the example shown, this file contains the following entries:
| node | x coordinate | y coordinate |
| 1 | 0.00 | 0.00 |
| 2 | 0.80 | 0.00 |
| 3 | 1.60 | 0.00 |
| 4 | 2.40 | 0.00 |
| 5 | 0.00 | 0.60 |
| 6 | 0.50 | 0.70 |
| 7 | 1.15 | 0.70 |
| 8 | 1.85 | 0.75 |
| 9 | 2.40 | 0.80 |
| 10 | 0.00 | 1.40 |
| 11 | 0.60 | 1.20 |
| 12 | 1.25 | 1.20 |
| 13 | 1.80 | 1.60 |
| 14 | 2.40 | 1.75 |
The file is double-precision binary, 8 bytes per float, with no control blocks (also known as C-style binary). A typical way to read it in Fortran would be:
real∗ 8 x(nsd,nn)
...
open (unit=1, file="mxyz", access="direct", recl=nsd∗nn∗8)
read (unit=1, rec=1) x
close (unit=1)
or using the EWD library:
call ewdreadfloat(x, nsd∗nn, "mxyz", 0, .false., .false.)
On Mac OS X, content of a coordinate file can be viewed using the octal dump command:
od -F mxyz | less
or, better still, using hexadecimal dump, with number of fields per column adjusted depending on the dimensionality of the domain:
hexdump -e ’"%E %E %E\n"’ mxyz | less
These commands exists on most UNIX systems, but the specific option to interpret bytes as 64-bit floating-point numbers may be different.
On little-endian Intel machines, the bytes need to be swapped first, e.g. using inline Perl code:
cat mxyz | perl -e ’while (sysread(STDIN,$d,8)){print pack("N",unpack("V",$d));}’ > mxyz.little
This file contains the nodal flow field data. There are ndf entries for each node containing the flow field variables of that node. The format is identical to the mxyz file.
Content of a data file can be viewed the same way as the coordinate file.
This file contains the Reference Node Group (RNG), or boundary, information. There are nef entries for each element containing the boundary code of that face. The boundary codes are either positive, for faces where RNG, or boundary code, is assigned, or zero, for faces with no boundary code assigned. For internal faces, zero value is sometimes replaced with a negative number of the neighboring element (dual connectivity). In the example shown, this file contains the following entries:
| element | face code | face code | face code |
| 1 | 1 | -2 | -15 |
| 2 | -3 | -12 | -1 |
| 3 | 1 | -4 | -2 |
| 4 | -5 | -10 | -3 |
| 5 | 1 | -6 | -4 |
| 6 | 2 | -7 | -5 |
| 7 | -6 | 2 | -8 |
| 8 | -7 | 3 | -9 |
| 9 | -8 | 3 | -10 |
| 10 | -4 | -9 | -11 |
| 11 | -10 | 3 | -12 |
| 12 | -2 | -11 | -13 |
| 13 | -12 | 3 | -14 |
| 14 | -15 | -13 | 4 |
| 15 | -1 | -14 | 4 |
The file is integer binary, 4 bytes per integer, with no control blocks (also known as C-style binary). A typical way to read it in Fortran would be:
integer rng(nef,ne)
...
open (unit=1, file="mrng", access="direct", recl=nef∗ne∗4)
read (unit=1, rec=1) rng
close (unit=1)
or using the EWD library:
call ewdreadint(rng, nef∗ne, "mrng", 0, .false., .false.)
In order to apply boundary conditions to proper nodes, we need also to define a mapping from element faces to element nodes. The drawings below define the conventions for face numbering (circled labels) used in our files and software:
| triangle | quadrilateral | tetrahedron |
|
|
|
| hexahedron | ||
| ||
Content of a RNG file can be viewed the same way as the connectivity file.
The XNS is able to generate simple rectangular or cubic meshes in 2 or 3 dimensions. In that case, the RNGs are defined as follows (unless explicitly reordered in the XNS input file):
- 2D → 1: y = ymin, 2: x = xmax, 3: y = ymax, 4: x = xmin.
- 3D → 1: z = zmin, 2: y = ymin, 3: x = xmax, 4: y = ymax, 5: x = xmin, 6: z = zmax.
Space-time
For now, for space-time cases, the semi-discrete, or spatial, meshes are simply extruded into the temporal dimension, forming e.g. prisms from triangles. This extrusion is done entirely within XNS, and so the spatial mesh files are still used. The only modification concerns the number of nodes, which was too hard for XNS to modify (and redistribute on multiple processors). For that reason, space-time cases use modified minf and mxyz files, which simply double the number of nodes to account for two time levels per time steps. The spatial versions are typically renamed as minf.space and mxyz.space. In case the space-time files are not generated by a particular mesh generation program, they can be created by hand:
hydra(~)% cp minf.space minf hydra(~)% vi minf <...double number of nodes listed in the file...> hydra(~)% cat mxyz.space mxyz.space > mxyz
This should not really be so hard to do inside XNS, which would let us eliminate the space-time files, at least for the structured-in-time meshes currently in use. However, the mesh files formatted for space-time are still useful in postprocessing, as they contain information for both time levels in a time step.
In the course of a time-dependent simulation, a sequence of data files is typically obtained. In case of changing connectivity and coordinates, these may be also recorded in a sequence of files. For visualization purposes, those files cannot be simply concatenated, since they include initial solutions which are identical to the last solution of the previous run. To eliminate these duplicate sets, one can use the dd utility and a script similar to this:
hydra(~)% cat Combine dd if=ia.1e5.0050 of=mien.all bs=18210320 dd if=ia.1e5.0100 of=mien.all bs=18210320 skip=1 seek=51 dd if=ia.1e5.0150 of=mien.all bs=18210320 skip=1 seek=101 dd if=ia.1e5.0200 of=mien.all bs=18210320 skip=1 seek=151 dd if=xa.1e5.0050 of=mxyz.all bs=9450864 dd if=xa.1e5.0100 of=mxyz.all bs=9450864 skip=1 seek=51 dd if=xa.1e5.0150 of=mxyz.all bs=9450864 skip=1 seek=101 dd if=xa.1e5.0200 of=mxyz.all bs=9450864 skip=1 seek=151 dd if=da.1e5.0050 of=data.all bs=12601152 dd if=da.1e5.0100 of=data.all bs=12601152 skip=1 seek=51 dd if=da.1e5.0150 of=data.all bs=12601152 skip=1 seek=101 dd if=da.1e5.0200 of=data.all bs=12601152 skip=1 seek=151 hydra(~)% ./Combine
Here, the bs parameter specifies the record length in bytes for each type of file, which is basically the size of mien, mxyz or data.out file, respectively. The skip parameter causes the first record in most files to be skipped. The seek parameter fast forwards a given number of records and causes the data to be effectively appended at the end of the output file (assuming 50 records were saved in each simulation).




