ocean_sponge_snapshot_reference Subroutine

public 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).

Arguments

Type IntentOptional Attributes Name
type(ocean_sponge_t), intent(inout) :: sp
type(hgrid_t), intent(in) :: grid
type(multilayer_state_t), intent(in) :: ms

Calls

proc~~ocean_sponge_snapshot_reference~~CallsGraph proc~ocean_sponge_snapshot_reference ocean_sponge_snapshot_reference proc~snapshot_column_concentration snapshot_column_concentration proc~ocean_sponge_snapshot_reference->proc~snapshot_column_concentration

Called by

proc~~ocean_sponge_snapshot_reference~~CalledByGraph proc~ocean_sponge_snapshot_reference ocean_sponge_snapshot_reference proc~engine_setup engine_setup proc~engine_setup->proc~ocean_sponge_snapshot_reference proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_setup proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_setup proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_create_finalize rdb_ocean_create_finalize proc~rdb_ocean_create_finalize->proc~complete_ocean_create proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~complete_ocean_create

Variables

Type Visibility Attributes Name Initial
integer, private :: i
integer, private :: it
integer, private :: j
integer, private :: nx
integer, private :: ny
integer, private :: nz

Source Code

   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