data_input_locate Subroutine

public pure subroutine data_input_locate(t_axis, nt, mode, cycle_period, t, n0, n1, w, out_of_range)

Bracket search + blend weight for a query time t (already in file-time units/offset — the caller applies t_offset/t_scale before calling). nt == 1 is degenerate: always returns n0 = n1 = 1, w = 0, never out of range.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: t_axis(nt)
integer, intent(in) :: nt
integer, intent(in) :: mode
real(kind=wp), intent(in) :: cycle_period
real(kind=wp), intent(in) :: t
integer, intent(out) :: n0
integer, intent(out) :: n1
real(kind=wp), intent(out) :: w
logical, intent(out) :: out_of_range

Called by

proc~~data_input_locate~~CalledByGraph proc~data_input_locate data_input_locate proc~data_input_refresh_brackets data_input_refresh_brackets proc~data_input_refresh_brackets->proc~data_input_locate proc~ocean_data_input_update_all ocean_data_input_update_all proc~ocean_data_input_update_all->proc~data_input_refresh_brackets proc~engine_step engine_step proc~engine_step->proc~ocean_data_input_update_all proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: gap
integer, private :: k
real(kind=wp), private :: t_eff

Source Code

   pure subroutine data_input_locate(t_axis, nt, mode, cycle_period, t, n0, n1, w, out_of_range)
      !! Bracket search + blend weight for a query time `t` (already in
      !! file-time units/offset — the caller applies `t_offset`/`t_scale`
      !! before calling).  `nt == 1` is degenerate: always returns
      !! `n0 = n1 = 1`, `w = 0`, never out of range.
      integer, intent(in) :: nt, mode
      real(wp), intent(in) :: t_axis(nt)
      real(wp), intent(in) :: cycle_period, t
      integer, intent(out) :: n0, n1
      real(wp), intent(out) :: w
      logical, intent(out) :: out_of_range

      integer :: k
      real(wp) :: t_eff, gap

      out_of_range = .false.

      if (nt <= 1) then
         n0 = 1
         n1 = 1
         w = 0.0_wp
         return
      end if

      if (mode == DATA_TIME_CYCLIC) then
         t_eff = t_axis(1) + modulo(t - t_axis(1), cycle_period)
         if (t_eff >= t_axis(nt)) then
            ! The seam bracket (nt, 1). Gap is NOT the mean record
            ! spacing — it is the wrap distance from the last record to
            ! the first record of the NEXT cycle.
            n0 = nt
            n1 = 1
            gap = (t_axis(1) + cycle_period) - t_axis(nt)
            if (gap > 0.0_wp) then
               w = (t_eff - t_axis(nt))/gap
            else
               w = 0.0_wp
            end if
         else
            n0 = 1
            do k = 1, nt - 1
               if (t_eff >= t_axis(k) .and. t_eff < t_axis(k + 1)) then
                  n0 = k
                  exit
               end if
            end do
            n1 = n0 + 1
            w = (t_eff - t_axis(n0))/(t_axis(n1) - t_axis(n0))
         end if
      else
         ! DATA_TIME_LINEAR (STATIC never reaches here — the caller
         ! returns before calling this for a static field).
         if (t < t_axis(1)) then
            n0 = 1
            n1 = 1
            w = 0.0_wp
            out_of_range = .true.
         else if (t > t_axis(nt)) then
            n0 = nt
            n1 = nt
            w = 0.0_wp
            out_of_range = .true.
         else if (t >= t_axis(nt)) then
            n0 = nt
            n1 = nt
            w = 0.0_wp
         else
            n0 = 1
            do k = 1, nt - 1
               if (t >= t_axis(k) .and. t < t_axis(k + 1)) then
                  n0 = k
                  exit
               end if
            end do
            n1 = n0 + 1
            w = (t - t_axis(n0))/(t_axis(n1) - t_axis(n0))
         end if
      end if
   end subroutine data_input_locate