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_CNRS_2017/NEMOGCM/NEMO/OPA_SRC/SBC – NEMO

source: branches/2017/dev_CNRS_2017/NEMOGCM/NEMO/OPA_SRC/SBC/sbcisf.F90 @ 8882

Last change on this file since 8882 was 8882, checked in by flavoni, 6 years ago

dev_CNRS_2017 branch: merged dev_r7881_ENHANCE09_RK3 with trunk r8864

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