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