[Dart-dev] DART/branches Revision: 12501
dart at ucar.edu
dart at ucar.edu
Tue Apr 10 16:19:57 MDT 2018
nancy at ucar.edu
2018-04-10 16:19:57 -0600 (Tue, 10 Apr 2018)
79
add a binary search array for finding enclosing levels fast
in a sorted list.
Modified: DART/branches/recam/assimilation_code/modules/utilities/utilities_mod.f90
===================================================================
--- DART/branches/recam/assimilation_code/modules/utilities/utilities_mod.f90 2018-04-10 22:18:31 UTC (rev 12500)
+++ DART/branches/recam/assimilation_code/modules/utilities/utilities_mod.f90 2018-04-10 22:19:57 UTC (rev 12501)
@@ -204,7 +204,8 @@
string_to_real, &
string_to_integer, &
string_to_logical, &
- array_dump
+ array_dump, &
+ find_enclosing_indices
! this routine is either in the null_mpi_utilities_mod.f90, or in
! the mpi_utilities_mod.f90 file, but it is not a module subroutine.
@@ -2459,6 +2460,162 @@
end subroutine array_3d_dump
+!-----------------------------------------------------------------------
+!> given an array of sorted values and a value to find, return the
+!> two indices that enclose that value, and the fraction between.
+!>
+!>
+!> and higher index values, and the fraction across.
+!>
+!> fraction_across = 0.0 is the 100% the smaller index value,
+!> 1.0 is the 100% the larger index value.
+!>
+!> if the array values are inverted (e.g. index 1 is the largest value),
+!> set inverted = .true. the interpretation in the calling code for
+!> smaller index, larger index and fraction_across remain the same as the default case.
+!>
+!> if the fraction_across the enclosing level should be computed using a
+!> log scale, set log_scale = .true.
+!>
+!> my_status values:
+!> 0 = good return
+!> -1 = value_to_find is below smallest value
+!> 1 = value_to_find is above largest value
+!> 96 = cannot use log scale with negative data values
+!> 97 = array only has a single value
+!> 98 = interval has 0 width or values are inverted
+!> 99 = unknown error
+!>
+!> bad output values use MISSING_I and MISSING_R8
+!>
+!> FIXME:
+!> added to the utilities module, but this module should be split into
+!> smaller modules because right now it's a dumping ground for every
+!> random routine that is useful to more than one module. (my fault
+!> as much as anyones.
+
+subroutine find_enclosing_indices(nitems, data_array, value_to_find, &
+ smaller_index, larger_index, fraction_across, my_status, &
+ inverted, log_scale)
+
+integer, intent(in) :: nitems
+real(r8), intent(in) :: data_array(nitems)
+real(r8), intent(in) :: value_to_find
+integer, intent(out) :: smaller_index
+integer, intent(out) :: larger_index
+real(r8), intent(out) :: fraction_across
+integer, intent(out) :: my_status
+logical, intent(in), optional :: inverted
+logical, intent(in), optional :: log_scale
+
+integer :: i, j, k
+integer :: smaller_val_i, larger_val_i
+logical :: one_is_smallest, linear_interp ! the normal defaults
+
+! set defaults and initialize intent(out) items
+! so we can return immediately on error.
+
+one_is_smallest = .true.
+if (present(inverted)) one_is_smallest = .not. inverted
+
+linear_interp = .true.
+if (present(log_scale)) linear_interp = .not. log_scale
+
+smaller_index = MISSING_I
+larger_index = MISSING_I
+fraction_across = MISSING_R8
+my_status = -99
+
+
+! exclude malformed call cases
+if (nitems <= 1) then
+ my_status = 97
+ return
+endif
+
+! set these indices so we can simplify the tests below
+if (one_is_smallest) then
+ smaller_val_i = 1
+ larger_val_i = nitems
+else
+ smaller_val_i = nitems
+ larger_val_i = 1
+endif
+
+! discard out of range values
More information about the Dart-dev
mailing list