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

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

source: branches/2015/nemo_v3_6_STABLE/NEMOGCM/NEMO/OPA_SRC/SBC/sbcisf.F90 @ 5628

Last change on this file since 5628 was 5628, checked in by mathiot, 9 years ago

correction of unconservation with ice shelf following corrections did by Jerome on the runoff

  • Property svn:keywords set to Id
File size: 42.5 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 lbclnk          !
21   USE iom             ! I/O manager library
22   USE in_out_manager  ! I/O manager
23   USE wrk_nemo        ! Memory allocation
24   USE timing          ! Timing
25   USE lib_fortran     ! glob_sum
26   USE zdfbfr
27   USE fldread         ! read input field at current time step
28
29
30
31   IMPLICIT NONE
32   PRIVATE
33
34   PUBLIC   sbc_isf, sbc_isf_div, sbc_isf_alloc  ! routine called in sbcmod and divcur
35
36   ! public in order to be able to output then
37
38   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   risf_tsc_b, risf_tsc   
39   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   qisf              !: net heat flux from ice shelf
40   REAL(wp), PUBLIC ::   rn_hisf_tbl                 !: thickness of top boundary layer [m]
41   LOGICAL , PUBLIC ::   ln_divisf                   !: flag to correct divergence
42   INTEGER , PUBLIC ::   nn_isfblk                   !:
43   INTEGER , PUBLIC ::   nn_gammablk                 !:
44   LOGICAL , PUBLIC ::   ln_conserve                 !:
45   REAL(wp), PUBLIC ::   rn_gammat0                  !: temperature exchange coeficient
46   REAL(wp), PUBLIC ::   rn_gammas0                  !: salinity    exchange coeficient
47   REAL(wp), PUBLIC ::   rdivisf                     !: flag to test if fwf apply on divergence
48
49   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  rzisf_tbl              !:depth of calving front (shallowest point) nn_isf ==2/3
50   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  rhisf_tbl, rhisf_tbl_0 !:thickness of tbl
51   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  r1_hisf_tbl            !:1/thickness of tbl
52   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  ralpha                 !:proportion of bottom cell influenced by tbl
53   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  risfLeff               !:effective length (Leff) BG03 nn_isf==2
54   REAL(wp)   , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  ttbl, stbl, utbl, vtbl !:top boundary layer variable at T point
55#if defined key_agrif
56   ! AGRIF can not handle these arrays as integers. The reason is a mystery but problems avoided by declaring them as reals
57   REAL(wp),    PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  misfkt, misfkb         !:Level of ice shelf base
58                                                                                          !: (first wet level and last level include in the tbl)
59#else
60   INTEGER,    PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:)     ::  misfkt, misfkb         !:Level of ice shelf base
61#endif
62
63
64   REAL(wp), PUBLIC, SAVE ::   rcpi   = 2000.0_wp     ! phycst ?
65   REAL(wp), PUBLIC, SAVE ::   kappa  = 1.54e-6_wp    ! phycst ?
66   REAL(wp), PUBLIC, SAVE ::   rhoisf = 920.0_wp      ! phycst ?
67   REAL(wp), PUBLIC, SAVE ::   tsurf  = -20.0_wp      ! phycst ?
68   REAL(wp), PUBLIC, SAVE ::   lfusisf= 0.334e6_wp    ! phycst ?
69
70!: Variable used in fldread to read the forcing file (nn_isf == 4 .OR. nn_isf == 3)
71   CHARACTER(len=100), PUBLIC ::   cn_dirisf  = './'    !: Root directory for location of ssr files
72   TYPE(FLD_N)       , PUBLIC ::   sn_qisf, sn_fwfisf     !: information about the runoff file to be read
73   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_qisf, sf_fwfisf
74   TYPE(FLD_N)       , PUBLIC ::   sn_rnfisf              !: information about the runoff file to be read
75   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_rnfisf           
76   TYPE(FLD_N)       , PUBLIC ::   sn_depmax_isf, sn_depmin_isf, sn_Leff_isf     !: information about the runoff file to be read
77   
78   !! * Substitutions
79#  include "domzgr_substitute.h90"
80   !!----------------------------------------------------------------------
81   !! NEMO/OPA 3.0 , LOCEAN-IPSL (2008)
82   !! $Id$
83   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
84   !!----------------------------------------------------------------------
85
86CONTAINS
87 
88  SUBROUTINE sbc_isf(kt)
89    INTEGER, INTENT(in)          ::   kt         ! ocean time step
90    INTEGER                      ::   ji, jj, jk, ijkmin, inum, ierror
91    INTEGER                      ::   ikt, ikb   ! top and bottom level of the isf boundary layer
92    REAL(wp)                     ::   rmin
93    REAL(wp)                     ::   zhk
94    REAL(wp)                     ::   zt_frz, zpress
95    CHARACTER(len=256)           ::   cfisf , cvarzisf, cvarhisf   ! name for isf file
96    CHARACTER(LEN=256)           :: cnameis                     ! name of iceshelf file
97    CHARACTER (LEN=32)           :: cvarLeff                    ! variable name for efficient Length scale
98    INTEGER           ::   ios           ! Local integer output status for namelist read
99      !
100      !!---------------------------------------------------------------------
101      NAMELIST/namsbc_isf/ nn_isfblk, rn_hisf_tbl, ln_divisf, ln_conserve, rn_gammat0, rn_gammas0, nn_gammablk, &
102                         & sn_fwfisf, sn_qisf, sn_rnfisf, sn_depmax_isf, sn_depmin_isf, sn_Leff_isf
103      !
104      !
105      !                                         ! ====================== !
106      IF( kt == nit000 ) THEN                   !  First call kt=nit000  !
107         !                                      ! ====================== !
108         REWIND( numnam_ref )              ! Namelist namsbc_rnf in reference namelist : Runoffs
109         READ  ( numnam_ref, namsbc_isf, IOSTAT = ios, ERR = 901)
110901      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_isf in reference namelist', lwp )
111
112         REWIND( numnam_cfg )              ! Namelist namsbc_rnf in configuration namelist : Runoffs
113         READ  ( numnam_cfg, namsbc_isf, IOSTAT = ios, ERR = 902 )
114902      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_isf in configuration namelist', lwp )
115         IF(lwm) WRITE ( numond, namsbc_isf )
116
117
118         IF ( lwp ) WRITE(numout,*)
119         IF ( lwp ) WRITE(numout,*) 'sbc_isf: heat flux of the ice shelf'
120         IF ( lwp ) WRITE(numout,*) '~~~~~~~~~'
121         IF ( lwp ) WRITE(numout,*) 'sbcisf :' 
122         IF ( lwp ) WRITE(numout,*) '~~~~~~~~'
123         IF ( lwp ) WRITE(numout,*) '        nn_isf      = ', nn_isf
124         IF ( lwp ) WRITE(numout,*) '        nn_isfblk   = ', nn_isfblk
125         IF ( lwp ) WRITE(numout,*) '        rn_hisf_tbl = ', rn_hisf_tbl
126         IF ( lwp ) WRITE(numout,*) '        ln_divisf   = ', ln_divisf 
127         IF ( lwp ) WRITE(numout,*) '        nn_gammablk = ', nn_gammablk 
128         IF ( lwp ) WRITE(numout,*) '        rn_tfri2    = ', rn_tfri2 
129         IF (ln_divisf) THEN       ! keep it in the namelist ??? used true anyway as for runoff ? (PM)
130            rdivisf = 1._wp
131         ELSE
132            rdivisf = 0._wp
133         END IF
134         !
135         ! Allocate public variable
136         IF ( sbc_isf_alloc()  /= 0 )         CALL ctl_stop( 'STOP', 'sbc_isf : unable to allocate arrays' )
137         !
138         ! initialisation
139         qisf(:,:)        = 0._wp  ; fwfisf(:,:) = 0._wp
140         risf_tsc(:,:,:)  = 0._wp
141         !
142         ! define isf tbl tickness, top and bottom indice
143         IF      (nn_isf == 1) THEN
144            rhisf_tbl(:,:) = rn_hisf_tbl
145            misfkt(:,:)    = mikt(:,:)         ! same indice for bg03 et cav => used in isfdiv
146         ELSE IF ((nn_isf == 3) .OR. (nn_isf == 2)) THEN
147            ALLOCATE( sf_rnfisf(1), STAT=ierror )
148            ALLOCATE( sf_rnfisf(1)%fnow(jpi,jpj,1), sf_rnfisf(1)%fdta(jpi,jpj,1,2) )
149            CALL fld_fill( sf_rnfisf, (/ sn_rnfisf /), cn_dirisf, 'sbc_isf_init', 'read fresh water flux isf data', 'namsbc_isf' )
150
151            !: read effective lenght (BG03)
152            IF (nn_isf == 2) THEN
153               ! Read Data and save some integral values
154               CALL iom_open( sn_Leff_isf%clname, inum )
155               cvarLeff  = 'soLeff'               !: variable name for Efficient Length scale
156               CALL iom_get( inum, jpdom_data, cvarLeff, risfLeff , 1)
157               CALL iom_close(inum)
158               !
159               risfLeff = risfLeff*1000           !: convertion in m
160            END IF
161
162           ! read depth of the top and bottom of the isf top boundary layer (in this case, isf front depth and grounding line depth)
163            CALL iom_open( sn_depmax_isf%clname, inum )
164            cvarhisf = TRIM(sn_depmax_isf%clvar)
165            CALL iom_get( inum, jpdom_data, cvarhisf, rhisf_tbl, 1) !: depth of deepest point of the ice shelf base
166            CALL iom_close(inum)
167            !
168            CALL iom_open( sn_depmin_isf%clname, inum )
169            cvarzisf = TRIM(sn_depmin_isf%clvar)
170            CALL iom_get( inum, jpdom_data, cvarzisf, rzisf_tbl, 1) !: depth of shallowest point of the ice shelves base
171            CALL iom_close(inum)
172            !
173            rhisf_tbl(:,:) = rhisf_tbl(:,:) - rzisf_tbl(:,:)        !: tickness isf boundary layer
174
175           !! compute first level of the top boundary layer
176           DO ji = 1, jpi
177              DO jj = 1, jpj
178                  jk = 2
179                  DO WHILE ( jk .LE. mbkt(ji,jj) .AND. fsdepw(ji,jj,jk) < rzisf_tbl(ji,jj) ) ;  jk = jk + 1 ;  END DO
180                  misfkt(ji,jj) = jk-1
181               END DO
182            END DO
183
184         ELSE IF ( nn_isf == 4 ) THEN
185            ! as in nn_isf == 1
186            rhisf_tbl(:,:) = rn_hisf_tbl
187            misfkt(:,:)    = mikt(:,:)         ! same indice for bg03 et cav => used in isfdiv
188           
189            ! load variable used in fldread (use for temporal interpolation of isf fwf forcing)
190            ALLOCATE( sf_fwfisf(1), sf_qisf(1), STAT=ierror )
191            ALLOCATE( sf_fwfisf(1)%fnow(jpi,jpj,1), sf_fwfisf(1)%fdta(jpi,jpj,1,2) )
192            ALLOCATE( sf_qisf(1)%fnow(jpi,jpj,1), sf_qisf(1)%fdta(jpi,jpj,1,2) )
193            CALL fld_fill( sf_fwfisf, (/ sn_fwfisf /), cn_dirisf, 'sbc_isf_init', 'read fresh water flux isf data', 'namsbc_isf' )
194            !CALL fld_fill( sf_qisf  , (/ sn_qisf   /), cn_dirisf, 'sbc_isf_init', 'read heat flux isf data'       , 'namsbc_isf' )
195         END IF
196         
197         rhisf_tbl_0(:,:) = rhisf_tbl(:,:)
198
199         ! compute bottom level of isf tbl and thickness of tbl below the ice shelf
200         DO jj = 1,jpj
201            DO ji = 1,jpi
202               ikt = misfkt(ji,jj)
203               ikb = misfkt(ji,jj)
204               ! thickness of boundary layer at least the top level thickness
205               rhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), fse3t_n(ji,jj,ikt))
206
207               ! determine the deepest level influenced by the boundary layer
208               ! test on tmask useless ?????
209               DO jk = ikt, mbkt(ji,jj)
210                  IF ( (SUM(fse3t_n(ji,jj,ikt:jk-1)) .LT. rhisf_tbl(ji,jj)) .AND. (tmask(ji,jj,jk) == 1) ) ikb = jk
211               END DO
212               rhisf_tbl(ji,jj) = MIN(rhisf_tbl(ji,jj), SUM(fse3t_n(ji,jj,ikt:ikb)))  ! limit the tbl to water thickness.
213               misfkb(ji,jj) = ikb                                                  ! last wet level of the tbl
214               r1_hisf_tbl(ji,jj) = 1._wp / rhisf_tbl(ji,jj)
215
216               zhk           = SUM( fse3t(ji, jj, ikt:ikb - 1)) * r1_hisf_tbl(ji,jj)  ! proportion of tbl cover by cell from ikt to ikb - 1
217               ralpha(ji,jj) = rhisf_tbl(ji,jj) * (1._wp - zhk ) / fse3t(ji,jj,ikb)  ! proportion of bottom cell influenced by boundary layer
218            END DO
219         END DO
220         
221      END IF
222
223      !                                            ! ---------------------------------------- !
224      IF( kt /= nit000 ) THEN                      !          Swap of forcing fields          !
225         !                                         ! ---------------------------------------- !
226         fwfisf_b  (:,:  ) = fwfisf  (:,:  )               ! Swap the ocean forcing fields except at nit000
227         risf_tsc_b(:,:,:) = risf_tsc(:,:,:)               ! where before fields are set at the end of the routine
228         !
229      ENDIF
230
231      IF( MOD( kt-1, nn_fsbc) == 0 ) THEN
232
233
234         ! compute salf and heat flux
235         IF (nn_isf == 1) THEN
236            ! realistic ice shelf formulation
237            ! compute T/S/U/V for the top boundary layer
238            CALL sbc_isf_tbl(tsn(:,:,:,jp_tem),ttbl(:,:),'T')
239            CALL sbc_isf_tbl(tsn(:,:,:,jp_sal),stbl(:,:),'T')
240            CALL sbc_isf_tbl(un(:,:,:),utbl(:,:),'U')
241            CALL sbc_isf_tbl(vn(:,:,:),vtbl(:,:),'V')
242            ! iom print
243            CALL iom_put('ttbl',ttbl(:,:))
244            CALL iom_put('stbl',stbl(:,:))
245            CALL iom_put('utbl',utbl(:,:))
246            CALL iom_put('vtbl',vtbl(:,:))
247            ! compute fwf and heat flux
248            CALL sbc_isf_cav (kt)
249
250         ELSE IF (nn_isf == 2) THEN
251            ! Beckmann and Goosse parametrisation
252            stbl(:,:)   = soce
253            CALL sbc_isf_bg03(kt)
254
255         ELSE IF (nn_isf == 3) THEN
256            ! specified runoff in depth (Mathiot et al., XXXX in preparation)
257            CALL fld_read ( kt, nn_fsbc, sf_rnfisf   )
258            fwfisf(:,:) = - sf_rnfisf(1)%fnow(:,:,1)         ! fresh water flux from the isf (fwfisf <0 mean melting)
259            qisf(:,:)   = fwfisf(:,:) * lfusisf              ! heat        flux
260            stbl(:,:)   = soce
261
262         ELSE IF (nn_isf == 4) THEN
263            ! specified fwf and heat flux forcing beneath the ice shelf
264            CALL fld_read ( kt, nn_fsbc, sf_fwfisf   )
265            !CALL fld_read ( kt, nn_fsbc, sf_qisf   )
266            fwfisf(:,:) = sf_fwfisf(1)%fnow(:,:,1)            ! fwf
267            qisf(:,:)   = fwfisf(:,:) * lfusisf              ! heat        flux
268            !qisf(:,:)   = sf_qisf(1)%fnow(:,:,1)              ! heat flux
269            stbl(:,:)   = soce
270
271         END IF
272         ! compute tsc due to isf
273         ! WARNING water add at temp = 0C, correction term is added, maybe better here but need a 3D variable).
274!         zpress = grav*rau0*fsdept(ji,jj,jk)*1.e-04
275         zt_frz = -1.9 !eos_fzp( tsn(ji,jj,jk,jp_sal), zpress )
276         risf_tsc(:,:,jp_tem) = qisf(:,:) * r1_rau0_rcp - rdivisf * fwfisf(:,:) * zt_frz * r1_rau0 !
277         
278         ! salt effect already take into account in vertical advection
279         risf_tsc(:,:,jp_sal) = (1.0_wp-rdivisf) * fwfisf(:,:) * stbl(:,:) * r1_rau0
280
281         ! output
282         IF( iom_use('qisf'  ) )   CALL iom_put('qisf'  , qisf)
283         IF( iom_use('fwfisf') )   CALL iom_put('fwfisf', fwfisf * stbl(:,:) / soce )
284
285         ! if apply only on the trend and not as a volume flux (rdivisf = 0), fwfisf have to be set to 0 now
286         fwfisf(:,:) = rdivisf * fwfisf(:,:)         
287 
288         ! lbclnk
289         CALL lbc_lnk(risf_tsc(:,:,jp_tem),'T',1.)
290         CALL lbc_lnk(risf_tsc(:,:,jp_sal),'T',1.)
291         CALL lbc_lnk(fwfisf(:,:)   ,'T',1.)
292         CALL lbc_lnk(qisf(:,:)     ,'T',1.)
293
294         IF( kt == nit000 ) THEN                          !   set the forcing field at nit000 - 1    !
295            IF( ln_rstart .AND.    &                     ! Restart: read in restart file
296                 & iom_varid( numror, 'fwf_isf_b', ldstop = .FALSE. ) > 0 ) THEN
297               IF(lwp) WRITE(numout,*) '          nit000-1 isf tracer content forcing fields read in the restart file'
298               CALL iom_get( numror, jpdom_autoglo, 'fwf_isf_b', fwfisf_b(:,:) )   ! before salt content isf_tsc trend
299               CALL iom_get( numror, jpdom_autoglo, 'isf_sc_b', risf_tsc_b(:,:,jp_sal) )   ! before salt content isf_tsc trend
300               CALL iom_get( numror, jpdom_autoglo, 'isf_hc_b', risf_tsc_b(:,:,jp_tem) )   ! before salt content isf_tsc trend
301            ELSE
302               fwfisf_b(:,:)    = fwfisf(:,:)
303               risf_tsc_b(:,:,:)= risf_tsc(:,:,:)
304            END IF
305         ENDIF
306         !
307      END IF
308 
309  END SUBROUTINE sbc_isf
310
311  INTEGER FUNCTION sbc_isf_alloc()
312      !!----------------------------------------------------------------------
313      !!               ***  FUNCTION sbc_isf_rnf_alloc  ***
314      !!----------------------------------------------------------------------
315      sbc_isf_alloc = 0       ! set to zero if no array to be allocated
316      IF( .NOT. ALLOCATED( qisf ) ) THEN
317         ALLOCATE(  risf_tsc(jpi,jpj,jpts), risf_tsc_b(jpi,jpj,jpts), qisf(jpi,jpj)   , &
318               &    rhisf_tbl(jpi,jpj)    , r1_hisf_tbl(jpi,jpj), rzisf_tbl(jpi,jpj)  , &
319               &    ttbl(jpi,jpj)         , stbl(jpi,jpj)       , utbl(jpi,jpj)       , &
320               &    vtbl(jpi, jpj)        , risfLeff(jpi,jpj)   , rhisf_tbl_0(jpi,jpj), &
321               &    ralpha(jpi,jpj)       , misfkt(jpi,jpj)     , misfkb(jpi,jpj)     , &
322               &    STAT= sbc_isf_alloc )
323         !
324         IF( lk_mpp                  )   CALL mpp_sum ( sbc_isf_alloc )
325         IF( sbc_isf_alloc /= 0 )   CALL ctl_warn('sbc_isf_alloc: failed to allocate arrays.')
326         !
327      ENDIF
328  END FUNCTION
329
330  SUBROUTINE sbc_isf_bg03(kt)
331   !!==========================================================================
332   !!                 *** SUBROUTINE sbcisf_bg03  ***
333   !! add net heat and fresh water flux from ice shelf melting
334   !! into the adjacent ocean using the parameterisation by
335   !! Beckmann and Goosse (2003), "A parameterization of ice shelf-ocean
336   !!     interaction for climate models", Ocean Modelling 5(2003) 157-170.
337   !!  (hereafter BG)
338   !!==========================================================================
339   !!----------------------------------------------------------------------
340   !!   sbc_isf_bg03      : routine called from sbcmod
341   !!----------------------------------------------------------------------
342   !!
343   !! ** Purpose   :   Add heat and fresh water fluxes due to ice shelf melting
344   !! ** Reference :   Beckmann et Goosse, 2003, Ocean Modelling
345   !!
346   !! History :
347   !!      !  06-02  (C. Wang) Original code
348   !!----------------------------------------------------------------------
349
350    INTEGER, INTENT ( in ) :: kt
351
352    INTEGER :: ji, jj, jk, jish  !temporary integer
353    INTEGER :: ijkmin
354    INTEGER :: ii, ij, ik 
355    INTEGER :: inum
356
357    REAL(wp) :: zt_sum      ! sum of the temperature between 200m and 600m
358    REAL(wp) :: zt_ave      ! averaged temperature between 200m and 600m
359    REAL(wp) :: zt_frz      ! freezing point temperature at depth z
360    REAL(wp) :: zpress      ! pressure to compute the freezing point in depth
361   
362    !!----------------------------------------------------------------------
363    IF ( nn_timing == 1 ) CALL timing_start('sbc_isf_bg03')
364     !
365
366    ! This test is false only in the very first time step of a run (JMM ???- Initialy build to skip 1rst year of run )
367    DO ji = 1, jpi
368       DO jj = 1, jpj
369          ik = misfkt(ji,jj)
370          !! Initialize arrays to 0 (each step)
371          zt_sum = 0.e0_wp
372          IF ( ik .GT. 1 ) THEN
373    ! 3. -----------the average temperature between 200m and 600m ---------------------
374             DO jk = misfkt(ji,jj),misfkb(ji,jj)
375             ! freezing point temperature  at ice shelf base BG eq. 2 (JMM sign pb ??? +7.64e-4 !!!)
376             ! after verif with UNESCO, wrong sign in BG eq. 2
377             ! Calculate freezing temperature
378                zpress = grav*rau0*fsdept(ji,jj,ik)*1.e-04 
379                CALL eos_fzp(tsb(ji,jj,ik,jp_sal), zt_frz, zpress) 
380                zt_sum = zt_sum + (tsn(ji,jj,ik,jp_tem)-zt_frz) * fse3t(ji,jj,ik) * tmask(ji,jj,ik)  ! sum temp
381             ENDDO
382             zt_ave = zt_sum/rhisf_tbl(ji,jj) ! calcul mean value
383   
384    ! 4. ------------Net heat flux and fresh water flux due to the ice shelf
385          ! For those corresponding to zonal boundary   
386             qisf(ji,jj) = - rau0 * rcp * rn_gammat0 * risfLeff(ji,jj) * e1t(ji,jj) * zt_ave  &
387                         & / (e1t(ji,jj) * e2t(ji,jj)) * tmask(ji,jj,ik) 
388             
389             fwfisf(ji,jj) = qisf(ji,jj) / lfusisf          !fresh water flux kg/(m2s)                 
390             fwfisf(ji,jj) = fwfisf(ji,jj) * ( soce / stbl(ji,jj) )
391             !add to salinity trend
392          ELSE
393             qisf(ji,jj) = 0._wp ; fwfisf(ji,jj) = 0._wp
394          END IF
395       ENDDO
396    ENDDO
397    !
398    IF( nn_timing == 1 )  CALL timing_stop('sbc_isf_bg03')
399  END SUBROUTINE sbc_isf_bg03
400
401   SUBROUTINE sbc_isf_cav( kt )
402      !!---------------------------------------------------------------------
403      !!                     ***  ROUTINE sbc_isf_cav  ***
404      !!
405      !! ** Purpose :   handle surface boundary condition under ice shelf
406      !!
407      !! ** Method  : -
408      !!
409      !! ** Action  :   utau, vtau : remain unchanged
410      !!                taum, wndm : remain unchanged
411      !!                qns        : update heat flux below ice shelf
412      !!                emp, emps  : update freshwater flux below ice shelf
413      !!---------------------------------------------------------------------
414      INTEGER, INTENT(in)          ::   kt         ! ocean time step
415      !
416      LOGICAL :: ln_isomip = .true.
417      REAL(wp), DIMENSION(:,:), POINTER       ::   zfrz,zpress,zti
418      REAL(wp), DIMENSION(:,:), POINTER       ::   zgammat2d, zgammas2d 
419      !REAL(wp), DIMENSION(:,:), POINTER ::   zqisf, zfwfisf
420      REAL(wp) ::   zlamb1, zlamb2, zlamb3
421      REAL(wp) ::   zeps1,zeps2,zeps3,zeps4,zeps6,zeps7
422      REAL(wp) ::   zaqe,zbqe,zcqe,zaqer,zdis,zsfrz,zcfac
423      REAL(wp) ::   zfwflx, zhtflx, zhtflx_b
424      REAL(wp) ::   zgammat, zgammas
425      REAL(wp) ::   zeps   =  -1.e-20_wp        !==   Local constant initialization   ==!
426      INTEGER  ::   ji, jj     ! dummy loop indices
427      INTEGER  ::   ii0, ii1, ij0, ij1   ! temporary integers
428      INTEGER  ::   ierror     ! return error code
429      LOGICAL  ::   lit=.TRUE.
430      INTEGER  ::   nit
431      !!---------------------------------------------------------------------
432      !
433      ! coeficient for linearisation of tfreez
434      zlamb1=-0.0575
435      zlamb2=0.0901
436      zlamb3=-7.61e-04
437      IF( nn_timing == 1 )  CALL timing_start('sbc_isf_cav')
438      !
439      CALL wrk_alloc( jpi,jpj, zfrz,zpress,zti, zgammat2d, zgammas2d )
440
441      zcfac=0.0_wp 
442      IF (ln_conserve)  zcfac=1.0_wp
443      zpress(:,:)=0.0_wp
444      zgammat2d(:,:)=0.0_wp
445      zgammas2d(:,:)=0.0_wp
446      !
447      !
448!CDIR COLLAPSE
449      DO jj = 1, jpj
450         DO ji = 1, jpi
451            ! Crude approximation for pressure (but commonly used)
452            ! 1e-04 to convert from Pa to dBar
453            zpress(ji,jj)=grav*rau0*fsdepw(ji,jj,mikt(ji,jj))*1.e-04
454            !
455         END DO
456      END DO
457
458! Calculate in-situ temperature (ref to surface)
459      zti(:,:)=tinsitu( ttbl, stbl, zpress )
460! Calculate freezing temperature
461      CALL eos_fzp( sss_m(:,:), zfrz(:,:), zpress )
462
463     
464      zhtflx=0._wp ; zfwflx=0._wp
465      IF (nn_isfblk == 1) THEN
466         DO jj = 1, jpj
467            DO ji = 1, jpi
468               IF (mikt(ji,jj) > 1 ) THEN
469                  nit = 1; lit = .TRUE.; zgammat=rn_gammat0; zgammas=rn_gammas0; zhtflx_b=0._wp
470                  DO WHILE ( lit )
471! compute gamma
472                     CALL sbc_isf_gammats(zgammat, zgammas, zhtflx, zfwflx, ji, jj, lit)
473! zhtflx is upward heat flux (out of ocean)
474                     zhtflx = zgammat*rcp*rau0*(zti(ji,jj)-zfrz(ji,jj))
475! zwflx is upward water flux
476                     zfwflx = - zhtflx/lfusisf
477! test convergence and compute gammat
478                     IF ( (zhtflx - zhtflx_b) .LE. 0.01 ) lit = .FALSE.
479
480                     nit = nit + 1
481                     IF (nit .GE. 100) THEN
482                        !WRITE(numout,*) "sbcisf : too many iteration ... ", zhtflx, zhtflx_b,zgammat, rn_gammat0, rn_tfri2, nn_gammablk, ji,jj
483                        !WRITE(numout,*) "sbcisf : too many iteration ... ", (zhtflx - zhtflx_b)/zhtflx
484                        CALL ctl_stop( 'STOP', 'sbc_isf_hol99 : too many iteration ...' )
485                     END IF
486! save gammat and compute zhtflx_b
487                     zgammat2d(ji,jj)=zgammat
488                     zhtflx_b = zhtflx
489                  END DO
490
491                  qisf(ji,jj) = - zhtflx
492! For genuine ISOMIP protocol this should probably be something like
493                  fwfisf(ji,jj) = zfwflx  * ( soce / MAX(stbl(ji,jj),zeps))
494               ELSE
495                  fwfisf(ji,jj) = 0._wp
496                  qisf(ji,jj)   = 0._wp
497               END IF
498            !
499            END DO
500         END DO
501
502      ELSE IF (nn_isfblk == 2 ) THEN
503
504! More complicated 3 equation thermodynamics as in MITgcm
505!CDIR COLLAPSE
506         DO jj = 2, jpj
507            DO ji = 2, jpi
508               IF (mikt(ji,jj) > 1 ) THEN
509                  nit=1; lit=.TRUE.; zgammat=rn_gammat0; zgammas=rn_gammas0; zhtflx_b=0._wp; zhtflx=0._wp
510                  DO WHILE ( lit )
511                     CALL sbc_isf_gammats(zgammat, zgammas, zhtflx, zfwflx, ji, jj, lit)
512
513                     zeps1=rcp*rau0*zgammat
514                     zeps2=lfusisf*rau0*zgammas
515                     zeps3=rhoisf*rcpi*kappa/risfdep(ji,jj)
516                     zeps4=zlamb2+zlamb3*risfdep(ji,jj)
517                     zeps6=zeps4-zti(ji,jj)
518                     zeps7=zeps4-tsurf
519                     zaqe=zlamb1 * (zeps1 + zeps3)
520                     zaqer=0.5/zaqe
521                     zbqe=zeps1*zeps6+zeps3*zeps7-zeps2
522                     zcqe=zeps2*stbl(ji,jj)
523                     zdis=zbqe*zbqe-4.0*zaqe*zcqe               
524! Presumably zdis can never be negative because gammas is very small compared to gammat
525                     zsfrz=(-zbqe-SQRT(zdis))*zaqer
526                     IF (zsfrz .lt. 0.0) zsfrz=(-zbqe+SQRT(zdis))*zaqer
527                     zfrz(ji,jj)=zeps4+zlamb1*zsfrz
528 
529! zfwflx is upward water flux
530                     zfwflx= rau0 * zgammas * ( (zsfrz-stbl(ji,jj)) / zsfrz )
531! zhtflx is upward heat flux (out of ocean)
532! If non conservative we have zcfac=0.0 so zhtflx is as ISOMIP but with different zfrz value
533                     zhtflx = ( zgammat*rau0 - zcfac*zfwflx ) * rcp * (zti(ji,jj) - zfrz(ji,jj) ) 
534! zwflx is upward water flux
535! If non conservative we have zcfac=0.0 so what follows is then zfwflx*sss_m/zsfrz
536                     zfwflx = ( zgammas*rau0 - zcfac*zfwflx ) * (zsfrz - stbl(ji,jj)) / stbl(ji,jj)
537! test convergence and compute gammat
538                     IF (( zhtflx - zhtflx_b) .LE. 0.01 ) lit = .FALSE.
539
540                     nit = nit + 1
541                     IF (nit .GE. 51) THEN
542                        WRITE(numout,*) "sbcisf : too many iteration ... ", &
543                            &  zhtflx, zhtflx_b, zgammat, zgammas, nn_gammablk, ji, jj, mikt(ji,jj), narea
544                        CALL ctl_stop( 'STOP', 'sbc_isf_hol99 : too many iteration ...' )
545                     END IF
546! save gammat and compute zhtflx_b
547                     zgammat2d(ji,jj)=zgammat
548                     zgammas2d(ji,jj)=zgammas
549                     zhtflx_b = zhtflx
550
551                  END DO
552! If non conservative we have zcfac=0.0 so zhtflx is as ISOMIP but with different zfrz value
553                  qisf(ji,jj) = - zhtflx 
554! If non conservative we have zcfac=0.0 so what follows is then zfwflx*sss_m/zsfrz
555                  fwfisf(ji,jj) = zfwflx 
556               ELSE
557                  fwfisf(ji,jj) = 0._wp
558                  qisf(ji,jj)   = 0._wp
559               ENDIF
560               !
561            END DO
562         END DO
563      ENDIF
564      ! lbclnk
565      CALL lbc_lnk(zgammas2d(:,:),'T',1.)
566      CALL lbc_lnk(zgammat2d(:,:),'T',1.)
567      ! output
568      CALL iom_put('isfgammat', zgammat2d)
569      CALL iom_put('isfgammas', zgammas2d)
570      !
571      CALL wrk_dealloc( jpi,jpj, zfrz,zpress,zti, zgammat2d, zgammas2d )
572      !
573      IF( nn_timing == 1 )  CALL timing_stop('sbc_isf_cav')
574
575   END SUBROUTINE sbc_isf_cav
576
577   SUBROUTINE sbc_isf_gammats(gt, gs, zqhisf, zqwisf, ji, jj, lit )
578      !!----------------------------------------------------------------------
579      !! ** Purpose    : compute the coefficient echange for heat flux
580      !!
581      !! ** Method     : gamma assume constant or depends of u* and stability
582      !!
583      !! ** References : Holland and Jenkins, 1999, JPO, p1787-1800, eq 14
584      !!                Jenkins et al., 2010, JPO, p2298-2312
585      !!---------------------------------------------------------------------
586      REAL(wp), INTENT(inout) :: gt, gs, zqhisf, zqwisf
587      INTEGER , INTENT(in)    :: ji,jj
588      LOGICAL , INTENT(inout) :: lit
589
590      INTEGER  :: ikt                 ! loop index
591      REAL(wp) :: zut, zvt, zustar           ! U, V at T point and friction velocity
592      REAL(wp) :: zdku, zdkv                 ! U, V shear
593      REAL(wp) :: zPr, zSc, zRc              ! Prandtl, Scmidth and Richardson number
594      REAL(wp) :: zmob, zmols                ! Monin Obukov length, coriolis factor at T point
595      REAL(wp) :: zbuofdep, zhnu             ! Bouyancy length scale, sublayer tickness
596      REAL(wp) :: zhmax                      ! limitation of mol
597      REAL(wp) :: zetastar                   ! stability parameter
598      REAL(wp) :: zgmolet, zgmoles, zgturb   ! contribution of modelecular sublayer and turbulence
599      REAL(wp) :: zcoef                      ! temporary coef
600      REAL(wp) :: zdep
601      REAL(wp), PARAMETER :: zxsiN = 0.052   ! dimensionless constant
602      REAL(wp), PARAMETER :: epsln = 1.0e-20 ! a small positive number
603      REAL(wp), PARAMETER :: znu   = 1.95e-6 ! kinamatic viscosity of sea water (m2.s-1)
604      REAL(wp) ::   rcs      = 1.0e-3_wp        ! conversion: mm/s ==> m/s
605      REAL(wp), DIMENSION(2) :: zts, zab
606      !!---------------------------------------------------------------------
607      !
608      IF( nn_gammablk == 0 ) THEN
609      !! gamma is constant (specified in namelist)
610         gt = rn_gammat0
611         gs = rn_gammas0
612         lit = .FALSE.
613      ELSE IF ( nn_gammablk == 1 ) THEN
614      !! gamma is assume to be proportional to u*
615      !! WARNING in case of Losh 2008 tbl parametrization,
616      !! you have to used the mean value of u in the boundary layer)
617      !! not yet coded
618      !! Jenkins et al., 2010, JPO, p2298-2312
619         ikt = mikt(ji,jj)
620      !! Compute U and V at T points
621   !      zut = 0.5 * ( utbl(ji-1,jj  ) + utbl(ji,jj) )
622   !      zvt = 0.5 * ( vtbl(ji  ,jj-1) + vtbl(ji,jj) )
623          zut = utbl(ji,jj)
624          zvt = vtbl(ji,jj)
625
626      !! compute ustar
627         zustar = SQRT( rn_tfri2 * (zut * zut + zvt * zvt) )
628      !! Compute mean value over the TBL
629
630      !! Compute gammats
631         gt = zustar * rn_gammat0
632         gs = zustar * rn_gammas0
633         lit = .FALSE.
634      ELSE IF ( nn_gammablk == 2 ) THEN
635      !! gamma depends of stability of boundary layer
636      !! WARNING in case of Losh 2008 tbl parametrization,
637      !! you have to used the mean value of u in the boundary layer)
638      !! not yet coded
639      !! Holland and Jenkins, 1999, JPO, p1787-1800, eq 14
640      !! as MOL depends of flux and flux depends of MOL, best will be iteration (TO DO)
641               ikt = mikt(ji,jj)
642
643      !! Compute U and V at T points
644               zut = 0.5 * ( utbl(ji-1,jj  ) + utbl(ji,jj) )
645               zvt = 0.5 * ( vtbl(ji  ,jj-1) + vtbl(ji,jj) )
646
647      !! compute ustar
648               zustar = SQRT( rn_tfri2 * (zut * zut + zvt * zvt) )
649               IF (zustar == 0._wp) THEN           ! only for kt = 1 I think
650                 gt = rn_gammat0
651                 gs = rn_gammas0
652               ELSE
653      !! compute Rc number (as done in zdfric.F90)
654               zcoef = 0.5 / fse3w(ji,jj,ikt)
655               !                                            ! shear of horizontal velocity
656               zdku = zcoef * (  un(ji-1,jj  ,ikt  ) + un(ji,jj,ikt  )   &
657                  &             -un(ji-1,jj  ,ikt+1) - un(ji,jj,ikt+1)  )
658               zdkv = zcoef * (  vn(ji  ,jj-1,ikt  ) + vn(ji,jj,ikt  )   &
659                  &             -vn(ji  ,jj-1,ikt+1) - vn(ji,jj,ikt+1)  )
660               !                                            ! richardson number (minimum value set to zero)
661               zRc = rn2(ji,jj,ikt+1) / ( zdku*zdku + zdkv*zdkv + 1.e-20 )
662
663      !! compute Pr and Sc number (can be improved)
664               zPr =   13.8
665               zSc = 2432.0
666
667      !! compute gamma mole
668               zgmolet = 12.5 * zPr ** (2.0/3.0) - 6.0
669               zgmoles = 12.5 * zSc ** (2.0/3.0) -6.0
670
671      !! compute bouyancy
672               zts(jp_tem) = ttbl(ji,jj)
673               zts(jp_sal) = stbl(ji,jj)
674               zdep        = fsdepw(ji,jj,ikt)
675               !
676               CALL eos_rab( zts, zdep, zab )
677                  !
678      !! compute length scale
679               zbuofdep = grav * ( zab(jp_tem) * zqhisf - zab(jp_sal) * zqwisf )  !!!!!!!!!!!!!!!!!!!!!!!!!!!!
680
681      !! compute Monin Obukov Length
682               ! Maximum boundary layer depth
683               zhmax = fsdept(ji,jj,mbkt(ji,jj)) - fsdepw(ji,jj,mikt(ji,jj)) -0.001
684               ! Compute Monin obukhov length scale at the surface and Ekman depth:
685               zmob   = zustar ** 3 / (vkarmn * (zbuofdep + epsln))
686               zmols  = SIGN(1._wp, zmob) * MIN(ABS(zmob), zhmax) * tmask(ji,jj,ikt)
687
688      !! compute eta* (stability parameter)
689               zetastar = 1 / ( SQRT(1 + MAX(zxsiN * zustar / ( ABS(ff(ji,jj)) * zmols * zRc ), 0.0)))
690
691      !! compute the sublayer thickness
692               zhnu = 5 * znu / zustar
693      !! compute gamma turb
694               zgturb = 1/vkarmn * LOG(zustar * zxsiN * zetastar * zetastar / ( ABS(ff(ji,jj)) * zhnu )) &
695               &      + 1 / ( 2 * zxsiN * zetastar ) - 1/vkarmn
696
697      !! compute gammats
698               gt = zustar / (zgturb + zgmolet)
699               gs = zustar / (zgturb + zgmoles)
700               END IF
701      END IF
702
703   END SUBROUTINE
704
705   SUBROUTINE sbc_isf_tbl( varin, varout, cptin )
706      !!----------------------------------------------------------------------
707      !!                  ***  SUBROUTINE sbc_isf_tbl  ***
708      !!
709      !! ** Purpose : compute mean T/S/U/V in the boundary layer
710      !!
711      !!----------------------------------------------------------------------
712      REAL(wp), DIMENSION(:,:,:), INTENT(in) :: varin
713      REAL(wp), DIMENSION(:,:)  , INTENT(out):: varout
714     
715      CHARACTER(len=1), INTENT(in) :: cptin ! point of variable in/out
716
717      REAL(wp) :: ze3, zhk
718      REAL(wp), DIMENSION(:,:), POINTER :: zikt
719
720      INTEGER :: ji,jj,jk
721      INTEGER :: ikt,ikb
722      INTEGER, DIMENSION(:,:), POINTER :: mkt, mkb
723
724      CALL wrk_alloc( jpi,jpj, mkt, mkb  )
725      CALL wrk_alloc( jpi,jpj, zikt )
726
727      ! get first and last level of tbl
728      mkt(:,:) = misfkt(:,:)
729      mkb(:,:) = misfkb(:,:)
730
731      varout(:,:)=0._wp
732      DO jj = 2,jpj
733         DO ji = 2,jpi
734            IF (ssmask(ji,jj) == 1) THEN
735               ikt = mkt(ji,jj)
736               ikb = mkb(ji,jj)
737
738               ! level fully include in the ice shelf boundary layer
739               DO jk = ikt, ikb - 1
740                  ze3 = fse3t_n(ji,jj,jk)
741                  IF (cptin == 'T' ) varout(ji,jj) = varout(ji,jj) + varin(ji,jj,jk) * r1_hisf_tbl(ji,jj) * ze3
742                  IF (cptin == 'U' ) varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,jk) + varin(ji-1,jj,jk)) &
743                     &                                                       * r1_hisf_tbl(ji,jj) * ze3
744                  IF (cptin == 'V' ) varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,jk) + varin(ji,jj-1,jk)) &
745                     &                                                       * r1_hisf_tbl(ji,jj) * ze3
746               END DO
747
748               ! level partially include in ice shelf boundary layer
749               zhk = SUM( fse3t_n(ji, jj, ikt:ikb - 1)) * r1_hisf_tbl(ji,jj)
750               IF (cptin == 'T') &
751                   &  varout(ji,jj) = varout(ji,jj) + varin(ji,jj,ikb) * (1._wp - zhk)
752               IF (cptin == 'U') &
753                   &  varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,ikb) + varin(ji-1,jj,ikb)) * (1._wp - zhk)
754               IF (cptin == 'V') &
755                   &  varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,ikb) + varin(ji,jj-1,ikb)) * (1._wp - zhk)
756            END IF
757         END DO
758      END DO
759
760      CALL wrk_dealloc( jpi,jpj, mkt, mkb )     
761      CALL wrk_dealloc( jpi,jpj, zikt ) 
762
763      IF (cptin == 'T') CALL lbc_lnk(varout,'T',1.)
764      IF (cptin == 'U' .OR. cptin == 'V') CALL lbc_lnk(varout,'T',-1.)
765
766   END SUBROUTINE sbc_isf_tbl
767     
768
769   SUBROUTINE sbc_isf_div( phdivn )
770      !!----------------------------------------------------------------------
771      !!                  ***  SUBROUTINE sbc_isf_div  ***
772      !!       
773      !! ** Purpose :   update the horizontal divergence with the runoff inflow
774      !!
775      !! ** Method  :   
776      !!                CAUTION : risf_tsc(:,:,jp_sal) is negative (outflow) increase the
777      !!                          divergence and expressed in m/s
778      !!
779      !! ** Action  :   phdivn   decreased by the runoff inflow
780      !!----------------------------------------------------------------------
781      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   phdivn   ! horizontal divergence
782      !!
783      INTEGER  ::   ji, jj, jk   ! dummy loop indices
784      INTEGER  ::   ikt, ikb 
785      INTEGER  ::   nk_isf
786      REAL(wp)     ::   zhk, z1_hisf_tbl, zhisf_tbl
787      REAL(wp)     ::   zfact     ! local scalar
788      !!----------------------------------------------------------------------
789      !
790      zfact   = 0.5_wp
791      !
792      IF (lk_vvl) THEN     ! need to re compute level distribution of isf fresh water
793         DO jj = 1,jpj
794            DO ji = 1,jpi
795               ikt = misfkt(ji,jj)
796               ikb = misfkt(ji,jj)
797               ! thickness of boundary layer at least the top level thickness
798               rhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), fse3t(ji,jj,ikt))
799
800               ! determine the deepest level influenced by the boundary layer
801               ! test on tmask useless ?????
802               DO jk = ikt, mbkt(ji,jj)
803!                  IF ( (SUM(fse3t(ji,jj,ikt:jk-1)) .LT. rhisf_tbl(ji,jj)) .AND. (tmask(ji,jj,jk) == 1) ) ikb = jk
804               END DO
805               rhisf_tbl(ji,jj) = MIN(rhisf_tbl(ji,jj), SUM(fse3t(ji,jj,ikt:ikb)))  ! limit the tbl to water thickness.
806               misfkb(ji,jj) = ikb                                                  ! last wet level of the tbl
807               r1_hisf_tbl(ji,jj) = 1._wp / rhisf_tbl(ji,jj)
808
809               zhk           = SUM( fse3t(ji, jj, ikt:ikb - 1)) * r1_hisf_tbl(ji,jj)  ! proportion of tbl cover by cell from ikt to ikb - 1
810               ralpha(ji,jj) = rhisf_tbl(ji,jj) * (1._wp - zhk ) / fse3t(ji,jj,ikb)  ! proportion of bottom cell influenced by boundary layer
811            END DO
812         END DO
813      END IF ! vvl case
814      !
815      DO jj = 1,jpj
816         DO ji = 1,jpi
817               ikt = misfkt(ji,jj)
818               ikb = misfkb(ji,jj)
819               ! level fully include in the ice shelf boundary layer
820               DO jk = ikt, ikb - 1
821                  phdivn(ji,jj,jk) = phdivn(ji,jj,jk) + ( fwfisf(ji,jj) + fwfisf_b(ji,jj) ) &
822                    &               * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact
823               END DO
824               ! level partially include in ice shelf boundary layer
825               phdivn(ji,jj,ikb) = phdivn(ji,jj,ikb) + ( fwfisf(ji,jj) &
826                  &             + fwfisf_b(ji,jj) ) * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact * ralpha(ji,jj) 
827            !==   ice shelf melting mass distributed over several levels   ==!
828         END DO
829      END DO
830      !
831   END SUBROUTINE sbc_isf_div
832                       
833   FUNCTION tinsitu( ptem, psal, ppress ) RESULT( pti )
834      !!----------------------------------------------------------------------
835      !!                 ***  ROUTINE eos_init  ***
836      !!
837      !! ** Purpose :   Compute the in-situ temperature [Celcius]
838      !!
839      !! ** Method  :   
840      !!
841      !! Reference  :   Bryden,h.,1973,deep-sea res.,20,401-408
842      !!----------------------------------------------------------------------
843      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) ::   ptem   ! potential temperature [Celcius]
844      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) ::   psal   ! salinity             [psu]
845      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) ::   ppress ! pressure             [dBar]
846      REAL(wp), DIMENSION(:,:), POINTER           ::   pti    ! in-situ temperature [Celcius]
847!      REAL(wp) :: fsatg
848!      REAL(wp) :: pfps, pfpt, pfphp
849      REAL(wp) :: zt, zs, zp, zh, zq, zxk
850      INTEGER  :: ji, jj            ! dummy loop indices
851      !
852      CALL wrk_alloc( jpi,jpj, pti  )
853      !
854      DO jj=1,jpj
855         DO ji=1,jpi
856            zh = ppress(ji,jj)
857! Theta1
858            zt = ptem(ji,jj)
859            zs = psal(ji,jj)
860            zp = 0.0
861            zxk= zh * fsatg( zs, zt, zp )
862            zt = zt + 0.5 * zxk
863            zq = zxk
864! Theta2
865            zp = zp + 0.5 * zh
866            zxk= zh*fsatg( zs, zt, zp )
867            zt = zt + 0.29289322 * ( zxk - zq )
868            zq = 0.58578644 * zxk + 0.121320344 * zq
869! Theta3
870            zxk= zh * fsatg( zs, zt, zp )
871            zt = zt + 1.707106781 * ( zxk - zq )
872            zq = 3.414213562 * zxk - 4.121320344 * zq
873! Theta4
874            zp = zp + 0.5 * zh
875            zxk= zh * fsatg( zs, zt, zp )
876            pti(ji,jj) = zt + ( zxk - 2.0 * zq ) / 6.0
877         END DO
878      END DO
879      !
880      CALL wrk_dealloc( jpi,jpj, pti  )
881      !
882   END FUNCTION tinsitu
883   !
884   FUNCTION fsatg( pfps, pfpt, pfphp )
885      !!----------------------------------------------------------------------
886      !!                 ***  FUNCTION fsatg  ***
887      !!
888      !! ** Purpose    :   Compute the Adiabatic laspse rate [Celcius].[decibar]^-1
889      !!
890      !! ** Reference  :   Bryden,h.,1973,deep-sea res.,20,401-408
891      !!
892      !! ** units      :   pressure        pfphp    decibars
893      !!                   temperature     pfpt     deg celsius (ipts-68)
894      !!                   salinity        pfps     (ipss-78)
895      !!                   adiabatic       fsatg    deg. c/decibar
896      !!----------------------------------------------------------------------
897      REAL(wp) :: pfps, pfpt, pfphp 
898      REAL(wp) :: fsatg
899      !
900      fsatg = (((-2.1687e-16*pfpt+1.8676e-14)*pfpt-4.6206e-13)*pfphp         &
901        &    +((2.7759e-12*pfpt-1.1351e-10)*(pfps-35.)+((-5.4481e-14*pfpt    &
902        &    +8.733e-12)*pfpt-6.7795e-10)*pfpt+1.8741e-8))*pfphp             &
903        &    +(-4.2393e-8*pfpt+1.8932e-6)*(pfps-35.)                         &
904        &    +((6.6228e-10*pfpt-6.836e-8)*pfpt+8.5258e-6)*pfpt+3.5803e-5
905      !
906    END FUNCTION fsatg
907    !!======================================================================
908END MODULE sbcisf
Note: See TracBrowser for help on using the repository browser.