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

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

source: NEMO/branches/2019/dev_r11943_MERGE_2019/src/OCE/SBC/sbcisf.F90 @ 11960

Last change on this file since 11960 was 11960, checked in by acc, 4 years ago

Branch 2019/dev_r11943_MERGE_2019. Merge in changes from 2019/dev_r11613_ENHANCE-04_namelists_as_internalfiles. (svn merge -r 11614:11954). Resolved tree conflicts and one actual conflict. Sette tested(these changes alter the ext/AGRIF reference; remember to update). See ticket #2341

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