Unformatted stream binary, GLOBAL format (rank-count-independent): the
solution is gathered to rank 0 and written over the global (nx_g, ny_g) grid.
The on-disk format is the unified format (magic 42); scalars iter, t,
extents (= [nx_g, ny_g]), neq2d, dt; grid record grid_type + a 2-component
fingerprint; the global ub array; then (v6, Q2d) the trailing records,
written/read unconditionally at fixed positions and mirroring 1D's v5
record ORDER (see checkpoint.f90's module header):
1. the Kahan t_comp compensation scalar;
2. the halo width h (validated on read against the current scheme's
halo width);
3. the GLOBAL boundary-ghost frame — the four width-h ghost bands
outside the global interior, corners included, in the fixed order
left, right, bottom, top (corners live in the bottom/top bands) —
moved via gather_boundary_ghosts_to_root /
scatter_boundary_ghosts_from_root (solution_gather_2d.F90). See
the record-block comment in write_checkpoint_2d for WHY the frame
must be persisted (multi-stage RK stage-snapshot ghost history).
The version number is checkpoint_io's single shared ckpt_version
constant. F2 bumped it 4→5 to add two 1D-only trailing records (see
checkpoint.f90's module header); 2D's on-disk body was byte-for-byte
unchanged by that bump, it just stamped version 5 in the header. Q2d bumps
it 5→6 to add 2D's own trailing records above (t_comp, then — same
initiative, after the restart bit-identity evidence gate — the halo width
and ghost-frame records); 1D's on-disk body is unchanged by THIS bump (a
freshly WRITTEN 1D checkpoint differs from its v5 form only in the
stamped header version). That does NOT make existing v5 files readable,
in either dimension — the strict version-equality check in
read_ckpt_header rejects legacy v4 and now also v5 files (1D or 2D),
the same owner-authorized break as before.
The mesh is NOT stored — on restart it is rebuilt from grid_file via build_mesh_2d_global/local. The fingerprint (sum and sum-of-squares of cell centres, via par_sum_real over local cells) detects a changed grid even at the same nx/ny. 2D is explicit-only, so there is no BDF2 array (cf. 1D).
MPI: write gathers to root, writes on rank 0, agrees via agree_outcome
(checkpoint_io's collective wrapper over par_lor). read opens the global
file read-only on every rank, validates, slices this rank's block via
decomp_2d % ix_first_global/iy_first_global; one collective decision point
via conclude_read.
Version compatibility: this is the unified v6 format (magic 42, version 6,
dim=2, extents=[nx_g, ny_g]). Legacy 2D v1 checkpoints (magic 4242), and
now also v4/v5 checkpoints, are NOT readable — read_ckpt_header's
magic/strict-version-equality check rejects them cleanly with a clear
error (owner-authorized break; no user-generated checkpoints exist).
Everything else — the global gather, the pointer-file mechanics, and the
MPI contract above — is unchanged.
Rank-independent geometric fingerprint of the grid: (sum, sum-of-squares) of cell-centre coordinates. For curvilinear grids it reduces over local cells (each cell owned once); for uniform grids it is a deterministic scalar combo identical on every rank.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(solver_state_2d_t), | intent(in) | :: | state |
Write a checkpoint: gather to root, write the global file on rank 0, agree outcome across ranks, update the latest_checkpoint_2d pointer file.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(solver_state_2d_t), | intent(in) | :: | state | |||
| character(len=*), | intent(in) | :: | base | |||
| real(kind=wp), | intent(in) | :: | t | |||
| integer, | intent(in) | :: | iter | |||
| logical, | intent(out), | optional | :: | is_ok | ||
| character(len=*), | intent(out), | optional | :: | message | ||
| character(len=*), | intent(out), | optional | :: | written_file |
Path of the file actually written ( |
|
| real(kind=wp), | intent(in), | optional | :: | t_comp |
Optional Kahan compensation term for |
Read a checkpoint and restore state. Every rank reads the global file read-only, validates magic/version/dim/nx/ny/neq/grid/halo-width, then slices its interior block and its owned piece of the GLOBAL boundary-ghost frame (v6; see the write-side record-block comment).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(solver_state_2d_t), | intent(inout) | :: | state | |||
| character(len=*), | intent(in) | :: | fname | |||
| real(kind=wp), | intent(out) | :: | t | |||
| integer, | intent(out) | :: | iter | |||
| logical, | intent(out), | optional | :: | is_ok | ||
| character(len=*), | intent(out), | optional | :: | message | ||
| real(kind=wp), | intent(out), | optional | :: | t_comp |
Optional: restored Kahan compensation term for |