How to Read Binary Files Using vtkPLOT3DReader
Joel E. Tohline

On August 22, 2008, for the first time, I successfully read binary data files (from my group's CFD simulations) into the scientific visualization utility called VisTrails. I accomplished this using the vtmodule named vtkPLOT3DReader. The Fortran77 source code that was used to successfully generate the practice binary 'XYZ' and 'Q' data files, and the vtmodule that was used to successfully read and visualize the contents of these data files can be obtained via the following links:

In what follows, I explain how I accomplished this task. The principal questions to be answered were:

"In precisely what format should I write out data from a Fortran77 code such that the resulting binary data files are readable by vtkPLOT3DReader?"

"What flags need to be activated in the call to the vtmodule vtkPLOT3DReader so that the Fortran binary data file, written on some other machine hardware, will be correctly interpreted by this vtmodule?"


Step #1:   The VisTrails documentation for vtkPLOT3DReader reads as follows...

 vtkPLOT3DReader is a reader object that reads PLOT3D formatted files and 
 generates structured grid(s) on output. PLOT3D is a computer graphics 
 program designed to visualize the grids and solutions of computational 
 fluid dynamics. Please see the "PLOT3D User's Manual" available from 
 NASA Ames Research Center, Moffett Field CA.

 PLOT3D files consist of a grid file (also known as XYZ file), an 
 optional solution file (also known as a Q file), and an optional function 
 file that contains user created data (currently unsupported). The Q file 
 contains solution  information as follows: the four parameters free stream 
 mach number (Fsmach), angle of attack (Alpha), Reynolds number (Re), and 
 total integration time (Time). This information is stored in an array
 called Properties in the FieldData of each output (tuple 0: fsmach, tuple 1:
 alpha, tuple 2: re, tuple 3: time). In addition, the solution file contains 
 the flow density (scalar), flow momentum (vector), and flow energy (scalar).

 The reader can generate additional scalars and vectors (or "functions")
 from this information. To use vtkPLOT3DReader, you must specify the 
 particular function number for the scalar and vector you want to visualize.
 This implementation of the reader provides the following functions. The
 scalar functions are:
    -1  - don't read or compute any scalars
    100 - density
    110 - pressure
    120 - temperature
    130 - enthalpy
    140 - internal energy
    144 - kinetic energy
    153 - velocity magnitude
    163 - stagnation energy
    170 - entropy
    184 - swirl.

 The vector functions are:
    -1  - don't read or compute any vectors
    200 - velocity
    201 - vorticity
    202 - momentum
    210 - pressure gradient.

 (Other functions are described in the PLOT3D spec, but only those listed are
 implemented here.) Note that by default, this reader creates the density 
 scalar (100) and momentum vector (202) as output. (These are just read in
 from the solution file.) Please note that the validity of computation is
 a function of this class's gas constants (R, Gamma) and the equations used.
 They may not be suitable for your computational domain.

 Additionally, you can read other data and associate it as a vtkDataArray
 into the output's point attribute data. Use the method AddFunction()
 to list all the functions that you'd like to read. AddFunction() accepts
 an integer parameter that defines the function number.


Step #2:    Online documents/references...

Following the advice provided in the first paragraph of the VisTrails documentation, I searched the web for a copy of the "PLOT3D User's Manual" as well as for helpful hints regarding acceptable file formats. See the following links:

The user's manual is quite a large file (because the pages of the manual were scanned into a PDF document); the most relevant chapter on file formats (Chapter 8) can be downloaded here.

According to the examples presented in Chapter 8 of the User's Manual and in the web reference #1, in order to conform with the data file formats expected by PLOT3D, in a Fortran77 code, the 3D (so-called "whole") grid ('XYZ') and data ('Q') file should be written (or read; replace each 'WRITE' with 'READ') by the following lines of code:

Preamble...

      PARAMETER(IDIM = 32) 
      PARAMETER(JDIM = 32)
      PARAMETER(KDIM = 32)
      REAL X(IDIM,JDIM,KDIM),Y(IDIM,JDIM,KDIM),Z(IDIN,JDIM,KDIM)
      REAL DENSITY(IDIM,JDIM,KDIM),
     C     ENERGY(IDIM,JDIM,KDIM)
      REAL XMOM(IDIM,JDIM,KDIM),
     C     YMOM(IDIM,JDIM,KDIM),
     C     ZMOM(IDIM,JDIM,KDIM)
      REAL Q(IDIM,JDIM,KDIM,5)
      REAL FSMACH,ALPHA,RE,TIME
      INTEGER I,J,K,NX
C
C  Insert code to define the grid arrays X, Y, Z.
C  Insert code to define the physical variables DENSITY, XMOM
C  YMOM, ZMOM, and ENERGY.
C
      DO K=1,KDIM
        DO J=1,JDIM
          DO I=1,IDIM
          Q(I,J,K,1) = DENSITY(I,J,K) 
          Q(I,J,K,2) = XMOM(I,J,K) 
          Q(I,J,K,3) = YMOM(I,J,K) 
          Q(I,J,K,4) = ZMOM(I,J,K) 
          Q(I,J,K,5) = ENERGY(I,J,K) 
          ENDDO
        ENDDO
      ENDDO

Example #A...

      WRITE(UNIT_1) IDIM,JDIM,KDIM
      WRITE(UNIT_1) (((X(I,J,K),I=1,IDIM),J=1,JDIM),K=1,KDIM),
     C            (((Y(I,J,K),I=1,IDIM),J=1,JDIM),K=,KDIM),
     C            (((Z(I,J,K),I=1,IDIM),J=1,JDIM),K=,KDIM)
C
      WRITE(UNIT_2) IDIM,JDIM,KDIM
      WRITE(UNIT_2) FSMACH,ALPHA,RE,TIME
      WRITE(UNIT_2) (((( Q(I,J,K,NX),I=1,IDIM),J=1,JDIM),
     C              K=1,KDIM),NX=1,5)

This sequence of WRITE (or READ) statements seems to work (provided the correct flags are activated when calling the vtmodule; see Step #4, below). By experimentation, I have also discovered that the following, simpler WRITE (or READ) statements will work as well:

Example #B...

      WRITE(UNIT_1) IDIM,JDIM,KDIM
      WRITE(UNIT_1) X,Y,Z
C
      WRITE(UNIT_2) IDIM,JDIM,KDIM
      WRITE(UNIT_2) FSMACH,ALPHA,RE,TIME
      WRITE(UNIT_2) Q


Step #3:   File sizes...

Whether you follow "Example #A" or "Example #B," the resulting file sizes for a grid having resolution (IDIM = 32, JDIM = 32, KDIM = 32) should be:


Step #4:   Flags/Processes activated in the vtmodule vtkPLOT3DReader...

The Fortran77 code with which I generated the binary 'XYZ' and 'Q' files was compiled and executed on a linux PC, which presumably uses the "little endian" byte-order convention. When using vtkPLOT3DReader to read in these 'XYZ' and 'Q' binary data files, I found it necessary to activate the following flags/processes within the vtmodule:


Concern:   Why the need to activate 'ForceReadOn'?

I understand why the first 3 flags have been activated: By default, the vtmodule expects to read in ASCII data files; and when the data is provided in binary format, the default expectation is "Big Endian" and no 4-byte header (i.e., no Fortran header). But I don't understand why I have to activate 'ForceReadOn'.

According to the VisTrails documentation for "input port ForceReadOn in 'vtkPLOT3DReader'", its purpose is...

   Try to read a binary file even if the file length seems to be
   inconsistent with the header information.  Use this with caution,
   if the file length is not the same as calculated from the header,
   either the file is corrupt or the settings are wrong.

Perhaps the Reader expects to find only one 4-byte header and one 4-byte trailer accompanying each Fortran binary data file whereas both the 'XYZ' and 'Q' data files necessarily have additional extraneous header information within each file. The required PLOT3D file format produces these additional headers because a 4-byte header and a 4-byte trailer must accompany every 'WRITE' statement and, following the proper PLOT3D protocol, more than one 'WRITE' statement is used to produce both binary data files. Is this the correct explanation?

To test this, I tried combining the WRITE statements into one for each file, as follows.

Example #C...

      WRITE(UNIT_1) IDIM,JDIM,KDIM,X,Y,Z
C
      WRITE(UNIT_2) IDIM,JDIM,KDIM,FSMACH,ALPHA,RE,TIME,Q

While these modifications in the Fortran77 code reduced the file sizes, as expected [393,228+8 bytes and 655,388+8 bytes, respectively], these shortened files were no longer readable by the vtmodule, vtkPLOT3DReader. So, I remain confused!