New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
sbcisf.F90 in NEMO/branches/UKMO/NEMO_4.0_mirror_text_diagnostics/src/OCE/SBC – NEMO

source: NEMO/branches/UKMO/NEMO_4.0_mirror_text_diagnostics/src/OCE/SBC/sbcisf.F90 @ 10986

Last change on this file since 10986 was 10986, checked in by andmirek, 5 years ago

GMED 462 add flush

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