configure_ocean_reference_density Subroutine

public subroutine configure_ocean_reference_density(ocean_state, geo)

Fan the ONE configured Boussinesq reference density out to every remaining slot that carries its own rho0 copy.

&ocean_ic_nml rho_0 lands on eos%rho0 in ocean_state_init_from_config; that is the ρ₀ of record. EPBL, kappa-shear, tidal mixing, wave speed, the eta_ib surface-pressure seam, GM / MEKE / Redi / MLE, the isopycnal slopes and (since the preceding commit) the PGF all copy it in their own configure_ocean_*. The four slots wired here were the remainder: they kept a hard 1035 type default that nothing ever assigned, so a namelist with rho_0 /= 1035 ran the EOS on one reference density and the surface forcing, wind stress and KPP buoyancy on another — no warning, no fail-loud, just a 1035/ρ₀ scaling on every surface heat/salt flux, every wind-stress acceleration, and N²/u*/B_0.

  • surface_flux%rho0 — the dt/(ρ₀·cp) heat and dt/ρ₀ salt divisors for EVERY surface tracer source, including what the sea-ice coupler delivers through Q_heat/Q_salt.
  • surface_stress%rho0 — the τ/(ρ₀·h_top) acceleration (both the top-layer and the DIRECT_STRESS distributed form).
  • vmix%rho0 — KPP: N² = −g/ρ₀·∂ρ/∂z, u* = √(|τ|/ρ₀), the kinematic surface fluxes q_T = Q_heat/(ρ₀·cp), q_S = Q_salt/ρ₀ feeding B_0, and the PP81 / convective-adjustment N².
  • geothermal%rho0 — the dt·Q_geo/(ρ₀·cp) bed heat source. The geothermal slot lives on the engine, not on ocean_state, so it is passed in (optional: a caller with no geothermal slot simply omits it).

Device contract (mem:separate): surface_flux, surface_stress and geothermal read their rho0 HOST-side (folded into the inv_scale / src_T scalar or passed by value into a *_impl), so those owe nothing. vmix%rho0 IS read on-device — this%rho0 appears inside the do concurrent bodies of vmix_compute_pp81, vmix_kpp_overlay_impl and vmix_convective_impl — but this routine runs in the configure phase, strictly BEFORE ocean_state_enter_data’s copyin, exactly like the neighbouring pp81_* / shear2_floor scalars it sits with. No !$acc update device is owed. A configure step that ever moves after enter_data must add one.

Arguments

Type IntentOptional Attributes Name
type(ocean_state_t), intent(inout) :: ocean_state
type(ocean_geothermal_t), intent(inout), optional :: geo

Engine-held geothermal slot (the split driver’s geo argument).


Called by

proc~~configure_ocean_reference_density~~CalledByGraph proc~configure_ocean_reference_density configure_ocean_reference_density proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_reference_density 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

Source Code

   subroutine configure_ocean_reference_density(ocean_state, geo)
      !! Fan the ONE configured Boussinesq reference density out to every
      !! remaining slot that carries its own `rho0` copy.
      !!
      !! `&ocean_ic_nml rho_0` lands on `eos%rho0` in
      !! `ocean_state_init_from_config`; that is the ρ₀ of record.  EPBL,
      !! kappa-shear, tidal mixing, wave speed, the `eta_ib` surface-pressure
      !! seam, GM / MEKE / Redi / MLE, the isopycnal slopes and (since the
      !! preceding commit) the PGF all copy it in their own
      !! `configure_ocean_*`.  The four slots wired here were the remainder:
      !! they kept a hard 1035 type default that nothing ever assigned, so a
      !! namelist with `rho_0 /= 1035` ran the EOS on one reference density
      !! and the surface forcing, wind stress and KPP buoyancy on another —
      !! no warning, no fail-loud, just a 1035/ρ₀ scaling on every surface
      !! heat/salt flux, every wind-stress acceleration, and N²/u*/B_0.
      !!
      !!   * `surface_flux%rho0`  — the `dt/(ρ₀·cp)` heat and `dt/ρ₀` salt
      !!     divisors for EVERY surface tracer source, including what the
      !!     sea-ice coupler delivers through `Q_heat`/`Q_salt`.
      !!   * `surface_stress%rho0` — the `τ/(ρ₀·h_top)` acceleration (both
      !!     the top-layer and the DIRECT_STRESS distributed form).
      !!   * `vmix%rho0` — KPP: N² = −g/ρ₀·∂ρ/∂z, u* = √(|τ|/ρ₀), the
      !!     kinematic surface fluxes q_T = Q_heat/(ρ₀·cp), q_S = Q_salt/ρ₀
      !!     feeding B_0, and the PP81 / convective-adjustment N².
      !!   * `geothermal%rho0` — the `dt·Q_geo/(ρ₀·cp)` bed heat source.
      !!     The geothermal slot lives on the engine, not on `ocean_state`,
      !!     so it is passed in (optional: a caller with no geothermal slot
      !!     simply omits it).
      !!
      !! Device contract (`mem:separate`): `surface_flux`, `surface_stress`
      !! and `geothermal` read their `rho0` HOST-side (folded into the
      !! `inv_scale` / `src_T` scalar or passed by value into a `*_impl`), so
      !! those owe nothing.  `vmix%rho0` IS read on-device — `this%rho0`
      !! appears inside the `do concurrent` bodies of `vmix_compute_pp81`,
      !! `vmix_kpp_overlay_impl` and `vmix_convective_impl` — but this
      !! routine runs in the configure phase, strictly BEFORE
      !! `ocean_state_enter_data`'s `copyin`, exactly like the neighbouring
      !! `pp81_*` / `shear2_floor` scalars it sits with.  No
      !! `!$acc update device` is owed.  **A configure step that ever moves
      !! after `enter_data` must add one.**
      type(ocean_state_t), intent(inout) :: ocean_state
      type(ocean_geothermal_t), intent(inout), optional :: geo
         !! Engine-held geothermal slot (the split driver's `geo` argument).

      ocean_state%surface_flux%rho0 = ocean_state%eos%rho0
      ocean_state%surface_stress%rho0 = ocean_state%eos%rho0
      ocean_state%vmix%rho0 = ocean_state%eos%rho0
      if (present(geo)) geo%rho0 = ocean_state%eos%rho0
   end subroutine configure_ocean_reference_density