ice_hlim_spec_is_valid Subroutine

public pure subroutine ice_hlim_spec_is_valid(hlim, ncat, ok, reason)

Shape/monotonicity predicate for a supplied &ocean_ice_nml hlim list (PR-58). A SUBROUTINE, not a function — a pure FUNCTION may not carry an intent(out) dummy (reason); pure SUBROUTINES can. n = ice_hlim_count(hlim); ok iff ALL of: (a) n >= 2 – one edge gives no width to extrapolate (SIS2 divergence D1: Roundabout fails loud here instead of SIS2’s silent fallback to the default table). (b) n <= ncat + 1 – more edges than the ITD has bins. (c) all(hlim(n+1:) < 0) – contiguity: no value after the first sentinel. (d) hlim(1) > 0 – mh_lim(1) > 0 is a live gate (rdb_ice_itd ice_adjust_categories). (e) hlim(k+1) > hlim(k), k = 1..n-1 – strictly increasing. Checking (d)+(e) on the SUPPLIED list is sufficient for the FULL h_lim(1..ncat+1): the constant-width extrapolation preserves both properties by induction (h_lim(k)-h_lim(k-1) = h_lim(k-1)-h_lim(k-2)), so no redundant post-extrapolation check is needed.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: hlim(:)
integer, intent(in) :: ncat
logical, intent(out) :: ok
character(len=:), intent(out), allocatable :: reason

Calls

proc~~ice_hlim_spec_is_valid~~CallsGraph proc~ice_hlim_spec_is_valid ice_hlim_spec_is_valid proc~ice_hlim_count ice_hlim_count proc~ice_hlim_spec_is_valid->proc~ice_hlim_count to_string to_string proc~ice_hlim_spec_is_valid->to_string

Called by

proc~~ice_hlim_spec_is_valid~~CalledByGraph proc~ice_hlim_spec_is_valid ice_hlim_spec_is_valid proc~validate_config validate_config proc~validate_config->proc~ice_hlim_spec_is_valid proc~build_pending_handle build_pending_handle proc~build_pending_handle->proc~validate_config proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~build_pending_handle proc~rdb_ocean_create_pending rdb_ocean_create_pending proc~rdb_ocean_create_pending->proc~build_pending_handle

Variables

Type Visibility Attributes Name Initial
integer, private :: k
integer, private :: n

Source Code

   pure subroutine ice_hlim_spec_is_valid(hlim, ncat, ok, reason)
      !! Shape/monotonicity predicate for a supplied `&ocean_ice_nml hlim`
      !! list (PR-58). A SUBROUTINE, not a function — a pure FUNCTION may
      !! not carry an `intent(out)` dummy (`reason`); pure SUBROUTINES
      !! can. `n = ice_hlim_count(hlim)`; `ok` iff ALL of:
      !!   (a) n >= 2                          -- one edge gives no width
      !!                                          to extrapolate (SIS2
      !!                                          divergence D1: Roundabout
      !!                                          fails loud here instead
      !!                                          of SIS2's silent
      !!                                          fallback to the default
      !!                                          table).
      !!   (b) n <= ncat + 1                   -- more edges than the ITD
      !!                                          has bins.
      !!   (c) all(hlim(n+1:) < 0)             -- contiguity: no value
      !!                                          after the first
      !!                                          sentinel.
      !!   (d) hlim(1) > 0                     -- mh_lim(1) > 0 is a live
      !!                                          gate (`rdb_ice_itd`
      !!                                          `ice_adjust_categories`).
      !!   (e) hlim(k+1) > hlim(k), k = 1..n-1  -- strictly increasing.
      !! Checking (d)+(e) on the SUPPLIED list is sufficient for the FULL
      !! `h_lim(1..ncat+1)`: the constant-width extrapolation preserves
      !! both properties by induction
      !! (`h_lim(k)-h_lim(k-1) = h_lim(k-1)-h_lim(k-2)`), so no redundant
      !! post-extrapolation check is needed.
      real(wp), intent(in) :: hlim(:)
      integer, intent(in) :: ncat
      logical, intent(out) :: ok
      character(len=:), allocatable, intent(out) :: reason
      integer :: n, k

      n = ice_hlim_count(hlim)
      ok = .false.
      reason = ""

      if (n < 2) then
         reason = "hlim must supply >= 2 entries (a single edge has no "// &
                  "width to extrapolate); got "//to_string(n)
         return
      end if
      if (n > ncat + 1) then
         reason = "hlim supplies "//to_string(n)//" entries, more than "// &
                  "ncat+1 ("//to_string(ncat + 1)//")"
         return
      end if
      if (.not. all(hlim(n + 1:) < 0.0_wp)) then
         reason = "hlim is not a contiguous leading run: a value follows "// &
                  "the first sentinel (entry "//to_string(n + 1)//")"
         return
      end if
      if (hlim(1) <= 0.0_wp) then
         reason = "hlim(1) must be > 0"
         return
      end if
      do k = 1, n - 1
         if (.not. (hlim(k + 1) > hlim(k))) then
            reason = "hlim must be strictly increasing (violated at entry "// &
                     to_string(k + 1)//")"
            return
         end if
      end do

      ok = .true.
      reason = "ok"
   end subroutine ice_hlim_spec_is_valid