Skip to content

2. Formats ​

ASCII is easy to read and slow to write and read back: a number takes 25 characters instead of its 8 bytes. The format is an argument of initialize, and the rest of the program does not change. heat now writes the same temperature in every format:

f90
function write_file(filename, format, compressor) result(error)
!< Write the temperature in the given format, with the given compressor.
character(*), intent(in) :: filename, format, compressor
integer(I4P)             :: error
type(vtk_file)           :: a_vtk_file

error = a_vtk_file%initialize(format=format, filename=filename, mesh_topology='RectilinearGrid', &
                              nx1=1, nx2=n, ny1=1, ny2=n, nz1=1, nz2=n, compressor=compressor)
error = a_vtk_file%xml_writer%write_piece(nx1=1, nx2=n, ny1=1, ny2=n, nz1=1, nz2=n)
error = a_vtk_file%xml_writer%write_geo(x=x, y=x, z=x)
error = a_vtk_file%xml_writer%write_dataarray(location='node', action='open')
error = a_vtk_file%xml_writer%write_dataarray(data_name='temperature', x=t, one_component=.true.)
error = a_vtk_file%xml_writer%write_dataarray(location='node', action='close')
error = a_vtk_file%xml_writer%write_piece()
error = a_vtk_file%finalize()
endfunction write_file

Running it ​

$ heat
file                           format           compressor    bytes
heat-ascii-none.vtr            ascii            none         362098
heat-binary-none.vtr           binary           none         149062
heat-raw-none.vtr              raw              none         111976
heat-raw-zlib.vtr              raw              zlib          82211
heat-binary-appended-zlib.vtr  binary-appended  zlib         109354
FormatWhere the data areNotes
asciiinside each DataArray, as textreadable, about 3 times the binary size
binaryinside each DataArray, base64 encoded4/3 of the raw size; the file is still valid XML text
rawafter the XML, in the appended section, as bytesthe smallest and the fastest to read
binary-appendedin the appended section, base64 encodedtext, as binary, with the metadata first
  • compressor='zlib' compresses the binary formats as VTK does (blocks of 32 KiB): smooth fields such as this one shrink, noisy ones much less. It needs the library built with zlib, see Installation.
  • The appended formats keep the data in a scratch file until finalize: memory does not grow with the file.
  • Arrays larger than 2 GiB need header_type='UInt64', see Large data arrays.

From now on heat writes raw data compressed with zlib.

heat_2.f90
f90
program heat
!< Tutorial, chapter 2: the same temperature in every format, and the size of each file.
use penf, only : I4P, I8P, R8P
use vtk_fortran, only : vtk_file
implicit none
integer(I4P), parameter :: n=24
character(*), parameter :: formats(5)=['ascii          ', 'binary         ', 'raw            ', 'raw            ', &
                                       'binary-appended']
character(*), parameter :: compressors(5)=['none', 'none', 'none', 'zlib', 'zlib']
real(R8P)               :: x(n), t(n,n,n)
integer(I8P)            :: bytes
integer(I4P)            :: i, j, k, f, error
character(len=:), allocatable :: filename

x = [(real(i - 1, R8P)/(n - 1), i=1, n)]
do k=1, n ; do j=1, n ; do i=1, n
  t(i,j,k) = blob(x(i), x(j), x(k), [0.35_R8P, 0.4_R8P, 0.5_R8P]) + 0.6_R8P*blob(x(i), x(j), x(k), [0.7_R8P, 0.65_R8P, 0.45_R8P])
enddo ; enddo ; enddo
t(1,:,:) = 0 ; t(n,:,:) = 0 ; t(:,1,:) = 0 ; t(:,n,:) = 0 ; t(:,:,1) = 0 ; t(:,:,n) = 0

print '(A,T32,A,T49,A,T63,A)', 'file', 'format', 'compressor', 'bytes'
do f=1, size(formats)
  filename = 'heat-'//trim(formats(f))//'-'//compressors(f)//'.vtr'
  error = write_file(filename=filename, format=trim(formats(f)), compressor=compressors(f))
  inquire(file=filename, size=bytes)
  print '(A,T32,A,T49,A,T58,I10)', filename, formats(f), compressors(f), bytes
enddo
contains
  function write_file(filename, format, compressor) result(error)
  !< Write the temperature in the given format, with the given compressor.
  character(*), intent(in) :: filename, format, compressor
  integer(I4P)             :: error
  type(vtk_file)           :: a_vtk_file

  error = a_vtk_file%initialize(format=format, filename=filename, mesh_topology='RectilinearGrid', &
                                nx1=1, nx2=n, ny1=1, ny2=n, nz1=1, nz2=n, compressor=compressor)
  error = a_vtk_file%xml_writer%write_piece(nx1=1, nx2=n, ny1=1, ny2=n, nz1=1, nz2=n)
  error = a_vtk_file%xml_writer%write_geo(x=x, y=x, z=x)
  error = a_vtk_file%xml_writer%write_dataarray(location='node', action='open')
  error = a_vtk_file%xml_writer%write_dataarray(data_name='temperature', x=t, one_component=.true.)
  error = a_vtk_file%xml_writer%write_dataarray(location='node', action='close')
  error = a_vtk_file%xml_writer%write_piece()
  error = a_vtk_file%finalize()
  endfunction write_file

  pure function blob(x, y, z, centre) result(t)
  !< A hot blob: a Gaussian bump of temperature 1 at its centre.
  real(R8P), intent(in) :: x, y, z, centre(3)
  real(R8P)             :: t

  t = exp(-((x - centre(1))**2 + (y - centre(2))**2 + (z - centre(3))**2)/0.04_R8P)
  endfunction blob
endprogram heat

What you learned

The format is one argument of initialize: ascii to look at the data, raw (with compressor='zlib') for real runs. Reference: Output format selection, Compressed binary data.

Next: 3. More data.