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

source: branches/NERC/dev_r5589_is_oce_cpl/NEMOGCM/NEMO/OPA_SRC/SBC/sbcisf.F90 @ 5619

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

ocean/ice sheet coupling: initial commit

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