Index: NEMO/branches/2020/dev_r12558_HPC-08_epico_Extra_Halo/src/OCE/LBC/lib_mpp.F90
===================================================================
--- NEMO/branches/2020/dev_r12558_HPC-08_epico_Extra_Halo/src/OCE/LBC/lib_mpp.F90	(revision 13229)
+++ NEMO/branches/2020/dev_r12558_HPC-08_epico_Extra_Halo/src/OCE/LBC/lib_mpp.F90	(revision 13247)
@@ -67,4 +67,6 @@
    PUBLIC   mpp_ini_znl
    PUBLIC   mppsend, mpprecv                          ! needed by TAM and ICB routines
+   PUBLIC   mppsend_sp, mpprecv_sp                          ! needed by TAM and ICB routines
+   PUBLIC   mppsend_dp, mpprecv_dp                          ! needed by TAM and ICB routines
    PUBLIC   mpp_report
    PUBLIC   mpp_bcast_nml
@@ -79,18 +81,26 @@
    !! for the compilation on AIX system as well as NEC and SGI. Ok on COMPACQ
    INTERFACE mpp_min
-      MODULE PROCEDURE mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real
+      MODULE PROCEDURE mppmin_a_int, mppmin_int
+      MODULE PROCEDURE mppmin_a_real_sp, mppmin_real_sp
+      MODULE PROCEDURE mppmin_a_real_dp, mppmin_real_dp
    END INTERFACE
    INTERFACE mpp_max
-      MODULE PROCEDURE mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real
+      MODULE PROCEDURE mppmax_a_int, mppmax_int
+      MODULE PROCEDURE mppmax_a_real_sp, mppmax_real_sp
+      MODULE PROCEDURE mppmax_a_real_dp, mppmax_real_dp
    END INTERFACE
    INTERFACE mpp_sum
-      MODULE PROCEDURE mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real,   &
-         &             mppsum_realdd, mppsum_a_realdd
+      MODULE PROCEDURE mppsum_a_int, mppsum_int
+      MODULE PROCEDURE mppsum_realdd, mppsum_a_realdd
+      MODULE PROCEDURE mppsum_a_real_sp, mppsum_real_sp
+      MODULE PROCEDURE mppsum_a_real_dp, mppsum_real_dp
    END INTERFACE
    INTERFACE mpp_minloc
-      MODULE PROCEDURE mpp_minloc2d ,mpp_minloc3d
+      MODULE PROCEDURE mpp_minloc2d_sp ,mpp_minloc3d_sp
+      MODULE PROCEDURE mpp_minloc2d_dp ,mpp_minloc3d_dp
    END INTERFACE
    INTERFACE mpp_maxloc
-      MODULE PROCEDURE mpp_maxloc2d ,mpp_maxloc3d
+      MODULE PROCEDURE mpp_maxloc2d_sp ,mpp_maxloc3d_sp
+      MODULE PROCEDURE mpp_maxloc2d_dp ,mpp_maxloc3d_dp
    END INTERFACE
 
@@ -158,5 +168,5 @@
    TYPE, PUBLIC ::   DELAYARR
       REAL(   wp), POINTER, DIMENSION(:) ::  z1d => NULL()
-      COMPLEX(wp), POINTER, DIMENSION(:) ::  y1d => NULL()
+      COMPLEX(dp), POINTER, DIMENSION(:) ::  y1d => NULL()
    END TYPE DELAYARR
    TYPE( DELAYARR ), DIMENSION(nbdelay), PUBLIC, SAVE  ::   todelay         !: must have SAVE for default initialization of DELAYARR
@@ -164,6 +174,6 @@
 
    ! timing summary report
-   REAL(wp), DIMENSION(2), PUBLIC ::  waiting_time = 0._wp
-   REAL(wp)              , PUBLIC ::  compute_time = 0._wp, elapsed_time = 0._wp
+   REAL(dp), DIMENSION(2), PUBLIC ::  waiting_time = 0._dp
+   REAL(dp)              , PUBLIC ::  compute_time = 0._dp, elapsed_time = 0._dp
    
    REAL(wp), DIMENSION(:), ALLOCATABLE, SAVE ::   tampon   ! buffer in case of bsend
@@ -251,4 +261,33 @@
       !!
       INTEGER ::   iflag
+      INTEGER :: mpi_working_type
+      !!----------------------------------------------------------------------
+      !
+#if defined key_mpp_mpi
+      IF (wp == dp) THEN
+         mpi_working_type = mpi_double_precision
+      ELSE
+         mpi_working_type = mpi_real
+      END IF
+      CALL mpi_isend( pmess, kbytes, mpi_working_type, kdest , ktyp, mpi_comm_oce, md_req, iflag )
+#endif
+      !
+   END SUBROUTINE mppsend
+
+
+   SUBROUTINE mppsend_dp( ktyp, pmess, kbytes, kdest, md_req )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mppsend  ***
+      !!
+      !! ** Purpose :   Send messag passing array
+      !!
+      !!----------------------------------------------------------------------
+      REAL(dp), INTENT(inout) ::   pmess(*)   ! array of real
+      INTEGER , INTENT(in   ) ::   kbytes     ! size of the array pmess
+      INTEGER , INTENT(in   ) ::   kdest      ! receive process number
+      INTEGER , INTENT(in   ) ::   ktyp       ! tag of the message
+      INTEGER , INTENT(in   ) ::   md_req     ! argument for isend
+      !!
+      INTEGER ::   iflag
       !!----------------------------------------------------------------------
       !
@@ -257,5 +296,28 @@
 #endif
       !
-   END SUBROUTINE mppsend
+   END SUBROUTINE mppsend_dp
+
+
+   SUBROUTINE mppsend_sp( ktyp, pmess, kbytes, kdest, md_req )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mppsend  ***
+      !!
+      !! ** Purpose :   Send messag passing array
+      !!
+      !!----------------------------------------------------------------------
+      REAL(sp), INTENT(inout) ::   pmess(*)   ! array of real
+      INTEGER , INTENT(in   ) ::   kbytes     ! size of the array pmess
+      INTEGER , INTENT(in   ) ::   kdest      ! receive process number
+      INTEGER , INTENT(in   ) ::   ktyp       ! tag of the message
+      INTEGER , INTENT(in   ) ::   md_req     ! argument for isend
+      !!
+      INTEGER ::   iflag
+      !!----------------------------------------------------------------------
+      !
+#if defined key_mpp_mpi
+      CALL mpi_isend( pmess, kbytes, mpi_real, kdest , ktyp, mpi_comm_oce, md_req, iflag )
+#endif
+      !
+   END SUBROUTINE mppsend_sp
 
 
@@ -275,4 +337,5 @@
       INTEGER :: iflag
       INTEGER :: use_source
+      INTEGER :: mpi_working_type
       !!----------------------------------------------------------------------
       !
@@ -283,8 +346,70 @@
       IF( PRESENT(ksource) )   use_source = ksource
       !
+      IF (wp == dp) THEN
+         mpi_working_type = mpi_double_precision
+      ELSE
+         mpi_working_type = mpi_real
+      END IF
+      CALL mpi_recv( pmess, kbytes, mpi_working_type, use_source, ktyp, mpi_comm_oce, istatus, iflag )
+#endif
+      !
+   END SUBROUTINE mpprecv
+
+   SUBROUTINE mpprecv_dp( ktyp, pmess, kbytes, ksource )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpprecv  ***
+      !!
+      !! ** Purpose :   Receive messag passing array
+      !!
+      !!----------------------------------------------------------------------
+      REAL(dp), INTENT(inout) ::   pmess(*)   ! array of real
+      INTEGER , INTENT(in   ) ::   kbytes     ! suze of the array pmess
+      INTEGER , INTENT(in   ) ::   ktyp       ! Tag of the recevied message
+      INTEGER, OPTIONAL, INTENT(in) :: ksource    ! source process number
+      !!
+      INTEGER :: istatus(mpi_status_size)
+      INTEGER :: iflag
+      INTEGER :: use_source
+      !!----------------------------------------------------------------------
+      !
+#if defined key_mpp_mpi
+      ! If a specific process number has been passed to the receive call,
+      ! use that one. Default is to use mpi_any_source
+      use_source = mpi_any_source
+      IF( PRESENT(ksource) )   use_source = ksource
+      !
       CALL mpi_recv( pmess, kbytes, mpi_double_precision, use_source, ktyp, mpi_comm_oce, istatus, iflag )
 #endif
       !
-   END SUBROUTINE mpprecv
+   END SUBROUTINE mpprecv_dp
+
+
+   SUBROUTINE mpprecv_sp( ktyp, pmess, kbytes, ksource )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpprecv  ***
+      !!
+      !! ** Purpose :   Receive messag passing array
+      !!
+      !!----------------------------------------------------------------------
+      REAL(sp), INTENT(inout) ::   pmess(*)   ! array of real
+      INTEGER , INTENT(in   ) ::   kbytes     ! suze of the array pmess
+      INTEGER , INTENT(in   ) ::   ktyp       ! Tag of the recevied message
+      INTEGER, OPTIONAL, INTENT(in) :: ksource    ! source process number
+      !!
+      INTEGER :: istatus(mpi_status_size)
+      INTEGER :: iflag
+      INTEGER :: use_source
+      !!----------------------------------------------------------------------
+      !
+#if defined key_mpp_mpi
+      ! If a specific process number has been passed to the receive call,
+      ! use that one. Default is to use mpi_any_source
+      use_source = mpi_any_source
+      IF( PRESENT(ksource) )   use_source = ksource
+      !
+      CALL mpi_recv( pmess, kbytes, mpi_real, use_source, ktyp, mpi_comm_oce, istatus, iflag )
+#endif
+      !
+   END SUBROUTINE mpprecv_sp
 
 
@@ -351,5 +476,5 @@
       CHARACTER(len=*), INTENT(in   )               ::   cdname  ! name of the calling subroutine
       CHARACTER(len=*), INTENT(in   )               ::   cdelay  ! name (used as id) of the delayed operation
-      COMPLEX(wp),      INTENT(in   ), DIMENSION(:) ::   y_in
+      COMPLEX(dp),      INTENT(in   ), DIMENSION(:) ::   y_in
       REAL(wp),         INTENT(  out), DIMENSION(:) ::   pout
       LOGICAL,          INTENT(in   )               ::   ldlast  ! true if this is the last time we call this routine
@@ -359,5 +484,5 @@
       INTEGER ::   idvar
       INTEGER ::   ierr, ilocalcomm
-      COMPLEX(wp), ALLOCATABLE, DIMENSION(:) ::   ytmp
+      COMPLEX(dp), ALLOCATABLE, DIMENSION(:) ::   ytmp
       !!----------------------------------------------------------------------
 #if defined key_mpp_mpi
@@ -432,6 +557,17 @@
       INTEGER ::   idvar
       INTEGER ::   ierr, ilocalcomm
-      !!----------------------------------------------------------------------
-#if defined key_mpp_mpi
+      INTEGER ::   MPI_TYPE
+      !!----------------------------------------------------------------------
+      
+#if defined key_mpp_mpi
+      if( wp == dp ) then
+         MPI_TYPE = MPI_DOUBLE_PRECISION
+      else if ( wp == sp ) then
+         MPI_TYPE = MPI_REAL
+      else
+        CALL ctl_stop( "Error defining type, wp is neither dp nor sp" )
+   
+      end if
+
       ilocalcomm = mpi_comm_oce
       IF( PRESENT(kcom) )   ilocalcomm = kcom
@@ -470,9 +606,8 @@
 # if defined key_mpi2
       IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.)
-      CALL  mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ierr )
-      ndelayid(idvar) = 1
+      CALL  mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_TYPE, mpi_max, ilocalcomm, ndelayid(idvar), ierr )
       IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.)
 # else
-      CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr )
+      CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_TYPE, mpi_max, ilocalcomm, ndelayid(idvar), ierr )
 # endif
 #else
@@ -551,12 +686,32 @@
 #  undef INTEGER_TYPE
 !
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+#  define SINGLE_PRECISION
 #  define REAL_TYPE
 #  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppmax_real
+#     define ROUTINE_ALLREDUCE           mppmax_real_sp
 #     include "mpp_allreduce_generic.h90"
 #     undef ROUTINE_ALLREDUCE
 #  undef DIM_0d
 #  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppmax_a_real
+#     define ROUTINE_ALLREDUCE           mppmax_a_real_sp
+#     include "mpp_allreduce_generic.h90"
+#     undef ROUTINE_ALLREDUCE
+#  undef DIM_1d
+#  undef SINGLE_PRECISION
+   !!
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+!
+#  define DIM_0d
+#     define ROUTINE_ALLREDUCE           mppmax_real_dp
+#     include "mpp_allreduce_generic.h90"
+#     undef ROUTINE_ALLREDUCE
+#  undef DIM_0d
+#  define DIM_1d
+#     define ROUTINE_ALLREDUCE           mppmax_a_real_dp
 #     include "mpp_allreduce_generic.h90"
 #     undef ROUTINE_ALLREDUCE
@@ -583,12 +738,31 @@
 #  undef INTEGER_TYPE
 !
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+#  define SINGLE_PRECISION
 #  define REAL_TYPE
 #  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppmin_real
+#     define ROUTINE_ALLREDUCE           mppmin_real_sp
 #     include "mpp_allreduce_generic.h90"
 #     undef ROUTINE_ALLREDUCE
 #  undef DIM_0d
 #  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppmin_a_real
+#     define ROUTINE_ALLREDUCE           mppmin_a_real_sp
+#     include "mpp_allreduce_generic.h90"
+#     undef ROUTINE_ALLREDUCE
+#  undef DIM_1d
+#  undef SINGLE_PRECISION
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+
+#  define DIM_0d
+#     define ROUTINE_ALLREDUCE           mppmin_real_dp
+#     include "mpp_allreduce_generic.h90"
+#     undef ROUTINE_ALLREDUCE
+#  undef DIM_0d
+#  define DIM_1d
+#     define ROUTINE_ALLREDUCE           mppmin_a_real_dp
 #     include "mpp_allreduce_generic.h90"
 #     undef ROUTINE_ALLREDUCE
@@ -616,13 +790,38 @@
 #  undef DIM_1d
 #  undef INTEGER_TYPE
-!
+
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+#  define OPERATION_SUM
+#  define SINGLE_PRECISION
 #  define REAL_TYPE
 #  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppsum_real
+#     define ROUTINE_ALLREDUCE           mppsum_real_sp
 #     include "mpp_allreduce_generic.h90"
 #     undef ROUTINE_ALLREDUCE
 #  undef DIM_0d
 #  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppsum_a_real
+#     define ROUTINE_ALLREDUCE           mppsum_a_real_sp
+#     include "mpp_allreduce_generic.h90"
+#     undef ROUTINE_ALLREDUCE
+#  undef DIM_1d
+#  undef REAL_TYPE
+#  undef OPERATION_SUM
+
+#  undef SINGLE_PRECISION
+
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+#  define OPERATION_SUM
+#  define REAL_TYPE
+#  define DIM_0d
+#     define ROUTINE_ALLREDUCE           mppsum_real_dp
+#     include "mpp_allreduce_generic.h90"
+#     undef ROUTINE_ALLREDUCE
+#  undef DIM_0d
+#  define DIM_1d
+#     define ROUTINE_ALLREDUCE           mppsum_a_real_dp
 #     include "mpp_allreduce_generic.h90"
 #     undef ROUTINE_ALLREDUCE
@@ -651,12 +850,16 @@
    !!----------------------------------------------------------------------
    !!
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+#  define SINGLE_PRECISION
 #  define OPERATION_MINLOC
 #  define DIM_2d
-#     define ROUTINE_LOC           mpp_minloc2d
+#     define ROUTINE_LOC           mpp_minloc2d_sp
 #     include "mpp_loc_generic.h90"
 #     undef ROUTINE_LOC
 #  undef DIM_2d
 #  define DIM_3d
-#     define ROUTINE_LOC           mpp_minloc3d
+#     define ROUTINE_LOC           mpp_minloc3d_sp
 #     include "mpp_loc_generic.h90"
 #     undef ROUTINE_LOC
@@ -666,14 +869,44 @@
 #  define OPERATION_MAXLOC
 #  define DIM_2d
-#     define ROUTINE_LOC           mpp_maxloc2d
+#     define ROUTINE_LOC           mpp_maxloc2d_sp
 #     include "mpp_loc_generic.h90"
 #     undef ROUTINE_LOC
 #  undef DIM_2d
 #  define DIM_3d
-#     define ROUTINE_LOC           mpp_maxloc3d
+#     define ROUTINE_LOC           mpp_maxloc3d_sp
 #     include "mpp_loc_generic.h90"
 #     undef ROUTINE_LOC
 #  undef DIM_3d
 #  undef OPERATION_MAXLOC
+#  undef SINGLE_PRECISION
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+#  define OPERATION_MINLOC
+#  define DIM_2d
+#     define ROUTINE_LOC           mpp_minloc2d_dp
+#     include "mpp_loc_generic.h90"
+#     undef ROUTINE_LOC
+#  undef DIM_2d
+#  define DIM_3d
+#     define ROUTINE_LOC           mpp_minloc3d_dp
+#     include "mpp_loc_generic.h90"
+#     undef ROUTINE_LOC
+#  undef DIM_3d
+#  undef OPERATION_MINLOC
+
+#  define OPERATION_MAXLOC
+#  define DIM_2d
+#     define ROUTINE_LOC           mpp_maxloc2d_dp
+#     include "mpp_loc_generic.h90"
+#     undef ROUTINE_LOC
+#  undef DIM_2d
+#  define DIM_3d
+#     define ROUTINE_LOC           mpp_maxloc3d_dp
+#     include "mpp_loc_generic.h90"
+#     undef ROUTINE_LOC
+#  undef DIM_3d
+#  undef OPERATION_MAXLOC
+
 
    SUBROUTINE mppsync()
@@ -904,8 +1137,8 @@
       !!---------------------------------------------------------------------
       INTEGER                     , INTENT(in)    ::   ilen, itype
-      COMPLEX(wp), DIMENSION(ilen), INTENT(in)    ::   ydda
-      COMPLEX(wp), DIMENSION(ilen), INTENT(inout) ::   yddb
-      !
-      REAL(wp) :: zerr, zt1, zt2    ! local work variables
+      COMPLEX(dp), DIMENSION(ilen), INTENT(in)    ::   ydda
+      COMPLEX(dp), DIMENSION(ilen), INTENT(inout) ::   yddb
+      !
+      REAL(dp) :: zerr, zt1, zt2    ! local work variables
       INTEGER  :: ji, ztmp           ! local scalar
       !!---------------------------------------------------------------------
@@ -1060,6 +1293,6 @@
     LOGICAL,           INTENT(IN) :: ld_tic
     LOGICAL, OPTIONAL, INTENT(IN) :: ld_global
-    REAL(wp), DIMENSION(2), SAVE :: tic_wt
-    REAL(wp),               SAVE :: tic_ct = 0._wp
+    REAL(dp), DIMENSION(2), SAVE :: tic_wt
+    REAL(dp),               SAVE :: tic_ct = 0._dp
     INTEGER :: ii
 #if defined key_mpp_mpi
@@ -1074,5 +1307,5 @@
     IF ( ld_tic ) THEN
        tic_wt(ii) = MPI_Wtime()                                                    ! start count tic->tac (waiting time)
-       IF ( tic_ct > 0.0_wp ) compute_time = compute_time + MPI_Wtime() - tic_ct   ! cumulate count tac->tic
+       IF ( tic_ct > 0.0_dp ) compute_time = compute_time + MPI_Wtime() - tic_ct   ! cumulate count tac->tic
     ELSE
        waiting_time(ii) = waiting_time(ii) + MPI_Wtime() - tic_wt(ii)              ! cumulate count tic->tac
