Chapter 26 — Key Takeaways (Visualization Output)
A one-page reference for writing data that ParaView, VisIt, gnuplot, and matplotlib can read.
The legacy VTK STRUCTURED_POINTS file — the five parts, in order
# vtk DataFile Version 3.0 <- line 1, EXACT (lowercase "vtk", case-sensitive)
<title / comment> <- line 2, any text ≤ 256 chars (put provenance here)
ASCII <- storage: ASCII or BINARY
DATASET STRUCTURED_POINTS <- grid type
DIMENSIONS nx ny nz <- number of POINTS per axis (nz=1 for 2-D)
ORIGIN x0 y0 z0 <- physical position of point (1,1,1)
SPACING dx dy dz <- physical gap between adjacent points
POINT_DATA (nx*ny*nz) <- values live AT points; count MUST match
SCALARS temperature double 1 <- array: name, type, components-per-point
LOOKUP_TABLE default <- color table (default = viewer chooses)
<one value per point> <- x (i) fastest, then y (j), then z (k)
Rules worth memorizing
| Rule |
Why |
Line 1 is exact and case-sensitive: # vtk DataFile Version 3.0 |
# VTK or #vtk → ParaView rejects the file |
POINT_DATA = nx*ny*nz, computed from the loop's own variables |
a mismatched count errors (too many) or silently shifts the field (too few) |
Value order: do k; do j; do i; write u(i,j,k) — i innermost |
VTK stores x-fastest; with i→x this is also Fortran column-major (contiguous) |
DIMENSIONS counts points, not cells |
an nx×ny field has nx*ny points, not (nx-1)*(ny-1) |
Finite-difference values are nodal → use POINT_DATA, not CELL_DATA |
the stencil approximates the Laplacian at a point |
Zero-pad frame names (heat_000100.vtk) |
ParaView orders frames by lexical sort; padding makes it match numeric order |
The writer (canonical signature — lives in heat_io)
subroutine write_vtk(field, filename, step)
type(field_t), intent(in) :: field ! nx, ny, dx, dy, u(:,:)
character(len=*), intent(in) :: filename ! from frame_name(step)
integer, intent(in) :: step ! recorded in the title line
! ... 10 header writes, then do j; do i; write(iu,'(f0.6)') field%u(i,j)
The output loop in the solver's time march
do step = 0, n_steps
if (mod(step, save_every) == 0) call write_vtk(field, frame_name(step), step)
call step_field(field, alpha, dt)
end do
| Want |
Write |
Read with |
| An animation of a field over time |
legacy .vtk per step (zero-padded) |
ParaView / VisIt (group → play) |
| Physical time on the ParaView slider |
a .pvd collection listing files + timestep |
ParaView (open the .pvd) |
| Compression / parallel per-rank pieces |
XML .vti (ImageData) / .pvti |
ParaView / VisIt |
| A quick heat map or line plot |
3-column x y v, blank line per scan |
gnuplot splot … with pm3d |
| A NumPy array for a figure |
whitespace matrix, top row first |
numpy.loadtxt → imshow |
| A publication figure |
the matrix, plus plot_heat.py |
matplotlib (savefig(dpi=300)) |
VTK dataset ladder (write the least you can)
STRUCTURED_POINTS / ImageData regular box: origin+spacing+dims → values only ← the heat plate
RECTILINEAR_GRID / .vtr axis-aligned, unequal spacing → coordinate arrays
STRUCTURED_GRID / .vts logical box, curved → every point's (x,y,z)
UNSTRUCTURED_GRID / .vtu arbitrary mesh → every point AND every cell
Edit descriptors used (from Chapter 7)
| Descriptor |
Produces |
Note |
i0 |
integer, minimum width |
never overflows to *; right for point counts |
i6.6 |
integer, 6 digits, zero-padded |
sortable frame numbers (frame_name) |
f0.6 |
real, self-sizing, 6 decimals |
clean VTK values; leading zero for |x|<1 (gfortran 10+/F2018) |
*(f8.3,1x) |
unlimited-repeat row |
one write emits a whole matrix row |
Pitfalls
- Case/spelling of
# vtk DataFile Version 3.0 — exact, or rejected.
POINT_DATA count off by one — the field silently shifts; compute it, never hard-code it.
- Transposed picture — you looped
i outer; VTK needs i inner.
- Frames play out of order — filenames not zero-padded.
- gnuplot draws nonsense — missing the blank line between scans.
jet/rainbow colormap — invents false edges; use viridis/inferno/magma/plasma.
- Autoscaled movie frames — colors mean different temperatures per frame; fix
vmin/vmax.
Heat-solver piece added this chapter
write_vtk(field, filename, step) in heat_io, called every save_every steps with frame_name(step) →
a zero-padded VTK time series you open in ParaView. Optional: a .pvd collection for physical time. This is
the visualization the Chapter 38
capstone presents.