Skip to content
Snippets Groups Projects
sbcice_cice.F90 43.5 KiB
Newer Older
Guillaume Samson's avatar
Guillaume Samson committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
MODULE sbcice_cice
   !!======================================================================
   !!                       ***  MODULE  sbcice_cice  ***
   !! To couple with sea ice model CICE (LANL)
   !!=====================================================================
#if defined key_cice
   !!----------------------------------------------------------------------
   !!   'key_cice' :                                     CICE sea-ice model
   !!----------------------------------------------------------------------
   !!   sbc_ice_cice  : sea-ice model time-stepping and update ocean sbc over ice-covered area
   !!----------------------------------------------------------------------
   USE oce             ! ocean dynamics and tracers
   USE dom_oce         ! ocean space and time domain
# if defined key_qco
   USE domqco         ! Variable volume
# else
   USE domvvl         ! Variable volume
# endif
   USE phycst, only : rcp, rho0, r1_rho0, rhos, rhoi
   USE in_out_manager  ! I/O manager
   USE iom, ONLY : iom_put,iom_use              ! I/O manager library !!Joakim edit
   USE lib_mpp         ! distributed memory computing library
   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
   USE daymod          ! calendar
   USE fldread         ! read input fields
   USE sbc_oce         ! Surface boundary condition: ocean fields
   USE sbc_ice         ! Surface boundary condition: ice   fields
   USE sbcblk          ! Surface boundary condition: bulk
   USE sbccpl

   USE ice_kinds_mod
   USE ice_blocks
   USE ice_domain
   USE ice_domain_size
   USE ice_boundary
   USE ice_constants
   USE ice_gather_scatter
   USE ice_calendar, only: dt
   USE ice_state, only: aice,aicen,uvel,vvel,vsno,vsnon,vice,vicen
# if defined key_cice4
   USE ice_flux, only: strax,stray,strocnx,strocny,frain,fsnow,  &
                strocnxT,strocnyT,                               & 
                sst,sss,uocn,vocn,ss_tltx,ss_tlty,fsalt_gbm,     &
                fresh_gbm,fhocn_gbm,fswthru_gbm,frzmlt,          &
                flatn_f,fsurfn_f,fcondtopn_f,                    &
                uatm,vatm,wind,fsw,flw,Tair,potT,Qa,rhoa,zlvl,   &
                swvdr,swvdf,swidr,swidf
   USE ice_therm_vertical, only: calc_Tsfc
#else
   USE ice_flux, only: strax,stray,strocnx,strocny,frain,fsnow,  &
                strocnxT,strocnyT,                               & 
                sst,sss,uocn,vocn,ss_tltx,ss_tlty,fsalt_ai,     &
                fresh_ai,fhocn_ai,fswthru_ai,frzmlt,          &
                flatn_f,fsurfn_f,fcondtopn_f,                    &
                uatm,vatm,wind,fsw,flw,Tair,potT,Qa,rhoa,zlvl,   &
                swvdr,swvdf,swidr,swidf
   USE ice_therm_shared, only: calc_Tsfc
#endif
   USE ice_forcing, only: frcvdr,frcvdf,frcidr,frcidf
   USE ice_atmo, only: calc_strair

   USE CICE_InitMod
   USE CICE_RunMod
   USE CICE_FinalMod

   IMPLICIT NONE
   PRIVATE

   PUBLIC cice_sbc_init   ! routine called by sbc_init
   PUBLIC cice_sbc_final  ! routine called by sbc_final
   PUBLIC sbc_ice_cice    ! routine called by sbc

   INTEGER             ::   ji_off
   INTEGER             ::   jj_off

   INTEGER , PARAMETER ::   jpfld   = 13   ! maximum number of files to read 
   INTEGER , PARAMETER ::   jp_snow = 1    ! index of snow file
   INTEGER , PARAMETER ::   jp_rain = 2    ! index of rain file
   INTEGER , PARAMETER ::   jp_sblm = 3    ! index of sublimation file
   INTEGER , PARAMETER ::   jp_top1 = 4    ! index of category 1 topmelt file
   INTEGER , PARAMETER ::   jp_top2 = 5    ! index of category 2 topmelt file
   INTEGER , PARAMETER ::   jp_top3 = 6    ! index of category 3 topmelt file
   INTEGER , PARAMETER ::   jp_top4 = 7    ! index of category 4 topmelt file
   INTEGER , PARAMETER ::   jp_top5 = 8    ! index of category 5 topmelt file
   INTEGER , PARAMETER ::   jp_bot1 = 9    ! index of category 1 botmelt file
   INTEGER , PARAMETER ::   jp_bot2 = 10   ! index of category 2 botmelt file
   INTEGER , PARAMETER ::   jp_bot3 = 11   ! index of category 3 botmelt file
   INTEGER , PARAMETER ::   jp_bot4 = 12   ! index of category 4 botmelt file
   INTEGER , PARAMETER ::   jp_bot5 = 13   ! index of category 5 botmelt file
   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf    ! structure of input fields (file informations, fields read)

   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:), PRIVATE ::   png     ! local array used in sbc_cice_ice

   !! * Substitutions
#  include "do_loop_substitute.h90"
   !!----------------------------------------------------------------------
   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
   !! $Id: sbcice_cice.F90 14595 2021-03-05 22:36:50Z clem $
   !! Software governed by the CeCILL license (see ./LICENSE)
   !!----------------------------------------------------------------------
CONTAINS

   INTEGER FUNCTION sbc_ice_cice_alloc()
      !!----------------------------------------------------------------------
      !!                ***  FUNCTION sbc_ice_cice_alloc  ***
      !!----------------------------------------------------------------------
      ALLOCATE( png(jpi,jpj,jpnij), STAT=sbc_ice_cice_alloc )
      CALL mpp_sum ( 'sbcice_cice', sbc_ice_cice_alloc )
      IF( sbc_ice_cice_alloc > 0 )   CALL ctl_warn('sbc_ice_cice_alloc: allocation of arrays failed.')
   END FUNCTION sbc_ice_cice_alloc

   SUBROUTINE sbc_ice_cice( kt, ksbc )
      !!---------------------------------------------------------------------
      !!                  ***  ROUTINE sbc_ice_cice  ***
      !!                   
      !! ** Purpose :   update the ocean surface boundary condition via the 
      !!                CICE Sea Ice Model time stepping 
      !!
      !! ** Method  : - Get any extra forcing fields for CICE  
      !!              - Prepare forcing fields
      !!              - CICE model time stepping
      !!              - call the routine that computes mass and 
      !!                heat fluxes at the ice/ocean interface
      !!
      !! ** Action  : - time evolution of the CICE sea-ice model
      !!              - update all sbc variables below sea-ice:
      !!                utau, vtau, qns , qsr, emp , sfx
      !!---------------------------------------------------------------------
      INTEGER, INTENT(in) ::   kt      ! ocean time step
      INTEGER, INTENT(in) ::   ksbc    ! surface forcing type
      !!----------------------------------------------------------------------
      !
      !                                        !----------------------!
      IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN     !  Ice time-step only  !
         !                                     !----------------------!

         ! Make sure any fluxes required for CICE are set
         IF      ( ksbc == jp_flx ) THEN
            CALL cice_sbc_force(kt)
         ELSE IF( ksbc == jp_purecpl ) THEN
            CALL sbc_cpl_ice_flx( kt, fr_i )
         ENDIF

         CALL cice_sbc_in  ( kt, ksbc )
         CALL CICE_Run
         CALL cice_sbc_out ( kt, ksbc )

         IF( ksbc == jp_purecpl )  CALL cice_sbc_hadgam(kt+1)

      ENDIF                                          ! End sea-ice time step only
      !
   END SUBROUTINE sbc_ice_cice


   SUBROUTINE cice_sbc_init( ksbc, Kbb, Kmm )
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE cice_sbc_init  ***
      !! ** Purpose: Initialise ice related fields for NEMO and coupling
      !!
      !!---------------------------------------------------------------------
      INTEGER, INTENT( in  ) ::   ksbc                ! surface forcing type
      INTEGER, INTENT( in  ) ::   Kbb, Kmm            ! time level indices
      REAL(wp), DIMENSION(jpi,jpj) :: ztmp1, ztmp2
      REAL(wp) ::   zcoefu, zcoefv, zcoeff            ! local scalar
      INTEGER  ::   ji, jj, jl, jk                    ! dummy loop indices
      !!---------------------------------------------------------------------
      !
      IF(lwp) WRITE(numout,*)'cice_sbc_init'

      ji_off = INT ( (jpiglo - nx_global) / 2 )
      jj_off = INT ( (jpjglo - ny_global) / 2 )

#if defined key_nemocice_decomp
      ! Pass initial SST from NEMO to CICE so ice is initialised correctly if
      ! there is no restart file.
      ! Values from a CICE restart file would overwrite this
      IF( .NOT. ln_rstart ) THEN    
         CALL nemo2cice( ts(:,:,1,jp_tem,Kmm) , sst , 'T' , 1.) 
      ENDIF  
#endif

! Initialize CICE
      CALL CICE_Initialize

! Do some CICE consistency checks
      IF( (ksbc == jp_flx) .OR. (ksbc == jp_purecpl) ) THEN
         IF( calc_strair .OR. calc_Tsfc ) THEN
            CALL ctl_stop( 'STOP', 'cice_sbc_init : Forcing option requires calc_strair=F and calc_Tsfc=F in ice_in' )
         ENDIF
      ELSEIF(ksbc == jp_blk) THEN
         IF( .NOT. (calc_strair .AND. calc_Tsfc) ) THEN
            CALL ctl_stop( 'STOP', 'cice_sbc_init : Forcing option requires calc_strair=T and calc_Tsfc=T in ice_in' )
         ENDIF
      ENDIF


! allocate sbc_ice and sbc_cice arrays
      IF( sbc_ice_alloc()      /= 0 )   CALL ctl_stop( 'STOP', 'sbc_ice_cice_alloc : unable to allocate arrays' )
      IF( sbc_ice_cice_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'sbc_ice_cice_alloc : unable to allocate cice arrays' )

! Ensure ocean temperatures are nowhere below freezing if not a NEMO restart
      IF( .NOT. ln_rstart ) THEN
         ts(:,:,:,jp_tem,Kmm) = MAX (ts(:,:,:,jp_tem,Kmm),Tocnfrz)
         ts(:,:,:,jp_tem,Kbb) = ts(:,:,:,jp_tem,Kmm)
      ENDIF

      fr_iu(:,:)=0.0
      fr_iv(:,:)=0.0

      CALL cice2nemo(aice,fr_i, 'T', 1. )
      IF( (ksbc == jp_flx) .OR. (ksbc == jp_purecpl) ) THEN
         DO jl=1,ncat
            CALL cice2nemo(aicen(:,:,jl,:),a_i(:,:,jl), 'T', 1. )
         ENDDO
      ENDIF

! T point to U point
! T point to V point
      DO_2D( 1, 0, 1, 0 )
         fr_iu(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji+1,jj))*umask(ji,jj,1)
         fr_iv(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji,jj+1))*vmask(ji,jj,1)
      END_2D

      CALL lbc_lnk( 'sbcice_cice', fr_iu , 'U', 1.0_wp,  fr_iv , 'V', 1.0_wp )

      ! set the snow+ice mass
      CALL cice2nemo(vsno(:,:,:),ztmp1,'T', 1. )
      CALL cice2nemo(vice(:,:,:),ztmp2,'T', 1. )
      snwice_mass  (:,:) = ( rhos * ztmp1(:,:) + rhoi * ztmp2(:,:)  )
      snwice_mass_b(:,:) = snwice_mass(:,:)

      IF( .NOT.ln_rstart ) THEN
         IF( ln_ice_embd ) THEN            ! embedded sea-ice: deplete the initial ssh below sea-ice area
            ssh(:,:,Kmm) = ssh(:,:,Kmm) - snwice_mass(:,:) * r1_rho0
            ssh(:,:,Kbb) = ssh(:,:,Kbb) - snwice_mass(:,:) * r1_rho0

!!gm This should be put elsewhere....   (same remark for limsbc)
!!gm especially here it is assumed zstar coordinate, but it can be ztilde....
#if defined key_qco
            IF( .NOT.ln_linssh )   CALL dom_qco_zgr( Kbb, Kmm )   ! interpolation scale factor, depth and water column
#else
            IF( .NOT.ln_linssh ) THEN
               !
               DO jk = 1,jpkm1                     ! adjust initial vertical scale factors
                  e3t(:,:,jk,Kmm) = e3t_0(:,:,jk)*( 1._wp + ssh(:,:,Kmm)*r1_ht_0(:,:)*tmask(:,:,jk) )
                  e3t(:,:,jk,Kbb) = e3t_0(:,:,jk)*( 1._wp + ssh(:,:,Kbb)*r1_ht_0(:,:)*tmask(:,:,jk) )
               ENDDO
               e3t(:,:,:,Krhs) = e3t(:,:,:,Kbb)
               ! Reconstruction of all vertical scale factors at now and before time-steps
               ! =============================================================================
               ! Horizontal scale factor interpolations
               ! --------------------------------------
               CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3u(:,:,:,Kbb), 'U' )
               CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3v(:,:,:,Kbb), 'V' )
               CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3u(:,:,:,Kmm), 'U' )
               CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3v(:,:,:,Kmm), 'V' )
               CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3f(:,:,:), 'F' )
               ! Vertical scale factor interpolations
               ! ------------------------------------
               CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3w (:,:,:,Kmm), 'W'  )
               CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3uw(:,:,:,Kmm), 'UW' )
               CALL dom_vvl_interpol( e3v(:,:,:,Kmm), e3vw(:,:,:,Kmm), 'VW' )
               CALL dom_vvl_interpol( e3u(:,:,:,Kbb), e3uw(:,:,:,Kbb), 'UW' )
               CALL dom_vvl_interpol( e3v(:,:,:,Kbb), e3vw(:,:,:,Kbb), 'VW' )
               ! t- and w- points depth
               ! ----------------------
               gdept(:,:,1,Kmm) = 0.5_wp * e3w(:,:,1,Kmm)
               gdepw(:,:,1,Kmm) = 0.0_wp
               gde3w(:,:,1)     = gdept(:,:,1,Kmm) - ssh(:,:,Kmm)
               DO jk = 2, jpk
                  gdept(:,:,jk,Kmm) = gdept(:,:,jk-1,Kmm) + e3w(:,:,jk,Kmm)
                  gdepw(:,:,jk,Kmm) = gdepw(:,:,jk-1,Kmm) + e3t(:,:,jk-1,Kmm)
                  gde3w(:,:,jk)     = gdept(:,:,jk  ,Kmm) - sshn   (:,:)
               END DO
            ENDIF
#endif
         ENDIF
      ENDIF
      !
   END SUBROUTINE cice_sbc_init

   
   SUBROUTINE cice_sbc_in( kt, ksbc )
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE cice_sbc_in  ***
      !! ** Purpose: Set coupling fields and pass to CICE
      !!---------------------------------------------------------------------
      INTEGER, INTENT(in   ) ::   kt   ! ocean time step
      INTEGER, INTENT(in   ) ::   ksbc ! surface forcing type
      !
      INTEGER  ::   ji, jj, jl                   ! dummy loop indices      
      REAL(wp), DIMENSION(jpi,jpj) :: ztmp, zpice
      REAL(wp), DIMENSION(jpi,jpj,ncat) :: ztmpn
      REAL(wp) ::   zintb, zintn  ! dummy argument
      !!---------------------------------------------------------------------
      !
      IF( kt == nit000 )  THEN
         IF(lwp) WRITE(numout,*)'cice_sbc_in'
      ENDIF

      ztmp(:,:)=0.0

! Aggregate ice concentration already set in cice_sbc_out (or cice_sbc_init on 
! the first time-step)

! forced and coupled case 

      IF( (ksbc == jp_flx).OR.(ksbc == jp_purecpl) ) THEN

         ztmpn(:,:,:)=0.0

! x comp of wind stress (CI_1)
! U point to F point
         DO_2D( 1, 1, 1, 0 )
            ztmp(ji,jj) = 0.5 * (  fr_iu(ji,jj) * utau(ji,jj)      &
                                 + fr_iu(ji,jj+1) * utau(ji,jj+1) ) * fmask(ji,jj,1)
         END_2D
         CALL nemo2cice(ztmp,strax,'F', -1. )

! y comp of wind stress (CI_2)
! V point to F point
         DO_2D( 1, 0, 1, 1 )
            ztmp(ji,jj) = 0.5 * (  fr_iv(ji,jj) * vtau(ji,jj)      &
                                 + fr_iv(ji+1,jj) * vtau(ji+1,jj) ) * fmask(ji,jj,1)
         END_2D
         CALL nemo2cice(ztmp,stray,'F', -1. )

! Surface downward latent heat flux (CI_5)
         IF(ksbc == jp_flx) THEN
            DO jl=1,ncat
               ztmpn(:,:,jl)=qla_ice(:,:,1)*a_i(:,:,jl)
            ENDDO
         ELSE
! emp_ice is set in sbc_cpl_ice_flx as sublimation-snow
            qla_ice(:,:,1)= - ( emp_ice(:,:)+sprecip(:,:) ) * rLsub
! End of temporary code
            DO_2D( 1, 1, 1, 1 )
               IF(fr_i(ji,jj).eq.0.0) THEN
                  DO jl=1,ncat
                     ztmpn(ji,jj,jl)=0.0
                  ENDDO
                  ! This will then be conserved in CICE
                  ztmpn(ji,jj,1)=qla_ice(ji,jj,1)
               ELSE
                  DO jl=1,ncat
                     ztmpn(ji,jj,jl)=qla_ice(ji,jj,1)*a_i(ji,jj,jl)/fr_i(ji,jj)
                  ENDDO
               ENDIF
            END_2D
         ENDIF
         DO jl=1,ncat
            CALL nemo2cice(ztmpn(:,:,jl),flatn_f(:,:,jl,:),'T', 1. )

! GBM conductive flux through ice (CI_6)
!  Convert to GBM
            IF(ksbc == jp_flx) THEN
               ztmp(:,:) = botmelt(:,:,jl)*a_i(:,:,jl)
            ELSE
               ztmp(:,:) = botmelt(:,:,jl)
            ENDIF
            CALL nemo2cice(ztmp,fcondtopn_f(:,:,jl,:),'T', 1. )

! GBM surface heat flux (CI_7)
!  Convert to GBM
            IF(ksbc == jp_flx) THEN
               ztmp(:,:) = (topmelt(:,:,jl)+botmelt(:,:,jl))*a_i(:,:,jl) 
            ELSE
               ztmp(:,:) = (topmelt(:,:,jl)+botmelt(:,:,jl))
            ENDIF
            CALL nemo2cice(ztmp,fsurfn_f(:,:,jl,:),'T', 1. )
         ENDDO

      ELSE IF(ksbc == jp_blk) THEN

! Pass bulk forcing fields to CICE (which will calculate heat fluxes etc itself)
! x comp and y comp of atmosphere surface wind (CICE expects on T points)
         ztmp(:,:) = wndi_ice(:,:)
         CALL nemo2cice(ztmp,uatm,'T', -1. )
         ztmp(:,:) = wndj_ice(:,:)
         CALL nemo2cice(ztmp,vatm,'T', -1. )
         ztmp(:,:) = SQRT ( wndi_ice(:,:)**2 + wndj_ice(:,:)**2 )
         CALL nemo2cice(ztmp,wind,'T', 1. )    ! Wind speed (m/s)
         ztmp(:,:) = qsr_ice(:,:,1)
         CALL nemo2cice(ztmp,fsw,'T', 1. )     ! Incoming short-wave (W/m^2)
         ztmp(:,:) = qlw_ice(:,:,1)
         CALL nemo2cice(ztmp,flw,'T', 1. )     ! Incoming long-wave (W/m^2)
         ztmp(:,:) = tatm_ice(:,:)
         CALL nemo2cice(ztmp,Tair,'T', 1. )    ! Air temperature (K)
         CALL nemo2cice(ztmp,potT,'T', 1. )    ! Potential temp (K)
! Following line uses MAX(....) to avoid problems if tatm_ice has unset halo rows  
         ztmp(:,:) = 101000. / ( 287.04 * MAX(1.0,tatm_ice(:,:)) )    
                                               ! Constant (101000.) atm pressure assumed
         CALL nemo2cice(ztmp,rhoa,'T', 1. )    ! Air density (kg/m^3)
         ztmp(:,:) = qatm_ice(:,:)
         CALL nemo2cice(ztmp,Qa,'T', 1. )      ! Specific humidity (kg/kg)
         ztmp(:,:)=10.0
         CALL nemo2cice(ztmp,zlvl,'T', 1. )    ! Atmos level height (m)

! May want to check all values are physically realistic (as in CICE routine 
! prepare_forcing)?

! Divide shortwave into spectral bands (as in prepare_forcing)
         ztmp(:,:)=qsr_ice(:,:,1)*frcvdr       ! visible direct
         CALL nemo2cice(ztmp,swvdr,'T', 1. )             
         ztmp(:,:)=qsr_ice(:,:,1)*frcvdf       ! visible diffuse
         CALL nemo2cice(ztmp,swvdf,'T', 1. )              
         ztmp(:,:)=qsr_ice(:,:,1)*frcidr       ! near IR direct
         CALL nemo2cice(ztmp,swidr,'T', 1. )
         ztmp(:,:)=qsr_ice(:,:,1)*frcidf       ! near IR diffuse
         CALL nemo2cice(ztmp,swidf,'T', 1. )

      ENDIF

! Snowfall
! Ensure fsnow is positive (as in CICE routine prepare_forcing)
      IF( iom_use('snowpre') )   CALL iom_put('snowpre',MAX( (1.0-fr_i(:,:))*sprecip(:,:) ,0.0)) !!Joakim edit  
      ztmp(:,:)=MAX(fr_i(:,:)*sprecip(:,:),0.0)  
      CALL nemo2cice(ztmp,fsnow,'T', 1. ) 

! Rainfall
      IF( iom_use('precip') )   CALL iom_put('precip', (1.0-fr_i(:,:))*(tprecip(:,:)-sprecip(:,:)) ) !!Joakim edit
      ztmp(:,:)=fr_i(:,:)*(tprecip(:,:)-sprecip(:,:))
      CALL nemo2cice(ztmp,frain,'T', 1. ) 

! Freezing/melting potential
! Calculated over NEMO leapfrog timestep (hence 2*dt)
      nfrzmlt(:,:) = rho0 * rcp * e3t_m(:,:) * ( Tocnfrz-sst_m(:,:) ) / ( 2.0*dt )

      ztmp(:,:) = nfrzmlt(:,:)
      CALL nemo2cice(ztmp,frzmlt,'T', 1. )

! SST  and SSS

      CALL nemo2cice(sst_m,sst,'T', 1. )
      CALL nemo2cice(sss_m,sss,'T', 1. )

! x comp and y comp of surface ocean current
! U point to F point
      DO_2D( 1, 1, 1, 0 )
         ztmp(ji,jj)=0.5*(ssu_m(ji,jj)+ssu_m(ji,jj+1))*fmask(ji,jj,1)
      END_2D
      CALL nemo2cice(ztmp,uocn,'F', -1. )

! V point to F point
      DO_2D( 1, 0, 1, 1 )
         ztmp(ji,jj)=0.5*(ssv_m(ji,jj)+ssv_m(ji+1,jj))*fmask(ji,jj,1)
      END_2D
      CALL nemo2cice(ztmp,vocn,'F', -1. )

      IF( ln_ice_embd ) THEN             !== embedded sea ice: compute representative ice top surface ==!
          !
          ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[n/nn_fsbc], n=0,nn_fsbc-1}
          !                                               = (1/nn_fsbc)^2 * {SUM[n], n=0,nn_fsbc-1}
         zintn = REAL( nn_fsbc - 1 ) / REAL( nn_fsbc ) * 0.5_wp
          !
          ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[1-n/nn_fsbc], n=0,nn_fsbc-1}
          !                                               = (1/nn_fsbc)^2 * (nn_fsbc^2 - {SUM[n], n=0,nn_fsbc-1})
         zintb = REAL( nn_fsbc + 1 ) / REAL( nn_fsbc ) * 0.5_wp
          !
         zpice(:,:) = ssh_m(:,:) + (  zintn * snwice_mass(:,:) +  zintb * snwice_mass_b(:,:)  ) * r1_rho0
          !
         !
      ELSE                                    !== non-embedded sea ice: use ocean surface for slope calculation ==!
         zpice(:,:) = ssh_m(:,:)
      ENDIF

! x comp and y comp of sea surface slope (on F points)
! T point to F point
      DO_2D( 1, 0, 1, 0 )
         ztmp(ji,jj)=0.5 * (  (zpice(ji+1,jj  )-zpice(ji,jj  )) * r1_e1u(ji,jj  )    &
            &               + (zpice(ji+1,jj+1)-zpice(ji,jj+1)) * r1_e1u(ji,jj+1)  ) * fmask(ji,jj,1)
      END_2D
      CALL nemo2cice( ztmp,ss_tltx,'F', -1. )

! T point to F point
      DO_2D( 1, 0, 1, 0 )
         ztmp(ji,jj)=0.5 * (  (zpice(ji  ,jj+1)-zpice(ji  ,jj)) * r1_e2v(ji  ,jj)    &
            &               + (zpice(ji+1,jj+1)-zpice(ji+1,jj)) * r1_e2v(ji+1,jj)  ) *  fmask(ji,jj,1)
      END_2D
      CALL nemo2cice(ztmp,ss_tlty,'F', -1. )
      !
   END SUBROUTINE cice_sbc_in


   SUBROUTINE cice_sbc_out( kt, ksbc )
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE cice_sbc_out  ***
      !! ** Purpose: Get fields from CICE and set surface fields for NEMO
      !!---------------------------------------------------------------------
      INTEGER, INTENT( in  ) ::   kt   ! ocean time step
      INTEGER, INTENT( in  ) ::   ksbc ! surface forcing type
      
      INTEGER  ::   ji, jj, jl                 ! dummy loop indices
      REAL(wp), DIMENSION(jpi,jpj) :: ztmp1, ztmp2
      !!---------------------------------------------------------------------
      !
      IF( kt == nit000 )  THEN
         IF(lwp) WRITE(numout,*)'cice_sbc_out'
      ENDIF
      
! x comp of ocean-ice stress 
      CALL cice2nemo(strocnx,ztmp1,'F', -1. )
      ss_iou(:,:)=0.0
! F point to U point
      DO_2D( 0, 0, 0, 0 )
         ss_iou(ji,jj) = 0.5 * ( ztmp1(ji,jj-1) + ztmp1(ji,jj) ) * umask(ji,jj,1)
      END_2D
      CALL lbc_lnk( 'sbcice_cice', ss_iou , 'U', -1.0_wp )

! y comp of ocean-ice stress 
      CALL cice2nemo(strocny,ztmp1,'F', -1. )
      ss_iov(:,:)=0.0
! F point to V point

      DO_2D( 0, 0, 1, 0 )
         ss_iov(ji,jj) = 0.5 * ( ztmp1(ji-1,jj) + ztmp1(ji,jj) ) * vmask(ji,jj,1)
      END_2D
      CALL lbc_lnk( 'sbcice_cice', ss_iov , 'V', -1.0_wp )

! x and y comps of surface stress
! Combine wind stress and ocean-ice stress
! [Note that fr_iu hasn't yet been updated, so still from start of CICE timestep]
! strocnx and strocny already weighted by ice fraction in CICE so not done here 

      utau(:,:)=(1.0-fr_iu(:,:))*utau(:,:)-ss_iou(:,:)
      vtau(:,:)=(1.0-fr_iv(:,:))*vtau(:,:)-ss_iov(:,:)     
 
! Also need ice/ocean stress on T points so that taum can be updated 
! This interpolation is already done in CICE so best to use those values 
      CALL cice2nemo(strocnxT,ztmp1,'T',-1.) 
      CALL cice2nemo(strocnyT,ztmp2,'T',-1.) 
 
! Update taum with modulus of ice-ocean stress 
! strocnxT and strocnyT are not weighted by ice fraction in CICE so must be done here 
taum(:,:)=(1.0-fr_i(:,:))*taum(:,:)+fr_i(:,:)*SQRT(ztmp1*ztmp1 + ztmp2*ztmp2) 

! Freshwater fluxes 

      IF(ksbc == jp_flx) THEN
! Note that emp from the forcing files is evap*(1-aice)-(tprecip-aice*sprecip)
! What we want here is evap*(1-aice)-tprecip*(1-aice) hence manipulation below
! Not ideal since aice won't be the same as in the atmosphere.  
! Better to use evap and tprecip? (but for now don't read in evap in this case)
         emp(:,:)  = emp(:,:)+fr_i(:,:)*(tprecip(:,:)-sprecip(:,:))
      ELSE IF(ksbc == jp_blk) THEN
         emp(:,:)  = (1.0-fr_i(:,:))*emp(:,:)        
      ELSE IF(ksbc == jp_purecpl) THEN
! emp_tot is set in sbc_cpl_ice_flx (called from cice_sbc_in above) 
! This is currently as required with the coupling fields from the UM atmosphere
         emp(:,:) = emp_tot(:,:)+tprecip(:,:)*fr_i(:,:) 
      ENDIF

#if defined key_cice4
      CALL cice2nemo(fresh_gbm,ztmp1,'T', 1. )
      CALL cice2nemo(fsalt_gbm,ztmp2,'T', 1. )
#else
      CALL cice2nemo(fresh_ai,ztmp1,'T', 1. )
      CALL cice2nemo(fsalt_ai,ztmp2,'T', 1. )
#endif

! Check to avoid unphysical expression when ice is forming (ztmp1 negative)
! Otherwise we are effectively allowing ice of higher salinity than the ocean to form
! which has to be compensated for by the ocean salinity potentially going negative
! This check breaks conservation but seems reasonable until we have prognostic ice salinity
! Note the 1000.0 below is to convert from kg salt to g salt (needed for PSU)
      WHERE (ztmp1(:,:).lt.0.0) ztmp2(:,:)=MAX(ztmp2(:,:),ztmp1(:,:)*sss_m(:,:)/1000.0)
      sfx(:,:)=ztmp2(:,:)*1000.0
      emp(:,:)=emp(:,:)-ztmp1(:,:)
      fmmflx(:,:) = ztmp1(:,:) !!Joakim edit
      
      CALL lbc_lnk( 'sbcice_cice', emp , 'T', 1.0_wp, sfx , 'T', 1.0_wp )

! Solar penetrative radiation and non solar surface heat flux

! Scale qsr and qns according to ice fraction (bulk formulae only)

      IF(ksbc == jp_blk) THEN
         qsr(:,:)=qsr(:,:)*(1.0-fr_i(:,:))
         qns(:,:)=qns(:,:)*(1.0-fr_i(:,:))
      ENDIF
! Take into account snow melting except for fully coupled when already in qns_tot
      IF(ksbc == jp_purecpl) THEN
         qsr(:,:)= qsr_tot(:,:)
         qns(:,:)= qns_tot(:,:)
      ELSE
         qns(:,:)= qns(:,:)-sprecip(:,:)*Lfresh*(1.0-fr_i(:,:))
      ENDIF

! Now add in ice / snow related terms
! [fswthru will be zero unless running with calc_Tsfc=T in CICE]
#if defined key_cice4
      CALL cice2nemo(fswthru_gbm,ztmp1,'T', 1. )
#else
      CALL cice2nemo(fswthru_ai,ztmp1,'T', 1. )
#endif
      qsr(:,:)=qsr(:,:)+ztmp1(:,:)
      CALL lbc_lnk( 'sbcice_cice', qsr , 'T', 1.0_wp )

      DO_2D( 1, 1, 1, 1 )
         nfrzmlt(ji,jj)=MAX(nfrzmlt(ji,jj),0.0)
      END_2D

#if defined key_cice4
      CALL cice2nemo(fhocn_gbm,ztmp1,'T', 1. )
#else
      CALL cice2nemo(fhocn_ai,ztmp1,'T', 1. )
#endif
      qns(:,:)=qns(:,:)+nfrzmlt(:,:)+ztmp1(:,:)

      CALL lbc_lnk( 'sbcice_cice', qns , 'T', 1.0_wp )

! Prepare for the following CICE time-step

      CALL cice2nemo(aice,fr_i,'T', 1. )
      IF( (ksbc == jp_flx).OR.(ksbc == jp_purecpl) ) THEN
         DO jl=1,ncat
            CALL cice2nemo(aicen(:,:,jl,:),a_i(:,:,jl), 'T', 1. )
         ENDDO
      ENDIF

! T point to U point
! T point to V point
      DO_2D( 1, 0, 1, 0 )
         fr_iu(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji+1,jj))*umask(ji,jj,1)
         fr_iv(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji,jj+1))*vmask(ji,jj,1)
      END_2D

      CALL lbc_lnk( 'sbcice_cice', fr_iu , 'U', 1.0_wp, fr_iv , 'V', 1.0_wp )

      ! set the snow+ice mass
      CALL cice2nemo(vsno(:,:,:),ztmp1,'T', 1. )
      CALL cice2nemo(vice(:,:,:),ztmp2,'T', 1. )
      snwice_mass  (:,:) = ( rhos * ztmp1(:,:) + rhoi * ztmp2(:,:)  )
      snwice_mass_b(:,:) = snwice_mass(:,:)
      snwice_fmass (:,:) = ( snwice_mass(:,:) - snwice_mass_b(:,:) ) / dt
      !
   END SUBROUTINE cice_sbc_out


   SUBROUTINE cice_sbc_hadgam( kt )
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE cice_sbc_hadgam  ***
      !! ** Purpose: Prepare fields needed to pass to HadGAM3 atmosphere
      !! 
      !!
      !!---------------------------------------------------------------------
      INTEGER, INTENT( in  ) ::   kt   ! ocean time step
      !!
      INTEGER  ::   jl                        ! dummy loop index
      INTEGER  ::   ierror
      !!---------------------------------------------------------------------
      !
      IF( kt == nit000 )  THEN
         IF(lwp) WRITE(numout,*)'cice_sbc_hadgam'
         IF( sbc_cpl_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'sbc_cpl_alloc : unable to allocate arrays' )
      ENDIF

      !                                         ! =========================== !
      !                                         !   Prepare Coupling fields   !
      !                                         ! =========================== !
      !
      ! x and y comp of ice velocity
      !
      CALL cice2nemo(uvel,u_ice,'F', -1. )
      CALL cice2nemo(vvel,v_ice,'F', -1. )
      !
      ! Ice concentration (CO_1) = a_i calculated at end of cice_sbc_out  
      !
      ! Snow and ice thicknesses (CO_2 and CO_3)
      !
      DO jl = 1, ncat
         CALL cice2nemo( vsnon(:,:,jl,:), h_s(:,:,jl),'T', 1. )
         CALL cice2nemo( vicen(:,:,jl,:), h_i(:,:,jl),'T', 1. )
      END DO
      !
   END SUBROUTINE cice_sbc_hadgam


   SUBROUTINE cice_sbc_final
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE cice_sbc_final  ***
      !! ** Purpose: Finalize CICE
      !!---------------------------------------------------------------------
      !
      IF(lwp) WRITE(numout,*)'cice_sbc_final'
      !
      CALL CICE_Finalize
      !
   END SUBROUTINE cice_sbc_final


   SUBROUTINE cice_sbc_force (kt)
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE cice_sbc_force  ***
      !! ** Purpose : Provide CICE forcing from files
      !!
      !!---------------------------------------------------------------------
      !! ** Method  :   READ monthly flux file in NetCDF files
      !!      
      !!  snowfall    
      !!  rainfall    
      !!  sublimation rate    
      !!  topmelt (category)
      !!  botmelt (category)
      !!
      !! History :
      !!----------------------------------------------------------------------
      USE iom
      !!
      INTEGER, INTENT( in  ) ::   kt   ! ocean time step
      !!
      INTEGER  ::   ierror             ! return error code
      INTEGER  ::   ifpr               ! dummy loop index
      !!
      CHARACTER(len=100) ::  cn_dir                            !   Root directory for location of CICE forcing files
      TYPE(FLD_N), DIMENSION(jpfld) ::   slf_i                 ! array of namelist informations on the fields to read
      TYPE(FLD_N) ::   sn_snow, sn_rain, sn_sblm               ! informations about the fields to be read
      TYPE(FLD_N) ::   sn_top1, sn_top2, sn_top3, sn_top4, sn_top5
      TYPE(FLD_N) ::   sn_bot1, sn_bot2, sn_bot3, sn_bot4, sn_bot5 
      !!
      NAMELIST/namsbc_cice/ cn_dir, sn_snow, sn_rain, sn_sblm,   &
         &                          sn_top1, sn_top2, sn_top3, sn_top4, sn_top5,  &
         &                          sn_bot1, sn_bot2, sn_bot3, sn_bot4, sn_bot5
      INTEGER :: ios
      !!---------------------------------------------------------------------

      !                                         ! ====================== !
      IF( kt == nit000 ) THEN                   !  First call kt=nit000  !
         !                                      ! ====================== !
         ! namsbc_cice is not yet in the reference namelist
         ! set file information (default values)
         cn_dir = './'       ! directory in which the model is executed

         ! (NB: frequency positive => hours, negative => months)
         !            !    file          ! frequency !  variable    ! time intep !  clim   ! 'yearly' or ! weights  ! rotation   ! landmask
         !            !    name          !  (hours)  !   name       !   (T/F)    !  (T/F)  !  'monthly'  ! filename ! pairs      ! file
         sn_snow = FLD_N( 'snowfall_1m'  ,    -1.    ,  'snowfall'  ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    ) 
         sn_rain = FLD_N( 'rainfall_1m'  ,    -1.    ,  'rainfall'  ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    ) 
         sn_sblm = FLD_N( 'sublim_1m'    ,    -1.    ,  'sublim'    ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_top1 = FLD_N( 'topmeltn1_1m' ,    -1.    ,  'topmeltn1' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_top2 = FLD_N( 'topmeltn2_1m' ,    -1.    ,  'topmeltn2' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_top3 = FLD_N( 'topmeltn3_1m' ,    -1.    ,  'topmeltn3' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_top4 = FLD_N( 'topmeltn4_1m' ,    -1.    ,  'topmeltn4' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_top5 = FLD_N( 'topmeltn5_1m' ,    -1.    ,  'topmeltn5' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_bot1 = FLD_N( 'botmeltn1_1m' ,    -1.    ,  'botmeltn1' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_bot2 = FLD_N( 'botmeltn2_1m' ,    -1.    ,  'botmeltn2' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_bot3 = FLD_N( 'botmeltn3_1m' ,    -1.    ,  'botmeltn3' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_bot4 = FLD_N( 'botmeltn4_1m' ,    -1.    ,  'botmeltn4' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )
         sn_bot5 = FLD_N( 'botmeltn5_1m' ,    -1.    ,  'botmeltn5' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    )

         READ  ( numnam_ref, namsbc_cice, IOSTAT = ios, ERR = 901)
901      IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_cice in reference namelist' )

         READ  ( numnam_cfg, namsbc_cice, IOSTAT = ios, ERR = 902 )
902      IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_cice in configuration namelist' )
         IF(lwm) WRITE ( numond, namsbc_cice )

         ! store namelist information in an array
         slf_i(jp_snow) = sn_snow   ;   slf_i(jp_rain) = sn_rain   ;   slf_i(jp_sblm) = sn_sblm
         slf_i(jp_top1) = sn_top1   ;   slf_i(jp_top2) = sn_top2   ;   slf_i(jp_top3) = sn_top3
         slf_i(jp_top4) = sn_top4   ;   slf_i(jp_top5) = sn_top5   ;   slf_i(jp_bot1) = sn_bot1
         slf_i(jp_bot2) = sn_bot2   ;   slf_i(jp_bot3) = sn_bot3   ;   slf_i(jp_bot4) = sn_bot4
         slf_i(jp_bot5) = sn_bot5
         
         ! set sf structure
         ALLOCATE( sf(jpfld), STAT=ierror )
         IF( ierror > 0 ) THEN
            CALL ctl_stop( 'cice_sbc_force: unable to allocate sf structure' )   ;   RETURN
         ENDIF

         DO ifpr= 1, jpfld
            ALLOCATE( sf(ifpr)%fnow(jpi,jpj,1) )
            ALLOCATE( sf(ifpr)%fdta(jpi,jpj,1,2) )
         END DO

         ! fill sf with slf_i and control print
         CALL fld_fill( sf, slf_i, cn_dir, 'cice_sbc_force', 'flux formulation for CICE', 'namsbc_cice' )
         !
      ENDIF

      CALL fld_read( kt, nn_fsbc, sf )           ! Read input fields and provides the
      !                                          ! input fields at the current time-step

      ! set the fluxes from read fields
      sprecip(:,:) = sf(jp_snow)%fnow(:,:,1)
      tprecip(:,:) = sf(jp_snow)%fnow(:,:,1)+sf(jp_rain)%fnow(:,:,1)
! May be better to do this conversion somewhere else
      qla_ice(:,:,1) = -rLsub*sf(jp_sblm)%fnow(:,:,1)
      topmelt(:,:,1) = sf(jp_top1)%fnow(:,:,1)
      topmelt(:,:,2) = sf(jp_top2)%fnow(:,:,1)
      topmelt(:,:,3) = sf(jp_top3)%fnow(:,:,1)
      topmelt(:,:,4) = sf(jp_top4)%fnow(:,:,1)
      topmelt(:,:,5) = sf(jp_top5)%fnow(:,:,1)
      botmelt(:,:,1) = sf(jp_bot1)%fnow(:,:,1)
      botmelt(:,:,2) = sf(jp_bot2)%fnow(:,:,1)
      botmelt(:,:,3) = sf(jp_bot3)%fnow(:,:,1)
      botmelt(:,:,4) = sf(jp_bot4)%fnow(:,:,1)
      botmelt(:,:,5) = sf(jp_bot5)%fnow(:,:,1)

      ! control print (if less than 100 time-step asked)
      IF( nitend-nit000 <= 100 .AND. lwp ) THEN
         WRITE(numout,*) 
         WRITE(numout,*) '        read forcing fluxes for CICE OK'
         CALL FLUSH(numout)
      ENDIF

   END SUBROUTINE cice_sbc_force

   SUBROUTINE nemo2cice( pn, pc, cd_type, psgn)
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE nemo2cice  ***
      !! ** Purpose :   Transfer field in NEMO array to field in CICE array.  
#if defined key_nemocice_decomp
      !!             
      !!                NEMO and CICE PE sub domains are identical, hence
      !!                there is no need to gather or scatter data from 
      !!                one PE configuration to another.
#else
      !!                Automatically gather/scatter between 
      !!                different processors and blocks
      !! ** Method :    A. Ensure all haloes are filled in NEMO field (pn)
      !!                B. Gather pn into global array (png)
      !!                C. Map png into CICE global array (pcg)
      !!                D. Scatter pcg to CICE blocks (pc) + update haloes  
#endif
      !!---------------------------------------------------------------------
      CHARACTER(len=1), INTENT( in ) ::   &
          cd_type       ! nature of pn grid-point
          !             !   = T or F gridpoints
      REAL(wp), INTENT( in ) ::   &
          psgn          ! control of the sign change
          !             !   =-1 , the sign is modified following the type of b.c. used
          !             !   = 1 , no sign change
      REAL(wp), DIMENSION(jpi,jpj) :: pn
#if !defined key_nemocice_decomp
      REAL(wp), DIMENSION(jpiglo,jpjglo) :: png2
      REAL (kind=dbl_kind), dimension(nx_global,ny_global) :: pcg
#endif
      REAL (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: pc
      INTEGER (int_kind) :: &
         field_type,        &! id for type of field (scalar, vector, angle)
         grid_loc            ! id for location on horizontal grid
                            !  (center, NEcorner, Nface, Eface)

      INTEGER  ::   ji, jj, jn                      ! dummy loop indices
      !!---------------------------------------------------------------------

!     A. Ensure all haloes are filled in NEMO field (pn)

      CALL lbc_lnk( 'sbcice_cice', pn , cd_type, psgn )

#if defined key_nemocice_decomp

      ! Copy local domain data from NEMO to CICE field
      pc(:,:,1)=0.0
      DO jj=2,ny_block-1
         DO ji=2,nx_block-1
            pc(ji,jj,1)=pn(ji-1+ji_off,jj-1+jj_off)
         ENDDO
      ENDDO

#else

!     B. Gather pn into global array (png)

      IF( jpnij > 1) THEN
         CALL mppsync
         CALL mppgather (pn,0,png) 
         CALL mppsync
      ELSE
         png(:,:,1)=pn(:,:)
      ENDIF

!     C. Map png into CICE global array (pcg)

! Need to make sure this is robust to changes in NEMO halo rows....
! (may be OK but not 100% sure)

      IF(narea==1) THEN     
!        pcg(:,:)=0.0
         DO jn=1,jpnij
            DO jj=njs0all(jn),nje0all(jn)
               DO ji=nis0all(jn),nie0all(jn)
                  png2(ji+nimppt(jn)-1,jj+njmppt(jn)-1)=png(ji,jj,jn)
               ENDDO
            ENDDO
         ENDDO
         DO jj=1,ny_global
            DO ji=1,nx_global
               pcg(ji,jj)=png2(ji+ji_off,jj+jj_off)
            ENDDO
         ENDDO
      ENDIF

#endif

      SELECT CASE ( cd_type )
         CASE ( 'T' )
            grid_loc=field_loc_center
         CASE ( 'F' )                              
            grid_loc=field_loc_NEcorner
      END SELECT

      SELECT CASE ( NINT(psgn) )
         CASE ( -1 )
            field_type=field_type_vector
         CASE ( 1 )                              
            field_type=field_type_scalar
      END SELECT

#if defined key_nemocice_decomp
      ! Ensure CICE halos are up to date
      CALL ice_HaloUpdate (pc, halo_info, grid_loc, field_type)
#else
!     D. Scatter pcg to CICE blocks (pc) + update halos
      CALL scatter_global(pc, pcg, 0, distrb_info, grid_loc, field_type)
#endif

   END SUBROUTINE nemo2cice

   SUBROUTINE cice2nemo ( pc, pn, cd_type, psgn )
      !!---------------------------------------------------------------------
      !!                    ***  ROUTINE cice2nemo  ***
      !! ** Purpose :   Transfer field in CICE array to field in NEMO array.
#if defined key_nemocice_decomp
      !!             
      !!                NEMO and CICE PE sub domains are identical, hence
      !!                there is no need to gather or scatter data from 
      !!                one PE configuration to another.
#else 
      !!                Automatically deal with scatter/gather between
      !!                different processors and blocks
      !! ** Method :    A. Gather CICE blocks (pc) into global array (pcg)
      !!                B. Map pcg into NEMO global array (png)
      !!                C. Scatter png into NEMO field (pn) for each processor
      !!                D. Ensure all haloes are filled in pn 
#endif
      !!---------------------------------------------------------------------

      CHARACTER(len=1), INTENT( in ) ::   &
          cd_type       ! nature of pn grid-point
          !             !   = T or F gridpoints
      REAL(wp), INTENT( in ) ::   &
          psgn          ! control of the sign change
          !             !   =-1 , the sign is modified following the type of b.c. used
          !             !   = 1 , no sign change
      REAL(wp), DIMENSION(jpi,jpj) :: pn

#if defined key_nemocice_decomp
      INTEGER (int_kind) :: &
         field_type,        & ! id for type of field (scalar, vector, angle)
         grid_loc             ! id for location on horizontal grid
                              ! (center, NEcorner, Nface, Eface)
#else
      REAL (kind=dbl_kind), dimension(nx_global,ny_global) :: pcg
#endif

      REAL (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks) :: pc

      INTEGER  ::   ji, jj, jn                      ! dummy loop indices


#if defined key_nemocice_decomp

      SELECT CASE ( cd_type )
         CASE ( 'T' )
            grid_loc=field_loc_center
         CASE ( 'F' )                              
            grid_loc=field_loc_NEcorner
      END SELECT

      SELECT CASE ( NINT(psgn) )
         CASE ( -1 )
            field_type=field_type_vector
         CASE ( 1 )                              
            field_type=field_type_scalar
      END SELECT

      CALL ice_HaloUpdate (pc, halo_info, grid_loc, field_type)


      pn(:,:)=0.0
      DO_2D( 1, 0, 1, 0 )
         pn(ji,jj)=pc(ji+1-ji_off,jj+1-jj_off,1)
      END_2D

#else

!      A. Gather CICE blocks (pc) into global array (pcg) 

      CALL gather_global(pcg, pc, 0, distrb_info)

!     B. Map pcg into NEMO global array (png)

! Need to make sure this is robust to changes in NEMO halo rows....
! (may be OK but not spent much time thinking about it)
! Note that non-existent pcg elements may be used below, but
! the lbclnk call on pn will replace these with sensible values

      IF(narea==1) THEN