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_r11613_ENHANCE-04_namelists_as_internalfiles/src/OCE/SBC – NEMO

source: NEMO/branches/2019/dev_r11613_ENHANCE-04_namelists_as_internalfiles/src/OCE/SBC/sbcisf.F90 @ 11844

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

Branch 2019/dev_r11613_ENHANCE-04_namelists_as_internalfiles. Final, non-substantive changes to complete this branch. These changes remove all REWIND statements on the old namelist fortran units (now character variables for internal files). These changes have been left until last since they are easily repeated via a script and it may be preferable to use the previous revision for merge purposes and reapply these last changes separately. This branch has been fully SETTE tested.

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