Commit cad8b5ca authored by aarograh's avatar aarograh Committed by Henderson, Shane
Browse files

Hotfix find index int

Squash branch 'hotfix_findIndex_int' into 'master'

* Add comments for findIndex_1DInt

* Add incl=3 option to findIndex

* Add a bunch of findIndex testing

* > should be >=

Fixes a bug in the integer findIndex routine

**Developer Checklist:**
- [x] Have you done a self-review after creating the merge request?
- [x] Have you filled in the Merge Request information (title, description) thoroughly?
- [x] Have you updated the relevant tickets (if this MR is linked to any VERA-dev tickets)?
- [x] Have you addressed all suggested feedback and commented on it to let the reviewer know? (Do not resolve discussions that the reviewer started)

**Reviewer Checklist:**
- [x] Have you confirmed all discussions were adequately addressed and resolved them all?
- [x] Does it conform to formatting guidelines?
- [x] Are there adequate and clear comments?
- [x] Is the design clean and sensible?
- [x] Are the changes optimal/efficient?
- [x] Were sufficient DBC checks added?
- [x] Are there unit tests? (if necessary)
- [x] Is the MR description clear, including a link to the VERA-Dev issue if appropriate?

**PSM Checklist**
- [x] Have you confirmed that all discussions were addressed, or that follow-on issues have been created for them?
- [x] Have you confirmed sufficient testing was conducted?
- [x] Does this impact other repositories?
- [x] Does the MR have an adequate description?
- [x] If the MR has multiple commits, did you set the MR to squash merge?

See merge request https://code.ornl.gov/futility/Futility/-/merge_requests/415
parent 34bfeea9
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -914,8 +914,23 @@ PURE FUNCTION findIndex_1DReal(r,pos,delta,incl,tol) RESULT(ind)
ENDFUNCTION findIndex_1DReal
!
!-------------------------------------------------------------------------------
!> @brief
!> @param r
!> @brief Finds the index of a value in an array
!> @param r the array to search; assumed to be in increasing order if @c delta is false
!> @param pos the value to find
!> @param delta whether the array is in incremental (delta) form or not
!> @param incl whether the search is inclusive or exclusive
!> @returns ind the index of the array in which pos falls
!>
!> @c incl can have several possible values:
!> - 0: exclusive, error if on mesh (default)
!> - 1: inclusive, return lower index if on mesh
!> - 2: inclusive, return upper index if on mesh
!> - 3: inclusive, return index if on mesh, error if not on mesh
!>
!> The following error codes can be returned:
!> - -1: pos is below the range of the array
!> - -2: pos is above the range of the array
!> - -3: pos is on a mesh point (incl /= 3) or not on a mesh point (incl = 3)
!>
PURE FUNCTION findIndex_1DInt(r,pos,delta,incl) RESULT(ind)
  INTEGER(SIK),INTENT(IN) :: r(:)
@@ -941,7 +956,7 @@ PURE FUNCTION findIndex_1DInt(r,pos,delta,incl) RESULT(ind)
  !If the logic should be inclusive or exclusive
  l_incl=0
  IF(PRESENT(incl)) THEN
    IF((0 <= incl) .AND. (incl <= 2)) l_incl=incl
    IF((0 <= incl) .AND. (incl <= 3)) l_incl=incl
  ENDIF

  !Below the array
@@ -961,11 +976,20 @@ PURE FUNCTION findIndex_1DInt(r,pos,delta,incl) RESULT(ind)
      ENDDO
      ind=ind-1
    ENDIF
  !Search for exact match
  ELSEIF(l_incl == 3) THEN
    ind=-3
    DO i=1,n
      IF(pos == tmp(i)) THEN
        ind=i
        EXIT
      ENDIF
    ENDDO
  !Inbetween, don't error on mesh
  ELSEIF(l_incl > 0) THEN
    IF((tmp(1) <= pos) .AND. (pos <= tmp(n))) THEN
      ind=1
      DO WHILE(pos > tmp(ind))
      DO WHILE(pos >= tmp(ind))
        ind=ind+1
        IF(ind > n) EXIT
      ENDDO
+220 −9
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ PROGRAM testArrayUtils
USE UnitTest
USE IntrType
USE Strings
USE IO_Strings
USE ArrayUtils
USE Sorting

@@ -526,6 +527,7 @@ ENDSUBROUTINE test1DReals
!
!-------------------------------------------------------------------------------
SUBROUTINE test1DInts()
  INTEGER(SIK) :: i,j,ref
  !
  COMPONENT_TEST('getAbsolute 1-D Array')
  tmpintarray(1)=0
@@ -548,21 +550,230 @@ SUBROUTINE test1DInts()
  CALL getAbsolute(tmpintarray(2:10),tmpi,XI=0)
  bool=ALL(tmpi == (/0,2,3,5,12,20,25,40,60,100/))
  ASSERT(bool,'getAbsolute, partial array, with Xi ')

  !
  COMPONENT_TEST('findIndex 1-D Array')
  !Test with 0.0 specified
  tmpintarray(1)=0
  tmpintarray(2)=2
  tmpintarray(3)=3
  tmpintarray(4)=5
  tmpintarray(5)=12
  tmpintarray(3)=6
  tmpintarray(4)=10
  tmpintarray(5)=15
  tmpintarray(6)=20
  tmpintarray(7)=25
  tmpintarray(8)=40
  tmpintarray(9)=60
  tmpintarray(7)=40
  tmpintarray(8)=60
  tmpintarray(9)=65
  tmpintarray(10)=100
  ASSERT(findIndex(tmpintarray,-1,.FALSE.) == -1,'Out of Lower Bounds')
  ASSERT(findIndex(tmpintarray,101,.FALSE.) == -2,'Out of Upper Bounds')
  ASSERT(findIndex(tmpintarray,0,.FALSE.) == -3,'On mesh boundary')

  ASSERT_EQ(findIndex(tmpintarray,-1,.FALSE.),-1,'Out of Lower Bounds')
  ASSERT_EQ(findIndex(tmpintarray,101,.FALSE.),-2,'Out of Upper Bounds')
  ASSERT_EQ(findIndex(tmpintarray,100,.FALSE.),-3,'On Mesh Boundary')
  ASSERT_EQ(findIndex(tmpintarray,1,.FALSE.),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,3,.FALSE.),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,8,.FALSE.),3,'index == 3')
  ASSERT_EQ(findIndex(tmpintarray,12,.FALSE.),4,'index == 4')
  ASSERT_EQ(findIndex(tmpintarray,18,.FALSE.),5,'index == 5')
  ASSERT_EQ(findIndex(tmpintarray,30,.FALSE.),6,'index == 6')
  ASSERT_EQ(findIndex(tmpintarray,50,.FALSE.),7,'index == 7')
  ASSERT_EQ(findIndex(tmpintarray,62,.FALSE.),8,'index == 8')
  ASSERT_EQ(findIndex(tmpintarray,70,.FALSE.),9,'index == 9')

  !Check what happens on a mesh boundary.
  ASSERT_EQ(findIndex(tmpintarray,0,.FALSE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,1,.FALSE.,INCL=1),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,-1,.FALSE.,INCL=1),-1,'index == -1')
  ASSERT_EQ(findIndex(tmpintarray,0,.FALSE.,INCL=1),-1,'index == -1')
  ASSERT_EQ(findIndex(tmpintarray,0,.FALSE.,INCL=2),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,2,.FALSE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,2,.FALSE.,INCL=1),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,2,.FALSE.,INCL=2),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,100,.FALSE.,INCL=1),9,'index == 9')
  ASSERT_EQ(findIndex(tmpintarray,100,.FALSE.,INCL=2),-2,'index == -2')
  ASSERT_EQ(findIndex(tmpintarray,101,.FALSE.,INCL=1),-2,'index == -2')

  j = 0
  DO i = -1,101
    IF(i == -1) THEN
      ref = -1
    ELSEIF(i == 101) THEN
      ref = -2
    ELSEIF(ANY(i == tmpintarray)) THEN
      j = j + 1
      ref = j
    ELSE
      ref = -3
    ENDIF
    ASSERT_EQ(findIndex(tmpintarray,i,.FALSE.,INCL=3),ref,'index == '//TRIM(ADJUSTL(str(j)))//' for i='//TRIM(ADJUSTL(str(i))))
  ENDDO !i

    !Test without 0.0 specified
  tmpintarray(1)=2
  tmpintarray(2)=6
  tmpintarray(3)=10
  tmpintarray(4)=15
  tmpintarray(5)=20
  tmpintarray(6)=40
  tmpintarray(7)=60
  tmpintarray(8)=65
  tmpintarray(9)=100
  tmpintarray(10)=110

  ASSERT_EQ(findIndex(tmpintarray,-1,.FALSE.),-1,'Out of Lower Bounds')
  ASSERT_EQ(findIndex(tmpintarray,111,.FALSE.),-2,'Out of Upper Bounds')
  ASSERT_EQ(findIndex(tmpintarray,110,.FALSE.),-3,'On Mesh Boundary')
  ASSERT_EQ(findIndex(tmpintarray,1,.FALSE.),-1,'index == -1')
  ASSERT_EQ(findIndex(tmpintarray,3,.FALSE.),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,8,.FALSE.),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,12,.FALSE.),3,'index == 3')
  ASSERT_EQ(findIndex(tmpintarray,18,.FALSE.),4,'index == 4')
  ASSERT_EQ(findIndex(tmpintarray,30,.FALSE.),5,'index == 5')
  ASSERT_EQ(findIndex(tmpintarray,50,.FALSE.),6,'index == 6')
  ASSERT_EQ(findIndex(tmpintarray,62,.FALSE.),7,'index == 7')
  ASSERT_EQ(findIndex(tmpintarray,70,.FALSE.),8,'index == 8')
  ASSERT_EQ(findIndex(tmpintarray,105,.FALSE.),9,'index == 9')

  !Check what happens on a mesh boundary.
  ASSERT_EQ(findIndex(tmpintarray,2,.FALSE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,2,.FALSE.,INCL=1),-1,'index == -1')
  ASSERT_EQ(findIndex(tmpintarray,2,.FALSE.,INCL=2),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,6,.FALSE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,6,.FALSE.,INCL=1),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,6,.FALSE.,INCL=2),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,110,.FALSE.,INCL=2),-2,'index == -2')

  !Test with negative lower bound specified
  tmpintarray(1)=0
  tmpintarray(2)=2
  tmpintarray(3)=6
  tmpintarray(4)=10
  tmpintarray(5)=15
  tmpintarray(6)=20
  tmpintarray(7)=40
  tmpintarray(8)=60
  tmpintarray(9)=65
  tmpintarray(10)=100

  ASSERT_EQ(findIndex((/-10,tmpintarray/),-11,.FALSE.),-1,'Out of Lower Bounds')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),101,.FALSE.),-2,'Out of Upper Bounds')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),100,.FALSE.),-3,'On Mesh Boundary')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),-1,.FALSE.),1,'index == 1')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),1,.FALSE.),2,'index == 2')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),3,.FALSE.),3,'index == 3')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),8,.FALSE.),4,'index == 4')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),12,.FALSE.),5,'index == 5')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),18,.FALSE.),6,'index == 6')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),30,.FALSE.),7,'index == 7')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),50,.FALSE.),8,'index == 8')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),62,.FALSE.),9,'index == 9')

  !Check what happens on a mesh boundary.
  ASSERT_EQ(findIndex((/-10,tmpintarray/),-10,.FALSE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),-10,.FALSE.,INCL=1),-1,'index == -1')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),-10,.FALSE.,INCL=2),1,'index == 1')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),0,.FALSE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),0,.FALSE.,INCL=1),1,'index == 1')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),0,.FALSE.,INCL=2),2,'index == 2')
  ASSERT_EQ(findIndex((/-10,tmpintarray/),100,.FALSE.,INCL=2),-2,'index == -2')

  !Test with 0.0 specified using DELTA
  tmpintarray(1)=0 !0.0
  tmpintarray(2)=2 !2.0
  tmpintarray(3)=4 !6.0
  tmpintarray(4)=4 !10.0
  tmpintarray(5)=5 !15.0
  tmpintarray(6)=5 !20.0
  tmpintarray(7)=20 !40.0
  tmpintarray(8)=20 !60.0
  tmpintarray(9)=5  !65.0
  tmpintarray(10)=35 !100.0

  ASSERT_EQ(findIndex(tmpintarray,-1,.TRUE.),-1,'Out of Lower Bounds')
  ASSERT_EQ(findIndex(tmpintarray,101,.TRUE.),-2,'Out of Upper Bounds')
  ASSERT_EQ(findIndex(tmpintarray,1,.TRUE.),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,3,.TRUE.),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,8,.TRUE.),3,'index == 3')
  ASSERT_EQ(findIndex(tmpintarray,12,.TRUE.),4,'index == 4')
  ASSERT_EQ(findIndex(tmpintarray,18,.TRUE.),5,'index == 5')
  ASSERT_EQ(findIndex(tmpintarray,30,.TRUE.),6,'index == 6')
  ASSERT_EQ(findIndex(tmpintarray,50,.TRUE.),7,'index == 7')
  ASSERT_EQ(findIndex(tmpintarray,62,.TRUE.),8,'index == 8')
  ASSERT_EQ(findIndex(tmpintarray,70,.TRUE.),9,'index == 9')

  !Check what happens on a mesh boundary.
  ASSERT_EQ(findIndex(tmpintarray,0,.TRUE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,0,.TRUE.,INCL=1),-1,'index == -1')
  ASSERT_EQ(findIndex(tmpintarray,0,.TRUE.,INCL=2),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,2,.TRUE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,2,.TRUE.,INCL=1),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,2,.TRUE.,INCL=2),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,100,.TRUE.,INCL=2),-2,'index == -2')

  !Test without 0.0 specified using DELTA
  tmpintarray(1)=2 !2.0
  tmpintarray(2)=4 !6.0
  tmpintarray(3)=4 !10.0
  tmpintarray(4)=5 !15.0
  tmpintarray(5)=5 !20.0
  tmpintarray(6)=20 !40.0
  tmpintarray(7)=20 !60.0
  tmpintarray(8)=5  !65.0
  tmpintarray(9)=35 !100.0
  tmpintarray(10)=10 !110.0

  ASSERT_EQ(findIndex((/0,tmpintarray/),-1,.TRUE.),-1,'Out of Lower Bounds')
  ASSERT_EQ(findIndex((/0,tmpintarray/),111,.TRUE.),-2,'Out of Upper Bounds')
  ASSERT_EQ(findIndex((/0,tmpintarray/),1,.TRUE.),1,'index == 1')
  ASSERT_EQ(findIndex((/0,tmpintarray/),3,.TRUE.),2,'index == 2')
  ASSERT_EQ(findIndex((/0,tmpintarray/),8,.TRUE.),3,'index == 3')
  ASSERT_EQ(findIndex((/0,tmpintarray/),12,.TRUE.),4,'index == 4')
  ASSERT_EQ(findIndex((/0,tmpintarray/),18,.TRUE.),5,'index == 5')
  ASSERT_EQ(findIndex((/0,tmpintarray/),30,.TRUE.),6,'index == 6')
  ASSERT_EQ(findIndex((/0,tmpintarray/),50,.TRUE.),7,'index == 7')
  ASSERT_EQ(findIndex((/0,tmpintarray/),62,.TRUE.),8,'index == 8')
  ASSERT_EQ(findIndex((/0,tmpintarray/),70,.TRUE.),9,'index == 9')
  ASSERT_EQ(findIndex((/0,tmpintarray/),105,.TRUE.),10,'index == 10')

  !Check what happens on a mesh boundary.
  ASSERT_EQ(findIndex((/0,tmpintarray/),0,.TRUE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex((/0,tmpintarray/),0,.TRUE.,INCL=1),-1,'index == -1')
  ASSERT_EQ(findIndex((/0,tmpintarray/),0,.TRUE.,INCL=2),1,'index == 1')
  ASSERT_EQ(findIndex((/0,tmpintarray/),2,.TRUE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex((/0,tmpintarray/),2,.TRUE.,INCL=1),1,'index == 1')
  ASSERT_EQ(findIndex((/0,tmpintarray/),2,.TRUE.,INCL=2),2,'index == 2')
  ASSERT_EQ(findIndex((/0,tmpintarray/),110,.TRUE.,INCL=2),-2,'index == -2')

  !Test with negative lower bound specified using DELTA
  tmpintarray(1)=-10 !-10.0
  tmpintarray(2)=10 !0.0
  tmpintarray(3)=2 !2.0
  tmpintarray(4)=4 !6.0
  tmpintarray(5)=4 !10.0
  tmpintarray(6)=5 !15.0
  tmpintarray(7)=5 !20.0
  tmpintarray(8)=20 !40.0
  tmpintarray(9)=20 !60.0
  tmpintarray(10)=5  !65.0

  ASSERT_EQ(findIndex(tmpintarray,-11,.TRUE.),-1,'Out of Lower Bounds')
  ASSERT_EQ(findIndex(tmpintarray,101,.TRUE.),-2,'Out of Upper Bounds')
  ASSERT_EQ(findIndex(tmpintarray,-1,.TRUE.),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,1,.TRUE.),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,3,.TRUE.),3,'index == 3')
  ASSERT_EQ(findIndex(tmpintarray,8,.TRUE.),4,'index == 4')
  ASSERT_EQ(findIndex(tmpintarray,12,.TRUE.),5,'index == 5')
  ASSERT_EQ(findIndex(tmpintarray,18,.TRUE.),6,'index == 6')
  ASSERT_EQ(findIndex(tmpintarray,30,.TRUE.),7,'index == 7')
  ASSERT_EQ(findIndex(tmpintarray,50,.TRUE.),8,'index == 8')
  ASSERT_EQ(findIndex(tmpintarray,62,.TRUE.),9,'index == 9')

  !Check what happens on a mesh boundary.
  ASSERT_EQ(findIndex(tmpintarray,-10,.TRUE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,-10,.TRUE.,INCL=1),-1,'index == -1')
  ASSERT_EQ(findIndex(tmpintarray,-10,.TRUE.,INCL=2),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,0,.TRUE.,INCL=0),-3,'index == -3')
  ASSERT_EQ(findIndex(tmpintarray,0,.TRUE.,INCL=1),1,'index == 1')
  ASSERT_EQ(findIndex(tmpintarray,0,.TRUE.,INCL=2),2,'index == 2')
  ASSERT_EQ(findIndex(tmpintarray,65,.TRUE.,INCL=2),-2,'index == -2')
  !
  COMPONENT_TEST('findNUnique 1-D Array')
  tmpintarray(1)=0