Perform the global reduction
After the local reductions have been performed (in _append), the results must be communicated between processes.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_reduction_spatial_type), | intent(inout) | :: | me(:) |
The reduction type to work on. All definitions should be present in here |
||
type(tem_comm_env_type), | intent(in) | :: | proc |
communicator for processes participating in this reduction |
subroutine tem_reduction_spatial_close(me, proc)
! ---------------------------------------------------------------------------
!> The reduction type to work on. All definitions should be
!! present in here
type( tem_reduction_spatial_type ), intent(inout) :: me(:)
!> communicator for processes participating in this reduction
type(tem_comm_env_type), intent(in) :: proc
! ---------------------------------------------------------------------------
integer :: i, nComp, ierr, globalnElems
real(kind=rk), allocatable :: buff(:)
real(kind=rk) :: Vglob
! ---------------------------------------------------------------------------
globalnElems = 0
!loop over all tracking objects
do i = 1, size(me)
! get number of components
nComp = me(i)%nComponents
allocate(buff(nComp))
buff = 0.0_rk
!choose reduction operation and perform it
select case( me( i )%reduceType )
!sum all values
case('sum', 'weighted_sum')
call mpi_reduce( me(i)%val, buff, &
& nComp, rk_mpi, mpi_sum, proc%root, proc%comm, iErr)
me(i)%val = buff
!sum all values and devide by number of elements
case('average')
globalnElems = 0
! get global number of elements in this reduction to rank 0
call mpi_reduce( me(i)%nElems, globalnElems, &
& 1, mpi_integer, mpi_sum, proc%root, proc%comm, iErr)
call mpi_reduce( me(i)%val, buff, &
& nComp, rk_mpi, mpi_sum, proc%root, proc%comm, iErr)
if (proc%rank == proc%root) &
& me(i)%val(:) = buff / real( globalnElems, kind = rk)
!sum all values(sum of squares) and extract a square root
case('l2norm')
call mpi_reduce( me(i)%val, buff, &
& nComp, rk_mpi, mpi_sum, proc%root, proc%comm, iErr)
me(i)%val(:) = sqrt(buff)
!maximium over all values
case('max','linfnorm')
call mpi_reduce( me(i)%val, buff, &
& nComp, rk_mpi, mpi_max, proc%root, proc%comm, iErr)
me(i)%val = buff
!minimum over all values
case('min')
call mpi_reduce( me(i)%val, buff, &
& nComp, rk_mpi, mpi_min, proc%root, proc%comm, iErr)
me(i)%val = buff
!sum all values(sum of squares), normalize and extract a square root
case('l2normalized')
call mpi_reduce( me(i)%Vloc, Vglob, &
& 1, rk_mpi, mpi_sum, proc%root, proc%comm, iErr)
call mpi_reduce( me(i)%val, buff, &
& nComp, rk_mpi, mpi_sum, proc%root, proc%comm, iErr)
me(i)%val(:) = sqrt(buff/Vglob)
case default
end select
deallocate( buff )
enddo
end subroutine tem_reduction_spatial_close