Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/FLO/floblk.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/FLO/floblk.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/FLO/floblk.F90	(revision 12603)
@@ -175,5 +175,5 @@
             zgidfl(jfl) = float(iioutfl(jfl) - iiinfl(jfl))
             IF( zufl(jfl)*zuoutfl <= 0. ) THEN
-               ztxfl(jfl) = 1.E99_wp
+               ztxfl(jfl) = HUGE(0.0_wp)
             ELSE
                IF( ABS(zudfl(jfl)) >= 1.E-5 ) THEN
@@ -191,5 +191,5 @@
             zgjdfl(jfl) = float(ijoutfl(jfl)-ijinfl(jfl))
             IF( zvfl(jfl)*zvoutfl <= 0. ) THEN
-               ztyfl(jfl) = 1.E99_wp
+               ztyfl(jfl) = HUGE(0.0_wp)
             ELSE
                IF( ABS(zvdfl(jfl)) >= 1.E-5 ) THEN
@@ -208,5 +208,5 @@
                zgkdfl(jfl) = float(ikoutfl(jfl) - ikinfl(jfl))
                IF( zwfl(jfl)*zwoutfl <= 0. ) THEN
-                  ztzfl(jfl) = 1.E99_wp
+                  ztzfl(jfl) = HUGE(0.0_wp)
                ELSE
                   IF( ABS(zwdfl(jfl)) >= 1.E-5 ) THEN
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/ICB/icbthm.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/ICB/icbthm.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/ICB/icbthm.F90	(revision 12603)
@@ -57,10 +57,10 @@
       TYPE(point)  , POINTER ::   pt
       !
-      COMPLEX(wp), DIMENSION(jpi,jpj) :: cicb_melt, cicb_hflx
+      COMPLEX(dp), DIMENSION(jpi,jpj) :: cicb_melt, cicb_hflx
       !!----------------------------------------------------------------------
       !
       !! initialiaze cicb_melt and cicb_heat
-      cicb_melt = CMPLX( 0.e0, 0.e0, wp ) 
-      cicb_hflx = CMPLX( 0.e0, 0.e0, wp ) 
+      cicb_melt = CMPLX( 0.e0, 0.e0, dp ) 
+      cicb_hflx = CMPLX( 0.e0, 0.e0, dp ) 
       !
       z1_rday = 1._wp / rday
@@ -176,5 +176,5 @@
             !! the use of DDPDD function for the cumulative sum is needed for reproducibility
             zmelt    = ( zdM - ( zdMbitsE - zdMbitsM ) ) * z1_dt   ! kg/s
-            CALL DDPDD( CMPLX( zmelt * z1_e1e2, 0.e0, wp ), cicb_melt(ii,ij) )
+            CALL DDPDD( CMPLX( zmelt * z1_e1e2, 0.e0, dp ), cicb_melt(ii,ij) )
             !
             ! iceberg heat flux
@@ -185,5 +185,5 @@
             zheat_hcflux = zmelt * pt%heat_density       ! heat content flux : kg/s x J/kg = J/s
             zheat_latent = - zmelt * rLfus               ! latent heat flux:  kg/s x J/kg = J/s
-            CALL DDPDD( CMPLX( ( zheat_hcflux + zheat_latent ) * z1_e1e2, 0.e0, wp ), cicb_hflx(ii,ij) )
+            CALL DDPDD( CMPLX( ( zheat_hcflux + zheat_latent ) * z1_e1e2, 0.e0, dp ), cicb_hflx(ii,ij) )
             !
             ! diagnostics
@@ -230,6 +230,6 @@
       END DO
       !
-      berg_grid%floating_melt = REAL(cicb_melt,wp)    ! kg/m2/s
-      berg_grid%calving_hflx  = REAL(cicb_hflx,wp)
+      berg_grid%floating_melt = REAL(cicb_melt,dp)    ! kg/m2/s
+      berg_grid%calving_hflx  = REAL(cicb_hflx,dp)
       !
       ! now use melt and associated heat flux in ocean (or not)
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/IOM/iom.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/IOM/iom.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/IOM/iom.F90	(revision 12603)
@@ -59,7 +59,11 @@
    PUBLIC iom_use, iom_context_finalize, iom_update_file_name, iom_miss_val
 
-   PRIVATE iom_rp0d, iom_rp1d, iom_rp2d, iom_rp3d
-   PRIVATE iom_g0d, iom_g1d, iom_g2d, iom_g3d, iom_get_123d
-   PRIVATE iom_p1d, iom_p2d, iom_p3d, iom_p4d
+   PRIVATE iom_rp0d_sp, iom_rp1d_sp, iom_rp2d_sp, iom_rp3d_sp
+   PRIVATE iom_rp0d_dp, iom_rp1d_dp, iom_rp2d_dp, iom_rp3d_dp
+   PRIVATE iom_get_123d
+   PRIVATE iom_g0d_sp, iom_g1d_sp, iom_g2d_sp, iom_g3d_sp
+   PRIVATE iom_g0d_dp, iom_g1d_dp, iom_g2d_dp, iom_g3d_dp
+   PRIVATE iom_p1d_sp, iom_p2d_sp, iom_p3d_sp, iom_p4d_sp
+   PRIVATE iom_p1d_dp, iom_p2d_dp, iom_p3d_dp, iom_p4d_dp
 #if defined key_iomput
    PRIVATE iom_set_domain_attr, iom_set_axis_attr, iom_set_field_attr, iom_set_file_attr, iom_get_file_attr, iom_set_grid_attr
@@ -70,5 +74,6 @@
 
    INTERFACE iom_get
-      MODULE PROCEDURE iom_g0d, iom_g1d, iom_g2d, iom_g3d
+      MODULE PROCEDURE iom_g0d_sp, iom_g1d_sp, iom_g2d_sp, iom_g3d_sp
+      MODULE PROCEDURE iom_g0d_dp, iom_g1d_dp, iom_g2d_dp, iom_g3d_dp
    END INTERFACE
    INTERFACE iom_getatt
@@ -79,8 +84,10 @@
    END INTERFACE
    INTERFACE iom_rstput
-      MODULE PROCEDURE iom_rp0d, iom_rp1d, iom_rp2d, iom_rp3d
+      MODULE PROCEDURE iom_rp0d_sp, iom_rp1d_sp, iom_rp2d_sp, iom_rp3d_sp
+      MODULE PROCEDURE iom_rp0d_dp, iom_rp1d_dp, iom_rp2d_dp, iom_rp3d_dp
    END INTERFACE
    INTERFACE iom_put
-      MODULE PROCEDURE iom_p0d, iom_p1d, iom_p2d, iom_p3d, iom_p4d
+      MODULE PROCEDURE iom_p0d_sp, iom_p1d_sp, iom_p2d_sp, iom_p3d_sp, iom_p4d_sp
+      MODULE PROCEDURE iom_p0d_dp, iom_p1d_dp, iom_p2d_dp, iom_p3d_dp, iom_p4d_dp
    END INTERFACE iom_put
   
@@ -169,8 +176,8 @@
          !
          IF( ln_cfmeta ) THEN   ! Add additional grid metadata
-            CALL iom_set_domain_attr("grid_T", area = e1e2t(nldi:nlei, nldj:nlej))
-            CALL iom_set_domain_attr("grid_U", area = e1e2u(nldi:nlei, nldj:nlej))
-            CALL iom_set_domain_attr("grid_V", area = e1e2v(nldi:nlei, nldj:nlej))
-            CALL iom_set_domain_attr("grid_W", area = e1e2t(nldi:nlei, nldj:nlej))
+            CALL iom_set_domain_attr("grid_T", area = real( e1e2t(nldi:nlei, nldj:nlej), dp))
+            CALL iom_set_domain_attr("grid_U", area = real( e1e2u(nldi:nlei, nldj:nlej), dp))
+            CALL iom_set_domain_attr("grid_V", area = real( e1e2v(nldi:nlei, nldj:nlej), dp))
+            CALL iom_set_domain_attr("grid_W", area = real( e1e2t(nldi:nlei, nldj:nlej), dp))
             CALL set_grid_bounds( "T", glamf, gphif, glamt, gphit )
             CALL set_grid_bounds( "U", glamv, gphiv, glamu, gphiu )
@@ -192,8 +199,8 @@
          !
          IF( ln_cfmeta .AND. .NOT. llrst_context) THEN   ! Add additional grid metadata
-            CALL iom_set_domain_attr("grid_T", area = e1e2t_crs(nldi:nlei, nldj:nlej))
-            CALL iom_set_domain_attr("grid_U", area = e1u_crs(nldi:nlei, nldj:nlej) * e2u_crs(nldi:nlei, nldj:nlej))
-            CALL iom_set_domain_attr("grid_V", area = e1v_crs(nldi:nlei, nldj:nlej) * e2v_crs(nldi:nlei, nldj:nlej))
-            CALL iom_set_domain_attr("grid_W", area = e1e2t_crs(nldi:nlei, nldj:nlej))
+            CALL iom_set_domain_attr("grid_T", area = real(e1e2t_crs(nldi:nlei, nldj:nlej), dp))
+            CALL iom_set_domain_attr("grid_U", area = real(e1u_crs(nldi:nlei, nldj:nlej) * e2u_crs(nldi:nlei, nldj:nlej), dp) )
+            CALL iom_set_domain_attr("grid_V", area = real(e1v_crs(nldi:nlei, nldj:nlej) * e2v_crs(nldi:nlei, nldj:nlej), dp) )
+            CALL iom_set_domain_attr("grid_W", area = real(e1e2t_crs(nldi:nlei, nldj:nlej), dp ) )
             CALL set_grid_bounds( "T", glamf_crs, gphif_crs, glamt_crs, gphit_crs )
             CALL set_grid_bounds( "U", glamv_crs, gphiv_crs, glamu_crs, gphiu_crs )
@@ -941,8 +948,60 @@
    !!                   INTERFACE iom_get
    !!----------------------------------------------------------------------
-   SUBROUTINE iom_g0d( kiomid, cdvar, pvar, ktime, ldxios )
+   SUBROUTINE iom_g0d_sp( kiomid, cdvar, pvar, ktime, ldxios )
       INTEGER         , INTENT(in   )                 ::   kiomid    ! Identifier of the file
       CHARACTER(len=*), INTENT(in   )                 ::   cdvar     ! Name of the variable
-      REAL(wp)        , INTENT(  out)                 ::   pvar      ! read field
+      REAL(sp)        , INTENT(  out)                 ::   pvar      ! read field
+      REAL(dp)                                        ::   ztmp_pvar ! tmp var to read field
+      INTEGER         , INTENT(in   ),     OPTIONAL   ::   ktime     ! record number
+      LOGICAL         , INTENT(in   ),     OPTIONAL   ::   ldxios    ! use xios to read restart
+      !
+      INTEGER                                         ::   idvar     ! variable id
+      INTEGER                                         ::   idmspc    ! number of spatial dimensions
+      INTEGER         , DIMENSION(1)                  ::   itime     ! record number
+      CHARACTER(LEN=100)                              ::   clinfo    ! info character
+      CHARACTER(LEN=100)                              ::   clname    ! file name
+      CHARACTER(LEN=1)                                ::   cldmspc   !
+      LOGICAL                                         ::   llxios
+      !
+      llxios = .FALSE.
+      IF( PRESENT(ldxios) ) llxios = ldxios
+
+      IF(.NOT.llxios) THEN  ! read data using default library
+         itime = 1
+         IF( PRESENT(ktime) ) itime = ktime
+         !
+         clname = iom_file(kiomid)%name
+         clinfo = '          iom_g0d, file: '//trim(clname)//', var: '//trim(cdvar)
+         !
+         IF( kiomid > 0 ) THEN
+            idvar = iom_varid( kiomid, cdvar )
+            IF( iom_file(kiomid)%nfid > 0 .AND. idvar > 0 ) THEN
+               idmspc = iom_file ( kiomid )%ndims( idvar )
+               IF( iom_file(kiomid)%luld(idvar) )  idmspc = idmspc - 1
+               WRITE(cldmspc , fmt='(i1)') idmspc
+               IF( idmspc > 0 )  CALL ctl_stop( TRIM(clinfo), 'When reading to a 0D array, we do not accept data', &
+                                    &                         'with 1 or more spatial dimensions: '//cldmspc//' were found.' , &
+                                    &                         'Use ncwa -a to suppress the unnecessary dimensions' )
+               CALL iom_nf90_get( kiomid, idvar, ztmp_pvar, itime )
+               pvar = ztmp_pvar
+            ENDIF
+         ENDIF
+      ELSE
+#if defined key_iomput
+         IF(lwp) WRITE(numout,*) 'XIOS RST READ (0D): ', trim(cdvar)
+         CALL iom_swap( TRIM(crxios_context) )
+         CALL xios_recv_field( trim(cdvar), pvar)
+         CALL iom_swap( TRIM(cxios_context) )
+#else
+         WRITE(ctmp1,*) 'Can not use XIOS in iom_g0d, file: '//trim(clname)//', var:'//trim(cdvar)
+         CALL ctl_stop( 'iom_g0d', ctmp1 )
+#endif
+      ENDIF
+   END SUBROUTINE iom_g0d_sp
+
+   SUBROUTINE iom_g0d_dp( kiomid, cdvar, pvar, ktime, ldxios )
+      INTEGER         , INTENT(in   )                 ::   kiomid    ! Identifier of the file
+      CHARACTER(len=*), INTENT(in   )                 ::   cdvar     ! Name of the variable
+      REAL(dp)        , INTENT(  out)                 ::   pvar      ! read field
       INTEGER         , INTENT(in   ),     OPTIONAL   ::   ktime     ! record number
       LOGICAL         , INTENT(in   ),     OPTIONAL   ::   ldxios    ! use xios to read restart
@@ -989,11 +1048,12 @@
 #endif
       ENDIF
-   END SUBROUTINE iom_g0d
-
-   SUBROUTINE iom_g1d( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, ldxios )
+   END SUBROUTINE iom_g0d_dp
+
+   SUBROUTINE iom_g1d_sp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, ldxios )
       INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file
       INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read
       CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable
-      REAL(wp)        , INTENT(  out), DIMENSION(:)           ::   pvar      ! read field
+      REAL(sp)        , INTENT(  out), DIMENSION(:)           ::   pvar      ! read field
+      REAL(dp)        , ALLOCATABLE  , DIMENSION(:)           ::   ztmp_pvar ! tmp var to read field
       INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number
       INTEGER         , INTENT(in   ), DIMENSION(1), OPTIONAL ::   kstart    ! start axis position of the reading 
@@ -1002,15 +1062,39 @@
       !
       IF( kiomid > 0 ) THEN
+         IF( iom_file(kiomid)%nfid > 0 ) THEN
+            ALLOCATE(ztmp_pvar(size(pvar,1)))
+            CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r1d=ztmp_pvar,   &
+              &                                                     ktime=ktime, kstart=kstart, kcount=kcount, &
+              &                                                     ldxios=ldxios )
+            pvar = ztmp_pvar
+            DEALLOCATE(ztmp_pvar)
+         END IF
+      ENDIF
+   END SUBROUTINE iom_g1d_sp
+
+
+   SUBROUTINE iom_g1d_dp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, ldxios )
+      INTEGER         , INTENT(in   )                         ::   kiomid    ! Identifier of the file
+      INTEGER         , INTENT(in   )                         ::   kdom      ! Type of domain to be read
+      CHARACTER(len=*), INTENT(in   )                         ::   cdvar     ! Name of the variable
+      REAL(dp)        , INTENT(  out), DIMENSION(:)           ::   pvar      ! read field
+      INTEGER         , INTENT(in   )              , OPTIONAL ::   ktime     ! record number
+      INTEGER         , INTENT(in   ), DIMENSION(1), OPTIONAL ::   kstart    ! start axis position of the reading 
+      INTEGER         , INTENT(in   ), DIMENSION(1), OPTIONAL ::   kcount    ! number of points in each axis
+      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios    ! read data using XIOS
+      !
+      IF( kiomid > 0 ) THEN
          IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r1d=pvar,   &
               &                                                     ktime=ktime, kstart=kstart, kcount=kcount, &
               &                                                     ldxios=ldxios )
       ENDIF
-   END SUBROUTINE iom_g1d
-
-   SUBROUTINE iom_g2d( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios)
+   END SUBROUTINE iom_g1d_dp
+
+   SUBROUTINE iom_g2d_sp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios)
       INTEGER         , INTENT(in   )                           ::   kiomid    ! Identifier of the file
       INTEGER         , INTENT(in   )                           ::   kdom      ! Type of domain to be read
       CHARACTER(len=*), INTENT(in   )                           ::   cdvar     ! Name of the variable
-      REAL(wp)        , INTENT(  out), DIMENSION(:,:)           ::   pvar      ! read field
+      REAL(sp)        , INTENT(  out), DIMENSION(:,:)           ::   pvar      ! read field
+      REAL(dp)        , ALLOCATABLE  , DIMENSION(:,:)           ::   ztmp_pvar ! tmp var to read field
       INTEGER         , INTENT(in   )                , OPTIONAL ::   ktime     ! record number
       INTEGER         , INTENT(in   ), DIMENSION(2)  , OPTIONAL ::   kstart    ! start axis position of the reading 
@@ -1023,15 +1107,43 @@
       !
       IF( kiomid > 0 ) THEN
+         IF( iom_file(kiomid)%nfid > 0 ) THEN
+            ALLOCATE(ztmp_pvar(size(pvar,1), size(pvar,2)))
+            CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r2d=ztmp_pvar,   &
+              &                                                     ktime=ktime, kstart=kstart, kcount=kcount, &
+              &                                                     lrowattr=lrowattr,  ldxios=ldxios)
+            pvar = ztmp_pvar
+            DEALLOCATE(ztmp_pvar)
+         END IF
+      ENDIF
+   END SUBROUTINE iom_g2d_sp
+
+
+   SUBROUTINE iom_g2d_dp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios)
+      INTEGER         , INTENT(in   )                           ::   kiomid    ! Identifier of the file
+      INTEGER         , INTENT(in   )                           ::   kdom      ! Type of domain to be read
+      CHARACTER(len=*), INTENT(in   )                           ::   cdvar     ! Name of the variable
+      REAL(dp)        , INTENT(  out), DIMENSION(:,:)           ::   pvar      ! read field
+      INTEGER         , INTENT(in   )                , OPTIONAL ::   ktime     ! record number
+      INTEGER         , INTENT(in   ), DIMENSION(2)  , OPTIONAL ::   kstart    ! start axis position of the reading 
+      INTEGER         , INTENT(in   ), DIMENSION(2)  , OPTIONAL ::   kcount    ! number of points in each axis
+      LOGICAL         , INTENT(in   )                , OPTIONAL ::   lrowattr  ! logical flag telling iom_get to
+                                                                               ! look for and use a file attribute
+                                                                               ! called open_ocean_jstart to set the start
+                                                                               ! value for the 2nd dimension (netcdf only)
+      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios      ! read data using XIOS
+      !
+      IF( kiomid > 0 ) THEN
          IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r2d=pvar,   &
               &                                                     ktime=ktime, kstart=kstart, kcount=kcount, &
               &                                                     lrowattr=lrowattr,  ldxios=ldxios)
       ENDIF
-   END SUBROUTINE iom_g2d
-
-   SUBROUTINE iom_g3d( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios )
+   END SUBROUTINE iom_g2d_dp
+
+   SUBROUTINE iom_g3d_sp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios )
       INTEGER         , INTENT(in   )                             ::   kiomid    ! Identifier of the file
       INTEGER         , INTENT(in   )                             ::   kdom      ! Type of domain to be read
       CHARACTER(len=*), INTENT(in   )                             ::   cdvar     ! Name of the variable
-      REAL(wp)        , INTENT(  out), DIMENSION(:,:,:)           ::   pvar      ! read field
+      REAL(sp)        , INTENT(  out), DIMENSION(:,:,:)           ::   pvar      ! read field
+      REAL(dp)        , ALLOCATABLE  , DIMENSION(:,:,:)           ::   ztmp_pvar ! tmp var to read field
       INTEGER         , INTENT(in   )                  , OPTIONAL ::   ktime     ! record number
       INTEGER         , INTENT(in   ), DIMENSION(3)    , OPTIONAL ::   kstart    ! start axis position of the reading 
@@ -1044,9 +1156,38 @@
       !
       IF( kiomid > 0 ) THEN
+         IF( iom_file(kiomid)%nfid > 0 ) THEN
+            ALLOCATE(ztmp_pvar(size(pvar,1), size(pvar,2), size(pvar,3)))
+            CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r3d=ztmp_pvar,   &
+              &                                                     ktime=ktime, kstart=kstart, kcount=kcount, &
+              &                                                     lrowattr=lrowattr, ldxios=ldxios )
+            pvar = ztmp_pvar
+            DEALLOCATE(ztmp_pvar)
+         END IF
+      ENDIF
+   END SUBROUTINE iom_g3d_sp
+
+   SUBROUTINE iom_g3d_dp( kiomid, kdom, cdvar, pvar, ktime, kstart, kcount, lrowattr, ldxios )
+      INTEGER         , INTENT(in   )                             ::   kiomid    ! Identifier of the file
+      INTEGER         , INTENT(in   )                             ::   kdom      ! Type of domain to be read
+      CHARACTER(len=*), INTENT(in   )                             ::   cdvar     ! Name of the variable
+      REAL(dp)        , INTENT(  out), DIMENSION(:,:,:)           ::   pvar      ! read field
+      INTEGER         , INTENT(in   )                  , OPTIONAL ::   ktime     ! record number
+      INTEGER         , INTENT(in   ), DIMENSION(3)    , OPTIONAL ::   kstart    ! start axis position of the reading 
+      INTEGER         , INTENT(in   ), DIMENSION(3)    , OPTIONAL ::   kcount    ! number of points in each axis
+      LOGICAL         , INTENT(in   )                  , OPTIONAL ::   lrowattr  ! logical flag telling iom_get to
+                                                                                 ! look for and use a file attribute
+                                                                                 ! called open_ocean_jstart to set the start
+                                                                                 ! value for the 2nd dimension (netcdf only)
+      LOGICAL         , INTENT(in   ),               OPTIONAL ::   ldxios        ! read data using XIOS
+      !
+      IF( kiomid > 0 ) THEN
          IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom       , cdvar        , pv_r3d=pvar,   &
               &                                                     ktime=ktime, kstart=kstart, kcount=kcount, &
               &                                                     lrowattr=lrowattr, ldxios=ldxios )
       ENDIF
-   END SUBROUTINE iom_g3d
+   END SUBROUTINE iom_g3d_dp
+
+
+
    !!----------------------------------------------------------------------
 
@@ -1065,7 +1206,7 @@
       INTEGER                    , INTENT(in   )           ::   kdom       ! Type of domain to be read
       CHARACTER(len=*)           , INTENT(in   )           ::   cdvar      ! Name of the variable
-      REAL(wp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d     ! read field (1D case)
-      REAL(wp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d     ! read field (2D case)
-      REAL(wp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d     ! read field (3D case)
+      REAL(dp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d     ! read field (1D case)
+      REAL(dp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d     ! read field (2D case)
+      REAL(dp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d     ! read field (3D case)
       INTEGER                    , INTENT(in   ), OPTIONAL ::   ktime      ! record number
       INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kstart     ! start position of the reading in each axis 
@@ -1096,5 +1237,5 @@
       INTEGER, DIMENSION(jpmax_dims) ::   idimsz      ! size of the dimensions of the variable
       INTEGER, DIMENSION(jpmax_dims) ::   ishape      ! size of the dimensions of the variable
-      REAL(wp)                       ::   zscf, zofs  ! sacle_factor and add_offset
+      REAL(dp)                       ::   zscf, zofs  ! sacle_factor and add_offset
       INTEGER                        ::   itmp        ! temporary integer
       CHARACTER(LEN=256)             ::   clinfo      ! info character
@@ -1103,5 +1244,5 @@
       LOGICAL                        ::   ll_depth_spec ! T => if kstart, kcount present then *only* use values for 3rd spatial dimension.
       INTEGER                        ::   inlev       ! number of levels for 3D data
-      REAL(wp)                       ::   gma, gmi
+      REAL(dp)                       ::   gma, gmi
       !---------------------------------------------------------------------
       !
@@ -1550,10 +1691,10 @@
    !!                   INTERFACE iom_rstput
    !!----------------------------------------------------------------------
-   SUBROUTINE iom_rp0d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+   SUBROUTINE iom_rp0d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
       INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
       INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
       INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
       CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
-      REAL(wp)        , INTENT(in)                         ::   pvar     ! written field
+      REAL(sp)        , INTENT(in)                         ::   pvar     ! written field
       INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
       LOGICAL, OPTIONAL :: ldxios   ! xios write flag
@@ -1574,16 +1715,47 @@
             IF( iom_file(kiomid)%nfid > 0 ) THEN
                ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
-               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r0d = pvar )
+               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r0d = real(pvar, dp) )
             ENDIF
          ENDIF
       ENDIF
-   END SUBROUTINE iom_rp0d
-
-   SUBROUTINE iom_rp1d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+   END SUBROUTINE iom_rp0d_sp
+
+   SUBROUTINE iom_rp0d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
       INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
       INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
       INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
       CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
-      REAL(wp)        , INTENT(in), DIMENSION(          :) ::   pvar     ! written field
+      REAL(dp)        , INTENT(in)                         ::   pvar     ! written field
+      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
+      LOGICAL, OPTIONAL :: ldxios   ! xios write flag
+      LOGICAL :: llx                ! local xios write flag
+      INTEGER :: ivid   ! variable id
+
+      llx = .FALSE.
+      IF(PRESENT(ldxios)) llx = ldxios
+      IF( llx ) THEN
+#ifdef key_iomput
+      IF( kt == kwrite ) THEN
+          IF(lwp) write(numout,*) 'RESTART: write (XIOS 0D) ',trim(cdvar)
+          CALL xios_send_field(trim(cdvar), pvar)
+      ENDIF
+#endif
+      ELSE
+         IF( kiomid > 0 ) THEN
+            IF( iom_file(kiomid)%nfid > 0 ) THEN
+               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
+               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r0d = pvar )
+            ENDIF
+         ENDIF
+      ENDIF
+   END SUBROUTINE iom_rp0d_dp
+
+
+   SUBROUTINE iom_rp1d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
+      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
+      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
+      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
+      REAL(sp)        , INTENT(in), DIMENSION(          :) ::   pvar     ! written field
       INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
       LOGICAL, OPTIONAL                                    ::   ldxios   ! xios write flag
@@ -1604,16 +1776,47 @@
             IF( iom_file(kiomid)%nfid > 0 ) THEN
                ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
-               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r1d = pvar )
+               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r1d = real(pvar, dp) )
             ENDIF
          ENDIF
       ENDIF
-   END SUBROUTINE iom_rp1d
-
-   SUBROUTINE iom_rp2d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+   END SUBROUTINE iom_rp1d_sp
+
+   SUBROUTINE iom_rp1d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
       INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
       INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
       INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
       CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
-      REAL(wp)        , INTENT(in), DIMENSION(:,    :    ) ::   pvar     ! written field
+      REAL(dp)        , INTENT(in), DIMENSION(          :) ::   pvar     ! written field
+      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
+      LOGICAL, OPTIONAL                                    ::   ldxios   ! xios write flag
+      LOGICAL :: llx                ! local xios write flag
+      INTEGER :: ivid   ! variable id
+
+      llx = .FALSE.
+      IF(PRESENT(ldxios)) llx = ldxios
+      IF( llx ) THEN
+#ifdef key_iomput
+      IF( kt == kwrite ) THEN
+         IF(lwp) write(numout,*) 'RESTART: write (XIOS 1D) ',trim(cdvar)
+         CALL xios_send_field(trim(cdvar), pvar)
+      ENDIF
+#endif
+      ELSE
+         IF( kiomid > 0 ) THEN
+            IF( iom_file(kiomid)%nfid > 0 ) THEN
+               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
+               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r1d = pvar )
+            ENDIF
+         ENDIF
+      ENDIF
+   END SUBROUTINE iom_rp1d_dp
+
+
+   SUBROUTINE iom_rp2d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
+      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
+      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
+      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
+      REAL(sp)        , INTENT(in), DIMENSION(:,    :    ) ::   pvar     ! written field
       INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
       LOGICAL, OPTIONAL :: ldxios   ! xios write flag
@@ -1634,16 +1837,47 @@
             IF( iom_file(kiomid)%nfid > 0 ) THEN
                ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
-               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r2d = pvar )
+               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r2d = real(pvar, dp) )
             ENDIF
          ENDIF
       ENDIF
-   END SUBROUTINE iom_rp2d
-
-   SUBROUTINE iom_rp3d( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+   END SUBROUTINE iom_rp2d_sp
+
+   SUBROUTINE iom_rp2d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
       INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
       INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
       INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
       CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
-      REAL(wp)        , INTENT(in),       DIMENSION(:,:,:) ::   pvar     ! written field
+      REAL(dp)        , INTENT(in), DIMENSION(:,    :    ) ::   pvar     ! written field
+      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
+      LOGICAL, OPTIONAL :: ldxios   ! xios write flag
+      LOGICAL :: llx
+      INTEGER :: ivid   ! variable id
+
+      llx = .FALSE.
+      IF(PRESENT(ldxios)) llx = ldxios
+      IF( llx ) THEN
+#ifdef key_iomput
+      IF( kt == kwrite ) THEN
+         IF(lwp) write(numout,*) 'RESTART: write (XIOS 2D) ',trim(cdvar)
+         CALL xios_send_field(trim(cdvar), pvar)
+      ENDIF
+#endif
+      ELSE
+         IF( kiomid > 0 ) THEN
+            IF( iom_file(kiomid)%nfid > 0 ) THEN
+               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
+               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r2d = pvar )
+            ENDIF
+         ENDIF
+      ENDIF
+   END SUBROUTINE iom_rp2d_dp
+
+
+   SUBROUTINE iom_rp3d_sp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
+      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
+      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
+      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
+      REAL(sp)        , INTENT(in),       DIMENSION(:,:,:) ::   pvar     ! written field
       INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
       LOGICAL, OPTIONAL :: ldxios   ! xios write flag
@@ -1664,9 +1898,40 @@
             IF( iom_file(kiomid)%nfid > 0 ) THEN
                ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
+               CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r3d = real(pvar, dp) )
+            ENDIF
+         ENDIF
+      ENDIF
+   END SUBROUTINE iom_rp3d_sp
+
+   SUBROUTINE iom_rp3d_dp( kt, kwrite, kiomid, cdvar, pvar, ktype, ldxios )
+      INTEGER         , INTENT(in)                         ::   kt       ! ocean time-step
+      INTEGER         , INTENT(in)                         ::   kwrite   ! writing time-step
+      INTEGER         , INTENT(in)                         ::   kiomid   ! Identifier of the file 
+      CHARACTER(len=*), INTENT(in)                         ::   cdvar    ! time axis name
+      REAL(dp)        , INTENT(in),       DIMENSION(:,:,:) ::   pvar     ! written field
+      INTEGER         , INTENT(in), OPTIONAL               ::   ktype    ! variable external type
+      LOGICAL, OPTIONAL :: ldxios   ! xios write flag
+      LOGICAL :: llx                 ! local xios write flag
+      INTEGER :: ivid   ! variable id
+
+      llx = .FALSE.
+      IF(PRESENT(ldxios)) llx = ldxios
+      IF( llx ) THEN
+#ifdef key_iomput
+      IF( kt == kwrite ) THEN
+         IF(lwp) write(numout,*) 'RESTART: write (XIOS 3D) ',trim(cdvar)
+         CALL xios_send_field(trim(cdvar), pvar)
+      ENDIF
+#endif
+      ELSE
+         IF( kiomid > 0 ) THEN
+            IF( iom_file(kiomid)%nfid > 0 ) THEN
+               ivid = iom_varid( kiomid, cdvar, ldstop = .FALSE. )
                CALL iom_nf90_rstput( kt, kwrite, kiomid, cdvar, ivid, ktype, pv_r3d = pvar )
             ENDIF
          ENDIF
       ENDIF
-   END SUBROUTINE iom_rp3d
+   END SUBROUTINE iom_rp3d_dp
+
 
 
@@ -1720,7 +1985,7 @@
    !!                   INTERFACE iom_put
    !!----------------------------------------------------------------------
-   SUBROUTINE iom_p0d( cdname, pfield0d )
+   SUBROUTINE iom_p0d_sp( cdname, pfield0d )
       CHARACTER(LEN=*), INTENT(in) ::   cdname
-      REAL(wp)        , INTENT(in) ::   pfield0d
+      REAL(sp)        , INTENT(in) ::   pfield0d
 !!      REAL(wp)        , DIMENSION(jpi,jpj) ::   zz     ! masson
 #if defined key_iomput
@@ -1731,9 +1996,23 @@
       IF( .FALSE. )   WRITE(numout,*) cdname, pfield0d   ! useless test to avoid compilation warnings
 #endif
-   END SUBROUTINE iom_p0d
-
-   SUBROUTINE iom_p1d( cdname, pfield1d )
+   END SUBROUTINE iom_p0d_sp
+
+   SUBROUTINE iom_p0d_dp( cdname, pfield0d )
+      CHARACTER(LEN=*), INTENT(in) ::   cdname
+      REAL(dp)        , INTENT(in) ::   pfield0d
+!!      REAL(wp)        , DIMENSION(jpi,jpj) ::   zz     ! masson
+#if defined key_iomput
+!!clem      zz(:,:)=pfield0d
+!!clem      CALL xios_send_field(cdname, zz)
+      CALL xios_send_field(cdname, (/pfield0d/)) 
+#else
+      IF( .FALSE. )   WRITE(numout,*) cdname, pfield0d   ! useless test to avoid compilation warnings
+#endif
+   END SUBROUTINE iom_p0d_dp
+
+
+   SUBROUTINE iom_p1d_sp( cdname, pfield1d )
       CHARACTER(LEN=*)          , INTENT(in) ::   cdname
-      REAL(wp),     DIMENSION(:), INTENT(in) ::   pfield1d
+      REAL(sp),     DIMENSION(:), INTENT(in) ::   pfield1d
 #if defined key_iomput
       CALL xios_send_field( cdname, RESHAPE( (/pfield1d/), (/1,1,SIZE(pfield1d)/) ) )
@@ -1741,9 +2020,19 @@
       IF( .FALSE. )   WRITE(numout,*) cdname, pfield1d   ! useless test to avoid compilation warnings
 #endif
-   END SUBROUTINE iom_p1d
-
-   SUBROUTINE iom_p2d( cdname, pfield2d )
+   END SUBROUTINE iom_p1d_sp
+
+   SUBROUTINE iom_p1d_dp( cdname, pfield1d )
+      CHARACTER(LEN=*)          , INTENT(in) ::   cdname
+      REAL(dp),     DIMENSION(:), INTENT(in) ::   pfield1d
+#if defined key_iomput
+      CALL xios_send_field( cdname, RESHAPE( (/pfield1d/), (/1,1,SIZE(pfield1d)/) ) )
+#else
+      IF( .FALSE. )   WRITE(numout,*) cdname, pfield1d   ! useless test to avoid compilation warnings
+#endif
+   END SUBROUTINE iom_p1d_dp
+
+   SUBROUTINE iom_p2d_sp( cdname, pfield2d )
       CHARACTER(LEN=*)            , INTENT(in) ::   cdname
-      REAL(wp),     DIMENSION(:,:), INTENT(in) ::   pfield2d
+      REAL(sp),     DIMENSION(:,:), INTENT(in) ::   pfield2d
 #if defined key_iomput
       CALL xios_send_field(cdname, pfield2d)
@@ -1751,9 +2040,19 @@
       IF( .FALSE. )   WRITE(numout,*) cdname, pfield2d   ! useless test to avoid compilation warnings
 #endif
-   END SUBROUTINE iom_p2d
-
-   SUBROUTINE iom_p3d( cdname, pfield3d )
+   END SUBROUTINE iom_p2d_sp
+
+   SUBROUTINE iom_p2d_dp( cdname, pfield2d )
+      CHARACTER(LEN=*)            , INTENT(in) ::   cdname
+      REAL(dp),     DIMENSION(:,:), INTENT(in) ::   pfield2d
+#if defined key_iomput
+      CALL xios_send_field(cdname, pfield2d)
+#else
+      IF( .FALSE. )   WRITE(numout,*) cdname, pfield2d   ! useless test to avoid compilation warnings
+#endif
+   END SUBROUTINE iom_p2d_dp
+
+   SUBROUTINE iom_p3d_sp( cdname, pfield3d )
       CHARACTER(LEN=*)                , INTENT(in) ::   cdname
-      REAL(wp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d
+      REAL(sp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d
 #if defined key_iomput
       CALL xios_send_field( cdname, pfield3d )
@@ -1761,9 +2060,19 @@
       IF( .FALSE. )   WRITE(numout,*) cdname, pfield3d   ! useless test to avoid compilation warnings
 #endif
-   END SUBROUTINE iom_p3d
-
-   SUBROUTINE iom_p4d( cdname, pfield4d )
+   END SUBROUTINE iom_p3d_sp
+
+   SUBROUTINE iom_p3d_dp( cdname, pfield3d )
       CHARACTER(LEN=*)                , INTENT(in) ::   cdname
-      REAL(wp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d
+      REAL(dp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d
+#if defined key_iomput
+      CALL xios_send_field( cdname, pfield3d )
+#else
+      IF( .FALSE. )   WRITE(numout,*) cdname, pfield3d   ! useless test to avoid compilation warnings
+#endif
+   END SUBROUTINE iom_p3d_dp
+
+   SUBROUTINE iom_p4d_sp( cdname, pfield4d )
+      CHARACTER(LEN=*)                , INTENT(in) ::   cdname
+      REAL(sp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d
 #if defined key_iomput
       CALL xios_send_field(cdname, pfield4d)
@@ -1771,6 +2080,15 @@
       IF( .FALSE. )   WRITE(numout,*) cdname, pfield4d   ! useless test to avoid compilation warnings
 #endif
-   END SUBROUTINE iom_p4d
-
+   END SUBROUTINE iom_p4d_sp
+
+   SUBROUTINE iom_p4d_dp( cdname, pfield4d )
+      CHARACTER(LEN=*)                , INTENT(in) ::   cdname
+      REAL(dp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d
+#if defined key_iomput
+      CALL xios_send_field(cdname, pfield4d)
+#else
+      IF( .FALSE. )   WRITE(numout,*) cdname, pfield4d   ! useless test to avoid compilation warnings
+#endif
+   END SUBROUTINE iom_p4d_dp
 
 #if defined key_iomput
@@ -1788,6 +2106,6 @@
       INTEGER                 , OPTIONAL, INTENT(in) ::   data_dim, data_ibegin, data_ni, data_jbegin, data_nj
       INTEGER                 , OPTIONAL, INTENT(in) ::   nvertex
-      REAL(wp), DIMENSION(:)  , OPTIONAL, INTENT(in) ::   lonvalue, latvalue
-      REAL(wp), DIMENSION(:,:), OPTIONAL, INTENT(in) ::   bounds_lon, bounds_lat, area
+      REAL(dp), DIMENSION(:)  , OPTIONAL, INTENT(in) ::   lonvalue, latvalue
+      REAL(dp), DIMENSION(:,:), OPTIONAL, INTENT(in) ::   bounds_lon, bounds_lat, area
       LOGICAL , DIMENSION(:)  , OPTIONAL, INTENT(in) ::   mask
       !!----------------------------------------------------------------------
@@ -1852,9 +2170,14 @@
       !!----------------------------------------------------------------------
       IF( PRESENT(paxis) ) THEN
-         IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, n_glo=SIZE(paxis), value=paxis )
-         IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, n_glo=SIZE(paxis), value=paxis )
-      ENDIF
-      IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, bounds=bounds )
-      IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, bounds=bounds )
+         IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, n_glo=SIZE(paxis), value=real(paxis, dp) )
+         IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, n_glo=SIZE(paxis), value=real(paxis, dp) )
+      ENDIF
+      IF( PRESENT(bounds) ) THEN
+         IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid, bounds=real(bounds, dp) )
+         IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid, bounds=real(bounds, dp) )
+      ELSE
+         IF( xios_is_valid_axis     (cdid) )   CALL xios_set_axis_attr     ( cdid)
+         IF( xios_is_valid_axisgroup(cdid) )   CALL xios_set_axisgroup_attr( cdid)
+      END IF
       CALL xios_solve_inheritance()
    END SUBROUTINE iom_set_axis_attr
@@ -1975,6 +2298,6 @@
 !don't define lon and lat for restart reading context. 
       IF ( .NOT.ldrxios ) &
-         CALL iom_set_domain_attr("grid_"//cdgrd, lonvalue = RESHAPE(plon(nldi:nlei, nldj:nlej),(/ ni*nj /)),   &
-         &                                     latvalue = RESHAPE(plat(nldi:nlei, nldj:nlej),(/ ni*nj /)))  
+         CALL iom_set_domain_attr("grid_"//cdgrd, lonvalue = real(RESHAPE(plon(nldi:nlei, nldj:nlej),(/ ni*nj /)), dp),   &
+         &                                     latvalue = real(RESHAPE(plat(nldi:nlei, nldj:nlej),(/ ni*nj /)),dp ) )  
       !
       IF ( ln_mskland .AND. (.NOT.ldxios) ) THEN
@@ -2091,6 +2414,6 @@
       ENDIF
       !
-      CALL iom_set_domain_attr("grid_"//cdgrd, bounds_lat = RESHAPE(z_bnds(:,nldi:nlei,nldj:nlej,1),(/ 4,ni*nj /)),           &
-          &                                    bounds_lon = RESHAPE(z_bnds(:,nldi:nlei,nldj:nlej,2),(/ 4,ni*nj /)), nvertex=4 )
+      CALL iom_set_domain_attr("grid_"//cdgrd, bounds_lat =real( RESHAPE(z_bnds(:,nldi:nlei,nldj:nlej,1),(/ 4,ni*nj /)), dp),           &
+          &                                    bounds_lon =real( RESHAPE(z_bnds(:,nldi:nlei,nldj:nlej,2),(/ 4,ni*nj /)), dp), nvertex=4 )
       !
       DEALLOCATE( z_bnds, z_fld, z_rot ) 
@@ -2120,6 +2443,6 @@
       CALL iom_set_domain_attr("gznl", ni_glo=jpiglo, nj_glo=jpjglo, ibegin=nimpp+nldi-2, jbegin=njmpp+nldj-2, ni=ni, nj=nj)
       CALL iom_set_domain_attr("gznl", data_dim=2, data_ibegin = 1-nldi, data_ni = jpi, data_jbegin = 1-nldj, data_nj = jpj)
-      CALL iom_set_domain_attr("gznl", lonvalue = zlon,   &
-         &                             latvalue = RESHAPE(plat(nldi:nlei, nldj:nlej),(/ ni*nj /)))  
+      CALL iom_set_domain_attr("gznl", lonvalue = real(zlon, dp),   &
+         &                             latvalue = real(RESHAPE(plat(nldi:nlei, nldj:nlej),(/ ni*nj /)),dp))  
       CALL iom_set_zoom_domain_attr("ptr", ibegin=ix-1, jbegin=0, ni=1, nj=jpjglo)
       !
@@ -2136,5 +2459,5 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(1)   ::   zz = 1.
+      REAL(dp), DIMENSION(1)   ::   zz = 1.
       !!----------------------------------------------------------------------
       !
@@ -2482,7 +2805,9 @@
       CHARACTER(LEN=*), INTENT(in ) ::   cdname
       REAL(wp)        , INTENT(out) ::   pmiss_val   
+      REAL(dp)                      ::   ztmp_pmiss_val   
 #if defined key_iomput
       ! get missing value
-      CALL xios_get_field_attr( cdname, default_value = pmiss_val )
+      CALL xios_get_field_attr( cdname, default_value = ztmp_pmiss_val )
+      pmiss_val = ztmp_pmiss_val
 #else
       IF( .FALSE. )   WRITE(numout,*) cdname, pmiss_val   ! useless test to avoid compilation warnings
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/IOM/iom_nf90.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/IOM/iom_nf90.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/IOM/iom_nf90.F90	(revision 12603)
@@ -33,8 +33,9 @@
 
    INTERFACE iom_nf90_get
-      MODULE PROCEDURE iom_nf90_g0d, iom_nf90_g123d
+      MODULE PROCEDURE iom_nf90_g0d_sp                   
+      MODULE PROCEDURE iom_nf90_g0d_dp, iom_nf90_g123d_dp
    END INTERFACE
    INTERFACE iom_nf90_rstput
-      MODULE PROCEDURE iom_nf90_rp0123d
+      MODULE PROCEDURE iom_nf90_rp0123d_dp
    END INTERFACE
 
@@ -273,5 +274,5 @@
    !!----------------------------------------------------------------------
 
-   SUBROUTINE iom_nf90_g0d( kiomid, kvid, pvar, kstart )
+   SUBROUTINE iom_nf90_g0d_sp( kiomid, kvid, pvar, kstart )
       !!-----------------------------------------------------------------------
       !!                  ***  ROUTINE  iom_nf90_g0d  ***
@@ -281,5 +282,5 @@
       INTEGER ,               INTENT(in   )            ::   kiomid   ! Identifier of the file
       INTEGER ,               INTENT(in   )            ::   kvid     ! variable id
-      REAL(wp),               INTENT(  out)            ::   pvar     ! read field
+      REAL(sp),               INTENT(  out)            ::   pvar     ! read field
       INTEGER , DIMENSION(1), INTENT(in   ), OPTIONAL  ::   kstart   ! start position of the reading in each axis
       !
@@ -288,8 +289,24 @@
       clinfo = 'iom_nf90_g0d , file: '//TRIM(iom_file(kiomid)%name)//', var: '//TRIM(iom_file(kiomid)%cn_var(kvid))
       CALL iom_nf90_check(NF90_GET_VAR(iom_file(kiomid)%nfid, iom_file(kiomid)%nvid(kvid), pvar, start = kstart), clinfo )
-   END SUBROUTINE iom_nf90_g0d
-
-
-   SUBROUTINE iom_nf90_g123d( kiomid, kvid, knbdim, kstart, kcount, kx1, kx2, ky1, ky2,   &
+   END SUBROUTINE iom_nf90_g0d_sp
+
+   SUBROUTINE iom_nf90_g0d_dp( kiomid, kvid, pvar, kstart )
+      !!-----------------------------------------------------------------------
+      !!                  ***  ROUTINE  iom_nf90_g0d  ***
+      !!
+      !! ** Purpose : read a scalar with NF90
+      !!-----------------------------------------------------------------------
+      INTEGER ,               INTENT(in   )            ::   kiomid   ! Identifier of the file
+      INTEGER ,               INTENT(in   )            ::   kvid     ! variable id
+      REAL(dp),               INTENT(  out)            ::   pvar     ! read field
+      INTEGER , DIMENSION(1), INTENT(in   ), OPTIONAL  ::   kstart   ! start position of the reading in each axis
+      !
+      CHARACTER(LEN=100)      ::   clinfo   ! info character
+      !---------------------------------------------------------------------
+      clinfo = 'iom_nf90_g0d , file: '//TRIM(iom_file(kiomid)%name)//', var: '//TRIM(iom_file(kiomid)%cn_var(kvid))
+      CALL iom_nf90_check(NF90_GET_VAR(iom_file(kiomid)%nfid, iom_file(kiomid)%nvid(kvid), pvar, start = kstart), clinfo )
+   END SUBROUTINE iom_nf90_g0d_dp
+
+   SUBROUTINE iom_nf90_g123d_dp( kiomid, kvid, knbdim, kstart, kcount, kx1, kx2, ky1, ky2,   &
          &                    pv_r1d, pv_r2d, pv_r3d )
       !!-----------------------------------------------------------------------
@@ -306,7 +323,7 @@
       INTEGER , DIMENSION(:)     , INTENT(in   )           ::   kcount    ! number of points to be read in each axis
       INTEGER ,                    INTENT(in   )           ::   kx1, kx2, ky1, ky2   ! subdomain indexes
-      REAL(wp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d    ! read field (1D case)
-      REAL(wp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d    ! read field (2D case)
-      REAL(wp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d    ! read field (3D case)
+      REAL(dp), DIMENSION(:)     , INTENT(  out), OPTIONAL ::   pv_r1d    ! read field (1D case)
+      REAL(dp), DIMENSION(:,:)   , INTENT(  out), OPTIONAL ::   pv_r2d    ! read field (2D case)
+      REAL(dp), DIMENSION(:,:,:) , INTENT(  out), OPTIONAL ::   pv_r3d    ! read field (3D case)
       !
       CHARACTER(LEN=100) ::   clinfo               ! info character
@@ -329,5 +346,6 @@
       ENDIF
       !
-   END SUBROUTINE iom_nf90_g123d
+   END SUBROUTINE iom_nf90_g123d_dp
+
 
 
@@ -503,6 +521,5 @@
    END SUBROUTINE iom_nf90_putatt
 
-
-   SUBROUTINE iom_nf90_rp0123d( kt, kwrite, kiomid, cdvar , kvid  , ktype,   &
+   SUBROUTINE iom_nf90_rp0123d_dp( kt, kwrite, kiomid, cdvar , kvid  , ktype,   &
          &                                  pv_r0d, pv_r1d, pv_r2d, pv_r3d )
       !!--------------------------------------------------------------------
@@ -517,8 +534,8 @@
       INTEGER                     , INTENT(in)           ::   kvid     ! variable id
       INTEGER                     , INTENT(in), OPTIONAL ::   ktype    ! variable type (default R8)
-      REAL(wp)                    , INTENT(in), OPTIONAL ::   pv_r0d   ! written Od field
-      REAL(wp), DIMENSION(      :), INTENT(in), OPTIONAL ::   pv_r1d   ! written 1d field
-      REAL(wp), DIMENSION(:, :   ), INTENT(in), OPTIONAL ::   pv_r2d   ! written 2d field
-      REAL(wp), DIMENSION(:, :, :), INTENT(in), OPTIONAL ::   pv_r3d   ! written 3d field
+      REAL(dp)                    , INTENT(in), OPTIONAL ::   pv_r0d   ! written Od field
+      REAL(dp), DIMENSION(      :), INTENT(in), OPTIONAL ::   pv_r1d   ! written 1d field
+      REAL(dp), DIMENSION(:, :   ), INTENT(in), OPTIONAL ::   pv_r2d   ! written 2d field
+      REAL(dp), DIMENSION(:, :, :), INTENT(in), OPTIONAL ::   pv_r3d   ! written 3d field
       !
       INTEGER               :: idims                ! number of dimension
@@ -720,5 +737,5 @@
       ENDIF
       !     
-   END SUBROUTINE iom_nf90_rp0123d
+   END SUBROUTINE iom_nf90_rp0123d_dp
 
 
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_lnk_multi_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_lnk_multi_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_lnk_multi_generic.h90	(revision 12603)
@@ -1,16 +1,36 @@
-#if defined DIM_2d
-#   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j)
-#   define PTR_TYPE              TYPE(PTR_2D)
-#   define PTR_ptab              pt2d
-#endif
-#if defined DIM_3d
-#   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j,k)
-#   define PTR_TYPE              TYPE(PTR_3D)
-#   define PTR_ptab              pt3d
-#endif
-#if defined DIM_4d
-#   define ARRAY_TYPE(i,j,k,l)   REAL(wp), DIMENSION(i,j,k,l)
-#   define PTR_TYPE              TYPE(PTR_4D)
-#   define PTR_ptab              pt4d
+#if defined SINGLE_PRECISION
+#   if defined DIM_2d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j)
+#      define PTR_TYPE              TYPE(PTR_2D_sp)
+#      define PTR_ptab              pt2d
+#   endif
+#   if defined DIM_3d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k)
+#      define PTR_TYPE              TYPE(PTR_3D_sp)
+#      define PTR_ptab              pt3d
+#   endif
+#   if defined DIM_4d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k,l)
+#      define PTR_TYPE              TYPE(PTR_4D_sp)
+#      define PTR_ptab              pt4d
+#   endif
+#   define PRECISION sp
+#else
+#   if defined DIM_2d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j)
+#      define PTR_TYPE              TYPE(PTR_2D_dp)
+#      define PTR_ptab              pt2d
+#   endif
+#   if defined DIM_3d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k)
+#      define PTR_TYPE              TYPE(PTR_3D_dp)
+#      define PTR_ptab              pt3d
+#   endif
+#   if defined DIM_4d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k,l)
+#      define PTR_TYPE              TYPE(PTR_4D_dp)
+#      define PTR_ptab              pt4d
+#   endif
+#   define PRECISION dp
 #endif
 
@@ -79,4 +99,5 @@
    END SUBROUTINE ROUTINE_LOAD
 
+#undef PRECISION
 #undef ARRAY_TYPE
 #undef PTR_TYPE
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_ext_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_ext_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_ext_generic.h90	(revision 12603)
@@ -8,5 +8,11 @@
 #   define L_SIZE(ptab)          1
 #endif
-#define ARRAY_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#if defined SINGLE_PRECISION
+#   define ARRAY_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#   define PRECISION sp
+#else
+#   define ARRAY_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#   define PRECISION dp
+#endif
 
    SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kextj )
@@ -149,4 +155,5 @@
    END SUBROUTINE ROUTINE_NFD
 
+#undef PRECISION
 #undef ARRAY_TYPE
 #undef ARRAY_IN
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_generic.h90	(revision 12603)
@@ -4,5 +4,9 @@
 #   define F_SIZE(ptab)             kfld
 #   if defined DIM_2d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D),INTENT(inout)::ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp),INTENT(inout)::ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp),INTENT(inout)::ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
 #      define K_SIZE(ptab)             1
@@ -10,5 +14,9 @@
 #   endif
 #   if defined DIM_3d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D),INTENT(inout)::ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp),INTENT(inout)::ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp),INTENT(inout)::ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
@@ -16,5 +24,9 @@
 #   endif
 #   if defined DIM_4d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D),INTENT(inout)::ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp),INTENT(inout)::ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp),INTENT(inout)::ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
@@ -41,6 +53,16 @@
 #      define L_SIZE(ptab)          SIZE(ptab,4)
 #   endif
-#   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#   if defined SINGLE_PRECISION
+#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#   else
+#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#   endif
 #endif
+
+#   if defined SINGLE_PRECISION
+#      define PRECISION sp
+#   else
+#      define PRECISION dp
+#   endif
 
 #if defined MULTI
@@ -167,4 +189,5 @@
    END SUBROUTINE ROUTINE_NFD
 
+#undef PRECISION
 #undef ARRAY_TYPE
 #undef ARRAY_IN
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_nogather_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_nogather_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbc_nfd_nogather_generic.h90	(revision 12603)
@@ -4,5 +4,9 @@
 #   define F_SIZE(ptab)             kfld
 #   if defined DIM_2d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D),INTENT(inout)::ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp),INTENT(inout)::ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp),INTENT(inout)::ptab(f)
+#      endif 
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
 #      define K_SIZE(ptab)             1
@@ -10,5 +14,9 @@
 #   endif
 #   if defined DIM_3d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D),INTENT(inout)::ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp),INTENT(inout)::ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp),INTENT(inout)::ptab(f)
+#      endif 
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
@@ -16,10 +24,18 @@
 #   endif
 #   if defined DIM_4d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D),INTENT(inout)::ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp),INTENT(inout)::ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp),INTENT(inout)::ptab(f)
+#      endif 
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
 #      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4)
 #   endif
-#   define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D),INTENT(inout)::ptab2(f)
+#   if defined SINGLE_PRECISION
+#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_sp),INTENT(inout)::ptab2(f)
+#   else
+#      define ARRAY2_TYPE(i,j,k,l,f)   TYPE(PTR_4D_dp),INTENT(inout)::ptab2(f)
+#   endif
 #   define J_SIZE(ptab2)            SIZE(ptab2(1)%pt4d,2)
 #   define ARRAY2_IN(i,j,k,l,f)     ptab2(f)%pt4d(i,j,k,l)
@@ -46,8 +62,17 @@
 #   define ARRAY2_IN(i,j,k,l,f)  ptab2(i,j,k,l)
 #   define J_SIZE(ptab2)             SIZE(ptab2,2)
-#   define ARRAY_TYPE(i,j,k,l,f)     REAL(wp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
-#   define ARRAY2_TYPE(i,j,k,l,f)    REAL(wp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f)
-#endif
-
+#   if defined SINGLE_PRECISION
+#      define ARRAY_TYPE(i,j,k,l,f)     REAL(sp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(sp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f)
+#   else
+#      define ARRAY_TYPE(i,j,k,l,f)     REAL(dp),INTENT(inout)::ARRAY_IN(i,j,k,l,f)
+#      define ARRAY2_TYPE(i,j,k,l,f)    REAL(dp),INTENT(inout)::ARRAY2_IN(i,j,k,l,f)
+#   endif
+#   endif
+#   ifdef SINGLE_PRECISION
+#      define PRECISION sp
+#   else
+#      define PRECISION dp
+#   endif
    SUBROUTINE ROUTINE_NFD( ptab, ptab2, cd_nat, psgn, kfld )
       !!----------------------------------------------------------------------
@@ -345,4 +370,5 @@
       END DO            ! End jf loop
    END SUBROUTINE ROUTINE_NFD
+#undef PRECISION
 #undef ARRAY_TYPE
 #undef ARRAY_IN
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbclnk.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbclnk.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbclnk.F90	(revision 12603)
@@ -28,20 +28,26 @@
 
    INTERFACE lbc_lnk
-      MODULE PROCEDURE   mpp_lnk_2d      , mpp_lnk_3d      , mpp_lnk_4d
+      MODULE PROCEDURE   mpp_lnk_2d_sp   , mpp_lnk_3d_sp   , mpp_lnk_4d_sp
+      MODULE PROCEDURE   mpp_lnk_2d_dp   , mpp_lnk_3d_dp   , mpp_lnk_4d_dp
    END INTERFACE
    INTERFACE lbc_lnk_ptr
-      MODULE PROCEDURE   mpp_lnk_2d_ptr  , mpp_lnk_3d_ptr  , mpp_lnk_4d_ptr
+      MODULE PROCEDURE   mpp_lnk_2d_ptr_sp , mpp_lnk_3d_ptr_sp , mpp_lnk_4d_ptr_sp
+      MODULE PROCEDURE   mpp_lnk_2d_ptr_dp , mpp_lnk_3d_ptr_dp , mpp_lnk_4d_ptr_dp
    END INTERFACE
    INTERFACE lbc_lnk_multi
-      MODULE PROCEDURE   lbc_lnk_2d_multi, lbc_lnk_3d_multi, lbc_lnk_4d_multi
+      MODULE PROCEDURE   lbc_lnk_2d_multi_sp , lbc_lnk_3d_multi_sp, lbc_lnk_4d_multi_sp
+      MODULE PROCEDURE   lbc_lnk_2d_multi_dp , lbc_lnk_3d_multi_dp, lbc_lnk_4d_multi_dp
    END INTERFACE
    !
    INTERFACE lbc_lnk_icb
-      MODULE PROCEDURE mpp_lnk_2d_icb
+      MODULE PROCEDURE mpp_lnk_2d_icb_dp, mpp_lnk_2d_icb_sp
    END INTERFACE
 
    INTERFACE mpp_nfd
-      MODULE PROCEDURE   mpp_nfd_2d    , mpp_nfd_3d    , mpp_nfd_4d
-      MODULE PROCEDURE   mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr
+      MODULE PROCEDURE   mpp_nfd_2d_sp    , mpp_nfd_3d_sp    , mpp_nfd_4d_sp
+      MODULE PROCEDURE   mpp_nfd_2d_dp    , mpp_nfd_3d_dp    , mpp_nfd_4d_dp
+      MODULE PROCEDURE   mpp_nfd_2d_ptr_sp, mpp_nfd_3d_ptr_sp, mpp_nfd_4d_ptr_sp
+      MODULE PROCEDURE   mpp_nfd_2d_ptr_dp, mpp_nfd_3d_ptr_dp, mpp_nfd_4d_ptr_dp
+      
    END INTERFACE
 
@@ -92,23 +98,55 @@
    !!----------------------------------------------------------------------
 
-#  define DIM_2d
-#     define ROUTINE_LOAD           load_ptr_2d
-#     define ROUTINE_MULTI          lbc_lnk_2d_multi
-#     include "lbc_lnk_multi_generic.h90"
-#     undef ROUTINE_MULTI
-#     undef ROUTINE_LOAD
-#  undef DIM_2d
-
-#  define DIM_3d
-#     define ROUTINE_LOAD           load_ptr_3d
-#     define ROUTINE_MULTI          lbc_lnk_3d_multi
-#     include "lbc_lnk_multi_generic.h90"
-#     undef ROUTINE_MULTI
-#     undef ROUTINE_LOAD
-#  undef DIM_3d
-
-#  define DIM_4d
-#     define ROUTINE_LOAD           load_ptr_4d
-#     define ROUTINE_MULTI          lbc_lnk_4d_multi
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+#  define SINGLE_PRECISION
+#  define DIM_2d
+#     define ROUTINE_LOAD           load_ptr_2d_sp
+#     define ROUTINE_MULTI          lbc_lnk_2d_multi_sp
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#  undef DIM_2d
+
+#  define DIM_3d
+#     define ROUTINE_LOAD           load_ptr_3d_sp
+#     define ROUTINE_MULTI          lbc_lnk_3d_multi_sp
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#  undef DIM_3d
+
+#  define DIM_4d
+#     define ROUTINE_LOAD           load_ptr_4d_sp
+#     define ROUTINE_MULTI          lbc_lnk_4d_multi_sp
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#  undef DIM_4d
+#  undef SINGLE_PRECISION
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+
+#  define DIM_2d
+#     define ROUTINE_LOAD           load_ptr_2d_dp
+#     define ROUTINE_MULTI          lbc_lnk_2d_multi_dp
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#  undef DIM_2d
+
+#  define DIM_3d
+#     define ROUTINE_LOAD           load_ptr_3d_dp
+#     define ROUTINE_MULTI          lbc_lnk_3d_multi_dp
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#  undef DIM_3d
+
+#  define DIM_4d
+#     define ROUTINE_LOAD           load_ptr_4d_dp
+#     define ROUTINE_MULTI          lbc_lnk_4d_multi_dp
 #     include "lbc_lnk_multi_generic.h90"
 #     undef ROUTINE_MULTI
@@ -130,10 +168,14 @@
    !                       !==  2D array and array of 2D pointer  ==!
    !
-#  define DIM_2d
-#     define ROUTINE_LNK           mpp_lnk_2d
-#     include "mpp_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     define MULTI
-#     define ROUTINE_LNK           mpp_lnk_2d_ptr
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+# define SINGLE_PRECISION
+#  define DIM_2d
+#     define ROUTINE_LNK           mpp_lnk_2d_sp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_2d_ptr_sp
 #     include "mpp_lnk_generic.h90"
 #     undef ROUTINE_LNK
@@ -144,9 +186,9 @@
    !
 #  define DIM_3d
-#     define ROUTINE_LNK           mpp_lnk_3d
-#     include "mpp_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     define MULTI
-#     define ROUTINE_LNK           mpp_lnk_3d_ptr
+#     define ROUTINE_LNK           mpp_lnk_3d_sp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_3d_ptr_sp
 #     include "mpp_lnk_generic.h90"
 #     undef ROUTINE_LNK
@@ -157,13 +199,55 @@
    !
 #  define DIM_4d
-#     define ROUTINE_LNK           mpp_lnk_4d
-#     include "mpp_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     define MULTI
-#     define ROUTINE_LNK           mpp_lnk_4d_ptr
-#     include "mpp_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     undef MULTI
-#  undef DIM_4d
+#     define ROUTINE_LNK           mpp_lnk_4d_sp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_4d_ptr_sp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     undef MULTI
+#  undef DIM_4d
+# undef SINGLE_PRECISION
+
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+#  define DIM_2d
+#     define ROUTINE_LNK           mpp_lnk_2d_dp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_2d_ptr_dp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_LNK           mpp_lnk_3d_dp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_3d_ptr_dp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_LNK           mpp_lnk_4d_dp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_4d_ptr_dp
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     undef MULTI
+#  undef DIM_4d
+
 
    !!----------------------------------------------------------------------
@@ -181,10 +265,14 @@
    !                       !==  2D array and array of 2D pointer  ==!
    !
-#  define DIM_2d
-#     define ROUTINE_NFD           mpp_nfd_2d
-#     include "mpp_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           mpp_nfd_2d_ptr
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+#  define SINGLE_PRECISION
+#  define DIM_2d
+#     define ROUTINE_NFD           mpp_nfd_2d_sp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_2d_ptr_sp
 #     include "mpp_nfd_generic.h90"
 #     undef ROUTINE_NFD
@@ -195,9 +283,9 @@
    !
 #  define DIM_3d
-#     define ROUTINE_NFD           mpp_nfd_3d
-#     include "mpp_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           mpp_nfd_3d_ptr
+#     define ROUTINE_NFD           mpp_nfd_3d_sp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_3d_ptr_sp
 #     include "mpp_nfd_generic.h90"
 #     undef ROUTINE_NFD
@@ -208,21 +296,60 @@
    !
 #  define DIM_4d
-#     define ROUTINE_NFD           mpp_nfd_4d
-#     include "mpp_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           mpp_nfd_4d_ptr
-#     include "mpp_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     undef MULTI
-#  undef DIM_4d
-
+#     define ROUTINE_NFD           mpp_nfd_4d_sp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_4d_ptr_sp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_4d
+#  undef SINGLE_PRECISION
+
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+#  define DIM_2d
+#     define ROUTINE_NFD           mpp_nfd_2d_dp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_2d_ptr_dp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_NFD           mpp_nfd_3d_dp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_3d_ptr_dp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NFD           mpp_nfd_4d_dp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_4d_ptr_dp
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_4d
 
    !!======================================================================
 
 
-
-   SUBROUTINE mpp_lbc_north_icb( pt2d, cd_type, psgn, kextj)
-      !!---------------------------------------------------------------------
+   !!======================================================================
+     !!---------------------------------------------------------------------
       !!                   ***  routine mpp_lbc_north_icb  ***
       !!
@@ -240,76 +367,14 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d     ! 2D array with extra halo
-      CHARACTER(len=1)        , INTENT(in   ) ::   cd_type  ! nature of pt3d grid-points
-      !                                                     !   = T ,  U , V , F or W -points
-      REAL(wp)                , INTENT(in   ) ::   psgn     ! = -1. the sign change across the
-      !!                                                    ! north fold, =  1. otherwise
-      INTEGER                 , INTENT(in   ) ::   kextj    ! Extra halo width at north fold
-      !
-      INTEGER ::   ji, jj, jr
-      INTEGER ::   ierr, itaille, ildi, ilei, iilb
-      INTEGER ::   ipj, ij, iproc
-      !
-      REAL(wp), DIMENSION(:,:)  , ALLOCATABLE  ::  ztab_e, znorthloc_e
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE  ::  znorthgloio_e
-      !!----------------------------------------------------------------------
-#if defined key_mpp_mpi
-      !
-      ipj=4
-      ALLOCATE(        ztab_e(jpiglo, 1-kextj:ipj+kextj)       ,       &
-     &            znorthloc_e(jpimax, 1-kextj:ipj+kextj)       ,       &
-     &          znorthgloio_e(jpimax, 1-kextj:ipj+kextj,jpni)    )
-      !
-      ztab_e(:,:)      = 0._wp
-      znorthloc_e(:,:) = 0._wp
-      !
-      ij = 1 - kextj
-      ! put the last ipj+2*kextj lines of pt2d into znorthloc_e 
-      DO jj = jpj - ipj + 1 - kextj , jpj + kextj
-         znorthloc_e(1:jpi,ij)=pt2d(1:jpi,jj)
-         ij = ij + 1
-      END DO
-      !
-      itaille = jpimax * ( ipj + 2*kextj )
-      !
-      IF( ln_timing ) CALL tic_tac(.TRUE.)
-      CALL MPI_ALLGATHER( znorthloc_e(1,1-kextj)    , itaille, MPI_DOUBLE_PRECISION,    &
-         &                znorthgloio_e(1,1-kextj,1), itaille, MPI_DOUBLE_PRECISION,    &
-         &                ncomm_north, ierr )
-      !
-      IF( ln_timing ) CALL tic_tac(.FALSE.)
-      !
-      DO jr = 1, ndim_rank_north            ! recover the global north array
-         iproc = nrank_north(jr) + 1
-         ildi = nldit (iproc)
-         ilei = nleit (iproc)
-         iilb = nimppt(iproc)
-         DO jj = 1-kextj, ipj+kextj
-            DO ji = ildi, ilei
-               ztab_e(ji+iilb-1,jj) = znorthgloio_e(ji,jj,jr)
-            END DO
-         END DO
-      END DO
-
-      ! 2. North-Fold boundary conditions
-      ! ----------------------------------
-      CALL lbc_nfd( ztab_e(:,1-kextj:ipj+kextj), cd_type, psgn, kextj )
-
-      ij = 1 - kextj
-      !! Scatter back to pt2d
-      DO jj = jpj - ipj + 1 - kextj , jpj + kextj
-         DO ji= 1, jpi
-            pt2d(ji,jj) = ztab_e(ji+nimpp-1,ij)
-         END DO
-         ij  = ij +1
-      END DO
-      !
-      DEALLOCATE( ztab_e, znorthloc_e, znorthgloio_e )
-      !
-#endif
-   END SUBROUTINE mpp_lbc_north_icb
-
-
-   SUBROUTINE mpp_lnk_2d_icb( cdname, pt2d, cd_type, psgn, kexti, kextj )
+#     define SINGLE_PRECISION
+#     define ROUTINE_LNK           mpp_lbc_north_icb_sp
+#     include "mpp_lbc_north_icb_generic.h90"
+#     undef ROUTINE_LNK
+#     undef SINGLE_PRECISION
+#     define ROUTINE_LNK           mpp_lbc_north_icb_dp
+#     include "mpp_lbc_north_icb_generic.h90"
+#     undef ROUTINE_LNK
+ 
+
       !!----------------------------------------------------------------------
       !!                  ***  routine mpp_lnk_2d_icb  ***
@@ -333,177 +398,14 @@
       !!                    nono   : number for local neighboring processors
       !!----------------------------------------------------------------------
-      CHARACTER(len=*)                                        , INTENT(in   ) ::   cdname      ! name of the calling subroutine
-      REAL(wp), DIMENSION(1-kexti:jpi+kexti,1-kextj:jpj+kextj), INTENT(inout) ::   pt2d     ! 2D array with extra halo
-      CHARACTER(len=1)                                        , INTENT(in   ) ::   cd_type  ! nature of ptab array grid-points
-      REAL(wp)                                                , INTENT(in   ) ::   psgn     ! sign used across the north fold
-      INTEGER                                                 , INTENT(in   ) ::   kexti    ! extra i-halo width
-      INTEGER                                                 , INTENT(in   ) ::   kextj    ! extra j-halo width
-      !
-      INTEGER  ::   jl   ! dummy loop indices
-      INTEGER  ::   imigr, iihom, ijhom        ! local integers
-      INTEGER  ::   ipreci, iprecj             !   -       -
-      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend
-      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend
-      !!
-      REAL(wp), DIMENSION(1-kexti:jpi+kexti,nn_hls+kextj,2) ::   r2dns, r2dsn
-      REAL(wp), DIMENSION(1-kextj:jpj+kextj,nn_hls+kexti,2) ::   r2dwe, r2dew
-      !!----------------------------------------------------------------------
-
-      ipreci = nn_hls + kexti      ! take into account outer extra 2D overlap area
-      iprecj = nn_hls + kextj
-
-      IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, 1, 1, 1, ld_lbc = .TRUE. )
-
-      ! 1. standard boundary treatment
-      ! ------------------------------
-      ! Order matters Here !!!!
-      !
-      !                                      ! East-West boundaries
-      !                                           !* Cyclic east-west
-      IF( l_Iperio ) THEN
-         pt2d(1-kexti:     1   ,:) = pt2d(jpim1-kexti: jpim1 ,:)       ! east
-         pt2d(  jpi  :jpi+kexti,:) = pt2d(     2     :2+kexti,:)       ! west
-         !
-      ELSE                                        !* closed
-         IF( .NOT. cd_type == 'F' )   pt2d(  1-kexti   :nn_hls   ,:) = 0._wp    ! east except at F-point
-                                      pt2d(jpi-nn_hls+1:jpi+kexti,:) = 0._wp    ! west
-      ENDIF
-      !                                      ! North-South boundaries
-      IF( l_Jperio ) THEN                         !* cyclic (only with no mpp j-split)
-         pt2d(:,1-kextj:     1   ) = pt2d(:,jpjm1-kextj:  jpjm1)       ! north
-         pt2d(:,  jpj  :jpj+kextj) = pt2d(:,     2     :2+kextj)       ! south
-      ELSE                                        !* closed
-         IF( .NOT. cd_type == 'F' )   pt2d(:,  1-kextj   :nn_hls   ) = 0._wp    ! north except at F-point
-                                      pt2d(:,jpj-nn_hls+1:jpj+kextj) = 0._wp    ! south
-      ENDIF
-      !
-
-      ! north fold treatment
-      ! -----------------------
-      IF( npolj /= 0 ) THEN
-         !
-         SELECT CASE ( jpni )
-                   CASE ( 1 )     ;   CALL lbc_nfd          ( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj )
-                   CASE DEFAULT   ;   CALL mpp_lbc_north_icb( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj )
-         END SELECT
-         !
-      ENDIF
-
-      ! 2. East and west directions exchange
-      ! ------------------------------------
-      ! we play with the neigbours AND the row number because of the periodicity
-      !
-      SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions
-      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case)
-         iihom = jpi-nreci-kexti
-         DO jl = 1, ipreci
-            r2dew(:,jl,1) = pt2d(nn_hls+jl,:)
-            r2dwe(:,jl,1) = pt2d(iihom +jl,:)
-         END DO
-      END SELECT
-      !
-      !                           ! Migrations
-      imigr = ipreci * ( jpj + 2*kextj )
-      !
-      IF( ln_timing ) CALL tic_tac(.TRUE.)
-      !
-      SELECT CASE ( nbondi )
-      CASE ( -1 )
-         CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req1 )
-         CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea )
-         CALL mpi_wait(ml_req1,ml_stat,ml_err)
-      CASE ( 0 )
-         CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 )
-         CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req2 )
-         CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea )
-         CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe )
-         CALL mpi_wait(ml_req1,ml_stat,ml_err)
-         CALL mpi_wait(ml_req2,ml_stat,ml_err)
-      CASE ( 1 )
-         CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 )
-         CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe )
-         CALL mpi_wait(ml_req1,ml_stat,ml_err)
-      END SELECT
-      !
-      IF( ln_timing ) CALL tic_tac(.FALSE.)
-      !
-      !                           ! Write Dirichlet lateral conditions
-      iihom = jpi - nn_hls
-      !
-      SELECT CASE ( nbondi )
-      CASE ( -1 )
-         DO jl = 1, ipreci
-            pt2d(iihom+jl,:) = r2dew(:,jl,2)
-         END DO
-      CASE ( 0 )
-         DO jl = 1, ipreci
-            pt2d(jl-kexti,:) = r2dwe(:,jl,2)
-            pt2d(iihom+jl,:) = r2dew(:,jl,2)
-         END DO
-      CASE ( 1 )
-         DO jl = 1, ipreci
-            pt2d(jl-kexti,:) = r2dwe(:,jl,2)
-         END DO
-      END SELECT
-
-
-      ! 3. North and south directions
-      ! -----------------------------
-      ! always closed : we play only with the neigbours
-      !
-      IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions
-         ijhom = jpj-nrecj-kextj
-         DO jl = 1, iprecj
-            r2dsn(:,jl,1) = pt2d(:,ijhom +jl)
-            r2dns(:,jl,1) = pt2d(:,nn_hls+jl)
-         END DO
-      ENDIF
-      !
-      !                           ! Migrations
-      imigr = iprecj * ( jpi + 2*kexti )
-      !
-      IF( ln_timing ) CALL tic_tac(.TRUE.)
-      !
-      SELECT CASE ( nbondj )
-      CASE ( -1 )
-         CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req1 )
-         CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono )
-         CALL mpi_wait(ml_req1,ml_stat,ml_err)
-      CASE ( 0 )
-         CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 )
-         CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req2 )
-         CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono )
-         CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso )
-         CALL mpi_wait(ml_req1,ml_stat,ml_err)
-         CALL mpi_wait(ml_req2,ml_stat,ml_err)
-      CASE ( 1 )
-         CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 )
-         CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso )
-         CALL mpi_wait(ml_req1,ml_stat,ml_err)
-      END SELECT
-      !
-      IF( ln_timing ) CALL tic_tac(.FALSE.)
-      !
-      !                           ! Write Dirichlet lateral conditions
-      ijhom = jpj - nn_hls
-      !
-      SELECT CASE ( nbondj )
-      CASE ( -1 )
-         DO jl = 1, iprecj
-            pt2d(:,ijhom+jl) = r2dns(:,jl,2)
-         END DO
-      CASE ( 0 )
-         DO jl = 1, iprecj
-            pt2d(:,jl-kextj) = r2dsn(:,jl,2)
-            pt2d(:,ijhom+jl) = r2dns(:,jl,2)
-         END DO
-      CASE ( 1 )
-         DO jl = 1, iprecj
-            pt2d(:,jl-kextj) = r2dsn(:,jl,2)
-         END DO
-      END SELECT
-      !
-   END SUBROUTINE mpp_lnk_2d_icb
-   
+
+#     define SINGLE_PRECISION
+#     define ROUTINE_LNK           mpp_lnk_2d_icb_sp
+#     include "mpp_lnk_icb_generic.h90"
+#     undef ROUTINE_LNK
+#     undef SINGLE_PRECISION
+#     define ROUTINE_LNK           mpp_lnk_2d_icb_dp
+#     include "mpp_lnk_icb_generic.h90"
+#     undef ROUTINE_LNK
+  
 END MODULE lbclnk
 
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbcnfd.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbcnfd.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lbcnfd.F90	(revision 12603)
@@ -26,26 +26,43 @@
 
    INTERFACE lbc_nfd
-      MODULE PROCEDURE   lbc_nfd_2d    , lbc_nfd_3d    , lbc_nfd_4d
-      MODULE PROCEDURE   lbc_nfd_2d_ptr, lbc_nfd_3d_ptr, lbc_nfd_4d_ptr
-      MODULE PROCEDURE   lbc_nfd_2d_ext
+      MODULE PROCEDURE   lbc_nfd_2d_sp    , lbc_nfd_3d_sp    , lbc_nfd_4d_sp
+      MODULE PROCEDURE   lbc_nfd_2d_ptr_sp, lbc_nfd_3d_ptr_sp, lbc_nfd_4d_ptr_sp
+      MODULE PROCEDURE   lbc_nfd_2d_ext_sp
+      MODULE PROCEDURE   lbc_nfd_2d_dp    , lbc_nfd_3d_dp    , lbc_nfd_4d_dp
+      MODULE PROCEDURE   lbc_nfd_2d_ptr_dp, lbc_nfd_3d_ptr_dp, lbc_nfd_4d_ptr_dp
+      MODULE PROCEDURE   lbc_nfd_2d_ext_dp
    END INTERFACE
    !
    INTERFACE lbc_nfd_nogather
 !                        ! Currently only 4d array version is needed
-     MODULE PROCEDURE   lbc_nfd_nogather_2d    , lbc_nfd_nogather_3d
-     MODULE PROCEDURE   lbc_nfd_nogather_4d
-     MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr, lbc_nfd_nogather_3d_ptr
+     MODULE PROCEDURE   lbc_nfd_nogather_2d_sp    , lbc_nfd_nogather_3d_sp
+     MODULE PROCEDURE   lbc_nfd_nogather_4d_sp
+     MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr_sp, lbc_nfd_nogather_3d_ptr_sp
+     MODULE PROCEDURE   lbc_nfd_nogather_2d_dp    , lbc_nfd_nogather_3d_dp
+     MODULE PROCEDURE   lbc_nfd_nogather_4d_dp
+     MODULE PROCEDURE   lbc_nfd_nogather_2d_ptr_dp, lbc_nfd_nogather_3d_ptr_dp
 !     MODULE PROCEDURE   lbc_nfd_nogather_4d_ptr
    END INTERFACE
 
-   TYPE, PUBLIC ::   PTR_2D   !: array of 2D pointers (also used in lib_mpp)
-      REAL(wp), DIMENSION (:,:)    , POINTER ::   pt2d
-   END TYPE PTR_2D
-   TYPE, PUBLIC ::   PTR_3D   !: array of 3D pointers (also used in lib_mpp)
-      REAL(wp), DIMENSION (:,:,:)  , POINTER ::   pt3d
-   END TYPE PTR_3D
-   TYPE, PUBLIC ::   PTR_4D   !: array of 4D pointers (also used in lib_mpp)
-      REAL(wp), DIMENSION (:,:,:,:), POINTER ::   pt4d
-   END TYPE PTR_4D
+   TYPE, PUBLIC ::   PTR_2D_dp   !: array of 2D pointers (also used in lib_mpp)
+      REAL(dp), DIMENSION (:,:)    , POINTER ::   pt2d
+   END TYPE PTR_2D_dp
+   TYPE, PUBLIC ::   PTR_3D_dp   !: array of 3D pointers (also used in lib_mpp)
+      REAL(dp), DIMENSION (:,:,:)  , POINTER ::   pt3d
+   END TYPE PTR_3D_dp
+   TYPE, PUBLIC ::   PTR_4D_dp   !: array of 4D pointers (also used in lib_mpp)
+      REAL(dp), DIMENSION (:,:,:,:), POINTER ::   pt4d
+   END TYPE PTR_4D_dp
+
+   TYPE, PUBLIC ::   PTR_2D_sp   !: array of 2D pointers (also used in lib_mpp)
+      REAL(sp), DIMENSION (:,:)    , POINTER ::   pt2d
+   END TYPE PTR_2D_sp
+   TYPE, PUBLIC ::   PTR_3D_sp   !: array of 3D pointers (also used in lib_mpp)
+      REAL(sp), DIMENSION (:,:,:)  , POINTER ::   pt3d
+   END TYPE PTR_3D_sp
+   TYPE, PUBLIC ::   PTR_4D_sp   !: array of 4D pointers (also used in lib_mpp)
+      REAL(sp), DIMENSION (:,:,:,:), POINTER ::   pt4d
+   END TYPE PTR_4D_sp
+
 
    PUBLIC   lbc_nfd            ! north fold conditions
@@ -75,12 +92,16 @@
    !!----------------------------------------------------------------------
    !
-   !                       !==  2D array and array of 2D pointer  ==!
-   !
-#  define DIM_2d
-#     define ROUTINE_NFD           lbc_nfd_2d
-#     include "lbc_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           lbc_nfd_2d_ptr
+   !                       !==  SINGLE PRECISION VERSIONS
+   !
+   !
+   !                       !==  2D array and array of 2D pointer  ==!
+   !
+#  define SINGLE_PRECISION
+#  define DIM_2d
+#     define ROUTINE_NFD           lbc_nfd_2d_sp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_2d_ptr_sp
 #     include "lbc_nfd_generic.h90"
 #     undef ROUTINE_NFD
@@ -91,5 +112,5 @@
    !
 #  define DIM_2d
-#     define ROUTINE_NFD           lbc_nfd_2d_ext
+#     define ROUTINE_NFD           lbc_nfd_2d_ext_sp
 #     include "lbc_nfd_ext_generic.h90"
 #     undef ROUTINE_NFD
@@ -99,22 +120,22 @@
    !
 #  define DIM_3d
-#     define ROUTINE_NFD           lbc_nfd_3d
-#     include "lbc_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           lbc_nfd_3d_ptr
-#     include "lbc_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     undef MULTI
-#  undef DIM_3d
-   !
-   !                       !==  4D array and array of 4D pointer  ==!
-   !
-#  define DIM_4d
-#     define ROUTINE_NFD           lbc_nfd_4d
-#     include "lbc_nfd_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           lbc_nfd_4d_ptr
+#     define ROUTINE_NFD           lbc_nfd_3d_sp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_3d_ptr_sp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NFD           lbc_nfd_4d_sp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_4d_ptr_sp
 #     include "lbc_nfd_generic.h90"
 #     undef ROUTINE_NFD
@@ -127,31 +148,31 @@
    !
 #  define DIM_2d
-#     define ROUTINE_NFD           lbc_nfd_nogather_2d
-#     include "lbc_nfd_nogather_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr
-#     include "lbc_nfd_nogather_generic.h90"
-#     undef ROUTINE_NFD
-#     undef MULTI
-#  undef DIM_2d
-   !
-   !                       !==  3D array and array of 3D pointer  ==!
-   !
-#  define DIM_3d
-#     define ROUTINE_NFD           lbc_nfd_nogather_3d
-#     include "lbc_nfd_nogather_generic.h90"
-#     undef ROUTINE_NFD
-#     define MULTI
-#     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr
-#     include "lbc_nfd_nogather_generic.h90"
-#     undef ROUTINE_NFD
-#     undef MULTI
-#  undef DIM_3d
-   !
-   !                       !==  4D array and array of 4D pointer  ==!
-   !
-#  define DIM_4d
-#     define ROUTINE_NFD           lbc_nfd_nogather_4d
+#     define ROUTINE_NFD           lbc_nfd_nogather_2d_sp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr_sp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_NFD           lbc_nfd_nogather_3d_sp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr_sp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NFD           lbc_nfd_nogather_4d_sp
 #     include "lbc_nfd_nogather_generic.h90"
 #     undef ROUTINE_NFD
@@ -162,6 +183,101 @@
 !#     undef MULTI
 #  undef DIM_4d
-
-   !!----------------------------------------------------------------------
+#  undef SINGLE_PRECISION
+
+   !!----------------------------------------------------------------------
+   !
+   !                       !==  DOUBLE PRECISION VERSIONS
+   !
+   !
+   !                       !==  2D array and array of 2D pointer  ==!
+   !
+#  define DIM_2d
+#     define ROUTINE_NFD           lbc_nfd_2d_dp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_2d_ptr_dp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  2D array with extra haloes  ==!
+   !
+#  define DIM_2d
+#     define ROUTINE_NFD           lbc_nfd_2d_ext_dp
+#     include "lbc_nfd_ext_generic.h90"
+#     undef ROUTINE_NFD
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_NFD           lbc_nfd_3d_dp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_3d_ptr_dp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NFD           lbc_nfd_4d_dp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_4d_ptr_dp
+#     include "lbc_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_4d
+   !
+   !  lbc_nfd_nogather routines
+   !
+   !                       !==  2D array and array of 2D pointer  ==!
+   !
+#  define DIM_2d
+#     define ROUTINE_NFD           lbc_nfd_nogather_2d_dp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_nogather_2d_ptr_dp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_NFD           lbc_nfd_nogather_3d_dp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           lbc_nfd_nogather_3d_ptr_dp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NFD           lbc_nfd_nogather_4d_dp
+#     include "lbc_nfd_nogather_generic.h90"
+#     undef ROUTINE_NFD
+!#     define MULTI
+!#     define ROUTINE_NFD           lbc_nfd_nogather_4d_ptr
+!#     include "lbc_nfd_nogather_generic.h90"
+!#     undef ROUTINE_NFD
+!#     undef MULTI
+#  undef DIM_4d
+
+   !!----------------------------------------------------------------------
+
 
 
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lib_mpp.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lib_mpp.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/lib_mpp.F90	(revision 12603)
@@ -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
@@ -260,4 +270,50 @@
 
 
+   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
+      !!----------------------------------------------------------------------
+      !
+#if defined key_mpp_mpi
+      CALL mpi_isend( pmess, kbytes, mpi_double_precision, kdest , ktyp, mpi_comm_oce, md_req, iflag )
+#endif
+      !
+   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
+
+
    SUBROUTINE mpprecv( ktyp, pmess, kbytes, ksource )
       !!----------------------------------------------------------------------
@@ -288,4 +344,61 @@
    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_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
+
 
    SUBROUTINE mppgather( ptab, kp, pio )
@@ -351,5 +464,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 +472,5 @@
       INTEGER ::   idvar
       INTEGER ::   ierr, ilocalcomm
-      COMPLEX(wp), ALLOCATABLE, DIMENSION(:) ::   ytmp
+      COMPLEX(dp), ALLOCATABLE, DIMENSION(:) ::   ytmp
       !!----------------------------------------------------------------------
 #if defined key_mpp_mpi
@@ -432,6 +545,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 +594,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 +674,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 +726,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 +778,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 +838,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 +857,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 +1125,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 +1281,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 +1295,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
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_allreduce_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_allreduce_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_allreduce_generic.h90	(revision 12603)
@@ -1,7 +1,13 @@
 !                          !==  IN: ptab is an array  ==!
 #   if defined REAL_TYPE
-#      define ARRAY_TYPE(i)    REAL(wp)         , INTENT(inout) ::   ARRAY_IN(i)
-#      define TMP_TYPE(i)      REAL(wp)         , ALLOCATABLE   ::   work(i)
-#      define MPI_TYPE mpi_double_precision
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i)    REAL(sp)         , INTENT(inout) ::   ARRAY_IN(i)
+#         define TMP_TYPE(i)      REAL(sp)         , ALLOCATABLE   ::   work(i)
+#         define MPI_TYPE mpi_real
+#      else
+#         define ARRAY_TYPE(i)    REAL(dp)         , INTENT(inout) ::   ARRAY_IN(i)
+#         define TMP_TYPE(i)      REAL(dp)         , ALLOCATABLE   ::   work(i)
+#         define MPI_TYPE mpi_double_precision
+#      endif 
 #   endif
 #   if defined INTEGER_TYPE
@@ -11,6 +17,6 @@
 #   endif
 #   if defined COMPLEX_TYPE
-#      define ARRAY_TYPE(i)    COMPLEX(wp)       , INTENT(inout) ::   ARRAY_IN(i)
-#      define TMP_TYPE(i)      COMPLEX(wp)       , ALLOCATABLE   ::   work(i)
+#      define ARRAY_TYPE(i)    COMPLEX(dp)       , INTENT(inout) ::   ARRAY_IN(i)
+#      define TMP_TYPE(i)      COMPLEX(dp)       , ALLOCATABLE   ::   work(i)
 #      define MPI_TYPE mpi_double_complex
 #   endif
@@ -75,4 +81,5 @@
    END SUBROUTINE ROUTINE_ALLREDUCE
 
+#undef PRECISION
 #undef ARRAY_TYPE
 #undef ARRAY_IN
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_lnk_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_lnk_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_lnk_generic.h90	(revision 12603)
@@ -5,5 +5,9 @@
 #   define OPT_K(k)                 ,ipf
 #   if defined DIM_2d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)                , INTENT(inout) ::   ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp)                , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp)                , INTENT(inout) ::   ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
 #      define K_SIZE(ptab)             1
@@ -11,5 +15,9 @@
 #   endif
 #   if defined DIM_3d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)                , INTENT(inout) ::   ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp)                , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp)                , INTENT(inout) ::   ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
@@ -17,5 +25,9 @@
 #   endif
 #   if defined DIM_4d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)                , INTENT(inout) ::   ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp)                , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp)                , INTENT(inout) ::   ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
@@ -23,5 +35,9 @@
 #   endif
 #else
-#   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
+#   if defined SINGLE_PRECISION
+#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
+#   else
+#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
+#   endif
 #   define NAT_IN(k)                cd_nat
 #   define SGN_IN(k)                psgn
@@ -44,4 +60,14 @@
 #   endif
 #endif
+
+# if defined SINGLE_PRECISION
+#    define PRECISION sp
+#    define SENDROUTINE mppsend_sp
+#    define RECVROUTINE mpprecv_sp
+# else
+#    define PRECISION dp
+#    define SENDROUTINE mppsend_dp
+#    define RECVROUTINE mpprecv_dp
+# endif
 
 #if defined MULTI
@@ -67,8 +93,8 @@
       INTEGER  ::   ifill_we, ifill_ea, ifill_so, ifill_no
       INTEGER  ::   ihl                          ! number of ranks and rows to be communicated 
-      REAL(wp) ::   zland
+      REAL(PRECISION) ::   zland
       INTEGER , DIMENSION(MPI_STATUS_SIZE)        ::   istat          ! for mpi_isend
-      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_we, zrcv_we, zsnd_ea, zrcv_ea   ! east -west  & west - east  halos
-      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_so, zrcv_so, zsnd_no, zrcv_no   ! north-south & south-north  halos
+      REAL(PRECISION), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_we, zrcv_we, zsnd_ea, zrcv_ea   ! east -west  & west - east  halos
+      REAL(PRECISION), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_so, zrcv_so, zsnd_no, zrcv_no   ! north-south & south-north  halos
       LOGICAL  ::   llsend_we, llsend_ea, llsend_no, llsend_so       ! communication send
       LOGICAL  ::   llrecv_we, llrecv_ea, llrecv_no, llrecv_so       ! communication receive 
@@ -174,9 +200,9 @@
       !
       ! non-blocking send of the western/eastern side using local temporary arrays
-      IF( llsend_we )   CALL mppsend( 1, zsnd_we(1,1,1,1,1), isize, nowe, ireq_we )
-      IF( llsend_ea )   CALL mppsend( 2, zsnd_ea(1,1,1,1,1), isize, noea, ireq_ea )
+      IF( llsend_we )   CALL SENDROUTINE( 1, zsnd_we(1,1,1,1,1), isize, nowe, ireq_we )
+      IF( llsend_ea )   CALL SENDROUTINE( 2, zsnd_ea(1,1,1,1,1), isize, noea, ireq_ea )
       ! blocking receive of the western/eastern halo in local temporary arrays
-      IF( llrecv_we )   CALL mpprecv( 2, zrcv_we(1,1,1,1,1), isize, nowe )
-      IF( llrecv_ea )   CALL mpprecv( 1, zrcv_ea(1,1,1,1,1), isize, noea )
+      IF( llrecv_we )   CALL RECVROUTINE( 2, zrcv_we(1,1,1,1,1), isize, nowe )
+      IF( llrecv_ea )   CALL RECVROUTINE( 1, zrcv_ea(1,1,1,1,1), isize, noea )
       !
       IF( ln_timing ) CALL tic_tac(.FALSE.)
@@ -289,9 +315,9 @@
       !
       ! non-blocking send of the southern/northern side
-      IF( llsend_so )   CALL mppsend( 3, zsnd_so(1,1,1,1,1), isize, noso, ireq_so )
-      IF( llsend_no )   CALL mppsend( 4, zsnd_no(1,1,1,1,1), isize, nono, ireq_no )
+      IF( llsend_so )   CALL SENDROUTINE( 3, zsnd_so(1,1,1,1,1), isize, noso, ireq_so )
+      IF( llsend_no )   CALL SENDROUTINE( 4, zsnd_no(1,1,1,1,1), isize, nono, ireq_no )
       ! blocking receive of the southern/northern halo
-      IF( llrecv_so )   CALL mpprecv( 4, zrcv_so(1,1,1,1,1), isize, noso )
-      IF( llrecv_no )   CALL mpprecv( 3, zrcv_no(1,1,1,1,1), isize, nono )
+      IF( llrecv_so )   CALL RECVROUTINE( 4, zrcv_so(1,1,1,1,1), isize, noso )
+      IF( llrecv_no )   CALL RECVROUTINE( 3, zrcv_no(1,1,1,1,1), isize, nono )
       !
       IF( ln_timing ) CALL tic_tac(.FALSE.)
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_loc_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_loc_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_loc_generic.h90	(revision 12603)
@@ -1,5 +1,13 @@
                           !==  IN: ptab is an array  ==!
-#      define ARRAY_TYPE(i,j,k)    REAL(wp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k)
-#      define MASK_TYPE(i,j,k)     REAL(wp)        , INTENT(in   ) ::   MASK_IN(i,j,k)
+#   if defined SINGLE_PRECISION
+#      define ARRAY_TYPE(i,j,k)    REAL(sp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k)
+#      define MASK_TYPE(i,j,k)     REAL(sp)        , INTENT(in   ) ::   MASK_IN(i,j,k)
+#      define PRECISION sp
+#   else
+#      define ARRAY_TYPE(i,j,k)    REAL(dp)        , INTENT(in   ) ::   ARRAY_IN(i,j,k)
+#      define MASK_TYPE(i,j,k)     REAL(dp)        , INTENT(in   ) ::   MASK_IN(i,j,k)
+#      define PRECISION dp
+#   endif
+
 #   if defined DIM_2d
 #      define ARRAY_IN(i,j,k)   ptab(i,j)
@@ -30,5 +38,5 @@
       ARRAY_TYPE(:,:,:)                            ! array on which loctrans operation is applied
       MASK_TYPE(:,:,:)                             ! local mask
-      REAL(wp)        , INTENT(  out) ::   pmin    ! Global minimum of ptab
+      REAL(PRECISION)        , INTENT(  out) ::   pmin    ! Global minimum of ptab
       INDEX_TYPE(:)                                ! index of minimum in global frame
 # if defined key_mpp_mpi
@@ -36,7 +44,7 @@
       INTEGER  ::   ierror, ii, idim
       INTEGER  ::   index0
-      REAL(wp) ::   zmin     ! local minimum
+      REAL(PRECISION) ::   zmin     ! local minimum
       INTEGER , DIMENSION(:), ALLOCATABLE  ::   ilocs
-      REAL(wp), DIMENSION(2,1) ::   zain, zaout
+      REAL(dp), DIMENSION(2,1) ::   zain, zaout
       !!-----------------------------------------------------------------------
       !
@@ -99,4 +107,6 @@
    END SUBROUTINE ROUTINE_LOC
 
+
+#undef PRECISION
 #undef ARRAY_TYPE
 #undef MAX_TYPE
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_nfd_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_nfd_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/LBC/mpp_nfd_generic.h90	(revision 12603)
@@ -5,5 +5,9 @@
 #   define LBC_ARG                  (jf)
 #   if defined DIM_2d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)     , INTENT(inout) ::   ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp)     , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp)     , INTENT(inout) ::   ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
 #      define K_SIZE(ptab)             1
@@ -11,5 +15,9 @@
 #   endif
 #   if defined DIM_3d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)     , INTENT(inout) ::   ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp)     , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp)     , INTENT(inout) ::   ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
@@ -17,5 +25,9 @@
 #   endif
 #   if defined DIM_4d
-#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)     , INTENT(inout) ::   ptab(f)
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp)     , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp)     , INTENT(inout) ::   ptab(f)
+#      endif
 #      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
 #      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
@@ -24,5 +36,9 @@
 #else
 !                          !==  IN: ptab is an array  ==!
-#   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
+#   if defined SINGLE_PRECISION
+#      define ARRAY_TYPE(i,j,k,l,f)    REAL(sp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
+#   else
+#      define ARRAY_TYPE(i,j,k,l,f)    REAL(dp)         , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
+#   endif
 #   define NAT_IN(k)                cd_nat
 #   define SGN_IN(k)                psgn
@@ -45,4 +61,16 @@
 #   endif
 #endif
+
+# if defined SINGLE_PRECISION
+#    define PRECISION sp
+#    define SENDROUTINE mppsend_sp
+#    define RECVROUTINE mpprecv_sp
+#    define MPI_TYPE MPI_REAL
+# else
+#    define PRECISION dp
+#    define SENDROUTINE mppsend_dp
+#    define RECVROUTINE mpprecv_dp
+#    define MPI_TYPE MPI_DOUBLE_PRECISION
+# endif
 
    SUBROUTINE ROUTINE_NFD( ptab, cd_nat, psgn, kfld )
@@ -66,8 +94,8 @@
       INTEGER, DIMENSION(:,:),          ALLOCATABLE ::   jj_s  ! position of sent lines
       INTEGER, DIMENSION(:),            ALLOCATABLE ::   ipj_s ! number of sent lines
-      REAL(wp), DIMENSION(:,:,:)      , ALLOCATABLE ::   ztabl
-      REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   ztab, ztabr
-      REAL(wp), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   znorthloc, zfoldwk      
-      REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   znorthgloio
+      REAL(PRECISION), DIMENSION(:,:,:)      , ALLOCATABLE ::   ztabl
+      REAL(PRECISION), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   ztab, ztabr
+      REAL(PRECISION), DIMENSION(:,:,:,:,:)  , ALLOCATABLE ::   znorthloc, zfoldwk      
+      REAL(PRECISION), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   znorthgloio
       !!----------------------------------------------------------------------
       !
@@ -160,5 +188,5 @@
          DO jr = 1, nsndto
             IF( nfipproc(isendto(jr),jpnj) /= narea-1 .AND. nfipproc(isendto(jr),jpnj) /= -1 ) THEN
-               CALL mppsend( 5, znorthloc, ibuffsize, nfipproc(isendto(jr),jpnj), ml_req_nf(jr) )
+               CALL SENDROUTINE( 5, znorthloc, ibuffsize, nfipproc(isendto(jr),jpnj), ml_req_nf(jr) )
             ENDIF
          END DO
@@ -176,5 +204,5 @@
             ENDIF
             IF( iproc /= narea-1 .AND. iproc /= -1 ) THEN
-               CALL mpprecv(5, zfoldwk, ibuffsize, iproc)
+               CALL RECVROUTINE(5, zfoldwk, ibuffsize, iproc)
                js = 0
                DO jf = 1, ipf ; DO jj = 1, ipj_s(jf)
@@ -246,6 +274,6 @@
          ! start waiting time measurement
          IF( ln_timing ) CALL tic_tac(.TRUE.)
-         CALL MPI_ALLGATHER( znorthloc  , ibuffsize, MPI_DOUBLE_PRECISION,                &
-            &                znorthgloio, ibuffsize, MPI_DOUBLE_PRECISION, ncomm_north, ierr )
+         CALL MPI_ALLGATHER( znorthloc  , ibuffsize, MPI_TYPE,                &
+            &                znorthgloio, ibuffsize, MPI_TYPE, ncomm_north, ierr )
          !
          ! stop waiting time measurement
@@ -298,4 +326,8 @@
    END SUBROUTINE ROUTINE_NFD
 
+#undef PRECISION
+#undef MPI_TYPE
+#undef SENDROUTINE
+#undef RECVROUTINE
 #undef ARRAY_TYPE
 #undef NAT_IN
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/ddatetoymdhms.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/ddatetoymdhms.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/ddatetoymdhms.h90	(revision 12603)
@@ -21,5 +21,5 @@
 
       !! * Arguments
-      real(wp), INTENT(IN) :: ddate
+      real(dp), INTENT(IN) :: ddate
       INTEGER, INTENT(OUT) :: kyea
       INTEGER, INTENT(OUT) :: kmon
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/obs_read_prof.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/obs_read_prof.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/obs_read_prof.F90	(revision 12603)
@@ -140,7 +140,7 @@
          & zphi, &
          & zlam
-      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
+      REAL(dp), DIMENSION(:), ALLOCATABLE :: &
          & zdat
-      REAL(wp), DIMENSION(knumfiles) :: &
+      REAL(dp), DIMENSION(knumfiles) :: &
          & djulini, &
          & djulend
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/obs_read_surf.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/obs_read_surf.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/OBS/obs_read_surf.F90	(revision 12603)
@@ -112,7 +112,7 @@
          & zphi, &
          & zlam
-      REAL(wp), DIMENSION(:), ALLOCATABLE :: &
+      REAL(dp), DIMENSION(:), ALLOCATABLE :: &
          & zdat
-      REAL(wp), DIMENSION(knumfiles) :: &
+      REAL(dp), DIMENSION(knumfiles) :: &
          & djulini, &
          & djulend
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/SBC/sbcfwb.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/SBC/sbcfwb.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/SBC/sbcfwb.F90	(revision 12603)
@@ -71,5 +71,5 @@
       REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   ztmsk_tospread, zerp_cor    !   -      -
       REAL(wp)   ,DIMENSION(1) ::   z_fwfprv  
-      COMPLEX(wp),DIMENSION(1) ::   y_fwfnow  
+      COMPLEX(dp),DIMENSION(1) ::   y_fwfnow  
       !!----------------------------------------------------------------------
       !
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/STO/stopar.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/STO/stopar.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/STO/stopar.F90	(revision 12603)
@@ -686,5 +686,5 @@
       INTEGER  :: jsto, jseed
       INTEGER(KIND=8)     ::   ziseed(4)           ! RNG seeds in integer type
-      REAL(KIND=8)        ::   zrseed(4)           ! RNG seeds in real type (with same bits to save in restart)
+      REAL(KIND=dp)       ::   zrseed(4)           ! RNG seeds in double-precision (with same bits to save in restart)
       CHARACTER(LEN=9)    ::   clsto2d='sto2d_000' ! stochastic parameter variable name
       CHARACTER(LEN=9)    ::   clsto3d='sto3d_000' ! stochastic parameter variable name
@@ -744,5 +744,5 @@
       INTEGER  :: jsto, jseed
       INTEGER(KIND=8)     ::   ziseed(4)           ! RNG seeds in integer type
-      REAL(KIND=8)        ::   zrseed(4)           ! RNG seeds in real type (with same bits to save in restart)
+      REAL(KIND=dp)       ::   zrseed(4)           ! RNG seeds in double-precision (with same bits to save in restart)
       CHARACTER(LEN=20)   ::   clkt                ! ocean time-step defined as a character
       CHARACTER(LEN=50)   ::   clname              ! restart file name
@@ -827,5 +827,5 @@
       !!
       INTEGER  :: ji, jj
-      REAL(KIND=8) :: gran   ! Gaussian random number (forced KIND=8 as in kiss_gaussian)
+      REAL(wp) :: gran   ! Gaussian random number (forced KIND=8 as in kiss_gaussian)
 
       DO_2D_11_11
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/TRA/traadv_fct.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/TRA/traadv_fct.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/TRA/traadv_fct.F90	(revision 12603)
@@ -374,12 +374,12 @@
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
       INTEGER  ::   ikm1         ! local integer
-      REAL(wp) ::   zpos, zneg, zbt, za, zb, zc, zbig, zrtrn    ! local scalars
-      REAL(wp) ::   zau, zbu, zcu, zav, zbv, zcv, zup, zdo            !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zbetup, zbetdo, zbup, zbdo
-      !!----------------------------------------------------------------------
-      !
-      zbig  = 1.e+40_wp
-      zrtrn = 1.e-15_wp
-      zbetup(:,:,:) = 0._wp   ;   zbetdo(:,:,:) = 0._wp
+      REAL(dp) ::   zpos, zneg, zbt, za, zb, zc, zbig, zrtrn    ! local scalars
+      REAL(dp) ::   zau, zbu, zcu, zav, zbv, zcv, zup, zdo            !   -      -
+      REAL(dp), DIMENSION(jpi,jpj,jpk) :: zbetup, zbetdo, zbup, zbdo
+      !!----------------------------------------------------------------------
+      !
+      zbig  = 1.e+40_dp
+      zrtrn = 1.e-15_dp
+      zbetup(:,:,:) = 0._dp   ;   zbetdo(:,:,:) = 0._dp
 
       ! Search local extrema
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/TRA/traadv_ubs.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/TRA/traadv_ubs.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/TRA/traadv_ubs.F90	(revision 12603)
@@ -270,5 +270,5 @@
       !!----------------------------------------------------------------------
       !
-      zbig  = 1.e+40_wp
+      zbig  = 1.e+38_wp
       zrtrn = 1.e-15_wp
       zbetup(:,:,:) = 0._wp   ;   zbetdo(:,:,:) = 0._wp
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/ZDF/zdfddm.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/ZDF/zdfddm.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/ZDF/zdfddm.F90	(revision 12603)
@@ -77,6 +77,8 @@
       REAL(wp) ::   zaw, zbw, zrw   ! local scalars
       REAL(wp) ::   zdt, zds
-      REAL(wp) ::   zinr, zrr       !   -      -
-      REAL(wp) ::   zavft, zavfs    !   -      -
+      REAL(wp) ::   zinr            !   -      -
+      REAL(dp) ::         zrr       !   -      -
+      REAL(wp) ::   zavft           !   -      -
+      REAL(dp) ::          zavfs    !   -      -
       REAL(wp) ::   zavdt, zavds    !   -      -
       REAL(wp), DIMENSION(jpi,jpj) ::   zrau, zmsks, zmskf, zmskd1, zmskd2, zmskd3
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/lib_fortran.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/lib_fortran.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/lib_fortran.F90	(revision 12603)
@@ -143,9 +143,9 @@
       !!----------------------------------------------------------------------
       REAL(wp),  INTENT(in   ) ::   ptab(:,:) ! array on which operation is applied
-      COMPLEX(wp)              ::  local_sum_2d
-      !
-      !!-----------------------------------------------------------------------
-      !
-      COMPLEX(wp)::   ctmp
+      COMPLEX(dp)              ::  local_sum_2d
+      !
+      !!-----------------------------------------------------------------------
+      !
+      COMPLEX(dp)::   ctmp
       REAL(wp)   ::   ztmp
       INTEGER    ::   ji, jj    ! dummy loop indices
@@ -161,5 +161,5 @@
          DO ji = 1, ipi
             ztmp =  ptab(ji,jj) * tmask_i(ji,jj)
-            CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
+            CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp )
          END DO
       END DO
@@ -172,9 +172,9 @@
       !!----------------------------------------------------------------------
       REAL(wp),  INTENT(in   ) ::   ptab(:,:,:) ! array on which operation is applied
-      COMPLEX(wp)              ::  local_sum_3d
-      !
-      !!-----------------------------------------------------------------------
-      !
-      COMPLEX(wp)::   ctmp
+      COMPLEX(dp)              ::  local_sum_3d
+      !
+      !!-----------------------------------------------------------------------
+      !
+      COMPLEX(dp)::   ctmp
       REAL(wp)   ::   ztmp
       INTEGER    ::   ji, jj, jk   ! dummy loop indices
@@ -192,5 +192,5 @@
           DO ji = 1, ipi
              ztmp =  ptab(ji,jj,jk) * tmask_i(ji,jj)
-             CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
+             CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp )
           END DO
         END DO
@@ -313,8 +313,8 @@
       !!              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
+      COMPLEX(dp), INTENT(in   ) ::   ydda
+      COMPLEX(dp), INTENT(inout) ::   yddb
+      !
+      REAL(dp) :: zerr, zt1, zt2  ! local work variables
       !!-----------------------------------------------------------------------
       !
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/lib_fortran_generic.h90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/lib_fortran_generic.h90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/lib_fortran_generic.h90	(revision 12603)
@@ -40,5 +40,5 @@
       REAL(wp)                              ::   FUNCTION_GLOB_OP   ! global sum
       !!
-      COMPLEX(wp)::   ctmp
+      COMPLEX(dp)::   ctmp
       REAL(wp)   ::   ztmp
       INTEGER    ::   ji, jj, jk   ! dummy loop indices
@@ -50,5 +50,5 @@
       ipk = K_SIZE(ptab)   ! 3rd dimension
       !
-      ctmp = CMPLX( 0.e0, 0.e0, wp )   ! warning ctmp is cumulated
+      ctmp = CMPLX( 0.e0, 0.e0, dp )   ! warning ctmp is cumulated
    
       DO jk = 1, ipk
@@ -56,5 +56,5 @@
           DO ji = 1, ipi
              ztmp =  ARRAY_IN(ji,jj,jk) * MASK_ARRAY(ji,jj)
-             CALL DDPDD( CMPLX( ztmp, 0.e0, wp ), ctmp )
+             CALL DDPDD( CMPLX( ztmp, 0.e0, dp ), ctmp )
           END DO
         END DO
@@ -109,5 +109,5 @@
       REAL(wp)                              ::   FUNCTION_GLOB_OP   ! global sum
       !!
-      COMPLEX(wp)::   ctmp
+      COMPLEX(dp)::   ctmp
       REAL(wp)   ::   ztmp
       INTEGER    ::   jk       ! dummy loop indices
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/nemogcm.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/nemogcm.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/nemogcm.F90	(revision 12603)
@@ -373,4 +373,12 @@
          WRITE(numout,*) "     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "
          WRITE(numout,*)
+         
+         ! Print the working precision to ocean.output
+         IF (wp == dp) THEN
+            WRITE(numout,*) "Working precision = double-precision"
+         ELSE
+            WRITE(numout,*) "Working precision = single-precision"
+         ENDIF
+         WRITE(numout,*)
          !
          WRITE(numout,cform_aaa)                                        ! Flag AAAAAAA
Index: NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/par_kind.F90
===================================================================
--- NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/par_kind.F90	(revision 12546)
+++ NEMO/branches/2020/dev_r12512_HPC-04_mcastril_Mixed_Precision_implementation/src/OCE/par_kind.F90	(revision 12603)
@@ -24,5 +24,9 @@
    INTEGER, PUBLIC, PARAMETER ::   sp = SELECTED_REAL_KIND( 6, 37)   !: single precision (real 4)
    INTEGER, PUBLIC, PARAMETER ::   dp = SELECTED_REAL_KIND(12,307)   !: double precision (real 8)
+# if defined key_single
+   INTEGER, PUBLIC, PARAMETER ::   wp = sp                              !: working precision
+# else
    INTEGER, PUBLIC, PARAMETER ::   wp = dp                              !: working precision
+# endif
 
    !                                                                !!** Integer **
