New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
lib_fortran.F90 in NEMO/branches/2020/dev_r14116_HPC-04_mcastril_Mixed_Precision_implementation_final/src/OCE – NEMO

source: NEMO/branches/2020/dev_r14116_HPC-04_mcastril_Mixed_Precision_implementation_final/src/OCE/lib_fortran.F90 @ 14644

Last change on this file since 14644 was 14644, checked in by sparonuz, 3 years ago

Merge trunk -r14642:HEAD

  • Property svn:keywords set to Id
File size: 20.3 KB
RevLine 
[2003]1MODULE lib_fortran
2   !!======================================================================
3   !!                       ***  MODULE  lib_fortran  ***
4   !! Fortran utilities:  includes some low levels fortran functionality
5   !!======================================================================
[2307]6   !! History :  3.2  !  2010-05  (M. Dunphy, R. Benshila)  Original code
[4161]7   !!            3.4  !  2013-06  (C. Rousset)  add glob_min, glob_max
8   !!                                           + 3d dim. of input is fexible (jpk, jpl...)
[7646]9   !!            4.0  !  2016-06  (T. Lovato)  double precision global sum by default
[2003]10   !!----------------------------------------------------------------------
[2307]11
[2003]12   !!----------------------------------------------------------------------
[3764]13   !!   glob_sum    : generic interface for global masked summation over
[2307]14   !!                 the interior domain for 1 or 2 2D or 3D arrays
[3764]15   !!                 it works only for T points
[2307]16   !!   SIGN        : generic interface for SIGN to overwrite f95 behaviour
17   !!                 of intrinsinc sign function
18   !!----------------------------------------------------------------------
[3632]19   USE par_oce         ! Ocean parameter
20   USE dom_oce         ! ocean domain
21   USE in_out_manager  ! I/O manager
22   USE lib_mpp         ! distributed memory computing
[10425]23   USE lbclnk          ! ocean lateral boundary conditions
[2003]24
25   IMPLICIT NONE
26   PRIVATE
27
[6140]28   PUBLIC   glob_sum      ! used in many places (masked with tmask_i)
[7646]29   PUBLIC   glob_sum_full ! used in many places (masked with tmask_h, ie only over the halos)
[10425]30   PUBLIC   local_sum     ! used in trcrad, local operation before glob_sum_delay
31   PUBLIC   sum3x3        ! used in trcrad, do a sum over 3x3 boxes
[6140]32   PUBLIC   DDPDD         ! also used in closea module
[4161]33   PUBLIC   glob_min, glob_max
[2341]34#if defined key_nosignedzero
[2003]35   PUBLIC SIGN
36#endif
37
38   INTERFACE glob_sum
[14219]39      MODULE PROCEDURE glob_sum_1d_sp, glob_sum_2d_sp, glob_sum_3d_sp
40      MODULE PROCEDURE glob_sum_1d_dp, glob_sum_2d_dp, glob_sum_3d_dp
[2003]41   END INTERFACE
[6140]42   INTERFACE glob_sum_full
[14219]43      MODULE PROCEDURE glob_sum_full_2d_sp, glob_sum_full_3d_sp
44      MODULE PROCEDURE glob_sum_full_2d_dp, glob_sum_full_3d_dp
[6140]45   END INTERFACE
[10425]46   INTERFACE local_sum
47      MODULE PROCEDURE local_sum_2d, local_sum_3d
48   END INTERFACE
49   INTERFACE sum3x3
50      MODULE PROCEDURE sum3x3_2d, sum3x3_3d
51   END INTERFACE
[4161]52   INTERFACE glob_min
[14219]53      MODULE PROCEDURE glob_min_2d_sp, glob_min_3d_sp
54      MODULE PROCEDURE glob_min_2d_dp, glob_min_3d_dp
[4161]55   END INTERFACE
56   INTERFACE glob_max
[14219]57      MODULE PROCEDURE glob_max_2d_sp, glob_max_3d_sp
58      MODULE PROCEDURE glob_max_2d_dp, glob_max_3d_dp
[4161]59   END INTERFACE
[2003]60
[3764]61#if defined key_nosignedzero
[2003]62   INTERFACE SIGN
[2307]63      MODULE PROCEDURE SIGN_SCALAR, SIGN_ARRAY_1D, SIGN_ARRAY_2D, SIGN_ARRAY_3D,   &
[3764]64         &             SIGN_ARRAY_1D_A, SIGN_ARRAY_2D_A, SIGN_ARRAY_3D_A,          &
65         &             SIGN_ARRAY_1D_B, SIGN_ARRAY_2D_B, SIGN_ARRAY_3D_B
[2003]66   END INTERFACE
67#endif
68
[12377]69   !! * Substitutions
70#  include "do_loop_substitute.h90"
[2307]71   !!----------------------------------------------------------------------
[9598]72   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
[3764]73   !! $Id$
[10068]74   !! Software governed by the CeCILL license (see ./LICENSE)
[2307]75   !!----------------------------------------------------------------------
[3764]76CONTAINS
[2003]77
[3764]78
[14286]79!                          ! FUNCTION global_sum !
80!                          ! single precision version !
81# define PRECISION sp
82# include "lib_fortran_globsum.h90"
83# undef PRECISION
84!                          ! double precision version !
85# define PRECISION dp
86# include "lib_fortran_globsum.h90"
87# undef PRECISION
[2307]88
[10425]89!                          ! FUNCTION local_sum !
90
91   FUNCTION local_sum_2d( ptab )
[2307]92      !!----------------------------------------------------------------------
[10425]93      REAL(wp),  INTENT(in   ) ::   ptab(:,:) ! array on which operation is applied
[13226]94      COMPLEX(dp)              ::  local_sum_2d
[10425]95      !
[2003]96      !!-----------------------------------------------------------------------
[2307]97      !
[13226]98      COMPLEX(dp)::   ctmp
[2307]99      REAL(wp)   ::   ztmp
[10425]100      INTEGER    ::   ji, jj    ! dummy loop indices
101      INTEGER    ::   ipi, ipj  ! dimensions
[2307]102      !!-----------------------------------------------------------------------
103      !
[10425]104      ipi = SIZE(ptab,1)   ! 1st dimension
105      ipj = SIZE(ptab,2)   ! 2nd dimension
[4161]106      !
[10425]107      ctmp = CMPLX( 0.e0, 0.e0, wp )   ! warning ctmp is cumulated
108
109      DO jj = 1, ipj
110         DO ji = 1, ipi
111            ztmp =  ptab(ji,jj) * tmask_i(ji,jj)
[13226]112            CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp )
[10425]113         END DO
[2307]114      END DO
115      !
[10425]116      local_sum_2d = ctmp
117       
118   END FUNCTION local_sum_2d
[2307]119
[10425]120   FUNCTION local_sum_3d( ptab )
[6140]121      !!----------------------------------------------------------------------
[10425]122      REAL(wp),  INTENT(in   ) ::   ptab(:,:,:) ! array on which operation is applied
[13226]123      COMPLEX(dp)              ::  local_sum_3d
[10425]124      !
[6140]125      !!-----------------------------------------------------------------------
126      !
[13226]127      COMPLEX(dp)::   ctmp
[6140]128      REAL(wp)   ::   ztmp
129      INTEGER    ::   ji, jj, jk   ! dummy loop indices
[10425]130      INTEGER    ::   ipi, ipj, ipk    ! dimensions
[6140]131      !!-----------------------------------------------------------------------
132      !
[10425]133      ipi = SIZE(ptab,1)   ! 1st dimension
134      ipj = SIZE(ptab,2)   ! 2nd dimension
135      ipk = SIZE(ptab,3)   ! 3rd dimension
[6140]136      !
[10425]137      ctmp = CMPLX( 0.e0, 0.e0, wp )   ! warning ctmp is cumulated
[6140]138
[10425]139      DO jk = 1, ipk
140        DO jj = 1, ipj
141          DO ji = 1, ipi
142             ztmp =  ptab(ji,jj,jk) * tmask_i(ji,jj)
[13226]143             CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp )
[10425]144          END DO
145        END DO
[4161]146      END DO
147      !
[10425]148      local_sum_3d = ctmp
149       
150   END FUNCTION local_sum_3d
[4161]151
[10425]152!                          ! FUNCTION sum3x3 !
[4161]153
[10425]154   SUBROUTINE sum3x3_2d( p2d )
[4161]155      !!-----------------------------------------------------------------------
[10425]156      !!                  ***  routine sum3x3_2d  ***
[4161]157      !!
[10425]158      !! ** Purpose : sum over 3x3 boxes
159      !!----------------------------------------------------------------------
160      REAL(wp), DIMENSION (:,:), INTENT(inout) ::   p2d
[4161]161      !
[10425]162      INTEGER ::   ji, ji2, jj, jj2     ! dummy loop indices
163      !!----------------------------------------------------------------------
[4161]164      !
[10425]165      IF( SIZE(p2d,1) /= jpi ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_2d, the first dimension is not equal to jpi' ) 
166      IF( SIZE(p2d,2) /= jpj ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_2d, the second dimension is not equal to jpj' ) 
[4161]167      !
[13324]168      ! work over the whole domain (guarantees all internal cells are set when nn_hls=2)
169      !
170      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
[14644]171         IF( MOD(mig(ji), 3) == MOD(nn_hls, 3) .AND.   &              ! 1st bottom left corner always at (Nis0-1, Njs0-1)
[13327]172           & MOD(mjg(jj), 3) == MOD(nn_hls, 3)         ) THEN         ! bottom left corner of a 3x3 box
[12377]173            ji2 = MIN(mig(ji)+2, jpiglo) - nimpp + 1                  ! right position of the box
174            jj2 = MIN(mjg(jj)+2, jpjglo) - njmpp + 1                  ! upper position of the box
175            IF( ji2 <= jpi .AND. jj2 <= jpj ) THEN                    ! the box is fully included in the local mpi domain
176               p2d(ji:ji2,jj:jj2) = SUM(p2d(ji:ji2,jj:jj2))
[10425]177            ENDIF
[12377]178         ENDIF
179      END_2D
[13226]180      CALL lbc_lnk( 'lib_fortran', p2d, 'T', 1.0_wp )
[14644]181      ! no need for 2nd exchange when nn_hls > 1
182      IF( nn_hls == 1 ) THEN
183         IF( mpiRnei(nn_hls,jpwe) > -1 ) THEN   ! 1st column was changed during the previous call to lbc_lnk
184            IF( MOD(mig(    1), 3) == 1 )   &   ! 1st box start at i=1 -> column 1 to 3 correctly computed locally
185               p2d(    1,:) = p2d(    2,:)      ! previous lbc_lnk corrupted column 1 -> put it back using column 2
186            IF( MOD(mig(    1), 3) == 2 )   &   ! 1st box start at i=3 -> column 1 and 2 correctly computed on west neighbourh
187               p2d(    2,:) = p2d(    1,:)      !  previous lbc_lnk fix column 1 -> copy it to column 2
[13324]188         ENDIF
[14644]189         IF( mpiRnei(nn_hls,jpea) > -1 ) THEN
[13324]190            IF( MOD(mig(jpi-2), 3) == 1 )   p2d(  jpi,:) = p2d(jpi-1,:)
191            IF( MOD(mig(jpi-2), 3) == 0 )   p2d(jpi-1,:) = p2d(  jpi,:)
192         ENDIF
[14644]193         IF( mpiRnei(nn_hls,jpso) > -1 ) THEN
[13324]194            IF( MOD(mjg(    1), 3) == 1 )   p2d(:,    1) = p2d(:,    2)
195            IF( MOD(mjg(    1), 3) == 2 )   p2d(:,    2) = p2d(:,    1)
196         ENDIF
[14644]197         IF( mpiRnei(nn_hls,jpno) > -1 ) THEN
[13324]198            IF( MOD(mjg(jpj-2), 3) == 1 )   p2d(:,  jpj) = p2d(:,jpj-1)
199            IF( MOD(mjg(jpj-2), 3) == 0 )   p2d(:,jpj-1) = p2d(:,  jpj)
200         ENDIF
201         CALL lbc_lnk( 'lib_fortran', p2d, 'T', 1.0_wp )
[10425]202      ENDIF
[4161]203
[10425]204   END SUBROUTINE sum3x3_2d
205
206   SUBROUTINE sum3x3_3d( p3d )
[4161]207      !!-----------------------------------------------------------------------
[10425]208      !!                  ***  routine sum3x3_3d  ***
[4161]209      !!
[10425]210      !! ** Purpose : sum over 3x3 boxes
211      !!----------------------------------------------------------------------
212      REAL(wp), DIMENSION (:,:,:), INTENT(inout) ::   p3d
[4161]213      !
[10425]214      INTEGER ::   ji, ji2, jj, jj2, jn     ! dummy loop indices
215      INTEGER ::   ipn                      ! Third dimension size
216      !!----------------------------------------------------------------------
[4161]217      !
[10425]218      IF( SIZE(p3d,1) /= jpi ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_3d, the first dimension is not equal to jpi' ) 
219      IF( SIZE(p3d,2) /= jpj ) CALL ctl_stop( 'STOP', 'wrong call of sum3x3_3d, the second dimension is not equal to jpj' ) 
220      ipn = SIZE(p3d,3)
[4161]221      !
[10425]222      DO jn = 1, ipn
[13324]223         !
224         ! work over the whole domain (guarantees all internal cells are set when nn_hls=2)
225         !
226         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
[14644]227            IF( MOD(mig(ji), 3) == MOD(nn_hls, 3) .AND.   &              ! 1st bottom left corner always at (Nis0-1, Njs0-1)
[13327]228              & MOD(mjg(jj), 3) == MOD(nn_hls, 3)         ) THEN         ! bottom left corner of a 3x3 box
[12377]229               ji2 = MIN(mig(ji)+2, jpiglo) - nimpp + 1                  ! right position of the box
230               jj2 = MIN(mjg(jj)+2, jpjglo) - njmpp + 1                  ! upper position of the box
231               IF( ji2 <= jpi .AND. jj2 <= jpj ) THEN                    ! the box is fully included in the local mpi domain
232                  p3d(ji:ji2,jj:jj2,jn) = SUM(p3d(ji:ji2,jj:jj2,jn))
[10425]233               ENDIF
[12377]234            ENDIF
235         END_2D
[4161]236      END DO
[13226]237      CALL lbc_lnk( 'lib_fortran', p3d, 'T', 1.0_wp )
[14644]238      ! no need for 2nd exchange when nn_hls > 1
239      IF( nn_hls == 1 ) THEN
240         IF( mpiRnei(nn_hls,jpwe) > -1 ) THEN    ! 1st column was changed during the previous call to lbc_lnk
241            IF( MOD(mig(    1), 3) == 1 )   &    ! 1st box start at i=1 -> column 1 to 3 correctly computed locally
242               p3d(    1,:,:) = p3d(    2,:,:)   ! previous lbc_lnk corrupted column 1 -> put it back using column 2
243            IF( MOD(mig(    1), 3) == 2 )   &    ! 1st box start at i=3 -> column 1 and 2 correctly computed on west neighbourh
244               p3d(    2,:,:) = p3d(    1,:,:)   !  previous lbc_lnk fix column 1 -> copy it to column 2
[13324]245         ENDIF
[14644]246         IF( mpiRnei(nn_hls,jpea) > -1 ) THEN
[13324]247            IF( MOD(mig(jpi-2), 3) == 1 )   p3d(  jpi,:,:) = p3d(jpi-1,:,:)
248            IF( MOD(mig(jpi-2), 3) == 0 )   p3d(jpi-1,:,:) = p3d(  jpi,:,:)
249         ENDIF
[14644]250         IF( mpiRnei(nn_hls,jpso) > -1 ) THEN
[13324]251            IF( MOD(mjg(    1), 3) == 1 )   p3d(:,    1,:) = p3d(:,    2,:)
252            IF( MOD(mjg(    1), 3) == 2 )   p3d(:,    2,:) = p3d(:,    1,:)
253         ENDIF
[14644]254         IF( mpiRnei(nn_hls,jpno) > -1 ) THEN
[13324]255            IF( MOD(mjg(jpj-2), 3) == 1 )   p3d(:,  jpj,:) = p3d(:,jpj-1,:)
256            IF( MOD(mjg(jpj-2), 3) == 0 )   p3d(:,jpj-1,:) = p3d(:,  jpj,:)
257         ENDIF
258         CALL lbc_lnk( 'lib_fortran', p3d, 'T', 1.0_wp )
[10425]259      ENDIF
[4161]260
[10425]261   END SUBROUTINE sum3x3_3d
[4161]262
263
[2003]264   SUBROUTINE DDPDD( ydda, yddb )
265      !!----------------------------------------------------------------------
266      !!               ***  ROUTINE DDPDD ***
[3764]267      !!
[2003]268      !! ** Purpose : Add a scalar element to a sum
269      !!
[3764]270      !!
271      !! ** Method  : The code uses the compensated summation with doublet
[2003]272      !!              (sum,error) emulated useing complex numbers. ydda is the
[3764]273      !!               scalar to add to the summ yddb
[2003]274      !!
[3764]275      !! ** Action  : This does only work for MPI.
276      !!
[2003]277      !! References : Using Acurate Arithmetics to Improve Numerical
278      !!              Reproducibility and Sability in Parallel Applications
[3764]279      !!              Yun HE and Chris H. Q. DING, Journal of Supercomputing 18, 259-277, 2001
[2003]280      !!----------------------------------------------------------------------
[13226]281      COMPLEX(dp), INTENT(in   ) ::   ydda
282      COMPLEX(dp), INTENT(inout) ::   yddb
[2307]283      !
[13226]284      REAL(dp) :: zerr, zt1, zt2  ! local work variables
[2307]285      !!-----------------------------------------------------------------------
286      !
[2003]287      ! Compute ydda + yddb using Knuth's trick.
[2307]288      zt1  = REAL(ydda) + REAL(yddb)
289      zerr = zt1 - REAL(ydda)
290      zt2  = ( (REAL(yddb) - zerr) + (REAL(ydda) - (zt1 - zerr)) )   &
291         &   + AIMAG(ydda)         + AIMAG(yddb)
292      !
[2003]293      ! The result is t1 + t2, after normalization.
[2307]294      yddb = CMPLX( zt1 + zt2, zt2 - ((zt1 + zt2) - zt1), wp )
295      !
[2003]296   END SUBROUTINE DDPDD
297
298#if defined key_nosignedzero
[2307]299   !!----------------------------------------------------------------------
300   !!   'key_nosignedzero'                                         F90 SIGN
301   !!----------------------------------------------------------------------
[3764]302
[2307]303   FUNCTION SIGN_SCALAR( pa, pb )
[2003]304      !!-----------------------------------------------------------------------
305      !!                  ***  FUNCTION SIGN_SCALAR  ***
306      !!
307      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
308      !!-----------------------------------------------------------------------
309      REAL(wp) :: pa,pb          ! input
[2307]310      REAL(wp) :: SIGN_SCALAR    ! result
311      !!-----------------------------------------------------------------------
312      IF ( pb >= 0.e0) THEN   ;   SIGN_SCALAR = ABS(pa)
313      ELSE                    ;   SIGN_SCALAR =-ABS(pa)
[2003]314      ENDIF
315   END FUNCTION SIGN_SCALAR
316
[2307]317
[3764]318   FUNCTION SIGN_ARRAY_1D( pa, pb )
[2003]319      !!-----------------------------------------------------------------------
320      !!                  ***  FUNCTION SIGN_ARRAY_1D  ***
321      !!
322      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
323      !!-----------------------------------------------------------------------
[2307]324      REAL(wp) :: pa,pb(:)                   ! input
[2003]325      REAL(wp) :: SIGN_ARRAY_1D(SIZE(pb,1))  ! result
[2307]326      !!-----------------------------------------------------------------------
327      WHERE ( pb >= 0.e0 )   ;   SIGN_ARRAY_1D = ABS(pa)
328      ELSEWHERE              ;   SIGN_ARRAY_1D =-ABS(pa)
[2003]329      END WHERE
330   END FUNCTION SIGN_ARRAY_1D
331
[2307]332
[3764]333   FUNCTION SIGN_ARRAY_2D(pa,pb)
[2003]334      !!-----------------------------------------------------------------------
335      !!                  ***  FUNCTION SIGN_ARRAY_2D  ***
336      !!
337      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
338      !!-----------------------------------------------------------------------
339      REAL(wp) :: pa,pb(:,:)      ! input
340      REAL(wp) :: SIGN_ARRAY_2D(SIZE(pb,1),SIZE(pb,2))  ! result
[2307]341      !!-----------------------------------------------------------------------
342      WHERE ( pb >= 0.e0 )   ;   SIGN_ARRAY_2D = ABS(pa)
343      ELSEWHERE              ;   SIGN_ARRAY_2D =-ABS(pa)
[2003]344      END WHERE
345   END FUNCTION SIGN_ARRAY_2D
346
[3764]347   FUNCTION SIGN_ARRAY_3D(pa,pb)
[2003]348      !!-----------------------------------------------------------------------
349      !!                  ***  FUNCTION SIGN_ARRAY_3D  ***
350      !!
351      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
352      !!-----------------------------------------------------------------------
353      REAL(wp) :: pa,pb(:,:,:)      ! input
354      REAL(wp) :: SIGN_ARRAY_3D(SIZE(pb,1),SIZE(pb,2),SIZE(pb,3))  ! result
[2307]355      !!-----------------------------------------------------------------------
356      WHERE ( pb >= 0.e0 )   ;   SIGN_ARRAY_3D = ABS(pa)
357      ELSEWHERE              ;   SIGN_ARRAY_3D =-ABS(pa)
[2003]358      END WHERE
359   END FUNCTION SIGN_ARRAY_3D
360
[2307]361
[3764]362   FUNCTION SIGN_ARRAY_1D_A(pa,pb)
[2003]363      !!-----------------------------------------------------------------------
364      !!                  ***  FUNCTION SIGN_ARRAY_1D_A  ***
365      !!
366      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
367      !!-----------------------------------------------------------------------
368      REAL(wp) :: pa(:),pb(:)      ! input
[2307]369      REAL(wp) :: SIGN_ARRAY_1D_A(SIZE(pb,1))  ! result
370      !!-----------------------------------------------------------------------
371      WHERE ( pb >= 0.e0 )   ;   SIGN_ARRAY_1D_A = ABS(pa)
372      ELSEWHERE              ;   SIGN_ARRAY_1D_A =-ABS(pa)
[2003]373      END WHERE
374   END FUNCTION SIGN_ARRAY_1D_A
375
[2307]376
[3764]377   FUNCTION SIGN_ARRAY_2D_A(pa,pb)
[2003]378      !!-----------------------------------------------------------------------
379      !!                  ***  FUNCTION SIGN_ARRAY_2D_A  ***
380      !!
381      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
382      !!-----------------------------------------------------------------------
383      REAL(wp) :: pa(:,:),pb(:,:)      ! input
384      REAL(wp) :: SIGN_ARRAY_2D_A(SIZE(pb,1),SIZE(pb,2))  ! result
[2307]385      !!-----------------------------------------------------------------------
386      WHERE ( pb >= 0.e0 )   ;   SIGN_ARRAY_2D_A = ABS(pa)
387      ELSEWHERE              ;   SIGN_ARRAY_2D_A =-ABS(pa)
[2003]388      END WHERE
389   END FUNCTION SIGN_ARRAY_2D_A
390
[2307]391
[3764]392   FUNCTION SIGN_ARRAY_3D_A(pa,pb)
[2003]393      !!-----------------------------------------------------------------------
394      !!                  ***  FUNCTION SIGN_ARRAY_3D_A  ***
395      !!
396      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
397      !!-----------------------------------------------------------------------
398      REAL(wp) :: pa(:,:,:),pb(:,:,:)  ! input
399      REAL(wp) :: SIGN_ARRAY_3D_A(SIZE(pb,1),SIZE(pb,2),SIZE(pb,3)) ! result
[2307]400      !!-----------------------------------------------------------------------
401      WHERE ( pb >= 0.e0 )   ;   SIGN_ARRAY_3D_A = ABS(pa)
402      ELSEWHERE              ;   SIGN_ARRAY_3D_A =-ABS(pa)
[2003]403      END WHERE
404   END FUNCTION SIGN_ARRAY_3D_A
405
[2307]406
[3764]407   FUNCTION SIGN_ARRAY_1D_B(pa,pb)
[2003]408      !!-----------------------------------------------------------------------
409      !!                  ***  FUNCTION SIGN_ARRAY_1D_B  ***
410      !!
411      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
412      !!-----------------------------------------------------------------------
413      REAL(wp) :: pa(:),pb      ! input
414      REAL(wp) :: SIGN_ARRAY_1D_B(SIZE(pa,1))  ! result
[2307]415      !!-----------------------------------------------------------------------
416      IF( pb >= 0.e0 ) THEN   ;   SIGN_ARRAY_1D_B = ABS(pa)
417      ELSE                    ;   SIGN_ARRAY_1D_B =-ABS(pa)
[2003]418      ENDIF
419   END FUNCTION SIGN_ARRAY_1D_B
420
[2307]421
[3764]422   FUNCTION SIGN_ARRAY_2D_B(pa,pb)
[2003]423      !!-----------------------------------------------------------------------
424      !!                  ***  FUNCTION SIGN_ARRAY_2D_B  ***
425      !!
426      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
427      !!-----------------------------------------------------------------------
428      REAL(wp) :: pa(:,:),pb      ! input
429      REAL(wp) :: SIGN_ARRAY_2D_B(SIZE(pa,1),SIZE(pa,2))  ! result
[2307]430      !!-----------------------------------------------------------------------
431      IF( pb >= 0.e0 ) THEN   ;   SIGN_ARRAY_2D_B = ABS(pa)
432      ELSE                    ;   SIGN_ARRAY_2D_B =-ABS(pa)
[2003]433      ENDIF
434   END FUNCTION SIGN_ARRAY_2D_B
435
[2307]436
[3764]437   FUNCTION SIGN_ARRAY_3D_B(pa,pb)
[2003]438      !!-----------------------------------------------------------------------
439      !!                  ***  FUNCTION SIGN_ARRAY_3D_B  ***
440      !!
441      !! ** Purpose : overwrite f95 behaviour of intrinsinc sign function
442      !!-----------------------------------------------------------------------
443      REAL(wp) :: pa(:,:,:),pb      ! input
444      REAL(wp) :: SIGN_ARRAY_3D_B(SIZE(pa,1),SIZE(pa,2),SIZE(pa,3))  ! result
[2307]445      !!-----------------------------------------------------------------------
446      IF( pb >= 0.e0 ) THEN   ;   SIGN_ARRAY_3D_B = ABS(pa)
447      ELSE                    ;   SIGN_ARRAY_3D_B =-ABS(pa)
[2003]448      ENDIF
449   END FUNCTION SIGN_ARRAY_3D_B
450#endif
451
[2307]452   !!======================================================================
[2003]453END MODULE lib_fortran
Note: See TracBrowser for help on using the repository browser.