rdb_ocean_get_kinetic_energy Function

public function rdb_ocean_get_kinetic_energy(c_handle, ke_out) result(status) bind(c, name="rdb_ocean_get_kinetic_energy")

Total kinetic energy (J, up to the Boussinesq reference-density factor — matches rdb_ocean_get_total_mass’s convention of leaving rho0 out) over the physical interior: sum(0.5 * h_layer * (u_centre^2 + v_centre^2) * areaT), faces averaged to centres — same formula as rdb_ocean_budgets::budget_total_ke, computed inline (weighted by the metrics’ areaT, so it is right on spherical / supergrid / tripolar grids too; grid%dx*grid%dy is only the fallback). Unlike the raw-pointer getters above, this refreshes the host itself — it hands back a NUMBER, not a pointer a caller could otherwise defer syncing for.

Arguments

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

Return Value integer(kind=c_int)


Calls

proc~~rdb_ocean_get_kinetic_energy~~CallsGraph proc~rdb_ocean_get_kinetic_energy rdb_ocean_get_kinetic_energy proc~handle_has_area handle_has_area proc~rdb_ocean_get_kinetic_energy->proc~handle_has_area proc~ocean_handle_refresh_host ocean_handle_refresh_host proc~rdb_ocean_get_kinetic_energy->proc~ocean_handle_refresh_host proc~resolve_ocean resolve_ocean proc~rdb_ocean_get_kinetic_energy->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
integer, private :: i
integer, private :: j
integer, private :: k
integer, private :: ng
integer, private :: nxp
integer, private :: nyp
real(kind=wp), private :: total
real(kind=wp), private :: uc
logical, private :: use_area
real(kind=wp), private :: vc

Source Code

   function rdb_ocean_get_kinetic_energy(c_handle, ke_out) result(status) &
      bind(c, name="rdb_ocean_get_kinetic_energy")
      !! Total kinetic energy (J, up to the Boussinesq reference-density
      !! factor — matches `rdb_ocean_get_total_mass`'s convention of
      !! leaving `rho0` out) over the physical interior:
      !! `sum(0.5 * h_layer * (u_centre^2 + v_centre^2) * areaT)`, faces
      !! averaged to centres — same formula as
      !! `rdb_ocean_budgets::budget_total_ke`, computed inline (weighted by
      !! the metrics' `areaT`, so it is right on spherical / supergrid /
      !! tripolar grids too; `grid%dx*grid%dy` is only the fallback). Unlike
      !! the raw-pointer getters above, this refreshes the host itself —
      !! it hands back a NUMBER, not a pointer a caller could otherwise
      !! defer syncing for.
      type(c_ptr), intent(in), value :: c_handle
      real(c_double), intent(out) :: ke_out
      integer(c_int) :: status

      type(ocean_handle_t), pointer :: h
      real(wp) :: total, uc, vc
      integer :: i, j, k, ng, nxp, nyp
      logical :: use_area

      ke_out = 0.0_c_double
      status = resolve_ocean(c_handle, h)
      if (status /= OCEAN_STATUS_OK) return

      call ocean_handle_refresh_host(h)
      use_area = handle_has_area(h)
      ng = h%grid%nghost
      nxp = h%grid%nx_phys
      nyp = h%grid%ny_phys
      total = 0.0_wp
      associate (ms => h%state%multilayer)
         do k = 1, ms%nz_ml
            do j = 1, nyp
               do i = 1, nxp
                  uc = 0.5_wp*(ms%u_face_x_layer(ng + i, ng + j, k) + &
                               ms%u_face_x_layer(ng + i + 1, ng + j, k))
                  vc = 0.5_wp*(ms%v_face_y_layer(ng + i, ng + j, k) + &
                               ms%v_face_y_layer(ng + i, ng + j + 1, k))
                  if (use_area) then
                     total = total + ms%h_layer(ng + i, ng + j, k)*0.5_wp*(uc*uc + vc*vc)* &
                             h%state%metrics%areaT(ng + i, ng + j)
                  else
                     total = total + ms%h_layer(ng + i, ng + j, k)*0.5_wp*(uc*uc + vc*vc)
                  end if
               end do
            end do
         end do
      end associate
      if (use_area) then
         ke_out = real(total, c_double)
      else
         ke_out = real(total*h%grid%dx*h%grid%dy, c_double)
      end if
      status = int(OCEAN_STATUS_OK, c_int)
   end function rdb_ocean_get_kinetic_energy