Chapter 7 — Teaching Notes
One-line purpose. Give students precise control over how data enters and leaves a program — formatted output to the column, list-directed convenience, files, the namelist configuration format, binary for scale, and error handling — and use it to make the heat solver runnable (config from a file) rather than recompilable.
Key ideas to emphasize
- Predict output to the column. The single most durable skill of §7.1 is reading
w.dand knowing the exact spaces before you compile. Drill it: put aprint '(f8.2)', ...on the board and have the class call out the leading spaces. Everything (tables, the case studies, Ch. 12 internal files) builds on this. - Text is a lossy, expensive conversion. The §7.5 threshold — text throws away precision and costs ~100× a byte copy — reframes I/O as a performance topic, not a formatting chore. Case Study 1 is the payoff; teach it as "where did the nine minutes go?"
namelistis a genuine language-level win. Students coming from Python expect to pull in a YAML/JSON library; show them three lines of Fortran do it. Emphasize: by name, any order, omit-to-default, case-insensitive. This changes how they configure every run.- Guard your I/O.
iostat/iomsgturn a crash into a message;iostat_end(never-1) ends a read loop portably. This is the seed of the Ch. 13 error-handling discipline — plant the pattern now.
Misconceptions to preempt
- "
print '(a)', xandprint *, xare the same." (No — formatted has no leading space; list-directed emits one blank. Show both.) - "End of file is
iostat == -1." (Processor-defined; useiostat_end. This is Find-the-Bug 7.12/the §7.6 🐛 callout — worth doing live.) - "A binary file records its own shape and type." (No — raw binary/stream is not self-describing; that is Ch. 25's whole reason to exist. Namelist echo/self-describing formats fill the gap.)
- "
reclis in bytes everywhere." (gfortran yes, Intel counts words by default — a real portability trap.) - "Asterisks mean bad data." (No — the field is too narrow; widen it. A too-narrow field is supposed to be loud.)
- Integer division inside a format (
real(1/3, dp)→0.00) — the Ch. 3 trap resurfacing; Exercise 7.22.
A live demonstration (5–8 minutes)
Compile and run code/example-01-edit-descriptors.f90, but first have the class predict every line on
paper. Then reveal the output and reconcile. Immediately follow with the "gotcha" pair:
print '(a)', 'x' vs print *, 'x' — one has a leading space, one does not — to cement §7.1/§7.2. If time
allows, run example-03-namelist-config.f90, then edit config.nml live (change nx, delete a line) and
re-run without recompiling — the "aha" of configuration-not-recompilation lands hard.
Class-time budget (~50 min)
- 12 min: edit descriptors (§7.1), with the predict-then-run demo. This is the load-bearing section.
- 6 min: list-directed vs formatted (§7.2); the leading-space gotcha.
- 10 min: files —
open/read/write/close/inquire,newunit, status/action (§7.3). - 10 min:
namelist(§7.4), with the live-edit demo. Most memorable section for scientists. - 6 min: unformatted/stream and why (§7.5) — the text-vs-binary threshold.
- 6 min:
iostat/iomsg, the EOF loop, and the Project Checkpoint (§7.6 + solver).
Prerequisites to review
- Ch. 3 §3.7 (format strings — students have seen
i0,f,es,a; this chapter formalizes them) and the integer-division trap (§3.4), which returns in Exercise 7.22. - Ch. 5 arrays/column-major (for whole-array writes and the contiguity of
field(:,1)vsfield(1,:)). - Ch. 6
intentand assumed-shape (forwrite_field(f(:,:), filename)).
Connections
Forward: Ch. 8 (read_config/write_field → heat_io module), Ch. 12 (internal files, deferred-length strings,
indexed filenames), Ch. 13 (error handling generalized from iostat), Ch. 15 (stream ↔ NumPy order='F'),
Ch. 25 (self-describing HDF5/NetCDF — the answer to "raw binary isn't self-describing"), Ch. 26 (VTK output),
Ch. 28/37 (I/O as a profiled bottleneck; reproducibility). Naming these payoffs motivates the "boring"
plumbing.