Results I/O (binary, VTK, PNG)

OpenPFC separates the kernel interface ResultsWriter from frontend implementations under include/openpfc/frontend/io/. How you attach writers depends on whether you use the JSON-driven App path or a custom main.

ResultsWriter (kernel)

include/openpfc/kernel/simulation/results_writer.hpp — abstract hook the Simulator calls when it is time to persist fields. Implementations live in the frontend (binary/VTK) or in your app.

Narrow dispatch seam (tests)

simulator_results_dispatch.hpp defines pfc::write_results_for_registered_fields(Model&, const ResultsWriterMap&, int file_num) — the same loop Simulator::write_results() uses after reading the counter. Prefer this free function in unit tests with a small Model and mock writers when you do not need the full integrator stack. Simulator::results_writers() exposes the live map for inspection-only tests on a constructed simulator. The kernel also provides pfc::write_scheduled_simulator_results(Simulator&) — the same counter bump + dispatch as Simulator::write_results() for callables that should not use member syntax.

Binary output (MPI-IO)

include/openpfc/frontend/io/binary_writer.hppBinaryWriter: raw binary, collective MPI-IO. Documented caveats: all ranks in the communicator must participate consistently in write() to avoid deadlock. Both BinaryWriter::set_domain and kernel BinaryReader::set_domain fail closed on invalid geometry (non-positive extents, negative offsets, or a piece outside the global box); see binary_field_io_spec.md.

Format (layout, filename printf pattern, collectives): binary_field_io_spec.md.

JSON-driven App path

simulation_wiring.hpp add_result_writers_from_json takes a ResultsWriterCatalog at the call site (e.g. default_results_writer_catalog() for built-in binary). It registers BinaryWriter only: for each fields[] entry it uses field["data"] as the path template. There is no VTK branch in that helper today—VTK is attached in code (see below).

Requirements in settings: saveat > 0, fields array with name and data.

VTK (ParaView / VisIt)

include/openpfc/frontend/io/vtk_writer.hppVTKWriter: .vti / .pvti output. Extent/origin/spacing and local point-count checks are implemented in vtk_writer_validate.hpp (pfc::io::vtk_validate), separate from XML and file I/O. Typical use is programmatic: construct VTKWriter, set_domain, set_origin, set_spacing, then add_results_writer or call from your step loop. See examples/11_write_results.cpp and Doxygen on VTKWriter.

PNG (2D grayscale, quick look)

include/openpfc/frontend/io/png_writer.hpppfc::io::write_mpi_scalar_field_png_xy: gathers a single z-slab (nz == 1 globally) to rank 0 and writes an 8-bit grayscale PNG. Used for lightweight visualization (e.g. Allen–Cahn apps/allen_cahn), not the main spectral App JSON pipeline.

Collective contract: All ranks in the communicator must participate consistently. Buffer size validation is fail-closed (communicator-wide agreement via MPI_Allreduce) before the MPI_Allgather/MPI_Gatherv calls, preventing deadlocks when a rank provides an incorrectly sized local_field.

Choosing a path

Goal

Mechanism

Large production runs, restarts

BinaryWriter + BinaryReader; match JSON fields/data paths.

Interactive visualization

VTKWriter from code or extend wiring to register it.

Quick 2D snapshot

png_writer.hpp helpers

See also