123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 |
- MODULE lib_fortran
- !!======================================================================
- !! *** MODULE lib_fortran ***
- !! Fortran utilities: includes some low levels fortran functionality
- !!======================================================================
- !! History : 3.2 ! 2010-05 (M. Dunphy, R. Benshila) Original code
- !! 3.4 ! 2013-06 (C. Rousset) add glob_min, glob_max
- !! + 3d dim. of input is fexible (jpk, jpl...)
- !!----------------------------------------------------------------------
- !!----------------------------------------------------------------------
- !! glob_sum : generic interface for global masked summation over
- !! the interior domain for 1 or 2 2D or 3D arrays
- !! it works only for T points
- !! SIGN : generic interface for SIGN to overwrite f95 behaviour
- !! of intrinsinc sign function
- !!----------------------------------------------------------------------
- USE par_oce ! Ocean parameter
- USE dom_oce ! ocean domain
- USE in_out_manager ! I/O manager
- USE lib_mpp ! distributed memory computing
- IMPLICIT NONE
- PRIVATE
- PUBLIC glob_sum ! used in many places
- PUBLIC DDPDD ! also used in closea module
- PUBLIC glob_min, glob_max
- #if defined key_nosignedzero
- PUBLIC SIGN
- #endif
- INTERFACE glob_sum
- MODULE PROCEDURE glob_sum_1d, glob_sum_2d, glob_sum_3d, &
- & glob_sum_2d_a, glob_sum_3d_a
- END INTERFACE
- INTERFACE glob_min
- MODULE PROCEDURE glob_min_2d, glob_min_3d,glob_min_2d_a, glob_min_3d_a
- END INTERFACE
- INTERFACE glob_max
- MODULE PROCEDURE glob_max_2d, glob_max_3d,glob_max_2d_a, glob_max_3d_a
- END INTERFACE
- #if defined key_nosignedzero
- INTERFACE SIGN
- MODULE PROCEDURE SIGN_SCALAR, SIGN_ARRAY_1D, SIGN_ARRAY_2D, SIGN_ARRAY_3D, &
- & SIGN_ARRAY_1D_A, SIGN_ARRAY_2D_A, SIGN_ARRAY_3D_A, &
- & SIGN_ARRAY_1D_B, SIGN_ARRAY_2D_B, SIGN_ARRAY_3D_B
- END INTERFACE
- #endif
- !!----------------------------------------------------------------------
- !! NEMO/OPA 3.3 , NEMO Consortium (2010)
- !! $Id: lib_fortran.F90 4161 2013-11-07 10:01:27Z cetlod $
- !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
- !!----------------------------------------------------------------------
- CONTAINS
- #if ! defined key_mpp_rep
- ! --- SUM ---
- FUNCTION glob_sum_1d( ptab, kdim )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_1D ***
- !!
- !! ** Purpose : perform a masked sum on the inner global domain of a 1D array
- !!-----------------------------------------------------------------------
- INTEGER :: kdim
- REAL(wp), INTENT(in), DIMENSION(kdim) :: ptab ! input 1D array
- REAL(wp) :: glob_sum_1d ! global sum
- !!-----------------------------------------------------------------------
- !
- glob_sum_1d = SUM( ptab(:) )
- IF( lk_mpp ) CALL mpp_sum( glob_sum_1d )
- !
- END FUNCTION glob_sum_1d
- FUNCTION glob_sum_2d( ptab )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_2D ***
- !!
- !! ** Purpose : perform a masked sum on the inner global domain of a 2D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab ! input 2D array
- REAL(wp) :: glob_sum_2d ! global masked sum
- !!-----------------------------------------------------------------------
- !
- glob_sum_2d = SUM( ptab(:,:)*tmask_i(:,:) )
- IF( lk_mpp ) CALL mpp_sum( glob_sum_2d )
- !
- END FUNCTION glob_sum_2d
- FUNCTION glob_sum_3d( ptab )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_3D ***
- !!
- !! ** Purpose : perform a masked sum on the inner global domain of a 3D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab ! input 3D array
- REAL(wp) :: glob_sum_3d ! global masked sum
- !!
- INTEGER :: jk
- INTEGER :: ijpk ! local variable: size of the 3d dimension of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab,3)
- !
- glob_sum_3d = 0.e0
- DO jk = 1, ijpk
- glob_sum_3d = glob_sum_3d + SUM( ptab(:,:,jk)*tmask_i(:,:) )
- END DO
- IF( lk_mpp ) CALL mpp_sum( glob_sum_3d )
- !
- END FUNCTION glob_sum_3d
- FUNCTION glob_sum_2d_a( ptab1, ptab2 )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_2D _a ***
- !!
- !! ** Purpose : perform a masked sum on the inner global domain of two 2D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab1, ptab2 ! input 2D array
- REAL(wp) , DIMENSION(2) :: glob_sum_2d_a ! global masked sum
- !!-----------------------------------------------------------------------
- !
- glob_sum_2d_a(1) = SUM( ptab1(:,:)*tmask_i(:,:) )
- glob_sum_2d_a(2) = SUM( ptab2(:,:)*tmask_i(:,:) )
- IF( lk_mpp ) CALL mpp_sum( glob_sum_2d_a, 2 )
- !
- END FUNCTION glob_sum_2d_a
- FUNCTION glob_sum_3d_a( ptab1, ptab2 )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_3D_a ***
- !!
- !! ** Purpose : perform a masked sum on the inner global domain of two 3D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab1, ptab2 ! input 3D array
- REAL(wp) , DIMENSION(2) :: glob_sum_3d_a ! global masked sum
- !!
- INTEGER :: jk
- INTEGER :: ijpk ! local variable: size of the 3d dimension of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab1,3)
- !
- glob_sum_3d_a(:) = 0.e0
- DO jk = 1, ijpk
- glob_sum_3d_a(1) = glob_sum_3d_a(1) + SUM( ptab1(:,:,jk)*tmask_i(:,:) )
- glob_sum_3d_a(2) = glob_sum_3d_a(2) + SUM( ptab2(:,:,jk)*tmask_i(:,:) )
- END DO
- IF( lk_mpp ) CALL mpp_sum( glob_sum_3d_a, 2 )
- !
- END FUNCTION glob_sum_3d_a
- #else
- !!----------------------------------------------------------------------
- !! 'key_mpp_rep' MPP reproducibility
- !!----------------------------------------------------------------------
-
- ! --- SUM ---
- FUNCTION glob_sum_1d( ptab, kdim )
- !!----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_1d ***
- !!
- !! ** Purpose : perform a sum in calling DDPDD routine
- !!----------------------------------------------------------------------
- INTEGER , INTENT(in) :: kdim
- REAL(wp), INTENT(in), DIMENSION(kdim) :: ptab
- REAL(wp) :: glob_sum_1d ! global sum
- !!
- COMPLEX(wp):: ctmp
- REAL(wp) :: ztmp
- INTEGER :: ji ! dummy loop indices
- !!-----------------------------------------------------------------------
- !
- ztmp = 0.e0
- ctmp = CMPLX( 0.e0, 0.e0, wp )
- DO ji = 1, kdim
- ztmp = ptab(ji)
- CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
- END DO
- IF( lk_mpp ) CALL mpp_sum( ctmp ) ! sum over the global domain
- glob_sum_1d = REAL(ctmp,wp)
- !
- END FUNCTION glob_sum_1d
- FUNCTION glob_sum_2d( ptab )
- !!----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_2d ***
- !!
- !! ** Purpose : perform a sum in calling DDPDD routine
- !!----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab
- REAL(wp) :: glob_sum_2d ! global masked sum
- !!
- COMPLEX(wp):: ctmp
- REAL(wp) :: ztmp
- INTEGER :: ji, jj ! dummy loop indices
- !!-----------------------------------------------------------------------
- !
- ztmp = 0.e0
- ctmp = CMPLX( 0.e0, 0.e0, wp )
- DO jj = 1, jpj
- DO ji =1, jpi
- ztmp = ptab(ji,jj) * tmask_i(ji,jj)
- CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
- END DO
- END DO
- IF( lk_mpp ) CALL mpp_sum( ctmp ) ! sum over the global domain
- glob_sum_2d = REAL(ctmp,wp)
- !
- END FUNCTION glob_sum_2d
- FUNCTION glob_sum_3d( ptab )
- !!----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_3d ***
- !!
- !! ** Purpose : perform a sum on a 3D array in calling DDPDD routine
- !!----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab
- REAL(wp) :: glob_sum_3d ! global masked sum
- !!
- COMPLEX(wp):: ctmp
- REAL(wp) :: ztmp
- INTEGER :: ji, jj, jk ! dummy loop indices
- INTEGER :: ijpk ! local variables: size of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab,3)
- !
- ztmp = 0.e0
- ctmp = CMPLX( 0.e0, 0.e0, wp )
- DO jk = 1, ijpk
- DO jj = 1, jpj
- DO ji =1, jpi
- ztmp = ptab(ji,jj,jk) * tmask_i(ji,jj)
- CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
- END DO
- END DO
- END DO
- IF( lk_mpp ) CALL mpp_sum( ctmp ) ! sum over the global domain
- glob_sum_3d = REAL(ctmp,wp)
- !
- END FUNCTION glob_sum_3d
- FUNCTION glob_sum_2d_a( ptab1, ptab2 )
- !!----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_2d_a ***
- !!
- !! ** Purpose : perform a sum on two 2D arrays in calling DDPDD routine
- !!----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab1, ptab2
- REAL(wp) :: glob_sum_2d_a ! global masked sum
- !!
- COMPLEX(wp):: ctmp
- REAL(wp) :: ztmp
- INTEGER :: ji, jj ! dummy loop indices
- !!-----------------------------------------------------------------------
- !
- ztmp = 0.e0
- ctmp = CMPLX( 0.e0, 0.e0, wp )
- DO jj = 1, jpj
- DO ji =1, jpi
- ztmp = ptab1(ji,jj) * tmask_i(ji,jj)
- CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
- ztmp = ptab2(ji,jj) * tmask_i(ji,jj)
- CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
- END DO
- END DO
- IF( lk_mpp ) CALL mpp_sum( ctmp ) ! sum over the global domain
- glob_sum_2d_a = REAL(ctmp,wp)
- !
- END FUNCTION glob_sum_2d_a
- FUNCTION glob_sum_3d_a( ptab1, ptab2 )
- !!----------------------------------------------------------------------
- !! *** FUNCTION glob_sum_3d_a ***
- !!
- !! ** Purpose : perform a sum on two 3D array in calling DDPDD routine
- !!----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab1, ptab2
- REAL(wp) :: glob_sum_3d_a ! global masked sum
- !!
- COMPLEX(wp):: ctmp
- REAL(wp) :: ztmp
- INTEGER :: ji, jj, jk ! dummy loop indices
- INTEGER :: ijpk ! local variables: size of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab1,3)
- !
- ztmp = 0.e0
- ctmp = CMPLX( 0.e0, 0.e0, wp )
- DO jk = 1, ijpk
- DO jj = 1, jpj
- DO ji = 1, jpi
- ztmp = ptab1(ji,jj,jk) * tmask_i(ji,jj)
- CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
- ztmp = ptab2(ji,jj,jk) * tmask_i(ji,jj)
- CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
- END DO
- END DO
- END DO
- IF( lk_mpp ) CALL mpp_sum( ctmp ) ! sum over the global domain
- glob_sum_3d_a = REAL(ctmp,wp)
- !
- END FUNCTION glob_sum_3d_a
- #endif
- ! --- MIN ---
- FUNCTION glob_min_2d( ptab )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_min_2D ***
- !!
- !! ** Purpose : perform a masked min on the inner global domain of a 2D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab ! input 2D array
- REAL(wp) :: glob_min_2d ! global masked min
- !!-----------------------------------------------------------------------
- !
- glob_min_2d = MINVAL( ptab(:,:)*tmask_i(:,:) )
- IF( lk_mpp ) CALL mpp_min( glob_min_2d )
- !
- END FUNCTION glob_min_2d
-
- FUNCTION glob_min_3d( ptab )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_min_3D ***
- !!
- !! ** Purpose : perform a masked min on the inner global domain of a 3D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab ! input 3D array
- REAL(wp) :: glob_min_3d ! global masked min
- !!
- INTEGER :: jk
- INTEGER :: ijpk ! local variable: size of the 3d dimension of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab,3)
- !
- glob_min_3d = MINVAL( ptab(:,:,1)*tmask_i(:,:) )
- DO jk = 2, ijpk
- glob_min_3d = MIN( glob_min_3d, MINVAL( ptab(:,:,jk)*tmask_i(:,:) ) )
- END DO
- IF( lk_mpp ) CALL mpp_min( glob_min_3d )
- !
- END FUNCTION glob_min_3d
- FUNCTION glob_min_2d_a( ptab1, ptab2 )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_min_2D _a ***
- !!
- !! ** Purpose : perform a masked min on the inner global domain of two 2D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab1, ptab2 ! input 2D array
- REAL(wp) , DIMENSION(2) :: glob_min_2d_a ! global masked min
- !!-----------------------------------------------------------------------
- !
- glob_min_2d_a(1) = MINVAL( ptab1(:,:)*tmask_i(:,:) )
- glob_min_2d_a(2) = MINVAL( ptab2(:,:)*tmask_i(:,:) )
- IF( lk_mpp ) CALL mpp_min( glob_min_2d_a, 2 )
- !
- END FUNCTION glob_min_2d_a
-
-
- FUNCTION glob_min_3d_a( ptab1, ptab2 )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_min_3D_a ***
- !!
- !! ** Purpose : perform a masked min on the inner global domain of two 3D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab1, ptab2 ! input 3D array
- REAL(wp) , DIMENSION(2) :: glob_min_3d_a ! global masked min
- !!
- INTEGER :: jk
- INTEGER :: ijpk ! local variable: size of the 3d dimension of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab1,3)
- !
- glob_min_3d_a(1) = MINVAL( ptab1(:,:,1)*tmask_i(:,:) )
- glob_min_3d_a(2) = MINVAL( ptab2(:,:,1)*tmask_i(:,:) )
- DO jk = 2, ijpk
- glob_min_3d_a(1) = MIN( glob_min_3d_a(1), MINVAL( ptab1(:,:,jk)*tmask_i(:,:) ) )
- glob_min_3d_a(2) = MIN( glob_min_3d_a(2), MINVAL( ptab2(:,:,jk)*tmask_i(:,:) ) )
- END DO
- IF( lk_mpp ) CALL mpp_min( glob_min_3d_a, 2 )
- !
- END FUNCTION glob_min_3d_a
- ! --- MAX ---
- FUNCTION glob_max_2d( ptab )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_max_2D ***
- !!
- !! ** Purpose : perform a masked max on the inner global domain of a 2D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab ! input 2D array
- REAL(wp) :: glob_max_2d ! global masked max
- !!-----------------------------------------------------------------------
- !
- glob_max_2d = MAXVAL( ptab(:,:)*tmask_i(:,:) )
- IF( lk_mpp ) CALL mpp_max( glob_max_2d )
- !
- END FUNCTION glob_max_2d
-
- FUNCTION glob_max_3d( ptab )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_max_3D ***
- !!
- !! ** Purpose : perform a masked max on the inner global domain of a 3D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab ! input 3D array
- REAL(wp) :: glob_max_3d ! global masked max
- !!
- INTEGER :: jk
- INTEGER :: ijpk ! local variable: size of the 3d dimension of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab,3)
- !
- glob_max_3d = MAXVAL( ptab(:,:,1)*tmask_i(:,:) )
- DO jk = 2, ijpk
- glob_max_3d = MAX( glob_max_3d, MAXVAL( ptab(:,:,jk)*tmask_i(:,:) ) )
- END DO
- IF( lk_mpp ) CALL mpp_max( glob_max_3d )
- !
- END FUNCTION glob_max_3d
- FUNCTION glob_max_2d_a( ptab1, ptab2 )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_max_2D _a ***
- !!
- !! ** Purpose : perform a masked max on the inner global domain of two 2D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:) :: ptab1, ptab2 ! input 2D array
- REAL(wp) , DIMENSION(2) :: glob_max_2d_a ! global masked max
- !!-----------------------------------------------------------------------
- !
- glob_max_2d_a(1) = MAXVAL( ptab1(:,:)*tmask_i(:,:) )
- glob_max_2d_a(2) = MAXVAL( ptab2(:,:)*tmask_i(:,:) )
- IF( lk_mpp ) CALL mpp_max( glob_max_2d_a, 2 )
- !
- END FUNCTION glob_max_2d_a
-
-
- FUNCTION glob_max_3d_a( ptab1, ptab2 )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION glob_max_3D_a ***
- !!
- !! ** Purpose : perform a masked max on the inner global domain of two 3D array
- !!-----------------------------------------------------------------------
- REAL(wp), INTENT(in), DIMENSION(:,:,:) :: ptab1, ptab2 ! input 3D array
- REAL(wp) , DIMENSION(2) :: glob_max_3d_a ! global masked max
- !!
- INTEGER :: jk
- INTEGER :: ijpk ! local variable: size of the 3d dimension of ptab
- !!-----------------------------------------------------------------------
- !
- ijpk = SIZE(ptab1,3)
- !
- glob_max_3d_a(1) = MAXVAL( ptab1(:,:,1)*tmask_i(:,:) )
- glob_max_3d_a(2) = MAXVAL( ptab2(:,:,1)*tmask_i(:,:) )
- DO jk = 2, ijpk
- glob_max_3d_a(1) = MAX( glob_max_3d_a(1), MAXVAL( ptab1(:,:,jk)*tmask_i(:,:) ) )
- glob_max_3d_a(2) = MAX( glob_max_3d_a(2), MAXVAL( ptab2(:,:,jk)*tmask_i(:,:) ) )
- END DO
- IF( lk_mpp ) CALL mpp_max( glob_max_3d_a, 2 )
- !
- END FUNCTION glob_max_3d_a
- SUBROUTINE DDPDD( ydda, yddb )
- !!----------------------------------------------------------------------
- !! *** ROUTINE DDPDD ***
- !!
- !! ** Purpose : Add a scalar element to a sum
- !!
- !!
- !! ** Method : The code uses the compensated summation with doublet
- !! (sum,error) emulated useing complex numbers. ydda is the
- !! scalar to add to the summ yddb
- !!
- !! ** Action : This does only work for MPI.
- !!
- !! References : Using Acurate Arithmetics to Improve Numerical
- !! Reproducibility and Sability in Parallel Applications
- !! Yun HE and Chris H. Q. DING, Journal of Supercomputing 18, 259-277, 2001
- !!----------------------------------------------------------------------
- COMPLEX(wp), INTENT(in ) :: ydda
- COMPLEX(wp), INTENT(inout) :: yddb
- !
- REAL(wp) :: zerr, zt1, zt2 ! local work variables
- !!-----------------------------------------------------------------------
- !
- ! Compute ydda + yddb using Knuth's trick.
- zt1 = REAL(ydda) + REAL(yddb)
- zerr = zt1 - REAL(ydda)
- zt2 = ( (REAL(yddb) - zerr) + (REAL(ydda) - (zt1 - zerr)) ) &
- & + AIMAG(ydda) + AIMAG(yddb)
- !
- ! The result is t1 + t2, after normalization.
- yddb = CMPLX( zt1 + zt2, zt2 - ((zt1 + zt2) - zt1), wp )
- !
- END SUBROUTINE DDPDD
- #if defined key_nosignedzero
- !!----------------------------------------------------------------------
- !! 'key_nosignedzero' F90 SIGN
- !!----------------------------------------------------------------------
- FUNCTION SIGN_SCALAR( pa, pb )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_SCALAR ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa,pb ! input
- REAL(wp) :: SIGN_SCALAR ! result
- !!-----------------------------------------------------------------------
- IF ( pb >= 0.e0) THEN ; SIGN_SCALAR = ABS(pa)
- ELSE ; SIGN_SCALAR =-ABS(pa)
- ENDIF
- END FUNCTION SIGN_SCALAR
- FUNCTION SIGN_ARRAY_1D( pa, pb )
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_1D ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa,pb(:) ! input
- REAL(wp) :: SIGN_ARRAY_1D(SIZE(pb,1)) ! result
- !!-----------------------------------------------------------------------
- WHERE ( pb >= 0.e0 ) ; SIGN_ARRAY_1D = ABS(pa)
- ELSEWHERE ; SIGN_ARRAY_1D =-ABS(pa)
- END WHERE
- END FUNCTION SIGN_ARRAY_1D
- FUNCTION SIGN_ARRAY_2D(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_2D ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa,pb(:,:) ! input
- REAL(wp) :: SIGN_ARRAY_2D(SIZE(pb,1),SIZE(pb,2)) ! result
- !!-----------------------------------------------------------------------
- WHERE ( pb >= 0.e0 ) ; SIGN_ARRAY_2D = ABS(pa)
- ELSEWHERE ; SIGN_ARRAY_2D =-ABS(pa)
- END WHERE
- END FUNCTION SIGN_ARRAY_2D
- FUNCTION SIGN_ARRAY_3D(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_3D ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa,pb(:,:,:) ! input
- REAL(wp) :: SIGN_ARRAY_3D(SIZE(pb,1),SIZE(pb,2),SIZE(pb,3)) ! result
- !!-----------------------------------------------------------------------
- WHERE ( pb >= 0.e0 ) ; SIGN_ARRAY_3D = ABS(pa)
- ELSEWHERE ; SIGN_ARRAY_3D =-ABS(pa)
- END WHERE
- END FUNCTION SIGN_ARRAY_3D
- FUNCTION SIGN_ARRAY_1D_A(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_1D_A ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa(:),pb(:) ! input
- REAL(wp) :: SIGN_ARRAY_1D_A(SIZE(pb,1)) ! result
- !!-----------------------------------------------------------------------
- WHERE ( pb >= 0.e0 ) ; SIGN_ARRAY_1D_A = ABS(pa)
- ELSEWHERE ; SIGN_ARRAY_1D_A =-ABS(pa)
- END WHERE
- END FUNCTION SIGN_ARRAY_1D_A
- FUNCTION SIGN_ARRAY_2D_A(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_2D_A ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa(:,:),pb(:,:) ! input
- REAL(wp) :: SIGN_ARRAY_2D_A(SIZE(pb,1),SIZE(pb,2)) ! result
- !!-----------------------------------------------------------------------
- WHERE ( pb >= 0.e0 ) ; SIGN_ARRAY_2D_A = ABS(pa)
- ELSEWHERE ; SIGN_ARRAY_2D_A =-ABS(pa)
- END WHERE
- END FUNCTION SIGN_ARRAY_2D_A
- FUNCTION SIGN_ARRAY_3D_A(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_3D_A ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa(:,:,:),pb(:,:,:) ! input
- REAL(wp) :: SIGN_ARRAY_3D_A(SIZE(pb,1),SIZE(pb,2),SIZE(pb,3)) ! result
- !!-----------------------------------------------------------------------
- WHERE ( pb >= 0.e0 ) ; SIGN_ARRAY_3D_A = ABS(pa)
- ELSEWHERE ; SIGN_ARRAY_3D_A =-ABS(pa)
- END WHERE
- END FUNCTION SIGN_ARRAY_3D_A
- FUNCTION SIGN_ARRAY_1D_B(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_1D_B ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa(:),pb ! input
- REAL(wp) :: SIGN_ARRAY_1D_B(SIZE(pa,1)) ! result
- !!-----------------------------------------------------------------------
- IF( pb >= 0.e0 ) THEN ; SIGN_ARRAY_1D_B = ABS(pa)
- ELSE ; SIGN_ARRAY_1D_B =-ABS(pa)
- ENDIF
- END FUNCTION SIGN_ARRAY_1D_B
- FUNCTION SIGN_ARRAY_2D_B(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_2D_B ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa(:,:),pb ! input
- REAL(wp) :: SIGN_ARRAY_2D_B(SIZE(pa,1),SIZE(pa,2)) ! result
- !!-----------------------------------------------------------------------
- IF( pb >= 0.e0 ) THEN ; SIGN_ARRAY_2D_B = ABS(pa)
- ELSE ; SIGN_ARRAY_2D_B =-ABS(pa)
- ENDIF
- END FUNCTION SIGN_ARRAY_2D_B
- FUNCTION SIGN_ARRAY_3D_B(pa,pb)
- !!-----------------------------------------------------------------------
- !! *** FUNCTION SIGN_ARRAY_3D_B ***
- !!
- !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
- !!-----------------------------------------------------------------------
- REAL(wp) :: pa(:,:,:),pb ! input
- REAL(wp) :: SIGN_ARRAY_3D_B(SIZE(pa,1),SIZE(pa,2),SIZE(pa,3)) ! result
- !!-----------------------------------------------------------------------
- IF( pb >= 0.e0 ) THEN ; SIGN_ARRAY_3D_B = ABS(pa)
- ELSE ; SIGN_ARRAY_3D_B =-ABS(pa)
- ENDIF
- END FUNCTION SIGN_ARRAY_3D_B
- #endif
- !!======================================================================
- END MODULE lib_fortran
|