Add the geothermal bottom heat flux to the lowest massive
tracer layer. Operates in hTr space (concentration
thickness):
d(hT_{k=1})/dt = Q_geo / (rho0 * cp)
(units (W/m^2)/(kg/m^3 * J/kg/K) = Km/s, matching hTr).
No-op when geo is absent, .not. enable, q_geo_const == 0,
no temperature tracer is registered, or ms%tracers is
unallocated — preserving the default-off bit-identity contract.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_geothermal_t), | intent(in), | optional | :: | geo |
Optional — when absent the kernel is a no-op (no geothermal forcing configured). |
|
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(in) | :: | dt | |||
| logical, | intent(in), | optional | :: | active |
Optional gate (thermo cadence). Absent => kernel runs; present-and-false => early return. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | idx_T | ||||
| integer, | private | :: | nx | ||||
| integer, | private | :: | ny | ||||
| integer, | private | :: | nz | ||||
| real(kind=wp), | private | :: | src_T |
subroutine ocean_geothermal_apply_tracers(grid, geo, ms, dt, active) !! Add the geothermal bottom heat flux to the lowest massive !! tracer layer. Operates in `hTr` space (concentration* !! thickness): !! d(hT_{k=1})/dt = Q_geo / (rho0 * cp) !! (units (W/m^2)/(kg/m^3 * J/kg/K) = K*m/s, matching `hTr`). !! !! No-op when `geo` is absent, `.not. enable`, `q_geo_const == 0`, !! no temperature tracer is registered, or `ms%tracers` is !! unallocated — preserving the default-off bit-identity contract. type(hgrid_t), intent(in) :: grid type(ocean_geothermal_t), intent(in), optional :: geo !! Optional — when absent the kernel is a no-op (no geothermal !! forcing configured). type(multilayer_state_t), intent(inout) :: ms real(wp), intent(in) :: dt logical, intent(in), optional :: active !! Optional gate (thermo cadence). Absent => kernel runs; !! present-and-false => early return. integer :: nx, ny, nz, idx_T real(wp) :: src_T if (present(active)) then if (.not. active) return end if if (.not. present(geo)) return if (.not. geo%enable) return if (geo%q_geo_const == 0.0_wp) return if (.not. allocated(ms%tracers)) return idx_T = ms%idx_temperature if (idx_T <= 0) return nx = grid%nx_total ny = grid%ny_total nz = ms%nz_ml src_T = dt*geo%q_geo_const/(geo%rho0*geo%cp) ! Shim+_impl split keeps `tracers(idx)%hTr` deref on the host ! (array-of-DT registry indirection blocks NVHPC device codegen). call apply_geothermal_src_impl(ms%tracers(idx_T)%hTr, & ms%heat_budget_geothermal, & ms%wet_mask, ms%h_layer, ms%k_bot, src_T, nz, & geo%h_min) end subroutine ocean_geothermal_apply_tracers