Chapter 26 — Teaching Notes
One-line purpose. Give the heat solver "eyes": teach students to write a valid VTK time series from Fortran and open it as an animation in ParaView, plus the lightweight gnuplot/matplotlib path — closing Part VI on the division of labor "Fortran computes, Python/ParaView visualizes."
Key ideas to emphasize
- A visualization file stores data, not a picture. This reframes everything. Students who internalize it stop thinking "how do I make a plot in Fortran?" (you don't) and start thinking "how do I write the field so a viewer can plot it?" The picture is a live question asked of the data in ParaView — write once, view many ways.
- The legacy VTK header is five fixed parts, parsed positionally. Order and spelling are exact. Put the
skeleton on the board and have students point to each part in the file the demo writes. The two bugs that
matter — the case-sensitive magic string and the
POINT_DATAcount — should be stated, shown, and broken on purpose. - The write order is
do j; do i(i innermost), and that is column-major. This is the chapter's one deep idea and its tie to the whole book: VTK wants x fastest, Fortran stores the first index fastest, so mappingi→x makes the required file order also the cache-friendly memory order. It previews Chapter 27 and rewards Chapter 5. Do not skip the Performance Note. - Zero-padded filenames are what make a time series work.
frame_name'si6.6(Chapter 12) is not cosmetic — ParaView orders frames by lexical sort. Showheat_2.vtkvsheat_10.vtksorting wrong, then the padded version sorting right. - Colormap choice is a correctness issue, not decoration.
jet/rainbow invents edges;viridis/infernodo not. One-word change, big honesty gain — worth 90 seconds even in a Fortran course.
Misconceptions to preempt
- "
DIMENSIONScounts cells." It counts points. Annx×nyfield hasnx*nypoints.POINT_DATAmust equal that product — the single most common VTK error. Make them compute it from the loop's own variables, never hard-code it. - "The values go in row-major / Python order." Watch students who think in NumPy write
u[j,i]order or loopiouter. The result compiles, writes every value, and renders transposed. This is the Chapter 15 row/column-major trap resurfacing; demo the transposed picture so they recognize it. - "ParaView will figure out the time order." Only from lexical filename sort — so padding is mandatory.
- "
f0.6of 0.0 is obviously0.000000." True on gfortran 10+ (our baseline), but flag that the leading zero for magnitude < 1 is the one formatting spot that differed on ancient compilers; ParaView accepts both. A good teachable moment about the book's "hand-computed, you confirm by compiling" honesty rule. - "Text output is fine at any scale." It is not — precision loss and conversion time (exercises 20–23) make ASCII VTK a poor choice at a billion cells; that is what Chapter 25's binary formats are for.
Live-coding demo (≈ 20 min)
- Start from a
field_tholding a 3×2 field with values 0–5 (code/example-01-legacy-vtk.f90). Predict the file on the board first, then writewrite_vtkline by line, compile, andcatthe file. Match it to the predicted skeleton. - Break it on purpose: change the magic string to
# VTK …, open in ParaView → rejected. ChangePOINT_DATAto 5 → error/short read. Swap the loop toiouter → transposed plate. Fix each. This three- bug tour teaches more than a clean run. - Wire
write_vtkinto a short time loop withframe_nameandsave_every(project-checkpoint.f90), run it, and open theheat_..vtkseries in ParaView: Apply → color by temperature → play. The payoff moment. - If time:
numpy.loadtxt+imshowon the matrix format, and switchjet→infernoto show the colormap difference.
Time budget (≈ 2.5–3 h of class + lab)
- §26.1 VTK data model + dataset ladder: 20 min.
- §26.2 legacy VTK writer + the three bugs +
.vti: 45 min (the core). - §26.3 ParaView + time series +
.pvd: 30 min (best done live at a machine). - §26.4–26.5 gnuplot/matplotlib + colormaps: 25 min.
- Project Checkpoint + lab (open your own solver's output): 30–45 min.
Prerequisites to review before teaching
- Chapter 7:
write(unit, fmt),newunit,status='replace', thei0/i6.6/fdescriptors. - Chapter 12:
frame_nameand internal-file writes for zero-padded filenames. - Chapter 9: the
field_tderived type (the single argument every writer takes). - Chapter 5: column-major layout (the Performance Note leans on it).
- Chapter 24: the solver whose field is the thing being visualized (nodal values → POINT_DATA).