D.4.1 Initialize_Data_Index Procedure

The main documentation of the Initialize_Data_Index Procedure contains additional explanation of this code listing.

  subroutine Initialize_Data_Index (Index, Many_Structure, One_Structure, &
                                    Many_of_One_Vector, Many_of_One_Array, &
                                    ! Many_of_One_Ragged, &
                                    status)

    ! Use associations.

    use Caesar_Flags_Module, only: initialized_flag

    ! Input variables.

    type(Base_Structure_type), target :: Many_Structure ! Column base structure.
    type(Base_Structure_type), target :: One_Structure  ! Row base structure.
    type(integer,1), optional :: Many_of_One_Vector     ! Vector indices.
    type(integer,2), optional :: Many_of_One_Array      ! Array indices.
    !type(Ragged_Integer_type), optional :: Many_of_One_Ragged ! Ragged indices.

    ! Output variables.

    ! Data_Index to be initialized.
    type(Data_Index_type), intent(out) :: Index 
    type(Status_type), intent(out), optional :: status  ! Exit status.

    ! Internal variables.

    type(Status_type), dimension(6) :: allocate_status ! Allocation Status.
    type(Status_type) :: consolidated_status         ! Consolidated Status.
    type(integer,1) :: Off_PE_Index_Temp             ! Off_PE_Index temporary.
    type(integer) :: entry, i, j                     ! Loop indices.

    !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ! Verify requirements.

    VERIFY(Valid_State(Many_Structure),5) ! Many_Structure is valid.
    VERIFY(Valid_State(One_Structure),5)  ! One_Structure is valid.

    ! Set allocation status.

    call Initialize (allocate_status)
    call Initialize (consolidated_status)

    ! Set up trace.

    if (PRESENT(Many_of_One_Vector)) then
      call Initialize (Index%Trace, Many_of_One_Vector, &
                       Length_PE(Many_Structure), allocate_status(1))
    else if (PRESENT(Many_of_One_Array)) then
      call Initialize (Index%Trace, Many_of_One_Array, &
                       Length_PE(Many_Structure), allocate_status(1))
    end if

    ! Initialize temporary to store off-PE indices. 
    !
    ! Note that the size that this variable needs to be is unknown. Assuming
    ! that the number of off-PE indices is less than the number of on-PE
    ! indices gives a size of Length_PE(One_Structure). This assumption
    ! means that the number of "boundary" values needed is less than
    ! the number of on-processor values, which will often be a reasonable
    ! assumption. However, one can imagine an almost worst-case scenario (not
    ! counting an extremely bad poly-connected structure, like a polyhedral
    ! mesh) consisting of a contiguous line of items connected like a
    ! 3-D structured hex mesh. Each item would connect to 8 off-PE items
    ! perpindicularly, and some others that are overlapped. The "end-caps"
    ! would not overlap, so would have an additional 9 items each. This
    ! gives rise to the following formula for the maximum:
    !
    !   Max size = 8 * Length_PE(One_Structure) + 18
    !
    ! This size is used for a temporary -- the actual variable is then sized
    ! to be exactly the needed size.

    call Initialize (Off_PE_Index_Temp, 8*Length_PE(One_Structure) + 18, &
                     allocate_status(2))

    ! Set up structure pointers.

    Index%Many_Structure => Many_Structure
    Index%One_Structure => One_Structure

    ! Set up for a Vector Index.

    if (PRESENT(Many_of_One_Vector)) then

      ! Verifications for a Vector.

      VERIFY(.not.PRESENT(Many_of_One_Array),7)
      VERIFY(.not.PRESENT(Many_of_One_Ragged),1000) ! Activate this later.
      VERIFY(Length_PE(One_Structure) == SIZE(Many_of_One_Vector), 5)

      ! Initialize Index1.

      Index%Dimensionality = 1
      call Initialize (Index%Index1, SIZE(Many_of_One_Vector,1), &
                       allocate_status(3))
      Index%Index1 = Many_of_One_Vector

      ! Set up the Off_PE_Index vector, and modify the Index1 vector to
      ! point off-PE references into Off_PE_Index with a negative flag.
      ! Also, change from global to local numbering.

      ! Loop over Index1 variables.

      Index%NOff_PE = 0
      do i = 1, SIZE(Many_of_One_Vector,1)

        ! Select Off-PE entries in Index1.
 
        if (Index%Index1(i) .NotInInterval. Range_PE(Many_Structure)) then

          ! If this value of Index1 hasn't been stored, store it.

          if (.not.ANY(Index%Index1(i) == Off_PE_Index_Temp)) then
            Index%NOff_PE = Index%NOff_PE + 1
            Off_PE_Index_Temp(Index%NOff_PE) = Index%Index1(i)
            Index%Index1(i) = -Index%NOff_PE

          ! Otherwise, figure out which entry in Off_PE_Index_Temp
          ! to set Index1 to (with a negative flag).

          else
            do entry = 1, Index%NOff_PE
              if (Index%Index1(i) == Off_PE_Index_Temp(entry)) then
                Index%Index1(i) = -entry
              end if
            end do
          end if

        ! For the On-PE indices, change to a local numbering.

        else

          Index%Index1(i) = Index%Index1(i) - First_PE(Many_Structure) + 1

        end if
      end do

    ! Set up for an Array Index.

    else if (PRESENT(Many_of_One_Array)) then

      ! Verifications for an Array.

      VERIFY(.not.PRESENT(Many_of_One_Vector),7)
      VERIFY(.not.PRESENT(Many_of_One_Ragged),1000) ! Activate this later.
      VERIFY(Length_PE(One_Structure) == SIZE(Many_of_One_Array,1), 5)

      ! Initialize Index2.

      Index%Dimensionality = 2
      call Initialize (Index%Index2, SIZE(Many_of_One_Array,1), &
                       SIZE(Many_of_One_Array,2), allocate_status(3))
      Index%Index2 = Many_of_One_Array

      ! Set up the Off_PE_Index vector, and modify the Index2 array to
      ! point off-PE references into Off_PE_Index with a negative flag.
      ! Also, change from global to local numbering.

      ! Loop over Index2 variables.

      Index%NOff_PE = 0
      do i = 1, SIZE(Many_of_One_Array,1)
        do j = 1, SIZE(Many_of_One_Array,2)

          ! Select Off-PE entries in Index2.
   
          if (Index%Index2(i,j) .NotInInterval. Range_PE(Many_Structure)) then
  
            ! If this value of Index2 hasn't been stored, store it.
  
            if (.not.ANY(Index%Index2(i,j) == Off_PE_Index_Temp)) then
              Index%NOff_PE = Index%NOff_PE + 1
              Off_PE_Index_Temp(Index%NOff_PE) = Index%Index2(i,j)
              Index%Index2(i,j) = -Index%NOff_PE
  
            ! Otherwise, figure out which entry in Off_PE_Index_Temp
            ! to set Index2 to (with a negative flag).
  
            else
              do entry = 1, Index%NOff_PE
                if (Index%Index2(i,j) == Off_PE_Index_Temp(entry)) then
                  Index%Index2(i,j) = -entry
                end if
              end do
            end if

          ! For the On-PE indices, change to a local numbering.
  
          else
  
            Index%Index2(i,j) = Index%Index2(i,j) &
                                - First_PE(Many_Structure) + 1

          end if
        end do
      end do

    ! Set up for a Ragged Index.

    ! <in the future>

    end if

    ! Store temporary in final form.

    VERIFY(Index%NOff_PE <= SIZE(Off_PE_Index_Temp),7)
    call Initialize (Index%Off_PE_Index, Index%NOff_PE, allocate_status(4))
    Index%Off_PE_Index = Off_PE_Index_Temp(1:Index%NOff_PE)
    call Finalize (Off_PE_Index_Temp, allocate_status(5))

    ! Set up off-PE trace.

    !if (Index%NOff_PE /= 0) then
      call Initialize (Index%Off_PE_Trace, Index%Off_PE_Index, &
                       Length_PE(Many_Structure), allocate_status(6))
    !end if

    ! Process status variables.

    consolidated_status = allocate_status
    if (PRESENT(status)) then
      WARN_IF(Error(consolidated_status), 5)
      status = consolidated_status
    else
      VERIFY(Normal(consolidated_status), 5)
    end if
    call Finalize (consolidated_status)
    call Finalize (allocate_status)

    ! Set initialization flag.

    Index%Initialized = initialized_flag

    ! Verify guarantees.

    VERIFY(Valid_State(Index),5)  ! Index is now valid.

    return
  end subroutine Initialize_Data_Index



Michael L. Hall