One scalar diagnostic — total water mass over the physical domain
(sum(h_layer * areaT) * RHO0_DIAG) — so a caller can prove the
solver actually advanced (and, in a closed quiescent/wall basin,
that it is conserving mass) without any state-array accessor (P2).
!$acc update self on the leaf array via associate (never the
aggregate ocean_state_t/multilayer_state_t) before summing, per
the D<->H contract — inert on a host build, load-bearing on GPU.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(out) | :: | m_out |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(ocean_handle_t), | private, | pointer | :: | h | |||
| real(kind=wp), | private | :: | total |
function rdb_ocean_get_total_mass(c_handle, m_out) result(status) & bind(c, name="rdb_ocean_get_total_mass") !! One scalar diagnostic — total water mass over the physical domain !! (`sum(h_layer * areaT) * RHO0_DIAG`) — so a caller can prove the !! solver actually advanced (and, in a closed quiescent/wall basin, !! that it is conserving mass) without any state-array accessor (P2). !! `!$acc update self` on the leaf array via `associate` (never the !! aggregate `ocean_state_t`/`multilayer_state_t`) before summing, per !! the D<->H contract — inert on a host build, load-bearing on GPU. type(c_ptr), intent(in), value :: c_handle real(c_double), intent(out) :: m_out integer(c_int) :: status type(ocean_handle_t), pointer :: h real(wp) :: total m_out = 0.0_c_double status = resolve_ocean(c_handle, h) if (status /= OCEAN_STATUS_OK) return associate (hlayer => h%state%multilayer%h_layer, ng => h%grid%nghost, & nxp => h%grid%nx_phys, nyp => h%grid%ny_phys) !$acc update self(hlayer) if (handle_has_area(h)) then ! Curvilinear (spherical / supergrid / tripolar) cells differ ! in area, and `grid%dx*grid%dy` is a placeholder there (1 m^2 ! on a supergrid), so weight each column by its own `areaT`. total = cell_area_weighted_sum(hlayer, h%state%metrics%areaT, ng, nxp, nyp) else total = sum(hlayer(ng + 1:ng + nxp, ng + 1:ng + nyp, :))*h%grid%dx*h%grid%dy end if end associate m_out = real(total*RHO0_DIAG, c_double) end function rdb_ocean_get_total_mass