New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
Changeset 12377 for NEMO/trunk/src/OCE/SBC – NEMO

Ignore:
Timestamp:
2020-02-12T15:39:06+01:00 (4 years ago)
Author:
acc
Message:

The big one. Merging all 2019 developments from the option 1 branch back onto the trunk.

This changeset reproduces 2019/dev_r11943_MERGE_2019 on the trunk using a 2-URL merge
onto a working copy of the trunk. I.e.:

svn merge --ignore-ancestry \

svn+ssh://acc@forge.ipsl.jussieu.fr/ipsl/forge/projets/nemo/svn/NEMO/trunk \
svn+ssh://acc@forge.ipsl.jussieu.fr/ipsl/forge/projets/nemo/svn/NEMO/branches/2019/dev_r11943_MERGE_2019 ./

The --ignore-ancestry flag avoids problems that may otherwise arise from the fact that
the merge history been trunk and branch may have been applied in a different order but
care has been taken before this step to ensure that all applicable fixes and updates
are present in the merge branch.

The trunk state just before this step has been branched to releases/release-4.0-HEAD
and that branch has been immediately tagged as releases/release-4.0.2. Any fixes
or additions in response to tickets on 4.0, 4.0.1 or 4.0.2 should be done on
releases/release-4.0-HEAD. From now on future 'point' releases (e.g. 4.0.2) will
remain unchanged with periodic releases as needs demand. Note release-4.0-HEAD is a
transitional naming convention. Future full releases, say 4.2, will have a release-4.2
branch which fulfills this role and the first point release (e.g. 4.2.0) will be made
immediately following the release branch creation.

2020 developments can be started from any trunk revision later than this one.

Location:
NEMO/trunk
Files:
8 deleted
21 edited
8 copied

Legend:

Unmodified
Added
Removed
  • NEMO/trunk

    • Property svn:externals
      •  

        old new  
        33^/utils/build/mk@HEAD         mk 
        44^/utils/tools@HEAD            tools 
        5 ^/vendors/AGRIF/dev@HEAD      ext/AGRIF 
         5^/vendors/AGRIF/dev_r11615_ENHANCE-04_namelists_as_internalfiles_agrif@HEAD      ext/AGRIF 
        66^/vendors/FCM@HEAD            ext/FCM 
        77^/vendors/IOIPSL@HEAD         ext/IOIPSL 
  • NEMO/trunk/src/OCE/SBC/cpl_oasis3.F90

    r12132 r12377  
    114114      !------------------------------------------------------------------ 
    115115      CALL oasis_init_comp ( ncomp_id, TRIM(cd_modname), nerror ) 
    116       IF ( nerror /= OASIS_Ok ) & 
     116      IF( nerror /= OASIS_Ok ) & 
    117117         CALL oasis_abort (ncomp_id, 'cpl_init', 'Failure in oasis_init_comp') 
    118118 
     
    122122 
    123123      CALL oasis_get_localcomm ( kl_comm, nerror ) 
    124       IF ( nerror /= OASIS_Ok ) & 
     124      IF( nerror /= OASIS_Ok ) & 
    125125         CALL oasis_abort (ncomp_id, 'cpl_init','Failure in oasis_get_localcomm' ) 
    126126      ! 
     
    149149 
    150150      ! patch to restore wraparound rows in cpl_send, cpl_rcv, cpl_define 
    151       IF ( ltmp_wapatch ) THEN 
     151      IF( ltmp_wapatch ) THEN 
    152152         nldi_save = nldi   ;   nlei_save = nlei 
    153153         nldj_save = nldj   ;   nlej_save = nlej 
     
    203203      paral(5) = jpiglo                                         ! global extent in x 
    204204       
    205       IF( ln_ctl ) THEN 
     205      IF( sn_cfctl%l_oasout ) THEN 
    206206         WRITE(numout,*) ' multiexchg: paral (1:5)', paral 
    207207         WRITE(numout,*) ' multiexchg: jpi, jpj =', jpi, jpj 
     
    217217      ! 
    218218      DO ji = 1, ksnd 
    219          IF ( ssnd(ji)%laction ) THEN 
     219         IF( ssnd(ji)%laction ) THEN 
    220220 
    221221            IF( ssnd(ji)%nct > nmaxcat ) THEN 
     
    228228               DO jm = 1, kcplmodel 
    229229 
    230                   IF ( ssnd(ji)%nct .GT. 1 ) THEN 
     230                  IF( ssnd(ji)%nct .GT. 1 ) THEN 
    231231                     WRITE(cli2,'(i2.2)') jc 
    232232                     zclname = TRIM(ssnd(ji)%clname)//'_cat'//cli2 
     
    234234                     zclname = ssnd(ji)%clname 
    235235                  ENDIF 
    236                   IF ( kcplmodel  > 1 ) THEN 
     236                  IF( kcplmodel  > 1 ) THEN 
    237237                     WRITE(cli2,'(i2.2)') jm 
    238238                     zclname = 'model'//cli2//'_'//TRIM(zclname) 
     
    241241                  IF( agrif_fixed() /= 0 ) THEN  
    242242                     zclname=TRIM(Agrif_CFixed())//'_'//TRIM(zclname) 
    243                   END IF 
    244 #endif 
    245                   IF( ln_ctl ) WRITE(numout,*) "Define", ji, jc, jm, " "//TRIM(zclname), " for ", OASIS_Out 
     243                  ENDIF 
     244#endif 
     245                  IF( sn_cfctl%l_oasout ) WRITE(numout,*) "Define", ji, jc, jm, " "//TRIM(zclname), " for ", OASIS_Out 
    246246                  CALL oasis_def_var (ssnd(ji)%nid(jc,jm), zclname, id_part   , (/ 2, 1 /),   & 
    247247                     &                OASIS_Out          , ishape , OASIS_REAL, nerror ) 
    248                   IF ( nerror /= OASIS_Ok ) THEN 
     248                  IF( nerror /= OASIS_Ok ) THEN 
    249249                     WRITE(numout,*) 'Failed to define transient ', ji, jc, jm, " "//TRIM(zclname) 
    250250                     CALL oasis_abort ( ssnd(ji)%nid(jc,jm), 'cpl_define', 'Failure in oasis_def_var' ) 
    251251                  ENDIF 
    252                   IF( ln_ctl .AND. ssnd(ji)%nid(jc,jm) /= -1 ) WRITE(numout,*) "variable defined in the namcouple" 
    253                   IF( ln_ctl .AND. ssnd(ji)%nid(jc,jm) == -1 ) WRITE(numout,*) "variable NOT defined in the namcouple" 
     252                  IF( sn_cfctl%l_oasout .AND. ssnd(ji)%nid(jc,jm) /= -1 ) WRITE(numout,*) "variable defined in the namcouple" 
     253                  IF( sn_cfctl%l_oasout .AND. ssnd(ji)%nid(jc,jm) == -1 ) WRITE(numout,*) "variable NOT defined in the namcouple" 
    254254               END DO 
    255255            END DO 
     
    262262      ! 
    263263      DO ji = 1, krcv 
    264          IF ( srcv(ji)%laction ) THEN  
     264         IF( srcv(ji)%laction ) THEN  
    265265             
    266266            IF( srcv(ji)%nct > nmaxcat ) THEN 
     
    273273               DO jm = 1, kcplmodel 
    274274                   
    275                   IF ( srcv(ji)%nct .GT. 1 ) THEN 
     275                  IF( srcv(ji)%nct .GT. 1 ) THEN 
    276276                     WRITE(cli2,'(i2.2)') jc 
    277277                     zclname = TRIM(srcv(ji)%clname)//'_cat'//cli2 
     
    279279                     zclname = srcv(ji)%clname 
    280280                  ENDIF 
    281                   IF ( kcplmodel  > 1 ) THEN 
     281                  IF( kcplmodel  > 1 ) THEN 
    282282                     WRITE(cli2,'(i2.2)') jm 
    283283                     zclname = 'model'//cli2//'_'//TRIM(zclname) 
     
    286286                  IF( agrif_fixed() /= 0 ) THEN  
    287287                     zclname=TRIM(Agrif_CFixed())//'_'//TRIM(zclname) 
    288                   END IF 
    289 #endif 
    290                   IF( ln_ctl ) WRITE(numout,*) "Define", ji, jc, jm, " "//TRIM(zclname), " for ", OASIS_In 
     288                  ENDIF 
     289#endif 
     290                  IF( sn_cfctl%l_oasout ) WRITE(numout,*) "Define", ji, jc, jm, " "//TRIM(zclname), " for ", OASIS_In 
    291291                  CALL oasis_def_var (srcv(ji)%nid(jc,jm), zclname, id_part   , (/ 2, 1 /),   & 
    292292                     &                OASIS_In           , ishape , OASIS_REAL, nerror ) 
    293                   IF ( nerror /= OASIS_Ok ) THEN 
     293                  IF( nerror /= OASIS_Ok ) THEN 
    294294                     WRITE(numout,*) 'Failed to define transient ', ji, jc, jm, " "//TRIM(zclname) 
    295295                     CALL oasis_abort ( srcv(ji)%nid(jc,jm), 'cpl_define', 'Failure in oasis_def_var' ) 
    296296                  ENDIF 
    297                   IF( ln_ctl .AND. srcv(ji)%nid(jc,jm) /= -1 ) WRITE(numout,*) "variable defined in the namcouple" 
    298                   IF( ln_ctl .AND. srcv(ji)%nid(jc,jm) == -1 ) WRITE(numout,*) "variable NOT defined in the namcouple" 
     297                  IF( sn_cfctl%l_oasout .AND. srcv(ji)%nid(jc,jm) /= -1 ) WRITE(numout,*) "variable defined in the namcouple" 
     298                  IF( sn_cfctl%l_oasout .AND. srcv(ji)%nid(jc,jm) == -1 ) WRITE(numout,*) "variable NOT defined in the namcouple" 
    299299 
    300300               END DO 
     
    316316#endif 
    317317      ! 
    318       IF ( ltmp_wapatch ) THEN 
     318      IF( ltmp_wapatch ) THEN 
    319319         nldi = nldi_save   ;   nlei = nlei_save 
    320320         nldj = nldj_save   ;   nlej = nlej_save 
     
    338338      !!-------------------------------------------------------------------- 
    339339      ! patch to restore wraparound rows in cpl_send, cpl_rcv, cpl_define 
    340       IF ( ltmp_wapatch ) THEN 
     340      IF( ltmp_wapatch ) THEN 
    341341         nldi_save = nldi   ;   nlei_save = nlei 
    342342         nldj_save = nldj   ;   nlej_save = nlej 
     
    355355               CALL oasis_put ( ssnd(kid)%nid(jc,jm), kstep, pdata(nldi:nlei, nldj:nlej,jc), kinfo ) 
    356356                
    357                IF ( ln_ctl ) THEN         
     357               IF ( sn_cfctl%l_oasout ) THEN         
    358358                  IF ( kinfo == OASIS_Sent     .OR. kinfo == OASIS_ToRest .OR.   & 
    359359                     & kinfo == OASIS_SentOut  .OR. kinfo == OASIS_ToRestOut ) THEN 
     
    374374         ENDDO 
    375375      ENDDO 
    376       IF ( ltmp_wapatch ) THEN 
     376      IF( ltmp_wapatch ) THEN 
    377377         nldi = nldi_save   ;   nlei = nlei_save 
    378378         nldj = nldj_save   ;   nlej = nlej_save 
     
    399399      !!-------------------------------------------------------------------- 
    400400      ! patch to restore wraparound rows in cpl_send, cpl_rcv, cpl_define 
    401       IF ( ltmp_wapatch ) THEN 
     401      IF( ltmp_wapatch ) THEN 
    402402         nldi_save = nldi   ;   nlei_save = nlei 
    403403         nldj_save = nldj   ;   nlej_save = nlej 
     
    409409      ! 
    410410      DO jc = 1, srcv(kid)%nct 
    411          IF ( ltmp_wapatch ) THEN 
     411         IF( ltmp_wapatch ) THEN 
    412412            IF( nimpp           ==      1 ) nldi = 1 
    413413            IF( nimpp + jpi - 1 == jpiglo ) nlei = jpi 
     
    426426                  &        kinfo == OASIS_RecvOut .OR. kinfo == OASIS_FromRestOut 
    427427                
    428                IF ( ln_ctl )   WRITE(numout,*) "llaction, kinfo, kstep, ivarid: " , llaction, kinfo, kstep, srcv(kid)%nid(jc,jm) 
     428               IF ( sn_cfctl%l_oasout )   WRITE(numout,*) "llaction, kinfo, kstep, ivarid: " , llaction, kinfo, kstep, srcv(kid)%nid(jc,jm) 
    429429                
    430                IF ( llaction ) THEN 
     430               IF( llaction ) THEN 
    431431                   
    432432                  kinfo = OASIS_Rcv 
     
    438438                  ENDIF 
    439439                   
    440                   IF ( ln_ctl ) THEN         
     440                  IF ( sn_cfctl%l_oasout ) THEN         
    441441                     WRITE(numout,*) '****************' 
    442442                     WRITE(numout,*) 'oasis_get: Incoming ', srcv(kid)%clname 
     
    456456         ENDDO 
    457457 
    458          IF ( ltmp_wapatch ) THEN 
     458         IF( ltmp_wapatch ) THEN 
    459459            nldi = nldi_save   ;   nlei = nlei_save 
    460460            nldj = nldj_save   ;   nlej = nlej_save 
     
    489489      ! 
    490490      DO ji = 1, nsnd 
    491          IF (ssnd(ji)%laction ) THEN 
     491         IF(ssnd(ji)%laction ) THEN 
    492492            DO jm = 1, ncplmodel 
    493493               IF( ssnd(ji)%nid(1,jm) /= -1 ) THEN 
     
    501501      ENDDO 
    502502      DO ji = 1, nrcv 
    503          IF (srcv(ji)%laction ) THEN 
     503         IF(srcv(ji)%laction ) THEN 
    504504            DO jm = 1, ncplmodel 
    505505               IF( srcv(ji)%nid(1,jm) /= -1 ) THEN 
     
    535535      ! 
    536536      DEALLOCATE( exfld ) 
    537       IF (nstop == 0) THEN 
     537      IF(nstop == 0) THEN 
    538538         CALL oasis_terminate( nerror )          
    539539      ELSE 
  • NEMO/trunk/src/OCE/SBC/cyclone.F90

    r10068 r12377  
    3737 
    3838   !! * Substitutions 
    39 #  include "vectopt_loop_substitute.h90" 
     39#  include "do_loop_substitute.h90" 
    4040   !!---------------------------------------------------------------------- 
    4141   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    137137            zhemi = SIGN( 1. , zrlat ) 
    138138            zinfl = 15.* rad                             ! clim inflow angle in Tropical Cyclones 
    139          IF ( vortex == 0 ) THEN 
     139         IF( vortex == 0 ) THEN 
    140140 
    141141            ! Vortex Holland reconstruct wind at each lon-lat position 
     
    147147            zb = 2. 
    148148 
    149             DO jj = 1, jpj 
    150                DO ji = 1, jpi 
    151  
    152                   ! calc distance between TC center and any point following great circle 
    153                   ! source : http://www.movable-type.co.uk/scripts/latlong.html 
    154                   zzrglam = rad * glamt(ji,jj) - zrlon 
    155                   zzrgphi = rad * gphit(ji,jj) 
    156                   zdist = ra * ACOS(  SIN( zrlat ) * SIN( zzrgphi )   & 
    157                      &              + COS( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) ) 
    158  
    159                  IF (zdist < zrout2) THEN ! calculation of wind only to a given max radius 
    160                   ! shape of the wind profile 
    161                   zztmp = ( zrmw / ( zdist + 1.e-12 ) )**zb 
    162                   zztmp =  zvmax * SQRT( zztmp * EXP(1. - zztmp) )     
    163  
    164                   IF (zdist > zrout1) THEN ! bring to zero between r_out1 and r_out2 
    165                      zztmp = zztmp * ( (zrout2-zdist)*1.e-6 ) 
    166                   ENDIF 
    167  
    168                   ! !!! KILL EQ WINDS 
    169                   ! IF (SIGN( 1. , zrlat ) /= zhemi) THEN 
    170                   !    zztmp = 0.                              ! winds in other hemisphere 
    171                   !    IF (ABS(gphit(ji,jj)) <= 5.) zztmp=0.   ! kill between 5N-5S 
    172                   ! ENDIF 
    173                   ! IF (ABS(gphit(ji,jj)) <= 10. .and. ABS(gphit(ji,jj)) > 5.) THEN 
    174                   !    zztmp = zztmp * ( 1./5. * (ABS(gphit(ji,jj)) - 5.) )  
    175                   !    !linear to zero between 10 and 5 
    176                   ! ENDIF 
    177                   ! !!! / KILL EQ 
    178  
    179                   IF (ABS(gphit(ji,jj)) >= 55.) zztmp = 0. ! kill weak spurious winds at high latitude 
    180  
    181                   zwnd_t =   COS( zinfl ) * zztmp     
    182                   zwnd_r = - SIN( zinfl ) * zztmp 
    183  
    184                   ! Project radial-tangential components on zonal-meridional components 
    185                   ! ------------------------------------------------------------------- 
    186                    
    187                   ! ztheta = azimuthal angle of the great circle between two points 
    188                   zztmp = COS( zrlat ) * SIN( zzrgphi ) & 
    189                      &  - SIN( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) 
    190                   ztheta = ATAN2(        COS( zzrgphi ) * SIN( zzrglam ) , zztmp ) 
    191  
    192                   zwnd_x(ji,jj) = zwnd_x(ji,jj) - zhemi * COS(ztheta)*zwnd_t + SIN(ztheta)*zwnd_r 
    193                   zwnd_y(ji,jj) = zwnd_y(ji,jj) + zhemi * SIN(ztheta)*zwnd_t + COS(ztheta)*zwnd_r 
    194                  ENDIF 
    195                END DO 
    196             END DO 
     149            DO_2D_11_11 
     150 
     151               ! calc distance between TC center and any point following great circle 
     152               ! source : http://www.movable-type.co.uk/scripts/latlong.html 
     153               zzrglam = rad * glamt(ji,jj) - zrlon 
     154               zzrgphi = rad * gphit(ji,jj) 
     155               zdist = ra * ACOS(  SIN( zrlat ) * SIN( zzrgphi )   & 
     156                  &              + COS( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) ) 
     157 
     158              IF(zdist < zrout2) THEN ! calculation of wind only to a given max radius 
     159               ! shape of the wind profile 
     160               zztmp = ( zrmw / ( zdist + 1.e-12 ) )**zb 
     161               zztmp =  zvmax * SQRT( zztmp * EXP(1. - zztmp) )     
     162 
     163               IF(zdist > zrout1) THEN ! bring to zero between r_out1 and r_out2 
     164                  zztmp = zztmp * ( (zrout2-zdist)*1.e-6 ) 
     165               ENDIF 
     166 
     167               ! !!! KILL EQ WINDS 
     168               ! IF(SIGN( 1. , zrlat ) /= zhemi) THEN 
     169               !    zztmp = 0.                              ! winds in other hemisphere 
     170               !    IF(ABS(gphit(ji,jj)) <= 5.) zztmp=0.   ! kill between 5N-5S 
     171               ! ENDIF 
     172               ! IF(ABS(gphit(ji,jj)) <= 10. .and. ABS(gphit(ji,jj)) > 5.) THEN 
     173               !    zztmp = zztmp * ( 1./5. * (ABS(gphit(ji,jj)) - 5.) )  
     174               !    !linear to zero between 10 and 5 
     175               ! ENDIF 
     176               ! !!! / KILL EQ 
     177 
     178               IF(ABS(gphit(ji,jj)) >= 55.) zztmp = 0. ! kill weak spurious winds at high latitude 
     179 
     180               zwnd_t =   COS( zinfl ) * zztmp     
     181               zwnd_r = - SIN( zinfl ) * zztmp 
     182 
     183               ! Project radial-tangential components on zonal-meridional components 
     184               ! ------------------------------------------------------------------- 
     185                
     186               ! ztheta = azimuthal angle of the great circle between two points 
     187               zztmp = COS( zrlat ) * SIN( zzrgphi ) & 
     188                  &  - SIN( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) 
     189               ztheta = ATAN2(        COS( zzrgphi ) * SIN( zzrglam ) , zztmp ) 
     190 
     191               zwnd_x(ji,jj) = zwnd_x(ji,jj) - zhemi * COS(ztheta)*zwnd_t + SIN(ztheta)*zwnd_r 
     192               zwnd_y(ji,jj) = zwnd_y(ji,jj) + zhemi * SIN(ztheta)*zwnd_t + COS(ztheta)*zwnd_r 
     193              ENDIF 
     194            END_2D 
    197195          
    198          ELSE IF ( vortex == 1 ) THEN 
     196         ELSE IF( vortex == 1 ) THEN 
    199197 
    200198            ! Vortex Willoughby reconstruct wind at each lon-lat position 
     
    206204            zn   =   2.1340 + 0.0077*zvmax - 0.4522*LOG(zrmw/1000.) - 0.0038*ABS( ztct(jtc,jp_lat) )             
    207205            zA   =   0.5913 + 0.0029*zvmax - 0.1361*LOG(zrmw/1000.) - 0.0042*ABS( ztct(jtc,jp_lat) )   
    208             IF (zA < 0) THEN  
     206            IF(zA < 0) THEN  
    209207               zA=0 
    210208            ENDIF            
    211209         
    212             DO jj = 1, jpj 
    213                DO ji = 1, jpi 
    214                                    
    215                   zzrglam = rad * glamt(ji,jj) - zrlon 
    216                   zzrgphi = rad * gphit(ji,jj) 
    217                   zdist = ra * ACOS(  SIN( zrlat ) * SIN( zzrgphi )   & 
    218                      &              + COS( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) ) 
    219  
    220                  IF (zdist < zrout2) THEN ! calculation of wind only to a given max radius 
     210            DO_2D_11_11 
     211                                
     212               zzrglam = rad * glamt(ji,jj) - zrlon 
     213               zzrgphi = rad * gphit(ji,jj) 
     214               zdist = ra * ACOS(  SIN( zrlat ) * SIN( zzrgphi )   & 
     215                  &              + COS( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) ) 
     216 
     217              IF(zdist < zrout2) THEN ! calculation of wind only to a given max radius 
     218             
     219               ! shape of the wind profile                      
     220               IF(zdist <= zrmw) THEN     ! inside the Radius of Maximum Wind 
     221                  zztmp  = zvmax * (zdist/zrmw)**zn 
     222               ELSE  
     223                  zztmp  = zvmax * ( (1-zA) * EXP(- (zdist-zrmw)/zXX1 ) + zA * EXP(- (zdist-zrmw)/zXX2 ) ) 
     224               ENDIF 
     225 
     226               IF(zdist > zrout1) THEN ! bring to zero between r_out1 and r_out2 
     227                  zztmp = zztmp * ( (zrout2-zdist)*1.e-6 ) 
     228               ENDIF 
     229 
     230               ! !!! KILL EQ WINDS 
     231               ! IF(SIGN( 1. , zrlat ) /= zhemi) THEN 
     232               !    zztmp = 0.                              ! winds in other hemisphere 
     233               !    IF(ABS(gphit(ji,jj)) <= 5.) zztmp=0.   ! kill between 5N-5S 
     234               ! ENDIF 
     235               ! IF(ABS(gphit(ji,jj)) <= 10. .and. ABS(gphit(ji,jj)) > 5.) THEN 
     236               !    zztmp = zztmp * ( 1./5. * (ABS(gphit(ji,jj)) - 5.) )  
     237               !    !linear to zero between 10 and 5 
     238               ! ENDIF 
     239               ! !!! / KILL EQ 
     240 
     241               IF(ABS(gphit(ji,jj)) >= 55.) zztmp = 0. ! kill weak spurious winds at high latitude 
     242 
     243               zwnd_t =   COS( zinfl ) * zztmp     
     244               zwnd_r = - SIN( zinfl ) * zztmp 
     245 
     246               ! Project radial-tangential components on zonal-meridional components 
     247               ! ------------------------------------------------------------------- 
    221248                
    222                   ! shape of the wind profile                      
    223                   IF (zdist <= zrmw) THEN     ! inside the Radius of Maximum Wind 
    224                      zztmp  = zvmax * (zdist/zrmw)**zn 
    225                   ELSE  
    226                      zztmp  = zvmax * ( (1-zA) * EXP(- (zdist-zrmw)/zXX1 ) + zA * EXP(- (zdist-zrmw)/zXX2 ) ) 
    227                   ENDIF 
    228  
    229                   IF (zdist > zrout1) THEN ! bring to zero between r_out1 and r_out2 
    230                      zztmp = zztmp * ( (zrout2-zdist)*1.e-6 ) 
    231                   ENDIF 
    232  
    233                   ! !!! KILL EQ WINDS 
    234                   ! IF (SIGN( 1. , zrlat ) /= zhemi) THEN 
    235                   !    zztmp = 0.                              ! winds in other hemisphere 
    236                   !    IF (ABS(gphit(ji,jj)) <= 5.) zztmp=0.   ! kill between 5N-5S 
    237                   ! ENDIF 
    238                   ! IF (ABS(gphit(ji,jj)) <= 10. .and. ABS(gphit(ji,jj)) > 5.) THEN 
    239                   !    zztmp = zztmp * ( 1./5. * (ABS(gphit(ji,jj)) - 5.) )  
    240                   !    !linear to zero between 10 and 5 
    241                   ! ENDIF 
    242                   ! !!! / KILL EQ 
    243  
    244                   IF (ABS(gphit(ji,jj)) >= 55.) zztmp = 0. ! kill weak spurious winds at high latitude 
    245  
    246                   zwnd_t =   COS( zinfl ) * zztmp     
    247                   zwnd_r = - SIN( zinfl ) * zztmp 
    248  
    249                   ! Project radial-tangential components on zonal-meridional components 
    250                   ! ------------------------------------------------------------------- 
    251                    
    252                   ! ztheta = azimuthal angle of the great circle between two points 
    253                   zztmp = COS( zrlat ) * SIN( zzrgphi ) & 
    254                      &  - SIN( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) 
    255                   ztheta = ATAN2(        COS( zzrgphi ) * SIN( zzrglam ) , zztmp ) 
    256  
    257                   zwnd_x(ji,jj) = zwnd_x(ji,jj) - zhemi * COS(ztheta)*zwnd_t + SIN(ztheta)*zwnd_r 
    258                   zwnd_y(ji,jj) = zwnd_y(ji,jj) + zhemi * SIN(ztheta)*zwnd_t + COS(ztheta)*zwnd_r 
    259                    
    260                  ENDIF 
    261                END DO 
    262             END DO 
     249               ! ztheta = azimuthal angle of the great circle between two points 
     250               zztmp = COS( zrlat ) * SIN( zzrgphi ) & 
     251                  &  - SIN( zrlat ) * COS( zzrgphi ) * COS( zzrglam ) 
     252               ztheta = ATAN2(        COS( zzrgphi ) * SIN( zzrglam ) , zztmp ) 
     253 
     254               zwnd_x(ji,jj) = zwnd_x(ji,jj) - zhemi * COS(ztheta)*zwnd_t + SIN(ztheta)*zwnd_r 
     255               zwnd_y(ji,jj) = zwnd_y(ji,jj) + zhemi * SIN(ztheta)*zwnd_t + COS(ztheta)*zwnd_r 
     256                
     257              ENDIF 
     258            END_2D 
    263259         ENDIF                                         ! / vortex Holland or Wiloughby 
    264260         ENDIF                                           ! / cyclone is defined in this slot ? yes--> begin 
  • NEMO/trunk/src/OCE/SBC/fldread.F90

    r12367 r12377  
    1313   !!   fld_read      : read input fields used for the computation of the surface boundary condition 
    1414   !!   fld_init      : initialization of field read 
    15    !!   fld_rec       : determined the record(s) to be read 
     15   !!   fld_def       : define the record(s) of the file and its name 
    1616   !!   fld_get       : read the data 
    1717   !!   fld_map       : read global data from file and map onto local data using a general mapping (use for open boundaries) 
    1818   !!   fld_rot       : rotate the vector fields onto the local grid direction 
    19    !!   fld_clopn     : update the data file name and close/open the files 
     19   !!   fld_clopn     : close/open the files 
    2020   !!   fld_fill      : fill the data structure with the associated information read in namelist 
    2121   !!   wgt_list      : manage the weights used for interpolation 
     
    2525   !!   seaoverland   : create shifted matrices for seaoverland application 
    2626   !!   fld_interp    : apply weights to input gridded data to create data on model grid 
    27    !!   ksec_week     : function returning the first 3 letters of the first day of the weekly file 
     27   !!   fld_filename  : define the filename according to a given date 
     28   !!   ksec_week     : function returning seconds between 00h of the beginning of the week and half of the current time step 
    2829   !!---------------------------------------------------------------------- 
    2930   USE oce            ! ocean dynamics and tracers 
     
    4445   PUBLIC   fld_map    ! routine called by tides_init 
    4546   PUBLIC   fld_read, fld_fill   ! called by sbc... modules 
    46    PUBLIC   fld_clopn 
     47   PUBLIC   fld_def 
    4748 
    4849   TYPE, PUBLIC ::   FLD_N      !: Namelist field informations 
     
    7273      INTEGER , DIMENSION(2)          ::   nrec_b       ! before record (1: index, 2: second since Jan. 1st 00h of nit000 year) 
    7374      INTEGER , DIMENSION(2)          ::   nrec_a       ! after  record (1: index, 2: second since Jan. 1st 00h of nit000 year) 
    74       REAL(wp) , ALLOCATABLE, DIMENSION(:,:,:  ) ::   fnow   ! input fields interpolated to now time step 
    75       REAL(wp) , ALLOCATABLE, DIMENSION(:,:,:,:) ::   fdta   ! 2 consecutive record of input fields 
     75      INTEGER , ALLOCATABLE, DIMENSION(:      ) ::   nrecsec   !  
     76      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:  ) ::   fnow   ! input fields interpolated to now time step 
     77      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) ::   fdta   ! 2 consecutive record of input fields 
    7678      CHARACTER(len = 256)            ::   wgtname      ! current name of the NetCDF weight file acting as a key 
    7779      !                                                 ! into the WGTLIST structure 
     
    118120   TYPE( WGT ), DIMENSION(tot_wgts)   ::   ref_wgts     ! array of wgts 
    119121   INTEGER                            ::   nxt_wgt = 1  ! point to next available space in ref_wgts array 
     122   INTEGER                            ::   nflag = 0 
    120123   REAL(wp), PARAMETER                ::   undeff_lsm = -999.00_wp 
    121124 
    122125!$AGRIF_END_DO_NOT_TREAT 
    123126 
     127   !! * Substitutions 
     128#  include "do_loop_substitute.h90" 
    124129   !!---------------------------------------------------------------------- 
    125130   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    129134CONTAINS 
    130135 
    131    SUBROUTINE fld_read( kt, kn_fsbc, sd, kit, kt_offset ) 
     136   SUBROUTINE fld_read( kt, kn_fsbc, sd, kit, pt_offset, Kmm ) 
    132137      !!--------------------------------------------------------------------- 
    133138      !!                    ***  ROUTINE fld_read  *** 
     
    145150      TYPE(FLD), INTENT(inout), DIMENSION(:) ::   sd        ! input field related variables 
    146151      INTEGER  , INTENT(in   ), OPTIONAL     ::   kit       ! subcycle timestep for timesplitting option 
    147       INTEGER  , INTENT(in   ), OPTIONAL     ::   kt_offset ! provide fields at time other than "now" 
    148       !                                                     !   kt_offset = -1 => fields at "before" time level 
    149       !                                                     !   kt_offset = +1 => fields at "after"  time level 
    150       !                                                     !   etc. 
    151       !! 
    152       INTEGER  ::   itmp         ! local variable 
     152      REAL(wp) , INTENT(in   ), OPTIONAL     ::   pt_offset ! provide fields at time other than "now" 
     153      INTEGER  , INTENT(in   ), OPTIONAL     ::   Kmm       ! ocean time level index 
     154      !! 
    153155      INTEGER  ::   imf          ! size of the structure sd 
    154156      INTEGER  ::   jf           ! dummy indices 
    155       INTEGER  ::   isecend      ! number of second since Jan. 1st 00h of nit000 year at nitend 
    156157      INTEGER  ::   isecsbc      ! number of seconds between Jan. 1st 00h of nit000 year and the middle of sbc time step 
    157       INTEGER  ::   it_offset    ! local time offset variable 
    158       LOGICAL  ::   llnxtyr      ! open next year  file? 
    159       LOGICAL  ::   llnxtmth     ! open next month file? 
    160       LOGICAL  ::   llstop       ! stop is the file does not exist 
    161158      LOGICAL  ::   ll_firstcall ! true if this is the first call to fld_read for this set of fields 
     159      REAL(wp) ::   zt_offset    ! local time offset variable 
    162160      REAL(wp) ::   ztinta       ! ratio applied to after  records when doing time interpolation 
    163161      REAL(wp) ::   ztintb       ! ratio applied to before records when doing time interpolation 
     
    167165      IF( PRESENT(kit) )   ll_firstcall = ll_firstcall .and. kit == 1 
    168166 
    169       IF ( nn_components == jp_iam_sas ) THEN   ;   it_offset = nn_fsbc 
    170       ELSE                                      ;   it_offset = 0 
    171       ENDIF 
    172       IF( PRESENT(kt_offset) )   it_offset = kt_offset 
    173  
    174       ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar  
    175       IF( present(kit) ) THEN   ! ignore kn_fsbc in this case 
    176          isecsbc = nsec_year + nsec1jan000 + (kit+it_offset)*NINT( rdt/REAL(nn_baro,wp) ) 
     167      IF( nn_components == jp_iam_sas ) THEN   ;   zt_offset = REAL( nn_fsbc, wp ) 
     168      ELSE                                     ;   zt_offset = 0. 
     169      ENDIF 
     170      IF( PRESENT(pt_offset) )   zt_offset = pt_offset 
     171 
     172      ! Note that all varibles starting by nsec_* are shifted time by +1/2 time step to be centrered 
     173      IF( PRESENT(kit) ) THEN   ! ignore kn_fsbc in this case 
     174         isecsbc = nsec_year + nsec1jan000 + NINT( (     REAL(      kit,wp) + zt_offset ) * rdt / REAL(nn_baro,wp) ) 
    177175      ELSE                      ! middle of sbc time step 
    178          isecsbc = nsec_year + nsec1jan000 + NINT(0.5 * REAL(kn_fsbc - 1,wp) * rdt) + it_offset * NINT(rdt) 
     176         ! note: we use kn_fsbc-1 because nsec_year is defined at the middle of the current time step 
     177         isecsbc = nsec_year + nsec1jan000 + NINT( ( 0.5*REAL(kn_fsbc-1,wp) + zt_offset ) * rdt ) 
    179178      ENDIF 
    180179      imf = SIZE( sd ) 
     
    183182         DO jf = 1, imf  
    184183            IF( TRIM(sd(jf)%clrootname) == 'NOT USED' )   CYCLE 
    185             CALL fld_init( kn_fsbc, sd(jf) )       ! read each before field (put them in after as they will be swapped) 
     184            CALL fld_init( isecsbc, sd(jf) )       ! read each before field (put them in after as they will be swapped) 
    186185         END DO 
    187186         IF( lwp ) CALL wgt_print()                ! control print 
     
    192191         ! 
    193192         DO jf = 1, imf                            ! ---   loop over field   --- ! 
    194  
     193            ! 
    195194            IF( TRIM(sd(jf)%clrootname) == 'NOT USED' )   CYCLE 
    196                        
    197             IF( isecsbc > sd(jf)%nrec_a(2) .OR. ll_firstcall ) THEN    ! read/update the after data? 
    198  
    199                sd(jf)%nrec_b(:) = sd(jf)%nrec_a(:)                                  ! swap before record informations 
    200                sd(jf)%rotn(1) = sd(jf)%rotn(2)                                      ! swap before rotate informations 
    201                IF( sd(jf)%ln_tint )   sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2)   ! swap before record field 
    202  
    203                CALL fld_rec( kn_fsbc, sd(jf), kt_offset = it_offset, kit = kit )    ! update after record informations 
    204  
    205                ! if kn_fsbc*rdt is larger than freqh (which is kind of odd), 
    206                ! it is possible that the before value is no more the good one... we have to re-read it 
    207                ! if before is not the last record of the file currently opened and after is the first record to be read 
    208                ! in a new file which means after = 1 (the file to be opened corresponds to the current time) 
    209                ! or after = nreclast + 1 (the file to be opened corresponds to a future time step) 
    210                IF( .NOT. ll_firstcall .AND. sd(jf)%ln_tint .AND. sd(jf)%nrec_b(1) /= sd(jf)%nreclast & 
    211                   &                   .AND. MOD( sd(jf)%nrec_a(1), sd(jf)%nreclast ) == 1 ) THEN 
    212                   itmp = sd(jf)%nrec_a(1)                       ! temporary storage 
    213                   sd(jf)%nrec_a(1) = sd(jf)%nreclast            ! read the last record of the file currently opened 
    214                   CALL fld_get( sd(jf) )                        ! read after data 
    215                   sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2)   ! re-swap before record field 
    216                   sd(jf)%nrec_b(1) = sd(jf)%nrec_a(1)           ! update before record informations 
    217                   sd(jf)%nrec_b(2) = sd(jf)%nrec_a(2) - NINT( sd(jf)%freqh * 3600. )  ! assume freq to be in hours in this case 
    218                   sd(jf)%rotn(1)   = sd(jf)%rotn(2)             ! update before rotate informations 
    219                   sd(jf)%nrec_a(1) = itmp                       ! move back to after record  
    220                ENDIF 
    221  
    222                CALL fld_clopn( sd(jf) )   ! Do we need to open a new year/month/week/day file? 
    223                 
    224                IF( sd(jf)%ln_tint ) THEN 
    225                    
    226                   ! if kn_fsbc*rdt is larger than freqh (which is kind of odd), 
    227                   ! it is possible that the before value is no more the good one... we have to re-read it 
    228                   ! if before record is not just just before the after record... 
    229                   IF( .NOT. ll_firstcall .AND. MOD( sd(jf)%nrec_a(1), sd(jf)%nreclast ) /= 1 & 
    230                      &                   .AND. sd(jf)%nrec_b(1) /= sd(jf)%nrec_a(1) - 1 ) THEN    
    231                      sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) - 1       ! move back to before record 
    232                      CALL fld_get( sd(jf) )                        ! read after data 
    233                      sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2)   ! re-swap before record field 
    234                      sd(jf)%nrec_b(1) = sd(jf)%nrec_a(1)           ! update before record informations 
    235                      sd(jf)%nrec_b(2) = sd(jf)%nrec_a(2) - NINT( sd(jf)%freqh * 3600. )  ! assume freq to be in hours in this case 
    236                      sd(jf)%rotn(1)   = sd(jf)%rotn(2)             ! update before rotate informations 
    237                      sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) + 1       ! move back to after record 
    238                   ENDIF 
    239                ENDIF ! temporal interpolation? 
    240  
    241                ! do we have to change the year/month/week/day of the forcing field??  
    242                ! if we do time interpolation we will need to open next year/month/week/day file before the end of the current 
    243                ! one. If so, we are still before the end of the year/month/week/day when calling fld_rec so sd(jf)%nrec_a(1) 
    244                ! will be larger than the record number that should be read for current year/month/week/day 
    245                ! do we need next file data? 
    246                ! This applies to both cases with or without time interpolation 
    247                IF( sd(jf)%nrec_a(1) > sd(jf)%nreclast ) THEN 
    248                    
    249                   sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) - sd(jf)%nreclast   !  
    250                    
    251                   IF( .NOT. ( sd(jf)%ln_clim .AND. sd(jf)%cltype == 'yearly' ) ) THEN   ! close/open the current/new file 
    252                       
    253                      llnxtmth = sd(jf)%cltype == 'monthly' .OR. nday == nmonth_len(nmonth)      ! open next month file? 
    254                      llnxtyr  = sd(jf)%cltype == 'yearly'  .OR. (nmonth == 12 .AND. llnxtmth)   ! open next year  file? 
    255  
    256                      ! if the run finishes at the end of the current year/month/week/day, we will allow next 
    257                      ! year/month/week/day file to be not present. If the run continue further than the current 
    258                      ! year/month/week/day, next year/month/week/day file must exist 
    259                      isecend = nsec_year + nsec1jan000 + (nitend - kt) * NINT(rdt)   ! second at the end of the run 
    260                      llstop = isecend > sd(jf)%nrec_a(2)                             ! read more than 1 record of next year 
    261                      ! we suppose that the date of next file is next day (should be ok even for weekly files...) 
    262                      CALL fld_clopn( sd(jf), nyear  + COUNT((/llnxtyr /))                                           ,         & 
    263                         &                    nmonth + COUNT((/llnxtmth/)) - 12                 * COUNT((/llnxtyr /)),         & 
    264                         &                    nday   + 1                   - nmonth_len(nmonth) * COUNT((/llnxtmth/)), llstop ) 
    265  
    266                      IF( sd(jf)%num <= 0 .AND. .NOT. llstop ) THEN    ! next year file does not exist 
    267                         CALL ctl_warn('next year/month/week/day file: '//TRIM(sd(jf)%clname)//     & 
    268                            &     ' not present -> back to current year/month/day') 
    269                         CALL fld_clopn( sd(jf) )               ! back to the current year/month/day 
    270                         sd(jf)%nrec_a(1) = sd(jf)%nreclast     ! force to read the last record in the current year file 
    271                      ENDIF 
    272                       
    273                   ENDIF 
    274                ENDIF   ! open need next file? 
    275                    
    276                ! read after data 
    277                CALL fld_get( sd(jf) ) 
    278                 
    279             ENDIF   ! read new data? 
     195            CALL fld_update( isecsbc, sd(jf), Kmm ) 
     196            ! 
    280197         END DO                                    ! --- end loop over field --- ! 
    281198 
     
    292209                  WRITE(numout, clfmt)  TRIM( sd(jf)%clvar ), kt, REAL(isecsbc,wp)/rday, nyear, nmonth, nday,   &             
    293210                     & sd(jf)%nrec_b(1), sd(jf)%nrec_a(1), REAL(sd(jf)%nrec_b(2),wp)/rday, REAL(sd(jf)%nrec_a(2),wp)/rday 
    294                   WRITE(numout, *) '      it_offset is : ',it_offset 
     211                  WRITE(numout, *) '      zt_offset is : ',zt_offset 
    295212               ENDIF 
    296213               ! temporal interpolation weights 
     
    316233 
    317234 
    318    SUBROUTINE fld_init( kn_fsbc, sdjf ) 
     235   SUBROUTINE fld_init( ksecsbc, sdjf ) 
    319236      !!--------------------------------------------------------------------- 
    320237      !!                    ***  ROUTINE fld_init  *** 
    321238      !! 
    322       !! ** Purpose :  - first call to fld_rec to define before values 
    323       !!               - if time interpolation, read before data  
    324       !!---------------------------------------------------------------------- 
    325       INTEGER  , INTENT(in   ) ::   kn_fsbc      ! sbc computation period (in time step)  
     239      !! ** Purpose :  - first call(s) to fld_def to define before values 
     240      !!               - open file 
     241      !!---------------------------------------------------------------------- 
     242      INTEGER  , INTENT(in   ) ::   ksecsbc   !  
    326243      TYPE(FLD), INTENT(inout) ::   sdjf         ! input field related variables 
    327       !! 
    328       LOGICAL :: llprevyr              ! are we reading previous year  file? 
    329       LOGICAL :: llprevmth             ! are we reading previous month file? 
    330       LOGICAL :: llprevweek            ! are we reading previous week  file? 
    331       LOGICAL :: llprevday             ! are we reading previous day   file? 
    332       LOGICAL :: llprev                ! llprevyr .OR. llprevmth .OR. llprevweek .OR. llprevday 
    333       INTEGER :: idvar                 ! variable id  
    334       INTEGER :: inrec                 ! number of record existing for this variable 
    335       INTEGER :: iyear, imonth, iday   ! first day of the current file in yyyy mm dd 
    336       INTEGER :: isec_week             ! number of seconds since start of the weekly file 
    337       CHARACTER(LEN=1000) ::   clfmt   ! write format 
    338       !!--------------------------------------------------------------------- 
    339       ! 
    340       llprevyr   = .FALSE. 
    341       llprevmth  = .FALSE. 
    342       llprevweek = .FALSE. 
    343       llprevday  = .FALSE. 
    344       isec_week  = 0 
    345       ! 
    346       ! define record informations 
    347       CALL fld_rec( kn_fsbc, sdjf, ldbefore = .TRUE. )  ! return before values in sdjf%nrec_a (as we will swap it later) 
    348       ! 
    349       ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar  
    350       ! 
    351       IF( sdjf%ln_tint ) THEN ! we need to read the previous record and we will put it in the current record structure 
    352          ! 
    353          IF( sdjf%nrec_a(1) == 0  ) THEN   ! we redefine record sdjf%nrec_a(1) with the last record of previous year file 
    354             IF    ( NINT(sdjf%freqh) == -12 ) THEN   ! yearly mean 
    355                IF( sdjf%cltype == 'yearly' ) THEN             ! yearly file 
    356                   sdjf%nrec_a(1) = 1                                                       ! force to read the unique record 
    357                   llprevyr  = .NOT. sdjf%ln_clim                                           ! use previous year  file? 
    358                ELSE 
    359                   CALL ctl_stop( "fld_init: yearly mean file must be in a yearly type of file: "//TRIM(sdjf%clrootname) ) 
    360                ENDIF 
    361             ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN   ! monthly mean 
    362                IF( sdjf%cltype == 'monthly' ) THEN            ! monthly file 
    363                   sdjf%nrec_a(1) = 1                                                       ! force to read the unique record 
    364                   llprevmth = .TRUE.                                                       ! use previous month file? 
    365                   llprevyr  = llprevmth .AND. nmonth == 1                                  ! use previous year  file? 
    366                ELSE                                           ! yearly file 
    367                   sdjf%nrec_a(1) = 12                                                      ! force to read december mean 
    368                   llprevyr = .NOT. sdjf%ln_clim                                            ! use previous year  file? 
    369                ENDIF 
    370             ELSE                                     ! higher frequency mean (in hours)  
    371                IF    ( sdjf%cltype      == 'monthly' ) THEN   ! monthly file 
    372                   sdjf%nrec_a(1) = NINT( 24. * REAL(nmonth_len(nmonth-1),wp) / sdjf%freqh )! last record of previous month 
    373                   llprevmth = .TRUE.                                                       ! use previous month file? 
    374                   llprevyr  = llprevmth .AND. nmonth == 1                                  ! use previous year  file? 
    375                ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ! weekly file 
    376                   llprevweek = .TRUE.                                                      ! use previous week  file? 
    377                   sdjf%nrec_a(1) = NINT( 24. * 7. / sdjf%freqh )                           ! last record of previous week 
    378                   isec_week = NINT(rday) * 7                                               ! add a shift toward previous week 
    379                ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ! daily file 
    380                   sdjf%nrec_a(1) = NINT( 24. / sdjf%freqh )                                ! last record of previous day 
    381                   llprevday = .TRUE.                                                       ! use previous day   file? 
    382                   llprevmth = llprevday .AND. nday   == 1                                  ! use previous month file? 
    383                   llprevyr  = llprevmth .AND. nmonth == 1                                  ! use previous year  file? 
    384                ELSE                                           ! yearly file 
    385                   sdjf%nrec_a(1) = NINT( 24. * REAL(nyear_len(0),wp) / sdjf%freqh )        ! last record of previous year  
    386                   llprevyr = .NOT. sdjf%ln_clim                                            ! use previous year  file? 
    387                ENDIF 
    388             ENDIF 
    389          ENDIF 
    390          ! 
    391          IF ( sdjf%cltype(1:4) == 'week' ) THEN 
    392             isec_week = isec_week + ksec_week( sdjf%cltype(6:8) )   ! second since the beginning of the week 
    393             llprevmth = isec_week > nsec_month                      ! longer time since the beginning of the week than the month 
    394             llprevyr  = llprevmth .AND. nmonth == 1 
    395          ENDIF 
    396          llprev = llprevyr .OR. llprevmth .OR. llprevweek .OR. llprevday 
    397          ! 
    398          iyear  = nyear  - COUNT((/llprevyr /)) 
    399          imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /)) 
    400          iday   = nday   - COUNT((/llprevday/)) + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday) 
    401          ! 
    402          CALL fld_clopn( sdjf, iyear, imonth, iday, .NOT. llprev ) 
    403          ! 
    404          ! if previous year/month/day file does not exist, we switch to the current year/month/day 
    405          IF( llprev .AND. sdjf%num <= 0 ) THEN 
    406             CALL ctl_warn( 'previous year/month/week/day file: '//TRIM(sdjf%clrootname)//   & 
    407                &           ' not present -> back to current year/month/week/day' ) 
    408             ! we force to read the first record of the current year/month/day instead of last record of previous year/month/day 
    409             llprev = .FALSE. 
    410             sdjf%nrec_a(1) = 1 
    411             CALL fld_clopn( sdjf ) 
    412          ENDIF 
    413          ! 
    414          IF( llprev ) THEN   ! check if the record sdjf%nrec_a(1) exists in the file 
    415             idvar = iom_varid( sdjf%num, sdjf%clvar )                                        ! id of the variable sdjf%clvar 
    416             IF( idvar <= 0 )   RETURN 
    417             inrec = iom_file( sdjf%num )%dimsz( iom_file( sdjf%num )%ndims(idvar), idvar )   ! size of the last dim of idvar 
    418             sdjf%nrec_a(1) = MIN( sdjf%nrec_a(1), inrec )   ! make sure we select an existing record 
    419          ENDIF 
    420          ! 
    421          ! read before data in after arrays(as we will swap it later) 
    422          CALL fld_get( sdjf ) 
    423          ! 
    424          clfmt = "('   fld_init : time-interpolation for ', a, ' read previous record = ', i6, ' at time = ', f7.2, ' days')" 
    425          IF(lwp) WRITE(numout, clfmt) TRIM(sdjf%clvar), sdjf%nrec_a(1), REAL(sdjf%nrec_a(2),wp)/rday 
    426          ! 
    427       ENDIF 
     244      !!--------------------------------------------------------------------- 
     245      ! 
     246      IF( nflag == 0 )   nflag = -( HUGE(0) - 10 ) 
     247      ! 
     248      CALL fld_def( sdjf ) 
     249      IF( sdjf%ln_tint .AND. ksecsbc < sdjf%nrecsec(1) )   CALL fld_def( sdjf, ldprev = .TRUE. ) 
     250      ! 
     251      CALL fld_clopn( sdjf ) 
     252      sdjf%nrec_a(:) = (/ 1, nflag /)  ! default definition to force flp_update to read the file. 
    428253      ! 
    429254   END SUBROUTINE fld_init 
    430255 
    431256 
    432    SUBROUTINE fld_rec( kn_fsbc, sdjf, ldbefore, kit, kt_offset ) 
    433       !!--------------------------------------------------------------------- 
    434       !!                    ***  ROUTINE fld_rec  *** 
     257   SUBROUTINE fld_update( ksecsbc, sdjf, Kmm ) 
     258      !!--------------------------------------------------------------------- 
     259      !!                    ***  ROUTINE fld_update  *** 
    435260      !! 
    436261      !! ** Purpose : Compute 
     
    441266      !!                  nrec_b(2) and nrec_a(2): time of the beginning and end of the record 
    442267      !!---------------------------------------------------------------------- 
    443       INTEGER  , INTENT(in   )           ::   kn_fsbc   ! sbc computation period (in time step)  
    444       TYPE(FLD), INTENT(inout)           ::   sdjf      ! input field related variables 
    445       LOGICAL  , INTENT(in   ), OPTIONAL ::   ldbefore  ! sent back before record values (default = .FALSE.) 
    446       INTEGER  , INTENT(in   ), OPTIONAL ::   kit       ! index of barotropic subcycle 
    447       !                                                 ! used only if sdjf%ln_tint = .TRUE. 
    448       INTEGER  , INTENT(in   ), OPTIONAL ::   kt_offset ! Offset of required time level compared to "now" 
    449       !                                                 !   time level in units of time steps. 
    450       ! 
    451       LOGICAL  ::   llbefore    ! local definition of ldbefore 
    452       INTEGER  ::   iendrec     ! end of this record (in seconds) 
    453       INTEGER  ::   imth        ! month number 
    454       INTEGER  ::   ifreq_sec   ! frequency mean (in seconds) 
    455       INTEGER  ::   isec_week   ! number of seconds since the start of the weekly file 
    456       INTEGER  ::   it_offset   ! local time offset variable 
    457       REAL(wp) ::   ztmp        ! temporary variable 
    458       !!---------------------------------------------------------------------- 
    459       ! 
    460       ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar  
    461       ! 
    462       IF( PRESENT(ldbefore) ) THEN   ;   llbefore = ldbefore .AND. sdjf%ln_tint   ! needed only if sdjf%ln_tint = .TRUE. 
    463       ELSE                           ;   llbefore = .FALSE. 
    464       ENDIF 
    465       ! 
    466       IF ( nn_components == jp_iam_sas ) THEN   ;   it_offset = nn_fsbc 
    467       ELSE                                      ;   it_offset = 0 
    468       ENDIF 
    469       IF( PRESENT(kt_offset) )      it_offset = kt_offset 
    470       IF( PRESENT(kit) ) THEN   ;   it_offset = ( kit + it_offset ) * NINT( rdt/REAL(nn_baro,wp) ) 
    471       ELSE                      ;   it_offset =         it_offset   * NINT(       rdt            ) 
    472       ENDIF 
    473       ! 
    474       !                                           ! =========== ! 
    475       IF    ( NINT(sdjf%freqh) == -12 ) THEN      ! yearly mean 
    476          !                                        ! =========== ! 
    477          ! 
    478          IF( sdjf%ln_tint ) THEN                  ! time interpolation, shift by 1/2 record 
    479             ! 
    480             !                  INT( ztmp ) 
    481             !                     /|\ 
    482             !                    1 |    *---- 
    483             !                    0 |----(               
    484             !                      |----+----|--> time 
    485             !                      0   /|\   1   (nday/nyear_len(1)) 
    486             !                           |    
    487             !                           |    
    488             !       forcing record :    1  
    489             !                             
    490             ztmp =  REAL( nsec_year, wp ) / ( REAL( nyear_len(1), wp ) * rday ) + 0.5 & 
    491                &  + REAL( it_offset, wp ) / ( REAL( nyear_len(1), wp ) * rday ) 
    492             sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/)) 
    493             ! swap at the middle of the year 
    494             IF( llbefore ) THEN   ;   sdjf%nrec_a(2) = nsec1jan000 - (1 - INT(ztmp)) * NINT(0.5 * rday) * nyear_len(0) + & 
    495                                     & INT(ztmp) * NINT( 0.5 * rday) * nyear_len(1)  
    496             ELSE                  ;   sdjf%nrec_a(2) = nsec1jan000 + (1 - INT(ztmp)) * NINT(0.5 * rday) * nyear_len(1) + & 
    497                                     & INT(ztmp) * INT(rday) * nyear_len(1) + INT(ztmp) * NINT( 0.5 * rday) * nyear_len(2)  
     268      INTEGER  ,           INTENT(in   ) ::   ksecsbc   !  
     269      TYPE(FLD),           INTENT(inout) ::   sdjf      ! input field related variables 
     270      INTEGER  , OPTIONAL, INTENT(in   ) ::   Kmm    ! ocean time level index 
     271      ! 
     272      INTEGER  ::   ja     ! end of this record (in seconds) 
     273      !!---------------------------------------------------------------------- 
     274      ! 
     275      IF( ksecsbc > sdjf%nrec_a(2) ) THEN     ! --> we need to update after data 
     276         
     277         ! find where is the new after record... (it is not necessary sdjf%nrec_a(1)+1 ) 
     278         ja = sdjf%nrec_a(1) 
     279         DO WHILE ( ksecsbc >= sdjf%nrecsec(ja) .AND. ja < sdjf%nreclast )   ! Warning: make sure ja <= sdjf%nreclast in this test 
     280            ja = ja + 1 
     281         END DO 
     282         IF( ksecsbc > sdjf%nrecsec(ja) )   ja = ja + 1   ! in case ksecsbc > sdjf%nrecsec(sdjf%nreclast) 
     283 
     284         ! if ln_tint and if the new after is not ja+1, we need also to update after data before the swap 
     285         ! so, after the swap, sdjf%nrec_b(2) will still be the closest value located just before ksecsbc 
     286         IF( sdjf%ln_tint .AND. ( ja > sdjf%nrec_a(1) + 1 .OR. sdjf%nrec_a(2) == nflag ) ) THEN 
     287            sdjf%nrec_a(:) = (/ ja-1, sdjf%nrecsec(ja-1) /)   ! update nrec_a with before information 
     288            CALL fld_get( sdjf, Kmm )                         ! read after data that will be used as before data 
     289         ENDIF 
     290             
     291         ! if after is in the next file... 
     292         IF( ja > sdjf%nreclast ) THEN 
     293             
     294            CALL fld_def( sdjf ) 
     295            IF( ksecsbc > sdjf%nrecsec(sdjf%nreclast) )   CALL fld_def( sdjf, ldnext = .TRUE. ) 
     296            CALL fld_clopn( sdjf )           ! open next file 
     297             
     298            ! find where is after in this new file 
     299            ja = 1 
     300            DO WHILE ( ksecsbc > sdjf%nrecsec(ja) .AND. ja < sdjf%nreclast ) 
     301               ja = ja + 1 
     302            END DO 
     303            IF( ksecsbc > sdjf%nrecsec(ja) )   ja = ja + 1   ! in case ksecsbc > sdjf%nrecsec(sdjf%nreclast) 
     304             
     305            IF( ja > sdjf%nreclast ) THEN 
     306               CALL ctl_stop( "STOP", "fld_def: need next-next file? we should not be there... file: "//TRIM(sdjf%clrootname) ) 
    498307            ENDIF 
    499          ELSE                                     ! no time interpolation 
    500             sdjf%nrec_a(1) = 1 
    501             sdjf%nrec_a(2) = NINT(rday) * nyear_len(1) + nsec1jan000   ! swap at the end    of the year 
    502             sdjf%nrec_b(2) = nsec1jan000                               ! beginning of the year (only for print) 
    503          ENDIF 
    504          ! 
    505          !                                        ! ============ ! 
    506       ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN      ! monthly mean ! 
    507          !                                        ! ============ ! 
    508          ! 
    509          IF( sdjf%ln_tint ) THEN                  ! time interpolation, shift by 1/2 record 
    510             ! 
    511             !                  INT( ztmp ) 
    512             !                     /|\ 
    513             !                    1 |    *---- 
    514             !                    0 |----(               
    515             !                      |----+----|--> time 
    516             !                      0   /|\   1   (nday/nmonth_len(nmonth)) 
    517             !                           |    
    518             !                           |    
    519             !       forcing record :  nmonth  
    520             !                             
    521             ztmp =  REAL( nsec_month, wp ) / ( REAL( nmonth_len(nmonth), wp ) * rday ) + 0.5 & 
    522            &      + REAL(  it_offset, wp ) / ( REAL( nmonth_len(nmonth), wp ) * rday ) 
    523             imth = nmonth + INT( ztmp ) - COUNT((/llbefore/)) 
    524             IF( sdjf%cltype == 'monthly' ) THEN   ;   sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/)) 
    525             ELSE                                  ;   sdjf%nrec_a(1) = imth 
     308             
     309            ! if ln_tint and if after is not the first record, we must (potentially again) update after data before the swap 
     310            IF( sdjf%ln_tint .AND. ja > 1 ) THEN 
     311               IF( sdjf%nrecsec(0) /= nflag ) THEN                  ! no trick used: after file is not the current file 
     312                  sdjf%nrec_a(:) = (/ ja-1, sdjf%nrecsec(ja-1) /)   ! update nrec_a with before information 
     313                  CALL fld_get( sdjf, Kmm )                         ! read after data that will be used as before data 
     314               ENDIF 
    526315            ENDIF 
    527             sdjf%nrec_a(2) = nmonth_half(   imth ) + nsec1jan000   ! swap at the middle of the month 
    528          ELSE                                    ! no time interpolation 
    529             IF( sdjf%cltype == 'monthly' ) THEN   ;   sdjf%nrec_a(1) = 1 
    530             ELSE                                  ;   sdjf%nrec_a(1) = nmonth 
    531             ENDIF 
    532             sdjf%nrec_a(2) =  nmonth_end(nmonth  ) + nsec1jan000   ! swap at the end    of the month 
    533             sdjf%nrec_b(2) =  nmonth_end(nmonth-1) + nsec1jan000   ! beginning of the month (only for print) 
    534          ENDIF 
    535          ! 
    536          !                                        ! ================================ ! 
    537       ELSE                                        ! higher frequency mean (in hours) 
    538          !                                        ! ================================ ! 
    539          ! 
    540          ifreq_sec = NINT( sdjf%freqh * 3600. )                                         ! frequency mean (in seconds) 
    541          IF( sdjf%cltype(1:4) == 'week' )   isec_week = ksec_week( sdjf%cltype(6:8) )   ! since the first day of the current week 
    542          ! number of second since the beginning of the file 
    543          IF(     sdjf%cltype      == 'monthly' ) THEN   ;   ztmp = REAL(nsec_month,wp)  ! since the first day of the current month 
    544          ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   ztmp = REAL(isec_week ,wp)  ! since the first day of the current week 
    545          ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   ztmp = REAL(nsec_day  ,wp)  ! since 00h of the current day 
    546          ELSE                                           ;   ztmp = REAL(nsec_year ,wp)  ! since 00h on Jan 1 of the current year 
    547          ENDIF 
    548          ztmp = ztmp + 0.5 * REAL(kn_fsbc - 1, wp) * rdt + REAL( it_offset, wp )        ! centrered in the middle of sbc time step 
    549          ztmp = ztmp + 0.01 * rdt                                                       ! avoid truncation error  
    550          IF( sdjf%ln_tint ) THEN                 ! time interpolation, shift by 1/2 record 
    551             ! 
    552             !          INT( ztmp/ifreq_sec + 0.5 ) 
    553             !                     /|\ 
    554             !                    2 |        *-----( 
    555             !                    1 |  *-----( 
    556             !                    0 |--(               
    557             !                      |--+--|--+--|--+--|--> time 
    558             !                      0 /|\ 1 /|\ 2 /|\ 3    (ztmp/ifreq_sec) 
    559             !                         |     |     | 
    560             !                         |     |     | 
    561             !       forcing record :  1     2     3 
    562             !                    
    563             ztmp= ztmp / REAL(ifreq_sec, wp) + 0.5 
    564          ELSE                                    ! no time interpolation 
    565             ! 
    566             !           INT( ztmp/ifreq_sec ) 
    567             !                     /|\ 
    568             !                    2 |           *-----( 
    569             !                    1 |     *-----( 
    570             !                    0 |-----(               
    571             !                      |--+--|--+--|--+--|--> time 
    572             !                      0 /|\ 1 /|\ 2 /|\ 3    (ztmp/ifreq_sec) 
    573             !                         |     |     | 
    574             !                         |     |     | 
    575             !       forcing record :  1     2     3 
    576             !                             
    577             ztmp= ztmp / REAL(ifreq_sec, wp) 
    578          ENDIF 
    579          sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/))   ! record number to be read 
    580  
    581          iendrec = ifreq_sec * sdjf%nrec_a(1) + nsec1jan000       ! end of this record (in second) 
    582          ! add the number of seconds between 00h Jan 1 and the end of previous month/week/day (ok if nmonth=1) 
    583          IF( sdjf%cltype      == 'monthly' )   iendrec = iendrec + NINT(rday) * SUM(nmonth_len(1:nmonth -1)) 
    584          IF( sdjf%cltype(1:4) == 'week'    )   iendrec = iendrec + ( nsec_year - isec_week ) 
    585          IF( sdjf%cltype      == 'daily'   )   iendrec = iendrec + NINT(rday) * ( nday_year - 1 ) 
    586          IF( sdjf%ln_tint ) THEN 
    587              sdjf%nrec_a(2) = iendrec - ifreq_sec / 2        ! swap at the middle of the record 
     316             
     317         ENDIF 
     318 
     319         IF( sdjf%ln_tint ) THEN  
     320            ! Swap data 
     321            sdjf%nrec_b(:)     = sdjf%nrec_a(:)                     ! swap before record informations 
     322            sdjf%rotn(1)       = sdjf%rotn(2)                       ! swap before rotate informations 
     323            sdjf%fdta(:,:,:,1) = sdjf%fdta(:,:,:,2)                 ! swap before record field 
    588324         ELSE 
    589              sdjf%nrec_a(2) = iendrec                        ! swap at the end    of the record 
    590              sdjf%nrec_b(2) = iendrec - ifreq_sec            ! beginning of the record (only for print) 
    591          ENDIF 
    592          ! 
    593       ENDIF 
    594       ! 
    595       IF( .NOT. sdjf%ln_tint ) sdjf%nrec_a(2) = sdjf%nrec_a(2) - 1   ! last second belongs to bext record : *----( 
    596       ! 
    597    END SUBROUTINE fld_rec 
    598  
    599  
    600    SUBROUTINE fld_get( sdjf ) 
     325            sdjf%nrec_b(:) = (/ ja-1, sdjf%nrecsec(ja-1) /)         ! only for print  
     326         ENDIF 
     327             
     328         ! read new after data 
     329         sdjf%nrec_a(:) = (/ ja, sdjf%nrecsec(ja) /)                ! update nrec_a as it is used by fld_get 
     330         CALL fld_get( sdjf, Kmm )                                  ! read after data (with nrec_a informations) 
     331         
     332      ENDIF 
     333      ! 
     334   END SUBROUTINE fld_update 
     335 
     336 
     337   SUBROUTINE fld_get( sdjf, Kmm ) 
    601338      !!--------------------------------------------------------------------- 
    602339      !!                    ***  ROUTINE fld_get  *** 
     
    604341      !! ** Purpose :   read the data 
    605342      !!---------------------------------------------------------------------- 
    606       TYPE(FLD)        , INTENT(inout) ::   sdjf   ! input field related variables 
     343      TYPE(FLD),           INTENT(inout) ::   sdjf   ! input field related variables 
     344      INTEGER  , OPTIONAL, INTENT(in   ) ::   Kmm    ! ocean time level index 
    607345      ! 
    608346      INTEGER ::   ipk      ! number of vertical levels of sdjf%fdta ( 2D: ipk=1 ; 3D: ipk=jpk ) 
     
    618356      IF( ASSOCIATED(sdjf%imap) ) THEN 
    619357         IF( sdjf%ln_tint ) THEN   ;   CALL fld_map( sdjf%num, sdjf%clvar, sdjf%fdta(:,:,:,2), sdjf%nrec_a(1),   & 
    620             &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint ) 
     358            &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint, Kmm ) 
    621359         ELSE                      ;   CALL fld_map( sdjf%num, sdjf%clvar, sdjf%fnow(:,:,:  ), sdjf%nrec_a(1),   & 
    622             &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint ) 
     360            &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint, Kmm ) 
    623361         ENDIF 
    624362      ELSE IF( LEN(TRIM(sdjf%wgtname)) > 0 ) THEN 
     
    656394            ENDIF 
    657395         CASE DEFAULT 
    658             IF (lk_c1d .AND. lmoor ) THEN 
     396            IF(lk_c1d .AND. lmoor ) THEN 
    659397               IF( sdjf%ln_tint ) THEN 
    660398                  CALL iom_get( sdjf%num, jpdom_unknown, sdjf%clvar, sdjf%fdta(2,2,:,2), sdjf%nrec_a(1) ) 
     
    677415 
    678416    
    679    SUBROUTINE fld_map( knum, cdvar, pdta, krec, kmap, kgrd, kbdy, ldtotvel, ldzint ) 
     417   SUBROUTINE fld_map( knum, cdvar, pdta, krec, kmap, kgrd, kbdy, ldtotvel, ldzint, Kmm ) 
    680418      !!--------------------------------------------------------------------- 
    681419      !!                    ***  ROUTINE fld_map  *** 
     
    694432      LOGICAL, OPTIONAL         , INTENT(in   ) ::   ldtotvel     ! true if total ( = barotrop + barocline) velocity 
    695433      LOGICAL, OPTIONAL         , INTENT(in   ) ::   ldzint       ! true if 3D variable requires a vertical interpolation 
     434      INTEGER, OPTIONAL         , INTENT(in   ) ::   Kmm          ! ocean time level index  
    696435      !! 
    697436      INTEGER                                   ::   ipi          ! length of boundary data on local process 
     
    758497                
    759498               CALL iom_getatt(knum, '_FillValue', zfv, cdvar=cdvar ) 
    760                CALL fld_bdy_interp(zdta_read, zdta_read_z, zdta_read_dz, pdta, kgrd, kbdy, zfv, ldtotvel) 
     499               CALL fld_bdy_interp(zdta_read, zdta_read_z, zdta_read_dz, pdta, kgrd, kbdy, zfv, ldtotvel, Kmm) 
    761500               DEALLOCATE( zdta_read, zdta_read_z, zdta_read_dz ) 
    762501                
     
    822561   END SUBROUTINE fld_map_core 
    823562    
    824     
    825    SUBROUTINE fld_bdy_interp(pdta_read, pdta_read_z, pdta_read_dz, pdta, kgrd, kbdy, pfv, ldtotvel) 
     563   SUBROUTINE fld_bdy_interp(pdta_read, pdta_read_z, pdta_read_dz, pdta, kgrd, kbdy, pfv, ldtotvel, Kmm ) 
    826564      !!--------------------------------------------------------------------- 
    827565      !!                    ***  ROUTINE fld_bdy_interp  *** 
     
    840578      INTEGER                   , INTENT(in   ) ::   kgrd            ! grid type (t, u, v) 
    841579      INTEGER                   , INTENT(in   ) ::   kbdy            ! bdy number 
     580      INTEGER, OPTIONAL         , INTENT(in   ) ::   Kmm             ! ocean time level index 
    842581      !! 
    843582      INTEGER                  ::   ipi                 ! length of boundary data on local process 
     
    866605         SELECT CASE( kgrd )                          
    867606         CASE(1)            ! depth of T points: 
    868             zdepth(:) = gdept_n(ji,jj,:) 
     607            zdepth(:) = gdept(ji,jj,:,Kmm) 
    869608         CASE(2)            ! depth of U points: we must not use gdept_n as we don't want to do a communication 
    870609            !                 --> copy what is done for gdept_n in domvvl... 
    871610            zdhalf(1) = 0.0_wp 
    872             zdepth(1) = 0.5_wp * e3uw_n(ji,jj,1) 
     611            zdepth(1) = 0.5_wp * e3uw(ji,jj,1,Kmm) 
    873612            DO jk = 2, jpk                               ! vertical sum 
    874613               !    zcoef = umask - wumask    ! 0 everywhere tmask = wmask, ie everywhere expect at jk = mikt 
     
    877616               !!gm ???????   BUG ?  gdept_n as well as gde3w_n  does not include the thickness of ISF ?? 
    878617               zcoef = ( umask(ji,jj,jk) - wumask(ji,jj,jk) ) 
    879                zdhalf(jk) = zdhalf(jk-1) + e3u_n(ji,jj,jk-1) 
    880                zdepth(jk) =       zcoef  * ( zdhalf(jk  ) + 0.5 * e3uw_n(ji,jj,jk))  & 
    881                   &         + (1.-zcoef) * ( zdepth(jk-1) +       e3uw_n(ji,jj,jk)) 
     618               zdhalf(jk) = zdhalf(jk-1) + e3u(ji,jj,jk-1,Kmm) 
     619               zdepth(jk) =          zcoef  * ( zdhalf(jk  ) + 0.5_wp * e3uw(ji,jj,jk,Kmm))  & 
     620                  &         + (1._wp-zcoef) * ( zdepth(jk-1) +          e3uw(ji,jj,jk,Kmm)) 
    882621            END DO 
    883622         CASE(3)            ! depth of V points: we must not use gdept_n as we don't want to do a communication 
    884623            !                 --> copy what is done for gdept_n in domvvl... 
    885624            zdhalf(1) = 0.0_wp 
    886             zdepth(1) = 0.5_wp * e3vw_n(ji,jj,1) 
     625            zdepth(1) = 0.5_wp * e3vw(ji,jj,1,Kmm) 
    887626            DO jk = 2, jpk                               ! vertical sum 
    888627               !    zcoef = vmask - wvmask    ! 0 everywhere tmask = wmask, ie everywhere expect at jk = mikt 
     
    891630               !!gm ???????   BUG ?  gdept_n as well as gde3w_n  does not include the thickness of ISF ?? 
    892631               zcoef = ( vmask(ji,jj,jk) - wvmask(ji,jj,jk) ) 
    893                zdhalf(jk) = zdhalf(jk-1) + e3v_n(ji,jj,jk-1) 
    894                zdepth(jk) =       zcoef  * ( zdhalf(jk  ) + 0.5 * e3vw_n(ji,jj,jk))  & 
    895                   &         + (1.-zcoef) * ( zdepth(jk-1) +       e3vw_n(ji,jj,jk)) 
     632               zdhalf(jk) = zdhalf(jk-1) + e3v(ji,jj,jk-1,Kmm) 
     633               zdepth(jk) =          zcoef  * ( zdhalf(jk  ) + 0.5_wp * e3vw(ji,jj,jk,Kmm))  & 
     634                  &         + (1._wp-zcoef) * ( zdepth(jk-1) +          e3vw(ji,jj,jk,Kmm)) 
    896635            END DO 
    897636         END SELECT 
     
    911650               END DO 
    912651            ENDIF 
    913          END DO 
     652         END DO   ! jpk 
    914653         ! 
    915654      END DO   ! ipi 
     
    937676            ztrans_new = 0._wp 
    938677            DO jk = 1, jpk                                ! calculate transport on model grid 
    939                ztrans_new = ztrans_new + pdta(jb,1,jk ) * e3u_n(ji,jj,jk) * umask(ji,jj,jk) 
     678               ztrans_new = ztrans_new +      pdta(jb,1,jk ) * e3u(ji,jj,jk,Kmm ) * umask(ji,jj,jk) 
    940679            ENDDO 
    941680            DO jk = 1, jpk                                ! make transport correction 
    942681               IF(ldtotvel) THEN ! bdy data are total velocity so adjust bt transport term to match input data 
    943                   pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hu_n(ji,jj) ) * umask(ji,jj,jk) 
     682                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hu(ji,jj,Kmm) ) * umask(ji,jj,jk) 
    944683               ELSE              ! we're just dealing with bc velocity so bt transport term should sum to zero 
    945                   pdta(jb,1,jk) = ( pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hu_n(ji,jj) ) * umask(ji,jj,jk) 
     684                  pdta(jb,1,jk) =   pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hu(ji,jj,Kmm)  * umask(ji,jj,jk) 
    946685               ENDIF 
    947686            ENDDO 
     
    958697            ztrans_new = 0._wp 
    959698            DO jk = 1, jpk                                ! calculate transport on model grid 
    960                ztrans_new = ztrans_new + pdta(jb,1,jk ) * e3v_n(ji,jj,jk) * vmask(ji,jj,jk) 
     699               ztrans_new = ztrans_new +      pdta(jb,1,jk ) * e3v(ji,jj,jk,Kmm ) * vmask(ji,jj,jk) 
    961700            ENDDO 
    962701            DO jk = 1, jpk                                ! make transport correction 
    963702               IF(ldtotvel) THEN ! bdy data are total velocity so adjust bt transport term to match input data 
    964                   pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hv_n(ji,jj) ) * vmask(ji,jj,jk) 
     703                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hv(ji,jj,Kmm) ) * vmask(ji,jj,jk) 
    965704               ELSE              ! we're just dealing with bc velocity so bt transport term should sum to zero 
    966                   pdta(jb,1,jk) = ( pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hv_n(ji,jj) ) * vmask(ji,jj,jk) 
     705                  pdta(jb,1,jk) =   pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hv(ji,jj,Kmm)  * vmask(ji,jj,jk) 
    967706               ENDIF 
    968707            ENDDO 
    969708         ENDDO 
    970709      END SELECT 
    971  
     710       
    972711   END SUBROUTINE fld_bdy_interp 
    973712 
    974     
     713 
    975714   SUBROUTINE fld_rot( kt, sd ) 
    976715      !!--------------------------------------------------------------------- 
     
    1013752                           sd(ju)%fdta(:,:,jk,jn) = utmp(:,:)   ;   sd(iv)%fdta(:,:,jk,jn) = vtmp(:,:) 
    1014753                        ELSE  
    1015                            CALL rot_rep( sd(ju)%fnow(:,:,jk  ), sd(iv)%fnow(:,:,jk  ), 'T', 'en->i', utmp(:,:) ) 
    1016                            CALL rot_rep( sd(ju)%fnow(:,:,jk  ), sd(iv)%fnow(:,:,jk  ), 'T', 'en->j', vtmp(:,:) ) 
     754                           CALL rot_rep( sd(ju)%fnow(:,:,jk   ), sd(iv)%fnow(:,:,jk   ), 'T', 'en->i', utmp(:,:) ) 
     755                           CALL rot_rep( sd(ju)%fnow(:,:,jk   ), sd(iv)%fnow(:,:,jk   ), 'T', 'en->j', vtmp(:,:) ) 
    1017756                           sd(ju)%fnow(:,:,jk   ) = utmp(:,:)   ;   sd(iv)%fnow(:,:,jk   ) = vtmp(:,:) 
    1018757                        ENDIF 
     
    1030769 
    1031770 
    1032    SUBROUTINE fld_clopn( sdjf, kyear, kmonth, kday, ldstop ) 
     771   SUBROUTINE fld_def( sdjf, ldprev, ldnext ) 
     772      !!--------------------------------------------------------------------- 
     773      !!                    ***  ROUTINE fld_def  *** 
     774      !! 
     775      !! ** Purpose :   define the record(s) of the file and its name 
     776      !!---------------------------------------------------------------------- 
     777      TYPE(FLD)        , INTENT(inout) ::   sdjf       ! input field related variables 
     778      LOGICAL, OPTIONAL, INTENT(in   ) ::   ldprev     !  
     779      LOGICAL, OPTIONAL, INTENT(in   ) ::   ldnext     !  
     780      ! 
     781      INTEGER  :: jt 
     782      INTEGER  :: idaysec               ! number of seconds in 1 day = NINT(rday) 
     783      INTEGER  :: iyr, imt, idy, isecwk 
     784      INTEGER  :: indexyr, indexmt 
     785      INTEGER  :: ireclast 
     786      INTEGER  :: ishift, istart 
     787      INTEGER, DIMENSION(2)  :: isave 
     788      REAL(wp) :: zfreqs 
     789      LOGICAL  :: llprev, llnext, llstop 
     790      LOGICAL  :: llprevmt, llprevyr 
     791      LOGICAL  :: llnextmt, llnextyr 
     792      !!---------------------------------------------------------------------- 
     793      idaysec = NINT(rday) 
     794      ! 
     795      IF( PRESENT(ldprev) ) THEN   ;   llprev = ldprev 
     796      ELSE                         ;   llprev = .FALSE. 
     797      ENDIF 
     798      IF( PRESENT(ldnext) ) THEN   ;   llnext = ldnext 
     799      ELSE                         ;   llnext = .FALSE. 
     800      ENDIF 
     801 
     802      ! current file parameters 
     803      IF( sdjf%cltype(1:4) == 'week' ) THEN          ! find the day of the beginning of the current week 
     804         isecwk = ksec_week( sdjf%cltype(6:8) )     ! seconds between the beginning of the week and half of current time step 
     805         llprevmt = isecwk > nsec_month               ! longer time since beginning of the current week than the current month 
     806         llprevyr = llprevmt .AND. nmonth == 1 
     807         iyr = nyear  - COUNT((/llprevyr/)) 
     808         imt = nmonth - COUNT((/llprevmt/)) + 12 * COUNT((/llprevyr/)) 
     809         idy = nday + nmonth_len(nmonth-1) * COUNT((/llprevmt/)) - isecwk / idaysec 
     810         isecwk = nsec_year - isecwk              ! seconds between 00h jan 1st of current year and current week beginning 
     811      ELSE 
     812         iyr = nyear 
     813         imt = nmonth 
     814         idy = nday 
     815         isecwk  = 0 
     816      ENDIF 
     817 
     818      ! previous file parameters 
     819      IF( llprev ) THEN 
     820         IF( sdjf%cltype(1:4) == 'week'    ) THEN     ! find the day of the beginning of previous week 
     821            isecwk = isecwk + 7 * idaysec         ! seconds between the beginning of previous week and half of the time step 
     822            llprevmt = isecwk > nsec_month            ! longer time since beginning of the previous week than the current month 
     823            llprevyr = llprevmt .AND. nmonth == 1 
     824            iyr = nyear  - COUNT((/llprevyr/)) 
     825            imt = nmonth - COUNT((/llprevmt/)) + 12 * COUNT((/llprevyr/)) 
     826            idy = nday + nmonth_len(nmonth-1) * COUNT((/llprevmt/)) - isecwk / idaysec 
     827            isecwk = nsec_year - isecwk           ! seconds between 00h jan 1st of current year and previous week beginning 
     828         ELSE 
     829            idy = nday   - COUNT((/ sdjf%cltype == 'daily'                 /)) 
     830            imt = nmonth - COUNT((/ sdjf%cltype == 'monthly' .OR. idy == 0 /)) 
     831            iyr = nyear  - COUNT((/ sdjf%cltype == 'yearly'  .OR. imt == 0 /)) 
     832            IF( idy == 0 ) idy = nmonth_len(imt) 
     833            IF( imt == 0 ) imt = 12 
     834            isecwk = 0 
     835         ENDIF 
     836      ENDIF 
     837 
     838      ! next file parameters 
     839      IF( llnext ) THEN 
     840         IF( sdjf%cltype(1:4) == 'week'    ) THEN     ! find the day of the beginning of next week 
     841            isecwk = 7 * idaysec - isecwk         ! seconds between half of the time step and the beginning of next week 
     842            llnextmt = isecwk > ( nmonth_len(nmonth)*idaysec - nsec_month )   ! larger than the seconds to the end of the month 
     843            llnextyr = llnextmt .AND. nmonth == 12 
     844            iyr = nyear  + COUNT((/llnextyr/)) 
     845            imt = nmonth + COUNT((/llnextmt/)) - 12 * COUNT((/llnextyr/)) 
     846            idy = nday - nmonth_len(nmonth) * COUNT((/llnextmt/)) + isecwk / idaysec + 1 
     847            isecwk = nsec_year + isecwk           ! seconds between 00h jan 1st of current year and next week beginning 
     848         ELSE 
     849            idy = nday   + COUNT((/ sdjf%cltype == 'daily'                                 /)) 
     850            imt = nmonth + COUNT((/ sdjf%cltype == 'monthly' .OR. idy > nmonth_len(nmonth) /)) 
     851            iyr = nyear  + COUNT((/ sdjf%cltype == 'yearly'  .OR. imt == 13                /)) 
     852            IF( idy > nmonth_len(nmonth) )   idy = 1 
     853            IF( imt == 13                )   imt = 1 
     854            isecwk = 0 
     855         ENDIF 
     856      ENDIF 
     857      ! 
     858      ! find the last record to be read -> update sdjf%nreclast 
     859      indexyr = iyr - nyear + 1                 ! which  year are we looking for? previous(0), current(1) or next(2)? 
     860      indexmt = imt + 12 * ( indexyr - 1 )      ! which month are we looking for (relatively to current year)?  
     861      ! 
     862      ! Last record to be read in the current file 
     863      ! Predefine the number of record in the file according of its type. 
     864      ! We could compare this number with the number of records in the file and make a stop if the 2 numbers do not match... 
     865      ! However this would be much less fexible (e.g. for tests) and will force to rewite input files according to nleapy... 
     866      IF    ( NINT(sdjf%freqh) == -12 ) THEN            ;   ireclast = 1    ! yearly mean: consider only 1 record 
     867      ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN                                ! monthly mean: 
     868         IF(     sdjf%cltype      == 'monthly' ) THEN   ;   ireclast = 1    !  consider that the file has  1 record 
     869         ELSE                                           ;   ireclast = 12   !  consider that the file has 12 record 
     870         ENDIF 
     871      ELSE                                                                  ! higher frequency mean (in hours) 
     872         IF(     sdjf%cltype      == 'monthly' ) THEN   ;   ireclast = NINT( 24. * REAL(nmonth_len(indexmt), wp) / sdjf%freqh ) 
     873         ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   ireclast = NINT( 24. * 7.                            / sdjf%freqh ) 
     874         ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   ireclast = NINT( 24.                                 / sdjf%freqh ) 
     875         ELSE                                           ;   ireclast = NINT( 24. * REAL( nyear_len(indexyr), wp) / sdjf%freqh ) 
     876         ENDIF 
     877      ENDIF 
     878 
     879      sdjf%nreclast = ireclast 
     880      ! Allocate arrays for beginning/middle/end of each record (seconds since Jan. 1st 00h of nit000 year) 
     881      IF( ALLOCATED(sdjf%nrecsec) )   DEALLOCATE( sdjf%nrecsec ) 
     882      ALLOCATE( sdjf%nrecsec( 0:ireclast ) ) 
     883      ! 
     884      IF    ( NINT(sdjf%freqh) == -12 ) THEN                                     ! yearly mean and yearly file 
     885         SELECT CASE( indexyr ) 
     886         CASE(0)   ;   sdjf%nrecsec(0) = nsec1jan000 - nyear_len( 0 ) * idaysec 
     887         CASE(1)   ;   sdjf%nrecsec(0) = nsec1jan000 
     888         CASE(2)   ;   sdjf%nrecsec(0) = nsec1jan000 + nyear_len( 1 ) * idaysec 
     889         ENDSELECT 
     890         sdjf%nrecsec(1) = sdjf%nrecsec(0) + nyear_len( indexyr ) * idaysec 
     891      ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN                                     ! monthly mean: 
     892         IF(     sdjf%cltype      == 'monthly' ) THEN                            !    monthly file 
     893            sdjf%nrecsec(0   ) = nsec1jan000 + nmonth_beg(indexmt  ) 
     894            sdjf%nrecsec(1   ) = nsec1jan000 + nmonth_beg(indexmt+1) 
     895         ELSE                                                                    !    yearly  file 
     896            ishift = 12 * ( indexyr - 1 ) 
     897            sdjf%nrecsec(0:12) = nsec1jan000 + nmonth_beg(1+ishift:13+ishift) 
     898         ENDIF 
     899      ELSE                                                                       ! higher frequency mean (in hours) 
     900         IF(     sdjf%cltype      == 'monthly' ) THEN   ;   istart = nsec1jan000 + nmonth_beg(indexmt) 
     901         ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   istart = nsec1jan000 + isecwk 
     902         ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   istart = nsec1jan000 + nmonth_beg(indexmt) + ( idy - 1 ) * idaysec 
     903         ELSEIF( indexyr          == 0         ) THEN   ;   istart = nsec1jan000 - nyear_len( 0 ) * idaysec 
     904         ELSEIF( indexyr          == 2         ) THEN   ;   istart = nsec1jan000 + nyear_len( 1 ) * idaysec 
     905         ELSE                                           ;   istart = nsec1jan000 
     906         ENDIF 
     907         zfreqs = sdjf%freqh * rhhmm * rmmss 
     908         DO jt = 0, sdjf%nreclast 
     909            sdjf%nrecsec(jt) = istart + NINT( zfreqs * REAL(jt,wp) ) 
     910         END DO 
     911      ENDIF 
     912      ! 
     913      IF( sdjf%ln_tint ) THEN   ! record time defined in the middle of the record, computed using an implementation 
     914                                ! of the rounded average that is valid over the full integer range 
     915         sdjf%nrecsec(1:sdjf%nreclast) = sdjf%nrecsec(0:sdjf%nreclast-1) / 2 + sdjf%nrecsec(1:sdjf%nreclast) / 2 + & 
     916            & MAX( MOD( sdjf%nrecsec(0:sdjf%nreclast-1), 2 ), MOD( sdjf%nrecsec(1:sdjf%nreclast), 2 ) ) 
     917      END IF 
     918      ! 
     919      sdjf%clname = fld_filename( sdjf, idy, imt, iyr ) 
     920      ! 
     921   END SUBROUTINE fld_def 
     922 
     923    
     924   SUBROUTINE fld_clopn( sdjf ) 
    1033925      !!--------------------------------------------------------------------- 
    1034926      !!                    ***  ROUTINE fld_clopn  *** 
    1035927      !! 
    1036       !! ** Purpose :   update the file name and close/open the files 
    1037       !!---------------------------------------------------------------------- 
    1038       TYPE(FLD)        , INTENT(inout) ::   sdjf     ! input field related variables 
    1039       INTEGER, OPTIONAL, INTENT(in   ) ::   kyear    ! year value 
    1040       INTEGER, OPTIONAL, INTENT(in   ) ::   kmonth   ! month value 
    1041       INTEGER, OPTIONAL, INTENT(in   ) ::   kday     ! day value 
    1042       LOGICAL, OPTIONAL, INTENT(in   ) ::   ldstop   ! stop if open to read a non-existing file (default = .TRUE.) 
    1043       ! 
    1044       LOGICAL  :: llprevyr              ! are we reading previous year  file? 
    1045       LOGICAL  :: llprevmth             ! are we reading previous month file? 
    1046       INTEGER  :: iyear, imonth, iday   ! first day of the current file in yyyy mm dd 
    1047       INTEGER  :: isec_week             ! number of seconds since start of the weekly file 
    1048       INTEGER  :: indexyr               ! year undex (O/1/2: previous/current/next) 
    1049       REAL(wp) :: zyear_len, zmonth_len ! length (days) of iyear and imonth             !  
    1050       CHARACTER(len = 256) ::   clname  ! temporary file name 
    1051       !!---------------------------------------------------------------------- 
    1052       IF( PRESENT(kyear) ) THEN                             ! use given values  
    1053          iyear = kyear 
    1054          imonth = kmonth 
    1055          iday = kday 
    1056          IF ( sdjf%cltype(1:4) == 'week' ) THEN             ! find the day of the beginning of the week 
    1057             isec_week = ksec_week( sdjf%cltype(6:8) )- (86400 * 8 )   
    1058             llprevmth  = isec_week > nsec_month             ! longer time since beginning of the week than the month 
    1059             llprevyr   = llprevmth .AND. nmonth == 1 
    1060             iyear  = nyear  - COUNT((/llprevyr /)) 
    1061             imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /)) 
    1062             iday   = nday   + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday) 
    1063          ENDIF 
    1064       ELSE                                                  ! use current day values 
    1065          IF ( sdjf%cltype(1:4) == 'week' ) THEN             ! find the day of the beginning of the week 
    1066             isec_week  = ksec_week( sdjf%cltype(6:8) )      ! second since the beginning of the week 
    1067             llprevmth  = isec_week > nsec_month             ! longer time since beginning of the week than the month 
    1068             llprevyr   = llprevmth .AND. nmonth == 1 
    1069          ELSE 
    1070             isec_week  = 0 
    1071             llprevmth  = .FALSE. 
    1072             llprevyr   = .FALSE. 
    1073          ENDIF 
    1074          iyear  = nyear  - COUNT((/llprevyr /)) 
    1075          imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /)) 
    1076          iday   = nday   + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday) 
    1077       ENDIF 
    1078  
    1079       ! build the new filename if not climatological data 
    1080       clname=TRIM(sdjf%clrootname) 
    1081       ! 
    1082       ! note that sdjf%ln_clim is is only acting on the presence of the year in the file name 
    1083       IF( .NOT. sdjf%ln_clim ) THEN    
    1084                                          WRITE(clname, '(a,"_y",i4.4)' ) TRIM( sdjf%clrootname ), iyear    ! add year 
    1085          IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a,"m" ,i2.2)' ) TRIM( clname          ), imonth   ! add month 
    1086       ELSE 
    1087          ! build the new filename if climatological data 
    1088          IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a,"_m",i2.2)' ) TRIM( sdjf%clrootname ), imonth   ! add month 
    1089       ENDIF 
    1090       IF( sdjf%cltype == 'daily' .OR. sdjf%cltype(1:4) == 'week' ) & 
    1091             &                            WRITE(clname, '(a,"d" ,i2.2)' ) TRIM( clname          ), iday     ! add day 
    1092       ! 
    1093       IF( TRIM(clname) /= TRIM(sdjf%clname) .OR. sdjf%num == 0 ) THEN   ! new file to be open  
    1094          ! 
    1095          sdjf%clname = TRIM(clname) 
    1096          IF( sdjf%num /= 0 )   CALL iom_close( sdjf%num )   ! close file if already open 
    1097          CALL iom_open( sdjf%clname, sdjf%num, ldstop = ldstop, ldiof =  LEN(TRIM(sdjf%wgtname)) > 0 ) 
    1098          ! 
    1099          ! find the last record to be read -> update sdjf%nreclast 
    1100          indexyr = iyear - nyear + 1 
    1101          zyear_len = REAL(nyear_len( indexyr ), wp) 
    1102          SELECT CASE ( indexyr ) 
    1103          CASE ( 0 )   ;   zmonth_len = 31.   ! previous year -> imonth = 12 
    1104          CASE ( 1 )   ;   zmonth_len = REAL(nmonth_len(imonth), wp) 
    1105          CASE ( 2 )   ;   zmonth_len = 31.   ! next     year -> imonth = 1 
    1106          END SELECT 
    1107          ! 
    1108          ! last record to be read in the current file 
    1109          IF    ( sdjf%freqh == -12. ) THEN                 ;   sdjf%nreclast = 1    !  yearly mean 
    1110          ELSEIF( sdjf%freqh ==  -1. ) THEN                                          ! monthly mean 
    1111             IF(     sdjf%cltype      == 'monthly' ) THEN   ;   sdjf%nreclast = 1 
    1112             ELSE                                           ;   sdjf%nreclast = 12 
    1113             ENDIF 
    1114          ELSE                                                                       ! higher frequency mean (in hours) 
    1115             IF(     sdjf%cltype      == 'monthly' ) THEN   ;   sdjf%nreclast = NINT( 24. * zmonth_len / sdjf%freqh ) 
    1116             ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   sdjf%nreclast = NINT( 24. * 7.         / sdjf%freqh ) 
    1117             ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   sdjf%nreclast = NINT( 24.              / sdjf%freqh ) 
    1118             ELSE                                           ;   sdjf%nreclast = NINT( 24. * zyear_len  / sdjf%freqh ) 
    1119             ENDIF 
    1120          ENDIF 
     928      !! ** Purpose :   close/open the files 
     929      !!---------------------------------------------------------------------- 
     930      TYPE(FLD)        , INTENT(inout) ::   sdjf       ! input field related variables 
     931      ! 
     932      INTEGER, DIMENSION(2)  :: isave 
     933      LOGICAL  :: llprev, llnext, llstop 
     934      !!---------------------------------------------------------------------- 
     935      ! 
     936      llprev = sdjf%nrecsec(sdjf%nreclast) < nsec000_1jan000   ! file ends before the beginning of the job -> file may not exist 
     937      llnext = sdjf%nrecsec(       0     ) > nsecend_1jan000   ! file begins after the end of the job -> file may not exist  
     938 
     939      llstop = sdjf%ln_clim .OR. .NOT. ( llprev .OR. llnext ) 
     940 
     941      IF( sdjf%num <= 0 .OR. .NOT. sdjf%ln_clim  ) THEN 
     942         IF( sdjf%num > 0 )   CALL iom_close( sdjf%num )   ! close file if already open 
     943         CALL iom_open( sdjf%clname, sdjf%num, ldstop = llstop, ldiof = LEN(TRIM(sdjf%wgtname)) > 0 ) 
     944      ENDIF 
     945      ! 
     946      IF( sdjf%num <= 0 .AND. .NOT. llstop ) THEN   ! file not found but we do accept this... 
     947         ! 
     948         IF( llprev ) THEN   ! previous file does not exist : go back to current and accept to read only the first record 
     949            CALL ctl_warn('previous file: '//TRIM(sdjf%clname)//' not found -> go back to current year/month/week/day file') 
     950            isave(1:2) = sdjf%nrecsec(sdjf%nreclast-1:sdjf%nreclast)   ! save previous file info 
     951            CALL fld_def( sdjf )   ! go back to current file 
     952            sdjf%nreclast = 1   ! force to use only the first record (do as if other were not existing...) 
     953            sdjf%nrecsec(0:1) = isave(1:2) 
     954         ENDIF 
     955         ! 
     956         IF( llnext ) THEN   ! next     file does not exist : go back to current and accept to read only the last  record  
     957            CALL ctl_warn('next file: '//TRIM(sdjf%clname)//' not found -> go back to current year/month/week/day file') 
     958            isave(1:2) = sdjf%nrecsec(0:1)    ! save next file info 
     959            CALL fld_def( sdjf )   ! go back to current file 
     960            ! -> read last record but keep record info from the first record of next file 
     961            sdjf%nrecsec(sdjf%nreclast-1:sdjf%nreclast) = isave(1:2) 
     962            sdjf%nrecsec(0:sdjf%nreclast-2) = nflag 
     963         ENDIF 
     964         ! 
     965         CALL iom_open( sdjf%clname, sdjf%num, ldiof = LEN(TRIM(sdjf%wgtname)) > 0 )    
    1121966         ! 
    1122967      ENDIF 
     
    13001145      CALL iom_open( sd%clname, inum, ldiof =  LEN(TRIM(sd%wgtname)) > 0 ) 
    13011146 
    1302       !! get dimensions 
    1303       IF ( SIZE(sd%fnow, 3) > 1 ) THEN 
     1147      !! get dimensions: we consider 2D data as 3D data with vertical dim size = 1 
     1148      IF( SIZE(sd%fnow, 3) > 0 ) THEN 
    13041149         ALLOCATE( ddims(4) ) 
    13051150      ELSE 
     
    13141159 
    13151160      CALL iom_open ( sd%wgtname, inum )   ! interpolation weights 
    1316       IF ( inum > 0 ) THEN 
     1161      IF( inum > 0 ) THEN 
    13171162 
    13181163         !! determine whether we have an east-west cyclic grid 
     
    16231468          
    16241469         ref_wgts(kw)%fly_dta(:,:,:) = 0.0 
    1625          SELECT CASE( SIZE(ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:),3) ) 
    1626          CASE(1) 
    1627               CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,1), nrec, rec1, recn) 
    1628          CASE DEFAULT 
    1629               CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:), nrec, rec1, recn) 
    1630          END SELECT  
     1470         CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:), nrec, rec1, recn) 
    16311471      ENDIF 
    16321472       
     
    16461486      END DO 
    16471487 
    1648       IF (ref_wgts(kw)%numwgt .EQ. 16) THEN 
     1488      IF(ref_wgts(kw)%numwgt .EQ. 16) THEN 
    16491489 
    16501490        !! fix up halo points that we couldnt read from file 
     
    16721512           IF( jpi1 == 2 ) THEN 
    16731513              rec1(1) = ref_wgts(kw)%ddims(1) - ref_wgts(kw)%overlap 
    1674               SELECT CASE( SIZE( ref_wgts(kw)%col(:,jpj1:jpj2,:),3) ) 
    1675               CASE(1) 
    1676                    CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,1), nrec, rec1, recn) 
    1677               CASE DEFAULT 
    1678                    CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn) 
    1679               END SELECT       
     1514              CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn) 
    16801515              ref_wgts(kw)%fly_dta(jpi1-1,jpj1:jpj2,:) = ref_wgts(kw)%col(1,jpj1:jpj2,:) 
    16811516           ENDIF 
    16821517           IF( jpi2 + jpimin - 1 == ref_wgts(kw)%ddims(1)+1 ) THEN 
    16831518              rec1(1) = 1 + ref_wgts(kw)%overlap 
    1684               SELECT CASE( SIZE( ref_wgts(kw)%col(:,jpj1:jpj2,:),3) ) 
    1685               CASE(1) 
    1686                    CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,1), nrec, rec1, recn) 
    1687               CASE DEFAULT 
    1688                    CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn) 
    1689               END SELECT 
     1519              CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn) 
    16901520              ref_wgts(kw)%fly_dta(jpi2+1,jpj1:jpj2,:) = ref_wgts(kw)%col(1,jpj1:jpj2,:) 
    16911521           ENDIF 
     
    17291559         END DO 
    17301560         ! 
    1731       END IF 
     1561      ENDIF 
    17321562      ! 
    17331563   END SUBROUTINE fld_interp 
    17341564 
    17351565 
     1566   FUNCTION fld_filename( sdjf, kday, kmonth, kyear ) 
     1567      !!--------------------------------------------------------------------- 
     1568      !!                    ***  FUNCTION fld_filename ***  
     1569      !! 
     1570      !! ** Purpose :   define the filename according to a given date 
     1571      !!--------------------------------------------------------------------- 
     1572      TYPE(FLD), INTENT(in) ::   sdjf         ! input field related variables 
     1573      INTEGER  , INTENT(in) ::   kday, kmonth, kyear 
     1574      ! 
     1575      CHARACTER(len = 256) ::   clname, fld_filename 
     1576      !!--------------------------------------------------------------------- 
     1577 
     1578       
     1579      ! build the new filename if not climatological data 
     1580      clname=TRIM(sdjf%clrootname) 
     1581      ! 
     1582      ! note that sdjf%ln_clim is is only acting on the presence of the year in the file name 
     1583      IF( .NOT. sdjf%ln_clim ) THEN    
     1584                                         WRITE(clname, '(a,"_y",i4.4)' ) TRIM( sdjf%clrootname ), kyear    ! add year 
     1585         IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a, "m",i2.2)' ) TRIM( clname          ), kmonth   ! add month 
     1586      ELSE 
     1587         ! build the new filename if climatological data 
     1588         IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a,"_m",i2.2)' ) TRIM( sdjf%clrootname ), kmonth   ! add month 
     1589      ENDIF 
     1590      IF(    sdjf%cltype == 'daily' .OR. sdjf%cltype(1:4) == 'week' ) & 
     1591         &                               WRITE(clname, '(a,"d" ,i2.2)' ) TRIM( clname          ), kday     ! add day 
     1592 
     1593      fld_filename = clname 
     1594       
     1595   END FUNCTION fld_filename 
     1596 
     1597 
    17361598   FUNCTION ksec_week( cdday ) 
    17371599      !!--------------------------------------------------------------------- 
    1738       !!                    ***  FUNCTION kshift_week ***  
    1739       !! 
    1740       !! ** Purpose :   return the first 3 letters of the first day of the weekly file 
     1600      !!                    ***  FUNCTION ksec_week ***  
     1601      !! 
     1602      !! ** Purpose :   seconds between 00h of the beginning of the week and half of the current time step 
    17411603      !!--------------------------------------------------------------------- 
    17421604      CHARACTER(len=*), INTENT(in)   ::   cdday   ! first 3 letters of the first day of the weekly file 
     
    17541616      ishift = ijul * NINT(rday) 
    17551617      !  
    1756       ksec_week = nsec_week + ishift 
     1618      ksec_week = nsec_monday + ishift 
    17571619      ksec_week = MOD( ksec_week, 7*NINT(rday) ) 
    17581620      !  
  • NEMO/trunk/src/OCE/SBC/geo2ocean.F90

    r10425 r12377  
    4343 
    4444   !! * Substitutions 
    45 #  include "vectopt_loop_substitute.h90" 
     45#  include "do_loop_substitute.h90" 
    4646   !!---------------------------------------------------------------------- 
    4747   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    160160      ! (computation done on the north stereographic polar plane) 
    161161      ! 
    162       DO jj = 2, jpjm1 
    163          DO ji = fs_2, jpi   ! vector opt. 
    164             !                   
    165             zlam = plamt(ji,jj)     ! north pole direction & modulous (at t-point) 
    166             zphi = pphit(ji,jj) 
    167             zxnpt = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    168             zynpt = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    169             znnpt = zxnpt*zxnpt + zynpt*zynpt 
    170             ! 
    171             zlam = plamu(ji,jj)     ! north pole direction & modulous (at u-point) 
    172             zphi = pphiu(ji,jj) 
    173             zxnpu = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    174             zynpu = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    175             znnpu = zxnpu*zxnpu + zynpu*zynpu 
    176             ! 
    177             zlam = plamv(ji,jj)     ! north pole direction & modulous (at v-point) 
    178             zphi = pphiv(ji,jj) 
    179             zxnpv = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    180             zynpv = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    181             znnpv = zxnpv*zxnpv + zynpv*zynpv 
    182             ! 
    183             zlam = plamf(ji,jj)     ! north pole direction & modulous (at f-point) 
    184             zphi = pphif(ji,jj) 
    185             zxnpf = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    186             zynpf = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
    187             znnpf = zxnpf*zxnpf + zynpf*zynpf 
    188             ! 
    189             zlam = plamv(ji,jj  )   ! j-direction: v-point segment direction (around t-point) 
    190             zphi = pphiv(ji,jj  ) 
    191             zlan = plamv(ji,jj-1) 
    192             zphh = pphiv(ji,jj-1) 
    193             zxvvt =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    194                &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    195             zyvvt =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    196                &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    197             znvvt = SQRT( znnpt * ( zxvvt*zxvvt + zyvvt*zyvvt )  ) 
    198             znvvt = MAX( znvvt, 1.e-14 ) 
    199             ! 
    200             zlam = plamf(ji,jj  )   ! j-direction: f-point segment direction (around u-point) 
    201             zphi = pphif(ji,jj  ) 
    202             zlan = plamf(ji,jj-1) 
    203             zphh = pphif(ji,jj-1) 
    204             zxffu =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    205                &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    206             zyffu =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    207                &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    208             znffu = SQRT( znnpu * ( zxffu*zxffu + zyffu*zyffu )  ) 
    209             znffu = MAX( znffu, 1.e-14 ) 
    210             ! 
    211             zlam = plamf(ji  ,jj)   ! i-direction: f-point segment direction (around v-point) 
    212             zphi = pphif(ji  ,jj) 
    213             zlan = plamf(ji-1,jj) 
    214             zphh = pphif(ji-1,jj) 
    215             zxffv =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    216                &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    217             zyffv =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    218                &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    219             znffv = SQRT( znnpv * ( zxffv*zxffv + zyffv*zyffv )  ) 
    220             znffv = MAX( znffv, 1.e-14 ) 
    221             ! 
    222             zlam = plamu(ji,jj+1)   ! j-direction: u-point segment direction (around f-point) 
    223             zphi = pphiu(ji,jj+1) 
    224             zlan = plamu(ji,jj  ) 
    225             zphh = pphiu(ji,jj  ) 
    226             zxuuf =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    227                &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    228             zyuuf =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
    229                &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
    230             znuuf = SQRT( znnpf * ( zxuuf*zxuuf + zyuuf*zyuuf )  ) 
    231             znuuf = MAX( znuuf, 1.e-14 ) 
    232             ! 
    233             !                       ! cosinus and sinus using dot and cross products 
    234             gsint(ji,jj) = ( zxnpt*zyvvt - zynpt*zxvvt ) / znvvt 
    235             gcost(ji,jj) = ( zxnpt*zxvvt + zynpt*zyvvt ) / znvvt 
    236             ! 
    237             gsinu(ji,jj) = ( zxnpu*zyffu - zynpu*zxffu ) / znffu 
    238             gcosu(ji,jj) = ( zxnpu*zxffu + zynpu*zyffu ) / znffu 
    239             ! 
    240             gsinf(ji,jj) = ( zxnpf*zyuuf - zynpf*zxuuf ) / znuuf 
    241             gcosf(ji,jj) = ( zxnpf*zxuuf + zynpf*zyuuf ) / znuuf 
    242             ! 
    243             gsinv(ji,jj) = ( zxnpv*zxffv + zynpv*zyffv ) / znffv 
    244             gcosv(ji,jj) =-( zxnpv*zyffv - zynpv*zxffv ) / znffv     ! (caution, rotation of 90 degres) 
    245             ! 
    246          END DO 
    247       END DO 
     162      DO_2D_00_01 
     163         !                   
     164         zlam = plamt(ji,jj)     ! north pole direction & modulous (at t-point) 
     165         zphi = pphit(ji,jj) 
     166         zxnpt = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     167         zynpt = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     168         znnpt = zxnpt*zxnpt + zynpt*zynpt 
     169         ! 
     170         zlam = plamu(ji,jj)     ! north pole direction & modulous (at u-point) 
     171         zphi = pphiu(ji,jj) 
     172         zxnpu = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     173         zynpu = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     174         znnpu = zxnpu*zxnpu + zynpu*zynpu 
     175         ! 
     176         zlam = plamv(ji,jj)     ! north pole direction & modulous (at v-point) 
     177         zphi = pphiv(ji,jj) 
     178         zxnpv = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     179         zynpv = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     180         znnpv = zxnpv*zxnpv + zynpv*zynpv 
     181         ! 
     182         zlam = plamf(ji,jj)     ! north pole direction & modulous (at f-point) 
     183         zphi = pphif(ji,jj) 
     184         zxnpf = 0. - 2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     185         zynpf = 0. - 2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. ) 
     186         znnpf = zxnpf*zxnpf + zynpf*zynpf 
     187         ! 
     188         zlam = plamv(ji,jj  )   ! j-direction: v-point segment direction (around t-point) 
     189         zphi = pphiv(ji,jj  ) 
     190         zlan = plamv(ji,jj-1) 
     191         zphh = pphiv(ji,jj-1) 
     192         zxvvt =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     193            &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     194         zyvvt =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     195            &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     196         znvvt = SQRT( znnpt * ( zxvvt*zxvvt + zyvvt*zyvvt )  ) 
     197         znvvt = MAX( znvvt, 1.e-14 ) 
     198         ! 
     199         zlam = plamf(ji,jj  )   ! j-direction: f-point segment direction (around u-point) 
     200         zphi = pphif(ji,jj  ) 
     201         zlan = plamf(ji,jj-1) 
     202         zphh = pphif(ji,jj-1) 
     203         zxffu =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     204            &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     205         zyffu =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     206            &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     207         znffu = SQRT( znnpu * ( zxffu*zxffu + zyffu*zyffu )  ) 
     208         znffu = MAX( znffu, 1.e-14 ) 
     209         ! 
     210         zlam = plamf(ji  ,jj)   ! i-direction: f-point segment direction (around v-point) 
     211         zphi = pphif(ji  ,jj) 
     212         zlan = plamf(ji-1,jj) 
     213         zphh = pphif(ji-1,jj) 
     214         zxffv =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     215            &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     216         zyffv =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     217            &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     218         znffv = SQRT( znnpv * ( zxffv*zxffv + zyffv*zyffv )  ) 
     219         znffv = MAX( znffv, 1.e-14 ) 
     220         ! 
     221         zlam = plamu(ji,jj+1)   ! j-direction: u-point segment direction (around f-point) 
     222         zphi = pphiu(ji,jj+1) 
     223         zlan = plamu(ji,jj  ) 
     224         zphh = pphiu(ji,jj  ) 
     225         zxuuf =  2. * COS( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     226            &  -  2. * COS( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     227         zyuuf =  2. * SIN( rad*zlam ) * TAN( rpi/4. - rad*zphi/2. )   & 
     228            &  -  2. * SIN( rad*zlan ) * TAN( rpi/4. - rad*zphh/2. ) 
     229         znuuf = SQRT( znnpf * ( zxuuf*zxuuf + zyuuf*zyuuf )  ) 
     230         znuuf = MAX( znuuf, 1.e-14 ) 
     231         ! 
     232         !                       ! cosinus and sinus using dot and cross products 
     233         gsint(ji,jj) = ( zxnpt*zyvvt - zynpt*zxvvt ) / znvvt 
     234         gcost(ji,jj) = ( zxnpt*zxvvt + zynpt*zyvvt ) / znvvt 
     235         ! 
     236         gsinu(ji,jj) = ( zxnpu*zyffu - zynpu*zxffu ) / znffu 
     237         gcosu(ji,jj) = ( zxnpu*zxffu + zynpu*zyffu ) / znffu 
     238         ! 
     239         gsinf(ji,jj) = ( zxnpf*zyuuf - zynpf*zxuuf ) / znuuf 
     240         gcosf(ji,jj) = ( zxnpf*zxuuf + zynpf*zyuuf ) / znuuf 
     241         ! 
     242         gsinv(ji,jj) = ( zxnpv*zxffv + zynpv*zyffv ) / znffv 
     243         gcosv(ji,jj) =-( zxnpv*zyffv - zynpv*zxffv ) / znffv     ! (caution, rotation of 90 degres) 
     244         ! 
     245      END_2D 
    248246 
    249247      ! =============== ! 
     
    251249      ! =============== ! 
    252250 
    253       DO jj = 2, jpjm1 
    254          DO ji = fs_2, jpi   ! vector opt. 
    255             IF( MOD( ABS( plamv(ji,jj) - plamv(ji,jj-1) ), 360. ) < 1.e-8 ) THEN 
    256                gsint(ji,jj) = 0. 
    257                gcost(ji,jj) = 1. 
    258             ENDIF 
    259             IF( MOD( ABS( plamf(ji,jj) - plamf(ji,jj-1) ), 360. ) < 1.e-8 ) THEN 
    260                gsinu(ji,jj) = 0. 
    261                gcosu(ji,jj) = 1. 
    262             ENDIF 
    263             IF(      ABS( pphif(ji,jj) - pphif(ji-1,jj) )         < 1.e-8 ) THEN 
    264                gsinv(ji,jj) = 0. 
    265                gcosv(ji,jj) = 1. 
    266             ENDIF 
    267             IF( MOD( ABS( plamu(ji,jj) - plamu(ji,jj+1) ), 360. ) < 1.e-8 ) THEN 
    268                gsinf(ji,jj) = 0. 
    269                gcosf(ji,jj) = 1. 
    270             ENDIF 
    271          END DO 
    272       END DO 
     251      DO_2D_00_01 
     252         IF( MOD( ABS( plamv(ji,jj) - plamv(ji,jj-1) ), 360. ) < 1.e-8 ) THEN 
     253            gsint(ji,jj) = 0. 
     254            gcost(ji,jj) = 1. 
     255         ENDIF 
     256         IF( MOD( ABS( plamf(ji,jj) - plamf(ji,jj-1) ), 360. ) < 1.e-8 ) THEN 
     257            gsinu(ji,jj) = 0. 
     258            gcosu(ji,jj) = 1. 
     259         ENDIF 
     260         IF(      ABS( pphif(ji,jj) - pphif(ji-1,jj) )         < 1.e-8 ) THEN 
     261            gsinv(ji,jj) = 0. 
     262            gcosv(ji,jj) = 1. 
     263         ENDIF 
     264         IF( MOD( ABS( plamu(ji,jj) - plamu(ji,jj+1) ), 360. ) < 1.e-8 ) THEN 
     265            gsinf(ji,jj) = 0. 
     266            gcosf(ji,jj) = 1. 
     267         ENDIF 
     268      END_2D 
    273269 
    274270      ! =========================== ! 
  • NEMO/trunk/src/OCE/SBC/sbc_oce.F90

    r12132 r12377  
    22   !!====================================================================== 
    33   !!                       ***  MODULE  sbc_oce  *** 
    4    !! Surface module :   variables defined in core memory  
     4   !! Surface module :   variables defined in core memory 
    55   !!====================================================================== 
    66   !! History :  3.0  ! 2006-06  (G. Madec)  Original code 
     
    99   !!             -   ! 2010-11  (G. Madec) ice-ocean stress always computed at each ocean time-step 
    1010   !!            3.3  ! 2010-10  (J. Chanut, C. Bricaud)  add the surface pressure forcing 
    11    !!            4.0  ! 2012-05  (C. Rousset) add attenuation coef for use in ice model  
     11   !!            4.0  ! 2012-05  (C. Rousset) add attenuation coef for use in ice model 
    1212   !!            4.0  ! 2016-06  (L. Brodeau) new unified bulk routine (based on AeroBulk) 
     13   !!            4.0  ! 2019-03  (F. Lemarié, G. Samson) add compatibility with ABL mode 
    1314   !!---------------------------------------------------------------------- 
    1415 
     
    2627   PUBLIC   sbc_oce_alloc   ! routine called in sbcmod.F90 
    2728   PUBLIC   sbc_tau2wnd     ! routine called in several sbc modules 
    28     
     29 
    2930   !!---------------------------------------------------------------------- 
    3031   !!           Namelist for the Ocean Surface Boundary Condition 
     
    3435   LOGICAL , PUBLIC ::   ln_flx         !: flux      formulation 
    3536   LOGICAL , PUBLIC ::   ln_blk         !: bulk formulation 
     37   LOGICAL , PUBLIC ::   ln_abl         !: Atmospheric boundary layer model 
    3638#if defined key_oasis3 
    3739   LOGICAL , PUBLIC ::   lk_oasis = .TRUE.  !: OASIS used 
     
    4345   LOGICAL , PUBLIC ::   ln_dm2dc       !: Daily mean to Diurnal Cycle short wave (qsr) 
    4446   LOGICAL , PUBLIC ::   ln_rnf         !: runoffs / runoff mouths 
    45    LOGICAL , PUBLIC ::   ln_isf         !: ice shelf melting 
    46    LOGICAL , PUBLIC ::   ln_ssr         !: Sea Surface restoring on SST and/or SSS       
     47   LOGICAL , PUBLIC ::   ln_ssr         !: Sea Surface restoring on SST and/or SSS 
    4748   LOGICAL , PUBLIC ::   ln_apr_dyn     !: Atmospheric pressure forcing used on dynamics (ocean & ice) 
    4849   INTEGER , PUBLIC ::   nn_ice         !: flag for ice in the surface boundary condition (=0/1/2/3) 
     
    5051   !                                             !: =F levitating ice (no presure effect) with mass and salt exchanges 
    5152   !                                             !: =T embedded sea-ice (pressure effect + mass and salt exchanges) 
    52    INTEGER , PUBLIC ::   nn_components  !: flag for sbc module (including sea-ice) coupling mode (see component definition below)  
    53    INTEGER , PUBLIC ::   nn_fwb         !: FreshWater Budget:  
    54    !                                             !:  = 0 unchecked  
     53   INTEGER , PUBLIC ::   nn_components  !: flag for sbc module (including sea-ice) coupling mode (see component definition below) 
     54   INTEGER , PUBLIC ::   nn_fwb         !: FreshWater Budget: 
     55   !                                             !:  = 0 unchecked 
    5556   !                                             !:  = 1 global mean of e-p-r set to zero at each nn_fsbc time step 
    5657   !                                             !:  = 2 annual global mean of e-p-r set to zero 
     
    7778   INTEGER , PUBLIC, PARAMETER ::   jp_flx     = 2        !: flux                          formulation 
    7879   INTEGER , PUBLIC, PARAMETER ::   jp_blk     = 3        !: bulk                          formulation 
    79    INTEGER , PUBLIC, PARAMETER ::   jp_purecpl = 4        !: Pure ocean-atmosphere Coupled formulation 
    80    INTEGER , PUBLIC, PARAMETER ::   jp_none    = 5        !: for OPA when doing coupling via SAS module 
    81     
    82    !!---------------------------------------------------------------------- 
    83    !!           Stokes drift parametrization definition  
     80   INTEGER , PUBLIC, PARAMETER ::   jp_abl     = 4        !: Atmospheric boundary layer    formulation 
     81   INTEGER , PUBLIC, PARAMETER ::   jp_purecpl = 5        !: Pure ocean-atmosphere Coupled formulation 
     82   INTEGER , PUBLIC, PARAMETER ::   jp_none    = 6        !: for OPA when doing coupling via SAS module 
     83 
     84   !!---------------------------------------------------------------------- 
     85   !!           Stokes drift parametrization definition 
    8486   !!---------------------------------------------------------------------- 
    8587   INTEGER , PUBLIC, PARAMETER ::   jp_breivik_2014 = 0     !: Breivik  2014: v_z=v_0*[exp(2*k*z)/(1-8*k*z)] 
    86    INTEGER , PUBLIC, PARAMETER ::   jp_li_2017      = 1     !: Li et al 2017: Stokes drift based on Phillips spectrum (Breivik 2016)  
    87                                                             !  with depth averaged profile 
    88    INTEGER , PUBLIC, PARAMETER ::   jp_peakfr       = 2     !: Li et al 2017: using the peak wave number read from wave model instead  
    89                                                             !  of the inverse depth scale 
     88   INTEGER , PUBLIC, PARAMETER ::   jp_li_2017      = 1     !: Li et al 2017: Stokes drift based on Phillips spectrum (Breivik 2016) 
     89   !  with depth averaged profile 
     90   INTEGER , PUBLIC, PARAMETER ::   jp_peakfr       = 2     !: Li et al 2017: using the peak wave number read from wave model instead 
     91   !  of the inverse depth scale 
    9092   LOGICAL , PUBLIC            ::   ll_st_bv2014  = .FALSE. !  logical indicator, .true. if Breivik 2014 parameterisation is active. 
    9193   LOGICAL , PUBLIC            ::   ll_st_li2017  = .FALSE. !  logical indicator, .true. if Li 2017 parameterisation is active. 
     
    9698   !!           component definition 
    9799   !!---------------------------------------------------------------------- 
    98    INTEGER , PUBLIC, PARAMETER ::   jp_iam_nemo = 0      !: Initial single executable configuration  
    99                                                          !  (no internal OASIS coupling) 
     100   INTEGER , PUBLIC, PARAMETER ::   jp_iam_nemo = 0      !: Initial single executable configuration 
     101   !  (no internal OASIS coupling) 
    100102   INTEGER , PUBLIC, PARAMETER ::   jp_iam_opa  = 1      !: Multi executable configuration - OPA component 
    101                                                          !  (internal OASIS coupling) 
     103   !  (internal OASIS coupling) 
    102104   INTEGER , PUBLIC, PARAMETER ::   jp_iam_sas  = 2      !: Multi executable configuration - SAS component 
    103                                                          !  (internal OASIS coupling) 
     105   !  (internal OASIS coupling) 
    104106   !!---------------------------------------------------------------------- 
    105107   !!              Ocean Surface Boundary Condition fields 
     
    107109   INTEGER , PUBLIC ::  ncpl_qsr_freq = 0        !: qsr coupling frequency per days from atmosphere (used by top) 
    108110   ! 
    109    LOGICAL , PUBLIC ::   lhftau = .FALSE.        !: HF tau used in TKE: mean(stress module) - module(mean stress) 
    110111   !!                                   !!   now    ! before   !! 
    111112   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   utau   , utau_b   !: sea surface i-stress (ocean referential)     [N/m2] 
    112113   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   vtau   , vtau_b   !: sea surface j-stress (ocean referential)     [N/m2] 
    113    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   taum              !: module of sea surface stress (at T-point)    [N/m2]  
    114    !! wndm is used onmpute surface gases exchanges in ice-free ocean or leads 
     114   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   taum              !: module of sea surface stress (at T-point)    [N/m2] 
     115   !! wndm is used compute surface gases exchanges in ice-free ocean or leads 
    115116   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wndm              !: wind speed module at T-point (=|U10m-Uoce|)  [m/s] 
     117   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   rhoa              !: air density at "rn_zu" m above the sea       [kg/m3] 
    116118   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   qsr               !: sea heat flux:     solar                     [W/m2] 
    117119   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   qns    , qns_b    !: sea heat flux: non solar                     [W/m2] 
     
    122124   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   emp_tot           !: total E-P over ocean and ice                 [Kg/m2/s] 
    123125   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   fmmflx            !: freshwater budget: freezing/melting          [Kg/m2/s] 
    124    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   rnf    , rnf_b    !: river runoff        [Kg/m2/s]   
    125    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   fwfisf , fwfisf_b !: ice shelf melting   [Kg/m2/s]   
    126    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   fwficb , fwficb_b !: iceberg melting [Kg/m2/s]   
    127  
     126   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   rnf    , rnf_b    !: river runoff                                 [Kg/m2/s] 
     127   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   fwficb , fwficb_b !: iceberg melting                              [Kg/m2/s] 
    128128   !! 
    129129   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::  sbc_tsc, sbc_tsc_b  !: sbc content trend                      [K.m/s] jpi,jpj,jpts 
     
    137137   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: xcplmask          !: coupling mask for ln_mixcpl (warning: allocated in sbccpl) 
    138138 
     139   !!--------------------------------------------------------------------- 
     140   !! ABL Vertical Domain size 
     141   !!--------------------------------------------------------------------- 
     142   INTEGER , PUBLIC            ::   jpka   = 2     !: ABL number of vertical levels (default definition) 
     143   INTEGER , PUBLIC            ::   jpkam1 = 1     !: jpka-1 
     144   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:)   ::   ght_abl, ghw_abl          !: ABL geopotential height (needed for iom) 
     145   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:)   ::   e3t_abl, e3w_abl          !: ABL vertical scale factors (needed for iom) 
     146 
    139147   !!---------------------------------------------------------------------- 
    140148   !!                     Sea Surface Mean fields 
     
    146154   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sss_m     !: mean (nn_fsbc time-step) surface sea salinity            [psu] 
    147155   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   ssh_m     !: mean (nn_fsbc time-step) sea surface height                [m] 
     156   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   tsk_m     !: mean (nn_fsbc time-step) SKIN surface sea temp.      [Celsius] 
    148157   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   e3t_m     !: mean (nn_fsbc time-step) sea surface layer thickness       [m] 
    149158   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   frq_m     !: mean (nn_fsbc time-step) fraction of solar net radiation absorbed in the 1st T level [-] 
    150159 
    151160   !! * Substitutions 
    152 #  include "vectopt_loop_substitute.h90" 
     161#  include "do_loop_substitute.h90" 
    153162   !!---------------------------------------------------------------------- 
    154163   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    167176      ! 
    168177      ALLOCATE( utau(jpi,jpj) , utau_b(jpi,jpj) , taum(jpi,jpj) ,     & 
    169          &      vtau(jpi,jpj) , vtau_b(jpi,jpj) , wndm(jpi,jpj) , STAT=ierr(1) )  
    170          ! 
     178         &      vtau(jpi,jpj) , vtau_b(jpi,jpj) , wndm(jpi,jpj) , rhoa(jpi,jpj) , STAT=ierr(1) ) 
     179      ! 
    171180      ALLOCATE( qns_tot(jpi,jpj) , qns  (jpi,jpj) , qns_b(jpi,jpj),        & 
    172181         &      qsr_tot(jpi,jpj) , qsr  (jpi,jpj) ,                        & 
    173182         &      emp    (jpi,jpj) , emp_b(jpi,jpj) ,                        & 
    174183         &      sfx    (jpi,jpj) , sfx_b(jpi,jpj) , emp_tot(jpi,jpj), fmmflx(jpi,jpj), STAT=ierr(2) ) 
    175          ! 
    176       ALLOCATE( fwfisf  (jpi,jpj), rnf  (jpi,jpj) , sbc_tsc  (jpi,jpj,jpts) , qsr_hc  (jpi,jpj,jpk) ,  & 
    177          &      fwfisf_b(jpi,jpj), rnf_b(jpi,jpj) , sbc_tsc_b(jpi,jpj,jpts) , qsr_hc_b(jpi,jpj,jpk) ,  & 
     184      ! 
     185      ALLOCATE( rnf  (jpi,jpj) , sbc_tsc  (jpi,jpj,jpts) , qsr_hc  (jpi,jpj,jpk) ,  & 
     186         &      rnf_b(jpi,jpj) , sbc_tsc_b(jpi,jpj,jpts) , qsr_hc_b(jpi,jpj,jpk) ,  & 
    178187         &      fwficb  (jpi,jpj), fwficb_b(jpi,jpj), STAT=ierr(3) ) 
    179          ! 
     188      ! 
    180189      ALLOCATE( tprecip(jpi,jpj) , sprecip(jpi,jpj) , fr_i(jpi,jpj) ,     & 
    181          &      atm_co2(jpi,jpj) ,                                        & 
     190         &      atm_co2(jpi,jpj) , tsk_m(jpi,jpj) ,                       & 
    182191         &      ssu_m  (jpi,jpj) , sst_m(jpi,jpj) , frq_m(jpi,jpj) ,      & 
    183192         &      ssv_m  (jpi,jpj) , sss_m(jpi,jpj) , ssh_m(jpi,jpj) , STAT=ierr(4) ) 
    184          ! 
     193      ! 
    185194      ALLOCATE( e3t_m(jpi,jpj) , STAT=ierr(5) ) 
    186          ! 
     195      ! 
    187196      sbc_oce_alloc = MAXVAL( ierr ) 
    188197      CALL mpp_sum ( 'sbc_oce', sbc_oce_alloc ) 
     
    195204      !!--------------------------------------------------------------------- 
    196205      !!                    ***  ROUTINE sbc_tau2wnd  *** 
    197       !!                    
    198       !! ** Purpose : Estimation of wind speed as a function of wind stress    
     206      !! 
     207      !! ** Purpose : Estimation of wind speed as a function of wind stress 
    199208      !! 
    200209      !! ** Method  : |tau|=rhoa*Cd*|U|^2 
     
    207216      INTEGER  ::   ji, jj                ! dummy indices 
    208217      !!--------------------------------------------------------------------- 
    209       zcoef = 0.5 / ( zrhoa * zcdrag )  
    210       DO jj = 2, jpjm1 
    211          DO ji = fs_2, fs_jpim1   ! vect. opt. 
    212             ztx = utau(ji-1,jj  ) + utau(ji,jj)  
    213             zty = vtau(ji  ,jj-1) + vtau(ji,jj)  
    214             ztau = SQRT( ztx * ztx + zty * zty ) 
    215             wndm(ji,jj) = SQRT ( ztau * zcoef ) * tmask(ji,jj,1) 
    216          END DO 
    217       END DO 
     218      zcoef = 0.5 / ( zrhoa * zcdrag ) 
     219      DO_2D_00_00 
     220         ztx = utau(ji-1,jj  ) + utau(ji,jj) 
     221         zty = vtau(ji  ,jj-1) + vtau(ji,jj) 
     222         ztau = SQRT( ztx * ztx + zty * zty ) 
     223         wndm(ji,jj) = SQRT ( ztau * zcoef ) * tmask(ji,jj,1) 
     224      END_2D 
    218225      CALL lbc_lnk( 'sbc_oce', wndm(:,:) , 'T', 1. ) 
    219226      ! 
  • NEMO/trunk/src/OCE/SBC/sbcapr.F90

    r11536 r12377  
    6969      NAMELIST/namsbc_apr/ cn_dir, sn_apr, ln_ref_apr, rn_pref, ln_apr_obc 
    7070      !!---------------------------------------------------------------------- 
    71       REWIND( numnam_ref )              ! Namelist namsbc_apr in reference namelist : File for atmospheric pressure forcing 
    7271      READ  ( numnam_ref, namsbc_apr, IOSTAT = ios, ERR = 901) 
    7372901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_apr in reference namelist' ) 
    7473 
    75       REWIND( numnam_cfg )              ! Namelist namsbc_apr in configuration namelist : File for atmospheric pressure forcing 
    7674      READ  ( numnam_cfg, namsbc_apr, IOSTAT = ios, ERR = 902 ) 
    7775902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_apr in configuration namelist' ) 
     
    103101      ! 
    104102      !                                            !* control check 
    105       IF ( ln_apr_obc  ) THEN 
     103      IF( ln_apr_obc  ) THEN 
    106104         IF(lwp) WRITE(numout,*) '         Inverse barometer added to OBC ssh data' 
    107105      ENDIF 
  • NEMO/trunk/src/OCE/SBC/sbcblk.F90

    r12276 r12377  
    1515   !!            3.7  !  2014-06  (L. Brodeau)  simplification and optimization of CORE bulk 
    1616   !!            4.0  !  2016-06  (L. Brodeau)  sbcblk_core becomes sbcblk and is not restricted to the CORE algorithm anymore 
    17    !!                 !                        ==> based on AeroBulk (http://aerobulk.sourceforge.net/) 
     17   !!                 !                        ==> based on AeroBulk (https://github.com/brodeau/aerobulk/) 
    1818   !!            4.0  !  2016-10  (G. Madec)  introduce a sbc_blk_init routine 
    19    !!            4.0  !  2016-10  (M. Vancoppenolle)  Introduce conduction flux emulator (M. Vancoppenolle)  
     19   !!            4.0  !  2016-10  (M. Vancoppenolle)  Introduce conduction flux emulator (M. Vancoppenolle) 
     20   !!            4.0  !  2019-03  (F. Lemarié & G. Samson)  add ABL compatibility (ln_abl=TRUE) 
    2021   !!---------------------------------------------------------------------- 
    2122 
     
    2324   !!   sbc_blk_init  : initialisation of the chosen bulk formulation as ocean surface boundary condition 
    2425   !!   sbc_blk       : bulk formulation as ocean surface boundary condition 
    25    !!   blk_oce       : computes momentum, heat and freshwater fluxes over ocean 
    26    !!   rho_air       : density of (moist) air (depends on T_air, q_air and SLP 
    27    !!   cp_air        : specific heat of (moist) air (depends spec. hum. q_air) 
    28    !!   q_sat         : saturation humidity as a function of SLP and temperature 
    29    !!   L_vap         : latent heat of vaporization of water as a function of temperature 
    30    !!             sea-ice case only :  
    31    !!   blk_ice_tau   : provide the air-ice stress 
    32    !!   blk_ice_flx   : provide the heat and mass fluxes at air-ice interface 
     26   !!   blk_oce_1     : computes pieces of momentum, heat and freshwater fluxes over ocean for ABL model  (ln_abl=TRUE) 
     27   !!   blk_oce_2     : finalizes momentum, heat and freshwater fluxes computation over ocean after the ABL step  (ln_abl=TRUE) 
     28   !!             sea-ice case only : 
     29   !!   blk_ice_1   : provide the air-ice stress 
     30   !!   blk_ice_2   : provide the heat and mass fluxes at air-ice interface 
    3331   !!   blk_ice_qcn   : provide ice surface temperature and snow/ice conduction flux (emulating conduction flux) 
    3432   !!   Cdn10_Lupkes2012 : Lupkes et al. (2012) air-ice drag 
    35    !!   Cdn10_Lupkes2015 : Lupkes et al. (2015) air-ice drag  
     33   !!   Cdn10_Lupkes2015 : Lupkes et al. (2015) air-ice drag 
    3634   !!---------------------------------------------------------------------- 
    3735   USE oce            ! ocean dynamics and tracers 
     
    4644   USE lib_fortran    ! to use key_nosignedzero 
    4745#if defined key_si3 
    48    USE ice     , ONLY :   u_ice, v_ice, jpl, a_i_b, at_i_b, t_su, rn_cnd_s, hfx_err_dif 
     46   USE ice     , ONLY :   jpl, a_i_b, at_i_b, rn_cnd_s, hfx_err_dif 
    4947   USE icethd_dh      ! for CALL ice_thd_snwblow 
    5048#endif 
    51    USE sbcblk_algo_ncar     ! => turb_ncar     : NCAR - CORE (Large & Yeager, 2009)  
    52    USE sbcblk_algo_coare    ! => turb_coare    : COAREv3.0 (Fairall et al. 2003)  
    53    USE sbcblk_algo_coare3p5 ! => turb_coare3p5 : COAREv3.5 (Edson et al. 2013) 
    54    USE sbcblk_algo_ecmwf    ! => turb_ecmwf    : ECMWF (IFS cycle 31)  
     49   USE sbcblk_algo_ncar     ! => turb_ncar     : NCAR - CORE (Large & Yeager, 2009) 
     50   USE sbcblk_algo_coare3p0 ! => turb_coare3p0 : COAREv3.0 (Fairall et al. 2003) 
     51   USE sbcblk_algo_coare3p6 ! => turb_coare3p6 : COAREv3.6 (Fairall et al. 2018 + Edson et al. 2013) 
     52   USE sbcblk_algo_ecmwf    ! => turb_ecmwf    : ECMWF (IFS cycle 45r1) 
    5553   ! 
    5654   USE iom            ! I/O manager library 
     
    6058   USE prtctl         ! Print control 
    6159 
     60   USE sbcblk_phy     ! a catalog of functions for physical/meteorological parameters in the marine boundary layer, rho_air, q_sat, etc... 
     61 
     62 
    6263   IMPLICIT NONE 
    6364   PRIVATE 
     
    6566   PUBLIC   sbc_blk_init  ! called in sbcmod 
    6667   PUBLIC   sbc_blk       ! called in sbcmod 
     68   PUBLIC   blk_oce_1     ! called in sbcabl 
     69   PUBLIC   blk_oce_2     ! called in sbcabl 
    6770#if defined key_si3 
    68    PUBLIC   blk_ice_tau   ! routine called in icesbc 
    69    PUBLIC   blk_ice_flx   ! routine called in icesbc 
     71   PUBLIC   blk_ice_   ! routine called in icesbc 
     72   PUBLIC   blk_ice_   ! routine called in icesbc 
    7073   PUBLIC   blk_ice_qcn   ! routine called in icesbc 
    71 #endif  
    72  
    73 !!Lolo: should ultimately be moved in the module with all physical constants ? 
    74 !!gm  : In principle, yes. 
    75    REAL(wp), PARAMETER ::   Cp_dry = 1005.0       !: Specic heat of dry air, constant pressure      [J/K/kg] 
    76    REAL(wp), PARAMETER ::   Cp_vap = 1860.0       !: Specic heat of water vapor, constant pressure  [J/K/kg] 
    77    REAL(wp), PARAMETER ::   R_dry = 287.05_wp     !: Specific gas constant for dry air              [J/K/kg] 
    78    REAL(wp), PARAMETER ::   R_vap = 461.495_wp    !: Specific gas constant for water vapor          [J/K/kg] 
    79    REAL(wp), PARAMETER ::   reps0 = R_dry/R_vap   !: ratio of gas constant for dry air and water vapor => ~ 0.622 
    80    REAL(wp), PARAMETER ::   rctv0 = R_vap/R_dry   !: for virtual temperature (== (1-eps)/eps) => ~ 0.608 
    81  
    82    INTEGER , PARAMETER ::   jpfld   =10           ! maximum number of files to read 
    83    INTEGER , PARAMETER ::   jp_wndi = 1           ! index of 10m wind velocity (i-component) (m/s)    at T-point 
    84    INTEGER , PARAMETER ::   jp_wndj = 2           ! index of 10m wind velocity (j-component) (m/s)    at T-point 
    85    INTEGER , PARAMETER ::   jp_tair = 3           ! index of 10m air temperature             (Kelvin) 
    86    INTEGER , PARAMETER ::   jp_humi = 4           ! index of specific humidity               ( % ) 
    87    INTEGER , PARAMETER ::   jp_qsr  = 5           ! index of solar heat                      (W/m2) 
    88    INTEGER , PARAMETER ::   jp_qlw  = 6           ! index of Long wave                       (W/m2) 
    89    INTEGER , PARAMETER ::   jp_prec = 7           ! index of total precipitation (rain+snow) (Kg/m2/s) 
    90    INTEGER , PARAMETER ::   jp_snow = 8           ! index of snow (solid prcipitation)       (kg/m2/s) 
    91    INTEGER , PARAMETER ::   jp_slp  = 9           ! index of sea level pressure              (Pa) 
    92    INTEGER , PARAMETER ::   jp_tdif =10           ! index of tau diff associated to HF tau   (N/m2)   at T-point 
    93  
    94    TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf   ! structure of input fields (file informations, fields read) 
    95  
    96    !                                             !!! Bulk parameters 
    97    REAL(wp), PARAMETER ::   cpa    = 1000.5         ! specific heat of air (only used for ice fluxes now...) 
    98    REAL(wp), PARAMETER ::   Ls     =    2.839e6     ! latent heat of sublimation 
    99    REAL(wp), PARAMETER ::   Stef   =    5.67e-8     ! Stefan Boltzmann constant 
    100    REAL(wp), PARAMETER ::   Cd_ice =    1.4e-3      ! transfer coefficient over ice 
    101    REAL(wp), PARAMETER ::   albo   =    0.066       ! ocean albedo assumed to be constant 
    102    ! 
     74#endif 
     75 
     76   INTEGER , PUBLIC            ::   jpfld         ! maximum number of files to read 
     77   INTEGER , PUBLIC, PARAMETER ::   jp_wndi = 1   ! index of 10m wind velocity (i-component) (m/s)    at T-point 
     78   INTEGER , PUBLIC, PARAMETER ::   jp_wndj = 2   ! index of 10m wind velocity (j-component) (m/s)    at T-point 
     79   INTEGER , PUBLIC, PARAMETER ::   jp_tair = 3   ! index of 10m air temperature             (Kelvin) 
     80   INTEGER , PUBLIC, PARAMETER ::   jp_humi = 4   ! index of specific humidity               ( % ) 
     81   INTEGER , PUBLIC, PARAMETER ::   jp_qsr  = 5   ! index of solar heat                      (W/m2) 
     82   INTEGER , PUBLIC, PARAMETER ::   jp_qlw  = 6   ! index of Long wave                       (W/m2) 
     83   INTEGER , PUBLIC, PARAMETER ::   jp_prec = 7   ! index of total precipitation (rain+snow) (Kg/m2/s) 
     84   INTEGER , PUBLIC, PARAMETER ::   jp_snow = 8   ! index of snow (solid prcipitation)       (kg/m2/s) 
     85   INTEGER , PUBLIC, PARAMETER ::   jp_slp  = 9   ! index of sea level pressure              (Pa) 
     86   INTEGER , PUBLIC, PARAMETER ::   jp_hpgi =10   ! index of ABL geostrophic wind or hpg (i-component) (m/s) at T-point 
     87   INTEGER , PUBLIC, PARAMETER ::   jp_hpgj =11   ! index of ABL geostrophic wind or hpg (j-component) (m/s) at T-point 
     88 
     89   TYPE(FLD), PUBLIC, ALLOCATABLE, DIMENSION(:) ::   sf   ! structure of input atmospheric fields (file informations, fields read) 
     90 
    10391   !                           !!* Namelist namsbc_blk : bulk parameters 
    10492   LOGICAL  ::   ln_NCAR        ! "NCAR"      algorithm   (Large and Yeager 2008) 
    10593   LOGICAL  ::   ln_COARE_3p0   ! "COARE 3.0" algorithm   (Fairall et al. 2003) 
    106    LOGICAL  ::   ln_COARE_3p5   ! "COARE 3.5" algorithm   (Edson et al. 2013) 
    107    LOGICAL  ::   ln_ECMWF       ! "ECMWF"     algorithm   (IFS cycle 31) 
     94   LOGICAL  ::   ln_COARE_3p6   ! "COARE 3.6" algorithm   (Edson et al. 2013) 
     95   LOGICAL  ::   ln_ECMWF       ! "ECMWF"     algorithm   (IFS cycle 45r1) 
    10896   ! 
    109    LOGICAL  ::   ln_taudif      ! logical flag to use the "mean of stress module - module of mean stress" data 
    110    REAL(wp) ::   rn_pfac        ! multiplication factor for precipitation 
    111    REAL(wp) ::   rn_efac        ! multiplication factor for evaporation 
    112    REAL(wp) ::   rn_vfac        ! multiplication factor for ice/ocean velocity in the calculation of wind stress 
    113    REAL(wp) ::   rn_zqt         ! z(q,t) : height of humidity and temperature measurements 
    114    REAL(wp) ::   rn_zu          ! z(u)   : height of wind measurements 
    115 !!gm ref namelist initialize it so remove the setting to false below 
    116    LOGICAL  ::   ln_Cd_L12 = .FALSE. !  Modify the drag ice-atm depending on ice concentration (from Lupkes et al. JGR2012) 
    117    LOGICAL  ::   ln_Cd_L15 = .FALSE. !  Modify the drag ice-atm depending on ice concentration (from Lupkes et al. JGR2015) 
     97   LOGICAL  ::   ln_Cd_L12      ! ice-atm drag = F( ice concentration )                        (Lupkes et al. JGR2012) 
     98   LOGICAL  ::   ln_Cd_L15      ! ice-atm drag = F( ice concentration, atmospheric stability ) (Lupkes et al. JGR2015) 
    11899   ! 
    119    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   Cd_atm                    ! transfer coefficient for momentum      (tau) 
    120    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   Ch_atm                    ! transfer coefficient for sensible heat (Q_sens) 
    121    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   Ce_atm                    ! tansfert coefficient for evaporation   (Q_lat) 
    122    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   t_zu                      ! air temperature at wind speed height (needed by Lupkes 2015 bulk scheme) 
    123    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   q_zu                      ! air spec. hum.  at wind speed height (needed by Lupkes 2015 bulk scheme) 
    124    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   cdn_oce, chn_oce, cen_oce ! needed by Lupkes 2015 bulk scheme 
     100   REAL(wp)         ::   rn_pfac   ! multiplication factor for precipitation 
     101   REAL(wp), PUBLIC ::   rn_efac   ! multiplication factor for evaporation 
     102   REAL(wp), PUBLIC ::   rn_vfac   ! multiplication factor for ice/ocean velocity in the calculation of wind stress 
     103   REAL(wp)         ::   rn_zqt    ! z(q,t) : height of humidity and temperature measurements 
     104   REAL(wp)         ::   rn_zu     ! z(u)   : height of wind measurements 
     105   ! 
     106   REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   Cd_ice , Ch_ice , Ce_ice   ! transfert coefficients over ice 
     107   REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   Cdn_oce, Chn_oce, Cen_oce  ! neutral coeffs over ocean (L15 bulk scheme) 
     108   REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   t_zu, q_zu                 ! air temp. and spec. hum. at wind speed height (L15 bulk scheme) 
     109 
     110   LOGICAL  ::   ln_skin_cs     ! use the cool-skin (only available in ECMWF and COARE algorithms) !LB 
     111   LOGICAL  ::   ln_skin_wl     ! use the warm-layer parameterization (only available in ECMWF and COARE algorithms) !LB 
     112   LOGICAL  ::   ln_humi_sph    ! humidity read in files ("sn_humi") is specific humidity [kg/kg] if .true. !LB 
     113   LOGICAL  ::   ln_humi_dpt    ! humidity read in files ("sn_humi") is dew-point temperature [K] if .true. !LB 
     114   LOGICAL  ::   ln_humi_rlh    ! humidity read in files ("sn_humi") is relative humidity     [%] if .true. !LB 
     115   ! 
     116   INTEGER  ::   nhumi          ! choice of the bulk algorithm 
     117   !                            ! associated indices: 
     118   INTEGER, PARAMETER :: np_humi_sph = 1 
     119   INTEGER, PARAMETER :: np_humi_dpt = 2 
     120   INTEGER, PARAMETER :: np_humi_rlh = 3 
    125121 
    126122   INTEGER  ::   nblk           ! choice of the bulk algorithm 
     
    128124   INTEGER, PARAMETER ::   np_NCAR      = 1   ! "NCAR" algorithm        (Large and Yeager 2008) 
    129125   INTEGER, PARAMETER ::   np_COARE_3p0 = 2   ! "COARE 3.0" algorithm   (Fairall et al. 2003) 
    130    INTEGER, PARAMETER ::   np_COARE_3p5 = 3   ! "COARE 3.5" algorithm   (Edson et al. 2013) 
    131    INTEGER, PARAMETER ::   np_ECMWF     = 4   ! "ECMWF" algorithm       (IFS cycle 31) 
     126   INTEGER, PARAMETER ::   np_COARE_3p6 = 3   ! "COARE 3.6" algorithm   (Edson et al. 2013) 
     127   INTEGER, PARAMETER ::   np_ECMWF     = 4   ! "ECMWF" algorithm       (IFS cycle 45r1) 
    132128 
    133129   !! * Substitutions 
    134 #  include "vectopt_loop_substitute.h90" 
     130#  include "do_loop_substitute.h90" 
    135131   !!---------------------------------------------------------------------- 
    136132   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    144140      !!             ***  ROUTINE sbc_blk_alloc *** 
    145141      !!------------------------------------------------------------------- 
    146       ALLOCATE( Cd_atm (jpi,jpj), Ch_atm (jpi,jpj), Ce_atm (jpi,jpj), t_zu(jpi,jpj), q_zu(jpi,jpj), & 
    147          &      cdn_oce(jpi,jpj), chn_oce(jpi,jpj), cen_oce(jpi,jpj), STAT=sbc_blk_alloc ) 
     142      ALLOCATE( t_zu(jpi,jpj)   , q_zu(jpi,jpj)   ,                                      & 
     143         &      Cdn_oce(jpi,jpj), Chn_oce(jpi,jpj), Cen_oce(jpi,jpj),                    & 
     144         &      Cd_ice (jpi,jpj), Ch_ice (jpi,jpj), Ce_ice (jpi,jpj), STAT=sbc_blk_alloc ) 
    148145      ! 
    149146      CALL mpp_sum ( 'sbcblk', sbc_blk_alloc ) 
     
    158155      !! ** Purpose :   choose and initialize a bulk formulae formulation 
    159156      !! 
    160       !! ** Method  :  
     157      !! ** Method  : 
    161158      !! 
    162159      !!---------------------------------------------------------------------- 
    163       INTEGER  ::   ifpr, jfld            ! dummy loop indice and argument 
     160      INTEGER  ::   jfpr                  ! dummy loop indice and argument 
    164161      INTEGER  ::   ios, ierror, ioptio   ! Local integer 
    165162      !! 
    166163      CHARACTER(len=100)            ::   cn_dir                ! Root directory for location of atmospheric forcing files 
    167       TYPE(FLD_N), DIMENSION(jpfld) ::   slf_i                 ! array of namelist informations on the fields to read 
     164      TYPE(FLD_N), ALLOCATABLE, DIMENSION(:) ::   slf_i        ! array of namelist informations on the fields to read 
    168165      TYPE(FLD_N) ::   sn_wndi, sn_wndj, sn_humi, sn_qsr       ! informations about the fields to be read 
    169166      TYPE(FLD_N) ::   sn_qlw , sn_tair, sn_prec, sn_snow      !       "                        " 
    170       TYPE(FLD_N) ::   sn_slp , sn_tdif                        !       "                        " 
     167      TYPE(FLD_N) ::   sn_slp , sn_hpgi, sn_hpgj               !       "                        " 
    171168      NAMELIST/namsbc_blk/ sn_wndi, sn_wndj, sn_humi, sn_qsr, sn_qlw ,                &   ! input fields 
    172          &                 sn_tair, sn_prec, sn_snow, sn_slp, sn_tdif,                & 
    173          &                 ln_NCAR, ln_COARE_3p0, ln_COARE_3p5, ln_ECMWF,             &   ! bulk algorithm 
    174          &                 cn_dir , ln_taudif, rn_zqt, rn_zu,                         &  
    175          &                 rn_pfac, rn_efac, rn_vfac, ln_Cd_L12, ln_Cd_L15 
     169         &                 sn_tair, sn_prec, sn_snow, sn_slp, sn_hpgi, sn_hpgj,       & 
     170         &                 ln_NCAR, ln_COARE_3p0, ln_COARE_3p6, ln_ECMWF,             &   ! bulk algorithm 
     171         &                 cn_dir , rn_zqt, rn_zu,                                    & 
     172         &                 rn_pfac, rn_efac, rn_vfac, ln_Cd_L12, ln_Cd_L15,           & 
     173         &                 ln_skin_cs, ln_skin_wl, ln_humi_sph, ln_humi_dpt, ln_humi_rlh  ! cool-skin / warm-layer !LB 
    176174      !!--------------------------------------------------------------------- 
    177175      ! 
     
    179177      IF( sbc_blk_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'sbc_blk : unable to allocate standard arrays' ) 
    180178      ! 
    181       !                             !** read bulk namelist   
    182       REWIND( numnam_ref )                !* Namelist namsbc_blk in reference namelist : bulk parameters 
     179      !                             !** read bulk namelist 
    183180      READ  ( numnam_ref, namsbc_blk, IOSTAT = ios, ERR = 901) 
    184181901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_blk in reference namelist' ) 
    185182      ! 
    186       REWIND( numnam_cfg )                !* Namelist namsbc_blk in configuration namelist : bulk parameters 
    187183      READ  ( numnam_cfg, namsbc_blk, IOSTAT = ios, ERR = 902 ) 
    188184902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_blk in configuration namelist' ) 
     
    192188      !                             !** initialization of the chosen bulk formulae (+ check) 
    193189      !                                   !* select the bulk chosen in the namelist and check the choice 
    194                                                                ioptio = 0 
    195       IF( ln_NCAR      ) THEN   ;   nblk =  np_NCAR        ;   ioptio = ioptio + 1   ;   ENDIF 
    196       IF( ln_COARE_3p0 ) THEN   ;   nblk =  np_COARE_3p0   ;   ioptio = ioptio + 1   ;   ENDIF 
    197       IF( ln_COARE_3p5 ) THEN   ;   nblk =  np_COARE_3p5   ;   ioptio = ioptio + 1   ;   ENDIF 
    198       IF( ln_ECMWF     ) THEN   ;   nblk =  np_ECMWF       ;   ioptio = ioptio + 1   ;   ENDIF 
    199       ! 
     190      ioptio = 0 
     191      IF( ln_NCAR      ) THEN 
     192         nblk =  np_NCAR        ;   ioptio = ioptio + 1 
     193      ENDIF 
     194      IF( ln_COARE_3p0 ) THEN 
     195         nblk =  np_COARE_3p0   ;   ioptio = ioptio + 1 
     196      ENDIF 
     197      IF( ln_COARE_3p6 ) THEN 
     198         nblk =  np_COARE_3p6   ;   ioptio = ioptio + 1 
     199      ENDIF 
     200      IF( ln_ECMWF     ) THEN 
     201         nblk =  np_ECMWF       ;   ioptio = ioptio + 1 
     202      ENDIF 
    200203      IF( ioptio /= 1 )   CALL ctl_stop( 'sbc_blk_init: Choose one and only one bulk algorithm' ) 
     204 
     205      !                             !** initialization of the cool-skin / warm-layer parametrization 
     206      IF( ln_skin_cs .OR. ln_skin_wl ) THEN 
     207         !! Some namelist sanity tests: 
     208         IF( ln_NCAR )      & 
     209            & CALL ctl_stop( 'sbc_blk_init: Cool-skin/warm-layer param. not compatible with NCAR algorithm' ) 
     210         IF( nn_fsbc /= 1 ) & 
     211            & CALL ctl_stop( 'sbc_blk_init: Please set "nn_fsbc" to 1 when using cool-skin/warm-layer param.') 
     212      END IF 
     213 
     214      IF( ln_skin_wl ) THEN 
     215         !! Check if the frequency of downwelling solar flux input makes sense and if ln_dm2dc=T if it is daily! 
     216         IF( (sn_qsr%freqh  < 0.).OR.(sn_qsr%freqh  > 24.) ) & 
     217            & CALL ctl_stop( 'sbc_blk_init: Warm-layer param. (ln_skin_wl) not compatible with freq. of solar flux > daily' ) 
     218         IF( (sn_qsr%freqh == 24.).AND.(.NOT. ln_dm2dc) ) & 
     219            & CALL ctl_stop( 'sbc_blk_init: Please set ln_dm2dc=T for warm-layer param. (ln_skin_wl) to work properly' ) 
     220      END IF 
     221 
     222      ioptio = 0 
     223      IF( ln_humi_sph ) THEN 
     224         nhumi =  np_humi_sph    ;   ioptio = ioptio + 1 
     225      ENDIF 
     226      IF( ln_humi_dpt ) THEN 
     227         nhumi =  np_humi_dpt    ;   ioptio = ioptio + 1 
     228      ENDIF 
     229      IF( ln_humi_rlh ) THEN 
     230         nhumi =  np_humi_rlh    ;   ioptio = ioptio + 1 
     231      ENDIF 
     232      IF( ioptio /= 1 )   CALL ctl_stop( 'sbc_blk_init: Choose one and only one type of air humidity' ) 
    201233      ! 
    202234      IF( ln_dm2dc ) THEN                 !* check: diurnal cycle on Qsr 
    203235         IF( sn_qsr%freqh /= 24. )   CALL ctl_stop( 'sbc_blk_init: ln_dm2dc=T only with daily short-wave input' ) 
    204          IF( sn_qsr%ln_tint ) THEN  
     236         IF( sn_qsr%ln_tint ) THEN 
    205237            CALL ctl_warn( 'sbc_blk_init: ln_dm2dc=T daily qsr time interpolation done by sbcdcy module',   & 
    206238               &           '              ==> We force time interpolation = .false. for qsr' ) 
     
    210242      !                                   !* set the bulk structure 
    211243      !                                      !- store namelist information in an array 
     244      IF( ln_blk ) jpfld = 9 
     245      IF( ln_abl ) jpfld = 11 
     246      ALLOCATE( slf_i(jpfld) ) 
     247      ! 
    212248      slf_i(jp_wndi) = sn_wndi   ;   slf_i(jp_wndj) = sn_wndj 
    213249      slf_i(jp_qsr ) = sn_qsr    ;   slf_i(jp_qlw ) = sn_qlw 
    214250      slf_i(jp_tair) = sn_tair   ;   slf_i(jp_humi) = sn_humi 
    215251      slf_i(jp_prec) = sn_prec   ;   slf_i(jp_snow) = sn_snow 
    216       slf_i(jp_slp)  = sn_slp    ;   slf_i(jp_tdif) = sn_tdif 
    217       ! 
    218       lhftau = ln_taudif                     !- add an extra field if HF stress is used 
    219       jfld = jpfld - COUNT( (/.NOT.lhftau/) ) 
     252      slf_i(jp_slp ) = sn_slp 
     253      IF( ln_abl ) THEN 
     254         slf_i(jp_hpgi) = sn_hpgi   ;   slf_i(jp_hpgj) = sn_hpgj 
     255      END IF 
    220256      ! 
    221257      !                                      !- allocate the bulk structure 
    222       ALLOCATE( sf(jfld), STAT=ierror ) 
     258      ALLOCATE( sf(jpfld), STAT=ierror ) 
    223259      IF( ierror > 0 )   CALL ctl_stop( 'STOP', 'sbc_blk_init: unable to allocate sf structure' ) 
    224       DO ifpr= 1, jfld 
    225          ALLOCATE( sf(ifpr)%fnow(jpi,jpj,1) ) 
    226          IF( slf_i(ifpr)%ln_tint )   ALLOCATE( sf(ifpr)%fdta(jpi,jpj,1,2) ) 
    227          IF( slf_i(ifpr)%freqh > 0. .AND. MOD( NINT(3600. * slf_i(ifpr)%freqh), nn_fsbc * NINT(rdt) ) /= 0 )   & 
    228             &  CALL ctl_warn( 'sbc_blk_init: sbcmod timestep rdt*nn_fsbc is NOT a submultiple of atmospheric forcing frequency.',   & 
    229             &                 '               This is not ideal. You should consider changing either rdt or nn_fsbc value...' ) 
    230  
     260      ! 
     261      DO jfpr= 1, jpfld 
     262         ! 
     263         IF( TRIM(sf(jfpr)%clrootname) == 'NOT USED' ) THEN    !--  not used field  --!   (only now allocated and set to zero) 
     264            ALLOCATE( sf(jfpr)%fnow(jpi,jpj,1) ) 
     265            sf(jfpr)%fnow(:,:,1) = 0._wp 
     266         ELSE                                                  !-- used field  --! 
     267            IF(   ln_abl    .AND.                                                      & 
     268               &    ( jfpr == jp_wndi .OR. jfpr == jp_wndj .OR. jfpr == jp_humi .OR.   & 
     269               &      jfpr == jp_hpgi .OR. jfpr == jp_hpgj .OR. jfpr == jp_tair     )  ) THEN   ! ABL: some fields are 3D input 
     270               ALLOCATE( sf(jfpr)%fnow(jpi,jpj,jpka) ) 
     271               IF( slf_i(jfpr)%ln_tint )   ALLOCATE( sf(jfpr)%fdta(jpi,jpj,jpka,2) ) 
     272            ELSE                                                                                ! others or Bulk fields are 2D fiels 
     273               ALLOCATE( sf(jfpr)%fnow(jpi,jpj,1) ) 
     274               IF( slf_i(jfpr)%ln_tint )   ALLOCATE( sf(jfpr)%fdta(jpi,jpj,1,2) ) 
     275            ENDIF 
     276            ! 
     277            IF( slf_i(jfpr)%freqh > 0. .AND. MOD( NINT(3600. * slf_i(jfpr)%freqh), nn_fsbc * NINT(rdt) ) /= 0 )   & 
     278               &  CALL ctl_warn( 'sbc_blk_init: sbcmod timestep rdt*nn_fsbc is NOT a submultiple of atmospheric forcing frequency.',   & 
     279               &                 '               This is not ideal. You should consider changing either rdt or nn_fsbc value...' ) 
     280         ENDIF 
    231281      END DO 
    232282      !                                      !- fill the bulk structure with namelist informations 
    233283      CALL fld_fill( sf, slf_i, cn_dir, 'sbc_blk_init', 'surface boundary condition -- bulk formulae', 'namsbc_blk' ) 
    234284      ! 
    235       IF ( ln_wave ) THEN 
    236       !Activated wave module but neither drag nor stokes drift activated 
    237          IF ( .NOT.(ln_cdgw .OR. ln_sdw .OR. ln_tauwoc .OR. ln_stcor ) )   THEN 
     285      IF( ln_wave ) THEN 
     286         !Activated wave module but neither drag nor stokes drift activated 
     287         IF( .NOT.(ln_cdgw .OR. ln_sdw .OR. ln_tauwoc .OR. ln_stcor ) )   THEN 
    238288            CALL ctl_stop( 'STOP',  'Ask for wave coupling but ln_cdgw=F, ln_sdw=F, ln_tauwoc=F, ln_stcor=F' ) 
    239       !drag coefficient read from wave model definable only with mfs bulk formulae and core  
    240          ELSEIF (ln_cdgw .AND. .NOT. ln_NCAR )       THEN        
    241              CALL ctl_stop( 'drag coefficient read from wave model definable only with NCAR and CORE bulk formulae') 
    242          ELSEIF (ln_stcor .AND. .NOT. ln_sdw)                             THEN 
    243              CALL ctl_stop( 'Stokes-Coriolis term calculated only if activated Stokes Drift ln_sdw=T') 
     289            !drag coefficient read from wave model definable only with mfs bulk formulae and core 
     290         ELSEIF(ln_cdgw .AND. .NOT. ln_NCAR )       THEN 
     291            CALL ctl_stop( 'drag coefficient read from wave model definable only with NCAR and CORE bulk formulae') 
     292         ELSEIF(ln_stcor .AND. .NOT. ln_sdw)                             THEN 
     293            CALL ctl_stop( 'Stokes-Coriolis term calculated only if activated Stokes Drift ln_sdw=T') 
    244294         ENDIF 
    245295      ELSE 
    246       IF ( ln_cdgw .OR. ln_sdw .OR. ln_tauwoc .OR. ln_stcor )                &  
    247          &   CALL ctl_stop( 'Not Activated Wave Module (ln_wave=F) but asked coupling ',    & 
    248          &                  'with drag coefficient (ln_cdgw =T) '  ,                        & 
    249          &                  'or Stokes Drift (ln_sdw=T) ' ,                                 & 
    250          &                  'or ocean stress modification due to waves (ln_tauwoc=T) ',      &   
    251          &                  'or Stokes-Coriolis term (ln_stcori=T)'  ) 
    252       ENDIF  
    253       ! 
    254       !            
     296         IF( ln_cdgw .OR. ln_sdw .OR. ln_tauwoc .OR. ln_stcor )                & 
     297            &   CALL ctl_stop( 'Not Activated Wave Module (ln_wave=F) but asked coupling ',    & 
     298            &                  'with drag coefficient (ln_cdgw =T) '  ,                        & 
     299            &                  'or Stokes Drift (ln_sdw=T) ' ,                                 & 
     300            &                  'or ocean stress modification due to waves (ln_tauwoc=T) ',      & 
     301            &                  'or Stokes-Coriolis term (ln_stcori=T)'  ) 
     302      ENDIF 
     303      ! 
     304      IF( ln_abl ) THEN       ! ABL: read 3D fields for wind, temperature, humidity and pressure gradient 
     305         rn_zqt = ght_abl(2)          ! set the bulk altitude to ABL first level 
     306         rn_zu  = ght_abl(2) 
     307         IF(lwp) WRITE(numout,*) 
     308         IF(lwp) WRITE(numout,*) '   ABL formulation: overwrite rn_zqt & rn_zu with ABL first level altitude' 
     309      ENDIF 
     310      ! 
     311      ! set transfer coefficients to default sea-ice values 
     312      Cd_ice(:,:) = rCd_ice 
     313      Ch_ice(:,:) = rCd_ice 
     314      Ce_ice(:,:) = rCd_ice 
     315      ! 
    255316      IF(lwp) THEN                     !** Control print 
    256317         ! 
    257          WRITE(numout,*)                  !* namelist  
     318         WRITE(numout,*)                  !* namelist 
    258319         WRITE(numout,*) '   Namelist namsbc_blk (other than data information):' 
    259320         WRITE(numout,*) '      "NCAR"      algorithm   (Large and Yeager 2008)     ln_NCAR      = ', ln_NCAR 
    260321         WRITE(numout,*) '      "COARE 3.0" algorithm   (Fairall et al. 2003)       ln_COARE_3p0 = ', ln_COARE_3p0 
    261          WRITE(numout,*) '      "COARE 3.5" algorithm   (Edson et al. 2013)         ln_COARE_3p5 = ', ln_COARE_3p0 
    262          WRITE(numout,*) '      "ECMWF"     algorithm   (IFS cycle 31)              ln_ECMWF     = ', ln_ECMWF 
    263          WRITE(numout,*) '      add High freq.contribution to the stress module     ln_taudif    = ', ln_taudif 
     322         WRITE(numout,*) '      "COARE 3.6" algorithm (Fairall 2018 + Edson al 2013)ln_COARE_3p6 = ', ln_COARE_3p6 
     323         WRITE(numout,*) '      "ECMWF"     algorithm   (IFS cycle 45r1)            ln_ECMWF     = ', ln_ECMWF 
    264324         WRITE(numout,*) '      Air temperature and humidity reference height (m)   rn_zqt       = ', rn_zqt 
    265325         WRITE(numout,*) '      Wind vector reference height (m)                    rn_zu        = ', rn_zu 
     
    275335         CASE( np_NCAR      )   ;   WRITE(numout,*) '   ==>>>   "NCAR" algorithm        (Large and Yeager 2008)' 
    276336         CASE( np_COARE_3p0 )   ;   WRITE(numout,*) '   ==>>>   "COARE 3.0" algorithm   (Fairall et al. 2003)' 
    277          CASE( np_COARE_3p5 )   ;   WRITE(numout,*) '   ==>>>   "COARE 3.5" algorithm   (Edson et al. 2013)' 
    278          CASE( np_ECMWF     )   ;   WRITE(numout,*) '   ==>>>   "ECMWF" algorithm       (IFS cycle 31)' 
     337         CASE( np_COARE_3p6 )   ;   WRITE(numout,*) '   ==>>>   "COARE 3.6" algorithm (Fairall 2018+Edson et al. 2013)' 
     338         CASE( np_ECMWF     )   ;   WRITE(numout,*) '   ==>>>   "ECMWF" algorithm       (IFS cycle 45r1)' 
    279339         END SELECT 
    280340         ! 
     341         WRITE(numout,*) 
     342         WRITE(numout,*) '      use cool-skin  parameterization (SSST)  ln_skin_cs  = ', ln_skin_cs 
     343         WRITE(numout,*) '      use warm-layer parameterization (SSST)  ln_skin_wl  = ', ln_skin_wl 
     344         ! 
     345         WRITE(numout,*) 
     346         SELECT CASE( nhumi )              !* Print the choice of air humidity 
     347         CASE( np_humi_sph )   ;   WRITE(numout,*) '   ==>>>   air humidity is SPECIFIC HUMIDITY     [kg/kg]' 
     348         CASE( np_humi_dpt )   ;   WRITE(numout,*) '   ==>>>   air humidity is DEW-POINT TEMPERATURE [K]' 
     349         CASE( np_humi_rlh )   ;   WRITE(numout,*) '   ==>>>   air humidity is RELATIVE HUMIDITY     [%]' 
     350         END SELECT 
     351         ! 
    281352      ENDIF 
    282353      ! 
     
    291362      !!              (momentum, heat, freshwater and runoff) 
    292363      !! 
    293       !! ** Method  : (1) READ each fluxes in NetCDF files: 
    294       !!      the 10m wind velocity (i-component) (m/s)    at T-point 
    295       !!      the 10m wind velocity (j-component) (m/s)    at T-point 
    296       !!      the 10m or 2m specific humidity     ( % ) 
    297       !!      the solar heat                      (W/m2) 
    298       !!      the Long wave                       (W/m2) 
    299       !!      the 10m or 2m air temperature       (Kelvin) 
    300       !!      the total precipitation (rain+snow) (Kg/m2/s) 
    301       !!      the snow (solid prcipitation)       (kg/m2/s) 
    302       !!      the tau diff associated to HF tau   (N/m2)   at T-point   (ln_taudif=T) 
    303       !!              (2) CALL blk_oce 
     364      !! ** Method  : 
     365      !!              (1) READ each fluxes in NetCDF files: 
     366      !!      the wind velocity (i-component) at z=rn_zu  (m/s) at T-point 
     367      !!      the wind velocity (j-component) at z=rn_zu  (m/s) at T-point 
     368      !!      the specific humidity           at z=rn_zqt (kg/kg) 
     369      !!      the air temperature             at z=rn_zqt (Kelvin) 
     370      !!      the solar heat                              (W/m2) 
     371      !!      the Long wave                               (W/m2) 
     372      !!      the total precipitation (rain+snow)         (Kg/m2/s) 
     373      !!      the snow (solid precipitation)              (kg/m2/s) 
     374      !!      ABL dynamical forcing (i/j-components of either hpg or geostrophic winds) 
     375      !!              (2) CALL blk_oce_1 and blk_oce_2 
    304376      !! 
    305377      !!      C A U T I O N : never mask the surface stress fields 
     
    318390      !!---------------------------------------------------------------------- 
    319391      INTEGER, INTENT(in) ::   kt   ! ocean time step 
    320       !!--------------------------------------------------------------------- 
     392      !!---------------------------------------------------------------------- 
     393      REAL(wp), DIMENSION(jpi,jpj) ::   zssq, zcd_du, zsen, zevp 
     394      REAL(wp) :: ztmp 
     395      !!---------------------------------------------------------------------- 
    321396      ! 
    322397      CALL fld_read( kt, nn_fsbc, sf )             ! input fields provided at the current time-step 
    323       ! 
     398 
     399      ! Sanity/consistence test on humidity at first time step to detect potential screw-up: 
     400      IF( kt == nit000 ) THEN 
     401         IF(lwp) WRITE(numout,*) '' 
     402#if defined key_agrif 
     403         IF(lwp) WRITE(numout,*) ' === AGRIF => Sanity/consistence test on air humidity SKIPPED! :( ===' 
     404#else 
     405         ztmp = SUM(tmask(:,:,1)) ! number of ocean points on local proc domain 
     406         IF( ztmp > 8._wp ) THEN ! test only on proc domains with at least 8 ocean points! 
     407            ztmp = SUM(sf(jp_humi)%fnow(:,:,1)*tmask(:,:,1))/ztmp ! mean humidity over ocean on proc 
     408            SELECT CASE( nhumi ) 
     409            CASE( np_humi_sph ) ! specific humidity => expect: 0. <= something < 0.065 [kg/kg] (0.061 is saturation at 45degC !!!) 
     410               IF(  (ztmp < 0._wp) .OR. (ztmp > 0.065)  ) ztmp = -1._wp 
     411            CASE( np_humi_dpt ) ! dew-point temperature => expect: 110. <= something < 320. [K] 
     412               IF( (ztmp < 110._wp).OR.(ztmp > 320._wp) ) ztmp = -1._wp 
     413            CASE( np_humi_rlh ) ! relative humidity => expect: 0. <= something < 100. [%] 
     414               IF(  (ztmp < 0._wp) .OR.(ztmp > 100._wp) ) ztmp = -1._wp 
     415            END SELECT 
     416            IF(ztmp < 0._wp) THEN 
     417               IF (lwp) WRITE(numout,'("   Mean humidity value found on proc #",i6.6," is: ",f10.5)') narea, ztmp 
     418               CALL ctl_stop( 'STOP', 'Something is wrong with air humidity!!!', & 
     419                  &   ' ==> check the unit in your input files'       , & 
     420                  &   ' ==> check consistence of namelist choice: specific? relative? dew-point?', & 
     421                  &   ' ==> ln_humi_sph -> [kg/kg] | ln_humi_rlh -> [%] | ln_humi_dpt -> [K] !!!' ) 
     422            END IF 
     423         END IF 
     424         IF(lwp) WRITE(numout,*) ' === Sanity/consistence test on air humidity sucessfuly passed! ===' 
     425#endif 
     426         IF(lwp) WRITE(numout,*) '' 
     427      END IF !IF( kt == nit000 ) 
    324428      !                                            ! compute the surface ocean fluxes using bulk formulea 
    325       IF( MOD( kt - 1, nn_fsbc ) == 0 )   CALL blk_oce( kt, sf, sst_m, ssu_m, ssv_m ) 
    326  
     429      IF( MOD( kt - 1, nn_fsbc ) == 0 ) THEN 
     430         CALL blk_oce_1( kt, sf(jp_wndi)%fnow(:,:,1), sf(jp_wndj)%fnow(:,:,1),   &   !   <<= in 
     431            &                sf(jp_tair)%fnow(:,:,1), sf(jp_humi)%fnow(:,:,1),   &   !   <<= in 
     432            &                sf(jp_slp )%fnow(:,:,1), sst_m, ssu_m, ssv_m,       &   !   <<= in 
     433            &                sf(jp_qsr )%fnow(:,:,1), sf(jp_qlw )%fnow(:,:,1),   &   !   <<= in (wl/cs) 
     434            &                tsk_m, zssq, zcd_du, zsen, zevp )                       !   =>> out 
     435 
     436         CALL blk_oce_2(     sf(jp_tair)%fnow(:,:,1), sf(jp_qsr )%fnow(:,:,1),   &   !   <<= in 
     437            &                sf(jp_qlw )%fnow(:,:,1), sf(jp_prec)%fnow(:,:,1),   &   !   <<= in 
     438            &                sf(jp_snow)%fnow(:,:,1), tsk_m,                     &   !   <<= in 
     439            &                zsen, zevp )                                            !   <=> in out 
     440      ENDIF 
     441      ! 
    327442#if defined key_cice 
    328443      IF( MOD( kt - 1, nn_fsbc ) == 0 )   THEN 
    329444         qlw_ice(:,:,1)   = sf(jp_qlw )%fnow(:,:,1) 
    330          IF( ln_dm2dc ) THEN ; qsr_ice(:,:,1) = sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) 
    331          ELSE                ; qsr_ice(:,:,1) =          sf(jp_qsr)%fnow(:,:,1)  
    332          ENDIF  
     445         IF( ln_dm2dc ) THEN 
     446            qsr_ice(:,:,1) = sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) 
     447         ELSE 
     448            qsr_ice(:,:,1) =          sf(jp_qsr)%fnow(:,:,1) 
     449         ENDIF 
    333450         tatm_ice(:,:)    = sf(jp_tair)%fnow(:,:,1) 
    334          qatm_ice(:,:)    = sf(jp_humi)%fnow(:,:,1) 
     451 
     452         SELECT CASE( nhumi ) 
     453         CASE( np_humi_sph ) 
     454            qatm_ice(:,:) =           sf(jp_humi)%fnow(:,:,1) 
     455         CASE( np_humi_dpt ) 
     456            qatm_ice(:,:) = q_sat(    sf(jp_humi)%fnow(:,:,1), sf(jp_slp)%fnow(:,:,1) ) 
     457         CASE( np_humi_rlh ) 
     458            qatm_ice(:,:) = q_air_rh( 0.01_wp*sf(jp_humi)%fnow(:,:,1), sf(jp_tair)%fnow(:,:,1), sf(jp_slp)%fnow(:,:,1)) !LB: 0.01 => RH is % percent in file 
     459         END SELECT 
     460 
    335461         tprecip(:,:)     = sf(jp_prec)%fnow(:,:,1) * rn_pfac 
    336462         sprecip(:,:)     = sf(jp_snow)%fnow(:,:,1) * rn_pfac 
     
    343469 
    344470 
    345    SUBROUTINE blk_oce( kt, sf, pst, pu, pv ) 
    346       !!--------------------------------------------------------------------- 
    347       !!                     ***  ROUTINE blk_oce  *** 
    348       !! 
    349       !! ** Purpose :   provide the momentum, heat and freshwater fluxes at 
    350       !!      the ocean surface at each time step 
    351       !! 
    352       !! ** Method  :   bulk formulea for the ocean using atmospheric 
    353       !!      fields read in sbc_read 
     471   SUBROUTINE blk_oce_1( kt, pwndi, pwndj , ptair, phumi, &  ! inp 
     472      &                  pslp , pst   , pu   , pv,        &  ! inp 
     473      &                  pqsr , pqlw  ,                   &  ! inp 
     474      &                  ptsk, pssq , pcd_du, psen , pevp   )  ! out 
     475      !!--------------------------------------------------------------------- 
     476      !!                     ***  ROUTINE blk_oce_1  *** 
     477      !! 
     478      !! ** Purpose :   if ln_blk=T, computes surface momentum, heat and freshwater fluxes 
     479      !!                if ln_abl=T, computes Cd x |U|, Ch x |U|, Ce x |U| for ABL integration 
     480      !! 
     481      !! ** Method  :   bulk formulae using atmospheric fields from : 
     482      !!                if ln_blk=T, atmospheric fields read in sbc_read 
     483      !!                if ln_abl=T, the ABL model at previous time-step 
     484      !! 
     485      !! ** Outputs : - pssq    : surface humidity used to compute latent heat flux (kg/kg) 
     486      !!              - pcd_du  : Cd x |dU| at T-points  (m/s) 
     487      !!              - psen    : Ch x |dU| at T-points  (m/s) 
     488      !!              - pevp    : Ce x |dU| at T-points  (m/s) 
     489      !!--------------------------------------------------------------------- 
     490      INTEGER , INTENT(in   )                 ::   kt     ! time step index 
     491      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pwndi  ! atmospheric wind at U-point              [m/s] 
     492      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pwndj  ! atmospheric wind at V-point              [m/s] 
     493      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   phumi  ! specific humidity at T-points            [kg/kg] 
     494      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   ptair  ! potential temperature at T-points        [Kelvin] 
     495      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pslp   ! sea-level pressure                       [Pa] 
     496      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pst    ! surface temperature                      [Celsius] 
     497      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pu     ! surface current at U-point (i-component) [m/s] 
     498      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pv     ! surface current at V-point (j-component) [m/s] 
     499      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pqsr   ! 
     500      REAL(wp), INTENT(in   ), DIMENSION(:,:) ::   pqlw   ! 
     501      REAL(wp), INTENT(  out), DIMENSION(:,:) ::   ptsk   ! skin temp. (or SST if CS & WL not used)  [Celsius] 
     502      REAL(wp), INTENT(  out), DIMENSION(:,:) ::   pssq   ! specific humidity at pst                 [kg/kg] 
     503      REAL(wp), INTENT(  out), DIMENSION(:,:) ::   pcd_du ! Cd x |dU| at T-points                    [m/s] 
     504      REAL(wp), INTENT(  out), DIMENSION(:,:) ::   psen   ! Ch x |dU| at T-points                    [m/s] 
     505      REAL(wp), INTENT(  out), DIMENSION(:,:) ::   pevp   ! Ce x |dU| at T-points                    [m/s] 
     506      ! 
     507      INTEGER  ::   ji, jj               ! dummy loop indices 
     508      REAL(wp) ::   zztmp                ! local variable 
     509      REAL(wp), DIMENSION(jpi,jpj) ::   zwnd_i, zwnd_j    ! wind speed components at T-point 
     510      REAL(wp), DIMENSION(jpi,jpj) ::   zU_zu             ! bulk wind speed at height zu  [m/s] 
     511      REAL(wp), DIMENSION(jpi,jpj) ::   ztpot             ! potential temperature of air at z=rn_zqt [K] 
     512      REAL(wp), DIMENSION(jpi,jpj) ::   zqair             ! specific humidity     of air at z=rn_zqt [kg/kg] 
     513      REAL(wp), DIMENSION(jpi,jpj) ::   zcd_oce           ! momentum transfert coefficient over ocean 
     514      REAL(wp), DIMENSION(jpi,jpj) ::   zch_oce           ! sensible heat transfert coefficient over ocean 
     515      REAL(wp), DIMENSION(jpi,jpj) ::   zce_oce           ! latent   heat transfert coefficient over ocean 
     516      REAL(wp), DIMENSION(jpi,jpj) ::   zqla              ! latent heat flux 
     517      REAL(wp), DIMENSION(jpi,jpj) ::   zztmp1, zztmp2 
     518      !!--------------------------------------------------------------------- 
     519      ! 
     520      ! local scalars ( place there for vector optimisation purposes) 
     521      !                           ! Temporary conversion from Celcius to Kelvin (and set minimum value far above 0 K) 
     522      ptsk(:,:) = pst(:,:) + rt0  ! by default: skin temperature = "bulk SST" (will remain this way if NCAR algorithm used!) 
     523 
     524      ! ----------------------------------------------------------------------------- ! 
     525      !      0   Wind components and module at T-point relative to the moving ocean   ! 
     526      ! ----------------------------------------------------------------------------- ! 
     527 
     528      ! ... components ( U10m - U_oce ) at T-point (unmasked) 
     529#if defined key_cyclone 
     530      zwnd_i(:,:) = 0._wp 
     531      zwnd_j(:,:) = 0._wp 
     532      CALL wnd_cyc( kt, zwnd_i, zwnd_j )    ! add analytical tropical cyclone (Vincent et al. JGR 2012) 
     533      DO_2D_00_00 
     534         pwndi(ji,jj) = pwndi(ji,jj) + zwnd_i(ji,jj) 
     535         pwndj(ji,jj) = pwndj(ji,jj) + zwnd_j(ji,jj) 
     536      END_2D 
     537#endif 
     538      DO_2D_00_00 
     539         zwnd_i(ji,jj) = (  pwndi(ji,jj) - rn_vfac * 0.5 * ( pu(ji-1,jj  ) + pu(ji,jj) )  ) 
     540         zwnd_j(ji,jj) = (  pwndj(ji,jj) - rn_vfac * 0.5 * ( pv(ji  ,jj-1) + pv(ji,jj) )  ) 
     541      END_2D 
     542      CALL lbc_lnk_multi( 'sbcblk', zwnd_i, 'T', -1., zwnd_j, 'T', -1. ) 
     543      ! ... scalar wind ( = | U10m - U_oce | ) at T-point (masked) 
     544      wndm(:,:) = SQRT(  zwnd_i(:,:) * zwnd_i(:,:)   & 
     545         &             + zwnd_j(:,:) * zwnd_j(:,:)  ) * tmask(:,:,1) 
     546 
     547      ! ----------------------------------------------------------------------------- ! 
     548      !      I   Solar FLUX                                                           ! 
     549      ! ----------------------------------------------------------------------------- ! 
     550 
     551      ! ocean albedo assumed to be constant + modify now Qsr to include the diurnal cycle                    ! Short Wave 
     552      zztmp = 1. - albo 
     553      IF( ln_dm2dc ) THEN 
     554         qsr(:,:) = zztmp * sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) * tmask(:,:,1) 
     555      ELSE 
     556         qsr(:,:) = zztmp *          sf(jp_qsr)%fnow(:,:,1)   * tmask(:,:,1) 
     557      ENDIF 
     558 
     559 
     560      ! ----------------------------------------------------------------------------- ! 
     561      !     II   Turbulent FLUXES                                                     ! 
     562      ! ----------------------------------------------------------------------------- ! 
     563 
     564      ! specific humidity at SST 
     565      pssq(:,:) = rdct_qsat_salt * q_sat( ptsk(:,:), pslp(:,:) ) 
     566 
     567      IF( ln_skin_cs .OR. ln_skin_wl ) THEN 
     568         !! Backup "bulk SST" and associated spec. hum. 
     569         zztmp1(:,:) = ptsk(:,:) 
     570         zztmp2(:,:) = pssq(:,:) 
     571      ENDIF 
     572 
     573      ! specific humidity of air at "rn_zqt" m above the sea 
     574      SELECT CASE( nhumi ) 
     575      CASE( np_humi_sph ) 
     576         zqair(:,:) = phumi(:,:)      ! what we read in file is already a spec. humidity! 
     577      CASE( np_humi_dpt ) 
     578         !IF(lwp) WRITE(numout,*) ' *** blk_oce => computing q_air out of d_air and slp !' !LBrm 
     579         zqair(:,:) = q_sat( phumi(:,:), pslp(:,:) ) 
     580      CASE( np_humi_rlh ) 
     581         !IF(lwp) WRITE(numout,*) ' *** blk_oce => computing q_air out of RH, t_air and slp !' !LBrm 
     582         zqair(:,:) = q_air_rh( 0.01_wp*phumi(:,:), ptair(:,:), pslp(:,:) ) !LB: 0.01 => RH is % percent in file 
     583      END SELECT 
     584      ! 
     585      ! potential temperature of air at "rn_zqt" m above the sea 
     586      IF( ln_abl ) THEN 
     587         ztpot = ptair(:,:) 
     588      ELSE 
     589         ! Estimate of potential temperature at z=rn_zqt, based on adiabatic lapse-rate 
     590         !    (see Josey, Gulev & Yu, 2013) / doi=10.1016/B978-0-12-391851-2.00005-2 
     591         !    (since reanalysis products provide T at z, not theta !) 
     592         !#LB: because AGRIF hates functions that return something else than a scalar, need to 
     593         !     use scalar version of gamma_moist() ... 
     594         DO_2D_11_11 
     595            ztpot(ji,jj) = ptair(ji,jj) + gamma_moist( ptair(ji,jj), zqair(ji,jj) ) * rn_zqt 
     596         END_2D 
     597      ENDIF 
     598 
     599 
     600 
     601      !! Time to call the user-selected bulk parameterization for 
     602      !!  ==  transfer coefficients  ==!   Cd, Ch, Ce at T-point, and more... 
     603      SELECT CASE( nblk ) 
     604 
     605      CASE( np_NCAR      ) 
     606         CALL turb_ncar    ( rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm,                              & 
     607            &                zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce ) 
     608 
     609      CASE( np_COARE_3p0 ) 
     610         CALL turb_coare3p0 ( kt, rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm, ln_skin_cs, ln_skin_wl, & 
     611            &                zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce,   & 
     612            &                Qsw=qsr(:,:), rad_lw=pqlw(:,:), slp=pslp(:,:) ) 
     613 
     614      CASE( np_COARE_3p6 ) 
     615         CALL turb_coare3p6 ( kt, rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm, ln_skin_cs, ln_skin_wl, & 
     616            &                zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce,   & 
     617            &                Qsw=qsr(:,:), rad_lw=pqlw(:,:), slp=pslp(:,:) ) 
     618 
     619      CASE( np_ECMWF     ) 
     620         CALL turb_ecmwf   ( kt, rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm, ln_skin_cs, ln_skin_wl,  & 
     621            &                zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce,   & 
     622            &                Qsw=qsr(:,:), rad_lw=pqlw(:,:), slp=pslp(:,:) ) 
     623 
     624      CASE DEFAULT 
     625         CALL ctl_stop( 'STOP', 'sbc_oce: non-existing bulk formula selected' ) 
     626 
     627      END SELECT 
     628 
     629      IF( ln_skin_cs .OR. ln_skin_wl ) THEN 
     630         !! ptsk and pssq have been updated!!! 
     631         !! 
     632         !! In the presence of sea-ice we forget about the cool-skin/warm-layer update of ptsk and pssq: 
     633         WHERE ( fr_i(:,:) > 0.001_wp ) 
     634            ! sea-ice present, we forget about the update, using what we backed up before call to turb_*() 
     635            ptsk(:,:) = zztmp1(:,:) 
     636            pssq(:,:) = zztmp2(:,:) 
     637         END WHERE 
     638      END IF 
     639 
     640      !!      CALL iom_put( "Cd_oce", zcd_oce)  ! output value of pure ocean-atm. transfer coef. 
     641      !!      CALL iom_put( "Ch_oce", zch_oce)  ! output value of pure ocean-atm. transfer coef. 
     642 
     643      IF( ABS(rn_zu - rn_zqt) < 0.1_wp ) THEN 
     644         !! If zu == zt, then ensuring once for all that: 
     645         t_zu(:,:) = ztpot(:,:) 
     646         q_zu(:,:) = zqair(:,:) 
     647      ENDIF 
     648 
     649 
     650      !  Turbulent fluxes over ocean  => BULK_FORMULA @ sbcblk_phy.F90 
     651      ! ------------------------------------------------------------- 
     652 
     653      IF( ln_abl ) THEN         !==  ABL formulation  ==!   multiplication by rho_air and turbulent fluxes computation done in ablstp 
     654         !! FL do we need this multiplication by tmask ... ??? 
     655         DO_2D_11_11 
     656            zztmp = zU_zu(ji,jj) !* tmask(ji,jj,1) 
     657            wndm(ji,jj)   = zztmp                   ! Store zU_zu in wndm to compute ustar2 in ablmod 
     658            pcd_du(ji,jj) = zztmp * zcd_oce(ji,jj) 
     659            psen(ji,jj)   = zztmp * zch_oce(ji,jj) 
     660            pevp(ji,jj)   = zztmp * zce_oce(ji,jj) 
     661         END_2D 
     662      ELSE                      !==  BLK formulation  ==!   turbulent fluxes computation 
     663         CALL BULK_FORMULA( rn_zu, ptsk(:,:), pssq(:,:), t_zu(:,:), q_zu(:,:), & 
     664            &               zcd_oce(:,:), zch_oce(:,:), zce_oce(:,:),         & 
     665            &               wndm(:,:), zU_zu(:,:), pslp(:,:),                 & 
     666            &               taum(:,:), psen(:,:), zqla(:,:),                  & 
     667            &               pEvap=pevp(:,:), prhoa=rhoa(:,:) ) 
     668 
     669         zqla(:,:) = zqla(:,:) * tmask(:,:,1) 
     670         psen(:,:) = psen(:,:) * tmask(:,:,1) 
     671         taum(:,:) = taum(:,:) * tmask(:,:,1) 
     672         pevp(:,:) = pevp(:,:) * tmask(:,:,1) 
     673 
     674         ! Tau i and j component on T-grid points, using array "zcd_oce" as a temporary array... 
     675         zcd_oce = 0._wp 
     676         WHERE ( wndm > 0._wp ) zcd_oce = taum / wndm 
     677         zwnd_i = zcd_oce * zwnd_i 
     678         zwnd_j = zcd_oce * zwnd_j 
     679 
     680         CALL iom_put( "taum_oce", taum )   ! output wind stress module 
     681 
     682         ! ... utau, vtau at U- and V_points, resp. 
     683         !     Note the use of 0.5*(2-umask) in order to unmask the stress along coastlines 
     684         !     Note the use of MAX(tmask(i,j),tmask(i+1,j) is to mask tau over ice shelves 
     685         DO_2D_10_10 
     686            utau(ji,jj) = 0.5 * ( 2. - umask(ji,jj,1) ) * ( zwnd_i(ji,jj) + zwnd_i(ji+1,jj  ) ) & 
     687               &          * MAX(tmask(ji,jj,1),tmask(ji+1,jj,1)) 
     688            vtau(ji,jj) = 0.5 * ( 2. - vmask(ji,jj,1) ) * ( zwnd_j(ji,jj) + zwnd_j(ji  ,jj+1) ) & 
     689               &          * MAX(tmask(ji,jj,1),tmask(ji,jj+1,1)) 
     690         END_2D 
     691         CALL lbc_lnk_multi( 'sbcblk', utau, 'U', -1., vtau, 'V', -1. ) 
     692 
     693         IF(sn_cfctl%l_prtctl) THEN 
     694            CALL prt_ctl( tab2d_1=wndm  , clinfo1=' blk_oce_1: wndm   : ') 
     695            CALL prt_ctl( tab2d_1=utau  , clinfo1=' blk_oce_1: utau   : ', mask1=umask,   & 
     696               &          tab2d_2=vtau  , clinfo2='            vtau   : ', mask2=vmask ) 
     697         ENDIF 
     698         ! 
     699      ENDIF !IF( ln_abl ) 
     700       
     701      ptsk(:,:) = ( ptsk(:,:) - rt0 ) * tmask(:,:,1)  ! Back to Celsius 
     702             
     703      IF( ln_skin_cs .OR. ln_skin_wl ) THEN 
     704         CALL iom_put( "t_skin" ,  ptsk        )  ! T_skin in Celsius 
     705         CALL iom_put( "dt_skin" , ptsk - pst  )  ! T_skin - SST temperature difference... 
     706      ENDIF 
     707 
     708      IF(sn_cfctl%l_prtctl) THEN 
     709         CALL prt_ctl( tab2d_1=pevp  , clinfo1=' blk_oce_1: pevp   : ' ) 
     710         CALL prt_ctl( tab2d_1=psen  , clinfo1=' blk_oce_1: psen   : ' ) 
     711         CALL prt_ctl( tab2d_1=pssq  , clinfo1=' blk_oce_1: pssq   : ' ) 
     712      ENDIF 
     713      ! 
     714   END SUBROUTINE blk_oce_1 
     715 
     716 
     717   SUBROUTINE blk_oce_2( ptair, pqsr, pqlw, pprec,   &   ! <<= in 
     718      &                  psnow, ptsk, psen, pevp     )   ! <<= in 
     719      !!--------------------------------------------------------------------- 
     720      !!                     ***  ROUTINE blk_oce_2  *** 
     721      !! 
     722      !! ** Purpose :   finalize the momentum, heat and freshwater fluxes computation 
     723      !!                at the ocean surface at each time step knowing Cd, Ch, Ce and 
     724      !!                atmospheric variables (from ABL or external data) 
    354725      !! 
    355726      !! ** Outputs : - utau    : i-component of the stress at U-point  (N/m2) 
     
    360731      !!              - qns     : Non Solar heat flux over the ocean    (W/m2) 
    361732      !!              - emp     : evaporation minus precipitation       (kg/m2/s) 
    362       !! 
    363       !!  ** Nota  :   sf has to be a dummy argument for AGRIF on NEC 
    364       !!--------------------------------------------------------------------- 
    365       INTEGER  , INTENT(in   )                 ::   kt    ! time step index 
    366       TYPE(fld), INTENT(inout), DIMENSION(:)   ::   sf    ! input data 
    367       REAL(wp) , INTENT(in)   , DIMENSION(:,:) ::   pst   ! surface temperature                      [Celcius] 
    368       REAL(wp) , INTENT(in)   , DIMENSION(:,:) ::   pu    ! surface current at U-point (i-component) [m/s] 
    369       REAL(wp) , INTENT(in)   , DIMENSION(:,:) ::   pv    ! surface current at V-point (j-component) [m/s] 
     733      !!--------------------------------------------------------------------- 
     734      REAL(wp), INTENT(in), DIMENSION(:,:) ::   ptair 
     735      REAL(wp), INTENT(in), DIMENSION(:,:) ::   pqsr 
     736      REAL(wp), INTENT(in), DIMENSION(:,:) ::   pqlw 
     737      REAL(wp), INTENT(in), DIMENSION(:,:) ::   pprec 
     738      REAL(wp), INTENT(in), DIMENSION(:,:) ::   psnow 
     739      REAL(wp), INTENT(in), DIMENSION(:,:) ::   ptsk   ! SKIN surface temperature   [Celsius] 
     740      REAL(wp), INTENT(in), DIMENSION(:,:) ::   psen 
     741      REAL(wp), INTENT(in), DIMENSION(:,:) ::   pevp 
    370742      ! 
    371743      INTEGER  ::   ji, jj               ! dummy loop indices 
    372       REAL(wp) ::   zztmp                ! local variable 
    373       REAL(wp), DIMENSION(jpi,jpj) ::   zwnd_i, zwnd_j    ! wind speed components at T-point 
    374       REAL(wp), DIMENSION(jpi,jpj) ::   zsq               ! specific humidity at pst 
    375       REAL(wp), DIMENSION(jpi,jpj) ::   zqlw, zqsb        ! long wave and sensible heat fluxes 
    376       REAL(wp), DIMENSION(jpi,jpj) ::   zqla, zevap       ! latent heat fluxes and evaporation 
    377       REAL(wp), DIMENSION(jpi,jpj) ::   zst               ! surface temperature in Kelvin 
    378       REAL(wp), DIMENSION(jpi,jpj) ::   zU_zu             ! bulk wind speed at height zu  [m/s] 
    379       REAL(wp), DIMENSION(jpi,jpj) ::   ztpot             ! potential temperature of air at z=rn_zqt [K] 
    380       REAL(wp), DIMENSION(jpi,jpj) ::   zrhoa             ! density of air   [kg/m^3] 
     744      REAL(wp) ::   zztmp,zz1,zz2,zz3    ! local variable 
     745      REAL(wp), DIMENSION(jpi,jpj) ::   ztskk             ! skin temp. in Kelvin  
     746      REAL(wp), DIMENSION(jpi,jpj) ::   zqlw              ! long wave and sensible heat fluxes       
     747      REAL(wp), DIMENSION(jpi,jpj) ::   zqla              ! latent heat fluxes and evaporation 
    381748      !!--------------------------------------------------------------------- 
    382749      ! 
    383750      ! local scalars ( place there for vector optimisation purposes) 
    384       zst(:,:) = pst(:,:) + rt0      ! convert SST from Celcius to Kelvin (and set minimum value far above 0 K) 
    385  
     751 
     752 
     753      ztskk(:,:) = ptsk(:,:) + rt0  ! => ptsk in Kelvin rather than Celsius 
     754       
    386755      ! ----------------------------------------------------------------------------- ! 
    387       !      0   Wind components and module at T-point relative to the moving ocean   ! 
     756      !     III    Net longwave radiative FLUX                                        ! 
    388757      ! ----------------------------------------------------------------------------- ! 
    389758 
    390       ! ... components ( U10m - U_oce ) at T-point (unmasked) 
    391 !!gm    move zwnd_i (_j) set to zero  inside the key_cyclone ??? 
    392       zwnd_i(:,:) = 0._wp 
    393       zwnd_j(:,:) = 0._wp 
    394 #if defined key_cyclone 
    395       CALL wnd_cyc( kt, zwnd_i, zwnd_j )    ! add analytical tropical cyclone (Vincent et al. JGR 2012) 
    396       DO jj = 2, jpjm1 
    397          DO ji = fs_2, fs_jpim1   ! vect. opt. 
    398             sf(jp_wndi)%fnow(ji,jj,1) = sf(jp_wndi)%fnow(ji,jj,1) + zwnd_i(ji,jj) 
    399             sf(jp_wndj)%fnow(ji,jj,1) = sf(jp_wndj)%fnow(ji,jj,1) + zwnd_j(ji,jj) 
    400          END DO 
    401       END DO 
    402 #endif 
    403       DO jj = 2, jpjm1 
    404          DO ji = fs_2, fs_jpim1   ! vect. opt. 
    405             zwnd_i(ji,jj) = (  sf(jp_wndi)%fnow(ji,jj,1) - rn_vfac * 0.5 * ( pu(ji-1,jj  ) + pu(ji,jj) )  ) 
    406             zwnd_j(ji,jj) = (  sf(jp_wndj)%fnow(ji,jj,1) - rn_vfac * 0.5 * ( pv(ji  ,jj-1) + pv(ji,jj) )  ) 
    407          END DO 
    408       END DO 
    409       CALL lbc_lnk_multi( 'sbcblk', zwnd_i, 'T', -1., zwnd_j, 'T', -1. ) 
    410       ! ... scalar wind ( = | U10m - U_oce | ) at T-point (masked) 
    411       wndm(:,:) = SQRT(  zwnd_i(:,:) * zwnd_i(:,:)   & 
    412          &             + zwnd_j(:,:) * zwnd_j(:,:)  ) * tmask(:,:,1) 
     759      !! LB: now moved after Turbulent fluxes because must use the skin temperature rather that the SST 
     760      !! (ztskk is skin temperature if ln_skin_cs==.TRUE. .OR. ln_skin_wl==.TRUE.) 
     761      zqlw(:,:) = emiss_w * ( pqlw(:,:) - stefan*ztskk(:,:)*ztskk(:,:)*ztskk(:,:)*ztskk(:,:) ) * tmask(:,:,1)   ! Net radiative longwave flux 
     762 
     763      !  Latent flux over ocean 
     764      ! ----------------------- 
     765 
     766      ! use scalar version of L_vap() for AGRIF compatibility 
     767      DO_2D_11_11 
     768         zqla(ji,jj) = - L_vap( ztskk(ji,jj) ) * pevp(ji,jj)    ! Latent Heat flux !!GS: possibility to add a global qla to avoid recomputation after abl update 
     769      END_2D 
     770 
     771      IF(sn_cfctl%l_prtctl) THEN 
     772         CALL prt_ctl( tab2d_1=zqla  , clinfo1=' blk_oce_2: zqla   : ' ) 
     773         CALL prt_ctl( tab2d_1=zqlw  , clinfo1=' blk_oce_2: zqlw   : ', tab2d_2=qsr, clinfo2=' qsr : ' ) 
     774 
     775      ENDIF 
    413776 
    414777      ! ----------------------------------------------------------------------------- ! 
    415       !      I   Radiative FLUXES                                                     ! 
     778      !     IV    Total FLUXES                                                       ! 
    416779      ! ----------------------------------------------------------------------------- ! 
    417  
    418       ! ocean albedo assumed to be constant + modify now Qsr to include the diurnal cycle                    ! Short Wave 
    419       zztmp = 1. - albo 
    420       IF( ln_dm2dc ) THEN   ;   qsr(:,:) = zztmp * sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) * tmask(:,:,1) 
    421       ELSE                  ;   qsr(:,:) = zztmp *          sf(jp_qsr)%fnow(:,:,1)   * tmask(:,:,1) 
    422       ENDIF 
    423  
    424       zqlw(:,:) = (  sf(jp_qlw)%fnow(:,:,1) - Stef * zst(:,:)*zst(:,:)*zst(:,:)*zst(:,:)  ) * tmask(:,:,1)   ! Long  Wave 
    425  
    426       ! ----------------------------------------------------------------------------- ! 
    427       !     II    Turbulent FLUXES                                                    ! 
    428       ! ----------------------------------------------------------------------------- ! 
    429  
    430       ! ... specific humidity at SST and IST tmask( 
    431       zsq(:,:) = 0.98 * q_sat( zst(:,:), sf(jp_slp)%fnow(:,:,1) ) 
    432       !! 
    433       !! Estimate of potential temperature at z=rn_zqt, based on adiabatic lapse-rate 
    434       !!    (see Josey, Gulev & Yu, 2013) / doi=10.1016/B978-0-12-391851-2.00005-2 
    435       !!    (since reanalysis products provide T at z, not theta !) 
    436       ztpot = sf(jp_tair)%fnow(:,:,1) + gamma_moist( sf(jp_tair)%fnow(:,:,1), sf(jp_humi)%fnow(:,:,1) ) * rn_zqt 
    437  
    438       SELECT CASE( nblk )        !==  transfer coefficients  ==!   Cd, Ch, Ce at T-point 
    439       ! 
    440       CASE( np_NCAR      )   ;   CALL turb_ncar    ( rn_zqt, rn_zu, zst, ztpot, zsq, sf(jp_humi)%fnow, wndm,   &  ! NCAR-COREv2 
    441          &                                           Cd_atm, Ch_atm, Ce_atm, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce ) 
    442       CASE( np_COARE_3p0 )   ;   CALL turb_coare   ( rn_zqt, rn_zu, zst, ztpot, zsq, sf(jp_humi)%fnow, wndm,   &  ! COARE v3.0 
    443          &                                           Cd_atm, Ch_atm, Ce_atm, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce ) 
    444       CASE( np_COARE_3p5 )   ;   CALL turb_coare3p5( rn_zqt, rn_zu, zst, ztpot, zsq, sf(jp_humi)%fnow, wndm,   &  ! COARE v3.5 
    445          &                                           Cd_atm, Ch_atm, Ce_atm, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce ) 
    446       CASE( np_ECMWF     )   ;   CALL turb_ecmwf   ( rn_zqt, rn_zu, zst, ztpot, zsq, sf(jp_humi)%fnow, wndm,   &  ! ECMWF 
    447          &                                           Cd_atm, Ch_atm, Ce_atm, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce ) 
    448       CASE DEFAULT 
    449          CALL ctl_stop( 'STOP', 'sbc_oce: non-existing bulk formula selected' ) 
    450       END SELECT 
    451  
    452       !                          ! Compute true air density : 
    453       IF( ABS(rn_zu - rn_zqt) > 0.01 ) THEN     ! At zu: (probably useless to remove zrho*grav*rn_zu from SLP...) 
    454          zrhoa(:,:) = rho_air( t_zu(:,:)              , q_zu(:,:)              , sf(jp_slp)%fnow(:,:,1) ) 
    455       ELSE                                      ! At zt: 
    456          zrhoa(:,:) = rho_air( sf(jp_tair)%fnow(:,:,1), sf(jp_humi)%fnow(:,:,1), sf(jp_slp)%fnow(:,:,1) ) 
    457       END IF 
    458  
    459 !!      CALL iom_put( "Cd_oce", Cd_atm)  ! output value of pure ocean-atm. transfer coef. 
    460 !!      CALL iom_put( "Ch_oce", Ch_atm)  ! output value of pure ocean-atm. transfer coef. 
    461  
    462       DO jj = 1, jpj             ! tau module, i and j component 
    463          DO ji = 1, jpi 
    464             zztmp = zrhoa(ji,jj)  * zU_zu(ji,jj) * Cd_atm(ji,jj)   ! using bulk wind speed 
    465             taum  (ji,jj) = zztmp * wndm  (ji,jj) 
    466             zwnd_i(ji,jj) = zztmp * zwnd_i(ji,jj) 
    467             zwnd_j(ji,jj) = zztmp * zwnd_j(ji,jj) 
    468          END DO 
    469       END DO 
    470  
    471       !                          ! add the HF tau contribution to the wind stress module 
    472       IF( lhftau )   taum(:,:) = taum(:,:) + sf(jp_tdif)%fnow(:,:,1) 
    473  
    474       CALL iom_put( "taum_oce", taum )   ! output wind stress module 
    475  
    476       ! ... utau, vtau at U- and V_points, resp. 
    477       !     Note the use of 0.5*(2-umask) in order to unmask the stress along coastlines 
    478       !     Note the use of MAX(tmask(i,j),tmask(i+1,j) is to mask tau over ice shelves 
    479       DO jj = 1, jpjm1 
    480          DO ji = 1, fs_jpim1 
    481             utau(ji,jj) = 0.5 * ( 2. - umask(ji,jj,1) ) * ( zwnd_i(ji,jj) + zwnd_i(ji+1,jj  ) ) & 
    482                &          * MAX(tmask(ji,jj,1),tmask(ji+1,jj,1)) 
    483             vtau(ji,jj) = 0.5 * ( 2. - vmask(ji,jj,1) ) * ( zwnd_j(ji,jj) + zwnd_j(ji  ,jj+1) ) & 
    484                &          * MAX(tmask(ji,jj,1),tmask(ji,jj+1,1)) 
    485          END DO 
    486       END DO 
    487       CALL lbc_lnk_multi( 'sbcblk', utau, 'U', -1., vtau, 'V', -1. ) 
    488  
    489       !  Turbulent fluxes over ocean 
    490       ! ----------------------------- 
    491  
    492       ! zqla used as temporary array, for rho*U (common term of bulk formulae): 
    493       zqla(:,:) = zrhoa(:,:) * zU_zu(:,:) * tmask(:,:,1) 
    494  
    495       IF( ABS( rn_zu - rn_zqt) < 0.01_wp ) THEN 
    496          !! q_air and t_air are given at 10m (wind reference height) 
    497          zevap(:,:) = rn_efac*MAX( 0._wp,             zqla(:,:)*Ce_atm(:,:)*(zsq(:,:) - sf(jp_humi)%fnow(:,:,1)) ) ! Evaporation, using bulk wind speed 
    498          zqsb (:,:) = cp_air(sf(jp_humi)%fnow(:,:,1))*zqla(:,:)*Ch_atm(:,:)*(zst(:,:) - ztpot(:,:)             )   ! Sensible Heat, using bulk wind speed 
    499       ELSE 
    500          !! q_air and t_air are not given at 10m (wind reference height) 
    501          ! Values of temp. and hum. adjusted to height of wind during bulk algorithm iteration must be used!!! 
    502          zevap(:,:) = rn_efac*MAX( 0._wp,             zqla(:,:)*Ce_atm(:,:)*(zsq(:,:) - q_zu(:,:) ) ) ! Evaporation, using bulk wind speed 
    503          zqsb (:,:) = cp_air(sf(jp_humi)%fnow(:,:,1))*zqla(:,:)*Ch_atm(:,:)*(zst(:,:) - t_zu(:,:) )   ! Sensible Heat, using bulk wind speed 
    504       ENDIF 
    505  
    506       zqla(:,:) = L_vap(zst(:,:)) * zevap(:,:)     ! Latent Heat flux 
    507  
    508  
    509       IF(ln_ctl) THEN 
    510          CALL prt_ctl( tab2d_1=zqla  , clinfo1=' blk_oce: zqla   : ', tab2d_2=Ce_atm , clinfo2=' Ce_oce  : ' ) 
    511          CALL prt_ctl( tab2d_1=zqsb  , clinfo1=' blk_oce: zqsb   : ', tab2d_2=Ch_atm , clinfo2=' Ch_oce  : ' ) 
    512          CALL prt_ctl( tab2d_1=zqlw  , clinfo1=' blk_oce: zqlw   : ', tab2d_2=qsr, clinfo2=' qsr : ' ) 
    513          CALL prt_ctl( tab2d_1=zsq   , clinfo1=' blk_oce: zsq    : ', tab2d_2=zst, clinfo2=' zst : ' ) 
    514          CALL prt_ctl( tab2d_1=utau  , clinfo1=' blk_oce: utau   : ', mask1=umask,   & 
    515             &          tab2d_2=vtau  , clinfo2=           ' vtau : ', mask2=vmask ) 
    516          CALL prt_ctl( tab2d_1=wndm  , clinfo1=' blk_oce: wndm   : ') 
    517          CALL prt_ctl( tab2d_1=zst   , clinfo1=' blk_oce: zst    : ') 
    518       ENDIF 
    519  
    520       ! ----------------------------------------------------------------------------- ! 
    521       !     III    Total FLUXES                                                       ! 
    522       ! ----------------------------------------------------------------------------- ! 
    523       ! 
    524       emp (:,:) = (  zevap(:,:)                                          &   ! mass flux (evap. - precip.) 
    525          &         - sf(jp_prec)%fnow(:,:,1) * rn_pfac  ) * tmask(:,:,1) 
    526       ! 
    527       qns(:,:) = zqlw(:,:) - zqsb(:,:) - zqla(:,:)                                &   ! Downward Non Solar 
    528          &     - sf(jp_snow)%fnow(:,:,1) * rn_pfac * rLfus                        &   ! remove latent melting heat for solid precip 
    529          &     - zevap(:,:) * pst(:,:) * rcp                                      &   ! remove evap heat content at SST 
    530          &     + ( sf(jp_prec)%fnow(:,:,1) - sf(jp_snow)%fnow(:,:,1) ) * rn_pfac  &   ! add liquid precip heat content at Tair 
    531          &     * ( sf(jp_tair)%fnow(:,:,1) - rt0 ) * rcp                          & 
    532          &     + sf(jp_snow)%fnow(:,:,1) * rn_pfac                                &   ! add solid  precip heat content at min(Tair,Tsnow) 
    533          &     * ( MIN( sf(jp_tair)%fnow(:,:,1), rt0 ) - rt0 ) * rcpi 
     780      ! 
     781      emp (:,:) = (  pevp(:,:)                                       &   ! mass flux (evap. - precip.) 
     782         &         - pprec(:,:) * rn_pfac  ) * tmask(:,:,1) 
     783      ! 
     784      qns(:,:) = zqlw(:,:) + psen(:,:) + zqla(:,:)                   &   ! Downward Non Solar 
     785         &     - psnow(:,:) * rn_pfac * rLfus                        &   ! remove latent melting heat for solid precip 
     786         &     - pevp(:,:) * ptsk(:,:) * rcp                         &   ! remove evap heat content at SST 
     787         &     + ( pprec(:,:) - psnow(:,:) ) * rn_pfac               &   ! add liquid precip heat content at Tair 
     788         &     * ( ptair(:,:) - rt0 ) * rcp                          & 
     789         &     + psnow(:,:) * rn_pfac                                &   ! add solid  precip heat content at min(Tair,Tsnow) 
     790         &     * ( MIN( ptair(:,:), rt0 ) - rt0 ) * rcpi 
    534791      qns(:,:) = qns(:,:) * tmask(:,:,1) 
    535792      ! 
    536793#if defined key_si3 
    537       qns_oce(:,:) = zqlw(:,:) - zqsb(:,:) - zqla(:,:)                                ! non solar without emp (only needed by SI3) 
     794      qns_oce(:,:) = zqlw(:,:) + psen(:,:) + zqla(:,:)                             ! non solar without emp (only needed by SI3) 
    538795      qsr_oce(:,:) = qsr(:,:) 
    539796#endif 
    540797      ! 
     798      CALL iom_put( "rho_air"  , rhoa*tmask(:,:,1) )       ! output air density [kg/m^3] 
     799      CALL iom_put( "evap_oce" , pevp )                    ! evaporation 
     800      CALL iom_put( "qlw_oce"  , zqlw )                    ! output downward longwave heat over the ocean 
     801      CALL iom_put( "qsb_oce"  , psen )                    ! output downward sensible heat over the ocean 
     802      CALL iom_put( "qla_oce"  , zqla )                    ! output downward latent   heat over the ocean 
     803      tprecip(:,:) = pprec(:,:) * rn_pfac * tmask(:,:,1)   ! output total precipitation [kg/m2/s] 
     804      sprecip(:,:) = psnow(:,:) * rn_pfac * tmask(:,:,1)   ! output solid precipitation [kg/m2/s] 
     805      CALL iom_put( 'snowpre', sprecip )                   ! Snow 
     806      CALL iom_put( 'precip' , tprecip )                   ! Total precipitation 
     807      ! 
    541808      IF ( nn_ice == 0 ) THEN 
    542          CALL iom_put( "qlw_oce" ,   zqlw )                 ! output downward longwave heat over the ocean 
    543          CALL iom_put( "qsb_oce" , - zqsb )                 ! output downward sensible heat over the ocean 
    544          CALL iom_put( "qla_oce" , - zqla )                 ! output downward latent   heat over the ocean 
    545          CALL iom_put( "qemp_oce",   qns-zqlw+zqsb+zqla )   ! output downward heat content of E-P over the ocean 
    546          CALL iom_put( "qns_oce" ,   qns  )                 ! output downward non solar heat over the ocean 
    547          CALL iom_put( "qsr_oce" ,   qsr  )                 ! output downward solar heat over the ocean 
    548          CALL iom_put( "qt_oce"  ,   qns+qsr )              ! output total downward heat over the ocean 
    549          tprecip(:,:) = sf(jp_prec)%fnow(:,:,1) * rn_pfac * tmask(:,:,1) ! output total precipitation [kg/m2/s] 
    550          sprecip(:,:) = sf(jp_snow)%fnow(:,:,1) * rn_pfac * tmask(:,:,1) ! output solid precipitation [kg/m2/s] 
    551          CALL iom_put( 'snowpre', sprecip )                 ! Snow 
    552          CALL iom_put( 'precip' , tprecip )                 ! Total precipitation 
    553       ENDIF 
    554       ! 
    555       IF(ln_ctl) THEN 
    556          CALL prt_ctl(tab2d_1=zqsb , clinfo1=' blk_oce: zqsb   : ', tab2d_2=zqlw , clinfo2=' zqlw  : ') 
    557          CALL prt_ctl(tab2d_1=zqla , clinfo1=' blk_oce: zqla   : ', tab2d_2=qsr  , clinfo2=' qsr   : ') 
    558          CALL prt_ctl(tab2d_1=pst  , clinfo1=' blk_oce: pst    : ', tab2d_2=emp  , clinfo2=' emp   : ') 
    559          CALL prt_ctl(tab2d_1=utau , clinfo1=' blk_oce: utau   : ', mask1=umask,   & 
    560             &         tab2d_2=vtau , clinfo2=              ' vtau  : ' , mask2=vmask ) 
    561       ENDIF 
    562       ! 
    563    END SUBROUTINE blk_oce 
    564  
    565  
    566  
    567    FUNCTION rho_air( ptak, pqa, pslp ) 
    568       !!------------------------------------------------------------------------------- 
    569       !!                           ***  FUNCTION rho_air  *** 
    570       !! 
    571       !! ** Purpose : compute density of (moist) air using the eq. of state of the atmosphere 
    572       !! 
    573       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk)  
    574       !!------------------------------------------------------------------------------- 
    575       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   ptak      ! air temperature             [K] 
    576       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pqa       ! air specific humidity   [kg/kg] 
    577       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pslp      ! pressure in                [Pa] 
    578       REAL(wp), DIMENSION(jpi,jpj)             ::   rho_air   ! density of moist air   [kg/m^3] 
    579       !!------------------------------------------------------------------------------- 
    580       ! 
    581       rho_air = pslp / (  R_dry*ptak * ( 1._wp + rctv0*pqa )  ) 
    582       ! 
    583    END FUNCTION rho_air 
    584  
    585  
    586    FUNCTION cp_air( pqa ) 
    587       !!------------------------------------------------------------------------------- 
    588       !!                           ***  FUNCTION cp_air  *** 
    589       !! 
    590       !! ** Purpose : Compute specific heat (Cp) of moist air 
    591       !! 
    592       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    593       !!------------------------------------------------------------------------------- 
    594       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pqa      ! air specific humidity         [kg/kg] 
    595       REAL(wp), DIMENSION(jpi,jpj)             ::   cp_air   ! specific heat of moist air   [J/K/kg] 
    596       !!------------------------------------------------------------------------------- 
    597       ! 
    598       Cp_air = Cp_dry + Cp_vap * pqa 
    599       ! 
    600    END FUNCTION cp_air 
    601  
    602  
    603    FUNCTION q_sat( ptak, pslp ) 
    604       !!---------------------------------------------------------------------------------- 
    605       !!                           ***  FUNCTION q_sat  *** 
    606       !! 
    607       !! ** Purpose : Specific humidity at saturation in [kg/kg] 
    608       !!              Based on accurate estimate of "e_sat" 
    609       !!              aka saturation water vapor (Goff, 1957) 
    610       !! 
    611       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    612       !!---------------------------------------------------------------------------------- 
    613       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   ptak    ! air temperature                       [K] 
    614       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pslp    ! sea level atmospheric pressure       [Pa] 
    615       REAL(wp), DIMENSION(jpi,jpj)             ::   q_sat   ! Specific humidity at saturation   [kg/kg] 
    616       ! 
    617       INTEGER  ::   ji, jj         ! dummy loop indices 
    618       REAL(wp) ::   ze_sat, ztmp   ! local scalar 
    619       !!---------------------------------------------------------------------------------- 
    620       ! 
    621       DO jj = 1, jpj 
    622          DO ji = 1, jpi 
    623             ! 
    624             ztmp = rt0 / ptak(ji,jj) 
    625             ! 
    626             ! Vapour pressure at saturation [hPa] : WMO, (Goff, 1957) 
    627             ze_sat = 10.**( 10.79574*(1. - ztmp) - 5.028*LOG10(ptak(ji,jj)/rt0)        & 
    628                &    + 1.50475*10.**(-4)*(1. - 10.**(-8.2969*(ptak(ji,jj)/rt0 - 1.)) )  & 
    629                &    + 0.42873*10.**(-3)*(10.**(4.76955*(1. - ztmp)) - 1.) + 0.78614  ) 
    630                ! 
    631             q_sat(ji,jj) = reps0 * ze_sat/( 0.01_wp*pslp(ji,jj) - (1._wp - reps0)*ze_sat )   ! 0.01 because SLP is in [Pa] 
    632             ! 
    633          END DO 
    634       END DO 
    635       ! 
    636    END FUNCTION q_sat 
    637  
    638  
    639    FUNCTION gamma_moist( ptak, pqa ) 
    640       !!---------------------------------------------------------------------------------- 
    641       !!                           ***  FUNCTION gamma_moist  *** 
    642       !! 
    643       !! ** Purpose : Compute the moist adiabatic lapse-rate. 
    644       !!     => http://glossary.ametsoc.org/wiki/Moist-adiabatic_lapse_rate 
    645       !!     => http://www.geog.ucsb.edu/~joel/g266_s10/lecture_notes/chapt03/oh10_3_01/oh10_3_01.html 
    646       !! 
    647       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    648       !!---------------------------------------------------------------------------------- 
    649       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   ptak          ! air temperature       [K] 
    650       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pqa           ! specific humidity [kg/kg] 
    651       REAL(wp), DIMENSION(jpi,jpj)             ::   gamma_moist   ! moist adiabatic lapse-rate 
    652       ! 
    653       INTEGER  ::   ji, jj         ! dummy loop indices 
    654       REAL(wp) :: zrv, ziRT        ! local scalar 
    655       !!---------------------------------------------------------------------------------- 
    656       ! 
    657       DO jj = 1, jpj 
    658          DO ji = 1, jpi 
    659             zrv = pqa(ji,jj) / (1. - pqa(ji,jj)) 
    660             ziRT = 1. / (R_dry*ptak(ji,jj))    ! 1/RT 
    661             gamma_moist(ji,jj) = grav * ( 1. + rLevap*zrv*ziRT ) / ( Cp_dry + rLevap*rLevap*zrv*reps0*ziRT/ptak(ji,jj) ) 
    662          END DO 
    663       END DO 
    664       ! 
    665    END FUNCTION gamma_moist 
    666  
    667  
    668    FUNCTION L_vap( psst ) 
    669       !!--------------------------------------------------------------------------------- 
    670       !!                           ***  FUNCTION L_vap  *** 
    671       !! 
    672       !! ** Purpose : Compute the latent heat of vaporization of water from temperature 
    673       !! 
    674       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    675       !!---------------------------------------------------------------------------------- 
    676       REAL(wp), DIMENSION(jpi,jpj)             ::   L_vap   ! latent heat of vaporization   [J/kg] 
    677       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   psst   ! water temperature                [K] 
    678       !!---------------------------------------------------------------------------------- 
    679       ! 
    680       L_vap = (  2.501 - 0.00237 * ( psst(:,:) - rt0)  ) * 1.e6 
    681       ! 
    682    END FUNCTION L_vap 
     809         CALL iom_put( "qemp_oce" , qns-zqlw-psen-zqla )   ! output downward heat content of E-P over the ocean 
     810         CALL iom_put( "qns_oce"  ,   qns  )               ! output downward non solar heat over the ocean 
     811         CALL iom_put( "qsr_oce"  ,   qsr  )               ! output downward solar heat over the ocean 
     812         CALL iom_put( "qt_oce"   ,   qns+qsr )            ! output total downward heat over the ocean 
     813      ENDIF 
     814      ! 
     815      IF(sn_cfctl%l_prtctl) THEN 
     816         CALL prt_ctl(tab2d_1=zqlw , clinfo1=' blk_oce_2: zqlw  : ') 
     817         CALL prt_ctl(tab2d_1=zqla , clinfo1=' blk_oce_2: zqla  : ', tab2d_2=qsr  , clinfo2=' qsr   : ') 
     818         CALL prt_ctl(tab2d_1=emp  , clinfo1=' blk_oce_2: emp   : ') 
     819      ENDIF 
     820      ! 
     821   END SUBROUTINE blk_oce_2 
     822 
    683823 
    684824#if defined key_si3 
     
    686826   !!   'key_si3'                                       SI3 sea-ice model 
    687827   !!---------------------------------------------------------------------- 
    688    !!   blk_ice_tau : provide the air-ice stress 
    689    !!   blk_ice_flx : provide the heat and mass fluxes at air-ice interface 
     828   !!   blk_ice_ : provide the air-ice stress 
     829   !!   blk_ice_ : provide the heat and mass fluxes at air-ice interface 
    690830   !!   blk_ice_qcn : provide ice surface temperature and snow/ice conduction flux (emulating conduction flux) 
    691831   !!   Cdn10_Lupkes2012 : Lupkes et al. (2012) air-ice drag 
    692    !!   Cdn10_Lupkes2015 : Lupkes et al. (2015) air-ice drag  
     832   !!   Cdn10_Lupkes2015 : Lupkes et al. (2015) air-ice drag 
    693833   !!---------------------------------------------------------------------- 
    694834 
    695    SUBROUTINE blk_ice_tau 
    696       !!--------------------------------------------------------------------- 
    697       !!                     ***  ROUTINE blk_ice_tau  *** 
     835   SUBROUTINE blk_ice_1( pwndi, pwndj, ptair, phumi, pslp , puice, pvice, ptsui,  &   ! inputs 
     836      &                  putaui, pvtaui, pseni, pevpi, pssqi, pcd_dui             )   ! optional outputs 
     837      !!--------------------------------------------------------------------- 
     838      !!                     ***  ROUTINE blk_ice_1  *** 
    698839      !! 
    699840      !! ** Purpose :   provide the surface boundary condition over sea-ice 
     
    703844      !!                NB: ice drag coefficient is assumed to be a constant 
    704845      !!--------------------------------------------------------------------- 
     846      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   pslp    ! sea-level pressure [Pa] 
     847      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   pwndi   ! atmospheric wind at T-point [m/s] 
     848      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   pwndj   ! atmospheric wind at T-point [m/s] 
     849      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   ptair   ! atmospheric wind at T-point [m/s] 
     850      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   phumi   ! atmospheric wind at T-point [m/s] 
     851      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   puice   ! sea-ice velocity on I or C grid [m/s] 
     852      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   pvice   ! " 
     853      REAL(wp) , INTENT(in   ), DIMENSION(:,:  ) ::   ptsui   ! sea-ice surface temperature [K] 
     854      REAL(wp) , INTENT(  out), DIMENSION(:,:  ), OPTIONAL ::   putaui  ! if ln_blk 
     855      REAL(wp) , INTENT(  out), DIMENSION(:,:  ), OPTIONAL ::   pvtaui  ! if ln_blk 
     856      REAL(wp) , INTENT(  out), DIMENSION(:,:  ), OPTIONAL ::   pseni   ! if ln_abl 
     857      REAL(wp) , INTENT(  out), DIMENSION(:,:  ), OPTIONAL ::   pevpi   ! if ln_abl 
     858      REAL(wp) , INTENT(  out), DIMENSION(:,:  ), OPTIONAL ::   pssqi   ! if ln_abl 
     859      REAL(wp) , INTENT(  out), DIMENSION(:,:  ), OPTIONAL ::   pcd_dui ! if ln_abl 
     860      ! 
    705861      INTEGER  ::   ji, jj    ! dummy loop indices 
    706       REAL(wp) ::   zwndi_f , zwndj_f, zwnorm_f   ! relative wind module and components at F-point 
    707862      REAL(wp) ::   zwndi_t , zwndj_t             ! relative wind components at T-point 
    708       REAL(wp), DIMENSION(jpi,jpj) ::   zrhoa     ! transfer coefficient for momentum      (tau) 
    709       !!--------------------------------------------------------------------- 
    710       ! 
    711       ! set transfer coefficients to default sea-ice values 
    712       Cd_atm(:,:) = Cd_ice 
    713       Ch_atm(:,:) = Cd_ice 
    714       Ce_atm(:,:) = Cd_ice 
    715  
    716       wndm_ice(:,:) = 0._wp      !!gm brutal.... 
     863      REAL(wp) ::   zootm_su                      ! sea-ice surface mean temperature 
     864      REAL(wp) ::   zztmp1, zztmp2                ! temporary arrays 
     865      REAL(wp), DIMENSION(jpi,jpj) ::   zcd_dui   ! transfer coefficient for momentum      (tau) 
     866      !!--------------------------------------------------------------------- 
     867      ! 
    717868 
    718869      ! ------------------------------------------------------------ ! 
     
    720871      ! ------------------------------------------------------------ ! 
    721872      ! C-grid ice dynamics :   U & V-points (same as ocean) 
    722       DO jj = 2, jpjm1 
    723          DO ji = fs_2, fs_jpim1   ! vect. opt. 
    724             zwndi_t = (  sf(jp_wndi)%fnow(ji,jj,1) - rn_vfac * 0.5 * ( u_ice(ji-1,jj  ) + u_ice(ji,jj) )  ) 
    725             zwndj_t = (  sf(jp_wndj)%fnow(ji,jj,1) - rn_vfac * 0.5 * ( v_ice(ji  ,jj-1) + v_ice(ji,jj) )  ) 
    726             wndm_ice(ji,jj) = SQRT( zwndi_t * zwndi_t + zwndj_t * zwndj_t ) * tmask(ji,jj,1) 
    727          END DO 
    728       END DO 
     873      DO_2D_00_00 
     874         zwndi_t = (  pwndi(ji,jj) - rn_vfac * 0.5_wp * ( puice(ji-1,jj  ) + puice(ji,jj) )  ) 
     875         zwndj_t = (  pwndj(ji,jj) - rn_vfac * 0.5_wp * ( pvice(ji  ,jj-1) + pvice(ji,jj) )  ) 
     876         wndm_ice(ji,jj) = SQRT( zwndi_t * zwndi_t + zwndj_t * zwndj_t ) * tmask(ji,jj,1) 
     877      END_2D 
    729878      CALL lbc_lnk( 'sbcblk', wndm_ice, 'T',  1. ) 
    730879      ! 
    731880      ! Make ice-atm. drag dependent on ice concentration 
    732881      IF    ( ln_Cd_L12 ) THEN   ! calculate new drag from Lupkes(2012) equations 
    733          CALL Cdn10_Lupkes2012( Cd_atm ) 
    734          Ch_atm(:,:) = Cd_atm(:,:)       ! momentum and heat transfer coef. are considered identical 
     882         CALL Cdn10_Lupkes2012( Cd_ice ) 
     883         Ch_ice(:,:) = Cd_ice(:,:)       ! momentum and heat transfer coef. are considered identical 
     884         Ce_ice(:,:) = Cd_ice(:,:) 
    735885      ELSEIF( ln_Cd_L15 ) THEN   ! calculate new drag from Lupkes(2015) equations 
    736          CALL Cdn10_Lupkes2015( Cd_atm, Ch_atm )  
    737       ENDIF 
    738  
    739 !!      CALL iom_put( "Cd_ice", Cd_atm)  ! output value of pure ice-atm. transfer coef. 
    740 !!      CALL iom_put( "Ch_ice", Ch_atm)  ! output value of pure ice-atm. transfer coef. 
     886         CALL Cdn10_Lupkes2015( ptsui, pslp, Cd_ice, Ch_ice ) 
     887         Ce_ice(:,:) = Ch_ice(:,:)       ! sensible and latent heat transfer coef. are considered identical 
     888      ENDIF 
     889 
     890      !! IF ( iom_use("Cd_ice") ) CALL iom_put("Cd_ice", Cd_ice)   ! output value of pure ice-atm. transfer coef. 
     891      !! IF ( iom_use("Ch_ice") ) CALL iom_put("Ch_ice", Ch_ice)   ! output value of pure ice-atm. transfer coef. 
    741892 
    742893      ! local scalars ( place there for vector optimisation purposes) 
    743       ! Computing density of air! Way denser that 1.2 over sea-ice !!! 
    744       zrhoa (:,:) =  rho_air(sf(jp_tair)%fnow(:,:,1), sf(jp_humi)%fnow(:,:,1), sf(jp_slp)%fnow(:,:,1)) 
    745  
    746       !!gm brutal.... 
    747       utau_ice  (:,:) = 0._wp 
    748       vtau_ice  (:,:) = 0._wp 
    749       !!gm end 
    750  
    751       ! ------------------------------------------------------------ ! 
    752       !    Wind stress relative to the moving ice ( U10m - U_ice )   ! 
    753       ! ------------------------------------------------------------ ! 
    754       ! C-grid ice dynamics :   U & V-points (same as ocean) 
    755       DO jj = 2, jpjm1 
    756          DO ji = fs_2, fs_jpim1   ! vect. opt. 
    757             utau_ice(ji,jj) = 0.5 * zrhoa(ji,jj) * Cd_atm(ji,jj) * ( wndm_ice(ji+1,jj  ) + wndm_ice(ji,jj) )            & 
    758                &          * ( 0.5 * (sf(jp_wndi)%fnow(ji+1,jj,1) + sf(jp_wndi)%fnow(ji,jj,1) ) - rn_vfac * u_ice(ji,jj) ) 
    759             vtau_ice(ji,jj) = 0.5 * zrhoa(ji,jj) * Cd_atm(ji,jj) * ( wndm_ice(ji,jj+1  ) + wndm_ice(ji,jj) )            & 
    760                &          * ( 0.5 * (sf(jp_wndj)%fnow(ji,jj+1,1) + sf(jp_wndj)%fnow(ji,jj,1) ) - rn_vfac * v_ice(ji,jj) ) 
    761          END DO 
    762       END DO 
    763       CALL lbc_lnk_multi( 'sbcblk', utau_ice, 'U', -1., vtau_ice, 'V', -1. ) 
    764       ! 
    765       ! 
    766       IF(ln_ctl) THEN 
    767          CALL prt_ctl(tab2d_1=utau_ice  , clinfo1=' blk_ice: utau_ice : ', tab2d_2=vtau_ice  , clinfo2=' vtau_ice : ') 
    768          CALL prt_ctl(tab2d_1=wndm_ice  , clinfo1=' blk_ice: wndm_ice : ') 
    769       ENDIF 
    770       ! 
    771    END SUBROUTINE blk_ice_tau 
    772  
    773  
    774    SUBROUTINE blk_ice_flx( ptsu, phs, phi, palb ) 
    775       !!--------------------------------------------------------------------- 
    776       !!                     ***  ROUTINE blk_ice_flx  *** 
     894      !IF (ln_abl) rhoa  (:,:)  = rho_air( ptair(:,:), phumi(:,:), pslp(:,:) ) !!GS: rhoa must be (re)computed here with ABL to avoid division by zero after (TBI) 
     895      zcd_dui(:,:) = wndm_ice(:,:) * Cd_ice(:,:) 
     896 
     897      IF( ln_blk ) THEN 
     898         ! ------------------------------------------------------------ ! 
     899         !    Wind stress relative to the moving ice ( U10m - U_ice )   ! 
     900         ! ------------------------------------------------------------ ! 
     901         ! C-grid ice dynamics :   U & V-points (same as ocean) 
     902         DO_2D_00_00 
     903            putaui(ji,jj) = 0.5_wp * (  rhoa(ji+1,jj) * zcd_dui(ji+1,jj)             & 
     904               &                      + rhoa(ji  ,jj) * zcd_dui(ji  ,jj)  )          & 
     905               &         * ( 0.5_wp * ( pwndi(ji+1,jj) + pwndi(ji,jj) ) - rn_vfac * puice(ji,jj) ) 
     906            pvtaui(ji,jj) = 0.5_wp * (  rhoa(ji,jj+1) * zcd_dui(ji,jj+1)             & 
     907               &                      + rhoa(ji,jj  ) * zcd_dui(ji,jj  )  )          & 
     908               &         * ( 0.5_wp * ( pwndj(ji,jj+1) + pwndj(ji,jj) ) - rn_vfac * pvice(ji,jj) ) 
     909         END_2D 
     910         CALL lbc_lnk_multi( 'sbcblk', putaui, 'U', -1., pvtaui, 'V', -1. ) 
     911         ! 
     912         IF(sn_cfctl%l_prtctl)  CALL prt_ctl( tab2d_1=putaui  , clinfo1=' blk_ice: putaui : '   & 
     913            &                               , tab2d_2=pvtaui  , clinfo2='          pvtaui : ' ) 
     914      ELSE 
     915         zztmp1 = 11637800.0_wp 
     916         zztmp2 =    -5897.8_wp 
     917         DO_2D_11_11 
     918            pcd_dui(ji,jj) = zcd_dui (ji,jj) 
     919            pseni  (ji,jj) = wndm_ice(ji,jj) * Ch_ice(ji,jj) 
     920            pevpi  (ji,jj) = wndm_ice(ji,jj) * Ce_ice(ji,jj) 
     921            zootm_su       = zztmp2 / ptsui(ji,jj)   ! ptsui is in K (it can't be zero ??) 
     922            pssqi  (ji,jj) = zztmp1 * EXP( zootm_su ) / rhoa(ji,jj) 
     923         END_2D 
     924      ENDIF 
     925      ! 
     926      IF(sn_cfctl%l_prtctl)  CALL prt_ctl(tab2d_1=wndm_ice  , clinfo1=' blk_ice: wndm_ice : ') 
     927      ! 
     928   END SUBROUTINE blk_ice_1 
     929 
     930 
     931   SUBROUTINE blk_ice_2( ptsu, phs, phi, palb, ptair, phumi, pslp, pqlw, pprec, psnow  ) 
     932      !!--------------------------------------------------------------------- 
     933      !!                     ***  ROUTINE blk_ice_2  *** 
    777934      !! 
    778935      !! ** Purpose :   provide the heat and mass fluxes at air-ice interface 
     
    784941      !! caution : the net upward water flux has with mm/day unit 
    785942      !!--------------------------------------------------------------------- 
    786       REAL(wp), DIMENSION(:,:,:), INTENT(in)  ::   ptsu   ! sea ice surface temperature 
     943      REAL(wp), DIMENSION(:,:,:), INTENT(in)  ::   ptsu   ! sea ice surface temperature [K] 
    787944      REAL(wp), DIMENSION(:,:,:), INTENT(in)  ::   phs    ! snow thickness 
    788945      REAL(wp), DIMENSION(:,:,:), INTENT(in)  ::   phi    ! ice thickness 
    789946      REAL(wp), DIMENSION(:,:,:), INTENT(in)  ::   palb   ! ice albedo (all skies) 
     947      REAL(wp), DIMENSION(:,:  ), INTENT(in)  ::   ptair 
     948      REAL(wp), DIMENSION(:,:  ), INTENT(in)  ::   phumi 
     949      REAL(wp), DIMENSION(:,:  ), INTENT(in)  ::   pslp 
     950      REAL(wp), DIMENSION(:,:  ), INTENT(in)  ::   pqlw 
     951      REAL(wp), DIMENSION(:,:  ), INTENT(in)  ::   pprec 
     952      REAL(wp), DIMENSION(:,:  ), INTENT(in)  ::   psnow 
    790953      !! 
    791954      INTEGER  ::   ji, jj, jl               ! dummy loop indices 
    792955      REAL(wp) ::   zst3                     ! local variable 
    793956      REAL(wp) ::   zcoef_dqlw, zcoef_dqla   !   -      - 
    794       REAL(wp) ::   zztmp, z1_rLsub           !   -      - 
     957      REAL(wp) ::   zztmp, zztmp2, z1_rLsub  !   -      - 
    795958      REAL(wp) ::   zfr1, zfr2               ! local variables 
    796959      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   z1_st         ! inverse of surface temperature 
     
    800963      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   z_dqsb        ! sensible  heat sensitivity over ice 
    801964      REAL(wp), DIMENSION(jpi,jpj)     ::   zevap, zsnw   ! evaporation and snw distribution after wind blowing (SI3) 
    802       REAL(wp), DIMENSION(jpi,jpj)     ::   zrhoa 
     965      REAL(wp), DIMENSION(jpi,jpj)     ::   zqair         ! specific humidity of air at z=rn_zqt [kg/kg] !LB 
    803966      REAL(wp), DIMENSION(jpi,jpj)     ::   ztmp, ztmp2 
    804967      !!--------------------------------------------------------------------- 
    805968      ! 
    806       zcoef_dqlw = 4.0 * 0.95 * Stef             ! local scalars 
    807       zcoef_dqla = -Ls * 11637800. * (-5897.8) 
    808       ! 
    809       zrhoa(:,:) = rho_air( sf(jp_tair)%fnow(:,:,1), sf(jp_humi)%fnow(:,:,1), sf(jp_slp)%fnow(:,:,1) ) 
     969      zcoef_dqlw = 4._wp * 0.95_wp * stefan             ! local scalars 
     970      zcoef_dqla = -rLsub * 11637800._wp * (-5897.8_wp) !LB: BAD! 
     971      ! 
     972      SELECT CASE( nhumi ) 
     973      CASE( np_humi_sph ) 
     974         zqair(:,:) =  phumi(:,:)      ! what we read in file is already a spec. humidity! 
     975      CASE( np_humi_dpt ) 
     976         zqair(:,:) = q_sat( phumi(:,:), pslp ) 
     977      CASE( np_humi_rlh ) 
     978         zqair(:,:) = q_air_rh( 0.01_wp*phumi(:,:), ptair(:,:), pslp(:,:) ) !LB: 0.01 => RH is % percent in file 
     979      END SELECT 
    810980      ! 
    811981      zztmp = 1. / ( 1. - albo ) 
    812       WHERE( ptsu(:,:,:) /= 0._wp )   ;   z1_st(:,:,:) = 1._wp / ptsu(:,:,:) 
    813       ELSEWHERE                       ;   z1_st(:,:,:) = 0._wp 
     982      WHERE( ptsu(:,:,:) /= 0._wp ) 
     983         z1_st(:,:,:) = 1._wp / ptsu(:,:,:) 
     984      ELSEWHERE 
     985         z1_st(:,:,:) = 0._wp 
    814986      END WHERE 
    815987      !                                     ! ========================== ! 
     
    825997               qsr_ice(ji,jj,jl) = zztmp * ( 1. - palb(ji,jj,jl) ) * qsr(ji,jj) 
    826998               ! Long  Wave (lw) 
    827                z_qlw(ji,jj,jl) = 0.95 * ( sf(jp_qlw)%fnow(ji,jj,1) - Stef * ptsu(ji,jj,jl) * zst3 ) * tmask(ji,jj,1) 
     999               z_qlw(ji,jj,jl) = 0.95 * ( pqlw(ji,jj) - stefan * ptsu(ji,jj,jl) * zst3 ) * tmask(ji,jj,1) 
    8281000               ! lw sensitivity 
    8291001               z_dqlw(ji,jj,jl) = zcoef_dqlw * zst3 
     
    8331005               ! ----------------------------! 
    8341006 
    835                ! ... turbulent heat fluxes with Ch_atm recalculated in blk_ice_tau 
     1007               ! ... turbulent heat fluxes with Ch_ice recalculated in blk_ice_1 
    8361008               ! Sensible Heat 
    837                z_qsb(ji,jj,jl) = zrhoa(ji,jj) * cpa * Ch_atm(ji,jj) * wndm_ice(ji,jj) * (ptsu(ji,jj,jl) - sf(jp_tair)%fnow(ji,jj,1)) 
     1009               z_qsb(ji,jj,jl) = rhoa(ji,jj) * rCp_air * Ch_ice(ji,jj) * wndm_ice(ji,jj) * (ptsu(ji,jj,jl) - ptair(ji,jj)) 
    8381010               ! Latent Heat 
    839                qla_ice(ji,jj,jl) = rn_efac * MAX( 0.e0, zrhoa(ji,jj) * Ls  * Ch_atm(ji,jj) * wndm_ice(ji,jj) *  & 
    840                   &                ( 11637800. * EXP( -5897.8 * z1_st(ji,jj,jl) ) / zrhoa(ji,jj) - sf(jp_humi)%fnow(ji,jj,1) ) ) 
     1011               zztmp2 = EXP( -5897.8 * z1_st(ji,jj,jl) ) 
     1012               qla_ice(ji,jj,jl) = rn_efac * MAX( 0.e0, rhoa(ji,jj) * rLsub  * Ce_ice(ji,jj) * wndm_ice(ji,jj) *  & 
     1013                  &                ( 11637800. * zztmp2 / rhoa(ji,jj) - zqair(ji,jj) ) ) 
    8411014               ! Latent heat sensitivity for ice (Dqla/Dt) 
    8421015               IF( qla_ice(ji,jj,jl) > 0._wp ) THEN 
    843                   dqla_ice(ji,jj,jl) = rn_efac * zcoef_dqla * Ch_atm(ji,jj) * wndm_ice(ji,jj) *  & 
    844                      &                 z1_st(ji,jj,jl)*z1_st(ji,jj,jl) * EXP(-5897.8 * z1_st(ji,jj,jl)) 
     1016                  dqla_ice(ji,jj,jl) = rn_efac * zcoef_dqla * Ce_ice(ji,jj) * wndm_ice(ji,jj) *  & 
     1017                     &                 z1_st(ji,jj,jl) * z1_st(ji,jj,jl) * zztmp2 
    8451018               ELSE 
    8461019                  dqla_ice(ji,jj,jl) = 0._wp 
     
    8481021 
    8491022               ! Sensible heat sensitivity (Dqsb_ice/Dtn_ice) 
    850                z_dqsb(ji,jj,jl) = zrhoa(ji,jj) * cpa * Ch_atm(ji,jj) * wndm_ice(ji,jj) 
     1023               z_dqsb(ji,jj,jl) = rhoa(ji,jj) * rCp_air * Ch_ice(ji,jj) * wndm_ice(ji,jj) 
    8511024 
    8521025               ! ----------------------------! 
     
    8631036      END DO 
    8641037      ! 
    865       tprecip(:,:) = sf(jp_prec)%fnow(:,:,1) * rn_pfac * tmask(:,:,1)  ! total precipitation [kg/m2/s] 
    866       sprecip(:,:) = sf(jp_snow)%fnow(:,:,1) * rn_pfac * tmask(:,:,1)  ! solid precipitation [kg/m2/s] 
    867       CALL iom_put( 'snowpre', sprecip )                    ! Snow precipitation 
    868       CALL iom_put( 'precip' , tprecip )                    ! Total precipitation 
     1038      tprecip(:,:) = pprec(:,:) * rn_pfac * tmask(:,:,1)  ! total precipitation [kg/m2/s] 
     1039      sprecip(:,:) = psnow(:,:) * rn_pfac * tmask(:,:,1)  ! solid precipitation [kg/m2/s] 
     1040      CALL iom_put( 'snowpre', sprecip )                  ! Snow precipitation 
     1041      CALL iom_put( 'precip' , tprecip )                  ! Total precipitation 
    8691042 
    8701043      ! --- evaporation --- ! 
     
    8831056      ! --- heat flux associated with emp --- ! 
    8841057      qemp_oce(:,:) = - ( 1._wp - at_i_b(:,:) ) * zevap(:,:) * sst_m(:,:) * rcp                  & ! evap at sst 
    885          &          + ( tprecip(:,:) - sprecip(:,:) ) * ( sf(jp_tair)%fnow(:,:,1) - rt0 ) * rcp  & ! liquid precip at Tair 
     1058         &          + ( tprecip(:,:) - sprecip(:,:) ) * ( ptair(:,:) - rt0 ) * rcp               & ! liquid precip at Tair 
    8861059         &          +   sprecip(:,:) * ( 1._wp - zsnw ) *                                        & ! solid precip at min(Tair,Tsnow) 
    887          &              ( ( MIN( sf(jp_tair)%fnow(:,:,1), rt0 ) - rt0 ) * rcpi * tmask(:,:,1) - rLfus ) 
     1060         &              ( ( MIN( ptair(:,:), rt0 ) - rt0 ) * rcpi * tmask(:,:,1) - rLfus ) 
    8881061      qemp_ice(:,:) =   sprecip(:,:) * zsnw *                                                    & ! solid precip (only) 
    889          &              ( ( MIN( sf(jp_tair)%fnow(:,:,1), rt0 ) - rt0 ) * rcpi * tmask(:,:,1) - rLfus ) 
     1062         &              ( ( MIN( ptair(:,:), rt0 ) - rt0 ) * rcpi * tmask(:,:,1) - rLfus ) 
    8901063 
    8911064      ! --- total solar and non solar fluxes --- ! 
     
    8951068 
    8961069      ! --- heat content of precip over ice in J/m3 (to be used in 1D-thermo) --- ! 
    897       qprec_ice(:,:) = rhos * ( ( MIN( sf(jp_tair)%fnow(:,:,1), rt0 ) - rt0 ) * rcpi * tmask(:,:,1) - rLfus ) 
     1070      qprec_ice(:,:) = rhos * ( ( MIN( ptair(:,:), rt0 ) - rt0 ) * rcpi * tmask(:,:,1) - rLfus ) 
    8981071 
    8991072      ! --- heat content of evap over ice in W/m2 (to be used in 1D-thermo) --- 
    9001073      DO jl = 1, jpl 
    9011074         qevap_ice(:,:,jl) = 0._wp ! should be -evap_ice(:,:,jl)*( ( Tice - rt0 ) * rcpi * tmask(:,:,1) ) 
    902          !                         ! But we do not have Tice => consider it at 0degC => evap=0  
     1075         !                         ! But we do not have Tice => consider it at 0degC => evap=0 
    9031076      END DO 
    9041077 
     
    9071080      zfr2 = ( 0.82 * ( 1.0 - cldf_ice ) + 0.65 * cldf_ice )            ! zfr2 such that zfr1 + zfr2 to equal 1 
    9081081      ! 
    909       WHERE    ( phs(:,:,:) <= 0._wp .AND. phi(:,:,:) <  0.1_wp )       ! linear decrease from hi=0 to 10cm   
     1082      WHERE    ( phs(:,:,:) <= 0._wp .AND. phi(:,:,:) <  0.1_wp )       ! linear decrease from hi=0 to 10cm 
    9101083         qtr_ice_top(:,:,:) = qsr_ice(:,:,:) * ( zfr1 + zfr2 * ( 1._wp - phi(:,:,:) * 10._wp ) ) 
    9111084      ELSEWHERE( phs(:,:,:) <= 0._wp .AND. phi(:,:,:) >= 0.1_wp )       ! constant (zfr1) when hi>10cm 
    9121085         qtr_ice_top(:,:,:) = qsr_ice(:,:,:) * zfr1 
    9131086      ELSEWHERE                                                         ! zero when hs>0 
    914          qtr_ice_top(:,:,:) = 0._wp  
     1087         qtr_ice_top(:,:,:) = 0._wp 
    9151088      END WHERE 
    9161089      ! 
    9171090 
    9181091      IF( iom_use('evap_ao_cea') .OR. iom_use('hflx_evap_cea') ) THEN 
    919          ztmp(:,:) = zevap(:,:) * ( 1._wp - at_i_b(:,:) )  
    920          CALL iom_put( 'evap_ao_cea'  , ztmp(:,:) * tmask(:,:,1) )   ! ice-free oce evap (cell average) 
    921          CALL iom_put( 'hflx_evap_cea', ztmp(:,:) * sst_m(:,:) * rcp * tmask(:,:,1) )   ! heat flux from evap (cell average) 
     1092         ztmp(:,:) = zevap(:,:) * ( 1._wp - at_i_b(:,:) ) 
     1093         IF( iom_use('evap_ao_cea'  ) )  CALL iom_put( 'evap_ao_cea'  , ztmp(:,:) * tmask(:,:,1) )   ! ice-free oce evap (cell average) 
     1094         IF( iom_use('hflx_evap_cea') )  CALL iom_put( 'hflx_evap_cea', ztmp(:,:) * sst_m(:,:) * rcp * tmask(:,:,1) )   ! heat flux from evap (cell average) 
    9221095      ENDIF 
    9231096      IF( iom_use('hflx_rain_cea') ) THEN 
    9241097         ztmp(:,:) = rcp * ( SUM( (ptsu-rt0) * a_i_b, dim=3 ) + sst_m(:,:) * ( 1._wp - at_i_b(:,:) ) ) 
    925          CALL iom_put( 'hflx_rain_cea', ( tprecip(:,:) - sprecip(:,:) ) * ztmp(:,:) )   ! heat flux from rain (cell average) 
     1098         IF( iom_use('hflx_rain_cea') )  CALL iom_put( 'hflx_rain_cea', ( tprecip(:,:) - sprecip(:,:) ) * ztmp(:,:) )   ! heat flux from rain (cell average) 
    9261099      ENDIF 
    9271100      IF( iom_use('hflx_snow_cea') .OR. iom_use('hflx_snow_ao_cea') .OR. iom_use('hflx_snow_ai_cea')  )  THEN 
    928           WHERE( SUM( a_i_b, dim=3 ) > 1.e-10 ) ;   ztmp(:,:) = rcpi * SUM( (ptsu-rt0) * a_i_b, dim=3 ) / SUM( a_i_b, dim=3 ) 
    929           ELSEWHERE                             ;   ztmp(:,:) = rcp * sst_m(:,:)     
    930           ENDWHERE 
    931           ztmp2(:,:) = sprecip(:,:) * ( ztmp(:,:) - rLfus )  
    932           CALL iom_put('hflx_snow_cea'   , ztmp2(:,:) ) ! heat flux from snow (cell average) 
    933           CALL iom_put('hflx_snow_ao_cea', ztmp2(:,:) * ( 1._wp - zsnw(:,:) ) ) ! heat flux from snow (over ocean) 
    934           CALL iom_put('hflx_snow_ai_cea', ztmp2(:,:) *           zsnw(:,:)   ) ! heat flux from snow (over ice) 
    935       ENDIF 
    936       ! 
    937       IF(ln_ctl) THEN 
     1101         WHERE( SUM( a_i_b, dim=3 ) > 1.e-10 ) 
     1102            ztmp(:,:) = rcpi * SUM( (ptsu-rt0) * a_i_b, dim=3 ) / SUM( a_i_b, dim=3 ) 
     1103         ELSEWHERE 
     1104            ztmp(:,:) = rcp * sst_m(:,:) 
     1105         ENDWHERE 
     1106         ztmp2(:,:) = sprecip(:,:) * ( ztmp(:,:) - rLfus ) 
     1107         IF( iom_use('hflx_snow_cea')    ) CALL iom_put('hflx_snow_cea'   , ztmp2(:,:) ) ! heat flux from snow (cell average) 
     1108         IF( iom_use('hflx_snow_ao_cea') ) CALL iom_put('hflx_snow_ao_cea', ztmp2(:,:) * ( 1._wp - zsnw(:,:) ) ) ! heat flux from snow (over ocean) 
     1109         IF( iom_use('hflx_snow_ai_cea') ) CALL iom_put('hflx_snow_ai_cea', ztmp2(:,:) *           zsnw(:,:)   ) ! heat flux from snow (over ice) 
     1110      ENDIF 
     1111      ! 
     1112      IF(sn_cfctl%l_prtctl) THEN 
    9381113         CALL prt_ctl(tab3d_1=qla_ice , clinfo1=' blk_ice: qla_ice  : ', tab3d_2=z_qsb   , clinfo2=' z_qsb    : ', kdim=jpl) 
    9391114         CALL prt_ctl(tab3d_1=z_qlw   , clinfo1=' blk_ice: z_qlw    : ', tab3d_2=dqla_ice, clinfo2=' dqla_ice : ', kdim=jpl) 
     
    9441119      ENDIF 
    9451120      ! 
    946    END SUBROUTINE blk_ice_flx 
    947     
     1121   END SUBROUTINE blk_ice_2 
     1122 
    9481123 
    9491124   SUBROUTINE blk_ice_qcn( ld_virtual_itd, ptsu, ptb, phs, phi ) 
     
    9541129      !!                to force sea ice / snow thermodynamics 
    9551130      !!                in the case conduction flux is emulated 
    956       !!                 
     1131      !! 
    9571132      !! ** Method  :   compute surface energy balance assuming neglecting heat storage 
    9581133      !!                following the 0-layer Semtner (1976) approach 
     
    9791154      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   zgfac   ! enhanced conduction factor 
    9801155      !!--------------------------------------------------------------------- 
    981        
     1156 
    9821157      ! -------------------------------------! 
    9831158      !      I   Enhanced conduction factor  ! 
     
    9871162      ! 
    9881163      zgfac(:,:,:) = 1._wp 
    989        
     1164 
    9901165      IF( ld_virtual_itd ) THEN 
    9911166         ! 
     
    9931168         zfac2 = EXP(1._wp) * 0.5_wp * zepsilon 
    9941169         zfac3 = 2._wp / zepsilon 
    995          !    
    996          DO jl = 1, jpl                 
    997             DO jj = 1 , jpj 
    998                DO ji = 1, jpi 
    999                   zhe = ( rn_cnd_s * phi(ji,jj,jl) + rcnd_i * phs(ji,jj,jl) ) * zfac                            ! Effective thickness 
    1000                   IF( zhe >=  zfac2 )   zgfac(ji,jj,jl) = MIN( 2._wp, 0.5_wp * ( 1._wp + LOG( zhe * zfac3 ) ) ) ! Enhanced conduction factor 
    1001                END DO 
    1002             END DO 
     1170         ! 
     1171         DO jl = 1, jpl 
     1172            DO_2D_11_11 
     1173               zhe = ( rn_cnd_s * phi(ji,jj,jl) + rcnd_i * phs(ji,jj,jl) ) * zfac                            ! Effective thickness 
     1174               IF( zhe >=  zfac2 )   zgfac(ji,jj,jl) = MIN( 2._wp, 0.5_wp * ( 1._wp + LOG( zhe * zfac3 ) ) ) ! Enhanced conduction factor 
     1175            END_2D 
    10031176         END DO 
    1004          !       
    1005       ENDIF 
    1006        
     1177         ! 
     1178      ENDIF 
     1179 
    10071180      ! -------------------------------------------------------------! 
    10081181      !      II   Surface temperature and conduction flux            ! 
     
    10121185      ! 
    10131186      DO jl = 1, jpl 
    1014          DO jj = 1 , jpj 
    1015             DO ji = 1, jpi 
    1016                !                     
    1017                zkeff_h = zfac * zgfac(ji,jj,jl) / &                                    ! Effective conductivity of the snow-ice system divided by thickness 
    1018                   &      ( rcnd_i * phs(ji,jj,jl) + rn_cnd_s * MAX( 0.01, phi(ji,jj,jl) ) ) 
    1019                ztsu    = ptsu(ji,jj,jl)                                                ! Store current iteration temperature 
    1020                ztsu0   = ptsu(ji,jj,jl)                                                ! Store initial surface temperature 
    1021                zqa0    = qsr_ice(ji,jj,jl) - qtr_ice_top(ji,jj,jl) + qns_ice(ji,jj,jl) ! Net initial atmospheric heat flux 
    1022                ! 
    1023                DO iter = 1, nit     ! --- Iterative loop 
    1024                   zqc   = zkeff_h * ( ztsu - ptb(ji,jj) )                              ! Conduction heat flux through snow-ice system (>0 downwards) 
    1025                   zqnet = zqa0 + dqns_ice(ji,jj,jl) * ( ztsu - ptsu(ji,jj,jl) ) - zqc  ! Surface energy budget 
    1026                   ztsu  = ztsu - zqnet / ( dqns_ice(ji,jj,jl) - zkeff_h )              ! Temperature update 
    1027                END DO 
    1028                ! 
    1029                ptsu   (ji,jj,jl) = MIN( rt0, ztsu ) 
    1030                qcn_ice(ji,jj,jl) = zkeff_h * ( ptsu(ji,jj,jl) - ptb(ji,jj) ) 
    1031                qns_ice(ji,jj,jl) = qns_ice(ji,jj,jl) + dqns_ice(ji,jj,jl) * ( ptsu(ji,jj,jl) - ztsu0 ) 
    1032                qml_ice(ji,jj,jl) = ( qsr_ice(ji,jj,jl) - qtr_ice_top(ji,jj,jl) + qns_ice(ji,jj,jl) - qcn_ice(ji,jj,jl) )  & 
    1033                              &   * MAX( 0._wp , SIGN( 1._wp, ptsu(ji,jj,jl) - rt0 ) ) 
    1034  
    1035                ! --- Diagnose the heat loss due to changing non-solar flux (as in icethd_zdf_bl99) --- ! 
    1036                hfx_err_dif(ji,jj) = hfx_err_dif(ji,jj) - ( dqns_ice(ji,jj,jl) * ( ptsu(ji,jj,jl) - ztsu0 ) ) * a_i_b(ji,jj,jl)  
    1037  
     1187         DO_2D_11_11 
     1188            ! 
     1189            zkeff_h = zfac * zgfac(ji,jj,jl) / &                                    ! Effective conductivity of the snow-ice system divided by thickness 
     1190               &      ( rcnd_i * phs(ji,jj,jl) + rn_cnd_s * MAX( 0.01, phi(ji,jj,jl) ) ) 
     1191            ztsu    = ptsu(ji,jj,jl)                                                ! Store current iteration temperature 
     1192            ztsu0   = ptsu(ji,jj,jl)                                                ! Store initial surface temperature 
     1193            zqa0    = qsr_ice(ji,jj,jl) - qtr_ice_top(ji,jj,jl) + qns_ice(ji,jj,jl) ! Net initial atmospheric heat flux 
     1194            ! 
     1195            DO iter = 1, nit     ! --- Iterative loop 
     1196               zqc   = zkeff_h * ( ztsu - ptb(ji,jj) )                              ! Conduction heat flux through snow-ice system (>0 downwards) 
     1197               zqnet = zqa0 + dqns_ice(ji,jj,jl) * ( ztsu - ptsu(ji,jj,jl) ) - zqc  ! Surface energy budget 
     1198               ztsu  = ztsu - zqnet / ( dqns_ice(ji,jj,jl) - zkeff_h )              ! Temperature update 
    10381199            END DO 
    1039          END DO 
     1200            ! 
     1201            ptsu   (ji,jj,jl) = MIN( rt0, ztsu ) 
     1202            qcn_ice(ji,jj,jl) = zkeff_h * ( ptsu(ji,jj,jl) - ptb(ji,jj) ) 
     1203            qns_ice(ji,jj,jl) = qns_ice(ji,jj,jl) + dqns_ice(ji,jj,jl) * ( ptsu(ji,jj,jl) - ztsu0 ) 
     1204            qml_ice(ji,jj,jl) = ( qsr_ice(ji,jj,jl) - qtr_ice_top(ji,jj,jl) + qns_ice(ji,jj,jl) - qcn_ice(ji,jj,jl) )  & 
     1205               &   * MAX( 0._wp , SIGN( 1._wp, ptsu(ji,jj,jl) - rt0 ) ) 
     1206 
     1207            ! --- Diagnose the heat loss due to changing non-solar flux (as in icethd_zdf_bl99) --- ! 
     1208            hfx_err_dif(ji,jj) = hfx_err_dif(ji,jj) - ( dqns_ice(ji,jj,jl) * ( ptsu(ji,jj,jl) - ztsu0 ) ) * a_i_b(ji,jj,jl) 
     1209 
     1210         END_2D 
    10401211         ! 
    1041       END DO  
    1042       !       
     1212      END DO 
     1213      ! 
    10431214   END SUBROUTINE blk_ice_qcn 
    1044     
    1045  
    1046    SUBROUTINE Cdn10_Lupkes2012( Cd ) 
     1215 
     1216 
     1217   SUBROUTINE Cdn10_Lupkes2012( pcd ) 
    10471218      !!---------------------------------------------------------------------- 
    10481219      !!                      ***  ROUTINE  Cdn10_Lupkes2012  *** 
    10491220      !! 
    1050       !! ** Purpose :    Recompute the neutral air-ice drag referenced at 10m  
     1221      !! ** Purpose :    Recompute the neutral air-ice drag referenced at 10m 
    10511222      !!                 to make it dependent on edges at leads, melt ponds and flows. 
    10521223      !!                 After some approximations, this can be resumed to a dependency 
    10531224      !!                 on ice concentration. 
    1054       !!                 
     1225      !! 
    10551226      !! ** Method :     The parameterization is taken from Lupkes et al. (2012) eq.(50) 
    10561227      !!                 with the highest level of approximation: level4, eq.(59) 
     
    10641235      !! 
    10651236      !!                 This new drag has a parabolic shape (as a function of A) starting at 
    1066       !!                 Cdw(say 1.5e-3) for A=0, reaching 1.97e-3 for A~0.5  
     1237      !!                 Cdw(say 1.5e-3) for A=0, reaching 1.97e-3 for A~0.5 
    10671238      !!                 and going down to Cdi(say 1.4e-3) for A=1 
    10681239      !! 
     
    10741245      !! 
    10751246      !!---------------------------------------------------------------------- 
    1076       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   Cd 
     1247      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pcd 
    10771248      REAL(wp), PARAMETER ::   zCe   = 2.23e-03_wp 
    10781249      REAL(wp), PARAMETER ::   znu   = 1._wp 
     
    10891260 
    10901261      ! ice-atm drag 
    1091       Cd(:,:) = Cd_ice +  &                                                         ! pure ice drag 
    1092          &      zCe    * ( 1._wp - at_i_b(:,:) )**zcoef * at_i_b(:,:)**(zmu-1._wp)  ! change due to sea-ice morphology 
    1093        
     1262      pcd(:,:) = rCd_ice +  &                                                         ! pure ice drag 
     1263         &      zCe     * ( 1._wp - at_i_b(:,:) )**zcoef * at_i_b(:,:)**(zmu-1._wp)  ! change due to sea-ice morphology 
     1264 
    10941265   END SUBROUTINE Cdn10_Lupkes2012 
    10951266 
    10961267 
    1097    SUBROUTINE Cdn10_Lupkes2015( Cd, Ch ) 
     1268   SUBROUTINE Cdn10_Lupkes2015( ptm_su, pslp, pcd, pch ) 
    10981269      !!---------------------------------------------------------------------- 
    10991270      !!                      ***  ROUTINE  Cdn10_Lupkes2015  *** 
    11001271      !! 
    11011272      !! ** pUrpose :    Alternative turbulent transfert coefficients formulation 
    1102       !!                 between sea-ice and atmosphere with distinct momentum  
    1103       !!                 and heat coefficients depending on sea-ice concentration  
     1273      !!                 between sea-ice and atmosphere with distinct momentum 
     1274      !!                 and heat coefficients depending on sea-ice concentration 
    11041275      !!                 and atmospheric stability (no meltponds effect for now). 
    1105       !!                 
     1276      !! 
    11061277      !! ** Method :     The parameterization is adapted from Lupkes et al. (2015) 
    11071278      !!                 and ECHAM6 atmospheric model. Compared to Lupkes2012 scheme, 
    11081279      !!                 it considers specific skin and form drags (Andreas et al. 2010) 
    1109       !!                 to compute neutral transfert coefficients for both heat and  
     1280      !!                 to compute neutral transfert coefficients for both heat and 
    11101281      !!                 momemtum fluxes. Atmospheric stability effect on transfert 
    11111282      !!                 coefficient is also taken into account following Louis (1979). 
     
    11161287      !!---------------------------------------------------------------------- 
    11171288      ! 
    1118       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   Cd 
    1119       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   Ch 
    1120       REAL(wp), DIMENSION(jpi,jpj)            ::   ztm_su, zst, zqo_sat, zqi_sat 
     1289      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   ptm_su ! sea-ice surface temperature [K] 
     1290      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pslp   ! sea-level pressure [Pa] 
     1291      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pcd    ! momentum transfert coefficient 
     1292      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pch    ! heat transfert coefficient 
     1293      REAL(wp), DIMENSION(jpi,jpj)            ::   zst, zqo_sat, zqi_sat 
    11211294      ! 
    11221295      ! ECHAM6 constants 
     
    11461319      !!---------------------------------------------------------------------- 
    11471320 
    1148       ! mean temperature 
    1149       WHERE( at_i_b(:,:) > 1.e-20 )   ;   ztm_su(:,:) = SUM( t_su(:,:,:) * a_i_b(:,:,:) , dim=3 ) / at_i_b(:,:) 
    1150       ELSEWHERE                       ;   ztm_su(:,:) = rt0 
    1151       ENDWHERE 
    1152        
    11531321      ! Momentum Neutral Transfert Coefficients (should be a constant) 
    11541322      zCdn_form_tmp = zce10 * ( LOG( 10._wp / z0_form_ice + 1._wp ) / LOG( rn_zu / z0_form_ice + 1._wp ) )**2   ! Eq. 40 
    11551323      zCdn_skin_ice = ( vkarmn                                      / LOG( rn_zu / z0_skin_ice + 1._wp ) )**2   ! Eq. 7 
    1156       zCdn_ice      = zCdn_skin_ice   ! Eq. 7 (cf Lupkes email for details) 
     1324      zCdn_ice      = zCdn_skin_ice   ! Eq. 7 
    11571325      !zCdn_ice     = 1.89e-3         ! old ECHAM5 value (cf Eq. 32) 
    11581326 
    11591327      ! Heat Neutral Transfert Coefficients 
    1160       zChn_skin_ice = vkarmn**2 / ( LOG( rn_zu / z0_ice + 1._wp ) * LOG( rn_zu * z1_alpha / z0_skin_ice + 1._wp ) )   ! Eq. 50 + Eq. 52 (cf Lupkes email for details) 
    1161       
     1328      zChn_skin_ice = vkarmn**2 / ( LOG( rn_zu / z0_ice + 1._wp ) * LOG( rn_zu * z1_alpha / z0_skin_ice + 1._wp ) )   ! Eq. 50 + Eq. 52 
     1329 
    11621330      ! Atmospheric and Surface Variables 
    11631331      zst(:,:)     = sst_m(:,:) + rt0                                        ! convert SST from Celcius to Kelvin 
    1164       zqo_sat(:,:) = 0.98_wp * q_sat( zst(:,:)   , sf(jp_slp)%fnow(:,:,1) )  ! saturation humidity over ocean [kg/kg] 
    1165       zqi_sat(:,:) = 0.98_wp * q_sat( ztm_su(:,:), sf(jp_slp)%fnow(:,:,1) )  ! saturation humidity over ice   [kg/kg] 
    1166       ! 
    1167       DO jj = 2, jpjm1           ! reduced loop is necessary for reproducibility 
    1168          DO ji = fs_2, fs_jpim1 
    1169             ! Virtual potential temperature [K] 
    1170             zthetav_os = zst(ji,jj)    * ( 1._wp + rctv0 * zqo_sat(ji,jj) )   ! over ocean 
    1171             zthetav_is = ztm_su(ji,jj) * ( 1._wp + rctv0 * zqi_sat(ji,jj) )   ! ocean ice 
    1172             zthetav_zu = t_zu (ji,jj)  * ( 1._wp + rctv0 * q_zu(ji,jj)    )   ! at zu 
    1173              
    1174             ! Bulk Richardson Number (could use Ri_bulk function from aerobulk instead) 
    1175             zrib_o = grav / zthetav_os * ( zthetav_zu - zthetav_os ) * rn_zu / MAX( 0.5, wndm(ji,jj)     )**2   ! over ocean 
    1176             zrib_i = grav / zthetav_is * ( zthetav_zu - zthetav_is ) * rn_zu / MAX( 0.5, wndm_ice(ji,jj) )**2   ! over ice 
    1177              
    1178             ! Momentum and Heat Neutral Transfert Coefficients 
    1179             zCdn_form_ice = zCdn_form_tmp * at_i_b(ji,jj) * ( 1._wp - at_i_b(ji,jj) )**zbeta  ! Eq. 40 
    1180             zChn_form_ice = zCdn_form_ice / ( 1._wp + ( LOG( z1_alphaf ) / vkarmn ) * SQRT( zCdn_form_ice ) )               ! Eq. 53  
    1181                         
    1182             ! Momentum and Heat Stability functions (possibility to use psi_m_ecmwf instead) 
    1183             z0w = rn_zu * EXP( -1._wp * vkarmn / SQRT( Cdn_oce(ji,jj) ) ) ! over water 
    1184             z0i = z0_skin_ice                                             ! over ice (cf Lupkes email for details) 
    1185             IF( zrib_o <= 0._wp ) THEN 
    1186                zfmw = 1._wp - zam * zrib_o / ( 1._wp + 3._wp * zc2 * Cdn_oce(ji,jj) * SQRT( -zrib_o * ( rn_zu / z0w + 1._wp ) ) )  ! Eq. 10 
    1187                zfhw = ( 1._wp + ( zbetah * ( zthetav_os - zthetav_zu )**r1_3 / ( Chn_oce(ji,jj) * MAX(0.01, wndm(ji,jj)) )   &     ! Eq. 26 
    1188                   &             )**zgamma )**z1_gamma 
    1189             ELSE 
    1190                zfmw = 1._wp / ( 1._wp + zam * zrib_o / SQRT( 1._wp + zrib_o ) )   ! Eq. 12 
    1191                zfhw = 1._wp / ( 1._wp + zah * zrib_o / SQRT( 1._wp + zrib_o ) )   ! Eq. 28 
    1192             ENDIF 
    1193              
    1194             IF( zrib_i <= 0._wp ) THEN 
    1195                zfmi = 1._wp - zam * zrib_i / (1._wp + 3._wp * zc2 * zCdn_ice * SQRT( -zrib_i * ( rn_zu / z0i + 1._wp)))   ! Eq.  9 
    1196                zfhi = 1._wp - zah * zrib_i / (1._wp + 3._wp * zc2 * zCdn_ice * SQRT( -zrib_i * ( rn_zu / z0i + 1._wp)))   ! Eq. 25 
    1197             ELSE 
    1198                zfmi = 1._wp / ( 1._wp + zam * zrib_i / SQRT( 1._wp + zrib_i ) )   ! Eq. 11 
    1199                zfhi = 1._wp / ( 1._wp + zah * zrib_i / SQRT( 1._wp + zrib_i ) )   ! Eq. 27 
    1200             ENDIF 
    1201              
    1202             ! Momentum Transfert Coefficients (Eq. 38) 
    1203             Cd(ji,jj) = zCdn_skin_ice *   zfmi +  & 
    1204                &        zCdn_form_ice * ( zfmi * at_i_b(ji,jj) + zfmw * ( 1._wp - at_i_b(ji,jj) ) ) / MAX( 1.e-06, at_i_b(ji,jj) ) 
    1205              
    1206             ! Heat Transfert Coefficients (Eq. 49) 
    1207             Ch(ji,jj) = zChn_skin_ice *   zfhi +  & 
    1208                &        zChn_form_ice * ( zfhi * at_i_b(ji,jj) + zfhw * ( 1._wp - at_i_b(ji,jj) ) ) / MAX( 1.e-06, at_i_b(ji,jj) ) 
    1209             ! 
    1210          END DO 
    1211       END DO 
    1212       CALL lbc_lnk_multi( 'sbcblk', Cd, 'T',  1., Ch, 'T', 1. ) 
     1332      zqo_sat(:,:) = rdct_qsat_salt * q_sat( zst(:,:)   , pslp(:,:) )   ! saturation humidity over ocean [kg/kg] 
     1333      zqi_sat(:,:) =                  q_sat( ptm_su(:,:), pslp(:,:) )   ! saturation humidity over ice   [kg/kg] 
     1334      ! 
     1335      DO_2D_00_00 
     1336         ! Virtual potential temperature [K] 
     1337         zthetav_os = zst(ji,jj)    * ( 1._wp + rctv0 * zqo_sat(ji,jj) )   ! over ocean 
     1338         zthetav_is = ptm_su(ji,jj) * ( 1._wp + rctv0 * zqi_sat(ji,jj) )   ! ocean ice 
     1339         zthetav_zu = t_zu (ji,jj)  * ( 1._wp + rctv0 * q_zu(ji,jj)    )   ! at zu 
     1340 
     1341         ! Bulk Richardson Number (could use Ri_bulk function from aerobulk instead) 
     1342         zrib_o = grav / zthetav_os * ( zthetav_zu - zthetav_os ) * rn_zu / MAX( 0.5, wndm(ji,jj)     )**2   ! over ocean 
     1343         zrib_i = grav / zthetav_is * ( zthetav_zu - zthetav_is ) * rn_zu / MAX( 0.5, wndm_ice(ji,jj) )**2   ! over ice 
     1344 
     1345         ! Momentum and Heat Neutral Transfert Coefficients 
     1346         zCdn_form_ice = zCdn_form_tmp * at_i_b(ji,jj) * ( 1._wp - at_i_b(ji,jj) )**zbeta  ! Eq. 40 
     1347         zChn_form_ice = zCdn_form_ice / ( 1._wp + ( LOG( z1_alphaf ) / vkarmn ) * SQRT( zCdn_form_ice ) )               ! Eq. 53 
     1348 
     1349         ! Momentum and Heat Stability functions (possibility to use psi_m_ecmwf instead ?) 
     1350         z0w = rn_zu * EXP( -1._wp * vkarmn / SQRT( Cdn_oce(ji,jj) ) ) ! over water 
     1351         z0i = z0_skin_ice                                             ! over ice 
     1352         IF( zrib_o <= 0._wp ) THEN 
     1353            zfmw = 1._wp - zam * zrib_o / ( 1._wp + 3._wp * zc2 * Cdn_oce(ji,jj) * SQRT( -zrib_o * ( rn_zu / z0w + 1._wp ) ) )  ! Eq. 10 
     1354            zfhw = ( 1._wp + ( zbetah * ( zthetav_os - zthetav_zu )**r1_3 / ( Chn_oce(ji,jj) * MAX(0.01, wndm(ji,jj)) )   &     ! Eq. 26 
     1355               &             )**zgamma )**z1_gamma 
     1356         ELSE 
     1357            zfmw = 1._wp / ( 1._wp + zam * zrib_o / SQRT( 1._wp + zrib_o ) )   ! Eq. 12 
     1358            zfhw = 1._wp / ( 1._wp + zah * zrib_o / SQRT( 1._wp + zrib_o ) )   ! Eq. 28 
     1359         ENDIF 
     1360 
     1361         IF( zrib_i <= 0._wp ) THEN 
     1362            zfmi = 1._wp - zam * zrib_i / (1._wp + 3._wp * zc2 * zCdn_ice * SQRT( -zrib_i * ( rn_zu / z0i + 1._wp)))   ! Eq.  9 
     1363            zfhi = 1._wp - zah * zrib_i / (1._wp + 3._wp * zc2 * zCdn_ice * SQRT( -zrib_i * ( rn_zu / z0i + 1._wp)))   ! Eq. 25 
     1364         ELSE 
     1365            zfmi = 1._wp / ( 1._wp + zam * zrib_i / SQRT( 1._wp + zrib_i ) )   ! Eq. 11 
     1366            zfhi = 1._wp / ( 1._wp + zah * zrib_i / SQRT( 1._wp + zrib_i ) )   ! Eq. 27 
     1367         ENDIF 
     1368 
     1369         ! Momentum Transfert Coefficients (Eq. 38) 
     1370         pcd(ji,jj) = zCdn_skin_ice *   zfmi +  & 
     1371            &        zCdn_form_ice * ( zfmi * at_i_b(ji,jj) + zfmw * ( 1._wp - at_i_b(ji,jj) ) ) / MAX( 1.e-06, at_i_b(ji,jj) ) 
     1372 
     1373         ! Heat Transfert Coefficients (Eq. 49) 
     1374         pch(ji,jj) = zChn_skin_ice *   zfhi +  & 
     1375            &        zChn_form_ice * ( zfhi * at_i_b(ji,jj) + zfhw * ( 1._wp - at_i_b(ji,jj) ) ) / MAX( 1.e-06, at_i_b(ji,jj) ) 
     1376         ! 
     1377      END_2D 
     1378      CALL lbc_lnk_multi( 'sbcblk', pcd, 'T',  1., pch, 'T', 1. ) 
    12131379      ! 
    12141380   END SUBROUTINE Cdn10_Lupkes2015 
  • NEMO/trunk/src/OCE/SBC/sbcblk_algo_ecmwf.F90

    r10069 r12377  
    11MODULE sbcblk_algo_ecmwf 
    22   !!====================================================================== 
    3    !!                       ***  MODULE  sbcblk_algo_ecmwf  *** 
    4    !! Computes turbulent components of surface fluxes 
    5    !!         according to the method in IFS of the ECMWF model 
    6    !! 
     3   !!                   ***  MODULE  sbcblk_algo_ecmwf  *** 
     4   !! Computes: 
    75   !!   * bulk transfer coefficients C_D, C_E and C_H 
    86   !!   * air temp. and spec. hum. adjusted from zt (2m) to zu (10m) if needed 
     
    108   !!   => all these are used in bulk formulas in sbcblk.F90 
    119   !! 
    12    !!    Using the bulk formulation/param. of IFS of ECMWF (cycle 31r2) 
     10   !!    Using the bulk formulation/param. of IFS of ECMWF (cycle 40r1) 
    1311   !!         based on IFS doc (avaible online on the ECMWF's website) 
    1412   !! 
     13   !!       Routine turb_ecmwf maintained and developed in AeroBulk 
     14   !!                     (https://github.com/brodeau/aerobulk) 
    1515   !! 
    16    !!       Routine turb_ecmwf maintained and developed in AeroBulk 
    17    !!                     (http://aerobulk.sourceforge.net/) 
    18    !! 
    19    !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
     16   !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk) 
    2017   !!---------------------------------------------------------------------- 
    2118   !! History :  4.0  !  2016-02  (L.Brodeau)   Original code 
     
    4138 
    4239   USE sbc_oce         ! Surface boundary condition: ocean fields 
     40   USE sbcblk_phy      ! all thermodynamics functions, rho_air, q_sat, etc... !LB 
     41   USE sbcblk_skin_ecmwf ! cool-skin/warm layer scheme !LB 
    4342 
    4443   IMPLICIT NONE 
    4544   PRIVATE 
    4645 
    47    PUBLIC ::   TURB_ECMWF   ! called by sbcblk.F90 
    48  
    49    !                   !! ECMWF own values for given constants, taken form IFS documentation... 
     46   PUBLIC :: SBCBLK_ALGO_ECMWF_INIT, TURB_ECMWF 
     47   !! * Substitutions 
     48#  include "do_loop_substitute.h90" 
     49 
     50   !! ECMWF own values for given constants, taken form IFS documentation... 
    5051   REAL(wp), PARAMETER ::   charn0 = 0.018    ! Charnock constant (pretty high value here !!! 
    5152   !                                          !    =>  Usually 0.011 for moderate winds) 
    5253   REAL(wp), PARAMETER ::   zi0     = 1000.   ! scale height of the atmospheric boundary layer...1 
    5354   REAL(wp), PARAMETER ::   Beta0    = 1.     ! gustiness parameter ( = 1.25 in COAREv3) 
    54    REAL(wp), PARAMETER ::   rctv0    = 0.608  ! constant to obtain virtual temperature... 
    55    REAL(wp), PARAMETER ::   Cp_dry = 1005.0   ! Specic heat of dry air, constant pressure      [J/K/kg] 
    56    REAL(wp), PARAMETER ::   Cp_vap = 1860.0   ! Specic heat of water vapor, constant pressure  [J/K/kg] 
    5755   REAL(wp), PARAMETER ::   alpha_M = 0.11    ! For roughness length (smooth surface term) 
    5856   REAL(wp), PARAMETER ::   alpha_H = 0.40    ! (Chapter 3, p.34, IFS doc Cy31r1) 
    5957   REAL(wp), PARAMETER ::   alpha_Q = 0.62    ! 
     58 
     59   INTEGER , PARAMETER ::   nb_itt = 10             ! number of itterations 
     60 
    6061   !!---------------------------------------------------------------------- 
    6162CONTAINS 
    6263 
    63    SUBROUTINE TURB_ECMWF( zt, zu, sst, t_zt, ssq , q_zt , U_zu,   & 
    64       &                   Cd, Ch, Ce , t_zu, q_zu, U_blk,         & 
    65       &                   Cdn, Chn, Cen                           ) 
    66       !!---------------------------------------------------------------------------------- 
    67       !!                      ***  ROUTINE  turb_ecmwf  *** 
    68       !! 
    69       !!            2015: L. Brodeau (brodeau@gmail.com) 
    70       !! 
    71       !! ** Purpose :   Computes turbulent transfert coefficients of surface 
    72       !!                fluxes according to IFS doc. (cycle 31) 
    73       !!                If relevant (zt /= zu), adjust temperature and humidity from height zt to zu 
    74       !! 
    75       !! ** Method : Monin Obukhov Similarity Theory 
     64 
     65   SUBROUTINE sbcblk_algo_ecmwf_init(l_use_cs, l_use_wl) 
     66      !!--------------------------------------------------------------------- 
     67      !!                  ***  FUNCTION sbcblk_algo_ecmwf_init  *** 
    7668      !! 
    7769      !! INPUT : 
    7870      !! ------- 
     71      !!    * l_use_cs : use the cool-skin parameterization 
     72      !!    * l_use_wl : use the warm-layer parameterization 
     73      !!--------------------------------------------------------------------- 
     74      LOGICAL , INTENT(in) ::   l_use_cs ! use the cool-skin parameterization 
     75      LOGICAL , INTENT(in) ::   l_use_wl ! use the warm-layer parameterization 
     76      INTEGER :: ierr 
     77      !!--------------------------------------------------------------------- 
     78      IF( l_use_wl ) THEN 
     79         ierr = 0 
     80         ALLOCATE ( dT_wl(jpi,jpj), Hz_wl(jpi,jpj), STAT=ierr ) 
     81         IF( ierr > 0 ) CALL ctl_stop( ' SBCBLK_ALGO_ECMWF_INIT => allocation of dT_wl & Hz_wl failed!' ) 
     82         dT_wl(:,:)  = 0._wp 
     83         Hz_wl(:,:)  = rd0 ! (rd0, constant, = 3m is default for Zeng & Beljaars) 
     84      ENDIF 
     85      IF( l_use_cs ) THEN 
     86         ierr = 0 
     87         ALLOCATE ( dT_cs(jpi,jpj), STAT=ierr ) 
     88         IF( ierr > 0 ) CALL ctl_stop( ' SBCBLK_ALGO_ECMWF_INIT => allocation of dT_cs failed!' ) 
     89         dT_cs(:,:) = -0.25_wp  ! First guess of skin correction 
     90      ENDIF 
     91   END SUBROUTINE sbcblk_algo_ecmwf_init 
     92 
     93 
     94 
     95   SUBROUTINE turb_ecmwf( kt, zt, zu, T_s, t_zt, q_s, q_zt, U_zu, l_use_cs, l_use_wl, & 
     96      &                      Cd, Ch, Ce, t_zu, q_zu, U_blk,                           & 
     97      &                      Cdn, Chn, Cen,                                           & 
     98      &                      Qsw, rad_lw, slp, pdT_cs,                                & ! optionals for cool-skin (and warm-layer) 
     99      &                      pdT_wl, pHz_wl )                                           ! optionals for warm-layer only 
     100      !!---------------------------------------------------------------------- 
     101      !!                      ***  ROUTINE  turb_ecmwf  *** 
     102      !! 
     103      !! ** Purpose :   Computes turbulent transfert coefficients of surface 
     104      !!                fluxes according to IFS doc. (cycle 45r1) 
     105      !!                If relevant (zt /= zu), adjust temperature and humidity from height zt to zu 
     106      !!                Returns the effective bulk wind speed at zu to be used in the bulk formulas 
     107      !! 
     108      !!                Applies the cool-skin warm-layer correction of the SST to T_s 
     109      !!                if the net shortwave flux at the surface (Qsw), the downwelling longwave 
     110      !!                radiative fluxes at the surface (rad_lw), and the sea-leve pressure (slp) 
     111      !!                are provided as (optional) arguments! 
     112      !! 
     113      !! INPUT : 
     114      !! ------- 
     115      !!    *  kt   : current time step (starts at 1) 
    79116      !!    *  zt   : height for temperature and spec. hum. of air            [m] 
    80       !!    *  zu   : height for wind speed (generally 10m)                   [m] 
    81       !!    *  U_zu : scalar wind speed at 10m                                [m/s] 
    82       !!    *  sst  : SST                                                     [K] 
     117      !!    *  zu   : height for wind speed (usually 10m)                     [m] 
    83118      !!    *  t_zt : potential air temperature at zt                         [K] 
    84       !!    *  ssq  : specific humidity at saturation at SST                  [kg/kg] 
    85119      !!    *  q_zt : specific humidity of air at zt                          [kg/kg] 
    86       !! 
     120      !!    *  U_zu : scalar wind speed at zu                                 [m/s] 
     121      !!    * l_use_cs : use the cool-skin parameterization 
     122      !!    * l_use_wl : use the warm-layer parameterization 
     123      !! 
     124      !! INPUT/OUTPUT: 
     125      !! ------------- 
     126      !!    *  T_s  : always "bulk SST" as input                              [K] 
     127      !!              -> unchanged "bulk SST" as output if CSWL not used      [K] 
     128      !!              -> skin temperature as output if CSWL used              [K] 
     129      !! 
     130      !!    *  q_s  : SSQ aka saturation specific humidity at temp. T_s       [kg/kg] 
     131      !!              -> doesn't need to be given a value if skin temp computed (in case l_use_cs=True or l_use_wl=True) 
     132      !!              -> MUST be given the correct value if not computing skint temp. (in case l_use_cs=False or l_use_wl=False) 
     133      !! 
     134      !! OPTIONAL INPUT: 
     135      !! --------------- 
     136      !!    *  Qsw    : net solar flux (after albedo) at the surface (>0)     [W/m^2] 
     137      !!    *  rad_lw : downwelling longwave radiation at the surface  (>0)   [W/m^2] 
     138      !!    *  slp    : sea-level pressure                                    [Pa] 
     139      !! 
     140      !! OPTIONAL OUTPUT: 
     141      !! ---------------- 
     142      !!    * pdT_cs  : SST increment "dT" for cool-skin correction           [K] 
     143      !!    * pdT_wl  : SST increment "dT" for warm-layer correction          [K] 
     144      !!    * pHz_wl  : thickness of warm-layer                               [m] 
    87145      !! 
    88146      !! OUTPUT : 
     
    93151      !!    *  t_zu   : pot. air temperature adjusted at wind height zu       [K] 
    94152      !!    *  q_zu   : specific humidity of air        //                    [kg/kg] 
    95       !!    *  U_blk  : bulk wind at 10m                                      [m/s] 
    96       !! 
    97       !! 
    98       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    99       !!---------------------------------------------------------------------------------- 
     153      !!    *  U_blk  : bulk wind speed at zu                                 [m/s] 
     154      !! 
     155      !! 
     156      !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk/) 
     157      !!---------------------------------------------------------------------------------- 
     158      INTEGER,  INTENT(in   )                     ::   kt       ! current time step 
    100159      REAL(wp), INTENT(in   )                     ::   zt       ! height for t_zt and q_zt                    [m] 
    101160      REAL(wp), INTENT(in   )                     ::   zu       ! height for U_zu                             [m] 
    102       REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   sst      ! sea surface temperature                [Kelvin] 
     161      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj) ::   T_s      ! sea surface temperature                [Kelvin] 
    103162      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   t_zt     ! potential air temperature              [Kelvin] 
    104       REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   ssq      ! sea surface specific humidity           [kg/kg] 
    105       REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   q_zt     ! specific air humidity                   [kg/kg] 
     163      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj) ::   q_s      ! sea surface specific humidity           [kg/kg] 
     164      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   q_zt     ! specific air humidity at zt             [kg/kg] 
    106165      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   U_zu     ! relative wind module at zu                [m/s] 
     166      LOGICAL , INTENT(in   )                     ::   l_use_cs ! use the cool-skin parameterization 
     167      LOGICAL , INTENT(in   )                     ::   l_use_wl ! use the warm-layer parameterization 
    107168      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cd       ! transfer coefficient for momentum         (tau) 
    108169      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Ch       ! transfer coefficient for sensible heat (Q_sens) 
     
    110171      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   t_zu     ! pot. air temp. adjusted at zu               [K] 
    111172      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   q_zu     ! spec. humidity adjusted at zu           [kg/kg] 
    112       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   U_blk    ! bulk wind at 10m                          [m/s] 
     173      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   U_blk    ! bulk wind speed at zu                     [m/s] 
    113174      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cdn, Chn, Cen ! neutral transfer coefficients 
    114175      ! 
     176      REAL(wp), INTENT(in   ), OPTIONAL, DIMENSION(jpi,jpj) ::   Qsw      !             [W/m^2] 
     177      REAL(wp), INTENT(in   ), OPTIONAL, DIMENSION(jpi,jpj) ::   rad_lw   !             [W/m^2] 
     178      REAL(wp), INTENT(in   ), OPTIONAL, DIMENSION(jpi,jpj) ::   slp      !             [Pa] 
     179      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pdT_cs 
     180      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pdT_wl   !             [K] 
     181      REAL(wp), INTENT(  out), OPTIONAL, DIMENSION(jpi,jpj) ::   pHz_wl   !             [m] 
     182      ! 
    115183      INTEGER :: j_itt 
    116       LOGICAL ::   l_zt_equal_zu = .FALSE.      ! if q and t are given at same height as U 
    117       INTEGER , PARAMETER ::   nb_itt = 4       ! number of itterations 
    118       ! 
    119       REAL(wp), DIMENSION(jpi,jpj) ::   u_star, t_star, q_star,   & 
    120          &  dt_zu, dq_zu,    & 
    121          &  znu_a,           & !: Nu_air, Viscosity of air 
    122          &  Linv,            & !: 1/L (inverse of Monin Obukhov length... 
    123          &  z0, z0t, z0q 
    124       REAL(wp), DIMENSION(jpi,jpj) ::   func_m, func_h 
    125       REAL(wp), DIMENSION(jpi,jpj) ::   ztmp0, ztmp1, ztmp2 
    126       !!---------------------------------------------------------------------------------- 
    127       ! 
    128       ! Identical first gess as in COARE, with IFS parameter values though 
    129       ! 
     184      LOGICAL :: l_zt_equal_zu = .FALSE.      ! if q and t are given at same height as U 
     185      ! 
     186      REAL(wp), DIMENSION(jpi,jpj) ::  u_star, t_star, q_star 
     187      REAL(wp), DIMENSION(jpi,jpj) :: dt_zu, dq_zu      
     188      REAL(wp), DIMENSION(jpi,jpj) :: znu_a !: Nu_air, Viscosity of air 
     189      REAL(wp), DIMENSION(jpi,jpj) :: Linv  !: 1/L (inverse of Monin Obukhov length... 
     190      REAL(wp), DIMENSION(jpi,jpj) :: z0, z0t, z0q 
     191      ! 
     192      REAL(wp), DIMENSION(:,:), ALLOCATABLE :: zsst  ! to back up the initial bulk SST 
     193      ! 
     194      REAL(wp), DIMENSION(jpi,jpj) :: func_m, func_h 
     195      REAL(wp), DIMENSION(jpi,jpj) :: ztmp0, ztmp1, ztmp2 
     196      CHARACTER(len=40), PARAMETER :: crtnm = 'turb_ecmwf@sbcblk_algo_ecmwf.F90' 
     197      !!---------------------------------------------------------------------------------- 
     198 
     199      IF( kt == nit000 ) CALL SBCBLK_ALGO_ECMWF_INIT(l_use_cs, l_use_wl) 
     200 
    130201      l_zt_equal_zu = .FALSE. 
    131       IF( ABS(zu - zt) < 0.01 )   l_zt_equal_zu = .TRUE.    ! testing "zu == zt" is risky with double precision 
    132  
    133  
     202      IF( ABS(zu - zt) < 0.01_wp )   l_zt_equal_zu = .TRUE.    ! testing "zu == zt" is risky with double precision 
     203 
     204      !! Initializations for cool skin and warm layer: 
     205      IF( l_use_cs .AND. (.NOT.(PRESENT(Qsw) .AND. PRESENT(rad_lw) .AND. PRESENT(slp))) ) & 
     206         &   CALL ctl_stop( '['//TRIM(crtnm)//'] => ' , 'you need to provide Qsw, rad_lw & slp to use cool-skin param!' ) 
     207 
     208      IF( l_use_wl .AND. (.NOT.(PRESENT(Qsw) .AND. PRESENT(rad_lw) .AND. PRESENT(slp))) ) & 
     209         &   CALL ctl_stop( '['//TRIM(crtnm)//'] => ' , 'you need to provide Qsw, rad_lw & slp to use warm-layer param!' ) 
     210 
     211      IF( l_use_cs .OR. l_use_wl ) THEN 
     212         ALLOCATE ( zsst(jpi,jpj) ) 
     213         zsst = T_s ! backing up the bulk SST 
     214         IF( l_use_cs ) T_s = T_s - 0.25_wp   ! First guess of correction 
     215         q_s    = rdct_qsat_salt*q_sat(MAX(T_s, 200._wp), slp) ! First guess of q_s 
     216      ENDIF 
     217 
     218 
     219      ! Identical first gess as in COARE, with IFS parameter values though... 
     220      ! 
    134221      !! First guess of temperature and humidity at height zu: 
    135       t_zu = MAX( t_zt , 0.0 )   ! who knows what's given on masked-continental regions... 
    136       q_zu = MAX( q_zt , 1.e-6)   !               " 
     222      t_zu = MAX( t_zt ,  180._wp )   ! who knows what's given on masked-continental regions... 
     223      q_zu = MAX( q_zt , 1.e-6_wp )   !               " 
    137224 
    138225      !! Pot. temp. difference (and we don't want it to be 0!) 
    139       dt_zu = t_zu - sst   ;   dt_zu = SIGN( MAX(ABS(dt_zu),1.e-6), dt_zu ) 
    140       dq_zu = q_zu - ssq   ;   dq_zu = SIGN( MAX(ABS(dq_zu),1.e-9), dq_zu ) 
    141  
    142       znu_a = visc_air(t_zt) ! Air viscosity (m^2/s) at zt given from temperature in (K) 
    143  
    144       ztmp2 = 0.5 * 0.5 ! initial guess for wind gustiness contribution 
    145       U_blk = SQRT(U_zu*U_zu + ztmp2) 
    146  
    147       ! z0     = 0.0001 
    148       ztmp2   = 10000.     ! optimization: ztmp2 == 1/z0 
    149       ztmp0   = LOG(zu*ztmp2) 
    150       ztmp1   = LOG(10.*ztmp2) 
    151       u_star = 0.035*U_blk*ztmp1/ztmp0       ! (u* = 0.035*Un10) 
    152  
    153       z0     = charn0*u_star*u_star/grav + 0.11*znu_a/u_star 
    154       z0t    = 0.1*EXP(vkarmn/(0.00115/(vkarmn/ztmp1)))   !  WARNING: 1/z0t ! 
     226      dt_zu = t_zu - T_s ;   dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6_wp), dt_zu ) 
     227      dq_zu = q_zu - q_s ;   dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9_wp), dq_zu ) 
     228 
     229      znu_a = visc_air(t_zu) ! Air viscosity (m^2/s) at zt given from temperature in (K) 
     230 
     231      U_blk = SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution 
     232 
     233      ztmp0   = LOG(    zu*10000._wp) ! optimization: 10000. == 1/z0 (with z0 first guess == 0.0001) 
     234      ztmp1   = LOG(10._wp*10000._wp) !       "                    "               " 
     235      u_star = 0.035_wp*U_blk*ztmp1/ztmp0       ! (u* = 0.035*Un10) 
     236 
     237      z0     = charn0*u_star*u_star/grav + 0.11_wp*znu_a/u_star 
     238      z0     = MIN( MAX(ABS(z0), 1.E-9) , 1._wp )                      ! (prevents FPE from stupid values from masked region later on) 
     239 
     240      z0t    = 1._wp / ( 0.1_wp*EXP(vkarmn/(0.00115/(vkarmn/ztmp1))) ) 
     241      z0t    = MIN( MAX(ABS(z0t), 1.E-9) , 1._wp )                      ! (prevents FPE from stupid values from masked region later on) 
    155242 
    156243      Cd     = (vkarmn/ztmp0)**2    ! first guess of Cd 
    157244 
    158       ztmp0 = vkarmn*vkarmn/LOG(zt*z0t)/Cd 
    159  
    160       ztmp2 = Ri_bulk( zu, t_zu, dt_zu, q_zu, dq_zu, U_blk )   ! Ribu = Bulk Richardson number 
    161  
    162       !! First estimate of zeta_u, depending on the stability, ie sign of Ribu (ztmp2): 
    163       ztmp1 = 0.5 + SIGN( 0.5 , ztmp2 ) 
     245      ztmp0 = vkarmn*vkarmn/LOG(zt/z0t)/Cd 
     246 
     247      ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, U_blk ) ! Bulk Richardson Number (BRN) 
     248 
     249      !! First estimate of zeta_u, depending on the stability, ie sign of BRN (ztmp2): 
     250      ztmp1 = 0.5 + SIGN( 0.5_wp , ztmp2 ) 
    164251      func_m = ztmp0*ztmp2 ! temporary array !! 
    165       !!             Ribu < 0                                 Ribu > 0   Beta = 1.25 
    166       func_h = (1.-ztmp1)*(func_m/(1.+ztmp2/(-zu/(zi0*0.004*Beta0**3)))) &  ! temporary array !!! func_h == zeta_u 
    167          &  +     ztmp1*(func_m*(1. + 27./9.*ztmp2/ztmp0)) 
     252      func_h = (1._wp-ztmp1) * (func_m/(1._wp+ztmp2/(-zu/(zi0*0.004_wp*Beta0**3)))) & !  BRN < 0 ! temporary array !!! func_h == zeta_u 
     253         &  +     ztmp1   * (func_m*(1._wp + 27._wp/9._wp*ztmp2/func_m))              !  BRN > 0 
     254      !#LB: should make sure that the "func_m" of "27./9.*ztmp2/func_m" is "ztmp0*ztmp2" and not "ztmp0==vkarmn*vkarmn/LOG(zt/z0t)/Cd" ! 
    168255 
    169256      !! First guess M-O stability dependent scaling params.(u*,t*,q*) to estimate z0 and z/L 
    170       ztmp0   =        vkarmn/(LOG(zu*z0t) - psi_h_ecmwf(func_h)) 
    171  
    172       u_star = U_blk*vkarmn/(LOG(zu) - LOG(z0)  - psi_m_ecmwf(func_h)) 
     257      ztmp0  = vkarmn/(LOG(zu/z0t) - psi_h_ecmwf(func_h)) 
     258 
     259      u_star = MAX ( U_blk*vkarmn/(LOG(zu) - LOG(z0)  - psi_m_ecmwf(func_h)) , 1.E-9 )  !  (MAX => prevents FPE from stupid values from masked region later on) 
    173260      t_star = dt_zu*ztmp0 
    174261      q_star = dq_zu*ztmp0 
    175262 
    176       ! What's need to be done if zt /= zu: 
     263      ! What needs to be done if zt /= zu: 
    177264      IF( .NOT. l_zt_equal_zu ) THEN 
    178          ! 
    179265         !! First update of values at zu (or zt for wind) 
    180266         ztmp0 = psi_h_ecmwf(func_h) - psi_h_ecmwf(zt*func_h/zu)    ! zt*func_h/zu == zeta_t 
    181          ztmp1 = log(zt/zu) + ztmp0 
     267         ztmp1 = LOG(zt/zu) + ztmp0 
    182268         t_zu = t_zt - t_star/vkarmn*ztmp1 
    183269         q_zu = q_zt - q_star/vkarmn*ztmp1 
    184          q_zu = (0.5 + sign(0.5,q_zu))*q_zu !Makes it impossible to have negative humidity : 
    185  
    186          dt_zu = t_zu - sst  ; dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6), dt_zu ) 
    187          dq_zu = q_zu - ssq  ; dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9), dq_zu ) 
    188          ! 
     270         q_zu = (0.5_wp + SIGN(0.5_wp,q_zu))*q_zu !Makes it impossible to have negative humidity : 
     271         ! 
     272         dt_zu = t_zu - T_s  ; dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6_wp), dt_zu ) 
     273         dq_zu = q_zu - q_s  ; dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9_wp), dq_zu ) 
    189274      ENDIF 
    190275 
     
    194279 
    195280      !! First guess of inverse of Monin-Obukov length (1/L) : 
    196       ztmp0 = (1. + rctv0*q_zu)  ! the factor to apply to temp. to get virt. temp... 
    197       Linv  =  grav*vkarmn*(t_star*ztmp0 + rctv0*t_zu*q_star) / ( u_star*u_star * t_zu*ztmp0 ) 
     281      Linv = One_on_L( t_zu, q_zu, u_star, t_star, q_star ) 
    198282 
    199283      !! Functions such as  u* = U_blk*vkarmn/func_m 
    200       ztmp1 = zu + z0 
    201       ztmp0 = ztmp1*Linv 
    202       func_m = LOG(ztmp1) -LOG(z0) - psi_m_ecmwf(ztmp0) + psi_m_ecmwf(z0*Linv) 
    203       func_h = LOG(ztmp1*z0t) - psi_h_ecmwf(ztmp0) + psi_h_ecmwf(1./z0t*Linv) 
    204  
     284      ztmp0 = zu*Linv 
     285      func_m = LOG(zu) - LOG(z0)  - psi_m_ecmwf(ztmp0) + psi_m_ecmwf( z0*Linv) 
     286      func_h = LOG(zu) - LOG(z0t) - psi_h_ecmwf(ztmp0) + psi_h_ecmwf(z0t*Linv) 
    205287 
    206288      !! ITERATION BLOCK 
    207       !! *************** 
    208  
    209289      DO j_itt = 1, nb_itt 
    210290 
    211291         !! Bulk Richardson Number at z=zu (Eq. 3.25) 
    212          ztmp0 = Ri_bulk(zu, t_zu, dt_zu, q_zu, dq_zu, U_blk) 
     292         ztmp0 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, U_blk ) ! Bulk Richardson Number (BRN) 
    213293 
    214294         !! New estimate of the inverse of the Monin-Obukhon length (Linv == zeta/zu) : 
    215          Linv = ztmp0*func_m*func_m/func_h / zu     ! From Eq. 3.23, Chap.3, p.33, IFS doc - Cy31r1 
     295         Linv = ztmp0*func_m*func_m/func_h / zu     ! From Eq. 3.23, Chap.3.2.3, IFS doc - Cy40r1 
     296         !! Note: it is slightly different that the L we would get with the usual 
     297         Linv = SIGN( MIN(ABS(Linv),200._wp), Linv ) ! (prevent FPE from stupid values from masked region later on...) 
    216298 
    217299         !! Update func_m with new Linv: 
    218          ztmp1 = zu + z0 
    219          func_m = LOG(ztmp1) -LOG(z0) - psi_m_ecmwf(ztmp1*Linv) + psi_m_ecmwf(z0*Linv) 
     300         func_m = LOG(zu) -LOG(z0) - psi_m_ecmwf(zu*Linv) + psi_m_ecmwf(z0*Linv) ! LB: should be "zu+z0" rather than "zu" alone, but z0 is tiny wrt zu! 
    220301 
    221302         !! Need to update roughness lengthes: 
     
    223304         ztmp2  = u_star*u_star 
    224305         ztmp1  = znu_a/u_star 
    225          z0    = alpha_M*ztmp1 + charn0*ztmp2/grav 
    226          z0t    = alpha_H*ztmp1                              ! eq.3.26, Chap.3, p.34, IFS doc - Cy31r1 
    227          z0q    = alpha_Q*ztmp1 
    228  
    229          !! Update wind at 10m taking into acount convection-related wind gustiness: 
    230          ! Only true when unstable (L<0) => when ztmp0 < 0 => - !!! 
    231          ztmp2 = ztmp2 * (MAX(-zi0*Linv/vkarmn,0.))**(2./3.) ! => w*^2  (combining Eq. 3.8 and 3.18, hap.3, IFS doc - Cy31r1) 
    232          !! => equivalent using Beta=1 (gustiness parameter, 1.25 for COARE, also zi0=600 in COARE..) 
    233          U_blk = MAX(sqrt(U_zu*U_zu + ztmp2), 0.2)              ! eq.3.17, Chap.3, p.32, IFS doc - Cy31r1 
     306         z0     = MIN( ABS( alpha_M*ztmp1 + charn0*ztmp2/grav ) , 0.001_wp) 
     307         z0t    = MIN( ABS( alpha_H*ztmp1                     ) , 0.001_wp)   ! eq.3.26, Chap.3, p.34, IFS doc - Cy31r1 
     308         z0q    = MIN( ABS( alpha_Q*ztmp1                     ) , 0.001_wp) 
     309 
     310         !! Update wind at zu with convection-related wind gustiness in unstable conditions (Chap. 3.2, IFS doc - Cy40r1, Eq.3.17 and Eq.3.18 + Eq.3.8) 
     311         ztmp2 = Beta0*Beta0*ztmp2*(MAX(-zi0*Linv/vkarmn,0._wp))**(2._wp/3._wp) ! square of wind gustiness contribution  (combining Eq. 3.8 and 3.18, hap.3, IFS doc - Cy31r1) 
     312         !!   ! Only true when unstable (L<0) => when ztmp0 < 0 => explains "-" before zi0 
     313         U_blk = MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp)        ! include gustiness in bulk wind speed 
    234314         ! => 0.2 prevents U_blk to be 0 in stable case when U_zu=0. 
    235315 
     
    238318         !! as well the air-sea differences: 
    239319         IF( .NOT. l_zt_equal_zu ) THEN 
    240  
    241320            !! Arrays func_m and func_h are free for a while so using them as temporary arrays... 
    242             func_h = psi_h_ecmwf((zu+z0)*Linv) ! temporary array !!! 
    243             func_m = psi_h_ecmwf((zt+z0)*Linv) ! temporary array !!! 
     321            func_h = psi_h_ecmwf(zu*Linv) ! temporary array !!! 
     322            func_m = psi_h_ecmwf(zt*Linv) ! temporary array !!! 
    244323 
    245324            ztmp2  = psi_h_ecmwf(z0t*Linv) 
    246325            ztmp0  = func_h - ztmp2 
    247             ztmp1  = vkarmn/(LOG(zu+z0) - LOG(z0t) - ztmp0) 
     326            ztmp1  = vkarmn/(LOG(zu) - LOG(z0t) - ztmp0) 
    248327            t_star = dt_zu*ztmp1 
    249328            ztmp2  = ztmp0 - func_m + ztmp2 
     
    253332            ztmp2  = psi_h_ecmwf(z0q*Linv) 
    254333            ztmp0  = func_h - ztmp2 
    255             ztmp1  = vkarmn/(LOG(zu+z0) - LOG(z0q) - ztmp0) 
     334            ztmp1  = vkarmn/(LOG(zu) - LOG(z0q) - ztmp0) 
    256335            q_star = dq_zu*ztmp1 
    257336            ztmp2  = ztmp0 - func_m + ztmp2 
    258             ztmp1  = log(zt/zu) + ztmp2 
     337            ztmp1  = LOG(zt/zu) + ztmp2 
    259338            q_zu   = q_zt - q_star/vkarmn*ztmp1 
    260  
    261             dt_zu = t_zu - sst ;  dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6), dt_zu ) 
    262             dq_zu = q_zu - ssq ;  dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9), dq_zu ) 
    263  
    264          END IF 
     339         ENDIF 
    265340 
    266341         !! Updating because of updated z0 and z0t and new Linv... 
    267          ztmp1 = zu + z0 
    268          ztmp0 = ztmp1*Linv 
    269          func_m = log(ztmp1) - LOG(z0 ) - psi_m_ecmwf(ztmp0) + psi_m_ecmwf(z0 *Linv) 
    270          func_h = log(ztmp1) - LOG(z0t) - psi_h_ecmwf(ztmp0) + psi_h_ecmwf(z0t*Linv) 
    271  
    272       END DO 
     342         ztmp0 = zu*Linv 
     343         func_m = log(zu) - LOG(z0 ) - psi_m_ecmwf(ztmp0) + psi_m_ecmwf(z0 *Linv) 
     344         func_h = log(zu) - LOG(z0t) - psi_h_ecmwf(ztmp0) + psi_h_ecmwf(z0t*Linv) 
     345 
     346 
     347         IF( l_use_cs ) THEN 
     348            !! Cool-skin contribution 
     349 
     350            CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U_blk, slp, rad_lw, & 
     351               &                   ztmp1, ztmp0,  Qlat=ztmp2)  ! Qnsol -> ztmp1 / Tau -> ztmp0 
     352 
     353            CALL CS_ECMWF( Qsw, ztmp1, u_star, zsst )  ! Qnsol -> ztmp1 
     354 
     355            T_s(:,:) = zsst(:,:) + dT_cs(:,:)*tmask(:,:,1) 
     356            IF( l_use_wl ) T_s(:,:) = T_s(:,:) + dT_wl(:,:)*tmask(:,:,1) 
     357            q_s(:,:) = rdct_qsat_salt*q_sat(MAX(T_s(:,:), 200._wp), slp(:,:)) 
     358 
     359         ENDIF 
     360 
     361         IF( l_use_wl ) THEN 
     362            !! Warm-layer contribution 
     363            CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U_blk, slp, rad_lw, & 
     364               &                   ztmp1, ztmp2)  ! Qnsol -> ztmp1 / Tau -> ztmp2 
     365            CALL WL_ECMWF( Qsw, ztmp1, u_star, zsst ) 
     366            !! Updating T_s and q_s !!! 
     367            T_s(:,:) = zsst(:,:) + dT_wl(:,:)*tmask(:,:,1) ! 
     368            IF( l_use_cs ) T_s(:,:) = T_s(:,:) + dT_cs(:,:)*tmask(:,:,1) 
     369            q_s(:,:) = rdct_qsat_salt*q_sat(MAX(T_s(:,:), 200._wp), slp(:,:)) 
     370         ENDIF 
     371 
     372         IF( l_use_cs .OR. l_use_wl .OR. (.NOT. l_zt_equal_zu) ) THEN 
     373            dt_zu = t_zu - T_s ;  dt_zu = SIGN( MAX(ABS(dt_zu),1.E-6_wp), dt_zu ) 
     374            dq_zu = q_zu - q_s ;  dq_zu = SIGN( MAX(ABS(dq_zu),1.E-9_wp), dq_zu ) 
     375         ENDIF 
     376 
     377      END DO !DO j_itt = 1, nb_itt 
    273378 
    274379      Cd = vkarmn*vkarmn/(func_m*func_m) 
    275380      Ch = vkarmn*vkarmn/(func_m*func_h) 
    276       ztmp1 = log((zu + z0)/z0q) - psi_h_ecmwf((zu + z0)*Linv) + psi_h_ecmwf(z0q*Linv)   ! func_q 
    277       Ce = vkarmn*vkarmn/(func_m*ztmp1) 
    278  
    279       ztmp1 = zu + z0 
    280       Cdn = vkarmn*vkarmn / (log(ztmp1/z0 )*log(ztmp1/z0 )) 
    281       Chn = vkarmn*vkarmn / (log(ztmp1/z0t)*log(ztmp1/z0t)) 
    282       Cen = vkarmn*vkarmn / (log(ztmp1/z0q)*log(ztmp1/z0q)) 
    283  
    284    END SUBROUTINE TURB_ECMWF 
     381      ztmp2 = log(zu/z0q) - psi_h_ecmwf(zu*Linv) + psi_h_ecmwf(z0q*Linv)   ! func_q 
     382      Ce = vkarmn*vkarmn/(func_m*ztmp2) 
     383 
     384      Cdn = vkarmn*vkarmn / (log(zu/z0 )*log(zu/z0 )) 
     385      Chn = vkarmn*vkarmn / (log(zu/z0t)*log(zu/z0t)) 
     386      Cen = vkarmn*vkarmn / (log(zu/z0q)*log(zu/z0q)) 
     387 
     388      IF( l_use_cs .AND. PRESENT(pdT_cs) ) pdT_cs = dT_cs 
     389      IF( l_use_wl .AND. PRESENT(pdT_wl) ) pdT_wl = dT_wl 
     390      IF( l_use_wl .AND. PRESENT(pHz_wl) ) pHz_wl = Hz_wl 
     391 
     392      IF( l_use_cs .OR. l_use_wl ) DEALLOCATE ( zsst ) 
     393 
     394   END SUBROUTINE turb_ecmwf 
    285395 
    286396 
     
    294404      !!         and L is M-O length 
    295405      !! 
    296       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
     406      !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
    297407      !!---------------------------------------------------------------------------------- 
    298408      REAL(wp), DIMENSION(jpi,jpj) :: psi_m_ecmwf 
     
    302412      REAL(wp) :: zzeta, zx, ztmp, psi_unst, psi_stab, stab 
    303413      !!---------------------------------------------------------------------------------- 
    304       ! 
    305       DO jj = 1, jpj 
    306          DO ji = 1, jpi 
    307             ! 
    308             zzeta = MIN( pzeta(ji,jj) , 5. ) !! Very stable conditions (L positif and big!): 
    309             ! 
    310             ! Unstable (Paulson 1970): 
    311             !   eq.3.20, Chap.3, p.33, IFS doc - Cy31r1 
    312             zx = SQRT(ABS(1. - 16.*zzeta)) 
    313             ztmp = 1. + SQRT(zx) 
    314             ztmp = ztmp*ztmp 
    315             psi_unst = LOG( 0.125*ztmp*(1. + zx) )   & 
    316                &       -2.*ATAN( SQRT(zx) ) + 0.5*rpi 
    317             ! 
    318             ! Unstable: 
    319             ! eq.3.22, Chap.3, p.33, IFS doc - Cy31r1 
    320             psi_stab = -2./3.*(zzeta - 5./0.35)*EXP(-0.35*zzeta) & 
    321                &       - zzeta - 2./3.*5./0.35 
    322             ! 
    323             ! Combining: 
    324             stab = 0.5 + SIGN(0.5, zzeta) ! zzeta > 0 => stab = 1 
    325             ! 
    326             psi_m_ecmwf(ji,jj) = (1. - stab) * psi_unst & ! (zzeta < 0) Unstable 
    327                &                +      stab  * psi_stab   ! (zzeta > 0) Stable 
    328             ! 
    329          END DO 
    330       END DO 
    331       ! 
     414      DO_2D_11_11 
     415         ! 
     416         zzeta = MIN( pzeta(ji,jj) , 5._wp ) !! Very stable conditions (L positif and big!): 
     417         ! 
     418         ! Unstable (Paulson 1970): 
     419         !   eq.3.20, Chap.3, p.33, IFS doc - Cy31r1 
     420         zx = SQRT(ABS(1._wp - 16._wp*zzeta)) 
     421         ztmp = 1._wp + SQRT(zx) 
     422         ztmp = ztmp*ztmp 
     423         psi_unst = LOG( 0.125_wp*ztmp*(1._wp + zx) )   & 
     424            &       -2._wp*ATAN( SQRT(zx) ) + 0.5_wp*rpi 
     425         ! 
     426         ! Unstable: 
     427         ! eq.3.22, Chap.3, p.33, IFS doc - Cy31r1 
     428         psi_stab = -2._wp/3._wp*(zzeta - 5._wp/0.35_wp)*EXP(-0.35_wp*zzeta) & 
     429            &       - zzeta - 2._wp/3._wp*5._wp/0.35_wp 
     430         ! 
     431         ! Combining: 
     432         stab = 0.5_wp + SIGN(0.5_wp, zzeta) ! zzeta > 0 => stab = 1 
     433         ! 
     434         psi_m_ecmwf(ji,jj) = (1._wp - stab) * psi_unst & ! (zzeta < 0) Unstable 
     435            &                +      stab  * psi_stab      ! (zzeta > 0) Stable 
     436         ! 
     437      END_2D 
    332438   END FUNCTION psi_m_ecmwf 
    333439 
    334     
     440 
    335441   FUNCTION psi_h_ecmwf( pzeta ) 
    336442      !!---------------------------------------------------------------------------------- 
     
    342448      !!         and L is M-O length 
    343449      !! 
    344       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
     450      !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
    345451      !!---------------------------------------------------------------------------------- 
    346452      REAL(wp), DIMENSION(jpi,jpj) :: psi_h_ecmwf 
     
    351457      !!---------------------------------------------------------------------------------- 
    352458      ! 
    353       DO jj = 1, jpj 
    354          DO ji = 1, jpi 
    355             ! 
    356             zzeta = MIN(pzeta(ji,jj) , 5.)   ! Very stable conditions (L positif and big!): 
    357             ! 
    358             zx  = ABS(1. - 16.*zzeta)**.25        ! this is actually (1/phi_m)**2  !!! 
    359             !                                     ! eq.3.19, Chap.3, p.33, IFS doc - Cy31r1 
    360             ! Unstable (Paulson 1970) : 
    361             psi_unst = 2.*LOG(0.5*(1. + zx*zx))   ! eq.3.20, Chap.3, p.33, IFS doc - Cy31r1 
    362             ! 
    363             ! Stable: 
    364             psi_stab = -2./3.*(zzeta - 5./0.35)*EXP(-0.35*zzeta) & ! eq.3.22, Chap.3, p.33, IFS doc - Cy31r1 
    365                &       - ABS(1. + 2./3.*zzeta)**1.5 - 2./3.*5./0.35 + 1.  
    366             ! LB: added ABS() to avoid NaN values when unstable, which contaminates the unstable solution... 
    367             ! 
    368             stab = 0.5 + SIGN(0.5, zzeta) ! zzeta > 0 => stab = 1 
    369             ! 
    370             ! 
    371             psi_h_ecmwf(ji,jj) = (1. - stab) * psi_unst &   ! (zzeta < 0) Unstable 
    372                &                +    stab    * psi_stab     ! (zzeta > 0) Stable 
    373             ! 
    374          END DO 
    375       END DO 
    376       ! 
     459      DO_2D_11_11 
     460         ! 
     461         zzeta = MIN(pzeta(ji,jj) , 5._wp)   ! Very stable conditions (L positif and big!): 
     462         ! 
     463         zx  = ABS(1._wp - 16._wp*zzeta)**.25        ! this is actually (1/phi_m)**2  !!! 
     464         !                                     ! eq.3.19, Chap.3, p.33, IFS doc - Cy31r1 
     465         ! Unstable (Paulson 1970) : 
     466         psi_unst = 2._wp*LOG(0.5_wp*(1._wp + zx*zx))   ! eq.3.20, Chap.3, p.33, IFS doc - Cy31r1 
     467         ! 
     468         ! Stable: 
     469         psi_stab = -2._wp/3._wp*(zzeta - 5._wp/0.35_wp)*EXP(-0.35_wp*zzeta) & ! eq.3.22, Chap.3, p.33, IFS doc - Cy31r1 
     470            &       - ABS(1._wp + 2._wp/3._wp*zzeta)**1.5_wp - 2._wp/3._wp*5._wp/0.35_wp + 1._wp 
     471         ! LB: added ABS() to avoid NaN values when unstable, which contaminates the unstable solution... 
     472         ! 
     473         stab = 0.5_wp + SIGN(0.5_wp, zzeta) ! zzeta > 0 => stab = 1 
     474         ! 
     475         ! 
     476         psi_h_ecmwf(ji,jj) = (1._wp - stab) * psi_unst &   ! (zzeta < 0) Unstable 
     477            &                +    stab    * psi_stab        ! (zzeta > 0) Stable 
     478         ! 
     479      END_2D 
    377480   END FUNCTION psi_h_ecmwf 
    378481 
    379  
    380    FUNCTION Ri_bulk( pz, ptz, pdt, pqz, pdq, pub ) 
    381       !!---------------------------------------------------------------------------------- 
    382       !! Bulk Richardson number (Eq. 3.25 IFS doc) 
    383       !! 
    384       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    385       !!---------------------------------------------------------------------------------- 
    386       REAL(wp), DIMENSION(jpi,jpj) ::   Ri_bulk   ! 
    387       ! 
    388       REAL(wp)                    , INTENT(in) ::   pz    ! height above the sea        [m] 
    389       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   ptz   ! air temperature at pz m     [K] 
    390       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pdt   ! ptz - sst                   [K] 
    391       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pqz   ! air temperature at pz m [kg/kg] 
    392       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pdq   ! pqz - ssq               [kg/kg] 
    393       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pub   ! bulk wind speed           [m/s] 
    394       !!---------------------------------------------------------------------------------- 
    395       ! 
    396       Ri_bulk =   grav*pz/(pub*pub)                                          & 
    397          &      * ( pdt/(ptz - 0.5_wp*(pdt + grav*pz/(Cp_dry+Cp_vap*pqz)))   & 
    398          &          + rctv0*pdq ) 
    399       ! 
    400    END FUNCTION Ri_bulk 
    401  
    402  
    403    FUNCTION visc_air(ptak) 
    404       !!---------------------------------------------------------------------------------- 
    405       !! Air kinetic viscosity (m^2/s) given from temperature in degrees... 
    406       !! 
    407       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    408       !!---------------------------------------------------------------------------------- 
    409       REAL(wp), DIMENSION(jpi,jpj)             ::   visc_air   ! 
    410       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   ptak       ! air temperature in (K) 
    411       ! 
    412       INTEGER  ::   ji, jj      ! dummy loop indices 
    413       REAL(wp) ::   ztc, ztc2   ! local scalar 
    414       !!---------------------------------------------------------------------------------- 
    415       ! 
    416       DO jj = 1, jpj 
    417          DO ji = 1, jpi 
    418             ztc  = ptak(ji,jj) - rt0   ! air temp, in deg. C 
    419             ztc2 = ztc*ztc 
    420             visc_air(ji,jj) = 1.326e-5*(1. + 6.542E-3*ztc + 8.301e-6*ztc2 - 4.84e-9*ztc2*ztc) 
    421          END DO 
    422       END DO 
    423       ! 
    424    END FUNCTION visc_air 
    425482 
    426483   !!====================================================================== 
  • NEMO/trunk/src/OCE/SBC/sbcblk_algo_ncar.F90

    r10190 r12377  
    1111   !! 
    1212   !!       Routine turb_ncar maintained and developed in AeroBulk 
    13    !!                     (http://aerobulk.sourceforge.net/) 
     13   !!                     (https://github.com/brodeau/aerobulk/) 
    1414   !! 
    1515   !!                         L. Brodeau, 2015 
     
    3838   USE lib_fortran     ! to use key_nosignedzero 
    3939 
     40   USE sbcblk_phy      ! all thermodynamics functions, rho_air, q_sat, etc... !LB 
    4041 
    4142   IMPLICIT NONE 
    4243   PRIVATE 
    4344 
    44    PUBLIC ::   TURB_NCAR   ! called by sbcblk.F90 
    45  
    46    !                              ! NCAR own values for given constants: 
    47    REAL(wp), PARAMETER ::   rctv0 = 0.608   ! constant to obtain virtual temperature... 
    48     
     45   PUBLIC :: TURB_NCAR   ! called by sbcblk.F90 
     46 
     47   INTEGER , PARAMETER ::   nb_itt = 5        ! number of itterations 
     48   !! * Substitutions 
     49#  include "do_loop_substitute.h90" 
     50 
    4951   !!---------------------------------------------------------------------- 
    5052CONTAINS 
     
    6163      !!                Returns the effective bulk wind speed at 10m to be used in the bulk formulas 
    6264      !! 
    63       !! ** Method : Monin Obukhov Similarity Theory 
    64       !!             + Large & Yeager (2004,2008) closure: CD_n10 = f(U_n10) 
    65       !! 
    66       !! ** References :   Large & Yeager, 2004 / Large & Yeager, 2008 
    67       !! 
    68       !! ** Last update: Laurent Brodeau, June 2014: 
    69       !!    - handles both cases zt=zu and zt/=zu 
    70       !!    - optimized: less 2D arrays allocated and less operations 
    71       !!    - better first guess of stability by checking air-sea difference of virtual temperature 
    72       !!       rather than temperature difference only... 
    73       !!    - added function "cd_neutral_10m" that uses the improved parametrization of 
    74       !!      Large & Yeager 2008. Drag-coefficient reduction for Cyclone conditions! 
    75       !!    - using code-wide physical constants defined into "phycst.mod" rather than redifining them 
    76       !!      => 'vkarmn' and 'grav' 
    77       !! 
    78       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    7965      !! 
    8066      !! INPUT : 
    8167      !! ------- 
    8268      !!    *  zt   : height for temperature and spec. hum. of air            [m] 
    83       !!    *  zu   : height for wind speed (generally 10m)                   [m] 
    84       !!    *  U_zu : scalar wind speed at 10m                                [m/s] 
    85       !!    *  sst  : SST                                                     [K] 
     69      !!    *  zu   : height for wind speed (usually 10m)                     [m] 
     70      !!    *  sst  : bulk SST                                                [K] 
    8671      !!    *  t_zt : potential air temperature at zt                         [K] 
    8772      !!    *  ssq  : specific humidity at saturation at SST                  [kg/kg] 
    8873      !!    *  q_zt : specific humidity of air at zt                          [kg/kg] 
     74      !!    *  U_zu : scalar wind speed at zu                                 [m/s] 
    8975      !! 
    9076      !! 
     
    9682      !!    *  t_zu   : pot. air temperature adjusted at wind height zu       [K] 
    9783      !!    *  q_zu   : specific humidity of air        //                    [kg/kg] 
    98       !!    *  U_blk  : bulk wind at 10m                                      [m/s] 
     84      !!    *  U_blk  : bulk wind speed at zu                                 [m/s] 
     85      !! 
     86      !! 
     87      !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk/) 
    9988      !!---------------------------------------------------------------------------------- 
    10089      REAL(wp), INTENT(in   )                     ::   zt       ! height for t_zt and q_zt                    [m] 
     
    10392      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   t_zt     ! potential air temperature              [Kelvin] 
    10493      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   ssq      ! sea surface specific humidity           [kg/kg] 
    105       REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   q_zt     ! specific air humidity                   [kg/kg] 
     94      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   q_zt     ! specific air humidity at zt             [kg/kg] 
    10695      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   U_zu     ! relative wind module at zu                [m/s] 
    10796      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cd       ! transfer coefficient for momentum         (tau) 
     
    11099      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   t_zu     ! pot. air temp. adjusted at zu               [K] 
    111100      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   q_zu     ! spec. humidity adjusted at zu           [kg/kg] 
    112       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   U_blk    ! bulk wind at 10m                          [m/s] 
     101      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   U_blk    ! bulk wind speed at zu                     [m/s] 
    113102      REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cdn, Chn, Cen ! neutral transfer coefficients 
    114103      ! 
    115       INTEGER ::   j_itt 
    116       LOGICAL ::   l_zt_equal_zu = .FALSE.      ! if q and t are given at same height as U 
    117       INTEGER , PARAMETER ::   nb_itt = 4       ! number of itterations 
     104      INTEGER :: j_itt 
     105      LOGICAL :: l_zt_equal_zu = .FALSE.      ! if q and t are given at same height as U 
    118106      ! 
    119107      REAL(wp), DIMENSION(jpi,jpj) ::   Cx_n10        ! 10m neutral latent/sensible coefficient 
     
    126114      ! 
    127115      l_zt_equal_zu = .FALSE. 
    128       IF( ABS(zu - zt) < 0.01 ) l_zt_equal_zu = .TRUE.    ! testing "zu == zt" is risky with double precision 
    129  
    130       U_blk = MAX( 0.5 , U_zu )   !  relative wind speed at zu (normally 10m), we don't want to fall under 0.5 m/s 
     116      IF( ABS(zu - zt) < 0.01_wp )  l_zt_equal_zu = .TRUE.    ! testing "zu == zt" is risky with double precision 
     117 
     118      U_blk = MAX( 0.5_wp , U_zu )   !  relative wind speed at zu (normally 10m), we don't want to fall under 0.5 m/s 
    131119 
    132120      !! First guess of stability: 
    133       ztmp0 = t_zt*(1. + rctv0*q_zt) - sst*(1. + rctv0*ssq) ! air-sea difference of virtual pot. temp. at zt 
    134       stab  = 0.5 + sign(0.5,ztmp0)                           ! stab = 1 if dTv > 0  => STABLE, 0 if unstable 
     121      ztmp0 = virt_temp(t_zt, q_zt) - virt_temp(sst, ssq) ! air-sea difference of virtual pot. temp. at zt 
     122      stab  = 0.5_wp + sign(0.5_wp,ztmp0)                           ! stab = 1 if dTv > 0  => STABLE, 0 if unstable 
    135123 
    136124      !! Neutral coefficients at 10m: 
     
    139127         ztmp0   (:,:) = cdn_wave(:,:) 
    140128      ELSE 
    141          ztmp0 = cd_neutral_10m( U_blk ) 
     129      ztmp0 = cd_neutral_10m( U_blk ) 
    142130      ENDIF 
    143131 
     
    146134      !! Initializing transf. coeff. with their first guess neutral equivalents : 
    147135      Cd = ztmp0 
    148       Ce = 1.e-3*( 34.6 * sqrt_Cd_n10 ) 
    149       Ch = 1.e-3*sqrt_Cd_n10*(18.*stab + 32.7*(1. - stab)) 
     136      Ce = 1.e-3_wp*( 34.6_wp * sqrt_Cd_n10 ) 
     137      Ch = 1.e-3_wp*sqrt_Cd_n10*(18._wp*stab + 32.7_wp*(1._wp - stab)) 
    150138      stab = sqrt_Cd_n10   ! Temporaty array !!! stab == SQRT(Cd) 
    151139  
    152       IF( ln_cdgw )   Cen = Ce  ; Chn = Ch 
     140      IF( ln_cdgw ) THEN 
     141   Cen = Ce 
     142   Chn = Ch 
     143      ENDIF 
    153144 
    154145      !! Initializing values at z_u with z_t values: 
    155146      t_zu = t_zt   ;   q_zu = q_zt 
    156147 
    157       !!  * Now starting iteration loop 
    158       DO j_itt=1, nb_itt 
     148      !! ITERATION BLOCK 
     149      DO j_itt = 1, nb_itt 
    159150         ! 
    160151         ztmp1 = t_zu - sst   ! Updating air/sea differences 
     
    162153 
    163154         ! Updating turbulent scales :   (L&Y 2004 eq. (7)) 
    164          ztmp1  = Ch/stab*ztmp1    ! theta*   (stab == SQRT(Cd)) 
    165          ztmp2  = Ce/stab*ztmp2    ! q*       (stab == SQRT(Cd)) 
    166  
    167          ztmp0 = 1. + rctv0*q_zu      ! multiply this with t and you have the virtual temperature 
     155         ztmp0 = stab*U_blk       ! u*       (stab == SQRT(Cd)) 
     156         ztmp1 = Ch/stab*ztmp1    ! theta*   (stab == SQRT(Cd)) 
     157         ztmp2 = Ce/stab*ztmp2    ! q*       (stab == SQRT(Cd)) 
    168158 
    169159         ! Estimate the inverse of Monin-Obukov length (1/L) at height zu: 
    170          ztmp0 =  (grav*vkarmn/(t_zu*ztmp0)*(ztmp1*ztmp0 + rctv0*t_zu*ztmp2)) / (Cd*U_blk*U_blk) 
    171          !                                                      ( Cd*U_blk*U_blk is U*^2 at zu ) 
    172  
     160         ztmp0 = One_on_L( t_zu, q_zu, ztmp0, ztmp1, ztmp2 ) 
     161          
    173162         !! Stability parameters : 
    174          zeta_u   = zu*ztmp0   ;  zeta_u = sign( min(abs(zeta_u),10.0), zeta_u ) 
     163         zeta_u   = zu*ztmp0 
     164         zeta_u = sign( min(abs(zeta_u),10._wp), zeta_u ) 
    175165         zpsi_h_u = psi_h( zeta_u ) 
    176166 
     
    178168         IF( .NOT. l_zt_equal_zu ) THEN 
    179169            !! Array 'stab' is free for the moment so using it to store 'zeta_t' 
    180             stab = zt*ztmp0 ;  stab = SIGN( MIN(ABS(stab),10.0), stab )  ! Temporaty array stab == zeta_t !!! 
     170            stab = zt*ztmp0 
     171            stab = SIGN( MIN(ABS(stab),10._wp), stab )  ! Temporaty array stab == zeta_t !!! 
    181172            stab = LOG(zt/zu) + zpsi_h_u - psi_h(stab)                   ! stab just used as temp array again! 
    182173            t_zu = t_zt - ztmp1/vkarmn*stab    ! ztmp1 is still theta*  L&Y 2004 eq.(9b) 
    183174            q_zu = q_zt - ztmp2/vkarmn*stab    ! ztmp2 is still q*      L&Y 2004 eq.(9c) 
    184             q_zu = max(0., q_zu) 
    185          END IF 
    186  
     175            q_zu = max(0._wp, q_zu) 
     176         ENDIF 
     177 
     178         ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)... 
     179         !   In very rare low-wind conditions, the old way of estimating the 
     180         !   neutral wind speed at 10m leads to a negative value that causes the code 
     181         !   to crash. To prevent this a threshold of 0.25m/s is imposed. 
    187182         ztmp2 = psi_m(zeta_u) 
    188183         IF( ln_cdgw ) THEN      ! surface wave case 
    189184            stab = vkarmn / ( vkarmn / sqrt_Cd_n10 - ztmp2 )  ! (stab == SQRT(Cd)) 
    190185            Cd   = stab * stab 
    191             ztmp0 = (LOG(zu/10.) - zpsi_h_u) / vkarmn / sqrt_Cd_n10 
     186            ztmp0 = (LOG(zu/10._wp) - zpsi_h_u) / vkarmn / sqrt_Cd_n10 
    192187            ztmp2 = stab / sqrt_Cd_n10   ! (stab == SQRT(Cd)) 
    193             ztmp1 = 1. + Chn * ztmp0      
     188            ztmp1 = 1._wp + Chn * ztmp0      
    194189            Ch    = Chn * ztmp2 / ztmp1  ! L&Y 2004 eq. (10b) 
    195             ztmp1 = 1. + Cen * ztmp0 
     190            ztmp1 = 1._wp + Cen * ztmp0 
    196191            Ce    = Cen * ztmp2 / ztmp1  ! L&Y 2004 eq. (10c) 
    197192 
    198193         ELSE 
    199             ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)... 
    200             !   In very rare low-wind conditions, the old way of estimating the 
    201             !   neutral wind speed at 10m leads to a negative value that causes the code 
    202             !   to crash. To prevent this a threshold of 0.25m/s is imposed. 
    203             ztmp0 = MAX( 0.25 , U_blk/(1. + sqrt_Cd_n10/vkarmn*(LOG(zu/10.) - ztmp2)) ) ! U_n10 (ztmp2 == psi_m(zeta_u)) 
    204             ztmp0 = cd_neutral_10m(ztmp0)                                               ! Cd_n10 
    205             Cdn(:,:) = ztmp0 
    206             sqrt_Cd_n10 = sqrt(ztmp0) 
    207  
    208             stab    = 0.5 + sign(0.5,zeta_u)                           ! update stability 
    209             Cx_n10  = 1.e-3*sqrt_Cd_n10*(18.*stab + 32.7*(1. - stab))  ! L&Y 2004 eq. (6c-6d)    (Cx_n10 == Ch_n10) 
    210             Chn(:,:) = Cx_n10 
    211  
    212             !! Update of transfer coefficients: 
    213             ztmp1 = 1. + sqrt_Cd_n10/vkarmn*(LOG(zu/10.) - ztmp2)   ! L&Y 2004 eq. (10a) (ztmp2 == psi_m(zeta_u)) 
    214             Cd      = ztmp0 / ( ztmp1*ztmp1 ) 
    215             stab = SQRT( Cd ) ! Temporary array !!! (stab == SQRT(Cd)) 
    216  
    217             ztmp0 = (LOG(zu/10.) - zpsi_h_u) / vkarmn / sqrt_Cd_n10 
    218             ztmp2 = stab / sqrt_Cd_n10   ! (stab == SQRT(Cd)) 
    219             ztmp1 = 1. + Cx_n10*ztmp0    ! (Cx_n10 == Ch_n10) 
    220             Ch  = Cx_n10*ztmp2 / ztmp1   ! L&Y 2004 eq. (10b) 
    221  
    222             Cx_n10  = 1.e-3 * (34.6 * sqrt_Cd_n10)  ! L&Y 2004 eq. (6b)    ! Cx_n10 == Ce_n10 
    223             Cen(:,:) = Cx_n10 
    224             ztmp1 = 1. + Cx_n10*ztmp0 
    225             Ce  = Cx_n10*ztmp2 / ztmp1  ! L&Y 2004 eq. (10c) 
    226             ENDIF 
    227          ! 
    228       END DO 
    229       ! 
     194         ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)... 
     195         !   In very rare low-wind conditions, the old way of estimating the 
     196         !   neutral wind speed at 10m leads to a negative value that causes the code 
     197         !   to crash. To prevent this a threshold of 0.25m/s is imposed. 
     198         ztmp0 = MAX( 0.25_wp , U_blk/(1._wp + sqrt_Cd_n10/vkarmn*(LOG(zu/10._wp) - ztmp2)) ) ! U_n10 (ztmp2 == psi_m(zeta_u)) 
     199         ztmp0 = cd_neutral_10m(ztmp0)                                               ! Cd_n10 
     200         Cdn(:,:) = ztmp0 
     201         sqrt_Cd_n10 = sqrt(ztmp0) 
     202 
     203         stab    = 0.5_wp + sign(0.5_wp,zeta_u)                        ! update stability 
     204         Cx_n10  = 1.e-3_wp*sqrt_Cd_n10*(18._wp*stab + 32.7_wp*(1._wp - stab))  ! L&Y 2004 eq. (6c-6d)    (Cx_n10 == Ch_n10) 
     205         Chn(:,:) = Cx_n10 
     206 
     207         !! Update of transfer coefficients: 
     208         ztmp1 = 1._wp + sqrt_Cd_n10/vkarmn*(LOG(zu/10._wp) - ztmp2)   ! L&Y 2004 eq. (10a) (ztmp2 == psi_m(zeta_u)) 
     209         Cd      = ztmp0 / ( ztmp1*ztmp1 ) 
     210         stab = SQRT( Cd ) ! Temporary array !!! (stab == SQRT(Cd)) 
     211 
     212         ztmp0 = (LOG(zu/10._wp) - zpsi_h_u) / vkarmn / sqrt_Cd_n10 
     213         ztmp2 = stab / sqrt_Cd_n10   ! (stab == SQRT(Cd)) 
     214         ztmp1 = 1._wp + Cx_n10*ztmp0    ! (Cx_n10 == Ch_n10) 
     215         Ch  = Cx_n10*ztmp2 / ztmp1   ! L&Y 2004 eq. (10b) 
     216 
     217         Cx_n10  = 1.e-3_wp * (34.6_wp * sqrt_Cd_n10)  ! L&Y 2004 eq. (6b)    ! Cx_n10 == Ce_n10 
     218         Cen(:,:) = Cx_n10 
     219         ztmp1 = 1._wp + Cx_n10*ztmp0 
     220         Ce  = Cx_n10*ztmp2 / ztmp1  ! L&Y 2004 eq. (10c) 
     221         ENDIF 
     222 
     223      END DO !DO j_itt = 1, nb_itt 
     224 
    230225   END SUBROUTINE turb_ncar 
    231226 
     
    238233      !! Origin: Large & Yeager 2008 eq.(11a) and eq.(11b) 
    239234      !! 
    240       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
     235      !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
    241236      !!---------------------------------------------------------------------------------- 
    242237      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pw10           ! scalar wind speed at 10m (m/s) 
     
    247242      !!---------------------------------------------------------------------------------- 
    248243      ! 
    249       DO jj = 1, jpj 
    250          DO ji = 1, jpi 
    251             ! 
    252             zw  = pw10(ji,jj) 
    253             zw6 = zw*zw*zw 
    254             zw6 = zw6*zw6 
    255             ! 
    256             ! When wind speed > 33 m/s => Cyclone conditions => special treatment 
    257             zgt33 = 0.5 + SIGN( 0.5, (zw - 33.) )   ! If pw10 < 33. => 0, else => 1 
    258             ! 
    259             cd_neutral_10m(ji,jj) = 1.e-3 * ( & 
    260                &       (1. - zgt33)*( 2.7/zw + 0.142 + zw/13.09 - 3.14807E-10*zw6) & ! wind <  33 m/s 
    261                &      +    zgt33   *      2.34 )                                     ! wind >= 33 m/s 
    262             ! 
    263             cd_neutral_10m(ji,jj) = MAX(cd_neutral_10m(ji,jj), 1.E-6) 
    264             ! 
    265          END DO 
    266       END DO 
     244      DO_2D_11_11 
     245         ! 
     246         zw  = pw10(ji,jj) 
     247         zw6 = zw*zw*zw 
     248         zw6 = zw6*zw6 
     249         ! 
     250         ! When wind speed > 33 m/s => Cyclone conditions => special treatment 
     251         zgt33 = 0.5_wp + SIGN( 0.5_wp, (zw - 33._wp) )   ! If pw10 < 33. => 0, else => 1 
     252         ! 
     253         cd_neutral_10m(ji,jj) = 1.e-3_wp * ( & 
     254            &       (1._wp - zgt33)*( 2.7_wp/zw + 0.142_wp + zw/13.09_wp - 3.14807E-10_wp*zw6) & ! wind <  33 m/s 
     255            &      +    zgt33   *      2.34_wp )                                                 ! wind >= 33 m/s 
     256         ! 
     257         cd_neutral_10m(ji,jj) = MAX(cd_neutral_10m(ji,jj), 1.E-6_wp) 
     258         ! 
     259      END_2D 
    267260      ! 
    268261   END FUNCTION cd_neutral_10m 
     
    273266      !! Universal profile stability function for momentum 
    274267      !!    !! Psis, L&Y 2004 eq. (8c), (8d), (8e) 
    275       !!      
    276       !! pzet0 : stability paramenter, z/L where z is altitude measurement                                           
     268      !! 
     269      !! pzeta : stability paramenter, z/L where z is altitude measurement 
    277270      !!         and L is M-O length 
    278271      !! 
    279       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    280       !!---------------------------------------------------------------------------------- 
    281       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pzeta 
    282       REAL(wp), DIMENSION(jpi,jpj)             ::   psi_m 
    283       ! 
    284       INTEGER  ::   ji, jj         ! dummy loop indices 
     272      !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
     273      !!---------------------------------------------------------------------------------- 
     274      REAL(wp), DIMENSION(jpi,jpj) :: psi_m 
     275      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta 
     276      ! 
     277      INTEGER  ::   ji, jj    ! dummy loop indices 
    285278      REAL(wp) :: zx2, zx, zstab   ! local scalars 
    286279      !!---------------------------------------------------------------------------------- 
    287       ! 
    288       DO jj = 1, jpj 
    289          DO ji = 1, jpi 
    290             zx2 = SQRT( ABS( 1. - 16.*pzeta(ji,jj) ) ) 
    291             zx2 = MAX ( zx2 , 1. ) 
    292             zx  = SQRT( zx2 ) 
    293             zstab = 0.5 + SIGN( 0.5 , pzeta(ji,jj) ) 
    294             ! 
    295             psi_m(ji,jj) =        zstab  * (-5.*pzeta(ji,jj))       &          ! Stable 
    296                &          + (1. - zstab) * (2.*LOG((1. + zx)*0.5)   &          ! Unstable 
    297                &               + LOG((1. + zx2)*0.5) - 2.*ATAN(zx) + rpi*0.5)  !    " 
    298             ! 
    299          END DO 
    300       END DO 
    301       ! 
     280      DO_2D_11_11 
     281         zx2 = SQRT( ABS( 1._wp - 16._wp*pzeta(ji,jj) ) ) 
     282         zx2 = MAX( zx2 , 1._wp ) 
     283         zx  = SQRT( zx2 ) 
     284         zstab = 0.5_wp + SIGN( 0.5_wp , pzeta(ji,jj) ) 
     285         ! 
     286         psi_m(ji,jj) =        zstab  * (-5._wp*pzeta(ji,jj))       &          ! Stable 
     287            &          + (1._wp - zstab) * (2._wp*LOG((1._wp + zx)*0.5_wp)   &          ! Unstable 
     288            &               + LOG((1._wp + zx2)*0.5_wp) - 2._wp*ATAN(zx) + rpi*0.5_wp)  !    " 
     289         ! 
     290      END_2D 
    302291   END FUNCTION psi_m 
    303292 
     
    308297      !!    !! Psis, L&Y 2004 eq. (8c), (8d), (8e) 
    309298      !! 
    310       !! pzet0 : stability paramenter, z/L where z is altitude measurement                                           
     299      !! pzeta : stability paramenter, z/L where z is altitude measurement 
    311300      !!         and L is M-O length 
    312301      !! 
    313       !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://sourceforge.net/p/aerobulk) 
    314       !!---------------------------------------------------------------------------------- 
     302      !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 
     303      !!---------------------------------------------------------------------------------- 
     304      REAL(wp), DIMENSION(jpi,jpj) :: psi_h 
    315305      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta 
    316       REAL(wp), DIMENSION(jpi,jpj)             :: psi_h 
    317       ! 
    318       INTEGER  ::   ji, jj    ! dummy loop indices 
     306      ! 
     307      INTEGER  ::   ji, jj     ! dummy loop indices 
    319308      REAL(wp) :: zx2, zstab  ! local scalars 
    320309      !!---------------------------------------------------------------------------------- 
    321310      ! 
    322       DO jj = 1, jpj 
    323          DO ji = 1, jpi 
    324             zx2 = SQRT( ABS( 1. - 16.*pzeta(ji,jj) ) ) 
    325             zx2 = MAX ( zx2 , 1. ) 
    326             zstab = 0.5 + SIGN( 0.5 , pzeta(ji,jj) ) 
    327             ! 
    328             psi_h(ji,jj) =         zstab  * (-5.*pzeta(ji,jj))        &  ! Stable 
    329                &           + (1. - zstab) * (2.*LOG( (1. + zx2)*0.5 ))   ! Unstable 
    330             ! 
    331          END DO 
    332       END DO 
    333       ! 
     311      DO_2D_11_11 
     312         zx2 = SQRT( ABS( 1._wp - 16._wp*pzeta(ji,jj) ) ) 
     313         zx2 = MAX( zx2 , 1._wp ) 
     314         zstab = 0.5_wp + SIGN( 0.5_wp , pzeta(ji,jj) ) 
     315         ! 
     316         psi_h(ji,jj) =         zstab  * (-5._wp*pzeta(ji,jj))        &  ! Stable 
     317            &           + (1._wp - zstab) * (2._wp*LOG( (1._wp + zx2)*0.5_wp ))   ! Unstable 
     318         ! 
     319      END_2D 
    334320   END FUNCTION psi_h 
    335321 
  • NEMO/trunk/src/OCE/SBC/sbccpl.F90

    r12288 r12377  
    2727   USE sbcwave         ! surface boundary condition: waves 
    2828   USE phycst          ! physical constants 
     29   USE isf_oce , ONLY : l_isfoasis, fwfisf_oasis ! ice shelf boundary condition 
    2930#if defined key_si3 
    3031   USE ice            ! ice variables 
     
    3233   USE cpl_oasis3     ! OASIS3 coupling 
    3334   USE geo2ocean      !  
    34    USE oce     , ONLY : tsn, un, vn, sshn, ub, vb, sshb, fraqsr_1lev 
     35   USE oce     , ONLY : ts, uu, vv, ssh, fraqsr_1lev 
    3536   USE ocealb         !  
    3637   USE eosbn2         !  
    3738   USE sbcrnf  , ONLY : l_rnfcpl 
    38    USE sbcisf  , ONLY : l_isfcpl 
    3939#if defined key_cice 
    4040   USE ice_domain_size, only: ncat 
     
    198198 
    199199   !! Substitution 
    200 #  include "vectopt_loop_substitute.h90" 
     200#  include "do_loop_substitute.h90" 
    201201   !!---------------------------------------------------------------------- 
    202202   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    264264      ! ================================ ! 
    265265      ! 
    266       REWIND( numnam_ref )              ! Namelist namsbc_cpl in reference namelist : Variables for OASIS coupling 
    267266      READ  ( numnam_ref, namsbc_cpl, IOSTAT = ios, ERR = 901) 
    268267901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_cpl in reference namelist' ) 
    269268      ! 
    270       REWIND( numnam_cfg )              ! Namelist namsbc_cpl in configuration namelist : Variables for OASIS coupling 
    271269      READ  ( numnam_cfg, namsbc_cpl, IOSTAT = ios, ERR = 902 ) 
    272270902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_cpl in configuration namelist' ) 
     
    453451      CASE( 'conservative'  ) 
    454452         srcv( (/jpr_rain, jpr_snow, jpr_ievp, jpr_tevp/) )%laction = .TRUE. 
    455          IF ( k_ice <= 1 )  srcv(jpr_ievp)%laction = .FALSE. 
     453         IF( k_ice <= 1 )  srcv(jpr_ievp)%laction = .FALSE. 
    456454      CASE( 'oce and ice'   )   ;   srcv( (/jpr_ievp, jpr_sbpr, jpr_semp, jpr_oemp/) )%laction = .TRUE. 
    457455      CASE default              ;   CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_rcv_emp%cldes' ) 
     
    474472      srcv(jpr_icb)%clname = 'OIceberg'   ;  IF( TRIM( sn_rcv_icb%cldes) == 'coupled' )   srcv(jpr_icb)%laction = .TRUE. 
    475473 
    476       IF( srcv(jpr_isf)%laction .AND. ln_isf ) THEN 
    477          l_isfcpl             = .TRUE.                      ! -> no need to read isf in sbcisf 
     474      IF( srcv(jpr_isf)%laction ) THEN 
     475         l_isfoasis = .TRUE.  ! -> isf fwf comes from oasis 
    478476         IF(lwp) WRITE(numout,*) 
    479477         IF(lwp) WRITE(numout,*) '   iceshelf received from oasis ' 
     478         CALL ctl_stop('STOP','not coded') 
    480479      ENDIF 
    481480      ! 
     
    533532      !                                                      ! ------------------------- ! 
    534533      srcv(jpr_taum)%clname = 'O_TauMod'   ;   IF( TRIM(sn_rcv_taumod%cldes) == 'coupled' )   srcv(jpr_taum)%laction = .TRUE. 
    535       lhftau = srcv(jpr_taum)%laction 
    536534      ! 
    537535      !                                                      ! ------------------------- ! 
     
    558556      srcv(jpr_botm )%clname = 'OBotMlt' 
    559557      IF( TRIM(sn_rcv_iceflx%cldes) == 'coupled' ) THEN 
    560          IF ( TRIM( sn_rcv_iceflx%clcat ) == 'yes' ) THEN 
     558         IF( TRIM( sn_rcv_iceflx%clcat ) == 'yes' ) THEN 
    561559            srcv(jpr_topm:jpr_botm)%nct = nn_cats_cpl 
    562560         ELSE 
     
    569567      !                                                      ! ------------------------- ! 
    570568      srcv(jpr_ts_ice)%clname = 'OTsfIce'    ! needed by Met Office 
    571       IF ( TRIM( sn_rcv_ts_ice%cldes ) == 'ice' )   srcv(jpr_ts_ice)%laction = .TRUE. 
    572       IF ( TRIM( sn_rcv_ts_ice%clcat ) == 'yes' )   srcv(jpr_ts_ice)%nct     = nn_cats_cpl 
    573       IF ( TRIM( sn_rcv_emp%clcat    ) == 'yes' )   srcv(jpr_ievp)%nct       = nn_cats_cpl 
     569      IF( TRIM( sn_rcv_ts_ice%cldes ) == 'ice' )   srcv(jpr_ts_ice)%laction = .TRUE. 
     570      IF( TRIM( sn_rcv_ts_ice%clcat ) == 'yes' )   srcv(jpr_ts_ice)%nct     = nn_cats_cpl 
     571      IF( TRIM( sn_rcv_emp%clcat    ) == 'yes' )   srcv(jpr_ievp)%nct       = nn_cats_cpl 
    574572 
    575573#if defined key_si3 
     
    699697         ! for example O_Runoff received by OPA from SAS and therefore O_Runoff received by SAS from the Atmosphere 
    700698         DO jn = 1, jprcv 
    701             IF ( srcv(jn)%clname(1:1) == "O" ) srcv(jn)%clname = "S"//srcv(jn)%clname(2:LEN(srcv(jn)%clname)) 
     699            IF( srcv(jn)%clname(1:1) == "O" ) srcv(jn)%clname = "S"//srcv(jn)%clname(2:LEN(srcv(jn)%clname)) 
    702700         END DO 
    703701         ! 
     
    726724      ! =================================================== ! 
    727725      DO jn = 1, jprcv 
    728          IF ( srcv(jn)%laction ) ALLOCATE( frcv(jn)%z3(jpi,jpj,srcv(jn)%nct) ) 
     726         IF( srcv(jn)%laction ) ALLOCATE( frcv(jn)%z3(jpi,jpj,srcv(jn)%nct) ) 
    729727      END DO 
    730728      ! Allocate taum part of frcv which is used even when not received as coupling field 
    731       IF ( .NOT. srcv(jpr_taum)%laction ) ALLOCATE( frcv(jpr_taum)%z3(jpi,jpj,srcv(jpr_taum)%nct) ) 
     729      IF( .NOT. srcv(jpr_taum)%laction ) ALLOCATE( frcv(jpr_taum)%z3(jpi,jpj,srcv(jpr_taum)%nct) ) 
    732730      ! Allocate w10m part of frcv which is used even when not received as coupling field 
    733       IF ( .NOT. srcv(jpr_w10m)%laction ) ALLOCATE( frcv(jpr_w10m)%z3(jpi,jpj,srcv(jpr_w10m)%nct) ) 
     731      IF( .NOT. srcv(jpr_w10m)%laction ) ALLOCATE( frcv(jpr_w10m)%z3(jpi,jpj,srcv(jpr_w10m)%nct) ) 
    734732      ! Allocate jpr_otx1 part of frcv which is used even when not received as coupling field 
    735       IF ( .NOT. srcv(jpr_otx1)%laction ) ALLOCATE( frcv(jpr_otx1)%z3(jpi,jpj,srcv(jpr_otx1)%nct) ) 
    736       IF ( .NOT. srcv(jpr_oty1)%laction ) ALLOCATE( frcv(jpr_oty1)%z3(jpi,jpj,srcv(jpr_oty1)%nct) ) 
     733      IF( .NOT. srcv(jpr_otx1)%laction ) ALLOCATE( frcv(jpr_otx1)%z3(jpi,jpj,srcv(jpr_otx1)%nct) ) 
     734      IF( .NOT. srcv(jpr_oty1)%laction ) ALLOCATE( frcv(jpr_oty1)%z3(jpi,jpj,srcv(jpr_oty1)%nct) ) 
    737735      ! Allocate itx1 and ity1 as they are used in sbc_cpl_ice_tau even if srcv(jpr_itx1)%laction = .FALSE. 
    738736      IF( k_ice /= 0 ) THEN 
    739          IF ( .NOT. srcv(jpr_itx1)%laction ) ALLOCATE( frcv(jpr_itx1)%z3(jpi,jpj,srcv(jpr_itx1)%nct) ) 
    740          IF ( .NOT. srcv(jpr_ity1)%laction ) ALLOCATE( frcv(jpr_ity1)%z3(jpi,jpj,srcv(jpr_ity1)%nct) ) 
    741       END IF 
     737         IF( .NOT. srcv(jpr_itx1)%laction ) ALLOCATE( frcv(jpr_itx1)%z3(jpi,jpj,srcv(jpr_itx1)%nct) ) 
     738         IF( .NOT. srcv(jpr_ity1)%laction ) ALLOCATE( frcv(jpr_ity1)%z3(jpi,jpj,srcv(jpr_ity1)%nct) ) 
     739      ENDIF 
    742740 
    743741      ! ================================ ! 
     
    763761      CASE( 'oce and ice' , 'weighted oce and ice' , 'oce and weighted ice' ) 
    764762         ssnd( (/jps_toce, jps_tice/) )%laction = .TRUE. 
    765          IF ( TRIM( sn_snd_temp%clcat ) == 'yes' )  ssnd(jps_tice)%nct = nn_cats_cpl 
     763         IF( TRIM( sn_snd_temp%clcat ) == 'yes' )  ssnd(jps_tice)%nct = nn_cats_cpl 
    766764      CASE( 'mixed oce-ice'                        )   ;   ssnd( jps_tmix )%laction = .TRUE. 
    767765      CASE default   ;   CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_temp%cldes' ) 
     
    783781      !     1. sending mixed oce-ice albedo or 
    784782      !     2. receiving mixed oce-ice solar radiation  
    785       IF ( TRIM ( sn_snd_alb%cldes ) == 'mixed oce-ice' .OR. TRIM ( sn_rcv_qsr%cldes ) == 'mixed oce-ice' ) THEN 
     783      IF( TRIM ( sn_snd_alb%cldes ) == 'mixed oce-ice' .OR. TRIM ( sn_rcv_qsr%cldes ) == 'mixed oce-ice' ) THEN 
    786784         CALL oce_alb( zaos, zacs ) 
    787785         ! Due to lack of information on nebulosity : mean clear/overcast sky 
     
    802800         ssnd(jps_fice1)%laction = .TRUE.                 ! First-order regridded ice concentration, to be used producing atmos-to-ice fluxes (Met Office requirement) 
    803801! Currently no namelist entry to determine sending of multi-category ice fraction so use the thickness entry for now 
    804          IF ( TRIM( sn_snd_thick%clcat  ) == 'yes' ) ssnd(jps_fice)%nct  = nn_cats_cpl 
    805          IF ( TRIM( sn_snd_thick1%clcat ) == 'yes' ) ssnd(jps_fice1)%nct = nn_cats_cpl 
     802         IF( TRIM( sn_snd_thick%clcat  ) == 'yes' ) ssnd(jps_fice)%nct  = nn_cats_cpl 
     803         IF( TRIM( sn_snd_thick1%clcat ) == 'yes' ) ssnd(jps_fice1)%nct = nn_cats_cpl 
    806804      ENDIF 
    807805       
    808       IF (TRIM( sn_snd_ifrac%cldes )  == 'coupled') ssnd(jps_ficet)%laction = .TRUE.  
     806      IF(TRIM( sn_snd_ifrac%cldes )  == 'coupled') ssnd(jps_ficet)%laction = .TRUE.  
    809807 
    810808      SELECT CASE ( TRIM( sn_snd_thick%cldes ) ) 
     
    812810      CASE( 'ice and snow' )  
    813811         ssnd(jps_hice:jps_hsnw)%laction = .TRUE. 
    814          IF ( TRIM( sn_snd_thick%clcat ) == 'yes' ) THEN 
     812         IF( TRIM( sn_snd_thick%clcat ) == 'yes' ) THEN 
    815813            ssnd(jps_hice:jps_hsnw)%nct = nn_cats_cpl 
    816814         ENDIF 
    817815      CASE ( 'weighted ice and snow' )  
    818816         ssnd(jps_hice:jps_hsnw)%laction = .TRUE. 
    819          IF ( TRIM( sn_snd_thick%clcat ) == 'yes' ) ssnd(jps_hice:jps_hsnw)%nct = nn_cats_cpl 
     817         IF( TRIM( sn_snd_thick%clcat ) == 'yes' ) ssnd(jps_hice:jps_hsnw)%nct = nn_cats_cpl 
    820818      CASE default   ;   CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_thick%cldes' ) 
    821819      END SELECT 
     
    834832         ssnd(jps_a_p)%laction  = .TRUE.  
    835833         ssnd(jps_ht_p)%laction = .TRUE.  
    836          IF ( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN  
     834         IF( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN  
    837835            ssnd(jps_a_p)%nct  = nn_cats_cpl  
    838836            ssnd(jps_ht_p)%nct = nn_cats_cpl  
    839837         ELSE  
    840             IF ( nn_cats_cpl > 1 ) THEN  
     838            IF( nn_cats_cpl > 1 ) THEN  
    841839               CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_mpnd%cldes if not exchanging category fields' )  
    842840            ENDIF  
     
    845843         ssnd(jps_a_p)%laction  = .TRUE.  
    846844         ssnd(jps_ht_p)%laction = .TRUE.  
    847          IF ( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN  
     845         IF( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN  
    848846            ssnd(jps_a_p)%nct  = nn_cats_cpl   
    849847            ssnd(jps_ht_p)%nct = nn_cats_cpl   
     
    919917      CASE ( 'ice only' )  
    920918         ssnd(jps_ttilyr)%laction = .TRUE.  
    921          IF ( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) THEN  
     919         IF( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) THEN  
    922920            ssnd(jps_ttilyr)%nct = nn_cats_cpl  
    923921         ELSE  
    924             IF ( nn_cats_cpl > 1 ) THEN  
     922            IF( nn_cats_cpl > 1 ) THEN  
    925923               CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_ttilyr%cldes if not exchanging category fields' )  
    926924            ENDIF  
     
    928926      CASE ( 'weighted ice' )  
    929927         ssnd(jps_ttilyr)%laction = .TRUE.  
    930          IF ( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) ssnd(jps_ttilyr)%nct = nn_cats_cpl  
     928         IF( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) ssnd(jps_ttilyr)%nct = nn_cats_cpl  
    931929      CASE default   ;   CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_ttilyr%cldes;'//sn_snd_ttilyr%cldes )  
    932930      END SELECT  
     
    938936      CASE ( 'ice only' )  
    939937         ssnd(jps_kice)%laction = .TRUE.  
    940          IF ( TRIM( sn_snd_cond%clcat ) == 'yes' ) THEN  
     938         IF( TRIM( sn_snd_cond%clcat ) == 'yes' ) THEN  
    941939            ssnd(jps_kice)%nct = nn_cats_cpl  
    942940         ELSE  
    943             IF ( nn_cats_cpl > 1 ) THEN  
     941            IF( nn_cats_cpl > 1 ) THEN  
    944942               CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_cond%cldes if not exchanging category fields' )  
    945943            ENDIF  
     
    947945      CASE ( 'weighted ice' )  
    948946         ssnd(jps_kice)%laction = .TRUE.  
    949          IF ( TRIM( sn_snd_cond%clcat ) == 'yes' ) ssnd(jps_kice)%nct = nn_cats_cpl  
     947         IF( TRIM( sn_snd_cond%clcat ) == 'yes' ) ssnd(jps_kice)%nct = nn_cats_cpl  
    950948      CASE default   ;   CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_cond%cldes;'//sn_snd_cond%cldes )  
    951949      END SELECT  
     
    10081006         ! for example O_SSTSST sent by OPA to SAS and therefore S_SSTSST sent by SAS to the Atmosphere 
    10091007         DO jn = 1, jpsnd 
    1010             IF ( ssnd(jn)%clname(1:1) == "O" ) ssnd(jn)%clname = "S"//ssnd(jn)%clname(2:LEN(ssnd(jn)%clname)) 
     1008            IF( ssnd(jn)%clname(1:1) == "O" ) ssnd(jn)%clname = "S"//ssnd(jn)%clname(2:LEN(ssnd(jn)%clname)) 
    10111009         END DO 
    10121010         ! 
     
    10351033      CALL cpl_define(jprcv, jpsnd, nn_cplmodel) 
    10361034       
    1037       IF (ln_usecplmask) THEN  
     1035      IF(ln_usecplmask) THEN  
    10381036         xcplmask(:,:,:) = 0. 
    10391037         CALL iom_open( 'cplmask', inum ) 
     
    10491047 
    10501048 
    1051    SUBROUTINE sbc_cpl_rcv( kt, k_fsbc, k_ice )      
     1049   SUBROUTINE sbc_cpl_rcv( kt, k_fsbc, k_ice, Kbb, Kmm )      
    10521050      !!---------------------------------------------------------------------- 
    10531051      !!             ***  ROUTINE sbc_cpl_rcv  *** 
     
    10991097      INTEGER, INTENT(in) ::   k_fsbc      ! frequency of sbc (-> ice model) computation  
    11001098      INTEGER, INTENT(in) ::   k_ice       ! ice management in the sbc (=0/1/2/3) 
     1099      INTEGER, INTENT(in) ::   Kbb, Kmm    ! ocean model time level indices 
    11011100      !! 
    11021101      LOGICAL  ::   llnewtx, llnewtau      ! update wind stress components and module?? 
     
    11661165            !                               
    11671166            IF( srcv(jpr_otx1)%clgrid == 'T' ) THEN 
    1168                DO jj = 2, jpjm1                                          ! T ==> (U,V) 
    1169                   DO ji = fs_2, fs_jpim1   ! vector opt. 
    1170                      frcv(jpr_otx1)%z3(ji,jj,1) = 0.5 * ( frcv(jpr_otx1)%z3(ji+1,jj  ,1) + frcv(jpr_otx1)%z3(ji,jj,1) ) 
    1171                      frcv(jpr_oty1)%z3(ji,jj,1) = 0.5 * ( frcv(jpr_oty1)%z3(ji  ,jj+1,1) + frcv(jpr_oty1)%z3(ji,jj,1) ) 
    1172                   END DO 
    1173                END DO 
     1167               DO_2D_00_00 
     1168                  frcv(jpr_otx1)%z3(ji,jj,1) = 0.5 * ( frcv(jpr_otx1)%z3(ji+1,jj  ,1) + frcv(jpr_otx1)%z3(ji,jj,1) ) 
     1169                  frcv(jpr_oty1)%z3(ji,jj,1) = 0.5 * ( frcv(jpr_oty1)%z3(ji  ,jj+1,1) + frcv(jpr_oty1)%z3(ji,jj,1) ) 
     1170               END_2D 
    11741171               CALL lbc_lnk_multi( 'sbccpl', frcv(jpr_otx1)%z3(:,:,1), 'U',  -1., frcv(jpr_oty1)%z3(:,:,1), 'V',  -1. ) 
    11751172            ENDIF 
     
    11921189         ! => need to be done only when otx1 was changed 
    11931190         IF( llnewtx ) THEN 
    1194             DO jj = 2, jpjm1 
    1195                DO ji = fs_2, fs_jpim1   ! vect. opt. 
    1196                   zzx = frcv(jpr_otx1)%z3(ji-1,jj  ,1) + frcv(jpr_otx1)%z3(ji,jj,1) 
    1197                   zzy = frcv(jpr_oty1)%z3(ji  ,jj-1,1) + frcv(jpr_oty1)%z3(ji,jj,1) 
    1198                   frcv(jpr_taum)%z3(ji,jj,1) = 0.5 * SQRT( zzx * zzx + zzy * zzy ) 
    1199                END DO 
    1200             END DO 
     1191            DO_2D_00_00 
     1192               zzx = frcv(jpr_otx1)%z3(ji-1,jj  ,1) + frcv(jpr_otx1)%z3(ji,jj,1) 
     1193               zzy = frcv(jpr_oty1)%z3(ji  ,jj-1,1) + frcv(jpr_oty1)%z3(ji,jj,1) 
     1194               frcv(jpr_taum)%z3(ji,jj,1) = 0.5 * SQRT( zzx * zzx + zzy * zzy ) 
     1195            END_2D 
    12011196            CALL lbc_lnk( 'sbccpl', frcv(jpr_taum)%z3(:,:,1), 'T', 1. ) 
    12021197            llnewtau = .TRUE. 
     
    12191214         IF( llnewtau ) THEN  
    12201215            zcoef = 1. / ( zrhoa * zcdrag )  
    1221             DO jj = 1, jpj 
    1222                DO ji = 1, jpi  
    1223                   frcv(jpr_w10m)%z3(ji,jj,1) = SQRT( frcv(jpr_taum)%z3(ji,jj,1) * zcoef ) 
    1224                END DO 
    1225             END DO 
     1216            DO_2D_11_11 
     1217               frcv(jpr_w10m)%z3(ji,jj,1) = SQRT( frcv(jpr_taum)%z3(ji,jj,1) * zcoef ) 
     1218            END_2D 
    12261219         ENDIF 
    12271220      ENDIF 
     
    12621255     
    12631256          IF( kt == nit000 ) ssh_ibb(:,:) = ssh_ib(:,:)  ! correct this later (read from restart if possible)  
    1264       END IF  
     1257      ENDIF  
    12651258      ! 
    12661259      IF( ln_sdw ) THEN  ! Stokes Drift correction activated 
     
    12981291         IF( srcv(jpr_sdrftx)%laction .OR. srcv(jpr_sdrfty)%laction .OR. srcv(jpr_wper)%laction & 
    12991292                                      .OR. srcv(jpr_hsig)%laction   .OR. srcv(jpr_wfreq)%laction) THEN 
    1300             CALL sbc_stokes() 
     1293            CALL sbc_stokes( Kmm ) 
    13011294         ENDIF 
    13021295      ENDIF 
     
    13501343      IF( srcv(jpr_ocx1)%laction ) THEN                      ! received by sas in case of opa <-> sas coupling 
    13511344         ssu_m(:,:) = frcv(jpr_ocx1)%z3(:,:,1) 
    1352          ub (:,:,1) = ssu_m(:,:)                             ! will be used in icestp in the call of ice_forcing_tau 
    1353          un (:,:,1) = ssu_m(:,:)                             ! will be used in sbc_cpl_snd if atmosphere coupling 
     1345         uu(:,:,1,Kbb) = ssu_m(:,:)                          ! will be used in icestp in the call of ice_forcing_tau 
     1346         uu(:,:,1,Kmm) = ssu_m(:,:)                          ! will be used in sbc_cpl_snd if atmosphere coupling 
    13541347         CALL iom_put( 'ssu_m', ssu_m ) 
    13551348      ENDIF 
    13561349      IF( srcv(jpr_ocy1)%laction ) THEN 
    13571350         ssv_m(:,:) = frcv(jpr_ocy1)%z3(:,:,1) 
    1358          vb (:,:,1) = ssv_m(:,:)                             ! will be used in icestp in the call of ice_forcing_tau 
    1359          vn (:,:,1) = ssv_m(:,:)                             ! will be used in sbc_cpl_snd if atmosphere coupling 
     1351         vv(:,:,1,Kbb) = ssv_m(:,:)                          ! will be used in icestp in the call of ice_forcing_tau 
     1352         vv(:,:,1,Kmm) = ssv_m(:,:)                          ! will be used in sbc_cpl_snd if atmosphere coupling 
    13601353         CALL iom_put( 'ssv_m', ssv_m ) 
    13611354      ENDIF 
     
    14011394             rnf(:,:)    = rnf(:,:) + fwficb(:,:)   ! iceberg added to runfofs 
    14021395         ENDIF 
    1403          IF( srcv(jpr_isf)%laction )  fwfisf(:,:) = - frcv(jpr_isf)%z3(:,:,1)  ! fresh water flux from the isf (fwfisf <0 mean melting)   
     1396         ! 
     1397         ! ice shelf fwf 
     1398         IF( srcv(jpr_isf)%laction )  THEN 
     1399            fwfisf_oasis(:,:) = - frcv(jpr_isf)%z3(:,:,1)  ! fresh water flux from the isf (fwfisf <0 mean melting)   
     1400         END IF 
    14041401         
    14051402         IF( ln_mixcpl ) THEN   ;   emp(:,:) = emp(:,:) * xcplmask(:,:,0) + zemp(:,:) * zmsk(:,:) 
     
    14111408         ELSE IF( srcv(jpr_qnsmix)%laction ) THEN   ;   zqns(:,:) = frcv(jpr_qnsmix)%z3(:,:,1) 
    14121409         ELSE                                       ;   zqns(:,:) = 0._wp 
    1413          END IF 
     1410         ENDIF 
    14141411         ! update qns over the free ocean with: 
    14151412         IF( nn_components /= jp_iam_opa ) THEN 
     
    15461543            p_tauj(:,:) = frcv(jpr_ity1)%z3(:,:,1) 
    15471544         CASE( 'F' ) 
    1548             DO jj = 2, jpjm1                                   ! F ==> (U,V) 
    1549                DO ji = fs_2, fs_jpim1   ! vector opt. 
    1550                   p_taui(ji,jj) = 0.5 * ( frcv(jpr_itx1)%z3(ji,jj,1) + frcv(jpr_itx1)%z3(ji  ,jj-1,1) ) 
    1551                   p_tauj(ji,jj) = 0.5 * ( frcv(jpr_ity1)%z3(ji,jj,1) + frcv(jpr_ity1)%z3(ji-1,jj  ,1) ) 
    1552                END DO 
    1553             END DO 
     1545            DO_2D_00_00 
     1546               p_taui(ji,jj) = 0.5 * ( frcv(jpr_itx1)%z3(ji,jj,1) + frcv(jpr_itx1)%z3(ji  ,jj-1,1) ) 
     1547               p_tauj(ji,jj) = 0.5 * ( frcv(jpr_ity1)%z3(ji,jj,1) + frcv(jpr_ity1)%z3(ji-1,jj  ,1) ) 
     1548            END_2D 
    15541549         CASE( 'T' ) 
    1555             DO jj = 2, jpjm1                                   ! T ==> (U,V) 
    1556                DO ji = fs_2, fs_jpim1   ! vector opt. 
    1557                   p_taui(ji,jj) = 0.5 * ( frcv(jpr_itx1)%z3(ji+1,jj  ,1) + frcv(jpr_itx1)%z3(ji,jj,1) ) 
    1558                   p_tauj(ji,jj) = 0.5 * ( frcv(jpr_ity1)%z3(ji  ,jj+1,1) + frcv(jpr_ity1)%z3(ji,jj,1) ) 
    1559                END DO 
    1560             END DO 
     1550            DO_2D_00_00 
     1551               p_taui(ji,jj) = 0.5 * ( frcv(jpr_itx1)%z3(ji+1,jj  ,1) + frcv(jpr_itx1)%z3(ji,jj,1) ) 
     1552               p_tauj(ji,jj) = 0.5 * ( frcv(jpr_ity1)%z3(ji  ,jj+1,1) + frcv(jpr_ity1)%z3(ji,jj,1) ) 
     1553            END_2D 
    15611554         CASE( 'I' ) 
    1562             DO jj = 2, jpjm1                                   ! I ==> (U,V) 
    1563                DO ji = 2, jpim1   ! NO vector opt. 
    1564                   p_taui(ji,jj) = 0.5 * ( frcv(jpr_itx1)%z3(ji+1,jj+1,1) + frcv(jpr_itx1)%z3(ji+1,jj  ,1) ) 
    1565                   p_tauj(ji,jj) = 0.5 * ( frcv(jpr_ity1)%z3(ji+1,jj+1,1) + frcv(jpr_ity1)%z3(ji  ,jj+1,1) ) 
    1566                END DO 
    1567             END DO 
     1555            DO_2D_00_00 
     1556               p_taui(ji,jj) = 0.5 * ( frcv(jpr_itx1)%z3(ji+1,jj+1,1) + frcv(jpr_itx1)%z3(ji+1,jj  ,1) ) 
     1557               p_tauj(ji,jj) = 0.5 * ( frcv(jpr_ity1)%z3(ji+1,jj+1,1) + frcv(jpr_ity1)%z3(ji  ,jj+1,1) ) 
     1558            END_2D 
    15681559         END SELECT 
    15691560         IF( srcv(jpr_itx1)%clgrid /= 'U' ) THEN  
     
    16831674      ! --- evaporation over ice (kg/m2/s) --- ! 
    16841675      DO jl=1,jpl 
    1685          IF (sn_rcv_emp%clcat == 'yes') THEN   ;   zevap_ice(:,:,jl) = frcv(jpr_ievp)%z3(:,:,jl) 
     1676         IF(sn_rcv_emp%clcat == 'yes') THEN   ;   zevap_ice(:,:,jl) = frcv(jpr_ievp)%z3(:,:,jl) 
    16861677         ELSE                                  ;   zevap_ice(:,:,jl) = frcv(jpr_ievp)%z3(:,:,1 )   ;   ENDIF 
    16871678      ENDDO 
     
    17041695      ENDIF 
    17051696      IF( srcv(jpr_isf)%laction ) THEN   ! iceshelf (fwfisf <0 mean melting) 
    1706         fwfisf(:,:) = - frcv(jpr_isf)%z3(:,:,1)   
     1697        fwfisf_oasis(:,:) = - frcv(jpr_isf)%z3(:,:,1)   
    17071698      ENDIF 
    17081699 
     
    17431734      ENDIF 
    17441735      IF( srcv(jpr_isf)%laction ) THEN   ! iceshelf (fwfisf <0 mean melting) 
    1745         fwfisf(:,:) = - frcv(jpr_isf)%z3(:,:,1) 
     1736        fwfisf_oasis(:,:) = - frcv(jpr_isf)%z3(:,:,1) 
    17461737      ENDIF 
    17471738      ! 
     
    17651756      IF( srcv(jpr_cal)%laction )   CALL iom_put( 'calving_cea' , frcv(jpr_cal)%z3(:,:,1) * tmask(:,:,1)                )  ! calving 
    17661757      IF( srcv(jpr_icb)%laction )   CALL iom_put( 'iceberg_cea' , frcv(jpr_icb)%z3(:,:,1) * tmask(:,:,1)                )  ! icebergs 
    1767       CALL iom_put( 'snowpre'     , sprecip(:,:)                                          )  ! Snow 
    1768       CALL iom_put( 'precip'      , tprecip(:,:)                                          )  ! total  precipitation 
    1769       IF ( iom_use('rain') ) CALL iom_put( 'rain'        , tprecip(:,:) - sprecip(:,:)                           )  ! liquid precipitation  
    1770       IF ( iom_use('snow_ao_cea') ) CALL iom_put( 'snow_ao_cea' , sprecip(:,:) * ( 1._wp - zsnw(:,:) )                  )  ! Snow over ice-free ocean  (cell average) 
    1771       IF ( iom_use('snow_ai_cea') ) CALL iom_put( 'snow_ai_cea' , sprecip(:,:) *           zsnw(:,:)                    )  ! Snow over sea-ice         (cell average) 
    1772       IF ( iom_use('rain_ao_cea') ) CALL iom_put( 'rain_ao_cea' , ( tprecip(:,:) - sprecip(:,:) ) * picefr(:,:)         )  ! liquid precipitation over ocean (cell average) 
    1773       IF ( iom_use('subl_ai_cea') ) CALL iom_put( 'subl_ai_cea' , frcv(jpr_ievp)%z3(:,:,1) * picefr(:,:) * tmask(:,:,1) )  ! Sublimation over sea-ice (cell average) 
    1774       IF ( iom_use('evap_ao_cea') ) CALL iom_put( 'evap_ao_cea' , ( frcv(jpr_tevp)%z3(:,:,1)  & 
     1758      IF( iom_use('snowpre') )      CALL iom_put( 'snowpre'     , sprecip(:,:)                                          )  ! Snow 
     1759      IF( iom_use('precip') )       CALL iom_put( 'precip'      , tprecip(:,:)                                          )  ! total  precipitation 
     1760      IF( iom_use('rain') )        CALL iom_put( 'rain'        , tprecip(:,:) - sprecip(:,:)                           )  ! liquid precipitation  
     1761      IF( iom_use('snow_ao_cea') ) CALL iom_put( 'snow_ao_cea' , sprecip(:,:) * ( 1._wp - zsnw(:,:) )                  )  ! Snow over ice-free ocean  (cell average) 
     1762      IF( iom_use('snow_ai_cea') ) CALL iom_put( 'snow_ai_cea' , sprecip(:,:) *           zsnw(:,:)                    )  ! Snow over sea-ice         (cell average) 
     1763      IF( iom_use('rain_ao_cea') ) CALL iom_put( 'rain_ao_cea' , ( tprecip(:,:) - sprecip(:,:) ) * picefr(:,:)         )  ! liquid precipitation over ocean (cell average) 
     1764      IF( iom_use('subl_ai_cea') ) CALL iom_put( 'subl_ai_cea' , frcv(jpr_ievp)%z3(:,:,1) * picefr(:,:) * tmask(:,:,1) )  ! Sublimation over sea-ice (cell average) 
     1765      IF( iom_use('evap_ao_cea') ) CALL iom_put( 'evap_ao_cea' , ( frcv(jpr_tevp)%z3(:,:,1)  & 
    17751766         &                                                        - frcv(jpr_ievp)%z3(:,:,1) * picefr(:,:) ) * tmask(:,:,1) )  ! ice-free oce evap (cell average) 
    17761767      ! note: runoff output is done in sbcrnf (which includes icebergs too) and iceshelf output is done in sbcisf 
     
    17831774      CASE( 'conservative' )     ! the required fields are directly provided 
    17841775         zqns_tot(:,:) = frcv(jpr_qnsmix)%z3(:,:,1) 
    1785          IF ( TRIM(sn_rcv_qns%clcat) == 'yes' ) THEN 
     1776         IF( TRIM(sn_rcv_qns%clcat) == 'yes' ) THEN 
    17861777            zqns_ice(:,:,1:jpl) = frcv(jpr_qnsice)%z3(:,:,1:jpl) 
    17871778         ELSE 
     
    17921783      CASE( 'oce and ice' )      ! the total flux is computed from ocean and ice fluxes 
    17931784         zqns_tot(:,:) =  ziceld(:,:) * frcv(jpr_qnsoce)%z3(:,:,1) 
    1794          IF ( TRIM(sn_rcv_qns%clcat) == 'yes' ) THEN 
     1785         IF( TRIM(sn_rcv_qns%clcat) == 'yes' ) THEN 
    17951786            DO jl=1,jpl 
    17961787               zqns_tot(:,:   ) = zqns_tot(:,:) + a_i(:,:,jl) * frcv(jpr_qnsice)%z3(:,:,jl)    
     
    19041895#endif 
    19051896      ! outputs 
    1906       IF ( srcv(jpr_cal)%laction ) CALL iom_put('hflx_cal_cea'    , - frcv(jpr_cal)%z3(:,:,1) * rLfus )   ! latent heat from calving 
    1907       IF ( srcv(jpr_icb)%laction ) CALL iom_put('hflx_icb_cea'    , - frcv(jpr_icb)%z3(:,:,1) * rLfus )   ! latent heat from icebergs melting 
    1908       IF ( iom_use(   'hflx_rain_cea') ) CALL iom_put('hflx_rain_cea' , ( tprecip(:,:) - sprecip(:,:) ) * zcptrain(:,:) )        ! heat flux from rain (cell average) 
    1909       IF ( iom_use(   'hflx_evap_cea') ) CALL iom_put('hflx_evap_cea' , ( frcv(jpr_tevp)%z3(:,:,1) - frcv(jpr_ievp)%z3(:,:,1) * picefr(:,:) )  & 
    1910            &                         * zcptn(:,:) * tmask(:,:,1) )            ! heat flux from evap (cell average) 
    1911       IF ( iom_use(   'hflx_prec_cea') ) CALL iom_put('hflx_prec_cea' ,    sprecip(:,:) * ( zcptsnw(:,:) - rLfus )  &                    ! heat flux from all precip (cell avg) 
    1912          &                          + ( tprecip(:,:) - sprecip(:,:) ) * zcptrain(:,:) ) 
    1913       IF ( iom_use(   'hflx_snow_cea') ) CALL iom_put('hflx_snow_cea'   , sprecip(:,:) * ( zcptsnw(:,:) - rLfus )  )               ! heat flux from snow (cell average) 
    1914       IF ( iom_use('hflx_snow_ao_cea') ) CALL iom_put('hflx_snow_ao_cea', sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) * ( 1._wp - zsnw(:,:) ) )   ! heat flux from snow (over ocean) 
    1915       IF ( iom_use('hflx_snow_ai_cea') ) CALL iom_put('hflx_snow_ai_cea', sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) *  zsnw(:,:) )              ! heat flux from snow (over ice) 
     1897      IF( srcv(jpr_cal)%laction       ) CALL iom_put('hflx_cal_cea'    , - frcv(jpr_cal)%z3(:,:,1) * rLfus )                      ! latent heat from calving 
     1898      IF( srcv(jpr_icb)%laction       ) CALL iom_put('hflx_icb_cea'    , - frcv(jpr_icb)%z3(:,:,1) * rLfus )                      ! latent heat from icebergs melting 
     1899      IF( iom_use('hflx_rain_cea')    ) CALL iom_put('hflx_rain_cea'   , ( tprecip(:,:) - sprecip(:,:) ) * zcptrain(:,:) )        ! heat flux from rain (cell average) 
     1900      IF( iom_use('hflx_evap_cea')    ) CALL iom_put('hflx_evap_cea'   , ( frcv(jpr_tevp)%z3(:,:,1) - frcv(jpr_ievp)%z3(:,:,1) & 
     1901           &                                                              * picefr(:,:) ) * zcptn(:,:) * tmask(:,:,1) )            ! heat flux from evap (cell average) 
     1902      IF( iom_use('hflx_prec_cea')    ) CALL iom_put('hflx_prec_cea'   ,  sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) +  &                    ! heat flux from all precip (cell avg) 
     1903         &                                                               ( tprecip(:,:) - sprecip(:,:) ) * zcptrain(:,:) ) 
     1904      IF( iom_use('hflx_snow_cea')    ) CALL iom_put('hflx_snow_cea'   , sprecip(:,:) * ( zcptsnw(:,:) - rLfus )  )               ! heat flux from snow (cell average) 
     1905      IF( iom_use('hflx_snow_ao_cea') ) CALL iom_put('hflx_snow_ao_cea', sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) & 
     1906           &                                                              * ( 1._wp - zsnw(:,:) )                  )               ! heat flux from snow (over ocean) 
     1907      IF( iom_use('hflx_snow_ai_cea') ) CALL iom_put('hflx_snow_ai_cea', sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) &  
     1908           &                                                              *           zsnw(:,:)                    )               ! heat flux from snow (over ice) 
    19161909      ! note: hflx for runoff and iceshelf are done in sbcrnf and sbcisf resp. 
    19171910      ! 
     
    19231916      CASE( 'conservative' ) 
    19241917         zqsr_tot(:,:  ) = frcv(jpr_qsrmix)%z3(:,:,1) 
    1925          IF ( TRIM(sn_rcv_qsr%clcat) == 'yes' ) THEN 
     1918         IF( TRIM(sn_rcv_qsr%clcat) == 'yes' ) THEN 
    19261919            zqsr_ice(:,:,1:jpl) = frcv(jpr_qsrice)%z3(:,:,1:jpl) 
    19271920         ELSE 
     
    19331926      CASE( 'oce and ice' ) 
    19341927         zqsr_tot(:,:  ) =  ziceld(:,:) * frcv(jpr_qsroce)%z3(:,:,1) 
    1935          IF ( TRIM(sn_rcv_qsr%clcat) == 'yes' ) THEN 
     1928         IF( TRIM(sn_rcv_qsr%clcat) == 'yes' ) THEN 
    19361929            DO jl = 1, jpl 
    19371930               zqsr_tot(:,:   ) = zqsr_tot(:,:) + a_i(:,:,jl) * frcv(jpr_qsrice)%z3(:,:,jl)    
     
    19991992      !                                                      ! ========================= ! 
    20001993      CASE ('coupled') 
    2001          IF ( TRIM(sn_rcv_dqnsdt%clcat) == 'yes' ) THEN 
     1994         IF( TRIM(sn_rcv_dqnsdt%clcat) == 'yes' ) THEN 
    20021995            zdqns_ice(:,:,1:jpl) = frcv(jpr_dqnsdt)%z3(:,:,1:jpl) 
    20031996         ELSE 
     
    20882081    
    20892082    
    2090    SUBROUTINE sbc_cpl_snd( kt ) 
     2083   SUBROUTINE sbc_cpl_snd( kt, Kbb, Kmm ) 
    20912084      !!---------------------------------------------------------------------- 
    20922085      !!             ***  ROUTINE sbc_cpl_snd  *** 
     
    20982091      !!---------------------------------------------------------------------- 
    20992092      INTEGER, INTENT(in) ::   kt 
     2093      INTEGER, INTENT(in) ::   Kbb, Kmm    ! ocean model time level index 
    21002094      ! 
    21012095      INTEGER ::   ji, jj, jl   ! dummy loop indices 
     
    21142108      IF( ssnd(jps_toce)%laction .OR. ssnd(jps_tice)%laction .OR. ssnd(jps_tmix)%laction ) THEN 
    21152109          
    2116          IF ( nn_components == jp_iam_opa ) THEN 
    2117             ztmp1(:,:) = tsn(:,:,1,jp_tem)   ! send temperature as it is (potential or conservative) -> use of l_useCT on the received part 
     2110         IF( nn_components == jp_iam_opa ) THEN 
     2111            ztmp1(:,:) = ts(:,:,1,jp_tem,Kmm)   ! send temperature as it is (potential or conservative) -> use of l_useCT on the received part 
    21182112         ELSE 
    21192113            ! we must send the surface potential temperature  
    2120             IF( l_useCT )  THEN    ;   ztmp1(:,:) = eos_pt_from_ct( tsn(:,:,1,jp_tem), tsn(:,:,1,jp_sal) ) 
    2121             ELSE                   ;   ztmp1(:,:) = tsn(:,:,1,jp_tem) 
     2114            IF( l_useCT )  THEN    ;   ztmp1(:,:) = eos_pt_from_ct( ts(:,:,1,jp_tem,Kmm), ts(:,:,1,jp_sal,Kmm) ) 
     2115            ELSE                   ;   ztmp1(:,:) = ts(:,:,1,jp_tem,Kmm) 
    21222116            ENDIF 
    21232117            ! 
     
    21472141               CASE default                  ;   CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_temp%clcat' ) 
    21482142               END SELECT 
    2149             CASE( 'oce and weighted ice')    ;   ztmp1(:,:) =   tsn(:,:,1,jp_tem) + rt0   
     2143            CASE( 'oce and weighted ice')    ;   ztmp1(:,:) =   ts(:,:,1,jp_tem,Kmm) + rt0   
    21502144               SELECT CASE( sn_snd_temp%clcat )  
    21512145               CASE( 'yes' )     
     
    23532347      !                                                      !  CO2 flux from PISCES     !  
    23542348      !                                                      ! ------------------------- ! 
    2355       IF( ssnd(jps_co2)%laction .AND. l_co2cpl )   THEN   
    2356          ztmp1(:,:) = oce_co2(:,:) * 1000.  ! conversion in molC/m2/s  
    2357          CALL cpl_snd( jps_co2, isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ) , info )  
    2358       ENDIF  
     2349      IF( ssnd(jps_co2)%laction .AND. l_co2cpl )   THEN  
     2350         ztmp1(:,:) = oce_co2(:,:) * 1000.  ! conversion in molC/m2/s 
     2351         CALL cpl_snd( jps_co2, isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ) , info ) 
     2352      ENDIF 
    23592353      ! 
    23602354      !                                                      ! ------------------------- ! 
     
    23712365         !                                                               i      i+1 (for I) 
    23722366         IF( nn_components == jp_iam_opa ) THEN 
    2373             zotx1(:,:) = un(:,:,1 
    2374             zoty1(:,:) = vn(:,:,1 
     2367            zotx1(:,:) = uu(:,:,1,Kmm 
     2368            zoty1(:,:) = vv(:,:,1,Kmm 
    23752369         ELSE         
    23762370            SELECT CASE( TRIM( sn_snd_crt%cldes ) ) 
    23772371            CASE( 'oce only'             )      ! C-grid ==> T 
    2378                DO jj = 2, jpjm1 
    2379                   DO ji = fs_2, fs_jpim1   ! vector opt. 
    2380                      zotx1(ji,jj) = 0.5 * ( un(ji,jj,1) + un(ji-1,jj  ,1) ) 
    2381                      zoty1(ji,jj) = 0.5 * ( vn(ji,jj,1) + vn(ji  ,jj-1,1) )  
    2382                   END DO 
    2383                END DO 
     2372               DO_2D_00_00 
     2373                  zotx1(ji,jj) = 0.5 * ( uu(ji,jj,1,Kmm) + uu(ji-1,jj  ,1,Kmm) ) 
     2374                  zoty1(ji,jj) = 0.5 * ( vv(ji,jj,1,Kmm) + vv(ji  ,jj-1,1,Kmm) )  
     2375               END_2D 
    23842376            CASE( 'weighted oce and ice' )      ! Ocean and Ice on C-grid ==> T   
    2385                DO jj = 2, jpjm1 
    2386                   DO ji = fs_2, fs_jpim1   ! vector opt. 
    2387                      zotx1(ji,jj) = 0.5 * ( un   (ji,jj,1) + un   (ji-1,jj  ,1) ) * zfr_l(ji,jj)   
    2388                      zoty1(ji,jj) = 0.5 * ( vn   (ji,jj,1) + vn   (ji  ,jj-1,1) ) * zfr_l(ji,jj) 
    2389                      zitx1(ji,jj) = 0.5 * ( u_ice(ji,jj  ) + u_ice(ji-1,jj    ) ) *  fr_i(ji,jj) 
    2390                      zity1(ji,jj) = 0.5 * ( v_ice(ji,jj  ) + v_ice(ji  ,jj-1  ) ) *  fr_i(ji,jj) 
    2391                   END DO 
    2392                END DO 
     2377               DO_2D_00_00 
     2378                  zotx1(ji,jj) = 0.5 * ( uu   (ji,jj,1,Kmm) + uu   (ji-1,jj  ,1,Kmm) ) * zfr_l(ji,jj)   
     2379                  zoty1(ji,jj) = 0.5 * ( vv   (ji,jj,1,Kmm) + vv   (ji  ,jj-1,1,Kmm) ) * zfr_l(ji,jj) 
     2380                  zitx1(ji,jj) = 0.5 * ( u_ice(ji,jj  )     + u_ice(ji-1,jj    )     ) *  fr_i(ji,jj) 
     2381                  zity1(ji,jj) = 0.5 * ( v_ice(ji,jj  )     + v_ice(ji  ,jj-1  )     ) *  fr_i(ji,jj) 
     2382               END_2D 
    23932383               CALL lbc_lnk_multi( 'sbccpl', zitx1, 'T', -1., zity1, 'T', -1. ) 
    23942384            CASE( 'mixed oce-ice'        )      ! Ocean and Ice on C-grid ==> T 
    2395                DO jj = 2, jpjm1 
    2396                   DO ji = fs_2, fs_jpim1   ! vector opt. 
    2397                      zotx1(ji,jj) = 0.5 * ( un   (ji,jj,1) + un   (ji-1,jj  ,1) ) * zfr_l(ji,jj)   & 
    2398                         &         + 0.5 * ( u_ice(ji,jj  ) + u_ice(ji-1,jj    ) ) *  fr_i(ji,jj) 
    2399                      zoty1(ji,jj) = 0.5 * ( vn   (ji,jj,1) + vn   (ji  ,jj-1,1) ) * zfr_l(ji,jj)   & 
    2400                         &         + 0.5 * ( v_ice(ji,jj  ) + v_ice(ji  ,jj-1  ) ) *  fr_i(ji,jj) 
    2401                   END DO 
    2402                END DO 
     2385               DO_2D_00_00 
     2386                  zotx1(ji,jj) = 0.5 * ( uu   (ji,jj,1,Kmm) + uu   (ji-1,jj  ,1,Kmm) ) * zfr_l(ji,jj)   & 
     2387                     &         + 0.5 * ( u_ice(ji,jj  )     + u_ice(ji-1,jj    )     ) *  fr_i(ji,jj) 
     2388                  zoty1(ji,jj) = 0.5 * ( vv   (ji,jj,1,Kmm) + vv   (ji  ,jj-1,1,Kmm) ) * zfr_l(ji,jj)   & 
     2389                     &         + 0.5 * ( v_ice(ji,jj  )     + v_ice(ji  ,jj-1  )     ) *  fr_i(ji,jj) 
     2390               END_2D 
    24032391            END SELECT 
    24042392            CALL lbc_lnk_multi( 'sbccpl', zotx1, ssnd(jps_ocx1)%clgrid, -1.,  zoty1, ssnd(jps_ocy1)%clgrid, -1. ) 
     
    24592447          SELECT CASE( TRIM( sn_snd_crtw%cldes ) )  
    24602448          CASE( 'oce only'             )      ! C-grid ==> T  
    2461              DO jj = 2, jpjm1  
    2462                 DO ji = fs_2, fs_jpim1   ! vector opt.  
    2463                    zotx1(ji,jj) = 0.5 * ( un(ji,jj,1) + un(ji-1,jj  ,1) )  
    2464                    zoty1(ji,jj) = 0.5 * ( vn(ji,jj,1) + vn(ji , jj-1,1) )   
    2465                 END DO  
    2466              END DO  
     2449             DO_2D_00_00 
     2450                zotx1(ji,jj) = 0.5 * ( uu(ji,jj,1,Kmm) + uu(ji-1,jj  ,1,Kmm) )  
     2451                zoty1(ji,jj) = 0.5 * ( vv(ji,jj,1,Kmm) + vv(ji , jj-1,1,Kmm) )   
     2452             END_2D 
    24672453          CASE( 'weighted oce and ice' )      ! Ocean and Ice on C-grid ==> T    
    2468              DO jj = 2, jpjm1  
    2469                 DO ji = fs_2, fs_jpim1   ! vector opt.  
    2470                    zotx1(ji,jj) = 0.5 * ( un   (ji,jj,1) + un   (ji-1,jj  ,1) ) * zfr_l(ji,jj)    
    2471                    zoty1(ji,jj) = 0.5 * ( vn   (ji,jj,1) + vn   (ji  ,jj-1,1) ) * zfr_l(ji,jj)  
    2472                    zitx1(ji,jj) = 0.5 * ( u_ice(ji,jj  ) + u_ice(ji-1,jj    ) ) *  fr_i(ji,jj)  
    2473                    zity1(ji,jj) = 0.5 * ( v_ice(ji,jj  ) + v_ice(ji  ,jj-1  ) ) *  fr_i(ji,jj)  
    2474                 END DO 
    2475              END DO 
     2454             DO_2D_00_00 
     2455                zotx1(ji,jj) = 0.5 * ( uu   (ji,jj,1,Kmm) + uu   (ji-1,jj  ,1,Kmm) ) * zfr_l(ji,jj)    
     2456                zoty1(ji,jj) = 0.5 * ( vv   (ji,jj,1,Kmm) + vv   (ji  ,jj-1,1,Kmm) ) * zfr_l(ji,jj)  
     2457                zitx1(ji,jj) = 0.5 * ( u_ice(ji,jj  ) + u_ice(ji-1,jj    ) ) *  fr_i(ji,jj)  
     2458                zity1(ji,jj) = 0.5 * ( v_ice(ji,jj  ) + v_ice(ji  ,jj-1  ) ) *  fr_i(ji,jj)  
     2459             END_2D 
    24762460             CALL lbc_lnk_multi( 'sbccpl', zitx1, 'T', -1.,  zity1, 'T', -1. )  
    24772461          CASE( 'mixed oce-ice'        )      ! Ocean and Ice on C-grid ==> T   
    2478              DO jj = 2, jpjm1  
    2479                 DO ji = fs_2, fs_jpim1   ! vector opt.  
    2480                    zotx1(ji,jj) = 0.5 * ( un   (ji,jj,1) + un   (ji-1,jj  ,1) ) * zfr_l(ji,jj)   &  
    2481                       &         + 0.5 * ( u_ice(ji,jj  ) + u_ice(ji-1,jj    ) ) *  fr_i(ji,jj)  
    2482                    zoty1(ji,jj) = 0.5 * ( vn   (ji,jj,1) + vn   (ji  ,jj-1,1) ) * zfr_l(ji,jj)   &  
    2483                       &         + 0.5 * ( v_ice(ji,jj  ) + v_ice(ji  ,jj-1  ) ) *  fr_i(ji,jj)  
    2484                 END DO 
    2485              END DO 
     2462             DO_2D_00_00 
     2463                zotx1(ji,jj) = 0.5 * ( uu   (ji,jj,1,Kmm) + uu   (ji-1,jj  ,1,Kmm) ) * zfr_l(ji,jj)   &  
     2464                   &         + 0.5 * ( u_ice(ji,jj  ) + u_ice(ji-1,jj    ) ) *  fr_i(ji,jj)  
     2465                zoty1(ji,jj) = 0.5 * ( vv   (ji,jj,1,Kmm) + vv   (ji  ,jj-1,1,Kmm) ) * zfr_l(ji,jj)   &  
     2466                   &         + 0.5 * ( v_ice(ji,jj  ) + v_ice(ji  ,jj-1  ) ) *  fr_i(ji,jj)  
     2467             END_2D 
    24862468          END SELECT 
    24872469         CALL lbc_lnk_multi( 'sbccpl', zotx1, ssnd(jps_ocxw)%clgrid, -1., zoty1, ssnd(jps_ocyw)%clgrid, -1. )  
     
    25222504      IF( ssnd(jps_ficet)%laction ) THEN  
    25232505         CALL cpl_snd( jps_ficet, isec, RESHAPE ( fr_i, (/jpi,jpj,1/) ), info )  
    2524       END IF  
     2506      ENDIF  
    25252507      !                                                      ! ------------------------- !  
    25262508      !                                                      !   Water levels to waves   !  
     
    25292511         IF( ln_apr_dyn ) THEN   
    25302512            IF( kt /= nit000 ) THEN   
    2531                ztmp1(:,:) = sshb(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) )   
     2513               ztmp1(:,:) = ssh(:,:,Kbb) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) )   
    25322514            ELSE   
    2533                ztmp1(:,:) = sshb(:,: 
     2515               ztmp1(:,:) = ssh(:,:,Kbb 
    25342516            ENDIF   
    25352517         ELSE   
    2536             ztmp1(:,:) = sshn(:,: 
     2518            ztmp1(:,:) = ssh(:,:,Kmm 
    25372519         ENDIF   
    25382520         CALL cpl_snd( jps_wlev  , isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ), info )  
    2539       END IF  
     2521      ENDIF  
    25402522      ! 
    25412523      !  Fields sent by OPA to SAS when doing OPA<->SAS coupling 
     
    25442526         !                          ! removed inverse barometer ssh when Patm 
    25452527         !                          forcing is used (for sea-ice dynamics) 
    2546          IF( ln_apr_dyn ) THEN   ;   ztmp1(:,:) = sshb(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 
    2547          ELSE                    ;   ztmp1(:,:) = sshn(:,:) 
     2528         IF( ln_apr_dyn ) THEN   ;   ztmp1(:,:) = ssh(:,:,Kbb) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 
     2529         ELSE                    ;   ztmp1(:,:) = ssh(:,:,Kmm) 
    25482530         ENDIF 
    25492531         CALL cpl_snd( jps_ssh   , isec, RESHAPE ( ztmp1            , (/jpi,jpj,1/) ), info ) 
     
    25522534      !                                                        ! SSS 
    25532535      IF( ssnd(jps_soce  )%laction )  THEN 
    2554          CALL cpl_snd( jps_soce  , isec, RESHAPE ( tsn(:,:,1,jp_sal), (/jpi,jpj,1/) ), info ) 
     2536         CALL cpl_snd( jps_soce  , isec, RESHAPE ( ts(:,:,1,jp_sal,Kmm), (/jpi,jpj,1/) ), info ) 
    25552537      ENDIF 
    25562538      !                                                        ! first T level thickness  
    25572539      IF( ssnd(jps_e3t1st )%laction )  THEN 
    2558          CALL cpl_snd( jps_e3t1st, isec, RESHAPE ( e3t_n(:,:,1)   , (/jpi,jpj,1/) ), info ) 
     2540         CALL cpl_snd( jps_e3t1st, isec, RESHAPE ( e3t(:,:,1,Kmm)   , (/jpi,jpj,1/) ), info ) 
    25592541      ENDIF 
    25602542      !                                                        ! Qsr fraction 
     
    25792561      !                                                      ! ------------------------- ! 
    25802562      ! needed by Met Office 
    2581       CALL eos_fzp(tsn(:,:,1,jp_sal), sstfrz) 
     2563      CALL eos_fzp(ts(:,:,1,jp_sal,Kmm), sstfrz) 
    25822564      ztmp1(:,:) = sstfrz(:,:) + rt0 
    25832565      IF( ssnd(jps_sstfrz)%laction )  CALL cpl_snd( jps_sstfrz, isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ), info) 
  • NEMO/trunk/src/OCE/SBC/sbcdcy.F90

    r10425 r12377  
    77   !!   NEMO    2.0  !  2006-02  (S. Masson, G. Madec)  adaptation to NEMO 
    88   !!           3.1  !  2009-07  (J.M. Molines)  adaptation to v3.1 
     9   !!           4.*  !  2019-10  (L. Brodeau)  nothing really new, but the routine 
     10   !!                ! "sbc_dcy_param" has been extracted from old function "sbc_dcy" 
     11   !!                ! => this allows the warm-layer param of COARE3* to know the time 
     12   !!                ! of dawn and dusk even if "ln_dm2dc=.false." (rdawn_dcy & rdusk_dcy 
     13   !!                ! are now public) 
    914   !!---------------------------------------------------------------------- 
    1015 
     
    2227   IMPLICIT NONE 
    2328   PRIVATE 
    24     
     29 
    2530   INTEGER, PUBLIC ::   nday_qsr   !: day when parameters were computed 
    26     
     31 
    2732   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   raa , rbb  , rcc  , rab     ! diurnal cycle parameters 
    28    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   rtmd, rdawn, rdusk, rscal   !    -      -       - 
    29    
     33   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   rtmd, rscal   !    -      -       - 
     34   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: rdawn_dcy, rdusk_dcy   !    -      -       - 
     35 
    3036   PUBLIC   sbc_dcy        ! routine called by sbc 
    31  
     37   PUBLIC   sbc_dcy_param  ! routine used here and called by warm-layer parameterization (sbcblk_skin_coare*) 
     38 
     39   !! * Substitutions 
     40#  include "do_loop_substitute.h90" 
    3241   !!---------------------------------------------------------------------- 
    3342   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
    34    !! $Id$  
     43   !! $Id$ 
    3544   !! Software governed by the CeCILL license (see ./LICENSE) 
    3645   !!---------------------------------------------------------------------- 
    3746CONTAINS 
    3847 
    39       INTEGER FUNCTION sbc_dcy_alloc() 
    40          !!---------------------------------------------------------------------- 
    41          !!                ***  FUNCTION sbc_dcy_alloc  *** 
    42          !!---------------------------------------------------------------------- 
    43          ALLOCATE( raa (jpi,jpj) , rbb  (jpi,jpj) , rcc  (jpi,jpj) , rab  (jpi,jpj) ,     & 
    44             &      rtmd(jpi,jpj) , rdawn(jpi,jpj) , rdusk(jpi,jpj) , rscal(jpi,jpj) , STAT=sbc_dcy_alloc ) 
    45             ! 
    46          CALL mpp_sum ( 'sbcdcy', sbc_dcy_alloc ) 
    47          IF( sbc_dcy_alloc /= 0 )   CALL ctl_stop( 'STOP', 'sbc_dcy_alloc: failed to allocate arrays' ) 
    48       END FUNCTION sbc_dcy_alloc 
     48   INTEGER FUNCTION sbc_dcy_alloc() 
     49      !!---------------------------------------------------------------------- 
     50      !!                ***  FUNCTION sbc_dcy_alloc  *** 
     51      !!---------------------------------------------------------------------- 
     52      ALLOCATE( raa (jpi,jpj) , rbb  (jpi,jpj) , rcc  (jpi,jpj) , rab  (jpi,jpj) ,     & 
     53         &      rtmd(jpi,jpj) , rdawn_dcy(jpi,jpj) , rdusk_dcy(jpi,jpj) , rscal(jpi,jpj) , STAT=sbc_dcy_alloc ) 
     54      ! 
     55      CALL mpp_sum ( 'sbcdcy', sbc_dcy_alloc ) 
     56      IF( sbc_dcy_alloc /= 0 )   CALL ctl_stop( 'STOP', 'sbc_dcy_alloc: failed to allocate arrays' ) 
     57   END FUNCTION sbc_dcy_alloc 
    4958 
    5059 
     
    6069      !! 
    6170      !! reference  : Bernie, DJ, E Guilyardi, G Madec, JM Slingo, and SJ Woolnough, 2007 
    62       !!              Impact of resolving the diurnal cycle in an ocean--atmosphere GCM.  
     71      !!              Impact of resolving the diurnal cycle in an ocean--atmosphere GCM. 
    6372      !!              Part 1: a diurnally forced OGCM. Climate Dynamics 29:6, 575-590. 
    6473      !!---------------------------------------------------------------------- 
    6574      LOGICAL , OPTIONAL          , INTENT(in) ::   l_mask    ! use the routine for night mask computation 
    66       REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pqsrin    ! input daily QSR flux  
     75      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pqsrin    ! input daily QSR flux 
    6776      REAL(wp), DIMENSION(jpi,jpj)             ::   zqsrout   ! output QSR flux with diurnal cycle 
    6877      !! 
    6978      INTEGER  ::   ji, jj                                       ! dummy loop indices 
    7079      INTEGER, DIMENSION(jpi,jpj) :: imask_night ! night mask 
    71       REAL(wp) ::   ztwopi, zinvtwopi, zconvrad  
    7280      REAL(wp) ::   zlo, zup, zlousd, zupusd 
    73       REAL(wp) ::   zdsws, zdecrad, ztx, zsin, zcos 
    74       REAL(wp) ::   ztmp, ztmp1, ztmp2, ztest 
     81      REAL(wp) ::   ztmp, ztmp1, ztmp2 
    7582      REAL(wp) ::   ztmpm, ztmpm1, ztmpm2 
    76       !---------------------------statement functions------------------------ 
    77       REAL(wp) ::   fintegral, pt1, pt2, paaa, pbbb, pccc        ! dummy statement function arguments 
    78       fintegral( pt1, pt2, paaa, pbbb, pccc ) =                         & 
    79          &   paaa * pt2 + zinvtwopi * pbbb * SIN(pccc + ztwopi * pt2)   & 
    80          & - paaa * pt1 - zinvtwopi * pbbb * SIN(pccc + ztwopi * pt1) 
    8183      !!--------------------------------------------------------------------- 
    8284      ! 
    8385      ! Initialization 
    8486      ! -------------- 
    85       ztwopi    = 2._wp * rpi 
    86       zinvtwopi = 1._wp / ztwopi 
    87       zconvrad  = ztwopi / 360._wp 
    88  
    8987      ! When are we during the day (from 0 to 1) 
    9088      zlo = ( REAL(nsec_day, wp) - 0.5_wp * rdt ) / rday 
    9189      zup = zlo + ( REAL(nn_fsbc, wp)     * rdt ) / rday 
    92       !                                           
    93       IF( nday_qsr == -1 ) THEN       ! first time step only   
     90      ! 
     91      IF( nday_qsr == -1 ) THEN       ! first time step only 
    9492         IF(lwp) THEN 
    9593            WRITE(numout,*) 
     
    9896            WRITE(numout,*) 
    9997         ENDIF 
     98      ENDIF 
     99 
     100      ! Setting parameters for each new day: 
     101      CALL sbc_dcy_param() 
     102 
     103      !CALL iom_put( "rdusk_dcy", rdusk_dcy(:,:)*tmask(:,:,1) ) !LB 
     104      !CALL iom_put( "rdawn_dcy", rdawn_dcy(:,:)*tmask(:,:,1) ) !LB 
     105      !CALL iom_put( "rscal_dcy", rscal(:,:)*tmask(:,:,1) ) !LB 
     106 
     107 
     108      !     3. update qsr with the diurnal cycle 
     109      !     ------------------------------------ 
     110 
     111      imask_night(:,:) = 0 
     112      DO_2D_11_11 
     113         ztmpm = 0._wp 
     114         IF( ABS(rab(ji,jj)) < 1. ) THEN         ! day duration is less than 24h 
     115            ! 
     116            IF( rdawn_dcy(ji,jj) < rdusk_dcy(ji,jj) ) THEN       ! day time in one part 
     117               zlousd = MAX(zlo, rdawn_dcy(ji,jj)) 
     118               zlousd = MIN(zlousd, zup) 
     119               zupusd = MIN(zup, rdusk_dcy(ji,jj)) 
     120               zupusd = MAX(zupusd, zlo) 
     121               ztmp = fintegral(zlousd, zupusd, raa(ji,jj), rbb(ji,jj), rcc(ji,jj)) 
     122               zqsrout(ji,jj) = pqsrin(ji,jj) * ztmp * rscal(ji,jj) 
     123               ztmpm = zupusd - zlousd 
     124               IF( ztmpm .EQ. 0 ) imask_night(ji,jj) = 1 
     125               ! 
     126            ELSE                                         ! day time in two parts 
     127               zlousd = MIN(zlo, rdusk_dcy(ji,jj)) 
     128               zupusd = MIN(zup, rdusk_dcy(ji,jj)) 
     129               ztmp1 = fintegral(zlousd, zupusd, raa(ji,jj), rbb(ji,jj), rcc(ji,jj)) 
     130               ztmpm1=zupusd-zlousd 
     131               zlousd = MAX(zlo, rdawn_dcy(ji,jj)) 
     132               zupusd = MAX(zup, rdawn_dcy(ji,jj)) 
     133               ztmp2 = fintegral(zlousd, zupusd, raa(ji,jj), rbb(ji,jj), rcc(ji,jj)) 
     134               ztmpm2 =zupusd-zlousd 
     135               ztmp = ztmp1 + ztmp2 
     136               ztmpm = ztmpm1 + ztmpm2 
     137               zqsrout(ji,jj) = pqsrin(ji,jj) * ztmp * rscal(ji,jj) 
     138               IF(ztmpm .EQ. 0.) imask_night(ji,jj) = 1 
     139            ENDIF 
     140         ELSE                                   ! 24h light or 24h night 
     141            ! 
     142            IF( raa(ji,jj) > rbb(ji,jj) ) THEN           ! 24h day 
     143               ztmp = fintegral(zlo, zup, raa(ji,jj), rbb(ji,jj), rcc(ji,jj)) 
     144               zqsrout(ji,jj) = pqsrin(ji,jj) * ztmp * rscal(ji,jj) 
     145               imask_night(ji,jj) = 0 
     146               ! 
     147            ELSE                                         ! No day 
     148               zqsrout(ji,jj) = 0.0_wp 
     149               imask_night(ji,jj) = 1 
     150            ENDIF 
     151         ENDIF 
     152      END_2D 
     153      ! 
     154      IF( PRESENT(l_mask) .AND. l_mask ) THEN 
     155         zqsrout(:,:) = float(imask_night(:,:)) 
     156      ENDIF 
     157      ! 
     158   END FUNCTION sbc_dcy 
     159 
     160 
     161   SUBROUTINE sbc_dcy_param( ) 
     162      !! 
     163      INTEGER  ::   ji, jj                                       ! dummy loop indices 
     164      !INTEGER, DIMENSION(jpi,jpj) :: imask_night ! night mask 
     165      REAL(wp) ::   zdsws, zdecrad, ztx, zsin, zcos 
     166      REAL(wp) ::   ztmp, ztest 
     167      !---------------------------statement functions------------------------ 
     168      ! 
     169      IF( nday_qsr == -1 ) THEN       ! first time step only 
    100170         ! allocate sbcdcy arrays 
    101171         IF( sbc_dcy_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'sbc_dcy_alloc : unable to allocate arrays' ) 
    102172         ! Compute rcc needed to compute the time integral of the diurnal cycle 
    103          rcc(:,:) = zconvrad * glamt(:,:) - rpi 
     173         rcc(:,:) = rad * glamt(:,:) - rpi 
    104174         ! time of midday 
    105175         rtmd(:,:) = 0.5_wp - glamt(:,:) / 360._wp 
     
    107177      ENDIF 
    108178 
    109       ! If this is a new day, we have to update the dawn, dusk and scaling function   
     179      ! If this is a new day, we have to update the dawn, dusk and scaling function 
    110180      !---------------------- 
    111      
    112       !     2.1 dawn and dusk   
    113  
    114       ! nday is the number of days since the beginning of the current month  
    115       IF( nday_qsr /= nday ) THEN  
     181 
     182      !     2.1 dawn and dusk 
     183 
     184      ! nday is the number of days since the beginning of the current month 
     185      IF( nday_qsr /= nday ) THEN 
    116186         ! save the day of the year and the daily mean of qsr 
    117          nday_qsr = nday  
    118          ! number of days since the previous winter solstice (supposed to be always 21 December)          
     187         nday_qsr = nday 
     188         ! number of days since the previous winter solstice (supposed to be always 21 December) 
    119189         zdsws = REAL(11 + nday_year, wp) 
    120190         ! declination of the earths orbit 
    121          zdecrad = (-23.5_wp * zconvrad) * COS( zdsws * ztwopi / REAL(nyear_len(1),wp) ) 
     191         zdecrad = (-23.5_wp * rad) * COS( zdsws * 2._wp*rpi / REAL(nyear_len(1),wp) ) 
    122192         ! Compute A and B needed to compute the time integral of the diurnal cycle 
    123193 
    124194         zsin = SIN( zdecrad )   ;   zcos = COS( zdecrad ) 
    125          DO jj = 1, jpj 
    126             DO ji = 1, jpi 
    127                ztmp = zconvrad * gphit(ji,jj) 
    128                raa(ji,jj) = SIN( ztmp ) * zsin 
    129                rbb(ji,jj) = COS( ztmp ) * zcos 
    130             END DO   
    131          END DO   
     195         DO_2D_11_11 
     196            ztmp = rad * gphit(ji,jj) 
     197            raa(ji,jj) = SIN( ztmp ) * zsin 
     198            rbb(ji,jj) = COS( ztmp ) * zcos 
     199         END_2D 
    132200         ! Compute the time of dawn and dusk 
    133201 
    134          ! rab to test if the day time is equal to 0, less than 24h of full day         
     202         ! rab to test if the day time is equal to 0, less than 24h of full day 
    135203         rab(:,:) = -raa(:,:) / rbb(:,:) 
    136          DO jj = 1, jpj 
    137             DO ji = 1, jpi 
    138                IF ( ABS(rab(ji,jj)) < 1._wp ) THEN         ! day duration is less than 24h 
    139          ! When is it night? 
    140                   ztx = zinvtwopi * (ACOS(rab(ji,jj)) - rcc(ji,jj)) 
    141                   ztest = -rbb(ji,jj) * SIN( rcc(ji,jj) + ztwopi * ztx ) 
    142          ! is it dawn or dusk? 
    143                   IF ( ztest > 0._wp ) THEN 
    144                      rdawn(ji,jj) = ztx 
    145                      rdusk(ji,jj) = rtmd(ji,jj) + ( rtmd(ji,jj) - rdawn(ji,jj) ) 
    146                   ELSE 
    147                      rdusk(ji,jj) = ztx 
    148                      rdawn(ji,jj) = rtmd(ji,jj) - ( rdusk(ji,jj) - rtmd(ji,jj) ) 
    149                   ENDIF 
     204         DO_2D_11_11 
     205            IF( ABS(rab(ji,jj)) < 1._wp ) THEN         ! day duration is less than 24h 
     206               ! When is it night? 
     207               ztx = 1._wp/(2._wp*rpi) * (ACOS(rab(ji,jj)) - rcc(ji,jj)) 
     208               ztest = -rbb(ji,jj) * SIN( rcc(ji,jj) + 2._wp*rpi * ztx ) 
     209               ! is it dawn or dusk? 
     210               IF( ztest > 0._wp ) THEN 
     211                  rdawn_dcy(ji,jj) = ztx 
     212                  rdusk_dcy(ji,jj) = rtmd(ji,jj) + ( rtmd(ji,jj) - rdawn_dcy(ji,jj) ) 
    150213               ELSE 
    151                   rdawn(ji,jj) = rtmd(ji,jj) + 0.5_wp 
    152                   rdusk(ji,jj) = rdawn(ji,jj) 
     214                  rdusk_dcy(ji,jj) = ztx 
     215                  rdawn_dcy(ji,jj) = rtmd(ji,jj) - ( rdusk_dcy(ji,jj) - rtmd(ji,jj) ) 
    153216               ENDIF 
    154              END DO   
    155          END DO   
    156          rdawn(:,:) = MOD( (rdawn(:,:) + 1._wp), 1._wp ) 
    157          rdusk(:,:) = MOD( (rdusk(:,:) + 1._wp), 1._wp ) 
     217            ELSE 
     218               rdawn_dcy(ji,jj) = rtmd(ji,jj) + 0.5_wp 
     219               rdusk_dcy(ji,jj) = rdawn_dcy(ji,jj) 
     220            ENDIF 
     221         END_2D 
     222         rdawn_dcy(:,:) = MOD( (rdawn_dcy(:,:) + 1._wp), 1._wp ) 
     223         rdusk_dcy(:,:) = MOD( (rdusk_dcy(:,:) + 1._wp), 1._wp ) 
    158224         !     2.2 Compute the scaling function: 
    159225         !         S* = the inverse of the time integral of the diurnal cycle from dawn to dusk 
    160226         !         Avoid possible infinite scaling factor, associated with very short daylight 
    161227         !         periods, by ignoring periods less than 1/1000th of a day (ticket #1040) 
    162          DO jj = 1, jpj 
    163             DO ji = 1, jpi 
    164                IF ( ABS(rab(ji,jj)) < 1._wp ) THEN         ! day duration is less than 24h 
    165                   rscal(ji,jj) = 0.0_wp 
    166                   IF ( rdawn(ji,jj) < rdusk(ji,jj) ) THEN      ! day time in one part 
    167                      IF( (rdusk(ji,jj) - rdawn(ji,jj) ) .ge. 0.001_wp ) THEN 
    168                        rscal(ji,jj) = fintegral(rdawn(ji,jj), rdusk(ji,jj), raa(ji,jj), rbb(ji,jj), rcc(ji,jj))  
    169                        rscal(ji,jj) = 1._wp / rscal(ji,jj) 
    170                      ENDIF 
    171                   ELSE                                         ! day time in two parts 
    172                      IF( (rdusk(ji,jj) + (1._wp - rdawn(ji,jj)) ) .ge. 0.001_wp ) THEN 
    173                        rscal(ji,jj) = fintegral(0._wp, rdusk(ji,jj), raa(ji,jj), rbb(ji,jj), rcc(ji,jj))   & 
    174                           &         + fintegral(rdawn(ji,jj), 1._wp, raa(ji,jj), rbb(ji,jj), rcc(ji,jj))  
    175                        rscal(ji,jj) = 1. / rscal(ji,jj) 
    176                      ENDIF 
     228         DO_2D_11_11 
     229            IF( ABS(rab(ji,jj)) < 1._wp ) THEN         ! day duration is less than 24h 
     230               rscal(ji,jj) = 0.0_wp 
     231               IF( rdawn_dcy(ji,jj) < rdusk_dcy(ji,jj) ) THEN      ! day time in one part 
     232                  IF( (rdusk_dcy(ji,jj) - rdawn_dcy(ji,jj) ) .ge. 0.001_wp ) THEN 
     233                     rscal(ji,jj) = fintegral(rdawn_dcy(ji,jj), rdusk_dcy(ji,jj), raa(ji,jj), rbb(ji,jj), rcc(ji,jj)) 
     234                     rscal(ji,jj) = 1._wp / rscal(ji,jj) 
    177235                  ENDIF 
    178                ELSE 
    179                   IF ( raa(ji,jj) > rbb(ji,jj) ) THEN         ! 24h day 
    180                      rscal(ji,jj) = fintegral(0._wp, 1._wp, raa(ji,jj), rbb(ji,jj), rcc(ji,jj))  
    181                      rscal(ji,jj) = 1._wp / rscal(ji,jj) 
    182                   ELSE                                          ! No day 
    183                      rscal(ji,jj) = 0.0_wp 
     236               ELSE                                         ! day time in two parts 
     237                  IF( (rdusk_dcy(ji,jj) + (1._wp - rdawn_dcy(ji,jj)) ) .ge. 0.001_wp ) THEN 
     238                     rscal(ji,jj) = fintegral(0._wp, rdusk_dcy(ji,jj), raa(ji,jj), rbb(ji,jj), rcc(ji,jj))   & 
     239                        &         + fintegral(rdawn_dcy(ji,jj), 1._wp, raa(ji,jj), rbb(ji,jj), rcc(ji,jj)) 
     240                     rscal(ji,jj) = 1. / rscal(ji,jj) 
    184241                  ENDIF 
    185242               ENDIF 
    186             END DO   
    187          END DO   
     243            ELSE 
     244               IF( raa(ji,jj) > rbb(ji,jj) ) THEN         ! 24h day 
     245                  rscal(ji,jj) = fintegral(0._wp, 1._wp, raa(ji,jj), rbb(ji,jj), rcc(ji,jj)) 
     246                  rscal(ji,jj) = 1._wp / rscal(ji,jj) 
     247               ELSE                                          ! No day 
     248                  rscal(ji,jj) = 0.0_wp 
     249               ENDIF 
     250            ENDIF 
     251         END_2D 
    188252         ! 
    189253         ztmp = rday / ( rdt * REAL(nn_fsbc, wp) ) 
    190254         rscal(:,:) = rscal(:,:) * ztmp 
    191255         ! 
    192       ENDIF  
    193          !     3. update qsr with the diurnal cycle 
    194          !     ------------------------------------ 
    195  
    196       imask_night(:,:) = 0 
    197       DO jj = 1, jpj 
    198          DO ji = 1, jpi 
    199             ztmpm = 0._wp 
    200             IF( ABS(rab(ji,jj)) < 1. ) THEN         ! day duration is less than 24h 
    201                ! 
    202                IF( rdawn(ji,jj) < rdusk(ji,jj) ) THEN       ! day time in one part 
    203                   zlousd = MAX(zlo, rdawn(ji,jj)) 
    204                   zlousd = MIN(zlousd, zup) 
    205                   zupusd = MIN(zup, rdusk(ji,jj)) 
    206                   zupusd = MAX(zupusd, zlo) 
    207                   ztmp = fintegral(zlousd, zupusd, raa(ji,jj), rbb(ji,jj), rcc(ji,jj))  
    208                   zqsrout(ji,jj) = pqsrin(ji,jj) * ztmp * rscal(ji,jj) 
    209                   ztmpm = zupusd - zlousd 
    210                   IF ( ztmpm .EQ. 0 ) imask_night(ji,jj) = 1 
    211                   ! 
    212                ELSE                                         ! day time in two parts 
    213                   zlousd = MIN(zlo, rdusk(ji,jj)) 
    214                   zupusd = MIN(zup, rdusk(ji,jj)) 
    215                   ztmp1 = fintegral(zlousd, zupusd, raa(ji,jj), rbb(ji,jj), rcc(ji,jj))  
    216                   ztmpm1=zupusd-zlousd 
    217                   zlousd = MAX(zlo, rdawn(ji,jj)) 
    218                   zupusd = MAX(zup, rdawn(ji,jj)) 
    219                   ztmp2 = fintegral(zlousd, zupusd, raa(ji,jj), rbb(ji,jj), rcc(ji,jj))  
    220                   ztmpm2 =zupusd-zlousd 
    221                   ztmp = ztmp1 + ztmp2 
    222                   ztmpm = ztmpm1 + ztmpm2 
    223                   zqsrout(ji,jj) = pqsrin(ji,jj) * ztmp * rscal(ji,jj) 
    224                   IF (ztmpm .EQ. 0.) imask_night(ji,jj) = 1 
    225                ENDIF 
    226             ELSE                                   ! 24h light or 24h night 
    227                ! 
    228                IF( raa(ji,jj) > rbb(ji,jj) ) THEN           ! 24h day 
    229                   ztmp = fintegral(zlo, zup, raa(ji,jj), rbb(ji,jj), rcc(ji,jj))  
    230                   zqsrout(ji,jj) = pqsrin(ji,jj) * ztmp * rscal(ji,jj) 
    231                   imask_night(ji,jj) = 0 
    232                   ! 
    233                ELSE                                         ! No day 
    234                   zqsrout(ji,jj) = 0.0_wp 
    235                   imask_night(ji,jj) = 1 
    236                ENDIF 
    237             ENDIF 
    238          END DO   
    239       END DO   
    240       ! 
    241       IF( PRESENT(l_mask) .AND. l_mask ) THEN 
    242          zqsrout(:,:) = float(imask_night(:,:)) 
    243       ENDIF 
    244       ! 
    245    END FUNCTION sbc_dcy 
     256      ENDIF !IF( nday_qsr /= nday ) 
     257      ! 
     258   END SUBROUTINE sbc_dcy_param 
     259 
     260 
     261   FUNCTION fintegral( pt1, pt2, paaa, pbbb, pccc ) 
     262      REAL(wp), INTENT(in) :: pt1, pt2, paaa, pbbb, pccc 
     263      REAL(wp) :: fintegral 
     264      fintegral =   paaa * pt2 + 1._wp/(2._wp*rpi) * pbbb * SIN(pccc + 2._wp*rpi*pt2)   & 
     265         &        - paaa * pt1 - 1._wp/(2._wp*rpi) * pbbb * SIN(pccc + 2._wp*rpi*pt1) 
     266   END FUNCTION fintegral 
    246267 
    247268   !!====================================================================== 
  • NEMO/trunk/src/OCE/SBC/sbcflx.F90

    r11536 r12377  
    3838 
    3939   !! * Substitutions 
    40 #  include "vectopt_loop_substitute.h90" 
     40#  include "do_loop_substitute.h90" 
    4141   !!---------------------------------------------------------------------- 
    4242   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    9191      IF( kt == nit000 ) THEN                ! First call kt=nit000   
    9292         ! set file information 
    93          REWIND( numnam_ref )              ! Namelist namsbc_flx in reference namelist : Files for fluxes 
    9493         READ  ( numnam_ref, namsbc_flx, IOSTAT = ios, ERR = 901) 
    9594901      IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_flx in reference namelist' ) 
    9695 
    97          REWIND( numnam_cfg )              ! Namelist namsbc_flx in configuration namelist : Files for fluxes 
    9896         READ  ( numnam_cfg, namsbc_flx, IOSTAT = ios, ERR = 902 ) 
    9997902      IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_flx in configuration namelist' ) 
     
    131129         ELSE                  ;   qsr(:,:) =          sf(jp_qsr)%fnow(:,:,1) 
    132130         ENDIF 
    133          DO jj = 1, jpj                                           ! set the ocean fluxes from read fields 
    134             DO ji = 1, jpi 
    135                utau(ji,jj) = sf(jp_utau)%fnow(ji,jj,1) 
    136                vtau(ji,jj) = sf(jp_vtau)%fnow(ji,jj,1) 
    137                qns (ji,jj) = sf(jp_qtot)%fnow(ji,jj,1) - sf(jp_qsr)%fnow(ji,jj,1) 
    138                emp (ji,jj) = sf(jp_emp )%fnow(ji,jj,1) 
    139             END DO 
    140          END DO 
     131         DO_2D_11_11 
     132            utau(ji,jj) = sf(jp_utau)%fnow(ji,jj,1) 
     133            vtau(ji,jj) = sf(jp_vtau)%fnow(ji,jj,1) 
     134            qns (ji,jj) = sf(jp_qtot)%fnow(ji,jj,1) - sf(jp_qsr)%fnow(ji,jj,1) 
     135            emp (ji,jj) = sf(jp_emp )%fnow(ji,jj,1) 
     136         END_2D 
    141137         !                                                        ! add to qns the heat due to e-p 
    142138         qns(:,:) = qns(:,:) - emp(:,:) * sst_m(:,:) * rcp        ! mass flux is at SST 
     
    147143         !                                                        ! module of wind stress and wind speed at T-point 
    148144         zcoef = 1. / ( zrhoa * zcdrag ) 
    149          DO jj = 2, jpjm1 
    150             DO ji = fs_2, fs_jpim1   ! vect. opt. 
    151                ztx = utau(ji-1,jj  ) + utau(ji,jj)  
    152                zty = vtau(ji  ,jj-1) + vtau(ji,jj)  
    153                zmod = 0.5 * SQRT( ztx * ztx + zty * zty ) 
    154                taum(ji,jj) = zmod 
    155                wndm(ji,jj) = SQRT( zmod * zcoef ) 
    156             END DO 
    157          END DO 
     145         DO_2D_00_00 
     146            ztx = utau(ji-1,jj  ) + utau(ji,jj)  
     147            zty = vtau(ji  ,jj-1) + vtau(ji,jj)  
     148            zmod = 0.5 * SQRT( ztx * ztx + zty * zty ) 
     149            taum(ji,jj) = zmod 
     150            wndm(ji,jj) = SQRT( zmod * zcoef ) 
     151         END_2D 
    158152         taum(:,:) = taum(:,:) * tmask(:,:,1) ; wndm(:,:) = wndm(:,:) * tmask(:,:,1) 
    159153         CALL lbc_lnk( 'sbcflx', taum(:,:), 'T', 1. )   ;   CALL lbc_lnk( 'sbcflx', wndm(:,:), 'T', 1. ) 
  • NEMO/trunk/src/OCE/SBC/sbcfwb.F90

    r10570 r12377  
    1717   USE dom_oce        ! ocean space and time domain 
    1818   USE sbc_oce        ! surface ocean boundary condition 
     19   USE isf_oce , ONLY : fwfisf_cav, fwfisf_par                    ! ice shelf melting contribution 
    1920   USE sbc_ice , ONLY : snwice_mass, snwice_mass_b, snwice_fmass 
    2021   USE phycst         ! physical constants 
    2122   USE sbcrnf         ! ocean runoffs 
    22    USE sbcisf         ! ice shelf melting contribution 
    2323   USE sbcssr         ! Sea-Surface damping terms 
    2424   ! 
     
    3939   REAL(wp) ::   area      ! global mean ocean surface (interior domain) 
    4040 
    41    !! * Substitutions 
    42 #  include "vectopt_loop_substitute.h90" 
    4341   !!---------------------------------------------------------------------- 
    4442   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    4846CONTAINS 
    4947 
    50    SUBROUTINE sbc_fwb( kt, kn_fwb, kn_fsbc ) 
     48   SUBROUTINE sbc_fwb( kt, kn_fwb, kn_fsbc, Kmm ) 
    5149      !!--------------------------------------------------------------------- 
    5250      !!                  ***  ROUTINE sbc_fwb  *** 
     
    6563      INTEGER, INTENT( in ) ::   kn_fsbc  !  
    6664      INTEGER, INTENT( in ) ::   kn_fwb   ! ocean time-step index 
     65      INTEGER, INTENT( in ) ::   Kmm      ! ocean time level index 
    6766      ! 
    6867      INTEGER  ::   inum, ikty, iyear     ! local integers 
     
    104103         ! 
    105104         IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN 
    106             y_fwfnow(1) = local_sum( e1e2t(:,:) * ( emp(:,:) - rnf(:,:) + fwfisf(:,:) - snwice_fmass(:,:) ) ) 
     105            y_fwfnow(1) = local_sum( e1e2t(:,:) * ( emp(:,:) - rnf(:,:) + fwfisf_cav(:,:) + fwfisf_par(:,:) - snwice_fmass(:,:) ) ) 
    107106            CALL mpp_delay_sum( 'sbcfwb', 'fwb', y_fwfnow(:), z_fwfprv(:), kt == nitend - nn_fsbc + 1 ) 
    108107            z_fwfprv(1) = z_fwfprv(1) / area 
     
    131130            a_fwb_b = a_fwb                           ! mean sea level taking into account the ice+snow 
    132131                                                      ! sum over the global domain 
    133             a_fwb   = glob_sum( 'sbcfwb', e1e2t(:,:) * ( sshn(:,:) + snwice_mass(:,:) * r1_rau0 ) ) 
     132            a_fwb   = glob_sum( 'sbcfwb', e1e2t(:,:) * ( ssh(:,:,Kmm) + snwice_mass(:,:) * r1_rau0 ) ) 
    134133            a_fwb   = a_fwb * 1.e+3 / ( area * rday * 365. )     ! convert in Kg/m3/s = mm/s 
    135134!!gm        !                                                      !!bug 365d year  
     
    159158            ztmsk_neg(:,:) = tmask_i(:,:) - ztmsk_pos(:,:) 
    160159            !                                                  ! fwf global mean (excluding ocean to ice/snow exchanges)  
    161             z_fwf     = glob_sum( 'sbcfwb', e1e2t(:,:) * ( emp(:,:) - rnf(:,:) + fwfisf(:,:) - snwice_fmass(:,:) ) ) / area 
     160            z_fwf     = glob_sum( 'sbcfwb', e1e2t(:,:) * ( emp(:,:) - rnf(:,:) + fwfisf_cav(:,:) + fwfisf_par(:,:) - snwice_fmass(:,:) ) ) / area 
    162161            !             
    163162            IF( z_fwf < 0._wp ) THEN         ! spread out over >0 erp area to increase evaporation 
  • NEMO/trunk/src/OCE/SBC/sbcice_cice.F90

    r11536 r12377  
    8888   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:), PRIVATE ::   png     ! local array used in sbc_cice_ice 
    8989 
     90   !! * Substitutions 
     91#  include "do_loop_substitute.h90" 
    9092   !!---------------------------------------------------------------------- 
    9193   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    132134         IF      ( ksbc == jp_flx ) THEN 
    133135            CALL cice_sbc_force(kt) 
    134          ELSE IF ( ksbc == jp_purecpl ) THEN 
     136         ELSE IF( ksbc == jp_purecpl ) THEN 
    135137            CALL sbc_cpl_ice_flx( fr_i ) 
    136138         ENDIF 
     
    140142         CALL cice_sbc_out ( kt, ksbc ) 
    141143 
    142          IF ( ksbc == jp_purecpl )  CALL cice_sbc_hadgam(kt+1) 
     144         IF( ksbc == jp_purecpl )  CALL cice_sbc_hadgam(kt+1) 
    143145 
    144146      ENDIF                                          ! End sea-ice time step only 
     
    147149 
    148150 
    149    SUBROUTINE cice_sbc_init( ksbc ) 
     151   SUBROUTINE cice_sbc_init( ksbc, Kbb, Kmm ) 
    150152      !!--------------------------------------------------------------------- 
    151153      !!                    ***  ROUTINE cice_sbc_init  *** 
     
    154156      !!--------------------------------------------------------------------- 
    155157      INTEGER, INTENT( in  ) ::   ksbc                ! surface forcing type 
     158      INTEGER, INTENT( in  ) ::   Kbb, Kmm            ! time level indices 
    156159      REAL(wp), DIMENSION(jpi,jpj) :: ztmp1, ztmp2 
    157160      REAL(wp) ::   zcoefu, zcoefv, zcoeff            ! local scalar 
     
    168171      ! there is no restart file. 
    169172      ! Values from a CICE restart file would overwrite this 
    170       IF ( .NOT. ln_rstart ) THEN     
    171          CALL nemo2cice( tsn(:,:,1,jp_tem) , sst , 'T' , 1.)  
     173      IF( .NOT. ln_rstart ) THEN     
     174         CALL nemo2cice( ts(:,:,1,jp_tem,Kmm) , sst , 'T' , 1.)  
    172175      ENDIF   
    173176#endif 
     
    177180 
    178181! Do some CICE consistency checks 
    179       IF ( (ksbc == jp_flx) .OR. (ksbc == jp_purecpl) ) THEN 
    180          IF ( calc_strair .OR. calc_Tsfc ) THEN 
     182      IF( (ksbc == jp_flx) .OR. (ksbc == jp_purecpl) ) THEN 
     183         IF( calc_strair .OR. calc_Tsfc ) THEN 
    181184            CALL ctl_stop( 'STOP', 'cice_sbc_init : Forcing option requires calc_strair=F and calc_Tsfc=F in ice_in' ) 
    182185         ENDIF 
    183       ELSEIF (ksbc == jp_blk) THEN 
    184          IF ( .NOT. (calc_strair .AND. calc_Tsfc) ) THEN 
     186      ELSEIF(ksbc == jp_blk) THEN 
     187         IF( .NOT. (calc_strair .AND. calc_Tsfc) ) THEN 
    185188            CALL ctl_stop( 'STOP', 'cice_sbc_init : Forcing option requires calc_strair=T and calc_Tsfc=T in ice_in' ) 
    186189         ENDIF 
     
    194197! Ensure ocean temperatures are nowhere below freezing if not a NEMO restart 
    195198      IF( .NOT. ln_rstart ) THEN 
    196          tsn(:,:,:,jp_tem) = MAX (tsn(:,:,:,jp_tem),Tocnfrz) 
    197          tsb(:,:,:,jp_tem) = tsn(:,:,:,jp_tem) 
     199         ts(:,:,:,jp_tem,Kmm) = MAX (ts(:,:,:,jp_tem,Kmm),Tocnfrz) 
     200         ts(:,:,:,jp_tem,Kbb) = ts(:,:,:,jp_tem,Kmm) 
    198201      ENDIF 
    199202 
     
    202205 
    203206      CALL cice2nemo(aice,fr_i, 'T', 1. ) 
    204       IF ( (ksbc == jp_flx) .OR. (ksbc == jp_purecpl) ) THEN 
     207      IF( (ksbc == jp_flx) .OR. (ksbc == jp_purecpl) ) THEN 
    205208         DO jl=1,ncat 
    206209            CALL cice2nemo(aicen(:,:,jl,:),a_i(:,:,jl), 'T', 1. ) 
     
    210213! T point to U point 
    211214! T point to V point 
    212       DO jj=1,jpjm1 
    213          DO ji=1,jpim1 
    214             fr_iu(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji+1,jj))*umask(ji,jj,1) 
    215             fr_iv(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji,jj+1))*vmask(ji,jj,1) 
    216          ENDDO 
    217       ENDDO 
     215      DO_2D_10_10 
     216         fr_iu(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji+1,jj))*umask(ji,jj,1) 
     217         fr_iv(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji,jj+1))*vmask(ji,jj,1) 
     218      END_2D 
    218219 
    219220      CALL lbc_lnk_multi( 'sbcice_cice', fr_iu , 'U', 1.,  fr_iv , 'V', 1. ) 
     
    227228      IF( .NOT.ln_rstart ) THEN 
    228229         IF( ln_ice_embd ) THEN            ! embedded sea-ice: deplete the initial ssh below sea-ice area 
    229             sshn(:,:) = sshn(:,:) - snwice_mass(:,:) * r1_rau0 
    230             sshb(:,:) = sshb(:,:) - snwice_mass(:,:) * r1_rau0 
     230            ssh(:,:,Kmm) = ssh(:,:,Kmm) - snwice_mass(:,:) * r1_rau0 
     231            ssh(:,:,Kbb) = ssh(:,:,Kbb) - snwice_mass(:,:) * r1_rau0 
    231232 
    232233!!gm This should be put elsewhere....   (same remark for limsbc) 
     
    235236               ! 
    236237               DO jk = 1,jpkm1                     ! adjust initial vertical scale factors 
    237                   e3t_n(:,:,jk) = e3t_0(:,:,jk)*( 1._wp + sshn(:,:)*tmask(:,:,1)/(ht_0(:,:) + 1.0 - tmask(:,:,1)) ) 
    238                   e3t_b(:,:,jk) = e3t_0(:,:,jk)*( 1._wp + sshb(:,:)*tmask(:,:,1)/(ht_0(:,:) + 1.0 - tmask(:,:,1)) ) 
     238                  e3t(:,:,jk,Kmm) = e3t_0(:,:,jk)*( 1._wp + ssh(:,:,Kmm)*tmask(:,:,1)/(ht_0(:,:) + 1.0 - tmask(:,:,1)) ) 
     239                  e3t(:,:,jk,Kbb) = e3t_0(:,:,jk)*( 1._wp + ssh(:,:,Kbb)*tmask(:,:,1)/(ht_0(:,:) + 1.0 - tmask(:,:,1)) ) 
    239240               ENDDO 
    240                e3t_a(:,:,:) = e3t_b(:,:,:) 
     241               e3t(:,:,:,Krhs) = e3t(:,:,:,Kbb) 
    241242               ! Reconstruction of all vertical scale factors at now and before time-steps 
    242243               ! ============================================================================= 
    243244               ! Horizontal scale factor interpolations 
    244245               ! -------------------------------------- 
    245                CALL dom_vvl_interpol( e3t_b(:,:,:), e3u_b(:,:,:), 'U' ) 
    246                CALL dom_vvl_interpol( e3t_b(:,:,:), e3v_b(:,:,:), 'V' ) 
    247                CALL dom_vvl_interpol( e3t_n(:,:,:), e3u_n(:,:,:), 'U' ) 
    248                CALL dom_vvl_interpol( e3t_n(:,:,:), e3v_n(:,:,:), 'V' ) 
    249                CALL dom_vvl_interpol( e3u_n(:,:,:), e3f_n(:,:,:), 'F' ) 
     246               CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3u(:,:,:,Kbb), 'U' ) 
     247               CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3v(:,:,:,Kbb), 'V' ) 
     248               CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3u(:,:,:,Kmm), 'U' ) 
     249               CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3v(:,:,:,Kmm), 'V' ) 
     250               CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3f(:,:,:), 'F' ) 
    250251               ! Vertical scale factor interpolations 
    251252               ! ------------------------------------ 
    252                CALL dom_vvl_interpol( e3t_n(:,:,:), e3w_n (:,:,:), 'W'  ) 
    253                CALL dom_vvl_interpol( e3u_n(:,:,:), e3uw_n(:,:,:), 'UW' ) 
    254                CALL dom_vvl_interpol( e3v_n(:,:,:), e3vw_n(:,:,:), 'VW' ) 
    255                CALL dom_vvl_interpol( e3u_b(:,:,:), e3uw_b(:,:,:), 'UW' ) 
    256                CALL dom_vvl_interpol( e3v_b(:,:,:), e3vw_b(:,:,:), 'VW' ) 
     253               CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3w (:,:,:,Kmm), 'W'  ) 
     254               CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3uw(:,:,:,Kmm), 'UW' ) 
     255               CALL dom_vvl_interpol( e3v(:,:,:,Kmm), e3vw(:,:,:,Kmm), 'VW' ) 
     256               CALL dom_vvl_interpol( e3u(:,:,:,Kbb), e3uw(:,:,:,Kbb), 'UW' ) 
     257               CALL dom_vvl_interpol( e3v(:,:,:,Kbb), e3vw(:,:,:,Kbb), 'VW' ) 
    257258               ! t- and w- points depth 
    258259               ! ---------------------- 
    259                gdept_n(:,:,1) = 0.5_wp * e3w_n(:,:,1) 
    260                gdepw_n(:,:,1) = 0.0_wp 
    261                gde3w_n(:,:,1) = gdept_n(:,:,1) - sshn(:,:) 
     260               gdept(:,:,1,Kmm) = 0.5_wp * e3w(:,:,1,Kmm) 
     261               gdepw(:,:,1,Kmm) = 0.0_wp 
     262               gde3w(:,:,1)     = gdept(:,:,1,Kmm) - ssh(:,:,Kmm) 
    262263               DO jk = 2, jpk 
    263                   gdept_n(:,:,jk) = gdept_n(:,:,jk-1) + e3w_n(:,:,jk) 
    264                   gdepw_n(:,:,jk) = gdepw_n(:,:,jk-1) + e3t_n(:,:,jk-1) 
    265                   gde3w_n(:,:,jk) = gdept_n(:,:,jk  ) - sshn   (:,:) 
     264                  gdept(:,:,jk,Kmm) = gdept(:,:,jk-1,Kmm) + e3w(:,:,jk,Kmm) 
     265                  gdepw(:,:,jk,Kmm) = gdepw(:,:,jk-1,Kmm) + e3t(:,:,jk-1,Kmm) 
     266                  gde3w(:,:,jk)     = gdept(:,:,jk  ,Kmm) - sshn   (:,:) 
    266267               END DO 
    267268            ENDIF 
     
    297298! forced and coupled case  
    298299 
    299       IF ( (ksbc == jp_flx).OR.(ksbc == jp_purecpl) ) THEN 
     300      IF( (ksbc == jp_flx).OR.(ksbc == jp_purecpl) ) THEN 
    300301 
    301302         ztmpn(:,:,:)=0.0 
     
    303304! x comp of wind stress (CI_1) 
    304305! U point to F point 
    305          DO jj=1,jpjm1 
    306             DO ji=1,jpi 
    307                ztmp(ji,jj) = 0.5 * (  fr_iu(ji,jj) * utau(ji,jj)      & 
    308                                     + fr_iu(ji,jj+1) * utau(ji,jj+1) ) * fmask(ji,jj,1) 
    309             ENDDO 
    310          ENDDO 
     306         DO_2D_10_11 
     307            ztmp(ji,jj) = 0.5 * (  fr_iu(ji,jj) * utau(ji,jj)      & 
     308                                 + fr_iu(ji,jj+1) * utau(ji,jj+1) ) * fmask(ji,jj,1) 
     309         END_2D 
    311310         CALL nemo2cice(ztmp,strax,'F', -1. ) 
    312311 
    313312! y comp of wind stress (CI_2) 
    314313! V point to F point 
    315          DO jj=1,jpj 
    316             DO ji=1,jpim1 
    317                ztmp(ji,jj) = 0.5 * (  fr_iv(ji,jj) * vtau(ji,jj)      & 
    318                                     + fr_iv(ji+1,jj) * vtau(ji+1,jj) ) * fmask(ji,jj,1) 
    319             ENDDO 
    320          ENDDO 
     314         DO_2D_11_10 
     315            ztmp(ji,jj) = 0.5 * (  fr_iv(ji,jj) * vtau(ji,jj)      & 
     316                                 + fr_iv(ji+1,jj) * vtau(ji+1,jj) ) * fmask(ji,jj,1) 
     317         END_2D 
    321318         CALL nemo2cice(ztmp,stray,'F', -1. ) 
    322319 
    323320! Surface downward latent heat flux (CI_5) 
    324          IF (ksbc == jp_flx) THEN 
     321         IF(ksbc == jp_flx) THEN 
    325322            DO jl=1,ncat 
    326323               ztmpn(:,:,jl)=qla_ice(:,:,1)*a_i(:,:,jl) 
     
    330327            qla_ice(:,:,1)= - ( emp_ice(:,:)+sprecip(:,:) ) * rLsub 
    331328! End of temporary code 
    332             DO jj=1,jpj 
    333                DO ji=1,jpi 
    334                   IF (fr_i(ji,jj).eq.0.0) THEN 
    335                      DO jl=1,ncat 
    336                         ztmpn(ji,jj,jl)=0.0 
    337                      ENDDO 
    338                      ! This will then be conserved in CICE 
    339                      ztmpn(ji,jj,1)=qla_ice(ji,jj,1) 
    340                   ELSE 
    341                      DO jl=1,ncat 
    342                         ztmpn(ji,jj,jl)=qla_ice(ji,jj,1)*a_i(ji,jj,jl)/fr_i(ji,jj) 
    343                      ENDDO 
    344                   ENDIF 
    345                ENDDO 
    346             ENDDO 
     329            DO_2D_11_11 
     330               IF(fr_i(ji,jj).eq.0.0) THEN 
     331                  DO jl=1,ncat 
     332                     ztmpn(ji,jj,jl)=0.0 
     333                  ENDDO 
     334                  ! This will then be conserved in CICE 
     335                  ztmpn(ji,jj,1)=qla_ice(ji,jj,1) 
     336               ELSE 
     337                  DO jl=1,ncat 
     338                     ztmpn(ji,jj,jl)=qla_ice(ji,jj,1)*a_i(ji,jj,jl)/fr_i(ji,jj) 
     339                  ENDDO 
     340               ENDIF 
     341            END_2D 
    347342         ENDIF 
    348343         DO jl=1,ncat 
     
    351346! GBM conductive flux through ice (CI_6) 
    352347!  Convert to GBM 
    353             IF (ksbc == jp_flx) THEN 
     348            IF(ksbc == jp_flx) THEN 
    354349               ztmp(:,:) = botmelt(:,:,jl)*a_i(:,:,jl) 
    355350            ELSE 
     
    360355! GBM surface heat flux (CI_7) 
    361356!  Convert to GBM 
    362             IF (ksbc == jp_flx) THEN 
     357            IF(ksbc == jp_flx) THEN 
    363358               ztmp(:,:) = (topmelt(:,:,jl)+botmelt(:,:,jl))*a_i(:,:,jl)  
    364359            ELSE 
     
    368363         ENDDO 
    369364 
    370       ELSE IF (ksbc == jp_blk) THEN 
     365      ELSE IF(ksbc == jp_blk) THEN 
    371366 
    372367! Pass bulk forcing fields to CICE (which will calculate heat fluxes etc itself) 
     
    434429! x comp and y comp of surface ocean current 
    435430! U point to F point 
    436       DO jj=1,jpjm1 
    437          DO ji=1,jpi 
    438             ztmp(ji,jj)=0.5*(ssu_m(ji,jj)+ssu_m(ji,jj+1))*fmask(ji,jj,1) 
    439          ENDDO 
    440       ENDDO 
     431      DO_2D_10_11 
     432         ztmp(ji,jj)=0.5*(ssu_m(ji,jj)+ssu_m(ji,jj+1))*fmask(ji,jj,1) 
     433      END_2D 
    441434      CALL nemo2cice(ztmp,uocn,'F', -1. ) 
    442435 
    443436! V point to F point 
    444       DO jj=1,jpj 
    445          DO ji=1,jpim1 
    446             ztmp(ji,jj)=0.5*(ssv_m(ji,jj)+ssv_m(ji+1,jj))*fmask(ji,jj,1) 
    447          ENDDO 
    448       ENDDO 
     437      DO_2D_11_10 
     438         ztmp(ji,jj)=0.5*(ssv_m(ji,jj)+ssv_m(ji+1,jj))*fmask(ji,jj,1) 
     439      END_2D 
    449440      CALL nemo2cice(ztmp,vocn,'F', -1. ) 
    450441 
     
    468459! x comp and y comp of sea surface slope (on F points) 
    469460! T point to F point 
    470       DO jj = 1, jpjm1 
    471          DO ji = 1, jpim1 
    472             ztmp(ji,jj)=0.5 * (  (zpice(ji+1,jj  )-zpice(ji,jj  )) * r1_e1u(ji,jj  )    & 
    473                &               + (zpice(ji+1,jj+1)-zpice(ji,jj+1)) * r1_e1u(ji,jj+1)  ) * fmask(ji,jj,1) 
    474          END DO 
    475       END DO 
     461      DO_2D_10_10 
     462         ztmp(ji,jj)=0.5 * (  (zpice(ji+1,jj  )-zpice(ji,jj  )) * r1_e1u(ji,jj  )    & 
     463            &               + (zpice(ji+1,jj+1)-zpice(ji,jj+1)) * r1_e1u(ji,jj+1)  ) * fmask(ji,jj,1) 
     464      END_2D 
    476465      CALL nemo2cice( ztmp,ss_tltx,'F', -1. ) 
    477466 
    478467! T point to F point 
    479       DO jj = 1, jpjm1 
    480          DO ji = 1, jpim1 
    481             ztmp(ji,jj)=0.5 * (  (zpice(ji  ,jj+1)-zpice(ji  ,jj)) * r1_e2v(ji  ,jj)    & 
    482                &               + (zpice(ji+1,jj+1)-zpice(ji+1,jj)) * r1_e2v(ji+1,jj)  ) *  fmask(ji,jj,1) 
    483          END DO 
    484       END DO 
     468      DO_2D_10_10 
     469         ztmp(ji,jj)=0.5 * (  (zpice(ji  ,jj+1)-zpice(ji  ,jj)) * r1_e2v(ji  ,jj)    & 
     470            &               + (zpice(ji+1,jj+1)-zpice(ji+1,jj)) * r1_e2v(ji+1,jj)  ) *  fmask(ji,jj,1) 
     471      END_2D 
    485472      CALL nemo2cice(ztmp,ss_tlty,'F', -1. ) 
    486473      ! 
     
    508495      ss_iou(:,:)=0.0 
    509496! F point to U point 
    510       DO jj=2,jpjm1 
    511          DO ji=2,jpim1 
    512             ss_iou(ji,jj) = 0.5 * ( ztmp1(ji,jj-1) + ztmp1(ji,jj) ) * umask(ji,jj,1) 
    513          ENDDO 
    514       ENDDO 
     497      DO_2D_00_00 
     498         ss_iou(ji,jj) = 0.5 * ( ztmp1(ji,jj-1) + ztmp1(ji,jj) ) * umask(ji,jj,1) 
     499      END_2D 
    515500      CALL lbc_lnk( 'sbcice_cice', ss_iou , 'U', -1. ) 
    516501 
     
    520505! F point to V point 
    521506 
    522       DO jj=1,jpjm1 
    523          DO ji=2,jpim1 
    524             ss_iov(ji,jj) = 0.5 * ( ztmp1(ji-1,jj) + ztmp1(ji,jj) ) * vmask(ji,jj,1) 
    525          ENDDO 
    526       ENDDO 
     507      DO_2D_10_00 
     508         ss_iov(ji,jj) = 0.5 * ( ztmp1(ji-1,jj) + ztmp1(ji,jj) ) * vmask(ji,jj,1) 
     509      END_2D 
    527510      CALL lbc_lnk( 'sbcice_cice', ss_iov , 'V', -1. ) 
    528511 
     
    546529! Freshwater fluxes  
    547530 
    548       IF (ksbc == jp_flx) THEN 
     531      IF(ksbc == jp_flx) THEN 
    549532! Note that emp from the forcing files is evap*(1-aice)-(tprecip-aice*sprecip) 
    550533! What we want here is evap*(1-aice)-tprecip*(1-aice) hence manipulation below 
     
    552535! Better to use evap and tprecip? (but for now don't read in evap in this case) 
    553536         emp(:,:)  = emp(:,:)+fr_i(:,:)*(tprecip(:,:)-sprecip(:,:)) 
    554       ELSE IF (ksbc == jp_blk) THEN 
     537      ELSE IF(ksbc == jp_blk) THEN 
    555538         emp(:,:)  = (1.0-fr_i(:,:))*emp(:,:)         
    556       ELSE IF (ksbc == jp_purecpl) THEN 
     539      ELSE IF(ksbc == jp_purecpl) THEN 
    557540! emp_tot is set in sbc_cpl_ice_flx (called from cice_sbc_in above)  
    558541! This is currently as required with the coupling fields from the UM atmosphere 
     
    584567! Scale qsr and qns according to ice fraction (bulk formulae only) 
    585568 
    586       IF (ksbc == jp_blk) THEN 
     569      IF(ksbc == jp_blk) THEN 
    587570         qsr(:,:)=qsr(:,:)*(1.0-fr_i(:,:)) 
    588571         qns(:,:)=qns(:,:)*(1.0-fr_i(:,:)) 
    589572      ENDIF 
    590573! Take into account snow melting except for fully coupled when already in qns_tot 
    591       IF (ksbc == jp_purecpl) THEN 
     574      IF(ksbc == jp_purecpl) THEN 
    592575         qsr(:,:)= qsr_tot(:,:) 
    593576         qns(:,:)= qns_tot(:,:) 
     
    606589      CALL lbc_lnk( 'sbcice_cice', qsr , 'T', 1. ) 
    607590 
    608       DO jj=1,jpj 
    609          DO ji=1,jpi 
    610             nfrzmlt(ji,jj)=MAX(nfrzmlt(ji,jj),0.0) 
    611          ENDDO 
    612       ENDDO 
     591      DO_2D_11_11 
     592         nfrzmlt(ji,jj)=MAX(nfrzmlt(ji,jj),0.0) 
     593      END_2D 
    613594 
    614595#if defined key_cice4 
     
    624605 
    625606      CALL cice2nemo(aice,fr_i,'T', 1. ) 
    626       IF ( (ksbc == jp_flx).OR.(ksbc == jp_purecpl) ) THEN 
     607      IF( (ksbc == jp_flx).OR.(ksbc == jp_purecpl) ) THEN 
    627608         DO jl=1,ncat 
    628609            CALL cice2nemo(aicen(:,:,jl,:),a_i(:,:,jl), 'T', 1. ) 
     
    632613! T point to U point 
    633614! T point to V point 
    634       DO jj=1,jpjm1 
    635          DO ji=1,jpim1 
    636             fr_iu(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji+1,jj))*umask(ji,jj,1) 
    637             fr_iv(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji,jj+1))*vmask(ji,jj,1) 
    638          ENDDO 
    639       ENDDO 
     615      DO_2D_10_10 
     616         fr_iu(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji+1,jj))*umask(ji,jj,1) 
     617         fr_iv(ji,jj)=0.5*(fr_i(ji,jj)+fr_i(ji,jj+1))*vmask(ji,jj,1) 
     618      END_2D 
    640619 
    641620      CALL lbc_lnk_multi( 'sbcice_cice', fr_iu , 'U', 1., fr_iv , 'V', 1. ) 
     
    762741         sn_bot5 = FLD_N( 'botmeltn5_1m' ,    -1.    ,  'botmeltn5' ,  .true.    , .true.  ,  ' yearly'  , ''       , ''         ,  ''    ) 
    763742 
    764          REWIND( numnam_ref )              ! Namelist namsbc_cice in reference namelist :  
    765743         READ  ( numnam_ref, namsbc_cice, IOSTAT = ios, ERR = 901) 
    766744901      IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_cice in reference namelist' ) 
    767745 
    768          REWIND( numnam_cfg )              ! Namelist namsbc_cice in configuration namelist : Parameters of the run 
    769746         READ  ( numnam_cfg, namsbc_cice, IOSTAT = ios, ERR = 902 ) 
    770747902      IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_cice in configuration namelist' ) 
     
    879856!     B. Gather pn into global array (png) 
    880857 
    881       IF ( jpnij > 1) THEN 
     858      IF( jpnij > 1) THEN 
    882859         CALL mppsync 
    883860         CALL mppgather (pn,0,png)  
     
    892869! (may be OK but not 100% sure) 
    893870 
    894       IF (nproc==0) THEN      
     871      IF(nproc==0) THEN      
    895872!        pcg(:,:)=0.0 
    896873         DO jn=1,jpnij 
     
    996973 
    997974      pn(:,:)=0.0 
    998       DO jj=1,jpjm1 
    999          DO ji=1,jpim1 
    1000             pn(ji,jj)=pc(ji+1-ji_off,jj+1-jj_off,1) 
    1001          ENDDO 
    1002       ENDDO 
     975      DO_2D_10_10 
     976         pn(ji,jj)=pc(ji+1-ji_off,jj+1-jj_off,1) 
     977      END_2D 
    1003978 
    1004979#else 
     
    1015990! the lbclnk call on pn will replace these with sensible values 
    1016991 
    1017       IF (nproc==0) THEN 
     992      IF(nproc==0) THEN 
    1018993         png(:,:,:)=0.0 
    1019994         DO jn=1,jpnij 
     
    10281003!     C. Scatter png into NEMO field (pn) for each processor 
    10291004 
    1030       IF ( jpnij > 1) THEN 
     1005      IF( jpnij > 1) THEN 
    10311006         CALL mppsync 
    10321007         CALL mppscatter (png,0,pn)  
     
    10561031   END SUBROUTINE sbc_ice_cice 
    10571032 
    1058    SUBROUTINE cice_sbc_init (ksbc)    ! Dummy routine 
     1033   SUBROUTINE cice_sbc_init (ksbc, Kbb, Kmm)    ! Dummy routine 
    10591034      IMPLICIT NONE 
    10601035      INTEGER, INTENT( in ) :: ksbc 
     1036      INTEGER, INTENT( in ) :: Kbb, Kmm 
    10611037      WRITE(*,*) 'cice_sbc_init: You should not have seen this print! error?', ksbc 
    10621038   END SUBROUTINE cice_sbc_init 
  • NEMO/trunk/src/OCE/SBC/sbcice_if.F90

    r11536 r12377  
    3535   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_ice   ! structure of input ice-cover (file informations, fields read) 
    3636    
     37   !! * Substitutions 
     38#  include "do_loop_substitute.h90" 
    3739   !!---------------------------------------------------------------------- 
    3840   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    4244CONTAINS 
    4345 
    44    SUBROUTINE sbc_ice_if( kt ) 
     46   SUBROUTINE sbc_ice_if( kt, Kbb, Kmm ) 
    4547      !!--------------------------------------------------------------------- 
    4648      !!                     ***  ROUTINE sbc_ice_if  *** 
     
    5961      !!--------------------------------------------------------------------- 
    6062      INTEGER, INTENT(in) ::   kt   ! ocean time step 
     63      INTEGER, INTENT(in) ::   Kbb, Kmm   ! ocean time level indices 
    6164      ! 
    6265      INTEGER  ::   ji, jj     ! dummy loop indices 
     
    7477         !                                      ! ====================== ! 
    7578         ! set file information 
    76          REWIND( numnam_ref )              ! Namelist namsbc_iif in reference namelist : Ice if file 
    7779         READ  ( numnam_ref, namsbc_iif, IOSTAT = ios, ERR = 901) 
    7880901      IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_iif in reference namelist' ) 
    7981 
    80          REWIND( numnam_cfg )              ! Namelist Namelist namsbc_iif in configuration namelist : Ice if file 
    8182         READ  ( numnam_cfg, namsbc_iif, IOSTAT = ios, ERR = 902 ) 
    8283902      IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_iif in configuration namelist' ) 
     
    108109 
    109110         ! Flux and ice fraction computation 
    110          DO jj = 1, jpj 
    111             DO ji = 1, jpi 
    112                ! 
    113                zt_fzp  = fr_i(ji,jj)                        ! freezing point temperature 
    114                zfr_obs = sf_ice(1)%fnow(ji,jj,1)            ! observed ice cover 
    115                !                                            ! ocean ice fraction (0/1) from the freezing point temperature 
    116                IF( sst_m(ji,jj) <= zt_fzp ) THEN   ;   fr_i(ji,jj) = 1.e0 
    117                ELSE                                ;   fr_i(ji,jj) = 0.e0 
    118                ENDIF 
     111         DO_2D_11_11 
     112            ! 
     113            zt_fzp  = fr_i(ji,jj)                        ! freezing point temperature 
     114            zfr_obs = sf_ice(1)%fnow(ji,jj,1)            ! observed ice cover 
     115            !                                            ! ocean ice fraction (0/1) from the freezing point temperature 
     116            IF( sst_m(ji,jj) <= zt_fzp ) THEN   ;   fr_i(ji,jj) = 1.e0 
     117            ELSE                                ;   fr_i(ji,jj) = 0.e0 
     118            ENDIF 
    119119 
    120                tsn(ji,jj,1,jp_tem) = MAX( tsn(ji,jj,1,jp_tem), zt_fzp )     ! avoid over-freezing point temperature 
     120            ts(ji,jj,1,jp_tem,Kmm) = MAX( ts(ji,jj,1,jp_tem,Kmm), zt_fzp )     ! avoid over-freezing point temperature 
    121121 
    122                qsr(ji,jj) = ( 1. - zfr_obs ) * qsr(ji,jj)   ! solar heat flux : zero below observed ice cover 
     122            qsr(ji,jj) = ( 1. - zfr_obs ) * qsr(ji,jj)   ! solar heat flux : zero below observed ice cover 
    123123 
    124                !                                            ! non solar heat flux : add a damping term  
    125                !      # ztrp*(t-(tgel-1.))  if observed ice and no opa ice   (zfr_obs=1 fr_i=0) 
    126                !      # ztrp*min(0,t-tgel)  if observed ice and opa ice      (zfr_obs=1 fr_i=1) 
    127                zqri = ztrp * ( tsb(ji,jj,1,jp_tem) - ( zt_fzp - 1.) ) 
    128                zqrj = ztrp * MIN( 0., tsb(ji,jj,1,jp_tem) - zt_fzp ) 
    129                zqrp = ( zfr_obs * ( (1. - fr_i(ji,jj) ) * zqri    & 
    130                  &                 +      fr_i(ji,jj)   * zqrj ) ) * tmask(ji,jj,1) 
     124            !                                            ! non solar heat flux : add a damping term  
     125            !      # ztrp*(t-(tgel-1.))  if observed ice and no opa ice   (zfr_obs=1 fr_i=0) 
     126            !      # ztrp*min(0,t-tgel)  if observed ice and opa ice      (zfr_obs=1 fr_i=1) 
     127            zqri = ztrp * ( ts(ji,jj,1,jp_tem,Kbb) - ( zt_fzp - 1.) ) 
     128            zqrj = ztrp * MIN( 0., ts(ji,jj,1,jp_tem,Kbb) - zt_fzp ) 
     129            zqrp = ( zfr_obs * ( (1. - fr_i(ji,jj) ) * zqri    & 
     130              &                 +      fr_i(ji,jj)   * zqrj ) ) * tmask(ji,jj,1) 
    131131 
    132                !                                            ! non-solar heat flux  
    133                !      # qns unchanged              if no climatological ice              (zfr_obs=0) 
    134                !      # qns = zqrp                 if climatological ice and no opa ice  (zfr_obs=1, fr_i=0) 
    135                !      # qns = zqrp -2(-4) watt/m2  if climatological ice and opa ice     (zfr_obs=1, fr_i=1) 
    136                !                                   (-2=arctic, -4=antarctic)    
    137                zqi = -3. + SIGN( 1._wp, ff_f(ji,jj) ) 
    138                qns(ji,jj) = ( ( 1.- zfr_obs ) * qns(ji,jj)                             & 
    139                   &          +      zfr_obs   * fr_i(ji,jj) * zqi ) * tmask(ji,jj,1)   & 
    140                   &       + zqrp 
    141             END DO 
    142          END DO 
     132            !                                            ! non-solar heat flux  
     133            !      # qns unchanged              if no climatological ice              (zfr_obs=0) 
     134            !      # qns = zqrp                 if climatological ice and no opa ice  (zfr_obs=1, fr_i=0) 
     135            !      # qns = zqrp -2(-4) watt/m2  if climatological ice and opa ice     (zfr_obs=1, fr_i=1) 
     136            !                                   (-2=arctic, -4=antarctic)    
     137            zqi = -3. + SIGN( 1._wp, ff_f(ji,jj) ) 
     138            qns(ji,jj) = ( ( 1.- zfr_obs ) * qns(ji,jj)                             & 
     139               &          +      zfr_obs   * fr_i(ji,jj) * zqi ) * tmask(ji,jj,1)   & 
     140               &       + zqrp 
     141         END_2D 
    143142         ! 
    144143      ENDIF 
  • NEMO/trunk/src/OCE/SBC/sbcmod.F90

    r12276 r12377  
    1515   !!            3.6  ! 2014-11  (P. Mathiot, C. Harris) add ice shelves melting 
    1616   !!            4.0  ! 2016-06  (L. Brodeau) new general bulk formulation 
     17   !!            4.0  ! 2019-03  (F. Lemarié & G. Samson)  add ABL compatibility (ln_abl=TRUE) 
    1718   !!---------------------------------------------------------------------- 
    1819 
     
    2425   USE oce            ! ocean dynamics and tracers 
    2526   USE dom_oce        ! ocean space and time domain 
     27   USE closea         ! closed seas 
    2628   USE phycst         ! physical constants 
    2729   USE sbc_oce        ! Surface boundary condition: ocean fields 
     
    3234   USE sbcflx         ! surface boundary condition: flux formulation 
    3335   USE sbcblk         ! surface boundary condition: bulk formulation 
     36   USE sbcabl         ! atmospheric boundary layer 
    3437   USE sbcice_if      ! surface boundary condition: ice-if sea-ice model 
    3538#if defined key_si3 
     
    3740#endif 
    3841   USE sbcice_cice    ! surface boundary condition: CICE sea-ice model 
    39    USE sbcisf         ! surface boundary condition: ice-shelf 
    4042   USE sbccpl         ! surface boundary condition: coupled formulation 
    4143   USE cpl_oasis3     ! OASIS routines for coupling 
     44   USE sbcclo         ! surface boundary condition: closed sea correction 
    4245   USE sbcssr         ! surface boundary condition: sea surface restoring 
    4346   USE sbcrnf         ! surface boundary condition: runoffs 
    4447   USE sbcapr         ! surface boundary condition: atmo pressure  
    45    USE sbcisf         ! surface boundary condition: ice shelf 
    4648   USE sbcfwb         ! surface boundary condition: freshwater budget 
    4749   USE icbstp         ! Icebergs 
     
    5961   USE timing         ! Timing 
    6062   USE wet_dry 
    61    USE diurnal_bulk, ONLY:   ln_diurnal_only   ! diurnal SST diagnostic 
     63   USE diu_bulk, ONLY:   ln_diurnal_only   ! diurnal SST diagnostic 
    6264 
    6365   IMPLICIT NONE 
     
    7678CONTAINS 
    7779 
    78    SUBROUTINE sbc_init 
     80   SUBROUTINE sbc_init( Kbb, Kmm, Kaa ) 
    7981      !!--------------------------------------------------------------------- 
    8082      !!                    ***  ROUTINE sbc_init *** 
     
    8890      !!              - nsbc: type of sbc 
    8991      !!---------------------------------------------------------------------- 
     92      INTEGER, INTENT(in) ::   Kbb, Kmm, Kaa         ! ocean time level indices 
    9093      INTEGER ::   ios, icpt                         ! local integer 
    9194      LOGICAL ::   ll_purecpl, ll_opa, ll_not_nemo   ! local logical 
    9295      !! 
    9396      NAMELIST/namsbc/ nn_fsbc  ,                                                    & 
    94          &             ln_usr   , ln_flx   , ln_blk       ,                          & 
     97         &             ln_usr   , ln_flx   , ln_blk   , ln_abl,                      & 
    9598         &             ln_cpl   , ln_mixcpl, nn_components,                          & 
    9699         &             nn_ice   , ln_ice_embd,                                       & 
    97100         &             ln_traqsr, ln_dm2dc ,                                         & 
    98          &             ln_rnf   , nn_fwb   , ln_ssr   , ln_isf    , ln_apr_dyn ,     & 
    99          &             ln_wave  , ln_cdgw  , ln_sdw   , ln_tauwoc  , ln_stcor   ,     & 
     101         &             ln_rnf   , nn_fwb     , ln_ssr   , ln_apr_dyn,              & 
     102         &             ln_wave  , ln_cdgw  , ln_sdw   , ln_tauwoc  , ln_stcor  ,     & 
    100103         &             ln_tauw  , nn_lsm, nn_sdrift 
    101104      !!---------------------------------------------------------------------- 
     
    108111      ! 
    109112      !                       !**  read Surface Module namelist 
    110       REWIND( numnam_ref )          !* Namelist namsbc in reference namelist : Surface boundary 
    111113      READ  ( numnam_ref, namsbc, IOSTAT = ios, ERR = 901) 
    112114901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc in reference namelist' ) 
    113       REWIND( numnam_cfg )          !* Namelist namsbc in configuration namelist : Parameters of the run 
    114115      READ  ( numnam_cfg, namsbc, IOSTAT = ios, ERR = 902 ) 
    115116902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc in configuration namelist' ) 
     
    125126         IF( lk_cice )   nn_ice      = 3 
    126127      ENDIF 
    127 #else 
    128       IF( lk_si3  )   nn_ice      = 2 
    129       IF( lk_cice )   nn_ice      = 3 
     128!!GS: TBD 
     129!#else 
     130!      IF( lk_si3  )   nn_ice      = 2 
     131!      IF( lk_cice )   nn_ice      = 3 
    130132#endif 
    131133      ! 
     
    137139         WRITE(numout,*) '         flux         formulation                   ln_flx        = ', ln_flx 
    138140         WRITE(numout,*) '         bulk         formulation                   ln_blk        = ', ln_blk 
     141         WRITE(numout,*) '         ABL          formulation                   ln_abl        = ', ln_abl 
    139142         WRITE(numout,*) '      Type of coupling (Ocean/Ice/Atmosphere) : ' 
    140143         WRITE(numout,*) '         ocean-atmosphere coupled formulation       ln_cpl        = ', ln_cpl 
     
    153156         WRITE(numout,*) '         Patm gradient added in ocean & ice Eqs.    ln_apr_dyn    = ', ln_apr_dyn 
    154157         WRITE(numout,*) '         runoff / runoff mouths                     ln_rnf        = ', ln_rnf 
    155          WRITE(numout,*) '         iceshelf formulation                       ln_isf        = ', ln_isf 
    156158         WRITE(numout,*) '         nb of iterations if land-sea-mask applied  nn_lsm        = ', nn_lsm 
    157159         WRITE(numout,*) '         surface wave                               ln_wave       = ', ln_wave 
     
    225227      CASE( 1 )                        !- Ice-cover climatology ("Ice-if" model)   
    226228      CASE( 2 )                        !- SI3  ice model 
     229         IF( .NOT.( ln_blk .OR. ln_cpl .OR. ln_abl .OR. ln_usr ) )   & 
     230            &                   CALL ctl_stop( 'sbc_init : SI3 sea-ice model requires ln_blk or ln_cpl or ln_abl or ln_usr = T' ) 
    227231      CASE( 3 )                        !- CICE ice model 
    228          IF( .NOT.( ln_blk .OR. ln_cpl ) )   CALL ctl_stop( 'sbc_init : CICE sea-ice model requires ln_blk or ln_cpl = T' ) 
    229          IF( lk_agrif                    )   CALL ctl_stop( 'sbc_init : CICE sea-ice model not currently available with AGRIF' )  
     232         IF( .NOT.( ln_blk .OR. ln_cpl .OR. ln_abl .OR. ln_usr ) )   & 
     233            &                   CALL ctl_stop( 'sbc_init : CICE sea-ice model requires ln_blk or ln_cpl or ln_abl or ln_usr = T' ) 
     234         IF( lk_agrif                                )   & 
     235            &                   CALL ctl_stop( 'sbc_init : CICE sea-ice model not currently available with AGRIF' )  
    230236      CASE DEFAULT                     !- not supported 
    231237      END SELECT 
     238      IF( ln_diurnal .AND. .NOT. ln_blk  )   CALL ctl_stop( "sbc_init: diurnal flux processing only implemented for bulk forcing" ) 
    232239      ! 
    233240      !                       !**  allocate and set required variables 
     
    239246#endif 
    240247      ! 
    241       IF( .NOT.ln_isf ) THEN        !* No ice-shelf in the domain : allocate and set to zero 
    242          IF( sbc_isf_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'sbc_init : unable to allocate sbc_isf arrays' ) 
    243          fwfisf  (:,:)   = 0._wp   ;   risf_tsc  (:,:,:) = 0._wp 
    244          fwfisf_b(:,:)   = 0._wp   ;   risf_tsc_b(:,:,:) = 0._wp 
    245       END IF 
    246248      ! 
    247249      IF( sbc_ssr_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'sbc_init : unable to allocate sbc_ssr arrays' ) 
     
    262264 
    263265      !                          ! Choice of the Surface Boudary Condition (set nsbc) 
     266      nday_qsr = -1   ! allow initialization at the 1st call !LB: now warm-layer of COARE* calls "sbc_dcy_param" of sbcdcy.F90! 
    264267      IF( ln_dm2dc ) THEN           !* daily mean to diurnal cycle 
    265          nday_qsr = -1   ! allow initialization at the 1st call 
    266          IF( .NOT.( ln_flx .OR. ln_blk ) .AND. nn_components /= jp_iam_opa )   & 
    267             &   CALL ctl_stop( 'qsr diurnal cycle from daily values requires a flux or bulk formulation' ) 
     268         !LB:nday_qsr = -1   ! allow initialization at the 1st call 
     269         IF( .NOT.( ln_flx .OR. ln_blk .OR. ln_abl ) .AND. nn_components /= jp_iam_opa )   & 
     270            &   CALL ctl_stop( 'qsr diurnal cycle from daily values requires flux, bulk or abl formulation' ) 
    268271      ENDIF 
    269272      !                             !* Choice of the Surface Boudary Condition 
     
    278281      IF( ln_flx          ) THEN   ;   nsbc = jp_flx     ; icpt = icpt + 1   ;   ENDIF       ! flux                 formulation 
    279282      IF( ln_blk          ) THEN   ;   nsbc = jp_blk     ; icpt = icpt + 1   ;   ENDIF       ! bulk                 formulation 
     283      IF( ln_abl          ) THEN   ;   nsbc = jp_abl     ; icpt = icpt + 1   ;   ENDIF       ! ABL                  formulation 
    280284      IF( ll_purecpl      ) THEN   ;   nsbc = jp_purecpl ; icpt = icpt + 1   ;   ENDIF       ! Pure Coupled         formulation 
    281285      IF( ll_opa          ) THEN   ;   nsbc = jp_none    ; icpt = icpt + 1   ;   ENDIF       ! opa coupling via SAS module 
     
    289293         CASE( jp_flx     )   ;   WRITE(numout,*) '   ==>>>   flux formulation' 
    290294         CASE( jp_blk     )   ;   WRITE(numout,*) '   ==>>>   bulk formulation' 
     295         CASE( jp_abl     )   ;   WRITE(numout,*) '   ==>>>   ABL  formulation' 
    291296         CASE( jp_purecpl )   ;   WRITE(numout,*) '   ==>>>   pure coupled formulation' 
    292297!!gm abusive use of jp_none ??   ===>>> need to be check and changed by adding a jp_sas parameter 
     
    335340      !                       !**  associated modules : initialization 
    336341      ! 
    337                           CALL sbc_ssm_init            ! Sea-surface mean fields initialization 
     342                          CALL sbc_ssm_init ( Kbb, Kmm ) ! Sea-surface mean fields initialization 
     343      ! 
     344      IF( l_sbc_clo   )   CALL sbc_clo_init              ! closed sea surface initialisation 
    338345      ! 
    339346      IF( ln_blk      )   CALL sbc_blk_init            ! bulk formulae initialization 
    340347 
     348      IF( ln_abl      )   CALL sbc_abl_init            ! Atmospheric Boundary Layer (ABL) 
     349 
    341350      IF( ln_ssr      )   CALL sbc_ssr_init            ! Sea-Surface Restoring initialization 
    342351      ! 
    343       IF( ln_isf      )   CALL sbc_isf_init            ! Compute iceshelves 
    344       ! 
    345                           CALL sbc_rnf_init            ! Runof initialization 
    346       ! 
    347       IF( ln_apr_dyn )    CALL sbc_apr_init            ! Atmo Pressure Forcing initialization 
     352      ! 
     353                          CALL sbc_rnf_init( Kmm )       ! Runof initialization 
     354      ! 
     355      IF( ln_apr_dyn )    CALL sbc_apr_init              ! Atmo Pressure Forcing initialization 
    348356      ! 
    349357#if defined key_si3 
     
    351359                          IF( sbc_ice_alloc() /= 0 )   CALL ctl_stop('STOP', 'sbc_ice_alloc : unable to allocate arrays' ) 
    352360      ELSEIF( nn_ice == 2 ) THEN 
    353                           CALL ice_init                ! ICE initialization 
     361                          CALL ice_init( Kbb, Kmm, Kaa )         ! ICE initialization 
    354362      ENDIF 
    355363#endif 
    356       IF( nn_ice == 3 )   CALL cice_sbc_init( nsbc )   ! CICE initialization 
    357       ! 
    358       IF( ln_wave     )   CALL sbc_wave_init           ! surface wave initialisation 
     364      IF( nn_ice == 3 )   CALL cice_sbc_init( nsbc, Kbb, Kmm )   ! CICE initialization 
     365      ! 
     366      IF( ln_wave     )   CALL sbc_wave_init                     ! surface wave initialisation 
    359367      ! 
    360368      IF( lwxios ) THEN 
     
    371379 
    372380 
    373    SUBROUTINE sbc( kt ) 
     381   SUBROUTINE sbc( kt, Kbb, Kmm ) 
    374382      !!--------------------------------------------------------------------- 
    375383      !!                    ***  ROUTINE sbc  *** 
     
    388396      !!---------------------------------------------------------------------- 
    389397      INTEGER, INTENT(in) ::   kt   ! ocean time step 
     398      INTEGER, INTENT(in) ::   Kbb, Kmm   ! ocean time level indices 
    390399      ! 
    391400      LOGICAL ::   ll_sas, ll_opa   ! local logical 
     
    406415         emp_b (:,:) = emp (:,:) 
    407416         sfx_b (:,:) = sfx (:,:) 
    408          IF ( ln_rnf ) THEN 
     417         IF( ln_rnf ) THEN 
    409418            rnf_b    (:,:  ) = rnf    (:,:  ) 
    410419            rnf_tsc_b(:,:,:) = rnf_tsc(:,:,:) 
    411420         ENDIF 
    412          IF( ln_isf )  THEN 
    413             fwfisf_b  (:,:  ) = fwfisf  (:,:  )                
    414             risf_tsc_b(:,:,:) = risf_tsc(:,:,:)               
    415          ENDIF 
    416421        ! 
    417422      ENDIF 
     
    423428      ll_opa = nn_components == jp_iam_opa 
    424429      ! 
    425       IF( .NOT.ll_sas )   CALL sbc_ssm ( kt )            ! mean ocean sea surface variables (sst_m, sss_m, ssu_m, ssv_m) 
    426       IF( ln_wave     )   CALL sbc_wave( kt )            ! surface waves 
     430      IF( .NOT.ll_sas )   CALL sbc_ssm ( kt, Kbb, Kmm )  ! mean ocean sea surface variables (sst_m, sss_m, ssu_m, ssv_m) 
     431      IF( ln_wave     )   CALL sbc_wave( kt, Kmm )       ! surface waves 
    427432 
    428433      ! 
     
    431436      SELECT CASE( nsbc )                                ! Compute ocean surface boundary condition 
    432437      !                                                  ! (i.e. utau,vtau, qns, qsr, emp, sfx) 
    433       CASE( jp_usr   )     ;   CALL usrdef_sbc_oce( kt )                    ! user defined formulation  
    434       CASE( jp_flx     )   ;   CALL sbc_flx       ( kt )                    ! flux formulation 
     438      CASE( jp_usr   )     ;   CALL usrdef_sbc_oce( kt, Kbb )                        ! user defined formulation  
     439      CASE( jp_flx     )   ;   CALL sbc_flx       ( kt )                             ! flux formulation 
    435440      CASE( jp_blk     ) 
    436          IF( ll_sas    )       CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice )   ! OPA-SAS coupling: SAS receiving fields from OPA 
     441         IF( ll_sas    )       CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice, Kbb, Kmm )   ! OPA-SAS coupling: SAS receiving fields from OPA 
    437442                               CALL sbc_blk       ( kt )                    ! bulk formulation for the ocean 
    438443                               ! 
    439       CASE( jp_purecpl )   ;   CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice )   ! pure coupled formulation 
     444      CASE( jp_abl     ) 
     445         IF( ll_sas    )       CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice, Kbb, Kmm )   ! OPA-SAS coupling: SAS receiving fields from OPA 
     446                               CALL sbc_abl       ( kt )                    ! ABL  formulation for the ocean 
     447                               ! 
     448      CASE( jp_purecpl )   ;   CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice, Kbb, Kmm )   ! pure coupled formulation 
    440449      CASE( jp_none    ) 
    441          IF( ll_opa    )       CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice )   ! OPA-SAS coupling: OPA receiving fields from SAS 
     450         IF( ll_opa    )       CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice, Kbb, Kmm )  ! OPA-SAS coupling: OPA receiving fields from SAS 
    442451      END SELECT 
    443452      ! 
    444       IF( ln_mixcpl )          CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice )   ! forced-coupled mixed formulation after forcing 
    445       ! 
    446       IF ( ln_wave .AND. (ln_tauwoc .OR. ln_tauw) ) CALL sbc_wstress( )      ! Wind stress provided by waves  
     453      IF( ln_mixcpl )          CALL sbc_cpl_rcv   ( kt, nn_fsbc, nn_ice, Kbb, Kmm )  ! forced-coupled mixed formulation after forcing 
     454      ! 
     455      IF ( ln_wave .AND. (ln_tauwoc .OR. ln_tauw) ) CALL sbc_wstress( )              ! Wind stress provided by waves  
    447456      ! 
    448457      !                                            !==  Misc. Options  ==! 
    449458      ! 
    450459      SELECT CASE( nn_ice )                                       ! Update heat and freshwater fluxes over sea-ice areas 
    451       CASE(  1 )   ;         CALL sbc_ice_if   ( kt )             ! Ice-cover climatology ("Ice-if" model) 
     460      CASE(  1 )   ;         CALL sbc_ice_if   ( kt, Kbb, Kmm )   ! Ice-cover climatology ("Ice-if" model) 
    452461#if defined key_si3 
    453       CASE(  2 )   ;         CALL ice_stp  ( kt, nsbc )          ! SI3 ice model 
     462      CASE(  2 )   ;         CALL ice_stp  ( kt, Kbb, Kmm, nsbc ) ! SI3 ice model 
    454463#endif 
    455464      CASE(  3 )   ;         CALL sbc_ice_cice ( kt, nsbc )       ! CICE ice model 
     
    458467      IF( ln_icebergs    )   THEN 
    459468                                     CALL icb_stp( kt )           ! compute icebergs 
    460          ! icebergs may advect into haloes during the icb step and alter emp. 
    461          ! A lbc_lnk is necessary here to ensure restartability (#2113) 
     469         ! Icebergs do not melt over the haloes.  
     470         ! So emp values over the haloes are no more consistent with the inner domain values.  
     471         ! A lbc_lnk is therefore needed to ensure reproducibility and restartability. 
     472         ! see ticket #2113 for discussion about this lbc_lnk. 
    462473         IF( .NOT. ln_passive_mode ) CALL lbc_lnk( 'sbcmod', emp, 'T', 1. ) ! ensure restartability with icebergs 
    463474      ENDIF 
    464475 
    465       IF( ln_isf         )   CALL sbc_isf( kt )                   ! compute iceshelves 
    466  
    467476      IF( ln_rnf         )   CALL sbc_rnf( kt )                   ! add runoffs to fresh water fluxes 
    468477 
    469       IF( ln_ssr         )   CALL sbc_ssr( kt )                   ! add SST/SSS damping term 
    470  
    471       IF( nn_fwb    /= 0 )   CALL sbc_fwb( kt, nn_fwb, nn_fsbc )  ! control the freshwater budget 
     478      IF( ln_ssr         )   CALL sbc_ssr( kt )                        ! add SST/SSS damping term 
     479 
     480      IF( nn_fwb    /= 0 )   CALL sbc_fwb( kt, nn_fwb, nn_fsbc, Kmm )  ! control the freshwater budget 
    472481 
    473482      ! Special treatment of freshwater fluxes over closed seas in the model domain 
    474483      ! Should not be run if ln_diurnal_only 
    475       IF( l_sbc_clo .AND. (.NOT. ln_diurnal_only) )   CALL sbc_clo( kt )    
     484      IF( l_sbc_clo     )   CALL sbc_clo( kt )    
    476485 
    477486!!$!RBbug do not understand why see ticket 667 
    478487!!$!clem: it looks like it is necessary for the north fold (in certain circumstances). Don't know why. 
    479488!!$      CALL lbc_lnk( 'sbcmod', emp, 'T', 1. ) 
    480       IF ( ll_wd ) THEN     ! If near WAD point limit the flux for now 
     489      IF( ll_wd ) THEN     ! If near WAD point limit the flux for now 
    481490         zthscl = atanh(rn_wd_sbcfra)                     ! taper frac default is .999  
    482          zwdht(:,:) = sshn(:,:) + ht_0(:,:) - rn_wdmin1   ! do this calc of water 
     491         zwdht(:,:) = ssh(:,:,Kmm) + ht_0(:,:) - rn_wdmin1   ! do this calc of water 
    483492                                                     ! depth above wd limit once 
    484493         WHERE( zwdht(:,:) <= 0.0 ) 
     
    510519            CALL iom_get( numror, jpdom_autoglo, 'utau_b', utau_b, ldxios = lrxios )   ! before i-stress  (U-point) 
    511520            CALL iom_get( numror, jpdom_autoglo, 'vtau_b', vtau_b, ldxios = lrxios )   ! before j-stress  (V-point) 
    512             CALL iom_get( numror, jpdom_autoglo, 'qns_b' , qns_b, ldxios = lrxios )   ! before non solar heat flux (T-point) 
     521            CALL iom_get( numror, jpdom_autoglo,  'qns_b',  qns_b, ldxios = lrxios )   ! before non solar heat flux (T-point) 
    513522            ! The 3D heat content due to qsr forcing is treated in traqsr 
    514523            ! CALL iom_get( numror, jpdom_autoglo, 'qsr_b' , qsr_b, ldxios = lrxios  ) ! before     solar heat flux (T-point) 
     
    567576      CALL iom_put( "vtau", vtau )   ! j-wind stress 
    568577      ! 
    569       IF(ln_ctl) THEN         ! print mean trends (used for debugging) 
    570          CALL prt_ctl(tab2d_1=fr_i              , clinfo1=' fr_i    - : ', mask1=tmask ) 
    571          CALL prt_ctl(tab2d_1=(emp-rnf + fwfisf), clinfo1=' emp-rnf - : ', mask1=tmask ) 
    572          CALL prt_ctl(tab2d_1=(sfx-rnf + fwfisf), clinfo1=' sfx-rnf - : ', mask1=tmask ) 
     578      IF(sn_cfctl%l_prtctl) THEN     ! print mean trends (used for debugging) 
     579         CALL prt_ctl(tab2d_1=fr_i             , clinfo1=' fr_i     - : ', mask1=tmask ) 
     580         CALL prt_ctl(tab2d_1=(emp-rnf)        , clinfo1=' emp-rnf - : ', mask1=tmask ) 
     581         CALL prt_ctl(tab2d_1=(sfx-rnf)        , clinfo1=' sfx-rnf - : ', mask1=tmask ) 
    573582         CALL prt_ctl(tab2d_1=qns              , clinfo1=' qns      - : ', mask1=tmask ) 
    574583         CALL prt_ctl(tab2d_1=qsr              , clinfo1=' qsr      - : ', mask1=tmask ) 
    575584         CALL prt_ctl(tab3d_1=tmask            , clinfo1=' tmask    - : ', mask1=tmask, kdim=jpk ) 
    576          CALL prt_ctl(tab3d_1=tsn(:,:,:,jp_tem), clinfo1=' sst      - : ', mask1=tmask, kdim=1   ) 
    577          CALL prt_ctl(tab3d_1=tsn(:,:,:,jp_sal), clinfo1=' sss      - : ', mask1=tmask, kdim=1   ) 
    578          CALL prt_ctl(tab2d_1=utau             , clinfo1=' utau     - : ', mask1=umask,                      & 
    579             &         tab2d_2=vtau             , clinfo2=' vtau     - : ', mask2=vmask ) 
     585         CALL prt_ctl(tab3d_1=ts(:,:,:,jp_tem,Kmm), clinfo1=' sst      - : ', mask1=tmask, kdim=1   ) 
     586         CALL prt_ctl(tab3d_1=ts(:,:,:,jp_sal,Kmm), clinfo1=' sss      - : ', mask1=tmask, kdim=1   ) 
     587         CALL prt_ctl(tab2d_1=utau                , clinfo1=' utau     - : ', mask1=umask,                      & 
     588            &         tab2d_2=vtau                , clinfo2=' vtau     - : ', mask2=vmask ) 
    580589      ENDIF 
    581590 
  • NEMO/trunk/src/OCE/SBC/sbcrnf.F90

    r12277 r12377  
    7070   TYPE(FLD),        ALLOCATABLE, DIMENSION(:) ::   sf_t_rnf     ! structure: river runoff temperature (file information, fields read)   
    7171  
     72   !! * Substitutions 
     73#  include "do_loop_substitute.h90" 
    7274   !!---------------------------------------------------------------------- 
    7375   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    183185 
    184186 
    185    SUBROUTINE sbc_rnf_div( phdivn ) 
     187   SUBROUTINE sbc_rnf_div( phdivn, Kmm ) 
    186188      !!---------------------------------------------------------------------- 
    187189      !!                  ***  ROUTINE sbc_rnf  *** 
     
    195197      !! ** Action  :   phdivn   decreased by the runoff inflow 
    196198      !!---------------------------------------------------------------------- 
     199      INTEGER                   , INTENT(in   ) ::   Kmm      ! ocean time level index 
    197200      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   phdivn   ! horizontal divergence 
    198201      !! 
     
    205208      IF( ln_rnf_depth .OR. ln_rnf_depth_ini ) THEN      !==   runoff distributed over several levels   ==! 
    206209         IF( ln_linssh ) THEN    !* constant volume case : just apply the runoff input flow 
    207             DO jj = 1, jpj 
    208                DO ji = 1, jpi 
    209                   DO jk = 1, nk_rnf(ji,jj) 
    210                      phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rau0 / h_rnf(ji,jj) 
    211                   END DO 
     210            DO_2D_11_11 
     211               DO jk = 1, nk_rnf(ji,jj) 
     212                  phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rau0 / h_rnf(ji,jj) 
    212213               END DO 
    213             END DO 
     214            END_2D 
    214215         ELSE                    !* variable volume case 
    215             DO jj = 1, jpj                   ! update the depth over which runoffs are distributed 
    216                DO ji = 1, jpi 
    217                   h_rnf(ji,jj) = 0._wp 
    218                   DO jk = 1, nk_rnf(ji,jj)                           ! recalculates h_rnf to be the depth in metres 
    219                      h_rnf(ji,jj) = h_rnf(ji,jj) + e3t_n(ji,jj,jk)   ! to the bottom of the relevant grid box 
    220                   END DO 
    221                   !                          ! apply the runoff input flow 
    222                   DO jk = 1, nk_rnf(ji,jj) 
    223                      phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rau0 / h_rnf(ji,jj) 
    224                   END DO 
     216            DO_2D_11_11 
     217               h_rnf(ji,jj) = 0._wp 
     218               DO jk = 1, nk_rnf(ji,jj)                           ! recalculates h_rnf to be the depth in metres 
     219                  h_rnf(ji,jj) = h_rnf(ji,jj) + e3t(ji,jj,jk,Kmm)   ! to the bottom of the relevant grid box 
    225220               END DO 
    226             END DO 
     221               !                          ! apply the runoff input flow 
     222               DO jk = 1, nk_rnf(ji,jj) 
     223                  phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rau0 / h_rnf(ji,jj) 
     224               END DO 
     225            END_2D 
    227226         ENDIF 
    228227      ELSE                       !==   runoff put only at the surface   ==! 
    229          h_rnf (:,:)   = e3t_n (:,:,1)        ! update h_rnf to be depth of top box 
    230          phdivn(:,:,1) = phdivn(:,:,1) - ( rnf(:,:) + rnf_b(:,:) ) * zfact * r1_rau0 / e3t_n(:,:,1) 
     228         h_rnf (:,:)   = e3t (:,:,1,Kmm)        ! update h_rnf to be depth of top box 
     229         phdivn(:,:,1) = phdivn(:,:,1) - ( rnf(:,:) + rnf_b(:,:) ) * zfact * r1_rau0 / e3t(:,:,1,Kmm) 
    231230      ENDIF 
    232231      ! 
     
    234233 
    235234 
    236    SUBROUTINE sbc_rnf_init 
     235   SUBROUTINE sbc_rnf_init( Kmm ) 
    237236      !!---------------------------------------------------------------------- 
    238237      !!                  ***  ROUTINE sbc_rnf_init  *** 
     
    244243      !! ** Action  : - read parameters 
    245244      !!---------------------------------------------------------------------- 
     245      INTEGER, INTENT(in) :: Kmm           ! ocean time level index 
    246246      CHARACTER(len=32) ::   rn_dep_file   ! runoff file name 
    247247      INTEGER           ::   ji, jj, jk, jm    ! dummy loop indices 
     
    275275      !                                   ! ============ 
    276276      ! 
    277       REWIND( numnam_ref ) 
    278277      READ  ( numnam_ref, namsbc_rnf, IOSTAT = ios, ERR = 901) 
    279278901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_rnf in reference namelist' ) 
    280279 
    281       REWIND( numnam_cfg ) 
    282280      READ  ( numnam_cfg, namsbc_rnf, IOSTAT = ios, ERR = 902 ) 
    283281902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_rnf in configuration namelist' ) 
     
    362360         ! 
    363361         nk_rnf(:,:) = 0                               ! set the number of level over which river runoffs are applied 
    364          DO jj = 1, jpj 
    365             DO ji = 1, jpi 
    366                IF( h_rnf(ji,jj) > 0._wp ) THEN 
    367                   jk = 2 
    368                   DO WHILE ( jk < mbkt(ji,jj) .AND. gdept_0(ji,jj,jk) < h_rnf(ji,jj) ) ;  jk = jk + 1 
    369                   END DO 
    370                   nk_rnf(ji,jj) = jk 
    371                ELSEIF( h_rnf(ji,jj) == -1._wp   ) THEN   ;  nk_rnf(ji,jj) = 1 
    372                ELSEIF( h_rnf(ji,jj) == -999._wp ) THEN   ;  nk_rnf(ji,jj) = mbkt(ji,jj) 
    373                ELSE 
    374                   CALL ctl_stop( 'sbc_rnf_init: runoff depth not positive, and not -999 or -1, rnf value in file fort.999'  ) 
    375                   WRITE(999,*) 'ji, jj, h_rnf(ji,jj) :', ji, jj, h_rnf(ji,jj) 
    376                ENDIF 
     362         DO_2D_11_11 
     363            IF( h_rnf(ji,jj) > 0._wp ) THEN 
     364               jk = 2 
     365               DO WHILE ( jk < mbkt(ji,jj) .AND. gdept_0(ji,jj,jk) < h_rnf(ji,jj) ) ;  jk = jk + 1 
     366               END DO 
     367               nk_rnf(ji,jj) = jk 
     368            ELSEIF( h_rnf(ji,jj) == -1._wp   ) THEN   ;  nk_rnf(ji,jj) = 1 
     369            ELSEIF( h_rnf(ji,jj) == -999._wp ) THEN   ;  nk_rnf(ji,jj) = mbkt(ji,jj) 
     370            ELSE 
     371               CALL ctl_stop( 'sbc_rnf_init: runoff depth not positive, and not -999 or -1, rnf value in file fort.999'  ) 
     372               WRITE(999,*) 'ji, jj, h_rnf(ji,jj) :', ji, jj, h_rnf(ji,jj) 
     373            ENDIF 
     374         END_2D 
     375         DO_2D_11_11 
     376            h_rnf(ji,jj) = 0._wp 
     377            DO jk = 1, nk_rnf(ji,jj) 
     378               h_rnf(ji,jj) = h_rnf(ji,jj) + e3t(ji,jj,jk,Kmm) 
    377379            END DO 
    378          END DO 
    379          DO jj = 1, jpj                                ! set the associated depth 
    380             DO ji = 1, jpi 
    381                h_rnf(ji,jj) = 0._wp 
    382                DO jk = 1, nk_rnf(ji,jj) 
    383                   h_rnf(ji,jj) = h_rnf(ji,jj) + e3t_n(ji,jj,jk) 
    384                END DO 
    385             END DO 
    386          END DO 
     380         END_2D 
    387381         ! 
    388382      ELSE IF( ln_rnf_depth_ini ) THEN           ! runoffs applied at the surface 
     
    409403         WHERE( zrnfcl(:,:,1) > 0._wp )  h_rnf(:,:) = zacoef * zrnfcl(:,:,1)   ! compute depth for all runoffs 
    410404         ! 
    411          DO jj = 1, jpj                     ! take in account min depth of ocean rn_hmin 
    412             DO ji = 1, jpi 
    413                IF( zrnfcl(ji,jj,1) > 0._wp ) THEN 
    414                   jk = mbkt(ji,jj) 
    415                   h_rnf(ji,jj) = MIN( h_rnf(ji,jj), gdept_0(ji,jj,jk ) ) 
    416                ENDIF 
     405         DO_2D_11_11 
     406            IF( zrnfcl(ji,jj,1) > 0._wp ) THEN 
     407               jk = mbkt(ji,jj) 
     408               h_rnf(ji,jj) = MIN( h_rnf(ji,jj), gdept_0(ji,jj,jk ) ) 
     409            ENDIF 
     410         END_2D 
     411         ! 
     412         nk_rnf(:,:) = 0                       ! number of levels on which runoffs are distributed 
     413         DO_2D_11_11 
     414            IF( zrnfcl(ji,jj,1) > 0._wp ) THEN 
     415               jk = 2 
     416               DO WHILE ( jk < mbkt(ji,jj) .AND. gdept_0(ji,jj,jk) < h_rnf(ji,jj) ) ;  jk = jk + 1 
     417               END DO 
     418               nk_rnf(ji,jj) = jk 
     419            ELSE 
     420               nk_rnf(ji,jj) = 1 
     421            ENDIF 
     422         END_2D 
     423         ! 
     424         DO_2D_11_11 
     425            h_rnf(ji,jj) = 0._wp 
     426            DO jk = 1, nk_rnf(ji,jj) 
     427               h_rnf(ji,jj) = h_rnf(ji,jj) + e3t(ji,jj,jk,Kmm) 
    417428            END DO 
    418          END DO 
    419          ! 
    420          nk_rnf(:,:) = 0                       ! number of levels on which runoffs are distributed 
    421          DO jj = 1, jpj 
    422             DO ji = 1, jpi 
    423                IF( zrnfcl(ji,jj,1) > 0._wp ) THEN 
    424                   jk = 2 
    425                   DO WHILE ( jk < mbkt(ji,jj) .AND. gdept_0(ji,jj,jk) < h_rnf(ji,jj) ) ;  jk = jk + 1 
    426                   END DO 
    427                   nk_rnf(ji,jj) = jk 
    428                ELSE 
    429                   nk_rnf(ji,jj) = 1 
    430                ENDIF 
    431             END DO 
    432          END DO 
    433          ! 
    434          DO jj = 1, jpj                                ! set the associated depth 
    435             DO ji = 1, jpi 
    436                h_rnf(ji,jj) = 0._wp 
    437                DO jk = 1, nk_rnf(ji,jj) 
    438                   h_rnf(ji,jj) = h_rnf(ji,jj) + e3t_n(ji,jj,jk) 
    439                END DO 
    440             END DO 
    441          END DO 
     429         END_2D 
    442430         ! 
    443431         IF( nn_rnf_depth_file == 1 ) THEN      !  save  output nb levels for runoff 
     
    449437      ELSE                                       ! runoffs applied at the surface 
    450438         nk_rnf(:,:) = 1 
    451          h_rnf (:,:) = e3t_n(:,:,1) 
     439         h_rnf (:,:) = e3t(:,:,1,Kmm) 
    452440      ENDIF 
    453441      ! 
  • NEMO/trunk/src/OCE/SBC/sbcssm.F90

    r10425 r12377  
    3939CONTAINS 
    4040 
    41    SUBROUTINE sbc_ssm( kt ) 
     41   SUBROUTINE sbc_ssm( kt, Kbb, Kmm ) 
    4242      !!--------------------------------------------------------------------- 
    4343      !!                     ***  ROUTINE sbc_oce  *** 
     
    5353      !!--------------------------------------------------------------------- 
    5454      INTEGER, INTENT(in) ::   kt   ! ocean time step 
     55      INTEGER, INTENT(in) ::   Kbb, Kmm   ! ocean time level indices 
    5556      ! 
    5657      INTEGER  ::   ji, jj               ! loop index 
     
    6061      ! 
    6162      !                                        !* surface T-, U-, V- ocean level variables (T, S, depth, velocity) 
    62       DO jj = 1, jpj 
    63          DO ji = 1, jpi 
    64             zts(ji,jj,jp_tem) = tsn(ji,jj,mikt(ji,jj),jp_tem) 
    65             zts(ji,jj,jp_sal) = tsn(ji,jj,mikt(ji,jj),jp_sal) 
    66          END DO 
    67       END DO 
     63      zts(:,:,jp_tem) = ts(:,:,1,jp_tem,Kmm) 
     64      zts(:,:,jp_sal) = ts(:,:,1,jp_sal,Kmm) 
    6865      ! 
    6966      IF( nn_fsbc == 1 ) THEN                             !   Instantaneous surface fields        ! 
    7067         !                                                ! ---------------------------------------- ! 
    71          ssu_m(:,:) = ub(:,:,1) 
    72          ssv_m(:,:) = vb(:,:,1) 
     68         ssu_m(:,:) = uu(:,:,1,Kbb) 
     69         ssv_m(:,:) = vv(:,:,1,Kbb) 
    7370         IF( l_useCT )  THEN    ;   sst_m(:,:) = eos_pt_from_ct( zts(:,:,jp_tem), zts(:,:,jp_sal) ) 
    74          ELSE                    ;   sst_m(:,:) = zts(:,:,jp_tem) 
     71         ELSE                   ;   sst_m(:,:) = zts(:,:,jp_tem) 
    7572         ENDIF 
    7673         sss_m(:,:) = zts(:,:,jp_sal) 
    7774         !                          ! removed inverse barometer ssh when Patm forcing is used (for sea-ice dynamics) 
    78          IF( ln_apr_dyn ) THEN   ;   ssh_m(:,:) = sshn(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 
    79          ELSE                    ;   ssh_m(:,:) = sshn(:,:) 
    80          ENDIF 
    81          ! 
    82          e3t_m(:,:) = e3t_n(:,:,1) 
     75         IF( ln_apr_dyn ) THEN   ;   ssh_m(:,:) = ssh(:,:,Kmm) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 
     76         ELSE                    ;   ssh_m(:,:) = ssh(:,:,Kmm) 
     77         ENDIF 
     78         ! 
     79         e3t_m(:,:) = e3t(:,:,1,Kmm) 
    8380         ! 
    8481         frq_m(:,:) = fraqsr_1lev(:,:) 
     
    9289            IF(lwp) WRITE(numout,*) '~~~~~~~   ' 
    9390            zcoef = REAL( nn_fsbc - 1, wp ) 
    94             ssu_m(:,:) = zcoef * ub(:,:,1) 
    95             ssv_m(:,:) = zcoef * vb(:,:,1) 
     91            ssu_m(:,:) = zcoef * uu(:,:,1,Kbb) 
     92            ssv_m(:,:) = zcoef * vv(:,:,1,Kbb) 
    9693            IF( l_useCT )  THEN    ;   sst_m(:,:) = zcoef * eos_pt_from_ct( zts(:,:,jp_tem), zts(:,:,jp_sal) ) 
    9794            ELSE                    ;   sst_m(:,:) = zcoef * zts(:,:,jp_tem) 
     
    9996            sss_m(:,:) = zcoef * zts(:,:,jp_sal) 
    10097            !                          ! removed inverse barometer ssh when Patm forcing is used (for sea-ice dynamics) 
    101             IF( ln_apr_dyn ) THEN   ;   ssh_m(:,:) = zcoef * ( sshn(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) ) 
    102             ELSE                    ;   ssh_m(:,:) = zcoef * sshn(:,:) 
    103             ENDIF 
    104             ! 
    105             e3t_m(:,:) = zcoef * e3t_n(:,:,1) 
     98            IF( ln_apr_dyn ) THEN   ;   ssh_m(:,:) = zcoef * ( ssh(:,:,Kmm) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) ) 
     99            ELSE                    ;   ssh_m(:,:) = zcoef *   ssh(:,:,Kmm) 
     100            ENDIF 
     101            ! 
     102            e3t_m(:,:) = zcoef * e3t(:,:,1,Kmm) 
    106103            ! 
    107104            frq_m(:,:) = zcoef * fraqsr_1lev(:,:) 
     
    120117         !                                                !        Cumulate at each time step        ! 
    121118         !                                                ! ---------------------------------------- ! 
    122          ssu_m(:,:) = ssu_m(:,:) + ub(:,:,1) 
    123          ssv_m(:,:) = ssv_m(:,:) + vb(:,:,1) 
     119         ssu_m(:,:) = ssu_m(:,:) + uu(:,:,1,Kbb) 
     120         ssv_m(:,:) = ssv_m(:,:) + vv(:,:,1,Kbb) 
    124121         IF( l_useCT )  THEN     ;   sst_m(:,:) = sst_m(:,:) + eos_pt_from_ct( zts(:,:,jp_tem), zts(:,:,jp_sal) ) 
    125122         ELSE                    ;   sst_m(:,:) = sst_m(:,:) + zts(:,:,jp_tem) 
     
    127124         sss_m(:,:) = sss_m(:,:) + zts(:,:,jp_sal) 
    128125         !                          ! removed inverse barometer ssh when Patm forcing is used (for sea-ice dynamics) 
    129          IF( ln_apr_dyn ) THEN   ;   ssh_m(:,:) = ssh_m(:,:) + sshn(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 
    130          ELSE                    ;   ssh_m(:,:) = ssh_m(:,:) + sshn(:,:) 
    131          ENDIF 
    132          ! 
    133          e3t_m(:,:) = e3t_m(:,:) + e3t_n(:,:,1) 
     126         IF( ln_apr_dyn ) THEN   ;   ssh_m(:,:) = ssh_m(:,:) + ssh(:,:,Kmm) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 
     127         ELSE                    ;   ssh_m(:,:) = ssh_m(:,:) + ssh(:,:,Kmm) 
     128         ENDIF 
     129         ! 
     130         e3t_m(:,:) = e3t_m(:,:) + e3t(:,:,1,Kmm) 
    134131         ! 
    135132         frq_m(:,:) = frq_m(:,:) + fraqsr_1lev(:,:) 
     
    184181 
    185182 
    186    SUBROUTINE sbc_ssm_init 
     183   SUBROUTINE sbc_ssm_init( Kbb, Kmm ) 
    187184      !!---------------------------------------------------------------------- 
    188185      !!                  ***  ROUTINE sbc_ssm_init  *** 
     
    192189      !! ** Action  : - read parameters 
    193190      !!---------------------------------------------------------------------- 
     191      INTEGER, INTENT(in) ::   Kbb, Kmm   ! ocean time level indices 
    194192      REAL(wp) ::   zcoef, zf_sbc   ! local scalar 
    195193      !!---------------------------------------------------------------------- 
     
    242240         ! 
    243241         IF(lwp) WRITE(numout,*) '   default initialisation of ss._m arrays' 
    244          ssu_m(:,:) = ub(:,:,1) 
    245          ssv_m(:,:) = vb(:,:,1) 
    246          IF( l_useCT )  THEN    ;   sst_m(:,:) = eos_pt_from_ct( tsn(:,:,1,jp_tem), tsn(:,:,1,jp_sal) ) 
    247          ELSE                   ;   sst_m(:,:) = tsn(:,:,1,jp_tem) 
    248          ENDIF 
    249          sss_m(:,:) = tsn  (:,:,1,jp_sal) 
    250          ssh_m(:,:) = sshn (:,:) 
    251          e3t_m(:,:) = e3t_n(:,:,1) 
     242         ssu_m(:,:) = uu(:,:,1,Kbb) 
     243         ssv_m(:,:) = vv(:,:,1,Kbb) 
     244         IF( l_useCT )  THEN    ;   sst_m(:,:) = eos_pt_from_ct( ts(:,:,1,jp_tem,Kmm), ts(:,:,1,jp_sal,Kmm) ) 
     245         ELSE                   ;   sst_m(:,:) = ts(:,:,1,jp_tem,Kmm) 
     246         ENDIF 
     247         sss_m(:,:) = ts  (:,:,1,jp_sal,Kmm) 
     248         ssh_m(:,:) = ssh(:,:,Kmm) 
     249         e3t_m(:,:) = e3t (:,:,1,Kmm) 
    252250         frq_m(:,:) = 1._wp 
    253251         ! 
  • NEMO/trunk/src/OCE/SBC/sbcssr.F90

    r12276 r12377  
    4949   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_sss   ! structure of input SSS (file informations, fields read) 
    5050 
     51   !! * Substitutions 
     52#  include "do_loop_substitute.h90" 
    5153   !!---------------------------------------------------------------------- 
    5254   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    9395            ! 
    9496            IF( nn_sstr == 1 ) THEN                                   !* Temperature restoring term 
    95                DO jj = 1, jpj 
    96                   DO ji = 1, jpi 
    97                      zqrp = rn_dqdt * ( sst_m(ji,jj) - sf_sst(1)%fnow(ji,jj,1) ) * tmask(ji,jj,1) 
    98                      qns(ji,jj) = qns(ji,jj) + zqrp 
    99                      qrp(ji,jj) = zqrp 
    100                   END DO 
    101                END DO 
     97               DO_2D_11_11 
     98                  zqrp = rn_dqdt * ( sst_m(ji,jj) - sf_sst(1)%fnow(ji,jj,1) ) * tmask(ji,jj,1) 
     99                  qns(ji,jj) = qns(ji,jj) + zqrp 
     100                  qrp(ji,jj) = zqrp 
     101               END_2D 
    102102            ENDIF 
    103103            ! 
     
    105105              ! use fraction of ice ( fr_i ) to adjust relaxation under ice if nn_sssr_ice .ne. 1 
    106106              ! n.b. coefice is initialised and fixed to 1._wp if nn_sssr_ice = 1 
    107                DO jj = 1, jpj 
    108                   DO ji = 1, jpi 
    109                      SELECT CASE ( nn_sssr_ice ) 
    110                        CASE ( 0 )    ;  coefice(ji,jj) = 1._wp - fr_i(ji,jj)              ! no/reduced damping under ice 
    111                        CASE  DEFAULT ;  coefice(ji,jj) = 1._wp + ( nn_sssr_ice - 1 ) * fr_i(ji,jj) ! reinforced damping (x nn_sssr_ice) under ice ) 
    112                      END SELECT 
    113                   END DO 
    114                END DO 
     107               DO_2D_11_11 
     108                  SELECT CASE ( nn_sssr_ice ) 
     109                    CASE ( 0 )    ;  coefice(ji,jj) = 1._wp - fr_i(ji,jj)              ! no/reduced damping under ice 
     110                    CASE  DEFAULT ;  coefice(ji,jj) = 1._wp + ( nn_sssr_ice - 1 ) * fr_i(ji,jj) ! reinforced damping (x nn_sssr_ice) under ice ) 
     111                  END SELECT 
     112               END_2D 
    115113            ENDIF 
    116114            ! 
    117115            IF( nn_sssr == 1 ) THEN                                   !* Salinity damping term (salt flux only (sfx)) 
    118116               zsrp = rn_deds / rday                                  ! from [mm/day] to [kg/m2/s] 
    119                DO jj = 1, jpj 
    120                   DO ji = 1, jpi 
    121                      zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) )   &      ! No damping in vicinity of river mouths 
    122                         &        *   coefice(ji,jj)            &      ! Optional control of damping under sea-ice 
    123                         &        * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj,1) ) * tmask(ji,jj,1) 
    124                      sfx(ji,jj) = sfx(ji,jj) + zerp                 ! salt flux 
    125                      erp(ji,jj) = zerp / MAX( sss_m(ji,jj), 1.e-20 ) ! converted into an equivalent volume flux (diagnostic only) 
    126                   END DO 
    127                END DO 
     117               DO_2D_11_11 
     118                  zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) )   &      ! No damping in vicinity of river mouths 
     119                     &        *   coefice(ji,jj)            &      ! Optional control of damping under sea-ice 
     120                     &        * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj,1) ) * tmask(ji,jj,1) 
     121                  sfx(ji,jj) = sfx(ji,jj) + zerp                 ! salt flux 
     122                  erp(ji,jj) = zerp / MAX( sss_m(ji,jj), 1.e-20 ) ! converted into an equivalent volume flux (diagnostic only) 
     123               END_2D 
    128124               ! 
    129125            ELSEIF( nn_sssr == 2 ) THEN                               !* Salinity damping term (volume flux (emp) and associated heat flux (qns) 
    130126               zsrp = rn_deds / rday                                  ! from [mm/day] to [kg/m2/s] 
    131127               zerp_bnd = rn_sssr_bnd / rday                          !       -              -     
    132                DO jj = 1, jpj 
    133                   DO ji = 1, jpi                             
    134                      zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) )   &      ! No damping in vicinity of river mouths 
    135                         &        *   coefice(ji,jj)            &      ! Optional control of damping under sea-ice 
    136                         &        * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj,1) )   & 
    137                         &        / MAX(  sss_m(ji,jj), 1.e-20   ) * tmask(ji,jj,1) 
    138                      IF( ln_sssr_bnd )   zerp = SIGN( 1., zerp ) * MIN( zerp_bnd, ABS(zerp) ) 
    139                      emp(ji,jj) = emp (ji,jj) + zerp 
    140                      qns(ji,jj) = qns(ji,jj) - zerp * rcp * sst_m(ji,jj) 
    141                      erp(ji,jj) = zerp 
    142                   END DO 
    143                END DO 
     128               DO_2D_11_11 
     129                  zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) )   &      ! No damping in vicinity of river mouths 
     130                     &        *   coefice(ji,jj)            &      ! Optional control of damping under sea-ice 
     131                     &        * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj,1) )   & 
     132                     &        / MAX(  sss_m(ji,jj), 1.e-20   ) * tmask(ji,jj,1) 
     133                  IF( ln_sssr_bnd )   zerp = SIGN( 1., zerp ) * MIN( zerp_bnd, ABS(zerp) ) 
     134                  emp(ji,jj) = emp (ji,jj) + zerp 
     135                  qns(ji,jj) = qns(ji,jj) - zerp * rcp * sst_m(ji,jj) 
     136                  erp(ji,jj) = zerp 
     137               END_2D 
    144138            ENDIF 
    145139            ! 
     
    180174      ENDIF 
    181175      !  
    182       REWIND( numnam_ref )              ! Namelist namsbc_ssr in reference namelist :  
    183176      READ  ( numnam_ref, namsbc_ssr, IOSTAT = ios, ERR = 901) 
    184177901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_ssr in reference namelist' ) 
    185178 
    186       REWIND( numnam_cfg )              ! Namelist namsbc_ssr in configuration namelist : 
    187179      READ  ( numnam_cfg, namsbc_ssr, IOSTAT = ios, ERR = 902 ) 
    188180902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_ssr in configuration namelist' ) 
  • NEMO/trunk/src/OCE/SBC/sbcwave.F90

    r11536 r12377  
    7272 
    7373   !! * Substitutions 
    74 #  include "vectopt_loop_substitute.h90" 
     74#  include "do_loop_substitute.h90" 
    7575   !!---------------------------------------------------------------------- 
    7676   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    8080CONTAINS 
    8181 
    82    SUBROUTINE sbc_stokes( ) 
     82   SUBROUTINE sbc_stokes( Kmm ) 
    8383      !!--------------------------------------------------------------------- 
    8484      !!                     ***  ROUTINE sbc_stokes  *** 
     
    9292      !! ** action   
    9393      !!--------------------------------------------------------------------- 
     94      INTEGER, INTENT(in) :: Kmm ! ocean time level index 
    9495      INTEGER  ::   jj, ji, jk   ! dummy loop argument 
    9596      INTEGER  ::   ik           ! local integer  
     
    111112      IF( ll_st_bv_li ) THEN   ! (Eq. (19) in Breivik et al. (2014) ) 
    112113         zfac = 2.0_wp * rpi / 16.0_wp 
    113          DO jj = 1, jpj 
    114             DO ji = 1, jpi 
    115                ! Stokes drift velocity estimated from Hs and Tmean 
    116                ztransp = zfac * hsw(ji,jj)*hsw(ji,jj) / MAX( wmp(ji,jj), 0.0000001_wp ) 
    117                ! Stokes surface speed 
    118                tsd2d(ji,jj) = SQRT( ut0sd(ji,jj)*ut0sd(ji,jj) + vt0sd(ji,jj)*vt0sd(ji,jj)) 
    119                ! Wavenumber scale 
    120                zk_t(ji,jj) = ABS( tsd2d(ji,jj) ) / MAX( ABS( 5.97_wp*ztransp ), 0.0000001_wp ) 
    121             END DO 
    122          END DO 
    123          DO jj = 1, jpjm1              ! exp. wave number & Stokes drift velocity at u- & v-points 
    124             DO ji = 1, jpim1 
    125                zk_u(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji+1,jj) ) 
    126                zk_v(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji,jj+1) ) 
    127                ! 
    128                zu0_sd(ji,jj) = 0.5_wp * ( ut0sd(ji,jj) + ut0sd(ji+1,jj) ) 
    129                zv0_sd(ji,jj) = 0.5_wp * ( vt0sd(ji,jj) + vt0sd(ji,jj+1) ) 
    130             END DO 
    131          END DO 
     114         DO_2D_11_11 
     115            ! Stokes drift velocity estimated from Hs and Tmean 
     116            ztransp = zfac * hsw(ji,jj)*hsw(ji,jj) / MAX( wmp(ji,jj), 0.0000001_wp ) 
     117            ! Stokes surface speed 
     118            tsd2d(ji,jj) = SQRT( ut0sd(ji,jj)*ut0sd(ji,jj) + vt0sd(ji,jj)*vt0sd(ji,jj)) 
     119            ! Wavenumber scale 
     120            zk_t(ji,jj) = ABS( tsd2d(ji,jj) ) / MAX( ABS( 5.97_wp*ztransp ), 0.0000001_wp ) 
     121         END_2D 
     122         DO_2D_10_10 
     123            zk_u(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji+1,jj) ) 
     124            zk_v(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji,jj+1) ) 
     125            ! 
     126            zu0_sd(ji,jj) = 0.5_wp * ( ut0sd(ji,jj) + ut0sd(ji+1,jj) ) 
     127            zv0_sd(ji,jj) = 0.5_wp * ( vt0sd(ji,jj) + vt0sd(ji,jj+1) ) 
     128         END_2D 
    132129      ELSE IF( ll_st_peakfr ) THEN    ! peak wave number calculated from the peak frequency received by the wave model 
    133          DO jj = 1, jpj 
    134             DO ji = 1, jpi 
    135                zk_t(ji,jj) = ( 2.0_wp * rpi * wfreq(ji,jj) ) * ( 2.0_wp * rpi * wfreq(ji,jj) ) / grav 
    136             END DO 
    137          END DO 
    138          DO jj = 1, jpjm1 
    139             DO ji = 1, jpim1 
    140                zk_u(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji+1,jj) ) 
    141                zk_v(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji,jj+1) ) 
    142                ! 
    143                zu0_sd(ji,jj) = 0.5_wp * ( ut0sd(ji,jj) + ut0sd(ji+1,jj) ) 
    144                zv0_sd(ji,jj) = 0.5_wp * ( vt0sd(ji,jj) + vt0sd(ji,jj+1) ) 
    145             END DO 
    146          END DO 
     130         DO_2D_11_11 
     131            zk_t(ji,jj) = ( 2.0_wp * rpi * wfreq(ji,jj) ) * ( 2.0_wp * rpi * wfreq(ji,jj) ) / grav 
     132         END_2D 
     133         DO_2D_10_10 
     134            zk_u(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji+1,jj) ) 
     135            zk_v(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji,jj+1) ) 
     136            ! 
     137            zu0_sd(ji,jj) = 0.5_wp * ( ut0sd(ji,jj) + ut0sd(ji+1,jj) ) 
     138            zv0_sd(ji,jj) = 0.5_wp * ( vt0sd(ji,jj) + vt0sd(ji,jj+1) ) 
     139         END_2D 
    147140      ENDIF 
    148141      ! 
    149142      !                       !==  horizontal Stokes Drift 3D velocity  ==! 
    150143      IF( ll_st_bv2014 ) THEN 
    151          DO jk = 1, jpkm1 
    152             DO jj = 2, jpjm1 
    153                DO ji = 2, jpim1 
    154                   zdep_u = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji+1,jj,jk) ) 
    155                   zdep_v = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji,jj+1,jk) ) 
    156                   !                           
    157                   zkh_u = zk_u(ji,jj) * zdep_u     ! k * depth 
    158                   zkh_v = zk_v(ji,jj) * zdep_v 
    159                   !                                ! Depth attenuation 
    160                   zda_u = EXP( -2.0_wp*zkh_u ) / ( 1.0_wp + 8.0_wp*zkh_u ) 
    161                   zda_v = EXP( -2.0_wp*zkh_v ) / ( 1.0_wp + 8.0_wp*zkh_v ) 
    162                   ! 
    163                   usd(ji,jj,jk) = zda_u * zu0_sd(ji,jj) * umask(ji,jj,jk) 
    164                   vsd(ji,jj,jk) = zda_v * zv0_sd(ji,jj) * vmask(ji,jj,jk) 
    165                END DO 
    166             END DO 
    167          END DO 
     144         DO_3D_00_00( 1, jpkm1 ) 
     145            zdep_u = 0.5_wp * ( gdept(ji,jj,jk,Kmm) + gdept(ji+1,jj,jk,Kmm) ) 
     146            zdep_v = 0.5_wp * ( gdept(ji,jj,jk,Kmm) + gdept(ji,jj+1,jk,Kmm) ) 
     147            !                           
     148            zkh_u = zk_u(ji,jj) * zdep_u     ! k * depth 
     149            zkh_v = zk_v(ji,jj) * zdep_v 
     150            !                                ! Depth attenuation 
     151            zda_u = EXP( -2.0_wp*zkh_u ) / ( 1.0_wp + 8.0_wp*zkh_u ) 
     152            zda_v = EXP( -2.0_wp*zkh_v ) / ( 1.0_wp + 8.0_wp*zkh_v ) 
     153            ! 
     154            usd(ji,jj,jk) = zda_u * zu0_sd(ji,jj) * umask(ji,jj,jk) 
     155            vsd(ji,jj,jk) = zda_v * zv0_sd(ji,jj) * vmask(ji,jj,jk) 
     156         END_3D 
    168157      ELSE IF( ll_st_li2017 .OR. ll_st_peakfr ) THEN 
    169158         ALLOCATE( zstokes_psi_u_top(jpi,jpj), zstokes_psi_v_top(jpi,jpj) ) 
    170          DO jj = 1, jpjm1              ! exp. wave number & Stokes drift velocity at u- & v-points 
    171             DO ji = 1, jpim1 
    172                zstokes_psi_u_top(ji,jj) = 0._wp 
    173                zstokes_psi_v_top(ji,jj) = 0._wp 
    174             END DO 
    175          END DO 
     159         DO_2D_10_10 
     160            zstokes_psi_u_top(ji,jj) = 0._wp 
     161            zstokes_psi_v_top(ji,jj) = 0._wp 
     162         END_2D 
    176163         zsqrtpi = SQRT(rpi) 
    177164         z_two_thirds = 2.0_wp / 3.0_wp 
    178          DO jk = 1, jpkm1 
    179             DO jj = 2, jpjm1 
    180                DO ji = 2, jpim1 
    181                   zbot_u = ( gdepw_n(ji,jj,jk+1) + gdepw_n(ji+1,jj,jk+1) )  ! 2 * bottom depth 
    182                   zbot_v = ( gdepw_n(ji,jj,jk+1) + gdepw_n(ji,jj+1,jk+1) )  ! 2 * bottom depth 
    183                   zkb_u  = zk_u(ji,jj) * zbot_u                             ! 2 * k * bottom depth 
    184                   zkb_v  = zk_v(ji,jj) * zbot_v                             ! 2 * k * bottom depth 
    185                   ! 
    186                   zke3_u = MAX(1.e-8_wp, 2.0_wp * zk_u(ji,jj) * e3u_n(ji,jj,jk))     ! 2k * thickness 
    187                   zke3_v = MAX(1.e-8_wp, 2.0_wp * zk_v(ji,jj) * e3v_n(ji,jj,jk))     ! 2k * thickness 
    188  
    189                   ! Depth attenuation .... do u component first.. 
    190                   zdepth      = zkb_u 
    191                   zsqrt_depth = SQRT(zdepth) 
    192                   zexp_depth  = EXP(-zdepth) 
    193                   zstokes_psi_u_bot = 1.0_wp - zexp_depth  & 
    194                        &              - z_two_thirds * ( zsqrtpi*zsqrt_depth*zdepth*ERFC(zsqrt_depth) & 
    195                        &              + 1.0_wp - (1.0_wp + zdepth)*zexp_depth ) 
    196                   zda_u                    = ( zstokes_psi_u_bot - zstokes_psi_u_top(ji,jj) ) / zke3_u 
    197                   zstokes_psi_u_top(ji,jj) =   zstokes_psi_u_bot 
    198  
    199                   !         ... and then v component 
    200                   zdepth      =zkb_v 
    201                   zsqrt_depth = SQRT(zdepth) 
    202                   zexp_depth  = EXP(-zdepth) 
    203                   zstokes_psi_v_bot = 1.0_wp - zexp_depth  & 
    204                        &              - z_two_thirds * ( zsqrtpi*zsqrt_depth*zdepth*ERFC(zsqrt_depth) & 
    205                        &              + 1.0_wp - (1.0_wp + zdepth)*zexp_depth ) 
    206                   zda_v                    = ( zstokes_psi_v_bot - zstokes_psi_v_top(ji,jj) ) / zke3_v 
    207                   zstokes_psi_v_top(ji,jj) =   zstokes_psi_v_bot 
    208                   ! 
    209                   usd(ji,jj,jk) = zda_u * zu0_sd(ji,jj) * umask(ji,jj,jk) 
    210                   vsd(ji,jj,jk) = zda_v * zv0_sd(ji,jj) * vmask(ji,jj,jk) 
    211                END DO 
    212             END DO 
    213          END DO 
     165         DO_3D_00_00( 1, jpkm1 ) 
     166            zbot_u = ( gdepw(ji,jj,jk+1,Kmm) + gdepw(ji+1,jj,jk+1,Kmm) )  ! 2 * bottom depth 
     167            zbot_v = ( gdepw(ji,jj,jk+1,Kmm) + gdepw(ji,jj+1,jk+1,Kmm) )  ! 2 * bottom depth 
     168            zkb_u  = zk_u(ji,jj) * zbot_u                             ! 2 * k * bottom depth 
     169            zkb_v  = zk_v(ji,jj) * zbot_v                             ! 2 * k * bottom depth 
     170            ! 
     171            zke3_u = MAX(1.e-8_wp, 2.0_wp * zk_u(ji,jj) * e3u(ji,jj,jk,Kmm))     ! 2k * thickness 
     172            zke3_v = MAX(1.e-8_wp, 2.0_wp * zk_v(ji,jj) * e3v(ji,jj,jk,Kmm))     ! 2k * thickness 
     173 
     174            ! Depth attenuation .... do u component first.. 
     175            zdepth      = zkb_u 
     176            zsqrt_depth = SQRT(zdepth) 
     177            zexp_depth  = EXP(-zdepth) 
     178            zstokes_psi_u_bot = 1.0_wp - zexp_depth  & 
     179                 &              - z_two_thirds * ( zsqrtpi*zsqrt_depth*zdepth*ERFC(zsqrt_depth) & 
     180                 &              + 1.0_wp - (1.0_wp + zdepth)*zexp_depth ) 
     181            zda_u                    = ( zstokes_psi_u_bot - zstokes_psi_u_top(ji,jj) ) / zke3_u 
     182            zstokes_psi_u_top(ji,jj) =   zstokes_psi_u_bot 
     183 
     184            !         ... and then v component 
     185            zdepth      =zkb_v 
     186            zsqrt_depth = SQRT(zdepth) 
     187            zexp_depth  = EXP(-zdepth) 
     188            zstokes_psi_v_bot = 1.0_wp - zexp_depth  & 
     189                 &              - z_two_thirds * ( zsqrtpi*zsqrt_depth*zdepth*ERFC(zsqrt_depth) & 
     190                 &              + 1.0_wp - (1.0_wp + zdepth)*zexp_depth ) 
     191            zda_v                    = ( zstokes_psi_v_bot - zstokes_psi_v_top(ji,jj) ) / zke3_v 
     192            zstokes_psi_v_top(ji,jj) =   zstokes_psi_v_bot 
     193            ! 
     194            usd(ji,jj,jk) = zda_u * zu0_sd(ji,jj) * umask(ji,jj,jk) 
     195            vsd(ji,jj,jk) = zda_v * zv0_sd(ji,jj) * vmask(ji,jj,jk) 
     196         END_3D 
    214197         DEALLOCATE( zstokes_psi_u_top, zstokes_psi_v_top ) 
    215198      ENDIF 
     
    220203      !                       !==  vertical Stokes Drift 3D velocity  ==! 
    221204      ! 
    222       DO jk = 1, jpkm1               ! Horizontal e3*divergence 
    223          DO jj = 2, jpj 
    224             DO ji = fs_2, jpi 
    225                ze3divh(ji,jj,jk) = (  e2u(ji  ,jj) * e3u_n(ji  ,jj,jk) * usd(ji  ,jj,jk)    & 
    226                   &                 - e2u(ji-1,jj) * e3u_n(ji-1,jj,jk) * usd(ji-1,jj,jk)    & 
    227                   &                 + e1v(ji,jj  ) * e3v_n(ji,jj  ,jk) * vsd(ji,jj  ,jk)    & 
    228                   &                 - e1v(ji,jj-1) * e3v_n(ji,jj-1,jk) * vsd(ji,jj-1,jk)  ) * r1_e1e2t(ji,jj) 
    229             END DO 
    230          END DO 
    231       END DO 
     205      DO_3D_01_01( 1, jpkm1 ) 
     206         ze3divh(ji,jj,jk) = (  e2u(ji  ,jj) * e3u(ji  ,jj,jk,Kmm) * usd(ji  ,jj,jk)    & 
     207            &                 - e2u(ji-1,jj) * e3u(ji-1,jj,jk,Kmm) * usd(ji-1,jj,jk)    & 
     208            &                 + e1v(ji,jj  ) * e3v(ji,jj  ,jk,Kmm) * vsd(ji,jj  ,jk)    & 
     209            &                 - e1v(ji,jj-1) * e3v(ji,jj-1,jk,Kmm) * vsd(ji,jj-1,jk)  ) * r1_e1e2t(ji,jj) 
     210      END_3D 
    232211      ! 
    233212#if defined key_agrif 
     
    291270      ! 
    292271      IF( ln_tauw ) THEN 
    293          DO jj = 1, jpjm1 
    294             DO ji = 1, jpim1 
    295                ! Stress components at u- & v-points 
    296                utau(ji,jj) = 0.5_wp * ( tauw_x(ji,jj) + tauw_x(ji+1,jj) ) 
    297                vtau(ji,jj) = 0.5_wp * ( tauw_y(ji,jj) + tauw_y(ji,jj+1) ) 
    298                ! 
    299                ! Stress module at t points 
    300                taum(ji,jj) = SQRT( tauw_x(ji,jj)*tauw_x(ji,jj) + tauw_y(ji,jj)*tauw_y(ji,jj) ) 
    301             END DO 
    302          END DO 
     272         DO_2D_10_10 
     273            ! Stress components at u- & v-points 
     274            utau(ji,jj) = 0.5_wp * ( tauw_x(ji,jj) + tauw_x(ji+1,jj) ) 
     275            vtau(ji,jj) = 0.5_wp * ( tauw_y(ji,jj) + tauw_y(ji,jj+1) ) 
     276            ! 
     277            ! Stress module at t points 
     278            taum(ji,jj) = SQRT( tauw_x(ji,jj)*tauw_x(ji,jj) + tauw_y(ji,jj)*tauw_y(ji,jj) ) 
     279         END_2D 
    303280         CALL lbc_lnk_multi( 'sbcwave', utau(:,:), 'U', -1. , vtau(:,:), 'V', -1. , taum(:,:) , 'T', -1. ) 
    304281      ENDIF 
     
    307284 
    308285 
    309    SUBROUTINE sbc_wave( kt ) 
     286   SUBROUTINE sbc_wave( kt, Kmm ) 
    310287      !!--------------------------------------------------------------------- 
    311288      !!                     ***  ROUTINE sbc_wave  *** 
     
    322299      !!--------------------------------------------------------------------- 
    323300      INTEGER, INTENT(in   ) ::   kt   ! ocean time step 
     301      INTEGER, INTENT(in   ) ::   Kmm  ! ocean time index 
    324302      !!--------------------------------------------------------------------- 
    325303      ! 
     
    361339         ! 
    362340         IF( ( ll_st_bv_li   .AND. jp_hsw>0 .AND. jp_wmp>0 .AND. jp_usd>0 .AND. jp_vsd>0 ) .OR. & 
    363            & ( ll_st_peakfr  .AND. jp_wfr>0 .AND. jp_usd>0 .AND. jp_vsd>0                ) ) CALL sbc_stokes() 
     341           & ( ll_st_peakfr  .AND. jp_wfr>0 .AND. jp_usd>0 .AND. jp_vsd>0                ) ) CALL sbc_stokes( Kmm ) 
    364342         ! 
    365343      ENDIF 
     
    395373      !!--------------------------------------------------------------------- 
    396374      ! 
    397       REWIND( numnam_ref )              ! Namelist namsbc_wave in reference namelist : File for drag coeff. from wave model 
    398375      READ  ( numnam_ref, namsbc_wave, IOSTAT = ios, ERR = 901) 
    399376901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_wave in reference namelist' ) 
    400377          
    401       REWIND( numnam_cfg )              ! Namelist namsbc_wave in configuration namelist : File for drag coeff. from wave model 
    402378      READ  ( numnam_cfg, namsbc_wave, IOSTAT = ios, ERR = 902 ) 
    403379902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_wave in configuration namelist' ) 
Note: See TracChangeset for help on using the changeset viewer.