Snapshot the seeded initial condition into sp%ref_tracer /
sp%u_ref / sp%v_ref (target_source = "ic", the only
implemented source in v1). HOST-side, plain do loops (mirrors
seed_ts_from_zfile — CLAUDE.md gotcha: this runs before
ocean_state_enter_data).
CALL-SITE CONTRACT (load-bearing, see the module docstring +
docs/plans/PLAN_PR23_real_sponge.md §13.1 item 4): must run
AFTER ocean_state_seed_from_cfg and BEFORE
ocean_state_restart_read in rdb_driver.F90. Snapshotting any
later would capture a warm-restarted run’s mid-run state instead
of the IC — a silent, resume-dependent physics change with a
bit-identical first step and no error.
Tracer concentration is hTr / h_layer, guarded by H_DIV_EPS
(pure 1/0 armour, D4 taxonomy). Under VCOORD_ZSTAR_FULL bed-side
layers can vanish (h_layer <= H_VANISHED); those columns fall
back to the nearest massive layer’s concentration (bed-up then
surface-down fill), mirroring the k_dep scan in
apply_geothermal_src_impl. No-op when .not. sp%enable (keeps
the default-off path free of extra work) or target_source /=
"ic" (the "file" source is PR-23b; validate_config has
already aborted before this runs if requested in v1).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_sponge_t), | intent(inout) | :: | sp | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(multilayer_state_t), | intent(in) | :: | ms |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | it | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | nx | ||||
| integer, | private | :: | ny | ||||
| integer, | private | :: | nz |
subroutine ocean_sponge_snapshot_reference(sp, grid, ms) !! Snapshot the seeded initial condition into `sp%ref_tracer` / !! `sp%u_ref` / `sp%v_ref` (`target_source = "ic"`, the only !! implemented source in v1). HOST-side, plain `do` loops (mirrors !! `seed_ts_from_zfile` — CLAUDE.md gotcha: this runs before !! `ocean_state_enter_data`). !! !! CALL-SITE CONTRACT (load-bearing, see the module docstring + !! `docs/plans/PLAN_PR23_real_sponge.md` §13.1 item 4): must run !! AFTER `ocean_state_seed_from_cfg` and BEFORE !! `ocean_state_restart_read` in `rdb_driver.F90`. Snapshotting any !! later would capture a warm-restarted run's mid-run state instead !! of the IC — a silent, resume-dependent physics change with a !! bit-identical first step and no error. !! !! Tracer concentration is `hTr / h_layer`, guarded by `H_DIV_EPS` !! (pure 1/0 armour, D4 taxonomy). Under `VCOORD_ZSTAR_FULL` bed-side !! layers can vanish (`h_layer <= H_VANISHED`); those columns fall !! back to the nearest massive layer's concentration (bed-up then !! surface-down fill), mirroring the `k_dep` scan in !! `apply_geothermal_src_impl`. No-op when `.not. sp%enable` (keeps !! the default-off path free of extra work) or `target_source /= !! "ic"` (the `"file"` source is PR-23b; `validate_config` has !! already aborted before this runs if requested in v1). type(ocean_sponge_t), intent(inout) :: sp type(hgrid_t), intent(in) :: grid type(multilayer_state_t), intent(in) :: ms integer :: i, j, it, nx, ny, nz if (.not. sp%enable) return ! Runs for `"linear_z"` too, on purpose: the analytic refresh below ! only owns TEMPERATURE and SALINITY, so every other registered ! tracer — and `u_ref`/`v_ref` — still needs the IC snapshot, or a ! passive tracer in the sponge band would be relaxed toward a ! hard zero it was never asked to go to. The refresh then ! overwrites the T/S planes on the first outer step. if (trim(sp%target_source) /= "ic" .and. & trim(sp%target_source) /= "linear_z") return if (.not. sp%is_init) return nx = grid%nx_total ny = grid%ny_total nz = ms%nz_ml if (allocated(ms%tracers)) then do it = 1, min(size(ms%tracers), sp%n_tracers) if (.not. allocated(ms%tracers(it)%hTr)) cycle do j = 1, ny do i = 1, nx call snapshot_column_concentration( & sp%ref_tracer(i, j, :, it), & ms%tracers(it)%hTr(i, j, :), ms%h_layer(i, j, :), nz) end do end do end do end if if (allocated(ms%u_face_x_layer) .and. size(ms%u_face_x_layer, 1) == nx + 1 & .and. size(ms%u_face_x_layer, 2) == ny) then sp%u_ref = ms%u_face_x_layer end if if (allocated(ms%v_face_y_layer) .and. size(ms%v_face_y_layer, 1) == nx & .and. size(ms%v_face_y_layer, 2) == ny + 1) then sp%v_ref = ms%v_face_y_layer end if end subroutine ocean_sponge_snapshot_reference