Changelog
All notable changes to Cocoa will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.4.0] - 2026-08-15
Added
Baroclinic coupling. Nodal baroclinic pressure gradient forcing with the elemental free-surface correction (Crank-Nicolson centered, ramped), internal-tide wave drag computed from a de-tided velocity (Nycander, Lyard and scalar formulations, with the de-tiding window carried across restarts), and momentum dispersion as an additive friction contribution in
mixed_layer_ratioanddispersion_cdmodes. Configured underforcing.baroclinic; the friction tensor closes with a positive-semidefinite eigenvalue clamp.bpg_effective_x/yare available as inspection output.cocoa_ocean3d, an installable Python preprocessor that turns HYCOM GOFS 3.1 fields into the nodal baroclinic forcing file: TEOS-10 density, column-integrated pressure gradient, mixed-layer and dispersion products, mesh regridding, and download.Sea-ice concentration as a first-class meteorological field: CF NetCDF and GRIB ingestion, composition across multi-domain sources, and attenuation of the wind drag coefficient via the Lupkes (2012) parameterization.
Elevation slope limiter (
numeric.elemental_slope_limiter), an optional post-GWCE pass that replaces zeta at nodes whose surrounding elemental elevation gradient exceeds a per-node threshold with the area-weighted average of the node’s element patch.GAHM2026 conformance for weak and degenerate tracks: ambient pressure from the ATCF RADP column, a clamped Holland B, minimum-strength gates, neighbor fill for unreported quadrant radii instead of fabricated ones, and snapshots with missing scalars skipped with a warning rather than aborting the run. Preprocessed fort.22 input (aswip NWS=19/20) is now rejected.
Configurable output compression (
output.compressionlevel and shuffle); the default is deflate level 1 without shuffle, chosen by measurement.utils/plot_cocoa.py, a single plotter for output, peak and mesh files that discovers the mesh and the plottable variables from the file’s UGRID/CF attributes. Handles global and regional meshes, vector pairs, and frame series or movies; shipped in the containers.Nightly and release container publication for the CPU, CUDA and ROCm families.
Changed
Output field variables are written as single precision. Coordinates, bathymetry, the time axis and checkpoints are unchanged.
simulation.start_timeis optional whencheckpoint.restart_fileis set; the cold-start clock is recovered from the checkpoint, and a configured value that disagrees with it is rejected rather than silently re-anchoring every forcing ramp.Checkpoint format version 4: baroclinic Crank-Nicolson levels and the de-tiding window are persisted, so a restart resumes them mid-window rather than rebuilding them. Version 3 checkpoints are refused.
Checkpoint restart compares mesh identity per section. Node positions, connectivity and boundaries must match; bathymetry, nodal attributes and self-attraction/loading may change between segments.
Profiling regions are nested rather than spelling the hierarchy in labels, and the per-step time-level advance, field extrema and checkpoint write are timed for the first time.
Run progress and the time-to-completion estimate are reported against the work this run performs, so a restart no longer starts at the resumed percentage.
Error and critical messages print from every MPI rank, prefixed with the rank id; lower levels stay rank-0-only.
Fixed
On rotated-pole meshes, wind stress and the baroclinic pressure gradient are rotated into the computational frame, and the spherical metric term in momentum is evaluated from the rotated coordinates. Previously geographic vectors reached the equations untransformed.
MPI runs wrote solver-frame velocity to output; velocity rotation to the geographic frame now applies in serial and distributed runs alike.
Flux boundary state is checkpointed in the mesh’s global ordering, so a checkpoint no longer depends on rank count. Truncated files written by earlier versions are refused.
The
internal_tide_frictionnodal attribute’s column count is validated at load, repairing an out-of-bounds read of a single-column attribute.The JSONL step log is written by one writer, one record per step.
Non-binary canopy values are resolved during fort.13 conversion.
Performance
Output staging is device-resident, packed on device and copied back on a dedicated execution-space instance so the transfer overlaps compute. With single-precision storage, the cost of 2-minute output on a 1.57M-node hurricane case (V100, one simulated day) falls from roughly 26% to 3.3% of runtime, and the file halves in size.
[0.3.1] - 2026-07-27
A maintenance release; no new model capability.
Changed
-i(now also spelled--input) is required and must name an existing file; the implicitcocoa_config.yamldefault is gone.--partitiongains the short spelling-p.
Fixed
Registering more extrema fields than the maximum truncated silently, and a sources/configs size mismatch indexed out of range. Both now throw at the boundary, naming the actual and allowed counts.
cocoa_mesh_tools.pyruns in a container with no username populated.
[0.3.0] - 2026-07-20
Added
GAHM parametric hurricane vortex forcing (
cocoa_vortex), with ATCF b-deck parsing and missing-central-pressure estimation.GRIB2 meteorological forcing via ecCodes (
cocoa_ENABLE_GRIB).Multi-source meteorological composition: self-contained
domains:entries, per-source wind reduction, and per-source activation ramps.Configuration schema validation on valijson (JSON Schema draft-07), with the schema embedded in the binary and reproduced in the user guide.
External YAML inclusion at designated configuration nodes.
Checkpoint format version 3: peaks are preserved across a restart, mesh identity is verified before restoring, and the end-of-run checkpoint is gated on solution stability.
Google Benchmark suite with scaling analysis, compile-gated in CI.
New dependencies: valijson and CLI11 (CPM-fetched); ecCodes (optional, GRIB builds only).
Changed
Asynchronous I/O is now always on. Output is delivered on a background writer thread and meteorological input is pre-read ahead of need, overlapping file access with computation in every run. MPI is initialized with
MPI_THREAD_FUNNELEDto support this; a run aborts at startup if the MPI build cannot provide it.Command-line parsing moved to CLI11:
--option=valuespellings now work, malformed values fail loudly, and--help/--versionfollow standard Unix formatting.Boolean configuration values must be
true/false; the YAML 1.1 spellings are rejected.CF NetCDF pressure units are read from the file and required.
Performance
Explicit solver per-step host stalls eliminated, worth roughly 13-15% throughput on a 1.57M-node hurricane case with meteorology; momentum nodal assembly reduced from three sweeps to one; wet/dry list compaction with no per-step device allocation; cached MPI ghost staging and device-direct boundary forcing scatter.
Removed
The
--asynciocommand-line flag and its modes. Asynchronous output is now unconditional, so there is no mode to select. The dedicated-MPI-I/O-rank mode (--asyncio=mpi) has been removed; all ranks now participate in computation.
Fixed
MPI runs fail fast on rank-local errors instead of hanging peers until walltime.
Land-boundary normals at multi-string junction nodes average the per-string normals (a documented deviation from ADCIRC’s last-wins).
Binary-inexact time steps (e.g. 0.1 s) no longer drop the final step.
[0.2.0b0] - 2026-06-29
Added
Full OWI NWS13 support, with Lagrangian moving-vortex interpolation for moving grids.
Grouped mesh NetCDF format carrying boundaries, nodal attributes and self-attraction/loading in one file, identified by a BLAKE2 content fingerprint (
mesh_id) that is stamped onto model output. The mesh tooling is consolidated intoutils/cocoa_mesh_tools.py.Checkpoint format version 2: timestamped single files, written at the end of a run by default, with a warning when a run would accumulate many of them.
Changed
“Hot start” is now “checkpoint” throughout the configuration and docs.
Container images moved to the
cocoaorgDocker Hub namespace.
Removed
The A/B checkpoint file pair and the FNV-1a mesh topology checksum, superseded by timestamped checkpoints and
mesh_id.
Fixed
OWI uniform-grid detection is de-biased with average spacing, so a grid that is regular within round-off is no longer misread as irregular.
Kokkos and KokkosKernels are found as standalone packages, and the diagnostics-color flag is selected per language, fixing the ROCm build.
Multi-value nodal attributes get their secondary dimension when a mesh is converted to the grouped format.
Performance
The static OWI grid is cached rather than reparsed, regular moving grids are read by corners, and the continuity diagonal solve is fused into one kernel.
Migration Guide
Migrating from ADCIRC
Converting Mesh Files
Cocoa uses NetCDF format for mesh files instead of ADCIRC’s fort.14/fort.13 format.
A conversion script is provided in the utils directory:
python utils/cocoa_mesh_tools.py from_adcirc \
--mesh fort.14 \
--attributes fort.13 \
--output mesh.nc
Arguments:
--mesh: ADCIRC mesh file (fort.14) - required--attributes: ADCIRC nodal attributes file (fort.13) - optional--output: Output NetCDF file path - required
Configuration Files
Cocoa uses YAML configuration files instead of ADCIRC’s fort.15 format. Key differences:
ADCIRC Parameter |
Cocoa Equivalent |
|---|---|
DT |
|
TAU0 |
|
STATIM |
|
RNDAY |
|
Note
In ADCIRC, a negative TAU0 value triggers spatially-varying computation.
In Cocoa, tau0 must always be a positive constant value.
Example conversion:
ADCIRC fort.15:
DT = 2.0
TAU0 = 0.005
RNDAY = 1.0
Cocoa YAML:
simulation:
time_step: 2s
start_time: 2025-01-01
end_time: 2025-01-02
physics:
tau0: 0.005