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 branches/2017/dev_r7881_ENHANCE09_RK3/NEMOGCM/NEMO/OPA_SRC/SBC – NEMO

source: branches/2017/dev_r7881_ENHANCE09_RK3/NEMOGCM/NEMO/OPA_SRC/SBC/sbcisf.F90 @ 8813

Last change on this file since 8813 was 8813, checked in by gm, 6 years ago

#1911 (ENHANCE-09): PART I.3 - phasing with updated branch dev_r8183_ICEMODEL revision 8787

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