! SPDX-FileCopyrightText: FLEXPART 1998-2019, see flexpart_license.txt ! SPDX-License-Identifier: GPL-3.0-or-later module mean_mod public ! Interface to select single or double precision version of the 'mean' ! function from type of input arguments ("function overloading") !******************************************************************** interface mean module procedure mean_sp module procedure mean_dp module procedure mean_mixed_dss module procedure mean_mixed_dsd end interface mean contains subroutine mean_sp(x_sp,xm,xs,number) !***************************************************************************** ! * ! This subroutine calculates mean and standard deviation of a given element.* ! * ! AUTHOR: Andreas Stohl, 25 January 1994 * ! * ! Single precision version ESO 2016 * !***************************************************************************** ! * ! Variables: * ! x_sp(number) field of input data * ! xm mean * ! xs standard deviation * ! number number of elements of field x_sp * ! * ! Constants: * ! eps tiny number * ! * !***************************************************************************** use par_mod, only: sp implicit none ! integer :: number,i ! real(sp) :: x_sp(number),xm,xs,xl,xq,xaux ! real(sp),parameter :: eps=1.0e-30 integer,intent(in) :: number real(sp), intent(in) :: x_sp(number) real(sp), intent(out) ::xm,xs real(sp) :: xl,xq,xaux real(sp),parameter :: eps=1.0e-30 integer :: i xl=0. xq=0. do i=1,number xl=xl+x_sp(i) xq=xq+x_sp(i)*x_sp(i) end do xm=xl/real(number,kind=sp) xaux=xq-xl*xl/real(number,kind=sp) if (xaux.lt.eps) then xs=0. else xs=sqrt(xaux/real(number-1,kind=sp)) endif end subroutine mean_sp subroutine mean_dp(x_dp,xm,xs,number) !***************************************************************************** ! * ! This subroutine calculates mean and standard deviation of a given element.* ! * ! AUTHOR: Andreas Stohl, 25 January 1994 * ! * ! Double precision version ESO 2016 * !***************************************************************************** ! * ! Variables: * ! x_dp(number) field of input data * ! xm mean * ! xs standard deviation * ! number number of elements of field x_dp * ! * ! Constants: * ! eps tiny number * ! * !***************************************************************************** use par_mod, only: dp implicit none integer,intent(in) :: number real(dp), intent(in) :: x_dp(number) real(dp), intent(out) ::xm,xs real(dp) :: xl,xq,xaux real(dp),parameter :: eps=1.0e-30 integer :: i xl=0._dp xq=0._dp do i=1,number xl=xl+x_dp(i) xq=xq+x_dp(i)*x_dp(i) end do xm=xl/real(number,kind=dp) xaux=xq-xl*xl/real(number,kind=dp) if (xaux.lt.eps) then xs=0._dp else xs=sqrt(xaux/real(number-1,kind=dp)) endif end subroutine mean_dp subroutine mean_mixed_dss(x_dp,xm,xs,number) !***************************************************************************** ! * ! This subroutine calculates mean and standard deviation of a given element.* ! * ! AUTHOR: Andreas Stohl, 25 January 1994 * ! * ! Mixed precision version ESO 2016 (dp in, sp out, sp out) * !***************************************************************************** ! * ! Variables: * ! x_dp(number) field of input data * ! xm mean * ! xs standard deviation * ! number number of elements of field x_dp * ! * ! Constants: * ! eps tiny number * ! * !***************************************************************************** use par_mod, only: sp,dp implicit none integer,intent(in) :: number real(dp), intent(in) :: x_dp(number) real(sp), intent(out) ::xm,xs real(sp) :: xl,xq,xaux real(sp),parameter :: eps=1.0e-30 integer :: i xl=0._sp xq=0._sp do i=1,number xl=xl+real(x_dp(i),kind=sp) xq=xq+real(x_dp(i),kind=sp)*real(x_dp(i),kind=sp) end do xm=xl/real(number,kind=sp) xaux=xq-xl*xl/real(number,kind=sp) if (xaux.lt.eps) then xs=0._sp else xs=sqrt(xaux/real(number-1,kind=sp)) endif end subroutine mean_mixed_dss subroutine mean_mixed_dsd(x_dp,xm,xs_dp,number) !***************************************************************************** ! * ! This subroutine calculates mean and standard deviation of a given element.* ! * ! AUTHOR: Andreas Stohl, 25 January 1994 * ! * ! Mixed precision version ESO 2016 (dp in, sp out, dp out) * !***************************************************************************** ! * ! Variables: * ! x_dp(number) field of input data * ! xm mean * ! xs_dp standard deviation * ! number number of elements of field x_dp * ! * ! Constants: * ! eps tiny number * ! * !***************************************************************************** use par_mod, only: sp,dp implicit none integer,intent(in) :: number real(dp), intent(in) :: x_dp(number) real(sp), intent(out) ::xm real(dp), intent(out) ::xs_dp real(dp) :: xl,xq,xaux real(dp),parameter :: eps=1.0e-30_dp integer :: i xl=0._dp xq=0._dp do i=1,number xl=xl+x_dp(i) xq=xq+x_dp(i)*x_dp(i) end do xm=real(xl,kind=sp)/real(number,kind=sp) xaux=xq-xl*xl/real(number,kind=dp) if (xaux.lt.eps) then xs_dp=0._dp else xs_dp=sqrt(xaux/real(number-1,kind=dp)) endif end subroutine mean_mixed_dsd end module mean_mod