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

source: branches/2017/dev_r7881_HPC09_ZDF/NEMOGCM/NEMO/OPA_SRC/SBC/sbcisf.F90 @ 8143

Last change on this file since 8143 was 8143, checked in by gm, 7 years ago

#1880 (HPC-09) - step-7: top/bottom drag computed at T-points, zdfbfr.F90 replaced by zdfdrg.F90 + changes in namelist

  • Property svn:keywords set to Id
File size: 43.3 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 manager library
24   USE fldread        ! read input field at current time step
25   USE lbclnk         !
26   USE wrk_nemo       ! Memory allocation
27   USE timing         ! Timing
28   USE lib_fortran    ! glob_sum
29
30   IMPLICIT NONE
31   PRIVATE
32
33   PUBLIC   sbc_isf, sbc_isf_init, sbc_isf_div, sbc_isf_alloc  ! routine called in sbcmod and divhor
34
35   ! public in order to be able to output then
36
37   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   risf_tsc_b, risf_tsc  !: before and now T & S isf contents [K.m/s & PSU.m/s] 
38   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   qisf                  !: net heat flux from ice shelf      [W/m2]
39   REAL(wp), PUBLIC ::   rn_hisf_tbl                 !: thickness of top boundary layer [m]
40   INTEGER , PUBLIC ::   nn_isf                      !: flag to choose between explicit/param/specified 
41   INTEGER , PUBLIC ::   nn_isfblk                   !: flag to choose the bulk formulation to compute the ice shelf melting
42   INTEGER , PUBLIC ::   nn_gammablk                 !: flag to choose how the exchange coefficient is computed
43   REAL(wp), PUBLIC ::   rn_gammat0                  !: temperature exchange coeficient []
44   REAL(wp), PUBLIC ::   rn_gammas0                  !: salinity    exchange coeficient []
45
46   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  rzisf_tbl              !:depth of calving front (shallowest point) nn_isf ==2/3
47   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  rhisf_tbl, rhisf_tbl_0 !:thickness of tbl  [m]
48   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  r1_hisf_tbl            !:1/thickness of tbl
49   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  ralpha                 !:proportion of bottom cell influenced by tbl
50   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  risfLeff               !:effective length (Leff) BG03 nn_isf==2
51   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  ttbl, stbl, utbl, vtbl !:top boundary layer variable at T point
52   INTEGER,    PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)      ::  misfkt, misfkb         !:Level of ice shelf base
53
54   LOGICAL, PUBLIC ::   l_isfcpl = .false.       ! isf recieved from oasis
55
56   REAL(wp), PUBLIC, SAVE ::   rcpi     = 2000.0_wp     ! specific heat of ice shelf             [J/kg/K]
57   REAL(wp), PUBLIC, SAVE ::   rkappa   = 1.54e-6_wp    ! heat diffusivity through the ice-shelf [m2/s]
58   REAL(wp), PUBLIC, SAVE ::   rhoisf   = 920.0_wp      ! volumic mass of ice shelf              [kg/m3]
59   REAL(wp), PUBLIC, SAVE ::   tsurf    = -20.0_wp      ! air temperature on top of ice shelf    [C]
60   REAL(wp), PUBLIC, SAVE ::   rlfusisf = 0.334e6_wp    ! latent heat of fusion of ice shelf     [J/kg]
61
62!: Variable used in fldread to read the forcing file (nn_isf == 4 .OR. nn_isf == 3)
63   CHARACTER(len=100), PUBLIC           :: cn_dirisf  = './' !: Root directory for location of ssr files
64   TYPE(FLD_N)       , PUBLIC           :: sn_fwfisf         !: information about the isf melting file to be read
65   TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_fwfisf
66   TYPE(FLD_N)       , PUBLIC           :: sn_rnfisf         !: information about the isf melting param.   file to be read
67   TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_rnfisf           
68   TYPE(FLD_N)       , PUBLIC           :: sn_depmax_isf     !: information about the grounding line depth file to be read
69   TYPE(FLD_N)       , PUBLIC           :: sn_depmin_isf     !: information about the calving   line depth file to be read
70   TYPE(FLD_N)       , PUBLIC           :: sn_Leff_isf       !: information about the effective length     file to be read
71   
72   !!----------------------------------------------------------------------
73   !! NEMO/OPA 3.7 , LOCEAN-IPSL (2015)
74   !! $Id$
75   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
76   !!----------------------------------------------------------------------
77CONTAINS
78 
79  SUBROUTINE sbc_isf( kt )
80      !!---------------------------------------------------------------------
81      !!                  ***  ROUTINE sbc_isf  ***
82      !!
83      !! ** Purpose : Compute Salt and Heat fluxes related to ice_shelf
84      !!              melting and freezing
85      !!
86      !! ** Method  :  4 parameterizations are available according to nn_isf
87      !!               nn_isf = 1 : Realistic ice_shelf formulation
88      !!                        2 : Beckmann & Goose parameterization
89      !!                        3 : Specified runoff in deptht (Mathiot & al. )
90      !!                        4 : specified fwf and heat flux forcing beneath the ice shelf
91      !!----------------------------------------------------------------------
92      INTEGER, INTENT( in ) :: kt                   ! ocean time step
93      !
94      INTEGER               :: ji, jj, jk           ! loop index
95      INTEGER               :: ikt, ikb             ! loop index
96      REAL(wp), DIMENSION(jpi,jpj) ::   zt_frz, zdep   ! freezing temperature (zt_frz) at depth (zdep)
97      REAL(wp), DIMENSION(:,:,:), POINTER :: zfwfisf3d, zqhcisf3d, zqlatisf3d
98      REAL(wp), DIMENSION(:,:  ), POINTER :: zqhcisf2d
99      !!---------------------------------------------------------------------
100      !
101      IF( MOD( kt-1, nn_fsbc) == 0 ) THEN
102
103         ! compute salt and heat flux
104         SELECT CASE ( nn_isf )
105         CASE ( 1 )    ! realistic ice shelf formulation
106            ! compute T/S/U/V for the top boundary layer
107            CALL sbc_isf_tbl(tsn(:,:,:,jp_tem),ttbl(:,:),'T')
108            CALL sbc_isf_tbl(tsn(:,:,:,jp_sal),stbl(:,:),'T')
109            CALL sbc_isf_tbl(un(:,:,:)        ,utbl(:,:),'U')
110            CALL sbc_isf_tbl(vn(:,:,:)        ,vtbl(:,:),'V')
111            ! iom print
112            CALL iom_put('ttbl',ttbl(:,:))
113            CALL iom_put('stbl',stbl(:,:))
114            CALL iom_put('utbl',utbl(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:))
115            CALL iom_put('vtbl',vtbl(:,:) * (1._wp - tmask(:,:,1)) * ssmask(:,:))
116            ! compute fwf and heat flux
117            ! compute fwf and heat flux
118            IF( .NOT.l_isfcpl ) THEN    ;   CALL sbc_isf_cav (kt)
119            ELSE                        ;   qisf(:,:)  = fwfisf(:,:) * rlfusisf  ! heat        flux
120            ENDIF
121
122         CASE ( 2 )    ! Beckmann and Goosse parametrisation
123            stbl(:,:)   = soce
124            CALL sbc_isf_bg03(kt)
125
126         CASE ( 3 )    ! specified runoff in depth (Mathiot et al., XXXX in preparation)
127            ! specified runoff in depth (Mathiot et al., XXXX in preparation)
128            IF( .NOT.l_isfcpl ) THEN
129               CALL fld_read ( kt, nn_fsbc, sf_rnfisf   )
130               fwfisf(:,:) = - sf_rnfisf(1)%fnow(:,:,1)         ! fresh water flux from the isf (fwfisf <0 mean melting)
131            ENDIF
132            qisf(:,:)   = fwfisf(:,:) * rlfusisf             ! heat flux
133            stbl(:,:)   = soce
134
135         CASE ( 4 )    ! specified fwf and heat flux forcing beneath the ice shelf
136           ! specified fwf and heat flux forcing beneath the ice shelf
137            IF( .NOT.l_isfcpl ) THEN
138               CALL fld_read ( kt, nn_fsbc, sf_fwfisf   )
139               !CALL fld_read ( kt, nn_fsbc, sf_qisf   )
140               fwfisf(:,:) = -sf_fwfisf(1)%fnow(:,:,1)            ! fwf
141            ENDIF
142            qisf(:,:)   = fwfisf(:,:) * rlfusisf               ! heat flux
143            stbl(:,:)   = soce
144
145         END SELECT
146
147         ! compute tsc due to isf
148         ! isf melting implemented as a volume flux and we assume that melt water is at 0 PSU.
149         ! WARNING water add at temp = 0C, need to add a correction term (fwfisf * tfreez / rau0).
150         ! compute freezing point beneath ice shelf (or top cell if nn_isf = 3)
151         DO jj = 1,jpj
152            DO ji = 1,jpi
153               zdep(ji,jj)=gdepw_n(ji,jj,misfkt(ji,jj))
154            END DO
155         END DO
156         CALL eos_fzp( stbl(:,:), zt_frz(:,:), zdep(:,:) )
157         
158         risf_tsc(:,:,jp_tem) = qisf(:,:) * r1_rau0_rcp - fwfisf(:,:) * zt_frz(:,:) * r1_rau0 !
159         risf_tsc(:,:,jp_sal) = 0.0_wp
160
161         ! lbclnk
162         CALL lbc_lnk(risf_tsc(:,:,jp_tem),'T',1.)
163         CALL lbc_lnk(risf_tsc(:,:,jp_sal),'T',1.)
164         CALL lbc_lnk(fwfisf(:,:)   ,'T',1.)
165         CALL lbc_lnk(qisf(:,:)     ,'T',1.)
166
167         ! output
168         CALL iom_put('qlatisf' , qisf)
169         CALL iom_put('fwfisf'  , fwfisf)
170
171        ! Diagnostics
172        IF ( iom_use('fwfisf3d') .OR. iom_use('qlatisf3d') .OR. iom_use('qhcisf3d') .OR. iom_use('qhcisf')) THEN
173            CALL wrk_alloc( jpi,jpj,jpk, zfwfisf3d, zqhcisf3d, zqlatisf3d )
174            CALL wrk_alloc( jpi,jpj,     zqhcisf2d                        )
175
176            zfwfisf3d(:,:,:) = 0.0_wp                         ! 3d ice shelf melting (kg/m2/s)
177            zqhcisf3d(:,:,:) = 0.0_wp                         ! 3d heat content flux (W/m2)
178            zqlatisf3d(:,:,:)= 0.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            CALL wrk_dealloc( jpi,jpj,jpk, zfwfisf3d, zqhcisf3d, zqlatisf3d )
202            CALL wrk_dealloc( jpi,jpj,     zqhcisf2d                        )
203          END IF
204          !
205        END IF
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           END IF
218         END IF
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      END IF
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(:,:), POINTER :: zhisf_tbl ! thickness of the tbl
718      !!----------------------------------------------------------------------
719      ! allocation
720      CALL wrk_alloc( jpi,jpj, zhisf_tbl)
721     
722      ! initialisation
723      pvarout(:,:)=0._wp
724   
725      SELECT CASE ( cd_ptin )
726      CASE ( 'U' ) ! compute U in the top boundary layer at T- point
727         DO jj = 1,jpj
728            DO ji = 1,jpi
729               ikt = miku(ji,jj) ; ikb = miku(ji,jj)
730               ! thickness of boundary layer at least the top level thickness
731               zhisf_tbl(ji,jj) = MAX( rhisf_tbl_0(ji,jj) , e3u_n(ji,jj,ikt) )
732
733               ! determine the deepest level influenced by the boundary layer
734               DO jk = ikt+1, mbku(ji,jj)
735                  IF ( (SUM(e3u_n(ji,jj,ikt:jk-1)) < zhisf_tbl(ji,jj)) .AND. (umask(ji,jj,jk) == 1) ) ikb = jk
736               END DO
737               zhisf_tbl(ji,jj) = MIN(zhisf_tbl(ji,jj), SUM(e3u_n(ji,jj,ikt:ikb)))  ! limit the tbl to water thickness.
738
739               ! level fully include in the ice shelf boundary layer
740               DO jk = ikt, ikb - 1
741                  ze3 = e3u_n(ji,jj,jk)
742                  pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,jk) / zhisf_tbl(ji,jj) * ze3
743               END DO
744
745               ! level partially include in ice shelf boundary layer
746               zhk = SUM( e3u_n(ji, jj, ikt:ikb - 1)) / zhisf_tbl(ji,jj)
747               pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,ikb) * (1._wp - zhk)
748            END DO
749         END DO
750         DO jj = 2, jpj
751            DO ji = 2, jpi
752!!gm a wet-point only average should be used here !!!
753               pvarout(ji,jj) = 0.5_wp * (pvarout(ji,jj) + pvarout(ji-1,jj))
754            END DO
755         END DO
756         CALL lbc_lnk(pvarout,'T',-1.)
757     
758      CASE ( 'V' ) ! compute V in the top boundary layer at T- point
759         DO jj = 1,jpj
760            DO ji = 1,jpi
761               ikt = mikv(ji,jj) ; ikb = mikv(ji,jj)
762               ! thickness of boundary layer at least the top level thickness
763               zhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), e3v_n(ji,jj,ikt))
764
765               ! determine the deepest level influenced by the boundary layer
766               DO jk = ikt+1, mbkv(ji,jj)
767                  IF ( (SUM(e3v_n(ji,jj,ikt:jk-1)) < zhisf_tbl(ji,jj)) .AND. (vmask(ji,jj,jk) == 1) ) ikb = jk
768               END DO
769               zhisf_tbl(ji,jj) = MIN(zhisf_tbl(ji,jj), SUM(e3v_n(ji,jj,ikt:ikb)))  ! limit the tbl to water thickness.
770
771               ! level fully include in the ice shelf boundary layer
772               DO jk = ikt, ikb - 1
773                  ze3 = e3v_n(ji,jj,jk)
774                  pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,jk) / zhisf_tbl(ji,jj) * ze3
775               END DO
776
777               ! level partially include in ice shelf boundary layer
778               zhk = SUM( e3v_n(ji, jj, ikt:ikb - 1)) / zhisf_tbl(ji,jj)
779               pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,ikb) * (1._wp - zhk)
780            END DO
781         END DO
782         DO jj = 2, jpj
783            DO ji = 2, jpi
784!!gm a wet-point only average should be used here !!!
785               pvarout(ji,jj) = 0.5_wp * (pvarout(ji,jj) + pvarout(ji,jj-1))
786            END DO
787         END DO
788         CALL lbc_lnk(pvarout,'T',-1.)
789
790      CASE ( 'T' ) ! compute T in the top boundary layer at T- point
791         DO jj = 1,jpj
792            DO ji = 1,jpi
793               ikt = misfkt(ji,jj)
794               ikb = misfkb(ji,jj)
795
796               ! level fully include in the ice shelf boundary layer
797               DO jk = ikt, ikb - 1
798                  ze3 = e3t_n(ji,jj,jk)
799                  pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,jk) * r1_hisf_tbl(ji,jj) * ze3
800               END DO
801
802               ! level partially include in ice shelf boundary layer
803               zhk = SUM( e3t_n(ji, jj, ikt:ikb - 1)) * r1_hisf_tbl(ji,jj)
804               pvarout(ji,jj) = pvarout(ji,jj) + pvarin(ji,jj,ikb) * (1._wp - zhk)
805            END DO
806         END DO
807      END SELECT
808
809      ! mask mean tbl value
810      pvarout(:,:) = pvarout(:,:) * ssmask(:,:)
811
812      ! deallocation
813      CALL wrk_dealloc( jpi,jpj, zhisf_tbl )     
814      !
815   END SUBROUTINE sbc_isf_tbl
816     
817
818   SUBROUTINE sbc_isf_div( phdivn )
819      !!----------------------------------------------------------------------
820      !!                  ***  SUBROUTINE sbc_isf_div  ***
821      !!       
822      !! ** Purpose :   update the horizontal divergence with the runoff inflow
823      !!
824      !! ** Method  :   
825      !!                CAUTION : risf_tsc(:,:,jp_sal) is negative (outflow) increase the
826      !!                          divergence and expressed in m/s
827      !!
828      !! ** Action  :   phdivn   decreased by the runoff inflow
829      !!----------------------------------------------------------------------
830      REAL(wp), DIMENSION(:,:,:), INTENT( inout ) ::   phdivn   ! horizontal divergence
831      !
832      INTEGER  ::   ji, jj, jk   ! dummy loop indices
833      INTEGER  ::   ikt, ikb 
834      REAL(wp) ::   zhk
835      REAL(wp) ::   zfact     ! local scalar
836      !!----------------------------------------------------------------------
837      !
838      zfact   = 0.5_wp
839      !
840      IF(.NOT.ln_linssh ) THEN     ! need to re compute level distribution of isf fresh water
841         DO jj = 1,jpj
842            DO ji = 1,jpi
843               ikt = misfkt(ji,jj)
844               ikb = misfkt(ji,jj)
845               ! thickness of boundary layer at least the top level thickness
846               rhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), e3t_n(ji,jj,ikt))
847
848               ! determine the deepest level influenced by the boundary layer
849               DO jk = ikt, mbkt(ji,jj)
850                  IF ( (SUM(e3t_n(ji,jj,ikt:jk-1)) .LT. rhisf_tbl(ji,jj)) .AND. (tmask(ji,jj,jk) == 1) ) ikb = jk
851               END DO
852               rhisf_tbl(ji,jj) = MIN(rhisf_tbl(ji,jj), SUM(e3t_n(ji,jj,ikt:ikb)))  ! limit the tbl to water thickness.
853               misfkb(ji,jj) = ikb                                                  ! last wet level of the tbl
854               r1_hisf_tbl(ji,jj) = 1._wp / rhisf_tbl(ji,jj)
855
856               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
857               ralpha(ji,jj) = rhisf_tbl(ji,jj) * (1._wp - zhk ) / e3t_n(ji,jj,ikb)  ! proportion of bottom cell influenced by boundary layer
858            END DO
859         END DO
860      END IF 
861      !
862      !==   ice shelf melting distributed over several levels   ==!
863      DO jj = 1,jpj
864         DO ji = 1,jpi
865               ikt = misfkt(ji,jj)
866               ikb = misfkb(ji,jj)
867               ! level fully include in the ice shelf boundary layer
868               DO jk = ikt, ikb - 1
869                  phdivn(ji,jj,jk) = phdivn(ji,jj,jk) + ( fwfisf(ji,jj) + fwfisf_b(ji,jj) ) &
870                    &              * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact
871               END DO
872               ! level partially include in ice shelf boundary layer
873               phdivn(ji,jj,ikb) = phdivn(ji,jj,ikb) + ( fwfisf(ji,jj) &
874                    &            + fwfisf_b(ji,jj) ) * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact * ralpha(ji,jj) 
875         END DO
876      END DO
877      !
878   END SUBROUTINE sbc_isf_div
879
880   !!======================================================================
881END MODULE sbcisf
Note: See TracBrowser for help on using the repository browser.