Index: NEMO/branches/2020/dev_r12702_ASINTER-02_emanuelaclementi_Waves/src/OCE/IOM/iom.F90
===================================================================
--- NEMO/branches/2020/dev_r12702_ASINTER-02_emanuelaclementi_Waves/src/OCE/IOM/iom.F90	(revision 12990)
+++ NEMO/branches/2020/dev_r12702_ASINTER-02_emanuelaclementi_Waves/src/OCE/IOM/iom.F90	(revision 13710)
@@ -21,4 +21,5 @@
    !!----------------------------------------------------------------------
    USE dom_oce         ! ocean space and time domain
+   USE domutl          ! 
    USE c1d             ! 1D vertical configuration
    USE flo_oce         ! floats module declarations
@@ -34,5 +35,4 @@
    USE ice      , ONLY :   jpl
 #endif
-   USE domngb          ! ocean space and time domain
    USE phycst          ! physical constants
    USE dianam          ! build name of file
@@ -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
   
@@ -94,5 +101,5 @@
 CONTAINS
 
-   SUBROUTINE iom_init( cdname, fname, ld_tmppatch, ld_closedef ) 
+   SUBROUTINE iom_init( cdname, fname, ld_closedef ) 
       !!----------------------------------------------------------------------
       !!                     ***  ROUTINE   ***
@@ -103,5 +110,4 @@
       CHARACTER(len=*),           INTENT(in)  :: cdname
       CHARACTER(len=*), OPTIONAL, INTENT(in)  :: fname
-      LOGICAL         , OPTIONAL, INTENT(in)  :: ld_tmppatch
       LOGICAL         , OPTIONAL, INTENT(in)  :: ld_closedef
 #if defined key_iomput
@@ -116,22 +122,8 @@
       REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zt_bnds, zw_bnds
       REAL(wp), DIMENSION(2,jpkam1)         :: za_bnds   ! ABL vertical boundaries
-      LOGICAL ::   ll_tmppatch = .TRUE.    !: seb: patch before we remove periodicity
-      INTEGER ::   nldi_save, nlei_save    !:      and close boundaries in output files
-      INTEGER ::   nldj_save, nlej_save    !:
       LOGICAL ::   ll_closedef = .TRUE.
-      !!----------------------------------------------------------------------
-      !
-      ! seb: patch before we remove periodicity and close boundaries in output files
-      IF( PRESENT(ld_tmppatch) ) THEN   ;   ll_tmppatch = ld_tmppatch
-      ELSE                              ;   ll_tmppatch = .TRUE.
-      ENDIF
-      IF ( ll_tmppatch ) THEN
-         nldi_save = nldi   ;   nlei_save = nlei
-         nldj_save = nldj   ;   nlej_save = nlej
-         IF( nimpp           ==      1 ) nldi = 1
-         IF( nimpp + jpi - 1 == jpiglo ) nlei = jpi
-         IF( njmpp           ==      1 ) nldj = 1
-         IF( njmpp + jpj - 1 == jpjglo ) nlej = jpj
-      ENDIF
+      LOGICAL ::   ll_exist
+      !!----------------------------------------------------------------------
+      !
       IF ( PRESENT(ld_closedef) ) ll_closedef = ld_closedef
       !
@@ -150,10 +142,10 @@
 
       SELECT CASE ( nleapy )        ! Choose calendar for IOIPSL
-      CASE ( 1)   ; CALL xios_define_calendar( TYPE = "Gregorian", time_origin = xios_date(irefyear,irefmonth,irefday,00,00,00), &
-          &                                    start_date = xios_date(nyear,nmonth,nday,0,0,0) )
-      CASE ( 0)   ; CALL xios_define_calendar( TYPE = "NoLeap"   , time_origin = xios_date(irefyear,irefmonth,irefday,00,00,00), &
-          &                                    start_date = xios_date(nyear,nmonth,nday,0,0,0) )
-      CASE (30)   ; CALL xios_define_calendar( TYPE = "D360"     , time_origin = xios_date(irefyear,irefmonth,irefday,00,00,00), &
-          &                                    start_date = xios_date(nyear,nmonth,nday,0,0,0) )
+      CASE ( 1)   ;   CALL xios_define_calendar( TYPE = "Gregorian", time_origin = xios_date(irefyear,irefmonth,irefday,0,0,0),   &
+          &                                                          start_date  = xios_date(   nyear,   nmonth,   nday,0,0,0) )
+      CASE ( 0)   ;   CALL xios_define_calendar( TYPE = "NoLeap"   , time_origin = xios_date(irefyear,irefmonth,irefday,0,0,0),   &
+          &                                                          start_date  = xios_date(   nyear,   nmonth,   nday,0,0,0) )
+      CASE (30)   ;   CALL xios_define_calendar( TYPE = "D360"     , time_origin = xios_date(irefyear,irefmonth,irefday,0,0,0),   &
+          &                                                          start_date  = xios_date(   nyear,   nmonth,   nday,0,0,0) )
       END SELECT
 
@@ -169,8 +161,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(Nis0:Nie0, Njs0:Nje0), dp))
+            CALL iom_set_domain_attr("grid_U", area = real( e1e2u(Nis0:Nie0, Njs0:Nje0), dp))
+            CALL iom_set_domain_attr("grid_V", area = real( e1e2v(Nis0:Nie0, Njs0:Nje0), dp))
+            CALL iom_set_domain_attr("grid_W", area = real( e1e2t(Nis0:Nie0, Njs0:Nje0), dp))
             CALL set_grid_bounds( "T", glamf, gphif, glamt, gphit )
             CALL set_grid_bounds( "U", glamv, gphiv, glamu, gphiu )
@@ -192,8 +184,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(Nis0:Nie0, Njs0:Nje0), dp))
+            CALL iom_set_domain_attr("grid_U", area = real(e1u_crs(Nis0:Nie0, Njs0:Nje0) * e2u_crs(Nis0:Nie0, Njs0:Nje0), dp))
+            CALL iom_set_domain_attr("grid_V", area = real(e1v_crs(Nis0:Nie0, Njs0:Nje0) * e2v_crs(Nis0:Nie0, Njs0:Nje0), dp))
+            CALL iom_set_domain_attr("grid_W", area = real(e1e2t_crs(Nis0:Nie0, Njs0:Nje0), 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 )
@@ -239,5 +231,5 @@
           CALL iom_set_axis_attr( "ghw_abl", bounds=za_bnds )
 
-          CALL iom_set_axis_attr( "nfloat", (/ (REAL(ji,wp), ji=1,jpnfl) /) )
+          CALL iom_set_axis_attr(  "nfloat", (/ (REAL(ji,wp), ji=1,jpnfl) /) )
 # if defined key_si3
           CALL iom_set_axis_attr( "ncatice", (/ (REAL(ji,wp), ji=1,jpl) /) )
@@ -252,5 +244,8 @@
           CALL iom_set_axis_attr( "iax_26C", (/ REAL(26,wp) /) )   ! strange syntaxe and idea...
           CALL iom_set_axis_attr( "iax_28C", (/ REAL(28,wp) /) )   ! strange syntaxe and idea...
-          CALL iom_set_axis_attr( "basin"  , (/ (REAL(ji,wp), ji=1,5) /) )
+          ! for diaprt, we need to define an axis which size can be 1 (default) or 5 (if the file subbasins.nc exists)
+          INQUIRE( FILE = 'subbasins.nc', EXIST = ll_exist )
+          nbasin = 1 + 4 * COUNT( (/ll_exist/) )
+          CALL iom_set_axis_attr( "basin"  , (/ (REAL(ji,wp), ji=1,nbasin) /) )
       ENDIF
       !
@@ -281,8 +276,4 @@
       DEALLOCATE( zt_bnds, zw_bnds )
       !
-      IF ( ll_tmppatch ) THEN
-         nldi = nldi_save   ;   nlei = nlei_save
-         nldj = nldj_save   ;   nlej = nlej_save
-      ENDIF
 #endif
       !
@@ -363,5 +354,5 @@
            rst_file = TRIM(clpath)//TRIM(cn_ocerst_in)
         ELSE
-           rst_file = TRIM(clpath)//'1_'//TRIM(cn_ocerst_in)
+           rst_file = TRIM(clpath)//TRIM(Agrif_CFixed())//'_'//TRIM(cn_ocerst_in)
         ENDIF
 !set name of the restart file and enable available fields
@@ -664,5 +655,5 @@
 
 
-   SUBROUTINE iom_open( cdname, kiomid, ldwrt, kdom, ldstop, ldiof, kdlev, cdcomp )
+   SUBROUTINE iom_open( cdname, kiomid, ldwrt, ldstop, ldiof, kdlev, cdcomp )
       !!---------------------------------------------------------------------
       !!                   ***  SUBROUTINE  iom_open  ***
@@ -673,5 +664,4 @@
       INTEGER         , INTENT(  out)           ::   kiomid   ! iom identifier of the opened file
       LOGICAL         , INTENT(in   ), OPTIONAL ::   ldwrt    ! open in write modeb          (default = .FALSE.)
-      INTEGER         , INTENT(in   ), OPTIONAL ::   kdom     ! Type of domain to be written (default = jpdom_local_noovlap)
       LOGICAL         , INTENT(in   ), OPTIONAL ::   ldstop   ! stop if open to read a non-existing file (default = .TRUE.)
       LOGICAL         , INTENT(in   ), OPTIONAL ::   ldiof    ! Interp On the Fly, needed for AGRIF (default = .FALSE.)
@@ -686,12 +676,9 @@
       LOGICAL               ::   llok      ! check the existence 
       LOGICAL               ::   llwrt     ! local definition of ldwrt
-      LOGICAL               ::   llnoov    ! local definition to read overlap
       LOGICAL               ::   llstop    ! local definition of ldstop
       LOGICAL               ::   lliof     ! local definition of ldiof
       INTEGER               ::   icnt      ! counter for digits in clcpu (max = jpmax_digits)
       INTEGER               ::   iln, ils  ! lengths of character
-      INTEGER               ::   idom      ! type of domain
       INTEGER               ::   istop     ! 
-      INTEGER, DIMENSION(2,5) ::   idompar ! domain parameters: 
       ! local number of points for x,y dimensions
       ! position of first local point for x,y dimensions
@@ -725,7 +712,4 @@
       ELSE                        ;   lliof = .FALSE.
       ENDIF
-      ! do we read the overlap 
-      ! ugly patch SM+JMM+RB to overwrite global definition in some cases
-      llnoov = (jpni * jpnj ) == jpnij .AND. .NOT. lk_agrif
       ! create the file name by added, if needed, TRIM(Agrif_CFixed()) and TRIM(clsuffix)
       ! =============
@@ -767,37 +751,4 @@
          lxios_sini = .TRUE.
       ENDIF
-      IF( llwrt ) THEN
-         ! check the domain definition
-! JMM + SM: ugly patch before getting the new version of lib_mpp)
-!         idom = jpdom_local_noovlap   ! default definition
-         IF( llnoov ) THEN   ;   idom = jpdom_local_noovlap   ! default definition
-         ELSE                ;   idom = jpdom_local_full      ! default definition
-         ENDIF
-         IF( PRESENT(kdom) )   idom = kdom
-         ! create the domain informations
-         ! =============
-         SELECT CASE (idom)
-         CASE (jpdom_local_full)
-            idompar(:,1) = (/ jpi             , jpj              /)
-            idompar(:,2) = (/ nimpp           , njmpp            /)
-            idompar(:,3) = (/ nimpp + jpi - 1 , njmpp + jpj - 1  /)
-            idompar(:,4) = (/ nldi - 1        , nldj - 1         /)
-            idompar(:,5) = (/ jpi - nlei      , jpj - nlej       /)
-         CASE (jpdom_local_noextra)
-            idompar(:,1) = (/ nlci            , nlcj             /)
-            idompar(:,2) = (/ nimpp           , njmpp            /)
-            idompar(:,3) = (/ nimpp + nlci - 1, njmpp + nlcj - 1 /)
-            idompar(:,4) = (/ nldi - 1        , nldj - 1         /)
-            idompar(:,5) = (/ nlci - nlei     , nlcj - nlej      /)
-         CASE (jpdom_local_noovlap)
-            idompar(:,1) = (/ nlei  - nldi + 1, nlej  - nldj + 1 /)
-            idompar(:,2) = (/ nimpp + nldi - 1, njmpp + nldj - 1 /)
-            idompar(:,3) = (/ nimpp + nlei - 1, njmpp + nlej - 1 /)
-            idompar(:,4) = (/ 0               , 0                /)
-            idompar(:,5) = (/ 0               , 0                /)
-         CASE DEFAULT
-            CALL ctl_stop( TRIM(clinfo), 'wrong value of kdom, only jpdom_local* cases are accepted' )
-         END SELECT
-      ENDIF
       ! Open the NetCDF file
       ! =============
@@ -823,5 +774,5 @@
       ENDIF
       IF( istop == nstop ) THEN   ! no error within this routine
-         CALL iom_nf90_open( clname, kiomid, llwrt, llok, idompar, kdlev = kdlev, cdcomp = cdcomp )
+         CALL iom_nf90_open( clname, kiomid, llwrt, llok, kdlev = kdlev, cdcomp = cdcomp )
       ENDIF
       !
@@ -941,8 +892,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 +992,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,57 +1006,131 @@
       !
       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)
-      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
-      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
+   END SUBROUTINE iom_g1d_dp
+
+   SUBROUTINE iom_g2d_sp( kiomid, kdom, cdvar, pvar, ktime, cd_type, psgn, kfill, 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(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
+      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W)
+      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.): (not) change sign across the north fold
+      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk
+      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 ::   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 )
-      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
-      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( 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,   &
+             &                                                      cd_type = cd_type, psgn   = psgn  , kfill = kfill,   &
+             &                                                      kstart  = kstart , kcount = kcount, ldxios=ldxios  )
+            pvar = ztmp_pvar
+            DEALLOCATE(ztmp_pvar)
+         ENDIF
+      ENDIF
+   END SUBROUTINE iom_g2d_sp
+
+   SUBROUTINE iom_g2d_dp( kiomid, kdom, cdvar, pvar, ktime, cd_type, psgn, kfill, 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
+      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W)
+      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.): (not) change sign across the north fold
+      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk
+      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 ::   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
+         IF( iom_file(kiomid)%nfid > 0 ) CALL iom_get_123d( kiomid, kdom, cdvar      , pv_r2d = pvar  , ktime = ktime,   &
+            &                                                       cd_type = cd_type, psgn   = psgn  , kfill = kfill,   &
+            &                                                       kstart  = kstart , kcount = kcount, ldxios=ldxios  )
+      ENDIF
+   END SUBROUTINE iom_g2d_dp
+
+   SUBROUTINE iom_g3d_sp( kiomid, kdom, cdvar, pvar, ktime, cd_type, psgn, kfill, 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(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
+      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W)
+      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.) : (not) change sign across the north fold
+      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk
+      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 ::   ldxios    ! read data using XIOS
+      !
+      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,   &
+            &                                                       cd_type = cd_type, psgn   = psgn  , kfill = kfill,   &
+            &                                                       kstart  = kstart , kcount = kcount, 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, cd_type, psgn, kfill, 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
+      CHARACTER(len=1), INTENT(in   )              , OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W)
+      REAL(dp)        , INTENT(in   )              , OPTIONAL ::   psgn      ! -1.(1.) : (not) change sign across the north fold
+      INTEGER         , INTENT(in   )              , OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk
+      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 ::   ldxios    ! read data using XIOS
+      !
+      IF( kiomid > 0 ) THEN
+         IF( iom_file(kiomid)%nfid > 0 ) THEN
+            CALL iom_get_123d( kiomid, kdom, cdvar      , pv_r3d = pvar  , ktime = ktime,   &
+            &                                                       cd_type = cd_type, psgn   = psgn  , kfill = kfill,   &
+            &                                                       kstart  = kstart , kcount = kcount, ldxios=ldxios  )
+         END IF
+      ENDIF
+   END SUBROUTINE iom_g3d_dp
+
    !!----------------------------------------------------------------------
 
-   SUBROUTINE iom_get_123d( kiomid, kdom  , cdvar ,   &
-         &                  pv_r1d, pv_r2d, pv_r3d,   &
-         &                  ktime , kstart, kcount,   &
-         &                  lrowattr, ldxios        )
+   SUBROUTINE iom_get_123d( kiomid , kdom, cdvar, pv_r1d, pv_r2d, pv_r3d, ktime ,   &
+         &                  cd_type, psgn, kfill, kstart, kcount, ldxios )
       !!-----------------------------------------------------------------------
       !!                  ***  ROUTINE  iom_get_123d  ***
@@ -1062,23 +1140,20 @@
       !! ** Method : read ONE record at each CALL
       !!-----------------------------------------------------------------------
-      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), 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)
-      INTEGER                    , INTENT(in   ), OPTIONAL ::   ktime      ! record number
-      INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kstart     ! start position of the reading in each axis 
-      INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kcount     ! number of points to be read 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     ! use XIOS to read restart
-      !
-      LOGICAL                        ::   llxios       ! local definition for XIOS read
-      LOGICAL                        ::   llnoov      ! local definition to read overlap
-      LOGICAL                        ::   luse_jattr  ! local definition to read open_ocean_jstart file attribute
-      INTEGER                        ::   jstartrow   ! start point for 2nd dimension optionally set by file attribute
+      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), 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
+      CHARACTER(len=1)           , INTENT(in   ), OPTIONAL ::   cd_type   ! nature of grid-points (T, U, V, F, W)
+      REAL(dp)                   , INTENT(in   ), OPTIONAL ::   psgn      ! -1.(1.) : (not) change sign across the north fold
+      INTEGER                    , INTENT(in   ), OPTIONAL ::   kfill     ! value of kfillmode in lbc_lbk
+      INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kstart    ! start position of the reading in each axis 
+      INTEGER , DIMENSION(:)     , INTENT(in   ), OPTIONAL ::   kcount    ! number of points to be read in each axis
+      LOGICAL                    , INTENT(in   ), OPTIONAL ::   ldxios    ! use XIOS to read restart
+      !
+      LOGICAL                        ::   llok        ! true if ok!
+      LOGICAL                        ::   llxios      ! local definition for XIOS read
       INTEGER                        ::   jl          ! loop on number of dimension 
       INTEGER                        ::   idom        ! type of domain
@@ -1096,12 +1171,14 @@
       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
+      REAL(wp)                       ::   zsgn        ! local value of psgn
       INTEGER                        ::   itmp        ! temporary integer
       CHARACTER(LEN=256)             ::   clinfo      ! info character
       CHARACTER(LEN=256)             ::   clname      ! file name
       CHARACTER(LEN=1)               ::   clrankpv, cldmspc      ! 
-      LOGICAL                        ::   ll_depth_spec ! T => if kstart, kcount present then *only* use values for 3rd spatial dimension.
+      CHARACTER(LEN=1)               ::   cl_type     ! local value of cd_type
+      LOGICAL                        ::   ll_only3rd  ! 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
       !---------------------------------------------------------------------
       !
@@ -1110,33 +1187,26 @@
       !
       llxios = .FALSE.
-      if(PRESENT(ldxios)) llxios = ldxios
-      idvar = iom_varid( kiomid, cdvar ) 
+      IF( PRESENT(ldxios) )   llxios = ldxios
+      !
       idom = kdom
+      istop = nstop
       !
       IF(.NOT.llxios) THEN
          clname = iom_file(kiomid)%name   !   esier to read
          clinfo = '          iom_get_123d, file: '//trim(clname)//', var: '//trim(cdvar)
-         ! local definition of the domain ?
-         ! do we read the overlap 
-         ! ugly patch SM+JMM+RB to overwrite global definition in some cases
-         llnoov = (jpni * jpnj ) == jpnij .AND. .NOT. lk_agrif 
          ! check kcount and kstart optionals parameters...
-         IF( PRESENT(kcount) .AND. (.NOT. PRESENT(kstart)) ) CALL ctl_stop(trim(clinfo), 'kcount present needs kstart present')
-         IF( PRESENT(kstart) .AND. (.NOT. PRESENT(kcount)) ) CALL ctl_stop(trim(clinfo), 'kstart present needs kcount present')
-         IF( PRESENT(kstart) .AND. idom /= jpdom_unknown .AND.  idom /= jpdom_autoglo_xy  ) &
-     &          CALL ctl_stop(trim(clinfo), 'kstart present needs kdom = jpdom_unknown or kdom = jpdom_autoglo_xy')
-
-         luse_jattr = .false.
-         IF( PRESENT(lrowattr) ) THEN
-            IF( lrowattr .AND. idom /= jpdom_data   ) CALL ctl_stop(trim(clinfo), 'lrowattr present and true needs kdom = jpdom_data')
-            IF( lrowattr .AND. idom == jpdom_data   ) luse_jattr = .true.
-         ENDIF
-
+         IF( PRESENT(kcount) .AND. .NOT. PRESENT(kstart) ) CALL ctl_stop(trim(clinfo), 'kcount present needs kstart present')
+         IF( PRESENT(kstart) .AND. .NOT. PRESENT(kcount) ) CALL ctl_stop(trim(clinfo), 'kstart present needs kcount present')
+         IF( PRESENT(kstart) .AND. idom /= jpdom_unknown .AND. idom /= jpdom_auto_xy ) &
+            &          CALL ctl_stop(TRIM(clinfo), 'kstart present needs idom = jpdom_unknown or idom = jpdom_auto_xy')
+         IF( idom == jpdom_auto_xy .AND. .NOT. PRESENT(kstart) ) &
+            &          CALL ctl_stop(TRIM(clinfo), 'idom = jpdom_auto_xy requires kstart to be present')
+         !
          ! Search for the variable in the data base (eventually actualize data)
-         istop = nstop
          !
+         idvar = iom_varid( kiomid, cdvar ) 
          IF( idvar > 0 ) THEN
-            ! to write iom_file(kiomid)%dimsz in a shorter way !
-            idimsz(:) = iom_file(kiomid)%dimsz(:, idvar) 
+            !
+            idimsz(:) = iom_file(kiomid)%dimsz(:, idvar)      ! to write iom_file(kiomid)%dimsz in a shorter way
             inbdim = iom_file(kiomid)%ndims(idvar)            ! number of dimensions in the file
             idmspc = inbdim                                   ! number of spatial dimensions in the file
@@ -1144,27 +1214,11 @@
             IF( idmspc > 3 )   CALL ctl_stop(trim(clinfo), 'the file has more than 3 spatial dimensions this case is not coded...') 
             !
-            ! update idom definition...
-            ! Identify the domain in case of jpdom_auto(glo/dta) definition
-            IF( idom == jpdom_autoglo_xy ) THEN
-               ll_depth_spec = .TRUE.
-               idom = jpdom_autoglo
-            ELSE
-               ll_depth_spec = .FALSE.
-            ENDIF
-            IF( idom == jpdom_autoglo .OR. idom == jpdom_autodta ) THEN            
-               IF( idom == jpdom_autoglo ) THEN   ;   idom = jpdom_global 
-               ELSE                               ;   idom = jpdom_data
-               ENDIF
+            ! Identify the domain in case of jpdom_auto definition
+            IF( idom == jpdom_auto .OR. idom == jpdom_auto_xy ) THEN            
+               idom = jpdom_global   ! default
+               ! else: if the file name finishes with _xxxx.nc with xxxx any number
                ind1 = INDEX( clname, '_', back = .TRUE. ) + 1
                ind2 = INDEX( clname, '.', back = .TRUE. ) - 1
                IF( ind2 > ind1 ) THEN   ;   IF( VERIFY( clname(ind1:ind2), '0123456789' ) == 0 )   idom = jpdom_local   ;   ENDIF
-            ENDIF
-            ! Identify the domain in case of jpdom_local definition
-            IF( idom == jpdom_local ) THEN
-               IF(     idimsz(1) == jpi               .AND. idimsz(2) == jpj               ) THEN   ;   idom = jpdom_local_full
-               ELSEIF( idimsz(1) == nlci              .AND. idimsz(2) == nlcj              ) THEN   ;   idom = jpdom_local_noextra
-               ELSEIF( idimsz(1) == (nlei - nldi + 1) .AND. idimsz(2) == (nlej - nldj + 1) ) THEN   ;   idom = jpdom_local_noovlap
-               ELSE   ;   CALL ctl_stop( trim(clinfo), 'impossible to identify the local domain' )
-               ENDIF
             ENDIF
             !
@@ -1179,22 +1233,30 @@
             WRITE(cldmspc , fmt='(i1)') idmspc
             !
-            !!GS: we consider 2D data as 3D data with vertical dim size = 1
-            !IF(     idmspc <  irankpv ) THEN 
-            !   CALL ctl_stop( TRIM(clinfo), 'The file has only '//cldmspc//' spatial dimension',   &
-            !      &                         'it is impossible to read a '//clrankpv//'D array from this file...' )
-            !ELSEIF( idmspc == irankpv ) THEN
-            IF( idmspc == irankpv ) THEN
+            IF(     idmspc <  irankpv ) THEN                     ! it seems we want to read more than we can...
+               IF(     irankpv == 3 .AND. idmspc == 2 ) THEN     !   3D input array from 2D spatial data in the file:
+                  llok = inlev == 1                              !     -> 3rd dimension must be equal to 1
+               ELSEIF( irankpv == 3 .AND. idmspc == 1 ) THEN     !   3D input array from 1D spatial data in the file:
+                  llok = inlev == 1 .AND. SIZE(pv_r3d, 2) == 1   !     -> 2nd and 3rd dimensions must be equal to 1
+               ELSEIF( irankpv == 2 .AND. idmspc == 2 ) THEN     !   2D input array from 1D spatial data in the file:
+                  llok = SIZE(pv_r2d, 2) == 1                    !     -> 2nd dimension must be equal to 1
+               ELSE
+                  llok = .FALSE.
+               ENDIF
+               IF( .NOT. llok )   CALL ctl_stop( TRIM(clinfo), 'The file has only '//cldmspc//' spatial dimension',   &
+                  &                                            '=> cannot read a true '//clrankpv//'D array from this file...' )
+            ELSEIF( idmspc == irankpv ) THEN
                IF( PRESENT(pv_r1d) .AND. idom /= jpdom_unknown )   &
                   &   CALL ctl_stop( TRIM(clinfo), 'case not coded...You must use jpdom_unknown' )
-            ELSEIF( idmspc >  irankpv ) THEN
+            ELSEIF( idmspc >  irankpv ) THEN                     ! it seems we want to read less than we should...
                   IF( PRESENT(pv_r2d) .AND. itime == 1 .AND. idimsz(3) == 1 .AND. idmspc == 3 ) THEN
-                     CALL ctl_warn( trim(clinfo), '2D array but 3 spatial dimensions for the data...'              ,   &
+                     CALL ctl_warn( trim(clinfo), '2D array input but 3 spatial dimensions in the file...'              ,   &
                            &         'As the size of the z dimension is 1 and as we try to read the first record, ',   &
                            &         'we accept this case, even if there is a possible mix-up between z and time dimension' )   
                      idmspc = idmspc - 1
-                  ELSE
-                     CALL ctl_stop( TRIM(clinfo), 'To keep iom lisibility, when reading a '//clrankpv//'D array,'         ,   &
-                        &                         'we do not accept data with '//cldmspc//' spatial dimensions',   &
-                        &                         'Use ncwa -a to suppress the unnecessary dimensions' )
+                  !!GS: possibility to read 3D ABL atmopsheric forcing and use 1st level to force BULK simulation
+                  !ELSE
+                  !   CALL ctl_stop( TRIM(clinfo), 'To keep iom lisibility, when reading a '//clrankpv//'D array,',   &
+                  !      &                         'we do not accept data with '//cldmspc//' spatial dimensions'  ,   &
+                  !      &                         'Use ncwa -a to suppress the unnecessary dimensions' )
                   ENDIF
             ENDIF
@@ -1202,45 +1264,29 @@
             ! definition of istart and icnt
             !
-            icnt  (:) = 1
-            istart(:) = 1
-            istart(idmspc+1) = itime
-   
-            IF( PRESENT(kstart) .AND. .NOT. ll_depth_spec ) THEN 
-               istart(1:idmspc) = kstart(1:idmspc) 
-               icnt  (1:idmspc) = kcount(1:idmspc)
-            ELSE
-               IF(idom == jpdom_unknown ) THEN
-                  icnt(1:idmspc) = idimsz(1:idmspc)
-               ELSE 
-                  IF( .NOT. PRESENT(pv_r1d) ) THEN   !   not a 1D array
-                     IF(     idom == jpdom_data    ) THEN
-                        jstartrow = 1
-                        IF( luse_jattr ) THEN
-                           CALL iom_getatt(kiomid, 'open_ocean_jstart', jstartrow ) ! -999 is returned if the attribute is not found
-                           jstartrow = MAX(1,jstartrow)
-                        ENDIF
-                        istart(1:2) = (/ mig(1), mjg(1) + jstartrow - 1 /)  ! icnt(1:2) done below
-                     ELSEIF( idom == jpdom_global  ) THEN ; istart(1:2) = (/ nimpp , njmpp  /)  ! icnt(1:2) done below
-                     ENDIF
-                     ! we do not read the overlap                     -> we start to read at nldi, nldj
-! JMM + SM: ugly patch before getting the new version of lib_mpp)
-!                  IF( idom /= jpdom_local_noovlap )   istart(1:2) = istart(1:2) + (/ nldi - 1, nldj - 1 /)
-                     IF( llnoov .AND. idom /= jpdom_local_noovlap ) istart(1:2) = istart(1:2) + (/ nldi - 1, nldj - 1 /)
-                  ! we do not read the overlap and the extra-halos -> from nldi to nlei and from nldj to nlej 
-! JMM + SM: ugly patch before getting the new version of lib_mpp)
-!                  icnt(1:2) = (/ nlei - nldi + 1, nlej - nldj + 1 /)
-                     IF( llnoov ) THEN   ;   icnt(1:2) = (/ nlei - nldi + 1, nlej - nldj + 1 /)
-                     ELSE                ;   icnt(1:2) = (/ nlci           , nlcj            /)
-                     ENDIF
-                     IF( PRESENT(pv_r3d) ) THEN
-                        IF( idom == jpdom_data ) THEN                        ;                               icnt(3) = inlev
-                        ELSEIF( ll_depth_spec .AND. PRESENT(kstart) ) THEN   ;   istart(3) = kstart(3)   ;   icnt(3) = kcount(3)
-                        ELSE                                                 ;                               icnt(3) = inlev
-                        ENDIF
-                     ENDIF
+            icnt  (:) = 1              ! default definition (simple way to deal with special cases listed above) 
+            istart(:) = 1              ! default definition (simple way to deal with special cases listed above) 
+            istart(idmspc+1) = itime   ! temporal dimenstion
+            !
+            IF( idom == jpdom_unknown ) THEN
+               IF( PRESENT(kstart) .AND. idom /= jpdom_auto_xy ) THEN 
+                  istart(1:idmspc) = kstart(1:idmspc) 
+                  icnt  (1:idmspc) = kcount(1:idmspc)
+               ELSE
+                  icnt  (1:idmspc) = idimsz(1:idmspc)
+               ENDIF
+            ELSE   !   not a 1D array as pv_r1d requires jpdom_unknown
+               ! we do not read the overlap and the extra-halos -> from Nis0 to Nie0 and from Njs0 to Nje0 
+               IF( idom == jpdom_global )   istart(1:2) = (/ mig0(Nis0), mjg0(Njs0) /)
+               icnt(1:2) = (/ Ni_0, Nj_0 /)
+               IF( PRESENT(pv_r3d) ) THEN
+                  IF( idom == jpdom_auto_xy ) THEN
+                     istart(3) = kstart(3)
+                     icnt  (3) = kcount(3)
+                  ELSE
+                     icnt  (3) = inlev
                   ENDIF
                ENDIF
             ENDIF
-
+            !
             ! check that istart and icnt can be used with this file
             !-
@@ -1253,5 +1299,5 @@
                ENDIF
             END DO
-
+            !
             ! check that icnt matches the input array
             !-     
@@ -1263,19 +1309,10 @@
             ELSE
                IF( irankpv == 2 ) THEN
-! JMM + SM: ugly patch before getting the new version of lib_mpp)
-!               ishape(1:2) = SHAPE(pv_r2d(nldi:nlei,nldj:nlej  ))   ;   ctmp1 = 'd(nldi:nlei,nldj:nlej)'
-                  IF( llnoov ) THEN ; ishape(1:2)=SHAPE(pv_r2d(nldi:nlei,nldj:nlej  )) ; ctmp1='d(nldi:nlei,nldj:nlej)'
-                  ELSE              ; ishape(1:2)=SHAPE(pv_r2d(1   :nlci,1   :nlcj  )) ; ctmp1='d(1:nlci,1:nlcj)'
-                  ENDIF
+                  ishape(1:2) = SHAPE(pv_r2d(Nis0:Nie0,Njs0:Nje0  ))   ;   ctmp1 = 'd(Nis0:Nie0,Njs0:Nje0)'
                ENDIF
                IF( irankpv == 3 ) THEN 
-! JMM + SM: ugly patch before getting the new version of lib_mpp)
-!               ishape(1:3) = SHAPE(pv_r3d(nldi:nlei,nldj:nlej,:))   ;   ctmp1 = 'd(nldi:nlei,nldj:nlej,:)'
-                  IF( llnoov ) THEN ; ishape(1:3)=SHAPE(pv_r3d(nldi:nlei,nldj:nlej,:)) ; ctmp1='d(nldi:nlei,nldj:nlej,:)'
-                  ELSE              ; ishape(1:3)=SHAPE(pv_r3d(1   :nlci,1   :nlcj,:)) ; ctmp1='d(1:nlci,1:nlcj,:)'
-                  ENDIF
+                  ishape(1:3) = SHAPE(pv_r3d(Nis0:Nie0,Njs0:Nje0,:))   ;   ctmp1 = 'd(Nis0:Nie0,Njs0:Nje0,:)'
                ENDIF
-            ENDIF
-         
+            ENDIF         
             DO jl = 1, irankpv
                WRITE( ctmp2, FMT="(', ', i1,'): ', i5,' /= icnt(', i1,'):', i5)" ) jl, ishape(jl), jl, icnt(jl)
@@ -1289,17 +1326,7 @@
          IF( idvar > 0 .AND. istop == nstop ) THEN   ! no additional errors until this point...
             !
-         ! find the right index of the array to be read
-! JMM + SM: ugly patch before getting the new version of lib_mpp)
-!         IF( idom /= jpdom_unknown ) THEN   ;   ix1 = nldi   ;   ix2 = nlei      ;   iy1 = nldj   ;   iy2 = nlej
-!         ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2)
-!         ENDIF
-            IF( llnoov ) THEN
-               IF( idom /= jpdom_unknown ) THEN   ;   ix1 = nldi   ;   ix2 = nlei      ;   iy1 = nldj   ;   iy2 = nlej
-               ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2)
-               ENDIF
-            ELSE
-               IF( idom /= jpdom_unknown ) THEN   ;   ix1 = 1      ;   ix2 = nlci      ;   iy1 = 1      ;   iy2 = nlcj
-               ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2)
-               ENDIF
+            ! find the right index of the array to be read
+            IF( idom /= jpdom_unknown ) THEN   ;   ix1 = Nis0   ;   ix2 = Nie0      ;   iy1 = Njs0   ;   iy2 = Nje0
+            ELSE                               ;   ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2)
             ENDIF
       
@@ -1308,16 +1335,14 @@
             IF( istop == nstop ) THEN   ! no additional errors until this point...
                IF(lwp) WRITE(numout,"(10x,' read ',a,' (rec: ',i6,') in ',a,' ok')") TRIM(cdvar), itime, TRIM(iom_file(kiomid)%name)
-             
+
+               cl_type = 'T'
+               IF( PRESENT(cd_type) )   cl_type = cd_type
+               zsgn = 1._wp
+               IF( PRESENT(psgn   ) )   zsgn    = psgn
                !--- overlap areas and extra hallows (mpp)
-               IF(     PRESENT(pv_r2d) .AND. idom /= jpdom_unknown ) THEN
-                  CALL lbc_lnk( 'iom', pv_r2d,'Z', -999., kfillmode = jpfillnothing )
-               ELSEIF( PRESENT(pv_r3d) .AND. idom /= jpdom_unknown ) THEN
-                  ! this if could be simplified with the new lbc_lnk that works with any size of the 3rd dimension
-                  IF( icnt(3) == inlev ) THEN
-                     CALL lbc_lnk( 'iom', pv_r3d,'Z', -999., kfillmode = jpfillnothing )
-                  ELSE   ! put some arbitrary value (a call to lbc_lnk will be done later...)
-                     DO jj = nlcj+1, jpj   ;   pv_r3d(1:nlci, jj, :) = pv_r3d(1:nlci, nlej, :)   ;   END DO
-                     DO ji = nlci+1, jpi   ;   pv_r3d(ji    , : , :) = pv_r3d(nlei  , :   , :)   ;   END DO
-                  ENDIF
+               IF(     PRESENT(pv_r2d) .AND. idom /= jpdom_unknown .AND. cl_type /= 'Z' ) THEN
+                  CALL lbc_lnk( 'iom', pv_r2d, cl_type, zsgn, kfillmode = kfill )
+               ELSEIF( PRESENT(pv_r3d) .AND. idom /= jpdom_unknown .AND. cl_type /= 'Z' ) THEN
+                  CALL lbc_lnk( 'iom', pv_r3d, cl_type, zsgn, kfillmode = kfill )
                ENDIF
                !
@@ -1336,20 +1361,13 @@
          CALL iom_swap( TRIM(crxios_context) ) 
          IF( PRESENT(pv_r3d) ) THEN
-            pv_r3d(:, :, :) = 0.
-            if(lwp) write(numout,*) 'XIOS RST READ (3D): ',trim(cdvar)
+            IF(lwp) WRITE(numout,*) 'XIOS RST READ (3D): ',TRIM(cdvar)
             CALL xios_recv_field( trim(cdvar), pv_r3d)
-            IF(idom /= jpdom_unknown ) then
-                CALL lbc_lnk( 'iom', pv_r3d,'Z', -999., kfillmode = jpfillnothing)
-            ENDIF
+            IF(idom /= jpdom_unknown )   CALL lbc_lnk( 'iom', pv_r3d,'Z', -999., kfillmode = jpfillnothing)
          ELSEIF( PRESENT(pv_r2d) ) THEN
-            pv_r2d(:, :) = 0.
-            if(lwp) write(numout,*) 'XIOS RST READ (2D): ', trim(cdvar)
+            IF(lwp) WRITE(numout,*) 'XIOS RST READ (2D): ', TRIM(cdvar)
             CALL xios_recv_field( trim(cdvar), pv_r2d)
-            IF(idom /= jpdom_unknown ) THEN
-                CALL lbc_lnk('iom', pv_r2d,'Z',-999., kfillmode = jpfillnothing)
-            ENDIF
+            IF(idom /= jpdom_unknown )   CALL lbc_lnk('iom', pv_r2d,'Z',-999., kfillmode = jpfillnothing)
          ELSEIF( PRESENT(pv_r1d) ) THEN
-            pv_r1d(:) = 0.
-            if(lwp) write(numout,*) 'XIOS RST READ (1D): ', trim(cdvar)
+            IF(lwp) WRITE(numout,*) 'XIOS RST READ (1D): ', TRIM(cdvar)
             CALL xios_recv_field( trim(cdvar), pv_r1d)
          ENDIF
@@ -1362,6 +1380,6 @@
 !some final adjustments
       ! C1D case : always call lbc_lnk to replicate the central value over the whole 3X3 domain
-      IF( lk_c1d .AND. PRESENT(pv_r2d) )   CALL lbc_lnk( 'iom', pv_r2d,'Z',1. )
-      IF( lk_c1d .AND. PRESENT(pv_r3d) )   CALL lbc_lnk( 'iom', pv_r3d,'Z',1. )
+      IF( lk_c1d .AND. PRESENT(pv_r2d) )   CALL lbc_lnk( 'iom', pv_r2d,'Z',1.0_wp )
+      IF( lk_c1d .AND. PRESENT(pv_r3d) )   CALL lbc_lnk( 'iom', pv_r3d,'Z',1.0_wp )
 
       !--- Apply scale_factor and offset
@@ -1550,10 +1568,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 +1592,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 +1653,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 +1714,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 +1775,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 +1862,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 +1873,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,36 +1897,111 @@
       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
-#if defined key_iomput
-      CALL xios_send_field(cdname, pfield2d)
+      REAL(sp),     DIMENSION(:,:), INTENT(in) ::   pfield2d
+      IF( iom_use(cdname) ) THEN
+#if defined key_iomput
+         IF( SIZE(pfield2d, dim=1) == jpi .AND. SIZE(pfield2d, dim=2) == jpj ) THEN
+            CALL xios_send_field( cdname, pfield2d(Nis0:Nie0, Njs0:Nje0) )       ! this extraction will create a copy of pfield2d
+         ELSE
+            CALL xios_send_field( cdname, pfield2d )
+         ENDIF
 #else
-      IF( .FALSE. )   WRITE(numout,*) cdname, pfield2d   ! useless test to avoid compilation warnings
-#endif
-   END SUBROUTINE iom_p2d
-
-   SUBROUTINE iom_p3d( cdname, pfield3d )
+         WRITE(numout,*) pfield2d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
+#endif
+      ENDIF
+   END SUBROUTINE iom_p2d_sp
+
+   SUBROUTINE iom_p2d_dp( cdname, pfield2d )
+      CHARACTER(LEN=*)            , INTENT(in) ::   cdname
+      REAL(dp),     DIMENSION(:,:), INTENT(in) ::   pfield2d
+      IF( iom_use(cdname) ) THEN
+#if defined key_iomput
+         IF( SIZE(pfield2d, dim=1) == jpi .AND. SIZE(pfield2d, dim=2) == jpj ) THEN
+            CALL xios_send_field( cdname, pfield2d(Nis0:Nie0, Njs0:Nje0) )       ! this extraction will create a copy of pfield2d
+         ELSE
+            CALL xios_send_field( cdname, pfield2d )
+         ENDIF
+#else
+         WRITE(numout,*) pfield2d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
+#endif
+      ENDIF
+   END SUBROUTINE iom_p2d_dp
+
+   SUBROUTINE iom_p3d_sp( cdname, pfield3d )
       CHARACTER(LEN=*)                , INTENT(in) ::   cdname
-      REAL(wp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d
-#if defined key_iomput
-      CALL xios_send_field( cdname, pfield3d )
+      REAL(sp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d
+      IF( iom_use(cdname) ) THEN
+#if defined key_iomput
+         IF( SIZE(pfield3d, dim=1) == jpi .AND. SIZE(pfield3d, dim=2) == jpj ) THEN
+            CALL xios_send_field( cdname, pfield3d(Nis0:Nie0, Njs0:Nje0,:) )     ! this extraction will create a copy of pfield3d
+         ELSE
+            CALL xios_send_field( cdname, pfield3d )
+         ENDIF
 #else
-      IF( .FALSE. )   WRITE(numout,*) cdname, pfield3d   ! useless test to avoid compilation warnings
-#endif
-   END SUBROUTINE iom_p3d
-
-   SUBROUTINE iom_p4d( cdname, pfield4d )
+         WRITE(numout,*) pfield3d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
+#endif
+      ENDIF
+   END SUBROUTINE iom_p3d_sp
+
+   SUBROUTINE iom_p3d_dp( cdname, pfield3d )
       CHARACTER(LEN=*)                , INTENT(in) ::   cdname
-      REAL(wp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d
-#if defined key_iomput
-      CALL xios_send_field(cdname, pfield4d)
+      REAL(dp),       DIMENSION(:,:,:), INTENT(in) ::   pfield3d
+      IF( iom_use(cdname) ) THEN
+#if defined key_iomput
+         IF( SIZE(pfield3d, dim=1) == jpi .AND. SIZE(pfield3d, dim=2) == jpj ) THEN
+            CALL xios_send_field( cdname, pfield3d(Nis0:Nie0, Njs0:Nje0,:) )     ! this extraction will create a copy of pfield3d
+         ELSE
+            CALL xios_send_field( cdname, pfield3d )
+         ENDIF
 #else
-      IF( .FALSE. )   WRITE(numout,*) cdname, pfield4d   ! useless test to avoid compilation warnings
-#endif
-   END SUBROUTINE iom_p4d
-
+         WRITE(numout,*) pfield3d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
+#endif
+      ENDIF
+   END SUBROUTINE iom_p3d_dp
+
+   SUBROUTINE iom_p4d_sp( cdname, pfield4d )
+      CHARACTER(LEN=*)                , INTENT(in) ::   cdname
+      REAL(sp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d
+      IF( iom_use(cdname) ) THEN
+#if defined key_iomput
+         IF( SIZE(pfield4d, dim=1) == jpi .AND. SIZE(pfield4d, dim=2) == jpj ) THEN
+            CALL xios_send_field( cdname, pfield4d(Nis0:Nie0, Njs0:Nje0,:,:) )   ! this extraction will create a copy of pfield4d
+         ELSE
+            CALL xios_send_field (cdname, pfield4d )
+         ENDIF
+#else
+         WRITE(numout,*) pfield4d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
+#endif
+      ENDIF
+   END SUBROUTINE iom_p4d_sp
+
+   SUBROUTINE iom_p4d_dp( cdname, pfield4d )
+      CHARACTER(LEN=*)                , INTENT(in) ::   cdname
+      REAL(dp),       DIMENSION(:,:,:,:), INTENT(in) ::   pfield4d
+      IF( iom_use(cdname) ) THEN
+#if defined key_iomput
+         IF( SIZE(pfield4d, dim=1) == jpi .AND. SIZE(pfield4d, dim=2) == jpj ) THEN
+            CALL xios_send_field( cdname, pfield4d(Nis0:Nie0, Njs0:Nje0,:,:) )   ! this extraction will create a copy of pfield4d
+         ELSE
+            CALL xios_send_field (cdname, pfield4d )
+         ENDIF
+#else
+         WRITE(numout,*) pfield4d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
+#endif
+      ENDIF
+   END SUBROUTINE iom_p4d_dp
 
 #if defined key_iomput
@@ -1788,6 +2019,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 +2083,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
@@ -1963,18 +2199,14 @@
       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   plat
       !
-      INTEGER  :: ni, nj
       REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zmask
       LOGICAL, INTENT(IN) :: ldxios, ldrxios
       !!----------------------------------------------------------------------
       !
-      ni = nlei-nldi+1
-      nj = nlej-nldj+1
-      !
-      CALL iom_set_domain_attr("grid_"//cdgrd, ni_glo=jpiglo, nj_glo=jpjglo, ibegin=nimpp+nldi-2, jbegin=njmpp+nldj-2, ni=ni, nj=nj)
-      CALL iom_set_domain_attr("grid_"//cdgrd, data_dim=2, data_ibegin = 1-nldi, data_ni = jpi, data_jbegin = 1-nldj, data_nj = jpj)
+      CALL iom_set_domain_attr("grid_"//cdgrd, ni_glo=Ni0glo,nj_glo=Nj0glo,ibegin=mig0(Nis0)-1,jbegin=mjg0(Njs0)-1,ni=Ni_0,nj=Nj_0)
+      CALL iom_set_domain_attr("grid_"//cdgrd, data_dim=2, data_ibegin = 0, data_ni = Ni_0, data_jbegin = 0, data_nj = Nj_0)
 !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(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp),   &
+         &                                        latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp ))  
       !
       IF ( ln_mskland .AND. (.NOT.ldxios) ) THEN
@@ -1982,15 +2214,14 @@
          SELECT CASE ( cdgrd )
          CASE('T')   ;   zmask(:,:,:)       = tmask(:,:,:)
-         CASE('U')   ;   zmask(2:jpim1,:,:) = tmask(2:jpim1,:,:) + tmask(3:jpi,:,:)   ;   CALL lbc_lnk( 'iom', zmask, 'U', 1. )
-         CASE('V')   ;   zmask(:,2:jpjm1,:) = tmask(:,2:jpjm1,:) + tmask(:,3:jpj,:)   ;   CALL lbc_lnk( 'iom', zmask, 'V', 1. )
+         CASE('U')   ;   zmask(2:jpim1,:,:) = tmask(2:jpim1,:,:) + tmask(3:jpi,:,:)
+         CASE('V')   ;   zmask(:,2:jpjm1,:) = tmask(:,2:jpjm1,:) + tmask(:,3:jpj,:)
          CASE('W')   ;   zmask(:,:,2:jpk  ) = tmask(:,:,1:jpkm1) + tmask(:,:,2:jpk)   ;   zmask(:,:,1) = tmask(:,:,1)
          END SELECT
          !
-         CALL iom_set_domain_attr( "grid_"//cdgrd       , mask = RESHAPE(zmask(nldi:nlei,nldj:nlej,1),(/ni*nj    /)) /= 0. )
-         CALL iom_set_grid_attr  ( "grid_"//cdgrd//"_3D", mask = RESHAPE(zmask(nldi:nlei,nldj:nlej,:),(/ni,nj,jpk/)) /= 0. )
+         CALL iom_set_domain_attr( "grid_"//cdgrd       , mask = RESHAPE(zmask(Nis0:Nie0,Njs0:Nje0,1),(/Ni_0*Nj_0    /)) /= 0. )
+         CALL iom_set_grid_attr  ( "grid_"//cdgrd//"_3D", mask = RESHAPE(zmask(Nis0:Nie0,Njs0:Nje0,:),(/Ni_0,Nj_0,jpk/)) /= 0. )
       ENDIF
       !
    END SUBROUTINE set_grid
-
 
    SUBROUTINE set_grid_bounds( cdgrd, plon_cnr, plat_cnr, plon_pnt, plat_pnt )
@@ -2005,7 +2236,9 @@
       REAL(wp), DIMENSION(jpi,jpj), OPTIONAL, INTENT(in) :: plon_pnt, plat_pnt  ! Lat/lon coord. of the point of cell (i,j)
       !
-      INTEGER :: ji, jj, jn, ni, nj
+      INTEGER :: ji, jj, jn
       INTEGER :: icnr, jcnr                             ! Offset such that the vertex coordinate (i+icnr,j+jcnr)
-      !                                                 ! represents the bottom-left corner of cell (i,j)
+      !                                                 ! represents the
+      !                                                 bottom-left corner of
+      !                                                 cell (i,j)
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: z_bnds      ! Lat/lon coordinates of the vertices of cell (i,j)
       REAL(wp), ALLOCATABLE, DIMENSION(:,:)     :: z_fld       ! Working array to determine where to rotate cells
@@ -2022,81 +2255,34 @@
       END SELECT
       !
-      ni = nlei-nldi+1   ! Dimensions of subdomain interior
-      nj = nlej-nldj+1
-      !
       z_fld(:,:) = 1._wp
-      CALL lbc_lnk( 'iom', z_fld, cdgrd, -1. )    ! Working array for location of northfold
+      CALL lbc_lnk( 'iom', z_fld, cdgrd, -1.0_wp )    ! Working array for location of northfold
       !
       ! Cell vertices that can be defined
-      DO jj = 2, jpjm1
-         DO ji = 2, jpim1
-            z_bnds(1,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left
-            z_bnds(2,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right
-            z_bnds(3,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right
-            z_bnds(4,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr+1) ! Top-left
-            z_bnds(1,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left
-            z_bnds(2,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right
-            z_bnds(3,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right
-            z_bnds(4,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr+1) ! Top-left
-         END DO
-      END DO
-      !
-      ! Cell vertices on boundries
-      DO jn = 1, 4
-         CALL lbc_lnk( 'iom', z_bnds(jn,:,:,1), cdgrd, 1., pfillval=999._wp )
-         CALL lbc_lnk( 'iom', z_bnds(jn,:,:,2), cdgrd, 1., pfillval=999._wp )
-      END DO
-      !
-      ! Zero-size cells at closed boundaries if cell points provided,
-      ! otherwise they are closed cells with unrealistic bounds
-      IF( PRESENT(plon_pnt) .AND. PRESENT(plat_pnt) ) THEN
-         IF( (nbondi == -1 .OR. nbondi == 2) .AND. .NOT. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6) ) THEN
-            DO jn = 1, 4        ! (West or jpni = 1), closed E-W
-               z_bnds(jn,1,:,1) = plat_pnt(1,:)  ;  z_bnds(jn,1,:,2) = plon_pnt(1,:)
-            END DO
-         ENDIF
-         IF( (nbondi == 1 .OR. nbondi == 2) .AND. .NOT. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6) ) THEN
-            DO jn = 1, 4        ! (East or jpni = 1), closed E-W
-               z_bnds(jn,nlci,:,1) = plat_pnt(nlci,:)  ;  z_bnds(jn,nlci,:,2) = plon_pnt(nlci,:)
-            END DO
-         ENDIF
-         IF( nbondj == -1 .OR. (nbondj == 2 .AND. jperio /= 2) ) THEN
-            DO jn = 1, 4        ! South or (jpnj = 1, not symmetric)
-               z_bnds(jn,:,1,1) = plat_pnt(:,1)  ;  z_bnds(jn,:,1,2) = plon_pnt(:,1)
-            END DO
-         ENDIF
-         IF( (nbondj == 1 .OR. nbondj == 2) .AND. jperio  < 3 ) THEN
-            DO jn = 1, 4        ! (North or jpnj = 1), no north fold
-               z_bnds(jn,:,nlcj,1) = plat_pnt(:,nlcj)  ;  z_bnds(jn,:,nlcj,2) = plon_pnt(:,nlcj)
-            END DO
-         ENDIF
-      ENDIF
-      !
-      IF( (nbondj == 1 .OR. nbondj == 2) .AND. jperio >= 3 ) THEN    ! Rotate cells at the north fold
-         DO jj = 1, jpj
-            DO ji = 1, jpi
-               IF( z_fld(ji,jj) == -1. ) THEN
-                  z_rot(1,:) = z_bnds(3,ji,jj,:) ; z_rot(2,:) = z_bnds(4,ji,jj,:)
-                  z_rot(3,:) = z_bnds(1,ji,jj,:) ; z_rot(4,:) = z_bnds(2,ji,jj,:)
-                  z_bnds(:,ji,jj,:) = z_rot(:,:)
-               ENDIF
-            END DO
-         END DO
-      ELSE IF( nbondj == 2 .AND. jperio == 2 ) THEN                  ! Invert cells at the symmetric equator
-         DO ji = 1, jpi
-            z_rot(1:2,:) = z_bnds(3:4,ji,1,:)
-            z_rot(3:4,:) = z_bnds(1:2,ji,1,:)
-            z_bnds(:,ji,1,:) = z_rot(:,:)
-         END DO
-      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 )
-      !
-      DEALLOCATE( z_bnds, z_fld, z_rot ) 
+      DO_2D( 0, 0, 0, 0 )
+         z_bnds(1,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left
+         z_bnds(2,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right
+         z_bnds(3,ji,jj,1) = plat_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right
+         z_bnds(4,ji,jj,1) = plat_cnr(ji+icnr,  jj+jcnr+1) ! Top-left
+         z_bnds(1,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr  ) ! Bottom-left
+         z_bnds(2,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr  ) ! Bottom-right
+         z_bnds(3,ji,jj,2) = plon_cnr(ji+icnr+1,jj+jcnr+1) ! Top-right
+         z_bnds(4,ji,jj,2) = plon_cnr(ji+icnr,  jj+jcnr+1) ! Top-left
+      END_2D
+      !
+      DO_2D( 0, 0, 0, 0 )
+         IF( z_fld(ji,jj) == -1. ) THEN
+            z_rot(1,:) = z_bnds(3,ji,jj,:) ; z_rot(2,:) = z_bnds(4,ji,jj,:)
+            z_rot(3,:) = z_bnds(1,ji,jj,:) ; z_rot(4,:) = z_bnds(2,ji,jj,:)
+            z_bnds(:,ji,jj,:) = z_rot(:,:)
+         ENDIF
+      END_2D
+      !
+      CALL iom_set_domain_attr("grid_"//cdgrd, bounds_lat = real(RESHAPE(z_bnds(:,Nis0:Nie0,Njs0:Nje0,1),(/ 4,Ni_0*Nj_0 /)), dp),           &
+          &                                    bounds_lon = real(RESHAPE(z_bnds(:,Nis0:Nie0,Njs0:Nje0,2),(/ 4,Ni_0*Nj_0 /)), dp), nvertex=4 )
+      !
+      DEALLOCATE( z_bnds, z_fld, z_rot )
       !
    END SUBROUTINE set_grid_bounds
 
-
    SUBROUTINE set_grid_znl( plat )
       !!----------------------------------------------------------------------
@@ -2108,19 +2294,17 @@
       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   plat
       !
-      INTEGER  :: ni, nj, ix, iy
+      INTEGER  :: ix, iy
       REAL(wp), DIMENSION(:), ALLOCATABLE  ::   zlon
       !!----------------------------------------------------------------------
       !
-      ni=nlei-nldi+1       ! define zonal mean domain (jpj*jpk)
-      nj=nlej-nldj+1
-      ALLOCATE( zlon(ni*nj) )       ;       zlon(:) = 0._wp
-      !
-!      CALL dom_ngb( -168.53, 65.03, ix, iy, 'T' ) !  i-line that passes through Bering Strait: Reference latitude (used in plots)
-      CALL dom_ngb( 180., 90., ix, iy, 'T' ) !  i-line that passes near the North Pole : Reference latitude (used in plots)
-      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_zoom_domain_attr("ptr", ibegin=ix-1, jbegin=0, ni=1, nj=jpjglo)
+      ALLOCATE( zlon(Ni_0*Nj_0) )       ;       zlon(:) = 0._wp
+      !
+!      CALL dom_ngb( -168.53_wp, 65.03_wp, ix, iy, 'T' ) !  i-line that passes through Bering Strait: Reference latitude (used in plots)
+      CALL dom_ngb( 180.0_wp, 90.0_wp, ix, iy, 'T' ) !  i-line that passes near the North Pole : Reference latitude (used in plots)
+      CALL iom_set_domain_attr("gznl", ni_glo=Ni0glo, nj_glo=Nj0glo, ibegin=mig0(Nis0)-1, jbegin=mjg0(Njs0)-1, ni=Ni_0, nj=Nj_0)
+      CALL iom_set_domain_attr("gznl", data_dim=2, data_ibegin = 0, data_ni = Ni_0, data_jbegin = 0, data_nj = Nj_0)
+      CALL iom_set_domain_attr("gznl", lonvalue = real(zlon, dp),   &
+         &                             latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp))  
+      CALL iom_set_zoom_domain_attr("ptr", ibegin=ix-1, jbegin=0, ni=1, nj=Nj_0)
       !
       CALL iom_update_file_name('ptr')
@@ -2136,5 +2320,5 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(1)   ::   zz = 1.
+      REAL(dp), DIMENSION(1)   ::   zz = 1.
       !!----------------------------------------------------------------------
       !
@@ -2198,6 +2382,6 @@
          cl1 = clgrd(jg)
          ! Equatorial section (attributs: jbegin, ni, name_suffix)
-         CALL dom_ngb( 0., 0., ix, iy, cl1 )
-         CALL iom_set_zoom_domain_attr('Eq'//cl1, ibegin=0, jbegin=iy-1, ni=jpiglo, nj=1 )
+         CALL dom_ngb( 0.0_wp, 0.0_wp, ix, iy, cl1 )
+         CALL iom_set_zoom_domain_attr('Eq'//cl1, ibegin=0, jbegin=iy-1, ni=Ni0glo, nj=1 )
          CALL iom_get_file_attr   ('Eq'//cl1, name_suffix = clsuff             )
          CALL iom_set_file_attr   ('Eq'//cl1, name_suffix = TRIM(clsuff)//'_Eq')
@@ -2424,5 +2608,5 @@
       !
       IF ( ll24 .AND. isec == 0 ) THEN   ! 00:00 of the next day -> move to 24:00 of the current day
-         CALL ju2ymds( pjday - 1., iyear, imonth, iday, zsec )
+         CALL ju2ymds( pjday - 1.0_wp, iyear, imonth, iday, zsec )
          isec = 86400
       ENDIF
@@ -2482,7 +2666,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
