The main documentation of the Collect_and_Combine_DV_from_OV Procedure contains additional explanation of this code listing.
define([COLLECT_AND_COMBINE_ROUTINE],[ pushdef([OP], [$1]) pushdef([Collect_and_OP_DV_from_OV], expand(Collect_and_$1_DV_from_OV)) subroutine Collect_and_OP_DV_from_OV (DV, OV) ! Input variable. type(Overlapped_Vector_type), intent(in) :: OV ! Variable to be combined. ! Input/Output variable. type(Distributed_Vector_type), intent(inout) :: DV ! Resultant DV. ! Internal variables. type(integer) :: i, j, k, m, o ! Loop counters. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! Verify requirements. VERIFY(Valid_State(OV),5) ! OV is valid. VERIFY(Valid_State(DV),5) ! DV is valid. VERIFY(OV%Dimensionality == DV%Dimensionality,5) ! Same dimensionality. VERIFY(OV%Dimensions(1:OV%Dimensionality-1) == dnl DV%Dimensions(1:DV%Dimensionality-1),5) ! Same dimensions. VERIFY(ASSOCIATED(OV%One_Structure,DV%Structure),5) ! Same one-structure. ! Collect and combine the values. There are different versions based ! on the dimensionality of the Index and on the dimensionality of the ! "Vector" itself. select case (OV%Many_of_One_Index%Dimensionality) ! Vector Index. Shape of DV%Values must be: ! ! DV%Values ( [dim1, [dim2, [dim3, ]]] One_Axis ) ! ! There is no Many_Axis to be combined -- no combination operation ! is used. case (1) ! Switch on the dimensionality of the data itself. select case (OV%Dimensionality) case (1) DV%Values1 = OPSTART where (OV%Many_of_One_Index%Index1 > 0) DV%Values1(:) = OV%DV%Values1(OV%Many_of_One_Index%Index1) end where where (OV%Many_of_One_Index%Index1 < 0) DV%Values1(:) = OV%Overlap_Values1(-OV%Many_of_One_Index%Index1) end where case (2) DV%Values2 = OPSTART do i = 1, OV%Dimensions(1) where (OV%Many_of_One_Index%Index1 > 0) DV%Values2(i,:) = OV%DV%Values2(i, OV%Many_of_One_Index%Index1) end where where (OV%Many_of_One_Index%Index1 < 0) DV%Values2(i,:) = & OV%Overlap_Values2(i, -OV%Many_of_One_Index%Index1) end where end do case (3) DV%Values3 = OPSTART do i = 1, OV%Dimensions(1) do j = 1, OV%Dimensions(2) where (OV%Many_of_One_Index%Index1 > 0) DV%Values3(i,j,:) = & OV%DV%Values3(i, j, OV%Many_of_One_Index%Index1) end where where (OV%Many_of_One_Index%Index1 < 0) DV%Values3(i,j,:) = & OV%Overlap_Values3(i, j, -OV%Many_of_One_Index%Index1) end where end do end do case (4) DV%Values4 = OPSTART do i = 1, OV%Dimensions(1) do j = 1, OV%Dimensions(2) do k = 1, OV%Dimensions(3) where (OV%Many_of_One_Index%Index1 > 0) DV%Values4(i,j,k,:) = & OV%DV%Values4(i, j, k, OV%Many_of_One_Index%Index1) end where where (OV%Many_of_One_Index%Index1 < 0) DV%Values4(i,j,k,:) = & OV%Overlap_Values4(i, j, k, -OV%Many_of_One_Index%Index1) end where end do end do end do end select ! Array Index. Shape of DV%Values must be: ! ! DV%Values ( [dim1, [dim2, [dim3, ]]] One_Axis ) ! ! The Many_Axis has been combined. case (2) ! Switch on the dimensionality of the data itself. select case (OV%Dimensionality) case (1) DV%Values1 = OPSTART do o = 1, SIZE(OV%Many_of_One_Index%Index2, 1) do m = 1, SIZE(OV%Many_of_One_Index%Index2, 2) if (OV%Many_of_One_Index%Index2(o,m) > 0) then DV%Values1(o) = OPERATION(DV%Values1(o), dnl OV%DV%Values1(OV%Many_of_One_Index%Index2(o,m))) else if (OV%Many_of_One_Index%Index2(o,m) < 0) then DV%Values1(o) = OPERATION(DV%Values1(o), dnl OV%Overlap_Values1(-OV%Many_of_One_Index%Index2(o,m))) end if end do ifelse(OP, [Average], [ DV%Values1(o) = DV%Values1(o) / & changetype(real, COUNT(OV%Many_of_One_Index%Index2(o,:) /= 0)) ]) end do case (2) DV%Values2 = OPSTART do i = 1, OV%Dimensions(1) do o = 1, SIZE(OV%Many_of_One_Index%Index2, 1) do m = 1, SIZE(OV%Many_of_One_Index%Index2, 2) if (OV%Many_of_One_Index%Index2(o,m) > 0) then DV%Values2(i,o) = OPERATION(DV%Values2(i,o), dnl OV%DV%Values2(i, OV%Many_of_One_Index%Index2(o,m))) else if (OV%Many_of_One_Index%Index2(o,m) < 0) then DV%Values2(i,o) = OPERATION(DV%Values2(i,o), dnl OV%Overlap_Values2(i, -OV%Many_of_One_Index%Index2(o,m))) end if end do ifelse(OP, [Average], [ DV%Values2(i,o) = DV%Values2(i,o) / & changetype(real, COUNT(OV%Many_of_One_Index%Index2(o,:) /= 0)) ]) end do end do case (3) DV%Values3 = OPSTART do i = 1, OV%Dimensions(1) do j = 1, OV%Dimensions(2) do o = 1, SIZE(OV%Many_of_One_Index%Index2, 1) do m = 1, SIZE(OV%Many_of_One_Index%Index2, 2) if (OV%Many_of_One_Index%Index2(o,m) > 0) then DV%Values3(i,j,o) = OPERATION(DV%Values3(i,j,o), dnl OV%DV%Values3(i, j, OV%Many_of_One_Index%Index2(o,m))) else if (OV%Many_of_One_Index%Index2(o,m) < 0) then DV%Values3(i,j,o) = OPERATION(DV%Values3(i,j,o), dnl OV%Overlap_Values3 dnl (i, j, -OV%Many_of_One_Index%Index2(o,m))) end if end do ifelse(OP, [Average], [ DV%Values3(i,j,o) = DV%Values3(i,j,o) / & changetype(real, dnl COUNT(OV%Many_of_One_Index%Index2(o,:) /= 0)) ]) end do end do end do case (4) DV%Values4 = OPSTART do i = 1, OV%Dimensions(1) do j = 1, OV%Dimensions(2) do k = 1, OV%Dimensions(3) do o = 1, SIZE(OV%Many_of_One_Index%Index2, 1) do m = 1, SIZE(OV%Many_of_One_Index%Index2, 2) if (OV%Many_of_One_Index%Index2(o,m) > 0) then DV%Values4(i,j,k,o) = OPERATION(DV%Values4(i,j,k,o), dnl OV%DV%Values4 dnl (i, j, k, OV%Many_of_One_Index%Index2(o,m))) else if (OV%Many_of_One_Index%Index2(o,m) < 0) then DV%Values4(i,j,k,o) = OPERATION(DV%Values4(i,j,k,o), dnl OV%Overlap_Values4 dnl (i, j, k, -OV%Many_of_One_Index%Index2(o,m))) end if end do ifelse(OP, [Average], [ DV%Values4(i,j,k,o) = DV%Values4(i,j,k,o) / & changetype(real, dnl COUNT(OV%Many_of_One_Index%Index2(o,:) /= 0)) ]) end do end do end do end do end select end select ! Set version number. DV = Version(OV) ! Verify guarantees. VERIFY(Valid_State(OV),5) ! OV is still valid. VERIFY(Valid_State(DV),5) ! DV is valid. return end subroutine Collect_and_OP_DV_from_OV popdef([OP]) popdef([OPERATION]) popdef([OPSTART]) popdef([Collect_and_OP_DV_from_OV]) ]) ! Add "Conserve" later if needed. fortext([Op],[Average SUM MAX MIN],[ ifelse( Op, [MAX], [ pushdef([OPERATION], [Op[]($1, & $2)]) pushdef([OPSTART],[-HUGE(zero)]) ], Op, [MIN], [ pushdef([OPERATION], [Op[]($1, & $2)]) pushdef([OPSTART],[HUGE(zero)]) ], [ pushdef([OPERATION], [$1 + & $2]) pushdef([OPSTART],[zero]) ] ) COLLECT_AND_COMBINE_ROUTINE(Op) ])