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