Index: /NEMO/releases/release-4.0/src/OCE/ICB/icb_oce.F90
===================================================================
--- /NEMO/releases/release-4.0/src/OCE/ICB/icb_oce.F90	(revision 10725)
+++ /NEMO/releases/release-4.0/src/OCE/ICB/icb_oce.F90	(revision 10726)
@@ -86,9 +86,10 @@
    ! particularly for MPP when iceberg can lie inside T grid but outside U, V, or f grid
    REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   uo_e, vo_e
-   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   ff_e, tt_e, fr_e, hicth
+   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   ff_e, tt_e, fr_e
    REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   ua_e, va_e
    REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   ssh_e
+   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   tmask_e, umask_e, vmask_e
 #if defined key_si3 || defined key_cice
-   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   ui_e, vi_e
+   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE ::   hi_e, ui_e, vi_e
 #endif
 
@@ -169,16 +170,20 @@
       !
       ! expanded arrays for bilinear interpolation
-      ALLOCATE( uo_e(0:jpi+1,0:jpj+1) , ua_e(0:jpi+1,0:jpj+1) ,   &
-         &      vo_e(0:jpi+1,0:jpj+1) , va_e(0:jpi+1,0:jpj+1) ,   &
+      ALLOCATE( uo_e(0:jpi+1,0:jpj+1) , ua_e(0:jpi+1,0:jpj+1) ,    &
+         &      vo_e(0:jpi+1,0:jpj+1) , va_e(0:jpi+1,0:jpj+1) ,    &
 #if defined key_si3 || defined key_cice
          &      ui_e(0:jpi+1,0:jpj+1) ,                            &
          &      vi_e(0:jpi+1,0:jpj+1) ,                            &
+         &      hi_e(0:jpi+1,0:jpj+1) ,                            &
 #endif
          &      ff_e(0:jpi+1,0:jpj+1) , fr_e(0:jpi+1,0:jpj+1)  ,   &
          &      tt_e(0:jpi+1,0:jpj+1) , ssh_e(0:jpi+1,0:jpj+1) ,   &
-         &      hicth(0:jpi+1,0:jpj+1),                            &
          &      first_width(nclasses) , first_length(nclasses) ,   &
          &      src_calving (jpi,jpj) ,                            &
          &      src_calving_hflx(jpi,jpj) , STAT=ill)
+      icb_alloc = icb_alloc + ill
+
+      ALLOCATE( tmask_e(0:jpi+1,0:jpj+1), umask_e(0:jpi+1,0:jpj+1), vmask_e(0:jpi+1,0:jpj+1), &
+         &      STAT=ill)
       icb_alloc = icb_alloc + ill
 
Index: /NEMO/releases/release-4.0/src/OCE/ICB/icbclv.F90
===================================================================
--- /NEMO/releases/release-4.0/src/OCE/ICB/icbclv.F90	(revision 10725)
+++ /NEMO/releases/release-4.0/src/OCE/ICB/icbclv.F90	(revision 10726)
@@ -24,4 +24,5 @@
    USE icbdia         ! iceberg diagnostics
    USE icbutl         ! iceberg utility routines
+   USE icb_oce        ! iceberg parameters 
 
    IMPLICIT NONE
@@ -57,9 +58,9 @@
       ! this assumes that input is given as equivalent water flux so that pure water density is appropriate
 
-      zfact = ( (1000._wp)**3 / ( NINT(rday) * nyear_len(1) ) ) * 850._wp
-      berg_grid%calving(:,:) = src_calving(:,:) * tmask_i(:,:) * zfact
+      zfact = ( (1000._wp)**3 / ( NINT(rday) * nyear_len(1) ) ) * rn_rho_bergs
+      berg_grid%calving(:,:) = src_calving(:,:) * zfact * tmask_i(:,:) * tmask(:,:,1)
 
       ! Heat in units of W/m2, and mask (just in case)
-      berg_grid%calving_hflx(:,:) = src_calving_hflx(:,:) * tmask_i(:,:)
+      berg_grid%calving_hflx(:,:) = src_calving_hflx(:,:) * tmask_i(:,:) * tmask(:,:,1)
 
       IF( ll_first_call .AND. .NOT. l_restarted_bergs ) THEN      ! This is a hack to simplify initialization
Index: /NEMO/releases/release-4.0/src/OCE/ICB/icbini.F90
===================================================================
--- /NEMO/releases/release-4.0/src/OCE/ICB/icbini.F90	(revision 10725)
+++ /NEMO/releases/release-4.0/src/OCE/ICB/icbini.F90	(revision 10726)
@@ -74,5 +74,16 @@
       !                          ! allocate gridded fields
       IF( icb_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'icb_alloc : unable to allocate arrays' )
-
+      !
+      !                          ! initialised variable with extra haloes to zero
+      uo_e(:,:) = 0._wp   ;   vo_e(:,:) = 0._wp   ;
+      ua_e(:,:) = 0._wp   ;   va_e(:,:) = 0._wp   ;
+      ff_e(:,:) = 0._wp   ;   tt_e(:,:) = 0._wp   ;
+      fr_e(:,:) = 0._wp   ;
+#if defined key_si3
+      hi_e(:,:) = 0._wp   ;
+      ui_e(:,:) = 0._wp   ;   vi_e(:,:) = 0._wp   ;
+#endif
+      ssh_e(:,:) = 0._wp  ; 
+      !
       !                          ! open ascii output file or files for iceberg status information
       !                          ! note that we choose to do this on all processors since we cannot
@@ -224,4 +235,12 @@
       src_calving_hflx(:,:) = 0._wp
 
+      ! definition of extended surface masked needed by icb_bilin_h
+      tmask_e(:,:) = 0._wp   ;   tmask_e(1:jpi,1:jpj) = tmask(:,:,1)
+      umask_e(:,:) = 0._wp   ;   umask_e(1:jpi,1:jpj) = umask(:,:,1)
+      vmask_e(:,:) = 0._wp   ;   vmask_e(1:jpi,1:jpj) = vmask(:,:,1)
+      CALL lbc_lnk_icb( 'icbini', tmask_e, 'T', +1._wp, 1, 1 )
+      CALL lbc_lnk_icb( 'icbini', umask_e, 'T', +1._wp, 1, 1 )
+      CALL lbc_lnk_icb( 'icbini', vmask_e, 'T', +1._wp, 1, 1 )
+      !
       ! assign each new iceberg with a unique number constructed from the processor number
       ! and incremented by the total number of processors
Index: /NEMO/releases/release-4.0/src/OCE/ICB/icbutl.F90
===================================================================
--- /NEMO/releases/release-4.0/src/OCE/ICB/icbutl.F90	(revision 10725)
+++ /NEMO/releases/release-4.0/src/OCE/ICB/icbutl.F90	(revision 10726)
@@ -70,11 +70,11 @@
       ! and ssh which is used to calculate gradients
 
-      uo_e(:,:) = 0._wp   ;   uo_e(1:jpi,1:jpj) = ssu_m(:,:) * umask(:,:,1)
-      vo_e(:,:) = 0._wp   ;   vo_e(1:jpi,1:jpj) = ssv_m(:,:) * vmask(:,:,1)
-      ff_e(:,:) = 0._wp   ;   ff_e(1:jpi,1:jpj) = ff_f (:,:) 
-      tt_e(:,:) = 0._wp   ;   tt_e(1:jpi,1:jpj) = sst_m(:,:)
-      fr_e(:,:) = 0._wp   ;   fr_e(1:jpi,1:jpj) = fr_i (:,:)
-      ua_e(:,:) = 0._wp   ;   ua_e(1:jpi,1:jpj) = utau (:,:) * umask(:,:,1) ! maybe mask useless because mask applied in sbcblk
-      va_e(:,:) = 0._wp   ;   va_e(1:jpi,1:jpj) = vtau (:,:) * vmask(:,:,1) ! maybe mask useless because mask applied in sbcblk
+      uo_e(1:jpi,1:jpj) = ssu_m(:,:) * umask(:,:,1)
+      vo_e(1:jpi,1:jpj) = ssv_m(:,:) * vmask(:,:,1)
+      ff_e(1:jpi,1:jpj) = ff_f (:,:) 
+      tt_e(1:jpi,1:jpj) = sst_m(:,:)
+      fr_e(1:jpi,1:jpj) = fr_i (:,:)
+      ua_e(1:jpi,1:jpj) = utau (:,:) * umask(:,:,1) ! maybe mask useless because mask applied in sbcblk
+      va_e(1:jpi,1:jpj) = vtau (:,:) * vmask(:,:,1) ! maybe mask useless because mask applied in sbcblk
       !
       CALL lbc_lnk_icb( 'icbutl', uo_e, 'U', -1._wp, 1, 1 )
@@ -86,29 +86,18 @@
       CALL lbc_lnk_icb( 'icbutl', tt_e, 'T', +1._wp, 1, 1 )
 #if defined key_si3
-      hicth(:,:) = 0._wp ;  hicth(1:jpi,1:jpj) = hm_i (:,:)  
-      ui_e(:,:) = 0._wp ;   ui_e(1:jpi, 1:jpj) = u_ice(:,:)
-      vi_e(:,:) = 0._wp ;   vi_e(1:jpi, 1:jpj) = v_ice(:,:)
+      hi_e(1:jpi, 1:jpj) = hm_i (:,:)  
+      ui_e(1:jpi, 1:jpj) = u_ice(:,:)
+      vi_e(1:jpi, 1:jpj) = v_ice(:,:)
       !      
       ! compute ssh slope using ssh_lead if embedded
       zssh_lead_m(:,:) = ice_var_sshdyn(ssh_m, snwice_mass, snwice_mass_b)
-      ssh_e(:,:) = 0._wp ;  ssh_e(1:jpi, 1:jpj) = zssh_lead_m(:,:) * tmask(:,:,1)
-      !
-      CALL lbc_lnk_icb( 'icbutl', hicth, 'T', +1._wp, 1, 1 )
+      ssh_e(1:jpi, 1:jpj) = zssh_lead_m(:,:) * tmask(:,:,1)
+      !
+      CALL lbc_lnk_icb( 'icbutl', hi_e , 'T', +1._wp, 1, 1 )
       CALL lbc_lnk_icb( 'icbutl', ui_e , 'U', -1._wp, 1, 1 )
       CALL lbc_lnk_icb( 'icbutl', vi_e , 'V', -1._wp, 1, 1 )
 #else
-      ssh_e(:,:) = 0._wp ;  ssh_e(1:jpi, 1:jpj) = ssh_m(:,:) * tmask(:,:,1)
+      ssh_e(1:jpi, 1:jpj) = ssh_m(:,:) * tmask(:,:,1)
 #endif
-
-      !! special for ssh which is used to calculate slope
-      !! so fudge some numbers all the way around the boundary
-      ssh_e(0    ,    :) = ssh_e(1  ,  :)
-      ssh_e(jpi+1,    :) = ssh_e(jpi,  :)
-      ssh_e(:    ,    0) = ssh_e(:  ,  1)
-      ssh_e(:    ,jpj+1) = ssh_e(:  ,jpj)
-      ssh_e(0,0)         = ssh_e(1,1)
-      ssh_e(jpi+1,0)     = ssh_e(jpi,1)
-      ssh_e(0,jpj+1)     = ssh_e(1,jpj)
-      ssh_e(jpi+1,jpj+1) = ssh_e(jpi,jpj)
       CALL lbc_lnk_icb( 'icbutl', ssh_e, 'T', +1._wp, 1, 1 )
       !
@@ -131,4 +120,6 @@
       !!             is half the off shore value, wile the normal-to-the-coast value is zero.
       !!             This is OK as a starting point.
+      !!       !!pm  HARD CODED: - rho_air now computed in sbcblk (what are the effect ?)
+      !!                         - drag coefficient (should it be namelist parameter ?)
       !!
       !!----------------------------------------------------------------------
@@ -142,16 +133,16 @@
       !!----------------------------------------------------------------------
 
-      pe1 = icb_utl_bilin_e( e1t, e1u, e1v, e1f, pi, pj )     ! scale factors
+      pe1 = icb_utl_bilin_e( e1t, e1u, e1v, e1f, pi, pj )      ! scale factors
       pe2 = icb_utl_bilin_e( e2t, e2u, e2v, e2f, pi, pj )
       !
-      puo  = icb_utl_bilin_h( uo_e, pi, pj, 'U' )             ! ocean velocities
-      pvo  = icb_utl_bilin_h( vo_e, pi, pj, 'V' )
-      psst = icb_utl_bilin_h( tt_e, pi, pj, 'T' )             ! SST
-      pcn  = icb_utl_bilin_h( fr_e , pi, pj, 'T' )            ! ice concentration
-      pff  = icb_utl_bilin_h( ff_e , pi, pj, 'F' )            ! Coriolis parameter
-      !
-      pua  = icb_utl_bilin_h( ua_e , pi, pj, 'U' )            ! 10m wind
-      pva  = icb_utl_bilin_h( va_e , pi, pj, 'V' )            ! here (ua,va) are stress => rough conversion from stress to speed
-      zcd  = 1.22_wp * 1.5e-3_wp                              ! air density * drag coefficient
+      puo  = icb_utl_bilin_h( uo_e, pi, pj, 'U', .false.  )    ! ocean velocities
+      pvo  = icb_utl_bilin_h( vo_e, pi, pj, 'V', .false.  )
+      psst = icb_utl_bilin_h( tt_e, pi, pj, 'T', .true.   )    ! SST
+      pcn  = icb_utl_bilin_h( fr_e, pi, pj, 'T', .true.   )    ! ice concentration
+      pff  = icb_utl_bilin_h( ff_e, pi, pj, 'F', .false.  )    ! Coriolis parameter
+      !
+      pua  = icb_utl_bilin_h( ua_e, pi, pj, 'U', .true.   )    ! 10m wind
+      pva  = icb_utl_bilin_h( va_e, pi, pj, 'V', .true.   )    ! here (ua,va) are stress => rough conversion from stress to speed
+      zcd  = 1.22_wp * 1.5e-3_wp                               ! air density * drag coefficient 
       zmod = 1._wp / MAX(  1.e-20, SQRT(  zcd * SQRT( pua*pua + pva*pva)  )  )
       pua  = pua * zmod                                       ! note: stress module=0 necessarly implies ua=va=0
@@ -159,7 +150,7 @@
 
 #if defined key_si3
-      pui = icb_utl_bilin_h( ui_e , pi, pj, 'U' )              ! sea-ice velocities
-      pvi = icb_utl_bilin_h( vi_e , pi, pj, 'V' )
-      phi = icb_utl_bilin_h( hicth, pi, pj, 'T' )              ! ice thickness
+      pui = icb_utl_bilin_h( ui_e , pi, pj, 'U', .false. )    ! sea-ice velocities
+      pvi = icb_utl_bilin_h( vi_e , pi, pj, 'V', .false. )
+      phi = icb_utl_bilin_h( hi_e , pi, pj, 'T', .true.  )    ! ice thickness
 #else
       pui = 0._wp
@@ -169,13 +160,13 @@
 
       ! Estimate SSH gradient in i- and j-direction (centred evaluation)
-      pssh_i = ( icb_utl_bilin_h( ssh_e, pi+0.1_wp, pj, 'T' ) -   &
-         &       icb_utl_bilin_h( ssh_e, pi-0.1_wp, pj, 'T' )  ) / ( 0.2_wp * pe1 )
-      pssh_j = ( icb_utl_bilin_h( ssh_e, pi, pj+0.1_wp, 'T' ) -   &
-         &       icb_utl_bilin_h( ssh_e, pi, pj-0.1_wp, 'T' )  ) / ( 0.2_wp * pe2 )
+      pssh_i = ( icb_utl_bilin_h( ssh_e, pi+0.1_wp, pj, 'T', .true. ) -   &
+         &       icb_utl_bilin_h( ssh_e, pi-0.1_wp, pj, 'T', .true. )  ) / ( 0.2_wp * pe1 )
+      pssh_j = ( icb_utl_bilin_h( ssh_e, pi, pj+0.1_wp, 'T', .true. ) -   &
+         &       icb_utl_bilin_h( ssh_e, pi, pj-0.1_wp, 'T', .true. )  ) / ( 0.2_wp * pe2 )
       !
    END SUBROUTINE icb_utl_interp
 
 
-   REAL(wp) FUNCTION icb_utl_bilin_h( pfld, pi, pj, cd_type )
+   REAL(wp) FUNCTION icb_utl_bilin_h( pfld, pi, pj, cd_type, plmask )
       !!----------------------------------------------------------------------
       !!                  ***  FUNCTION icb_utl_bilin  ***
@@ -191,7 +182,10 @@
       REAL(wp)                            , INTENT(in) ::   pi, pj    ! targeted coordinates in (i,j) referential
       CHARACTER(len=1)                    , INTENT(in) ::   cd_type   ! type of pfld array grid-points: = T , U , V or F points
+      LOGICAL                             , INTENT(in) ::   plmask    ! special treatment of mask point
       !
       INTEGER  ::   ii, ij   ! local integer
       REAL(wp) ::   zi, zj   ! local real
+      REAL(wp) :: zw1, zw2, zw3, zw4
+      REAL(wp), DIMENSION(4) :: zmask
       !!----------------------------------------------------------------------
       !
@@ -201,41 +195,64 @@
          ! since we're looking for four T points containing quadrant we're in of 
          ! current T cell
-         ii = MAX(1, INT( pi     ))
-         ij = MAX(1, INT( pj     ))    ! T-point
+         ii = MAX(0, INT( pi     ))
+         ij = MAX(0, INT( pj     ))    ! T-point
          zi = pi - REAL(ii,wp)
          zj = pj - REAL(ij,wp)
       CASE ( 'U' )
-         ii = MAX(1, INT( pi-0.5 ))
-         ij = MAX(1, INT( pj     ))    ! U-point
-         zi = pi - 0.5 - REAL(ii,wp)
+         ii = MAX(0, INT( pi-0.5_wp ))
+         ij = MAX(0, INT( pj     ))    ! U-point
+         zi = pi - 0.5_wp - REAL(ii,wp)
          zj = pj - REAL(ij,wp)
       CASE ( 'V' )
-         ii = MAX(1, INT( pi     ))
-         ij = MAX(1, INT( pj-0.5 ))    ! V-point
+         ii = MAX(0, INT( pi     ))
+         ij = MAX(0, INT( pj-0.5_wp ))    ! V-point
          zi = pi - REAL(ii,wp)
-         zj = pj - 0.5 - REAL(ij,wp)
+         zj = pj - 0.5_wp - REAL(ij,wp)
       CASE ( 'F' )
-         ii = MAX(1, INT( pi-0.5 ))
-         ij = MAX(1, INT( pj-0.5 ))    ! F-point
-         zi = pi - 0.5 - REAL(ii,wp)
-         zj = pj - 0.5 - REAL(ij,wp)
+         ii = MAX(0, INT( pi-0.5_wp ))
+         ij = MAX(0, INT( pj-0.5_wp ))    ! F-point
+         zi = pi - 0.5_wp - REAL(ii,wp)
+         zj = pj - 0.5_wp - REAL(ij,wp)
       END SELECT
       !
       ! find position in this processor. Prevent near edge problems (see #1389)
-      !
-      IF    ( ii < mig( 1 ) ) THEN   ;   ii = 1
-      ELSEIF( ii > mig(jpi) ) THEN   ;   ii = jpi
-      ELSE                           ;   ii = mi1(ii)
-      ENDIF
-      IF    ( ij < mjg( 1 ) ) THEN   ;   ij = 1
-      ELSEIF( ij > mjg(jpj) ) THEN   ;   ij = jpj
-      ELSE                           ;   ij  = mj1(ij)
-      ENDIF
-      !
-      IF( ii == jpi )   ii = ii-1      
-      IF( ij == jpj )   ij = ij-1
-      !
-      icb_utl_bilin_h = ( pfld(ii,ij  ) * (1.-zi) + pfld(ii+1,ij  ) * zi ) * (1.-zj)   &
-         &            + ( pfld(ii,ij+1) * (1.-zi) + pfld(ii+1,ij+1) * zi ) *     zj
+      ! (PM) will be useless if extra halo is used in NEMO
+      !
+      IF    ( ii <= mig(1)-1 ) THEN   ;   ii = 0
+      ELSEIF( ii  > mig(jpi) ) THEN   ;   ii = jpi
+      ELSE                            ;   ii = mi1(ii)
+      ENDIF
+      IF    ( ij <= mjg(1)-1 ) THEN   ;   ij = 0
+      ELSEIF( ij  > mjg(jpj) ) THEN   ;   ij = jpj
+      ELSE                            ;   ij = mj1(ij)
+      ENDIF
+      !
+      ! define mask array 
+      IF (plmask) THEN
+         ! land value is not used in the interpolation
+         SELECT CASE ( cd_type )
+         CASE ( 'T' )
+            zmask = (/tmask_e(ii,ij), tmask_e(ii+1,ij), tmask_e(ii,ij+1), tmask_e(ii+1,ij+1)/)
+         CASE ( 'U' )
+            zmask = (/umask_e(ii,ij), umask_e(ii+1,ij), umask_e(ii,ij+1), umask_e(ii+1,ij+1)/)
+         CASE ( 'V' )
+            zmask = (/vmask_e(ii,ij), vmask_e(ii+1,ij), vmask_e(ii,ij+1), vmask_e(ii+1,ij+1)/)
+         CASE ( 'F' )
+            ! F case only used for coriolis, ff_f is not mask so zmask = 1
+            zmask = 1.
+         END SELECT
+      ELSE
+         ! land value is used during interpolation
+         zmask = 1.
+      END iF
+      !
+      ! compute weight
+      zw1 = zmask(1) * (1._wp-zi) * (1._wp-zj)
+      zw2 = zmask(2) *        zi  * (1._wp-zj)
+      zw3 = zmask(3) * (1._wp-zi) *        zj
+      zw4 = zmask(4) *        zi  *        zj
+      !
+      ! compute interpolated value
+      icb_utl_bilin_h = ( pfld(ii,ij)*zw1 + pfld(ii+1,ij)*zw2 + pfld(ii,ij+1)*zw3 + pfld(ii+1,ij+1)*zw4 ) / MAX(1.e-20, zw1+zw2+zw3+zw4) 
       !
    END FUNCTION icb_utl_bilin_h
@@ -372,5 +389,5 @@
       REAL(wp)                , INTENT(in) ::   pi, pj               ! targeted coordinates in (i,j) referential
       !
-      INTEGER  ::   ii, ij, icase   ! local integer
+      INTEGER  ::   ii, ij, icase, ierr   ! local integer
       !
       ! weights corresponding to corner points of a T cell quadrant
@@ -394,15 +411,19 @@
 
       ! find position in this processor. Prevent near edge problems (see #1389)
-      IF    ( ii < mig( 1 ) ) THEN   ;   ii = 1
-      ELSEIF( ii > mig(jpi) ) THEN   ;   ii = jpi
+      !
+      ierr = 0
+      IF    ( ii < mig( 1 ) ) THEN   ;   ii = 1       ; ierr = ierr + 1
+      ELSEIF( ii > mig(jpi) ) THEN   ;   ii = jpi     ; ierr = ierr + 1
       ELSE                           ;   ii = mi1(ii)
       ENDIF
-      IF    ( ij < mjg( 1 ) ) THEN   ;   ij = 1
-      ELSEIF( ij > mjg(jpj) ) THEN   ;   ij = jpj
+      IF    ( ij < mjg( 1 ) ) THEN   ;   ij = 1       ; ierr = ierr + 1
+      ELSEIF( ij > mjg(jpj) ) THEN   ;   ij = jpj     ; ierr = ierr + 1
       ELSE                           ;   ij  = mj1(ij)
       ENDIF
       !
-      IF( ii == jpi )   ii = ii-1      
-      IF( ij == jpj )   ij = ij-1
+      IF( ii == jpi ) THEN ; ii = ii-1 ; ierr = ierr + 1 ; END IF     
+      IF( ij == jpj ) THEN ; ij = ij-1 ; ierr = ierr + 1 ; END IF
+      !
+      IF ( ierr > 0 ) CALL ctl_stop('STOP','icb_utl_bilin_e: an icebergs coordinates is out of valid range (out of bound error)')
       !
       IF(    0.0_wp <= zi .AND. zi < 0.5_wp   ) THEN
@@ -436,6 +457,6 @@
       ENDIF
       !
-      icb_utl_bilin_e = ( ze01 * (1.-zi) + ze11 * zi ) *     zj    &
-         &            + ( ze00 * (1.-zi) + ze10 * zi ) * (1.-zj)
+      icb_utl_bilin_e = ( ze01 * (1._wp-zi) + ze11 * zi ) *        zj    &
+         &            + ( ze00 * (1._wp-zi) + ze10 * zi ) * (1._wp-zj)
       !
    END FUNCTION icb_utl_bilin_e
Index: /NEMO/releases/release-4.0/src/OCE/LBC/mpp_loc_generic.h90
===================================================================
--- /NEMO/releases/release-4.0/src/OCE/LBC/mpp_loc_generic.h90	(revision 10725)
+++ /NEMO/releases/release-4.0/src/OCE/LBC/mpp_loc_generic.h90	(revision 10726)
@@ -17,8 +17,10 @@
 #      define MPI_OPERATION mpi_maxloc
 #      define LOC_OPERATION MAXLOC
+#      define ERRVAL -HUGE
 #   endif
 #   if defined OPERATION_MINLOC
 #      define MPI_OPERATION mpi_minloc
 #      define LOC_OPERATION MINLOC
+#      define ERRVAL HUGE
 #   endif
 
@@ -42,26 +44,33 @@
       !
       idim = SIZE(kindex)
-      ALLOCATE ( ilocs(idim) )
       !
-      ilocs = LOC_OPERATION( ARRAY_IN(:,:,:) , mask= MASK_IN(:,:,:) == 1._wp )
-      zmin  = ARRAY_IN(ilocs(1),ilocs(2),ilocs(3))
-      !
-      kindex(1) = ilocs(1) + nimpp - 1
+      IF ( ALL(MASK_IN(:,:,:) /= 1._wp) ) THEN
+         ! special case for land processors
+         zmin = ERRVAL(zmin)
+         index0 = 0
+      ELSE
+         ALLOCATE ( ilocs(idim) )
+         !
+         ilocs = LOC_OPERATION( ARRAY_IN(:,:,:) , mask= MASK_IN(:,:,:) == 1._wp )
+         zmin  = ARRAY_IN(ilocs(1),ilocs(2),ilocs(3))
+         !
+         kindex(1) = mig( ilocs(1) )
 #  if defined DIM_2d || defined DIM_3d    /* avoid warning when kindex has 1 element */
-      kindex(2) = ilocs(2) + njmpp - 1
+         kindex(2) = mjg( ilocs(2) )
 #  endif
 #  if defined DIM_3d                      /* avoid warning when kindex has 2 elements */
-      kindex(3) = ilocs(3)
+         kindex(3) = ilocs(3)
 #  endif
-      ! 
-      DEALLOCATE (ilocs)
-      !
-      index0 = kindex(1)-1   ! 1d index starting at 0
+         ! 
+         DEALLOCATE (ilocs)
+         !
+         index0 = kindex(1)-1   ! 1d index starting at 0
 #  if defined DIM_2d || defined DIM_3d   /* avoid warning when kindex has 1 element */
-      index0 = index0 + jpiglo * (kindex(2)-1)
+         index0 = index0 + jpiglo * (kindex(2)-1)
 #  endif
 #  if defined DIM_3d                     /* avoid warning when kindex has 2 elements */
-      index0 = index0 + jpiglo * jpjglo * (kindex(3)-1)
+         index0 = index0 + jpiglo * jpjglo * (kindex(3)-1)
 #  endif
+      END IF
       zain(1,:) = zmin
       zain(2,:) = REAL(index0, wp)
@@ -98,2 +107,3 @@
 #undef LOC_OPERATION
 #undef INDEX_TYPE
+#undef ERRVAL
