rdb_ocean_get_total_mass Function

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

Arguments

Type IntentOptional Attributes Name
type(c_ptr), intent(in), value :: c_handle
real(kind=c_double), intent(out) :: m_out

Return Value integer(kind=c_int)


Calls

proc~~rdb_ocean_get_total_mass~~CallsGraph proc~rdb_ocean_get_total_mass rdb_ocean_get_total_mass proc~cell_area_weighted_sum cell_area_weighted_sum proc~rdb_ocean_get_total_mass->proc~cell_area_weighted_sum proc~handle_has_area handle_has_area proc~rdb_ocean_get_total_mass->proc~handle_has_area proc~resolve_ocean resolve_ocean proc~rdb_ocean_get_total_mass->proc~resolve_ocean proc~handle_check handle_check proc~resolve_ocean->proc~handle_check

Variables

Type Visibility Attributes Name Initial
type(ocean_handle_t), private, pointer :: h
real(kind=wp), private :: total

Source Code

   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