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.
sbcisf.F90 in NEMO/branches/2019/dev_r10721_KERNEL-02_Storkey_Coward_IMMERSE_first_steps/src/OCE/SBC – NEMO

source: NEMO/branches/2019/dev_r10721_KERNEL-02_Storkey_Coward_IMMERSE_first_steps/src/OCE/SBC/sbcisf.F90 @ 10954

Last change on this file since 10954 was 10954, checked in by acc, 5 years ago

2019/dev_r10721_KERNEL-02_Storkey_Coward_IMMERSE_first_steps : Convert TRA modules and all knock on effects of these conversions. SETTE tested

  • Property svn:keywords set to Id
File size: 46.0 KB
Line 
1MODULE sbcisf
2   !!======================================================================
3   !!                       ***  MODULE  sbcisf  ***
4   !! Surface module :  update surface ocean boundary condition under ice
5   !!                   shelf
6   !!======================================================================
7   !! History :  3.2  !  2011-02  (C.Harris  ) Original code isf cav
8   !!            X.X  !  2006-02  (C. Wang   ) Original code bg03
9   !!            3.4  !  2013-03  (P. Mathiot) Merging + parametrization
10   !!----------------------------------------------------------------------
11
12   !!----------------------------------------------------------------------
13   !!   sbc_isf       : update sbc under ice shelf
14   !!----------------------------------------------------------------------
15   USE oce            ! ocean dynamics and tracers
16   USE dom_oce        ! ocean space and time domain
17   USE phycst         ! physical constants
18   USE eosbn2         ! equation of state
19   USE sbc_oce        ! surface boundary condition: ocean fields
20   USE zdfdrg         ! vertical physics: top/bottom drag coef.
21   !
22   USE in_out_manager ! I/O manager
23   USE iom            ! I/O library
24   USE fldread        ! read input field at current time step
25   USE lbclnk         !
26   USE lib_fortran    ! glob_sum
27
28   IMPLICIT NONE
29   PRIVATE
30
31   PUBLIC   sbc_isf, sbc_isf_init, sbc_isf_div, sbc_isf_alloc  ! routine called in sbcmod and divhor
32
33   ! public in order to be able to output then
34
35   REAL(wp), PUBLIC ::   rn_hisf_tbl                 !: thickness of top boundary layer [m]
36   INTEGER , PUBLIC ::   nn_isf                      !: flag to choose between explicit/param/specified 
37   INTEGER , PUBLIC ::   nn_isfblk                   !: flag to choose the bulk formulation to compute the ice shelf melting
38   INTEGER , PUBLIC ::   nn_gammablk                 !: flag to choose how the exchange coefficient is computed
39   REAL(wp), PUBLIC ::   rn_gammat0                  !: temperature exchange coeficient []
40   REAL(wp), PUBLIC ::   rn_gammas0                  !: salinity    exchange coeficient []
41
42   INTEGER , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   misfkt   , misfkb        !: Level of ice shelf base
43   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   rzisf_tbl                !: depth of calving front (shallowest point) nn_isf ==2/3
44   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   rhisf_tbl, rhisf_tbl_0   !: thickness of tbl  [m]
45   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   r1_hisf_tbl              !: 1/thickness of tbl
46   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ralpha                   !: proportion of bottom cell influenced by tbl
47   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   risfLeff                 !: effective length (Leff) BG03 nn_isf==2
48   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ttbl, stbl, utbl, vtbl   !: top boundary layer variable at T point
49   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   qisf                     !: net heat flux from ice shelf      [W/m2]
50   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   risf_tsc_b, risf_tsc     !: before and now T & S isf contents [K.m/s & PSU.m/s] 
51
52   LOGICAL, PUBLIC ::   l_isfcpl = .false.       !: isf recieved from oasis
53
54   REAL(wp), PUBLIC, SAVE ::   rcpisf   = 2000.0_wp     !: specific heat of ice shelf             [J/kg/K]
55   REAL(wp), PUBLIC, SAVE ::   rkappa   = 1.54e-6_wp    !: heat diffusivity through the ice-shelf [m2/s]
56   REAL(wp), PUBLIC, SAVE ::   rhoisf   = 920.0_wp      !: volumic mass of ice shelf              [kg/m3]
57   REAL(wp), PUBLIC, SAVE ::   tsurf    = -20.0_wp      !: air temperature on top of ice shelf    [C]
58   REAL(wp), PUBLIC, SAVE ::   rLfusisf = 0.334e6_wp    !: latent heat of fusion of ice shelf     [J/kg]
59
60!: Variable used in fldread to read the forcing file (nn_isf == 4 .OR. nn_isf == 3)
61   CHARACTER(len=100), PUBLIC           :: cn_dirisf  = './' !: Root directory for location of ssr files
62   TYPE(FLD_N)       , PUBLIC           :: sn_fwfisf         !: information about the isf melting file to be read
63   TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_fwfisf
64   TYPE(FLD_N)       , PUBLIC           :: sn_rnfisf         !: information about the isf melting param.   file to be read
65   TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_rnfisf           
66   TYPE(FLD_N)       , PUBLIC           :: sn_depmax_isf     !: information about the grounding line depth file to be read
67   TYPE(FLD_N)       , PUBLIC           :: sn_depmin_isf     !: information about the calving   line depth file to be read
68   TYPE(FLD_N)       , PUBLIC           :: sn_Leff_isf       !: information about the effective length     file to be read
69   
70   !!----------------------------------------------------------------------
71   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
72   !! $Id$
73   !! Software governed by the CeCILL license (see ./LICENSE)
74   !!----------------------------------------------------------------------
75CONTAINS
76 
77  SUBROUTINE sbc_isf( kt, Kmm )
78      !!---------------------------------------------------------------------
79      !!                  ***  ROUTINE sbc_isf  ***
80      !!
81      !! ** Purpose : Compute Salt and Heat fluxes related to ice_shelf
82      !!              melting and freezing
83      !!
84      !! ** Method  :  4 parameterizations are available according to nn_isf
85      !!               nn_isf = 1 : Realistic ice_shelf formulation
86      !!                        2 : Beckmann & Goose parameterization
87      !!                        3 : Specified runoff in deptht (Mathiot & al. )
88      !!                        4 : specified fwf and heat flux forcing beneath the ice shelf
89      !!----------------------------------------------------------------------
90      INTEGER, INTENT(in) ::   kt   ! ocean time step
91      INTEGER, INTENT(in) ::   Kmm  ! ocean time level indices
92      !
93      INTEGER ::   ji, jj, jk   ! loop index
94      INTEGER ::   ikt, ikb     ! local integers
95      REAL(wp), DIMENSION(jpi,jpj) ::   zt_frz, zdep   ! freezing temperature (zt_frz) at depth (zdep)
96      REAL(wp), DIMENSION(:,:)  , ALLOCATABLE ::   zqhcisf2d
97      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   zfwfisf3d, zqhcisf3d, zqlatisf3d
98      !!---------------------------------------------------------------------
99      !
100      IF( MOD( kt-1, nn_fsbc) == 0 ) THEN    ! compute salt and heat flux
101         !
102         SELECT CASE ( nn_isf )
103         CASE ( 1 )    ! realistic ice shelf formulation
104            ! compute T/S/U/V for the top boundary layer
105            CALL sbc_isf_tbl(ts(:,:,:,jp_tem,Kmm),ttbl(:,:),'T',Kmm)
106            CALL sbc_isf_tbl(ts(:,:,:,jp_sal,Kmm),stbl(:,:),'T',Kmm)
107            CALL sbc_isf_tbl(uu(:,:,:,Kmm)       ,utbl(:,:),'U',Kmm)
108            CALL sbc_isf_tbl(vv(:,:,:,Kmm)       ,vtbl(:,:),'V',Kmm)
109            ! iom print
110            CALL iom_put('ttbl',ttbl(:,:))
111            CALL iom_put('stbl',stbl(:,:))
112            CALL iom_put('utbl',utbl(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:))
113            CALL iom_put('vtbl',vtbl(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:))
114            ! compute fwf and heat flux
115            ! compute fwf and heat flux
116            IF( .NOT.l_isfcpl ) THEN    ;   CALL sbc_isf_cav (kt, Kmm)
117            ELSE                        ;   qisf(:,:)  = fwfisf(:,:) * rLfusisf  ! heat        flux
118            ENDIF
119            !
120         CASE ( 2 )    ! Beckmann and Goosse parametrisation
121            stbl(:,:)   = soce
122            CALL sbc_isf_bg03(kt, Kmm)
123            !
124         CASE ( 3 )    ! specified runoff in depth (Mathiot et al., XXXX in preparation)
125            ! specified runoff in depth (Mathiot et al., XXXX in preparation)
126            IF( .NOT.l_isfcpl ) THEN
127               CALL fld_read ( kt, nn_fsbc, sf_rnfisf   )
128               fwfisf(:,:) = - sf_rnfisf(1)%fnow(:,:,1)         ! fresh water flux from the isf (fwfisf <0 mean melting)
129            ENDIF
130            qisf(:,:)   = fwfisf(:,:) * rLfusisf             ! heat flux
131            stbl(:,:)   = soce
132            !
133         CASE ( 4 )    ! specified fwf and heat flux forcing beneath the ice shelf
134            !          ! specified fwf and heat flux forcing beneath the ice shelf
135            IF( .NOT.l_isfcpl ) THEN
136               CALL fld_read ( kt, nn_fsbc, sf_fwfisf   )
137               !CALL fld_read ( kt, nn_fsbc, sf_qisf   )
138               fwfisf(:,:) = -sf_fwfisf(1)%fnow(:,:,1)            ! fwf
139            ENDIF
140            qisf(:,:)   = fwfisf(:,:) * rLfusisf               ! heat flux
141            stbl(:,:)   = soce
142            !
143         END SELECT
144
145         ! compute tsc due to isf
146         ! isf melting implemented as a volume flux and we assume that melt water is at 0 PSU.
147         ! WARNING water add at temp = 0C, need to add a correction term (fwfisf * tfreez / rau0).
148         ! compute freezing point beneath ice shelf (or top cell if nn_isf = 3)
149         DO jj = 1,jpj
150            DO ji = 1,jpi
151               zdep(ji,jj)=gdepw_n(ji,jj,misfkt(ji,jj))
152            END DO
153         END DO
154         CALL eos_fzp( stbl(:,:), zt_frz(:,:), zdep(:,:) )
155         
156         risf_tsc(:,:,jp_tem) = qisf(:,:) * r1_rau0_rcp - fwfisf(:,:) * zt_frz(:,:) * r1_rau0 !
157         risf_tsc(:,:,jp_sal) = 0.0_wp
158
159         ! lbclnk
160         CALL lbc_lnk_multi( 'sbcisf', risf_tsc(:,:,jp_tem), 'T', 1., risf_tsc(:,:,jp_sal), 'T', 1., fwfisf,'T', 1., qisf, 'T', 1.)
161         ! output
162         IF( iom_use('iceshelf_cea') )   CALL iom_put( 'iceshelf_cea', -fwfisf(:,:)                      )   ! isf mass flux
163         IF( iom_use('hflx_isf_cea') )   CALL iom_put( 'hflx_isf_cea', risf_tsc(:,:,jp_tem) * rau0 * rcp )   ! isf sensible+latent heat (W/m2)
164         IF( iom_use('qlatisf' ) )       CALL iom_put( 'qlatisf'     , qisf(:,:)                         )   ! isf latent heat
165         IF( iom_use('fwfisf'  ) )       CALL iom_put( 'fwfisf'      , fwfisf(:,:)                       )   ! isf mass flux (opposite sign)
166
167         ! Diagnostics
168         IF( iom_use('fwfisf3d') .OR. iom_use('qlatisf3d') .OR. iom_use('qhcisf3d') .OR. iom_use('qhcisf')) THEN
169            ALLOCATE( zfwfisf3d(jpi,jpj,jpk) , zqhcisf3d(jpi,jpj,jpk) , zqlatisf3d(jpi,jpj,jpk) )
170            ALLOCATE( zqhcisf2d(jpi,jpj) )
171            !
172            zfwfisf3d (:,:,:) = 0._wp                         ! 3d ice shelf melting (kg/m2/s)
173            zqhcisf3d (:,:,:) = 0._wp                         ! 3d heat content flux (W/m2)
174            zqlatisf3d(:,:,:) = 0._wp                         ! 3d ice shelf melting latent heat flux (W/m2)
175            zqhcisf2d (:,:)   = fwfisf(:,:) * zt_frz * rcp    ! 2d heat content flux (W/m2)
176            !
177            DO jj = 1,jpj
178               DO ji = 1,jpi
179                  ikt = misfkt(ji,jj)
180                  ikb = misfkb(ji,jj)
181                  DO jk = ikt, ikb - 1
182                     zfwfisf3d (ji,jj,jk) = zfwfisf3d (ji,jj,jk) + fwfisf   (ji,jj) * r1_hisf_tbl(ji,jj) * e3t(ji,jj,jk,Kmm)
183                     zqhcisf3d (ji,jj,jk) = zqhcisf3d (ji,jj,jk) + zqhcisf2d(ji,jj) * r1_hisf_tbl(ji,jj) * e3t(ji,jj,jk,Kmm)
184                     zqlatisf3d(ji,jj,jk) = zqlatisf3d(ji,jj,jk) + qisf     (ji,jj) * r1_hisf_tbl(ji,jj) * e3t(ji,jj,jk,Kmm)
185                  END DO
186                  zfwfisf3d (ji,jj,jk) = zfwfisf3d (ji,jj,jk) + fwfisf   (ji,jj) * r1_hisf_tbl(ji,jj)   & 
187                     &                                                                   * ralpha(ji,jj) * e3t(ji,jj,jk,Kmm)
188                  zqhcisf3d (ji,jj,jk) = zqhcisf3d (ji,jj,jk) + zqhcisf2d(ji,jj) * r1_hisf_tbl(ji,jj)   & 
189                     &                                                                   * ralpha(ji,jj) * e3t(ji,jj,jk,Kmm)
190                  zqlatisf3d(ji,jj,jk) = zqlatisf3d(ji,jj,jk) + qisf     (ji,jj) * r1_hisf_tbl(ji,jj)   & 
191                     &                                                                   * ralpha(ji,jj) * e3t(ji,jj,jk,Kmm)
192               END DO
193            END DO
194            !
195            CALL iom_put('fwfisf3d' , zfwfisf3d (:,:,:))
196            CALL iom_put('qlatisf3d', zqlatisf3d(:,:,:))
197            CALL iom_put('qhcisf3d' , zqhcisf3d (:,:,:))
198            CALL iom_put('qhcisf'   , zqhcisf2d (:,:  ))
199            !
200            DEALLOCATE( zfwfisf3d, zqhcisf3d, zqlatisf3d )
201            DEALLOCATE( zqhcisf2d )
202         ENDIF
203         !
204      ENDIF
205
206      IF( kt == nit000 ) THEN                         !   set the forcing field at nit000 - 1    !
207         IF( ln_rstart .AND.    &                     ! Restart: read in restart file
208            &   iom_varid( numror, 'fwf_isf_b', ldstop = .FALSE. ) > 0 ) THEN
209            IF(lwp) WRITE(numout,*) '          nit000-1 isf tracer content forcing fields read in the restart file'
210            CALL iom_get( numror, jpdom_autoglo, 'fwf_isf_b', fwfisf_b(:,:)         , ldxios = lrxios )   ! before salt content isf_tsc trend
211            CALL iom_get( numror, jpdom_autoglo, 'isf_sc_b' , risf_tsc_b(:,:,jp_sal), ldxios = lrxios )   ! before salt content isf_tsc trend
212            CALL iom_get( numror, jpdom_autoglo, 'isf_hc_b' , risf_tsc_b(:,:,jp_tem), ldxios = lrxios )   ! before salt content isf_tsc trend
213         ELSE
214            fwfisf_b(:,:)    = fwfisf(:,:)
215            risf_tsc_b(:,:,:)= risf_tsc(:,:,:)
216         ENDIF
217      ENDIF
218      !
219      IF( lrst_oce ) THEN
220         IF(lwp) WRITE(numout,*)
221         IF(lwp) WRITE(numout,*) 'sbc : isf surface tracer content forcing fields written in ocean restart file ',   &
222            &                    'at it= ', kt,' date= ', ndastp
223         IF(lwp) WRITE(numout,*) '~~~~'
224         IF( lwxios ) CALL iom_swap(      cwxios_context          )
225         CALL iom_rstput( kt, nitrst, numrow, 'fwf_isf_b', fwfisf(:,:)         , ldxios = lwxios )
226         CALL iom_rstput( kt, nitrst, numrow, 'isf_hc_b' , risf_tsc(:,:,jp_tem), ldxios = lwxios )
227         CALL iom_rstput( kt, nitrst, numrow, 'isf_sc_b' , risf_tsc(:,:,jp_sal), ldxios = lwxios )
228         IF( lwxios ) CALL iom_swap(      cxios_context          )
229      ENDIF
230      !
231   END SUBROUTINE sbc_isf
232
233
234   INTEGER FUNCTION sbc_isf_alloc()
235      !!----------------------------------------------------------------------
236      !!               ***  FUNCTION sbc_isf_rnf_alloc  ***
237      !!----------------------------------------------------------------------
238      sbc_isf_alloc = 0       ! set to zero if no array to be allocated
239      IF( .NOT. ALLOCATED( qisf ) ) THEN
240         ALLOCATE(  risf_tsc(jpi,jpj,jpts), risf_tsc_b(jpi,jpj,jpts), qisf(jpi,jpj)   , &
241               &    rhisf_tbl(jpi,jpj)    , r1_hisf_tbl(jpi,jpj), rzisf_tbl(jpi,jpj)  , &
242               &    ttbl(jpi,jpj)         , stbl(jpi,jpj)       , utbl(jpi,jpj)       , &
243               &    vtbl(jpi, jpj)        , risfLeff(jpi,jpj)   , rhisf_tbl_0(jpi,jpj), &
244               &    ralpha(jpi,jpj)       , misfkt(jpi,jpj)     , misfkb(jpi,jpj)     , &
245               &    STAT= sbc_isf_alloc )
246         !
247         CALL mpp_sum ( 'sbcisf', sbc_isf_alloc )
248         IF( sbc_isf_alloc /= 0 )   CALL ctl_stop( 'STOP', 'sbc_isf_alloc: failed to allocate arrays.' )
249         !
250      ENDIF
251   END FUNCTION
252
253
254  SUBROUTINE sbc_isf_init( Kmm )
255      !!---------------------------------------------------------------------
256      !!                  ***  ROUTINE sbc_isf_init  ***
257      !!
258      !! ** Purpose : Initialisation of variables for iceshelf fluxes formulation
259      !!
260      !! ** Method  :  4 parameterizations are available according to nn_isf
261      !!               nn_isf = 1 : Realistic ice_shelf formulation
262      !!                        2 : Beckmann & Goose parameterization
263      !!                        3 : Specified runoff in deptht (Mathiot & al. )
264      !!                        4 : specified fwf and heat flux forcing beneath the ice shelf
265      !!----------------------------------------------------------------------
266      INTEGER, INTENT(in) ::   Kmm  ! ocean time level indices
267      INTEGER               :: ji, jj, jk           ! loop index
268      INTEGER               :: ik                   ! current level index
269      INTEGER               :: ikt, ikb             ! top and bottom level of the isf boundary layer
270      INTEGER               :: inum, ierror
271      INTEGER               :: ios                  ! Local integer output status for namelist read
272      REAL(wp)              :: zhk
273      CHARACTER(len=256)    :: cvarzisf, cvarhisf   ! name for isf file
274      CHARACTER(LEN=32 )    :: cvarLeff             ! variable name for efficient Length scale
275      !!----------------------------------------------------------------------
276      NAMELIST/namsbc_isf/ nn_isfblk, rn_hisf_tbl, rn_gammat0, rn_gammas0, nn_gammablk, nn_isf, &
277                         & sn_fwfisf, sn_rnfisf, sn_depmax_isf, sn_depmin_isf, sn_Leff_isf
278      !!----------------------------------------------------------------------
279
280      REWIND( numnam_ref )              ! Namelist namsbc_rnf in reference namelist : Runoffs
281      READ  ( numnam_ref, namsbc_isf, IOSTAT = ios, ERR = 901)
282901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namsbc_isf in reference namelist', lwp )
283
284      REWIND( numnam_cfg )              ! Namelist namsbc_rnf in configuration namelist : Runoffs
285      READ  ( numnam_cfg, namsbc_isf, IOSTAT = ios, ERR = 902 )
286902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namsbc_isf in configuration namelist', lwp )
287      IF(lwm) WRITE ( numond, namsbc_isf )
288
289      IF(lwp) WRITE(numout,*)
290      IF(lwp) WRITE(numout,*) 'sbc_isf_init : heat flux of the ice shelf'
291      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
292      IF(lwp) WRITE(numout,*) '   Namelist namsbc_isf :'
293      IF(lwp) WRITE(numout,*) '      type ice shelf melting/freezing         nn_isf      = ', nn_isf
294      IF(lwp) WRITE(numout,*) '      bulk formulation (nn_isf=1 only)        nn_isfblk   = ', nn_isfblk
295      IF(lwp) WRITE(numout,*) '      thickness of the top boundary layer     rn_hisf_tbl = ', rn_hisf_tbl
296      IF(lwp) WRITE(numout,*) '      gamma formulation                       nn_gammablk = ', nn_gammablk 
297      IF(lwp) WRITE(numout,*) '      gammat coefficient                      rn_gammat0  = ', rn_gammat0 
298      IF(lwp) WRITE(numout,*) '      gammas coefficient                      rn_gammas0  = ', rn_gammas0 
299      IF(lwp) WRITE(numout,*) '      top drag coef. used (from namdrg_top)   rn_Cd0      = ', r_Cdmin_top 
300
301
302                           !  1 = presence of ISF    2 = bg03 parametrisation
303                           !  3 = rnf file for isf   4 = ISF fwf specified
304                           !  option 1 and 4 need ln_isfcav = .true. (domzgr)
305      !
306      ! Allocate public variable
307      IF ( sbc_isf_alloc()  /= 0 )         CALL ctl_stop( 'STOP', 'sbc_isf : unable to allocate arrays' )
308      !
309      ! initialisation
310      qisf    (:,:)    = 0._wp   ;   fwfisf  (:,:) = 0._wp
311      risf_tsc(:,:,:)  = 0._wp   ;   fwfisf_b(:,:) = 0._wp
312      !
313      ! define isf tbl tickness, top and bottom indice
314      SELECT CASE ( nn_isf )
315      CASE ( 1 ) 
316         IF(lwp) WRITE(numout,*)
317         IF(lwp) WRITE(numout,*) '      ==>>>   presence of under iceshelf seas (nn_isf = 1)'
318         rhisf_tbl(:,:) = rn_hisf_tbl
319         misfkt   (:,:) = mikt(:,:)         ! same indice for bg03 et cav => used in isfdiv
320         !
321      CASE ( 2 , 3 )
322         IF( .NOT.l_isfcpl ) THEN
323             ALLOCATE( sf_rnfisf(1), STAT=ierror )
324             ALLOCATE( sf_rnfisf(1)%fnow(jpi,jpj,1), sf_rnfisf(1)%fdta(jpi,jpj,1,2) )
325             CALL fld_fill( sf_rnfisf, (/ sn_rnfisf /), cn_dirisf, 'sbc_isf_init', 'read fresh water flux isf data', 'namsbc_isf' )
326          ENDIF
327          !  read effective lenght (BG03)
328          IF( nn_isf == 2 ) THEN
329            IF(lwp) WRITE(numout,*)
330            IF(lwp) WRITE(numout,*) '      ==>>>   bg03 parametrisation (nn_isf = 2)'
331            CALL iom_open( sn_Leff_isf%clname, inum )
332            cvarLeff = TRIM(sn_Leff_isf%clvar)
333            CALL iom_get( inum, jpdom_data, cvarLeff, risfLeff , 1)
334            CALL iom_close(inum)
335            !
336            risfLeff = risfLeff*1000.0_wp           !: convertion in m
337         ELSE
338            IF(lwp) WRITE(numout,*)
339            IF(lwp) WRITE(numout,*) '      ==>>>   rnf file for isf (nn_isf = 3)'
340         ENDIF
341         ! read depth of the top and bottom of the isf top boundary layer (in this case, isf front depth and grounding line depth)
342         CALL iom_open( sn_depmax_isf%clname, inum )
343         cvarhisf = TRIM(sn_depmax_isf%clvar)
344         CALL iom_get( inum, jpdom_data, cvarhisf, rhisf_tbl, 1) !: depth of deepest point of the ice shelf base
345         CALL iom_close(inum)
346         !
347         CALL iom_open( sn_depmin_isf%clname, inum )
348         cvarzisf = TRIM(sn_depmin_isf%clvar)
349         CALL iom_get( inum, jpdom_data, cvarzisf, rzisf_tbl, 1) !: depth of shallowest point of the ice shelves base
350         CALL iom_close(inum)
351         !
352         rhisf_tbl(:,:) = rhisf_tbl(:,:) - rzisf_tbl(:,:)        !: tickness isf boundary layer
353
354         !! compute first level of the top boundary layer
355         DO ji = 1, jpi
356            DO jj = 1, jpj
357                ik = 2
358!!gm potential bug: use gdepw_0 not _n
359                DO WHILE ( ik <= mbkt(ji,jj) .AND. gdepw(ji,jj,ik,Kmm) < rzisf_tbl(ji,jj) ) ;  ik = ik + 1 ;  END DO
360                misfkt(ji,jj) = ik-1
361            END DO
362         END DO
363         !
364      CASE ( 4 ) 
365         IF(lwp) WRITE(numout,*)
366         IF(lwp) WRITE(numout,*) '      ==>>>   specified fresh water flux in ISF (nn_isf = 4)'
367         ! as in nn_isf == 1
368         rhisf_tbl(:,:) = rn_hisf_tbl
369         misfkt   (:,:) = mikt(:,:)         ! same indice for bg03 et cav => used in isfdiv
370         !
371         ! load variable used in fldread (use for temporal interpolation of isf fwf forcing)
372         IF( .NOT.l_isfcpl ) THEN
373           ALLOCATE( sf_fwfisf(1), STAT=ierror )
374           ALLOCATE( sf_fwfisf(1)%fnow(jpi,jpj,1), sf_fwfisf(1)%fdta(jpi,jpj,1,2) )
375           CALL fld_fill( sf_fwfisf, (/ sn_fwfisf /), cn_dirisf, 'sbc_isf_init', 'read fresh water flux isf data', 'namsbc_isf' )
376         ENDIF
377         !
378      CASE DEFAULT
379         CALL ctl_stop( 'sbc_isf_init: wrong value of nn_isf' )
380      END SELECT
381         
382      rhisf_tbl_0(:,:) = rhisf_tbl(:,:)
383
384      ! compute bottom level of isf tbl and thickness of tbl below the ice shelf
385      DO jj = 1,jpj
386         DO ji = 1,jpi
387            ikt = misfkt(ji,jj)
388            ikb = misfkt(ji,jj)
389            ! thickness of boundary layer at least the top level thickness
390            rhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), e3t(ji,jj,ikt,Kmm))
391
392            ! determine the deepest level influenced by the boundary layer
393            DO jk = ikt+1, mbkt(ji,jj)
394               IF( (SUM(e3t(ji,jj,ikt:jk-1,Kmm)) < rhisf_tbl(ji,jj)) .AND. (tmask(ji,jj,jk) == 1) )   ikb = jk
395            END DO
396            rhisf_tbl(ji,jj) = MIN(rhisf_tbl(ji,jj), SUM(e3t(ji,jj,ikt:ikb,Kmm))) ! limit the tbl to water thickness.
397            misfkb(ji,jj) = ikb                                                   ! last wet level of the tbl
398            r1_hisf_tbl(ji,jj) = 1._wp / rhisf_tbl(ji,jj)
399
400            zhk           = SUM( e3t(ji, jj, ikt:ikb - 1,Kmm)) * r1_hisf_tbl(ji,jj) ! proportion of tbl cover by cell from ikt to ikb - 1
401            ralpha(ji,jj) = rhisf_tbl(ji,jj) * (1._wp - zhk ) / e3t(ji,jj,ikb,Kmm)  ! proportion of bottom cell influenced by boundary layer
402         END DO
403      END DO
404
405      IF( lwxios ) THEN
406          CALL iom_set_rstw_var_active('fwf_isf_b')
407          CALL iom_set_rstw_var_active('isf_hc_b')
408          CALL iom_set_rstw_var_active('isf_sc_b')
409      ENDIF
410
411
412  END SUBROUTINE sbc_isf_init
413
414
415  SUBROUTINE sbc_isf_bg03( kt, Kmm )
416      !!---------------------------------------------------------------------
417      !!                  ***  ROUTINE sbc_isf_bg03  ***
418      !!
419      !! ** Purpose : add net heat and fresh water flux from ice shelf melting
420      !!          into the adjacent ocean
421      !!
422      !! ** Method  :   See reference
423      !!
424      !! ** Reference : Beckmann and Goosse (2003), "A parameterization of ice shelf-ocean
425      !!         interaction for climate models", Ocean Modelling 5(2003) 157-170.
426      !!         (hereafter BG)
427      !! History :  06-02  (C. Wang) Original code
428      !!----------------------------------------------------------------------
429      INTEGER, INTENT ( in ) :: kt
430      INTEGER, INTENT ( in ) :: Kmm  ! ocean time level indices
431      !
432      INTEGER  :: ji, jj, jk ! dummy loop index
433      INTEGER  :: ik         ! current level
434      REAL(wp) :: zt_sum     ! sum of the temperature between 200m and 600m
435      REAL(wp) :: zt_ave     ! averaged temperature between 200m and 600m
436      REAL(wp) :: zt_frz     ! freezing point temperature at depth z
437      REAL(wp) :: zpress     ! pressure to compute the freezing point in depth
438      !!----------------------------------------------------------------------
439      !
440      DO ji = 1, jpi
441         DO jj = 1, jpj
442            ik = misfkt(ji,jj)
443            !! Initialize arrays to 0 (each step)
444            zt_sum = 0.e0_wp
445            IF ( ik > 1 ) THEN
446               ! 1. -----------the average temperature between 200m and 600m ---------------------
447               DO jk = misfkt(ji,jj),misfkb(ji,jj)
448                  ! Calculate freezing temperature
449                  zpress = grav*rau0*gdept(ji,jj,ik,Kmm)*1.e-04
450                  CALL eos_fzp(stbl(ji,jj), zt_frz, zpress) 
451                  zt_sum = zt_sum + (ts(ji,jj,jk,jp_tem,Kmm)-zt_frz) * e3t(ji,jj,jk,Kmm) * tmask(ji,jj,jk)  ! sum temp
452               END DO
453               zt_ave = zt_sum/rhisf_tbl(ji,jj) ! calcul mean value
454               ! 2. ------------Net heat flux and fresh water flux due to the ice shelf
455               ! For those corresponding to zonal boundary   
456               qisf(ji,jj) = - rau0 * rcp * rn_gammat0 * risfLeff(ji,jj) * e1t(ji,jj) * zt_ave  &
457                           & * r1_e1e2t(ji,jj) * tmask(ji,jj,jk)
458             
459               fwfisf(ji,jj) = qisf(ji,jj) / rLfusisf          !fresh water flux kg/(m2s)                 
460               fwfisf(ji,jj) = fwfisf(ji,jj) * ( soce / stbl(ji,jj) )
461               !add to salinity trend
462            ELSE
463               qisf(ji,jj) = 0._wp   ;   fwfisf(ji,jj) = 0._wp
464            END IF
465         END DO
466      END DO
467      !
468  END SUBROUTINE sbc_isf_bg03
469
470
471  SUBROUTINE sbc_isf_cav( kt, Kmm )
472      !!---------------------------------------------------------------------
473      !!                     ***  ROUTINE sbc_isf_cav  ***
474      !!
475      !! ** Purpose :   handle surface boundary condition under ice shelf
476      !!
477      !! ** Method  : -
478      !!
479      !! ** Action  :   utau, vtau : remain unchanged
480      !!                taum, wndm : remain unchanged
481      !!                qns        : update heat flux below ice shelf
482      !!                emp, emps  : update freshwater flux below ice shelf
483      !!---------------------------------------------------------------------
484      INTEGER, INTENT(in) ::   kt   ! ocean time step
485      INTEGER, INTENT(in) ::   Kmm  ! ocean time level index
486      !
487      INTEGER  ::   ji, jj     ! dummy loop indices
488      INTEGER  ::   nit
489      LOGICAL  ::   lit
490      REAL(wp) ::   zlamb1, zlamb2, zlamb3
491      REAL(wp) ::   zeps1,zeps2,zeps3,zeps4,zeps6,zeps7
492      REAL(wp) ::   zaqe,zbqe,zcqe,zaqer,zdis,zsfrz,zcfac
493      REAL(wp) ::   zeps = 1.e-20_wp       
494      REAL(wp) ::   zerr
495      REAL(wp), DIMENSION(jpi,jpj) ::   zfrz
496      REAL(wp), DIMENSION(jpi,jpj) ::   zgammat, zgammas 
497      REAL(wp), DIMENSION(jpi,jpj) ::   zfwflx, zhtflx, zhtflx_b
498      !!---------------------------------------------------------------------
499      !
500      ! coeficient for linearisation of potential tfreez
501      ! Crude approximation for pressure (but commonly used)
502      IF ( l_useCT ) THEN   ! linearisation from Jourdain et al. (2017)
503         zlamb1 =-0.0564_wp
504         zlamb2 = 0.0773_wp
505         zlamb3 =-7.8633e-8 * grav * rau0
506      ELSE                  ! linearisation from table 4 (Asay-Davis et al., 2015)
507         zlamb1 =-0.0573_wp
508         zlamb2 = 0.0832_wp
509         zlamb3 =-7.53e-8 * grav * rau0
510      ENDIF
511      !
512      ! initialisation
513      zgammat(:,:) = rn_gammat0 ; zgammas (:,:) = rn_gammas0
514      zhtflx (:,:) = 0.0_wp     ; zhtflx_b(:,:) = 0.0_wp   
515      zfwflx (:,:) = 0.0_wp
516
517      ! compute ice shelf melting
518      nit = 1 ; lit = .TRUE.
519      DO WHILE ( lit )    ! maybe just a constant number of iteration as in blk_core is fine
520         SELECT CASE ( nn_isfblk )
521         CASE ( 1 )   !  ISOMIP formulation (2 equations) for volume flux (Hunter et al., 2006)
522            ! Calculate freezing temperature
523            CALL eos_fzp( stbl(:,:), zfrz(:,:), risfdep(:,:) )
524
525            ! compute gammat every where (2d)
526            CALL sbc_isf_gammats(zgammat, zgammas, zhtflx, zfwflx, Kmm)
527           
528            ! compute upward heat flux zhtflx and upward water flux zwflx
529            DO jj = 1, jpj
530               DO ji = 1, jpi
531                  zhtflx(ji,jj) =   zgammat(ji,jj)*rcp*rau0*(ttbl(ji,jj)-zfrz(ji,jj))
532                  zfwflx(ji,jj) = - zhtflx(ji,jj)/rLfusisf
533               END DO
534            END DO
535
536            ! Compute heat flux and upward fresh water flux
537            qisf  (:,:) = - zhtflx(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:)
538            fwfisf(:,:) =   zfwflx(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:)
539
540         CASE ( 2 )  ! ISOMIP+ formulation (3 equations) for volume flux (Asay-Davis et al., 2015)
541            ! compute gammat every where (2d)
542            CALL sbc_isf_gammats(zgammat, zgammas, zhtflx, zfwflx, Kmm)
543
544            ! compute upward heat flux zhtflx and upward water flux zwflx
545            ! Resolution of a 2d equation from equation 21, 22 and 23 to find Sb (Asay-Davis et al., 2015)
546            DO jj = 1, jpj
547               DO ji = 1, jpi
548                  ! compute coeficient to solve the 2nd order equation
549                  zeps1 = rcp*rau0*zgammat(ji,jj)
550                  zeps2 = rLfusisf*rau0*zgammas(ji,jj)
551                  zeps3 = rhoisf*rcpisf*rkappa/MAX(risfdep(ji,jj),zeps)
552                  zeps4 = zlamb2+zlamb3*risfdep(ji,jj)
553                  zeps6 = zeps4-ttbl(ji,jj)
554                  zeps7 = zeps4-tsurf
555                  zaqe  = zlamb1 * (zeps1 + zeps3)
556                  zaqer = 0.5_wp/MIN(zaqe,-zeps)
557                  zbqe  = zeps1*zeps6+zeps3*zeps7-zeps2
558                  zcqe  = zeps2*stbl(ji,jj)
559                  zdis  = zbqe*zbqe-4.0_wp*zaqe*zcqe               
560
561                  ! Presumably zdis can never be negative because gammas is very small compared to gammat
562                  ! compute s freeze
563                  zsfrz=(-zbqe-SQRT(zdis))*zaqer
564                  IF ( zsfrz < 0.0_wp ) zsfrz=(-zbqe+SQRT(zdis))*zaqer
565
566                  ! compute t freeze (eq. 22)
567                  zfrz(ji,jj)=zeps4+zlamb1*zsfrz
568 
569                  ! zfwflx is upward water flux
570                  ! zhtflx is upward heat flux (out of ocean)
571                  ! compute the upward water and heat flux (eq. 28 and eq. 29)
572                  zfwflx(ji,jj) = rau0 * zgammas(ji,jj) * (zsfrz-stbl(ji,jj)) / MAX(zsfrz,zeps)
573                  zhtflx(ji,jj) = zgammat(ji,jj) * rau0 * rcp * (ttbl(ji,jj) - zfrz(ji,jj) ) 
574               END DO
575            END DO
576
577            ! compute heat and water flux
578            qisf  (:,:) = - zhtflx(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:)
579            fwfisf(:,:) =   zfwflx(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:)
580
581         END SELECT
582
583         ! define if we need to iterate (nn_gammablk 0/1 do not need iteration)
584         IF ( nn_gammablk <  2 ) THEN ; lit = .FALSE.
585         ELSE                           
586            ! check total number of iteration
587            IF (nit >= 100) THEN ; CALL ctl_stop( 'STOP', 'sbc_isf_hol99 : too many iteration ...' )
588            ELSE                 ; nit = nit + 1
589            END IF
590
591            ! compute error between 2 iterations
592            ! if needed save gammat and compute zhtflx_b for next iteration
593            zerr = MAXVAL(ABS(zhtflx-zhtflx_b))
594            IF ( zerr <= 0.01_wp ) THEN ; lit = .FALSE.
595            ELSE                        ; zhtflx_b(:,:) = zhtflx(:,:)
596            END IF
597         END IF
598      END DO
599      !
600      CALL iom_put('isfgammat', zgammat)
601      CALL iom_put('isfgammas', zgammas)
602      !
603   END SUBROUTINE sbc_isf_cav
604
605
606   SUBROUTINE sbc_isf_gammats(pgt, pgs, pqhisf, pqwisf, Kmm )
607      !!----------------------------------------------------------------------
608      !! ** Purpose    : compute the coefficient echange for heat flux
609      !!
610      !! ** Method     : gamma assume constant or depends of u* and stability
611      !!
612      !! ** References : Holland and Jenkins, 1999, JPO, p1787-1800, eq 14
613      !!                Jenkins et al., 2010, JPO, p2298-2312
614      !!---------------------------------------------------------------------
615      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pgt   , pgs      !
616      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pqhisf, pqwisf   !
617      INTEGER                 , INTENT(in   ) ::   Kmm  ! ocean time level indices
618      !
619      INTEGER  :: ji, jj                     ! loop index
620      INTEGER  :: ikt                        ! local integer
621      REAL(wp) :: zdku, zdkv                 ! U, V shear
622      REAL(wp) :: zPr, zSc, zRc              ! Prandtl, Scmidth and Richardson number
623      REAL(wp) :: zmob, zmols                ! Monin Obukov length, coriolis factor at T point
624      REAL(wp) :: zbuofdep, zhnu             ! Bouyancy length scale, sublayer tickness
625      REAL(wp) :: zhmax                      ! limitation of mol
626      REAL(wp) :: zetastar                   ! stability parameter
627      REAL(wp) :: zgmolet, zgmoles, zgturb   ! contribution of modelecular sublayer and turbulence
628      REAL(wp) :: zcoef                      ! temporary coef
629      REAL(wp) :: zdep
630      REAL(wp) :: zeps = 1.0e-20_wp   
631      REAL(wp), PARAMETER :: zxsiN = 0.052_wp   ! dimensionless constant
632      REAL(wp), PARAMETER :: znu   = 1.95e-6_wp ! kinamatic viscosity of sea water (m2.s-1)
633      REAL(wp), DIMENSION(2) :: zts, zab
634      REAL(wp), DIMENSION(jpi,jpj) :: zustar   ! U, V at T point and friction velocity
635      !!---------------------------------------------------------------------
636      !
637      SELECT CASE ( nn_gammablk )
638      CASE ( 0 ) ! gamma is constant (specified in namelist)
639         !! ISOMIP formulation (Hunter et al, 2006)
640         pgt(:,:) = rn_gammat0
641         pgs(:,:) = rn_gammas0
642
643      CASE ( 1 ) ! gamma is assume to be proportional to u*
644         !! Jenkins et al., 2010, JPO, p2298-2312
645         !! Adopted by Asay-Davis et al. (2015)
646         !! compute ustar (eq. 24)
647!!gm  NB  use pCdU here so that it will incorporate local boost of Cd0 and log layer case :
648!!         zustar(:,:) = SQRT( rCdU_top(:,:) * SQRT(utbl(:,:) * utbl(:,:) + vtbl(:,:) * vtbl(:,:) + r_ke0_top) )
649!! or better :  compute ustar in zdfdrg  and use it here as well as in TKE, GLS and Co
650!!
651!!     ===>>>>    GM  to be done this chrismas
652!!         
653!!gm end
654         zustar(:,:) = SQRT( r_Cdmin_top * (utbl(:,:) * utbl(:,:) + vtbl(:,:) * vtbl(:,:) + r_ke0_top) )
655
656         !! Compute gammats
657         pgt(:,:) = zustar(:,:) * rn_gammat0
658         pgs(:,:) = zustar(:,:) * rn_gammas0
659     
660      CASE ( 2 ) ! gamma depends of stability of boundary layer
661         !! Holland and Jenkins, 1999, JPO, p1787-1800, eq 14
662         !! as MOL depends of flux and flux depends of MOL, best will be iteration (TO DO)
663         !! compute ustar
664         zustar(:,:) = SQRT( r_Cdmin_top * (utbl(:,:) * utbl(:,:) + vtbl(:,:) * vtbl(:,:) + r_ke0_top) )
665
666         !! compute Pr and Sc number (can be improved)
667         zPr =   13.8_wp
668         zSc = 2432.0_wp
669
670         !! compute gamma mole
671         zgmolet = 12.5_wp * zPr ** (2.0/3.0) - 6.0_wp
672         zgmoles = 12.5_wp * zSc ** (2.0/3.0) - 6.0_wp
673
674         !! compute gamma
675         DO ji = 2, jpi
676            DO jj = 2, jpj
677               ikt = mikt(ji,jj)
678
679               IF( zustar(ji,jj) == 0._wp ) THEN           ! only for kt = 1 I think
680                  pgt = rn_gammat0
681                  pgs = rn_gammas0
682               ELSE
683                  !! compute Rc number (as done in zdfric.F90)
684!!gm better to do it like in the new zdfric.F90   i.e. avm weighted Ri computation
685!!gm moreover, use Max(rn2,0) to take care of static instabilities....
686                  zcoef = 0.5_wp / e3w(ji,jj,ikt+1,Kmm)
687                  !                                            ! shear of horizontal velocity
688                  zdku = zcoef * (  uu(ji-1,jj  ,ikt  ,Kmm) + uu(ji,jj,ikt  ,Kmm)  &
689                     &             -uu(ji-1,jj  ,ikt+1,Kmm) - uu(ji,jj,ikt+1,Kmm)  )
690                  zdkv = zcoef * (  vv(ji  ,jj-1,ikt  ,Kmm) + vv(ji,jj,ikt  ,Kmm)  &
691                     &             -vv(ji  ,jj-1,ikt+1,Kmm) - vv(ji,jj,ikt+1,Kmm)  )
692                  !                                            ! richardson number (minimum value set to zero)
693                  zRc = rn2(ji,jj,ikt+1) / MAX( zdku*zdku + zdkv*zdkv, zeps )
694
695                  !! compute bouyancy
696                  zts(jp_tem) = ttbl(ji,jj)
697                  zts(jp_sal) = stbl(ji,jj)
698                  zdep        = gdepw(ji,jj,ikt,Kmm)
699                  !
700                  CALL eos_rab( zts, zdep, zab, Kmm )
701                  !
702                  !! compute length scale
703                  zbuofdep = grav * ( zab(jp_tem) * pqhisf(ji,jj) - zab(jp_sal) * pqwisf(ji,jj) )  !!!!!!!!!!!!!!!!!!!!!!!!!!!!
704
705                  !! compute Monin Obukov Length
706                  ! Maximum boundary layer depth
707                  zhmax = gdept(ji,jj,mbkt(ji,jj),Kmm) - gdepw(ji,jj,mikt(ji,jj),Kmm) -0.001_wp
708                  ! Compute Monin obukhov length scale at the surface and Ekman depth:
709                  zmob   = zustar(ji,jj) ** 3 / (vkarmn * (zbuofdep + zeps))
710                  zmols  = SIGN(1._wp, zmob) * MIN(ABS(zmob), zhmax) * tmask(ji,jj,ikt)
711
712                  !! compute eta* (stability parameter)
713                  zetastar = 1._wp / ( SQRT(1._wp + MAX(zxsiN * zustar(ji,jj) / ( ABS(ff_f(ji,jj)) * zmols * zRc ), 0._wp)))
714
715                  !! compute the sublayer thickness
716                  zhnu = 5 * znu / zustar(ji,jj)
717
718                  !! compute gamma turb
719                  zgturb = 1._wp / vkarmn * LOG(zustar(ji,jj) * zxsiN * zetastar * zetastar / ( ABS(ff_f(ji,jj)) * zhnu )) &
720                  &      + 1._wp / ( 2 * zxsiN * zetastar ) - 1._wp / vkarmn
721
722                  !! compute gammats
723                  pgt(ji,jj) = zustar(ji,jj) / (zgturb + zgmolet)
724                  pgs(ji,jj) = zustar(ji,jj) / (zgturb + zgmoles)
725               END IF
726            END DO
727         END DO
728         CALL lbc_lnk_multi( 'sbcisf', pgt, 'T', 1., pgs, 'T', 1.)
729      END SELECT
730      !
731   END SUBROUTINE sbc_isf_gammats
732
733
734   SUBROUTINE sbc_isf_tbl( pvarin, pvarout, cd_ptin, Kmm )
735      !!----------------------------------------------------------------------
736      !!                  ***  SUBROUTINE sbc_isf_tbl  ***
737      !!
738      !! ** Purpose : compute mean T/S/U/V in the boundary layer at T- point
739      !!
740      !!----------------------------------------------------------------------
741      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) :: pvarin
742      REAL(wp), DIMENSION(:,:)  , INTENT(  out) :: pvarout
743      CHARACTER(len=1),           INTENT(in   ) :: cd_ptin ! point of variable in/out
744      INTEGER                   , INTENT(in   ) :: Kmm  ! ocean time level indices
745      !
746      INTEGER ::   ji, jj, jk                ! loop index
747      INTEGER ::   ikt, ikb                    ! top and bottom index of the tbl
748      REAL(wp) ::   ze3, zhk
749      REAL(wp), DIMENSION(jpi,jpj) :: zhisf_tbl ! thickness of the tbl
750      !!----------------------------------------------------------------------
751     
752      ! initialisation
753      pvarout(:,:)=0._wp
754   
755      SELECT CASE ( cd_ptin )
756      CASE ( 'U' ) ! compute U in the top boundary layer at T- point
757         DO jj = 1,jpj
758            DO ji = 1,jpi
759               ikt = miku(ji,jj) ; ikb = miku(ji,jj)
760               ! thickness of boundary layer at least the top level thickness
761               zhisf_tbl(ji,jj) = MAX( rhisf_tbl_0(ji,jj) , e3u(ji,jj,ikt,Kmm) )
762
763               ! determine the deepest level influenced by the boundary layer
764               DO jk = ikt+1, mbku(ji,jj)
765                  IF ( (SUM(e3u(ji,jj,ikt:jk-1,Kmm)) < zhisf_tbl(ji,jj)) .AND. (umask(ji,jj,jk) == 1) ) ikb = jk
766               END DO
767               zhisf_tbl(ji,jj) = MIN(zhisf_tbl(ji,jj), SUM(e3u(ji,jj,ikt:ikb,Kmm)))  ! limit the tbl to water thickness.
768
769               ! level fully include in the ice shelf boundary layer
770               DO jk = ikt, ikb - 1
771                  ze3 = e3u(ji,jj,jk,Kmm)
772                  pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,jk) / zhisf_tbl(ji,jj) * ze3
773               END DO
774
775               ! level partially include in ice shelf boundary layer
776               zhk = SUM( e3u(ji, jj, ikt:ikb - 1,Kmm)) / zhisf_tbl(ji,jj)
777               pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,ikb) * (1._wp - zhk)
778            END DO
779         END DO
780         DO jj = 2, jpj
781            DO ji = 2, jpi
782!!gm a wet-point only average should be used here !!!
783               pvarout(ji,jj) = 0.5_wp * (pvarout(ji,jj) + pvarout(ji-1,jj))
784            END DO
785         END DO
786         CALL lbc_lnk('sbcisf', pvarout,'T',-1.)
787     
788      CASE ( 'V' ) ! compute V in the top boundary layer at T- point
789         DO jj = 1,jpj
790            DO ji = 1,jpi
791               ikt = mikv(ji,jj) ; ikb = mikv(ji,jj)
792               ! thickness of boundary layer at least the top level thickness
793               zhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), e3v(ji,jj,ikt,Kmm))
794
795               ! determine the deepest level influenced by the boundary layer
796               DO jk = ikt+1, mbkv(ji,jj)
797                  IF ( (SUM(e3v(ji,jj,ikt:jk-1,Kmm)) < zhisf_tbl(ji,jj)) .AND. (vmask(ji,jj,jk) == 1) ) ikb = jk
798               END DO
799               zhisf_tbl(ji,jj) = MIN(zhisf_tbl(ji,jj), SUM(e3v(ji,jj,ikt:ikb,Kmm)))  ! limit the tbl to water thickness.
800
801               ! level fully include in the ice shelf boundary layer
802               DO jk = ikt, ikb - 1
803                  ze3 = e3v(ji,jj,jk,Kmm)
804                  pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,jk) / zhisf_tbl(ji,jj) * ze3
805               END DO
806
807               ! level partially include in ice shelf boundary layer
808               zhk = SUM( e3v(ji, jj, ikt:ikb - 1,Kmm)) / zhisf_tbl(ji,jj)
809               pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,ikb) * (1._wp - zhk)
810            END DO
811         END DO
812         DO jj = 2, jpj
813            DO ji = 2, jpi
814!!gm a wet-point only average should be used here !!!
815               pvarout(ji,jj) = 0.5_wp * (pvarout(ji,jj) + pvarout(ji,jj-1))
816            END DO
817         END DO
818         CALL lbc_lnk('sbcisf', pvarout,'T',-1.)
819
820      CASE ( 'T' ) ! compute T in the top boundary layer at T- point
821         DO jj = 1,jpj
822            DO ji = 1,jpi
823               ikt = misfkt(ji,jj)
824               ikb = misfkb(ji,jj)
825
826               ! level fully include in the ice shelf boundary layer
827               DO jk = ikt, ikb - 1
828                  ze3 = e3t(ji,jj,jk,Kmm)
829                  pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,jk) * r1_hisf_tbl(ji,jj) * ze3
830               END DO
831
832               ! level partially include in ice shelf boundary layer
833               zhk = SUM( e3t(ji, jj, ikt:ikb - 1,Kmm)) * r1_hisf_tbl(ji,jj)
834               pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,ikb) * (1._wp - zhk)
835            END DO
836         END DO
837      END SELECT
838      !
839      ! mask mean tbl value
840      pvarout(:,:) = pvarout(:,:) * ssmask(:,:)
841      !
842   END SUBROUTINE sbc_isf_tbl
843     
844
845   SUBROUTINE sbc_isf_div( phdivn, Kmm )
846      !!----------------------------------------------------------------------
847      !!                  ***  SUBROUTINE sbc_isf_div  ***
848      !!       
849      !! ** Purpose :   update the horizontal divergence with the runoff inflow
850      !!
851      !! ** Method  :   
852      !!                CAUTION : risf_tsc(:,:,jp_sal) is negative (outflow) increase the
853      !!                          divergence and expressed in m/s
854      !!
855      !! ** Action  :   phdivn   decreased by the runoff inflow
856      !!----------------------------------------------------------------------
857      REAL(wp), DIMENSION(:,:,:), INTENT( inout ) ::   phdivn   ! horizontal divergence
858      INTEGER                   , INTENT( in    ) ::   Kmm      ! ocean time level indices
859      !
860      INTEGER  ::   ji, jj, jk   ! dummy loop indices
861      INTEGER  ::   ikt, ikb 
862      REAL(wp) ::   zhk
863      REAL(wp) ::   zfact     ! local scalar
864      !!----------------------------------------------------------------------
865      !
866      zfact   = 0.5_wp
867      !
868      IF(.NOT.ln_linssh ) THEN     ! need to re compute level distribution of isf fresh water
869         DO jj = 1,jpj
870            DO ji = 1,jpi
871               ikt = misfkt(ji,jj)
872               ikb = misfkt(ji,jj)
873               ! thickness of boundary layer at least the top level thickness
874               rhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), e3t(ji,jj,ikt,Kmm))
875
876               ! determine the deepest level influenced by the boundary layer
877               DO jk = ikt, mbkt(ji,jj)
878                  IF ( (SUM(e3t(ji,jj,ikt:jk-1,Kmm)) .LT. rhisf_tbl(ji,jj)) .AND. (tmask(ji,jj,jk) == 1) ) ikb = jk
879               END DO
880               rhisf_tbl(ji,jj) = MIN(rhisf_tbl(ji,jj), SUM(e3t(ji,jj,ikt:ikb,Kmm)))  ! limit the tbl to water thickness.
881               misfkb(ji,jj) = ikb                                                  ! last wet level of the tbl
882               r1_hisf_tbl(ji,jj) = 1._wp / rhisf_tbl(ji,jj)
883
884               zhk           = SUM( e3t(ji, jj, ikt:ikb - 1,Kmm)) * r1_hisf_tbl(ji,jj)  ! proportion of tbl cover by cell from ikt to ikb - 1
885               ralpha(ji,jj) = rhisf_tbl(ji,jj) * (1._wp - zhk ) / e3t(ji,jj,ikb,Kmm)  ! proportion of bottom cell influenced by boundary layer
886            END DO
887         END DO
888      END IF 
889      !
890      !==   ice shelf melting distributed over several levels   ==!
891      DO jj = 1,jpj
892         DO ji = 1,jpi
893               ikt = misfkt(ji,jj)
894               ikb = misfkb(ji,jj)
895               ! level fully include in the ice shelf boundary layer
896               DO jk = ikt, ikb - 1
897                  phdivn(ji,jj,jk) = phdivn(ji,jj,jk) + ( fwfisf(ji,jj) + fwfisf_b(ji,jj) ) &
898                    &              * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact
899               END DO
900               ! level partially include in ice shelf boundary layer
901               phdivn(ji,jj,ikb) = phdivn(ji,jj,ikb) + ( fwfisf(ji,jj) &
902                    &            + fwfisf_b(ji,jj) ) * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact * ralpha(ji,jj) 
903         END DO
904      END DO
905      !
906   END SUBROUTINE sbc_isf_div
907
908   !!======================================================================
909END MODULE sbcisf
Note: See TracBrowser for help on using the repository browser.