Magic-number sentinel. Arbitrary but unlikely-in-uninitialised-memory,
and distinct from MAGIC_DESTROYED so a stale/garbage pointer and an
already-destroyed handle are both rejected by handle_check.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | HANDLE_ERR_INVALID | = | 2 | |
| integer, | public, | parameter | :: | HANDLE_ERR_NULL | = | 1 | |
| integer, | public, | parameter | :: | HANDLE_OK | = | 0 | |
| integer, | private, | parameter | :: | MAGIC_DESTROYED | = | int(z'DEADBEEF') |
handle_check return codes. |
| integer, | private, | parameter | :: | MAGIC_OCEAN | = | int(z'72616B4F') |
‘rakO’ |
One ocean simulation: config + the P2.4 setup/step/teardown
engine (god-state + grid + geothermal + bc_source + decomp +
sea-ice params — rdb_ocean_engine). state/grid below are
thin views onto engine%state/engine%grid kept ONLY so the
P2 accessor bodies (h%state%..., h%grid%...) did not all
need touching when this handle was rewired onto the shared
engine (P2.4): state is POINTER-associated to engine%state
right after engine_enter_data (stable for the handle’s
lifetime — engine is a component of this heap-allocated,
pointer-accessed handle, never copied/reallocated); grid is a
ONE-TIME VALUE COPY of engine%grid right after engine_setup
(safe because grid metadata is read-only after setup — no
kernel ever mutates nx_phys/dx/… mid-run). The standalone
sf slot from P1 is gone: engine_setup now fully configures
engine%state%surface_flux from the namelist (P2.4 closes the
“API surface flux is a separate, minimally-seeded object” gap),
so rdb_ocean_get/set_*_flux read/write h%state%surface_flux
directly, same as the driver.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(config_t), | public | :: | cfg | ||||
| logical, | public | :: | device_mapped | = | .false. |
True between |
|
| type(ocean_engine_t), | public | :: | engine |
Not declared |
|||
| type(hgrid_t), | public | :: | grid | ||||
| logical, | public | :: | host_is_current | = | .true. |
P2 lazy-sync gate ( |
|
| logical, | public | :: | is_initialised | = | .false. |
True once create() has completed device mapping. |
|
| logical, | public | :: | is_pending | = | .false. |
P2.5: true from |
|
| integer, | public | :: | magic | = | 0 | ||
| integer, | public | :: | n_inner | = | 0 |
Barotropic fast-loop substep count, mirrored from
|
|
| type(ocean_state_t), | public, | pointer | :: | state | => | null() | |
| real(kind=wp), | public | :: | t_current | = | 0.0_wp |
Resolve an opaque c_ptr to a Fortran pointer and verify it.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in) | :: | c_handle | |||
| type(ocean_handle_t), | intent(out), | pointer | :: | h |
Allocate a new ocean handle and return its opaque C pointer. Caller
(rdb_ocean_create_from_string) is responsible for eventually
passing it to handle_destroy — including on every early-return
failure path, so a handle that never reached is_initialised does
not leak.
Free an ocean handle. Idempotent on null/already-destroyed/garbage
handles — silently no-ops rather than aborting, so a Python
__del__ can call this blind. Caller is responsible for having
already unwound device residency and called engine_teardown
(engine%state%destroy() releases the god-state’s Fortran
allocations) — h%state is only a pointer VIEW onto
h%engine%state (see ocean_handle_t’s docstring), never
separately allocated, so there is nothing to deallocate through
it here; this only releases the handle’s own heap block
(which takes engine — a value component — down with it).
garbage or already destroyed
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(inout) | :: | c_handle |