diff --git a/src/OCE/DOM/dom_oce.F90 b/src/OCE/DOM/dom_oce.F90
index 71d351a9a8b5d84d08fe69f7fff2fe05dc13c8d1..71a085f23d4a78e64b7bfec6751b9f2a5c7c9e7d 100644
--- a/src/OCE/DOM/dom_oce.F90
+++ b/src/OCE/DOM/dom_oce.F90
@@ -27,6 +27,8 @@ MODULE dom_oce
 
    PUBLIC dom_oce_alloc  ! Called from nemogcm.F90
 
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
    !!----------------------------------------------------------------------
    !! time & space domain namelist
    !! ----------------------------
@@ -194,6 +196,7 @@ MODULE dom_oce
 
    INTEGER , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   mikt, miku, mikv, mikf   !: top first wet T-, U-, V-, F-level           (ISF)
 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)           ::   smask0                              !: surface mask at T-pts on inner domain
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)           ::   ssmask, ssumask, ssvmask, ssfmask   !: surface mask at T-,U-, V- and F-pts
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:), TARGET ::   tmask, umask, vmask, wmask, fmask   !: land/ocean mask at T-, U-, V-, W- and F-pts
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:), TARGET ::   wumask, wvmask                      !: land/ocean mask at WU- and WV-pts
@@ -326,7 +329,7 @@ CONTAINS
       ALLOCATE( risfdep(jpi,jpj) , bathy(jpi,jpj) , STAT=ierr(ii)  )
          !
       ii = ii+1
-      ALLOCATE( tmask_i(jpi,jpj) ,                                                              &
+      ALLOCATE( tmask_i(jpi,jpj) , smask0(A2D(0))   ,                                           &
          &      ssmask (jpi,jpj) , ssumask(jpi,jpj) , ssvmask(jpi,jpj) , ssfmask(jpi,jpj) ,     &
          &      mbkt   (jpi,jpj) , mbku   (jpi,jpj) , mbkv   (jpi,jpj) , mbkf(jpi,jpj)    , STAT=ierr(ii) )
          !
diff --git a/src/OCE/DOM/dommsk.F90 b/src/OCE/DOM/dommsk.F90
index 904fec9b03f78748a6aa4e12da5f2420d1f7428d..ce234ad277642515bb38c2f21d023e45a9f137fc 100644
--- a/src/OCE/DOM/dommsk.F90
+++ b/src/OCE/DOM/dommsk.F90
@@ -144,7 +144,8 @@ CONTAINS
             tmask(ji,jj,jk) = tmask(ji,jj,jk) * bdytmask(ji,jj)
          END_3D
       ENDIF
-         
+      smask0(A2D(0)) = tmask(A2D(0),1)
+      
       !  Ocean/land mask at u-, v-, and f-points   (computed from tmask)
       ! ----------------------------------------
       ! NB: at this point, fmask is designed for free slip lateral boundary condition
diff --git a/src/OCE/IOM/iom.F90 b/src/OCE/IOM/iom.F90
index 728c75ebc126708f37ff28f9299372abe1b10c4d..9a1f1c859c0b50a4e3fbe0b9e04d5a069e0d7e27 100644
--- a/src/OCE/IOM/iom.F90
+++ b/src/OCE/IOM/iom.F90
@@ -1202,6 +1202,7 @@ CONTAINS
       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
+      INTEGER                        ::   ihls        ! local value of the halo size
       REAL(dp)                       ::   gma, gmi
       !---------------------------------------------------------------------
       CHARACTER(LEN=lc)                               ::   context
@@ -1332,14 +1333,22 @@ CONTAINS
             ELSE
                IF( irankpv == 2 )   ishape(1:2) = SHAPE(pv_r2d)
                IF( irankpv == 3 )   ishape(1:3) = SHAPE(pv_r3d)
-               IF( ishape(1) == jpi .AND. ishape(2) == jpj ) THEN
-                  ishape(1:2) = (/ Ni_0, Nj_0 /)
-                  ix1 = Nis0   ;   ix2 = Nie0      ;   iy1 = Njs0   ;   iy2 = Nje0      ! index of the array to be read
+               IF(     ishape(1) == Ni_0   .AND. ishape(2) == Nj_0   ) THEN           ! array with 0 halo
+                  ihls = 0
+                  ix1 = 1      ;   ix2 = Ni_0     ;   iy1 = 1      ;   iy2 = Nj_0     ! index of the array to be read
+                  ctmp1 = 'd(:,:'
+               ELSEIF( ishape(1) == jpi    .AND. ishape(2) == jpj    ) THEN           ! array with nn_hls halos
+                  ihls = nn_hls
+                  ix1 = Nis0   ;   ix2 = Nie0     ;   iy1 = Njs0   ;   iy2 = Nje0     ! index of the array to be read
                   ctmp1 = 'd(Nis0:Nie0,Njs0:Nje0'
+               ELSEIF( ishape(1) == Ni_0+1 .AND. ishape(2) == Nj_0+1 ) THEN           ! nn_hls = 2 and array with 1 halo
+                  ihls = 1
+                  ix1 = 2      ;   ix2 = Ni_0+1   ;   iy1 = 2      ;   iy2 = Nj_0+1   ! index of the array to be read
+                  ctmp1 = 'd(2:Ni_0+1,2:Ni_0+1'
                ELSE
-                  ix1 = 1      ;   ix2 = icnt(1)   ;   iy1 = 1      ;   iy2 = icnt(2)   ! index of the array to be read
-                  ctmp1 = 'd(:,:'
+                  CALL ctl_stop( 'iom_get_123d: should have been an impossible case...' )
                ENDIF
+               ishape(1:2) = (/ Ni_0, Nj_0 /)   ! update and force ishape to match the inner domain
                IF( irankpv == 3 )   ctmp1 = TRIM(ctmp1)//',:'
                ctmp1 = TRIM(ctmp1)//')'
             ENDIF
@@ -1359,17 +1368,17 @@ CONTAINS
             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)
-               llok = idom /= jpdom_unknown .AND. cl_type /= 'Z'  &
-                  &   .AND.   ix1 == Nis0   .AND.   ix2 == Nie0   .AND.   iy1 == Njs0   .AND.   iy2 == Nje0
-               IF(     PRESENT(pv_r2d) .AND. llok ) THEN
-                  CALL lbc_lnk( 'iom', pv_r2d, cl_type, zsgn, kfillmode = kfill )
-               ELSEIF( PRESENT(pv_r3d) .AND. llok ) THEN
-                  CALL lbc_lnk( 'iom', pv_r3d, cl_type, zsgn, kfillmode = kfill )
+               !--- halos and NP folding (NP folding to be done even if no halos)
+               IF( idom /= jpdom_unknown .AND. cl_type /= 'Z' .AND. ( PRESENT(pv_r2d) .OR. PRESENT(pv_r3d) ) ) THEN
+                  cl_type = 'T'
+                  IF( PRESENT(cd_type) )   cl_type = cd_type
+                  zsgn = 1._wp
+                  IF( PRESENT(psgn   ) )   zsgn    = psgn
+                  IF(     PRESENT(pv_r2d) .AND. llok ) THEN
+                     CALL lbc_lnk( 'iom', pv_r2d, cl_type, zsgn, kfillmode = kfill, khls = ihls )
+                  ELSEIF( PRESENT(pv_r3d) .AND. llok ) THEN
+                     CALL lbc_lnk( 'iom', pv_r3d, cl_type, zsgn, kfillmode = kfill, khls = ihls )
+                  ENDIF
                ENDIF
                !
             ELSE
diff --git a/src/OCE/IOM/iom_nf90.F90 b/src/OCE/IOM/iom_nf90.F90
index 287d943a98dad8af33f1643e8477d41552d419ae..171ef53bf0bb10ec16e9971bdb866a0eb75d0347 100644
--- a/src/OCE/IOM/iom_nf90.F90
+++ b/src/OCE/IOM/iom_nf90.F90
@@ -697,10 +697,12 @@ CONTAINS
 
             IF( PRESENT(pv_r2d) )  ishape(1:2) = SHAPE(pv_r2d)
             IF( PRESENT(pv_r3d) )  ishape(1:3) = SHAPE(pv_r3d)
-            IF(     ishape(1) == Ni_0 .AND. ishape(2) == Nj_0 ) THEN
-               ix1 = 1      ;   ix2 = Ni_0   ;   iy1 = 1      ;   iy2 = Nj_0
-            ELSEIF( ishape(1) == jpi  .AND. ishape(2) == jpj  ) THEN
-               ix1 = Nis0   ;   ix2 = Nie0   ;   iy1 = Njs0   ;   iy2 = Nje0
+            IF(     ishape(1) == Ni_0   .AND. ishape(2) == Nj_0   ) THEN           ! array with 0 halo
+               ix1 = 1      ;   ix2 = Ni_0     ;   iy1 = 1      ;   iy2 = Nj_0
+            ELSEIF( ishape(1) == jpi    .AND. ishape(2) == jpj    ) THEN           ! array with nn_hls halos
+               ix1 = Nis0   ;   ix2 = Nie0     ;   iy1 = Njs0   ;   iy2 = Nje0
+            ELSEIF( ishape(1) == Ni_0+1 .AND. ishape(2) == Nj_0+1 ) THEN           ! nn_hls = 2 and array with 1 halo
+               ix1 = 2      ;   ix2 = Ni_0+1   ;   iy1 = 2      ;   iy2 = Nj_0+1
             ELSE
                CALL ctl_stop( 'iom_nf90_rp0123d: should have been an impossible case...' )
             ENDIF
diff --git a/src/OCE/LBC/lib_mpp.F90 b/src/OCE/LBC/lib_mpp.F90
index 0bcde50b8b6b0f5ec11e9d5d80bdee7fed706e1d..9854cb04bfb0ec3f99ce4a44bce63274dbfdac15 100644
--- a/src/OCE/LBC/lib_mpp.F90
+++ b/src/OCE/LBC/lib_mpp.F90
@@ -143,9 +143,9 @@ MODULE lib_mpp
 
    ! Neighbourgs informations
    INTEGER,    PARAMETER, PUBLIC ::   n_hlsmax = 3
-   INTEGER, DIMENSION(         8), PUBLIC ::   mpinei      !: 8-neighbourg MPI indexes (starting at 0, -1 if no neighbourg)
-   INTEGER, DIMENSION(n_hlsmax,8), PUBLIC ::   mpiSnei     !: 8-neighbourg Send MPI indexes (starting at 0, -1 if no neighbourg)
-   INTEGER, DIMENSION(n_hlsmax,8), PUBLIC ::   mpiRnei     !: 8-neighbourg Recv MPI indexes (starting at 0, -1 if no neighbourg)
+   INTEGER, DIMENSION(           8), PUBLIC ::   mpinei      !: 8-neighbourg MPI indexes (starting at 0, -1 if no neighbourg)
+   INTEGER, DIMENSION(0:n_hlsmax,8), PUBLIC ::   mpiSnei     !: 8-neighbourg Send MPI indexes (starting at 0, -1 if no neighbourg)
+   INTEGER, DIMENSION(0:n_hlsmax,8), PUBLIC ::   mpiRnei     !: 8-neighbourg Recv MPI indexes (starting at 0, -1 if no neighbourg)
    INTEGER,    PARAMETER, PUBLIC ::   jpwe = 1   !: WEst
    INTEGER,    PARAMETER, PUBLIC ::   jpea = 2   !: EAst
    INTEGER,    PARAMETER, PUBLIC ::   jpso = 3   !: SOuth
diff --git a/src/OCE/LBC/mppini.F90 b/src/OCE/LBC/mppini.F90
index e5cd21c354c4e766e2e79045f80c25ffeda116bb..da174b39072a4294fd5303db17f984660faa4851 100644
--- a/src/OCE/LBC/mppini.F90
+++ b/src/OCE/LBC/mppini.F90
@@ -489,7 +489,9 @@ CONTAINS
       ! -----------------------------------------
       !
       ! set default neighbours
-      mpinei(:) = impi(:,narea)
+      mpinei(:) = impi(:,narea)   ! should be just local but is still used in icblbc and mpp_lnk_icb_generic.h90...
+      mpiSnei(0,:) = -1  ! no comm if no halo (but need it for NP Folding
+      mpiRnei(0,:) = -1 
       DO jh = 1, n_hlsmax
          mpiSnei(jh,:) = impi(:,narea)   ! default definition
          mpiRnei(jh,:) = impi(:,narea)
diff --git a/src/OCE/SBC/cpl_oasis3.F90 b/src/OCE/SBC/cpl_oasis3.F90
index 3c7e15ba498c8dfea73eaf4365356bd7b82089ce..091ce68733631adda99b5faf9e27f8724200b421 100644
--- a/src/OCE/SBC/cpl_oasis3.F90
+++ b/src/OCE/SBC/cpl_oasis3.F90
@@ -64,7 +64,6 @@ MODULE cpl_oasis3
    INTEGER                    ::   nrcv         ! total number of fields received
    INTEGER                    ::   nsnd         ! total number of fields sent
    INTEGER                    ::   ncplmodel    ! Maximum number of models to/from which NEMO is potentialy sending/receiving data
-   INTEGER, PUBLIC, PARAMETER ::   nmaxfld=62   ! Maximum number of coupling fields
    INTEGER, PUBLIC, PARAMETER ::   nmaxcat=5    ! Maximum number of coupling fields
    INTEGER, PUBLIC, PARAMETER ::   nmaxcpl=5    ! Maximum number of coupling fields
 
@@ -78,7 +77,7 @@ MODULE cpl_oasis3
       INTEGER               ::   ncplmodel ! Maximum number of models to/from which this variable may be sent/received
    END TYPE FLD_CPL
 
-   TYPE(FLD_CPL), DIMENSION(nmaxfld), PUBLIC ::   srcv, ssnd   !: Coupling fields
+   TYPE(FLD_CPL), DIMENSION(:), ALLOCATABLE, PUBLIC ::   srcv, ssnd   !: Coupling fields
 
    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   exfld   ! Temporary buffer for receiving
 
@@ -153,15 +152,6 @@ CONTAINS
          CALL oasis_abort ( ncomp_id, 'cpl_define', 'ncplmodel is larger than nmaxcpl, increase nmaxcpl')   ;   RETURN
       ENDIF
 
-      nrcv = krcv
-      IF( nrcv > nmaxfld ) THEN
-         CALL oasis_abort ( ncomp_id, 'cpl_define', 'nrcv is larger than nmaxfld, increase nmaxfld')   ;   RETURN
-      ENDIF
-
-      nsnd = ksnd
-      IF( nsnd > nmaxfld ) THEN
-         CALL oasis_abort ( ncomp_id, 'cpl_define', 'nsnd is larger than nmaxfld, increase nmaxfld')   ;   RETURN
-      ENDIF
       !
       ! ... Define the shape for the area that excludes the halo as we don't want them to be "seen" by oasis
       !
diff --git a/src/OCE/SBC/sbccpl.F90 b/src/OCE/SBC/sbccpl.F90
index c3feee0dc7ad84ed850fcc57d988dc13772ef686..dc41fe2a8aa8d637d07776ed36f606e7b6c4b14a 100644
--- a/src/OCE/SBC/sbccpl.F90
+++ b/src/OCE/SBC/sbccpl.F90
@@ -388,6 +388,7 @@ CONTAINS
       !                 define the north fold type of lbc                  (srcv(:)%nsgn)
 
       ! default definitions of srcv
+      ALLOCATE( srcv(jprcv) )
       srcv(:)%laction = .FALSE.   ;   srcv(:)%clgrid = 'T'   ;   srcv(:)%nsgn = 1.   ;   srcv(:)%nct = 1
 
       !                                                      ! ------------------------- !
@@ -759,8 +760,9 @@ CONTAINS
       ! for each field: define the OASIS name                           (ssnd(:)%clname)
       !                 define send or not from the namelist parameters (ssnd(:)%laction)
       !                 define the north fold type of lbc               (ssnd(:)%nsgn)
-
+      
       ! default definitions of nsnd
+      ALLOCATE( ssnd(jpsnd) )
       ssnd(:)%laction = .FALSE.   ;   ssnd(:)%clgrid = 'T'   ;   ssnd(:)%nsgn = 1.  ; ssnd(:)%nct = 1
 
       !                                                      ! ------------------------- !