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.
limthd_dh.F90 in trunk/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: trunk/NEMOGCM/NEMO/LIM_SRC_3/limthd_dh.F90 @ 2760

Last change on this file since 2760 was 2715, checked in by rblod, 13 years ago

First attempt to put dynamic allocation on the trunk

  • Property svn:keywords set to Id
File size: 35.3 KB
Line 
1MODULE limthd_dh
2   !!======================================================================
3   !!                       ***  MODULE limthd_dh ***
4   !!  LIM-3 :   thermodynamic growth and decay of the ice
5   !!======================================================================
6   !! History :  LIM  ! 2003-05 (M. Vancoppenolle) Original code in 1D
7   !!                 ! 2005-06 (M. Vancoppenolle) 3D version
8   !!            3.2  ! 2009-07 (M. Vancoppenolle, Y. Aksenov, G. Madec) bug correction in rdmsnif & rdmicif
9   !!            4.0  ! 2011-02 (G. Madec) dynamical allocation
10   !!----------------------------------------------------------------------
11#if defined key_lim3
12   !!----------------------------------------------------------------------
13   !!   'key_lim3'                                      LIM3 sea-ice model
14   !!----------------------------------------------------------------------
15   !!   lim_thd_dh  : vertical accr./abl. and lateral ablation of sea ice
16   !!----------------------------------------------------------------------
17   USE par_oce          ! ocean parameters
18   USE phycst           ! physical constants (OCE directory)
19   USE sbc_oce          ! Surface boundary condition: ocean fields
20   USE ice              ! LIM variables
21   USE par_ice          ! LIM parameters
22   USE thd_ice          ! LIM thermodynamics
23   USE wrk_nemo         ! workspace manager
24   USE in_out_manager   ! I/O manager
25   USE lib_mpp          ! MPP library
26
27   IMPLICIT NONE
28   PRIVATE
29
30   PUBLIC   lim_thd_dh   ! called by lim_thd
31
32   REAL(wp) ::   epsi20 = 1e-20   ! constant values
33   REAL(wp) ::   epsi13 = 1e-13   !
34   REAL(wp) ::   epsi16 = 1e-16   !
35   REAL(wp) ::   zzero  = 0.e0    !
36   REAL(wp) ::   zone   = 1.e0    !
37
38   !!----------------------------------------------------------------------
39   !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2010)
40   !! $Id$
41   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
42   !!----------------------------------------------------------------------
43CONTAINS
44
45   SUBROUTINE lim_thd_dh( kideb, kiut, jl )
46      !!------------------------------------------------------------------
47      !!                ***  ROUTINE lim_thd_dh  ***
48      !!
49      !! ** Purpose :   determines variations of ice and snow thicknesses.
50      !!
51      !! ** Method  :   Ice/Snow surface melting arises from imbalance in surface fluxes
52      !!              Bottom accretion/ablation arises from flux budget
53      !!              Snow thickness can increase by precipitation and decrease by sublimation
54      !!              If snow load excesses Archmiede limit, snow-ice is formed by
55      !!              the flooding of sea-water in the snow
56      !!
57      !!                 1) Compute available flux of heat for surface ablation
58      !!                 2) Compute snow and sea ice enthalpies
59      !!                 3) Surface ablation and sublimation
60      !!                 4) Bottom accretion/ablation
61      !!                 5) Case of Total ablation
62      !!                 6) Snow ice formation
63      !!
64      !! References : Bitz and Lipscomb, 1999, J. Geophys. Res.
65      !!              Fichefet T. and M. Maqueda 1997, J. Geophys. Res., 102(C6), 12609-12646   
66      !!              Vancoppenolle, Fichefet and Bitz, 2005, Geophys. Res. Let.
67      !!              Vancoppenolle et al.,2009, Ocean Modelling
68      !!------------------------------------------------------------------
69      INTEGER , INTENT(in) ::   kideb, kiut   ! Start/End point on which the  the computation is applied
70      INTEGER , INTENT(in) ::   jl            ! Thickness cateogry number
71      !!
72      INTEGER  ::   ji , jk        ! dummy loop indices
73      INTEGER  ::   zji, zjj       ! 2D corresponding indices to ji
74      INTEGER  ::   isnow          ! switch for presence (1) or absence (0) of snow
75      INTEGER  ::   isnowic        ! snow ice formation not
76      INTEGER  ::   i_ice_switch   ! ice thickness above a certain treshold or not
77      INTEGER  ::   iter
78      INTEGER  ::   num_iter_max, numce_dh
79
80      REAL(wp) ::   meance_dh
81      REAL(wp) ::   zzfmass_i, zihgnew                     ! local scalar
82      REAL(wp) ::   zzfmass_s, zhsnew, ztmelts             ! local scalar
83      REAL(wp) ::   zhn, zdhcf, zdhbf, zhni, zhnfi, zihg   !
84      REAL(wp) ::   zdhnm, zhnnew, zhisn, zihic, zzc       !
85      REAL(wp) ::   zfracs       ! fractionation coefficient for bottom salt entrapment
86      REAL(wp) ::   zds          ! increment of bottom ice salinity
87      REAL(wp) ::   zcoeff       ! dummy argument for snowfall partitioning over ice and leads
88      REAL(wp) ::   zsm_snowice  ! snow-ice salinity
89      REAL(wp) ::   zswi1        ! switch for computation of bottom salinity
90      REAL(wp) ::   zswi12       ! switch for computation of bottom salinity
91      REAL(wp) ::   zswi2        ! switch for computation of bottom salinity
92      REAL(wp) ::   zgrr         ! bottom growth rate
93      REAL(wp) ::   ztform       ! bottom formation temperature
94      !
95      REAL(wp), POINTER, DIMENSION(:) ::   zh_i, ztfs  , zqfont_su, zqprec  , zhgnew
96      REAL(wp), POINTER, DIMENSION(:) ::   zh_s, zhsold, zqfont_bo, z_f_surf, zfmass_i
97      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_mel, zdh_s_sub  , zfdt_init , zqt_i, zqt_dummy, zdq_i
98      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_pre, zfsalt_melt, zfdt_final, zqt_s, zfbase   , zinnermelt
99      !
100      REAL(wp), DIMENSION(jpij,jkmax) ::   zdeltah
101      REAL(wp), DIMENSION(jpij,jkmax) ::   zqt_i_lay   ! total ice heat content
102      !!------------------------------------------------------------------
103
104      IF( wrk_in_use(1, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22) ) THEN
105         CALL ctl_stop('lim_thd_dh: requestead workspace arrays unavailable')   ;   RETURN
106      ENDIF
107      ! Set-up pointers to sub-arrays of workspace arrays
108      zh_i        => wrk_1d_1 (1:jpij)   ! ice layer thickness
109      zh_s        => wrk_1d_2 (1:jpij)   ! snow layer thickness
110      ztfs        => wrk_1d_3 (1:jpij)   ! melting point
111      zhsold      => wrk_1d_4 (1:jpij)   ! old snow thickness
112      zqprec      => wrk_1d_5 (1:jpij)   ! energy of fallen snow
113      zqfont_su   => wrk_1d_6 (1:jpij)   ! incoming, remaining surface energy
114      zqfont_bo   => wrk_1d_7 (1:jpij)   ! incoming, bottom energy
115      z_f_surf    => wrk_1d_8 (1:jpij)   ! surface heat for ablation
116      zhgnew      => wrk_1d_9 (1:jpij)   ! new ice thickness
117      zfmass_i    => wrk_1d_10(1:jpij)   !
118      !
119      zdh_s_mel   => wrk_1d_11(1:jpij)   ! snow melt
120      zdh_s_pre   => wrk_1d_12(1:jpij)   ! snow precipitation
121      zdh_s_sub   => wrk_1d_13(1:jpij)   ! snow sublimation
122      zfsalt_melt => wrk_1d_14(1:jpij)   ! salt flux due to ice melt
123      !
124      !                              ! Pathological cases
125      zfdt_init   => wrk_1d_15(1:jpij)   ! total incoming heat for ice melt
126      zfdt_final  => wrk_1d_16(1:jpij)   ! total remaing heat for ice melt
127      zqt_i       => wrk_1d_17(1:jpij)   ! total ice heat content
128      zqt_s       => wrk_1d_18(1:jpij)   ! total snow heat content
129      zqt_dummy   => wrk_1d_19(1:jpij)   ! dummy heat content
130           
131      zfbase      => wrk_1d_20(1:jpij)       
132      zdq_i       => wrk_1d_21(1:jpij) 
133      zinnermelt  => wrk_1d_22(1:jpij) 
134
135      zfsalt_melt(:)  = 0._wp
136      ftotal_fin(:)   = 0._wp
137      zfdt_init(:)    = 0._wp
138      zfdt_final(:)   = 0._wp
139
140      DO ji = kideb, kiut
141         old_ht_i_b(ji) = ht_i_b(ji)
142         old_ht_s_b(ji) = ht_s_b(ji)
143      END DO
144      !
145      !------------------------------------------------------------------------------!
146      !  1) Calculate available heat for surface ablation                            !
147      !------------------------------------------------------------------------------!
148      !
149      DO ji = kideb, kiut
150         isnow         = INT( 1.0 - MAX ( 0.0 , SIGN ( 1.0 , - ht_s_b(ji) ) ) )
151         ztfs(ji)      = isnow * rtt + ( 1.0 - isnow ) * rtt
152         z_f_surf(ji)  = qnsr_ice_1d(ji) + ( 1.0 - i0(ji) ) * qsr_ice_1d(ji) - fc_su(ji)
153         z_f_surf(ji)  = MAX( zzero , z_f_surf(ji) ) * MAX( zzero , SIGN( zone , t_su_b(ji) - ztfs(ji) ) )
154         zfdt_init(ji) = ( z_f_surf(ji) + MAX( fbif_1d(ji) + qlbbq_1d(ji) + fc_bo_i(ji),0.0 ) ) * rdt_ice
155      END DO ! ji
156
157      zqfont_su  (:) = 0._wp
158      zqfont_bo  (:) = 0._wp
159      dsm_i_se_1d(:) = 0._wp     
160      dsm_i_si_1d(:) = 0._wp   
161      !
162      !------------------------------------------------------------------------------!
163      !  2) Computing layer thicknesses and  snow and sea-ice enthalpies.            !
164      !------------------------------------------------------------------------------!
165      !
166      DO ji = kideb, kiut     ! Layer thickness
167         zh_i(ji) = ht_i_b(ji) / nlay_i
168         zh_s(ji) = ht_s_b(ji) / nlay_s
169      END DO
170      !
171      zqt_s(:) = 0._wp        ! Total enthalpy of the snow
172      DO jk = 1, nlay_s
173         DO ji = kideb, kiut
174            zqt_s(ji) =  zqt_s(ji) + q_s_b(ji,jk) * ht_s_b(ji) / nlay_s
175         END DO
176      END DO
177      !
178      zqt_i(:) = 0._wp        ! Total enthalpy of the ice
179      DO jk = 1, nlay_i
180         DO ji = kideb, kiut
181            zzc = q_i_b(ji,jk) * ht_i_b(ji) / nlay_i
182            zqt_i(ji)        =  zqt_i(ji) + zzc
183            zqt_i_lay(ji,jk) =              zzc
184         END DO
185      END DO
186      !
187      !------------------------------------------------------------------------------|
188      !  3) Surface ablation and sublimation                                         |
189      !------------------------------------------------------------------------------|
190      !
191      !-------------------------
192      ! 3.1 Snow precips / melt
193      !-------------------------
194      ! Snow accumulation in one thermodynamic time step
195      ! snowfall is partitionned between leads and ice
196      ! if snow fall was uniform, a fraction (1-at_i) would fall into leads
197      ! but because of the winds, more snow falls on leads than on sea ice
198      ! and a greater fraction (1-at_i)^beta of the total mass of snow
199      ! (beta < 1) falls in leads.
200      ! In reality, beta depends on wind speed,
201      ! and should decrease with increasing wind speed but here, it is
202      ! considered as a constant. an average value is 0.66
203      ! Martin Vancoppenolle, December 2006
204
205      ! Snow fall
206      DO ji = kideb, kiut
207         zcoeff = ( 1.0 - ( 1.0 - at_i_b(ji) )**betas ) / at_i_b(ji) 
208         zdh_s_pre(ji) = zcoeff * sprecip_1d(ji) * rdt_ice / rhosn
209      END DO
210      zdh_s_mel(:) =  0._wp
211
212      ! Melt of fallen snow
213      DO ji = kideb, kiut
214         ! tatm_ice is now in K
215         zqprec   (ji)   =  rhosn * ( cpic * ( rtt - tatm_ice_1d(ji) ) + lfus ) 
216         zqfont_su(ji)   =  z_f_surf(ji) * rdt_ice
217         zdeltah  (ji,1) =  MIN( 0.e0 , - zqfont_su(ji) / MAX( zqprec(ji) , epsi13 ) )
218         zqfont_su(ji)   =  MAX( 0.e0 , - zdh_s_pre(ji) - zdeltah(ji,1)              ) * zqprec(ji)
219         zdeltah  (ji,1) =  MAX( - zdh_s_pre(ji) , zdeltah(ji,1) )
220         zdh_s_mel(ji)   =  zdh_s_mel(ji) + zdeltah(ji,1)
221         ! heat conservation
222         qt_s_in(ji,jl)  =  qt_s_in(ji,jl) + zqprec(ji) * zdh_s_pre(ji)
223         zqt_s  (ji)     =  zqt_s  (ji)    + zqprec(ji) * zdh_s_pre(ji)
224         zqt_s  (ji)     =  MAX( zqt_s(ji) - zqfont_su(ji) , 0.e0 ) 
225      END DO
226
227
228      ! Snow melt due to surface heat imbalance
229      DO jk = 1, nlay_s
230         DO ji = kideb, kiut
231            zdeltah  (ji,jk) = - zqfont_su(ji) / q_s_b(ji,jk)
232            zqfont_su(ji)    =  MAX( 0.0 , - zh_s(ji) - zdeltah(ji,jk) ) * q_s_b(ji,jk) 
233            zdeltah  (ji,jk) =  MAX( zdeltah(ji,jk) , - zh_s(ji) )
234            zdh_s_mel(ji)    =  zdh_s_mel(ji) + zdeltah(ji,jk)        ! resulting melt of snow   
235         END DO
236      END DO
237
238      ! Apply snow melt to snow depth
239      DO ji = kideb, kiut
240         dh_s_tot(ji)   =  zdh_s_mel(ji) + zdh_s_pre(ji)
241         ! Old and new snow depths
242         zhsold(ji)     =  ht_s_b(ji)
243         zhsnew         =  ht_s_b(ji) + dh_s_tot(ji)
244         ! If snow is still present zhn = 1, else zhn = 0
245         zhn            =  1.0 - MAX( zzero , SIGN( zone , - zhsnew ) )
246         ht_s_b(ji)     =  MAX( zzero , zhsnew )
247         ! Volume and mass variations of snow
248         dvsbq_1d  (ji) =  a_i_b(ji) * ( ht_s_b(ji) - zhsold(ji) - zdh_s_mel(ji) )
249         dvsbq_1d  (ji) =  MIN( zzero, dvsbq_1d(ji) )
250         rdmsnif_1d(ji) =  rdmsnif_1d(ji) + rhosn * dvsbq_1d(ji)
251      END DO ! ji
252
253      !--------------------------
254      ! 3.2 Surface ice ablation
255      !--------------------------
256      DO ji = kideb, kiut 
257         dh_i_surf(ji) =  0._wp
258         z_f_surf (ji) =  zqfont_su(ji) / rdt_ice ! heat conservation test
259         zdq_i    (ji) =  0._wp
260      END DO ! ji
261
262      DO jk = 1, nlay_i
263         DO ji = kideb, kiut 
264            !                                                    ! melt of layer jk
265            zdeltah  (ji,jk) = - zqfont_su(ji) / q_i_b(ji,jk)
266            !                                                    ! recompute heat available
267            zqfont_su(ji)    = MAX( 0.0 , - zh_i(ji) - zdeltah(ji,jk) ) * q_i_b(ji,jk) 
268            !                                                    ! melt of layer jk cannot be higher than its thickness
269            zdeltah  (ji,jk) = MAX( zdeltah(ji,jk) , - zh_i(ji) )
270            !                                                    ! update surface melt
271            dh_i_surf(ji)    = dh_i_surf(ji) + zdeltah(ji,jk) 
272            !                                                    ! for energy conservation
273            zdq_i    (ji)    = zdq_i(ji) + zdeltah(ji,jk) * q_i_b(ji,jk) / rdt_ice
274            !
275            ! contribution to ice-ocean salt flux
276            zji = MOD( npb(ji) - 1 , jpi ) + 1
277            zjj =    ( npb(ji) - 1 ) / jpi + 1
278            zfsalt_melt(ji) = zfsalt_melt(ji) + ( sss_m(zji,zjj) - sm_i_b(ji) ) * a_i_b(ji)    &
279               &                              * MIN( zdeltah(ji,jk) , 0.e0 ) * rhoic / rdt_ice 
280         END DO
281      END DO
282
283      !                     !-------------------
284      IF( con_i ) THEN      ! Conservation test
285         !                  !-------------------
286         numce_dh  = 0
287         meance_dh = 0._wp
288         DO ji = kideb, kiut
289            IF ( ( z_f_surf(ji) + zdq_i(ji) ) .GE. 1.0e-3 ) THEN
290               numce_dh  = numce_dh + 1
291               meance_dh = meance_dh + z_f_surf(ji) + zdq_i(ji)
292            ENDIF
293            IF( z_f_surf(ji) + zdq_i(ji) .GE. 1.0e-3  ) THEN!
294               WRITE(numout,*) ' ALERTE heat loss for surface melt '
295               WRITE(numout,*) ' zji, zjj, jl :', zji, zjj, jl
296               WRITE(numout,*) ' ht_i_b       : ', ht_i_b(ji)
297               WRITE(numout,*) ' z_f_surf     : ', z_f_surf(ji)
298               WRITE(numout,*) ' zdq_i        : ', zdq_i(ji)
299               WRITE(numout,*) ' ht_i_b       : ', ht_i_b(ji)
300               WRITE(numout,*) ' fc_bo_i      : ', fc_bo_i(ji)
301               WRITE(numout,*) ' fbif_1d      : ', fbif_1d(ji)
302               WRITE(numout,*) ' qlbbq_1d     : ', qlbbq_1d(ji)
303               WRITE(numout,*) ' s_i_new      : ', s_i_new(ji)
304               WRITE(numout,*) ' sss_m        : ', sss_m(zji,zjj)
305            ENDIF
306         END DO
307         !
308         IF( numce_dh > 0 )   meance_dh = meance_dh / numce_dh
309         WRITE(numout,*) ' Error report - Category : ', jl
310         WRITE(numout,*) ' ~~~~~~~~~~~~ '
311         WRITE(numout,*) ' Number of points where there is sur. me. error : ', numce_dh
312         WRITE(numout,*) ' Mean basal growth error on error points : ', meance_dh
313         !
314      ENDIF
315
316      !----------------------
317      ! 3.3 Snow sublimation
318      !----------------------
319
320      DO ji = kideb, kiut
321         ! if qla is positive (upwards), heat goes to the atmosphere, therefore
322         ! snow sublimates, if qla is negative (downwards), snow condensates
323         zdh_s_sub(ji)    =  - parsub * qla_ice_1d(ji) / ( rhosn * lsub ) * rdt_ice
324         dh_s_tot (ji)    =  dh_s_tot(ji) + zdh_s_sub(ji)
325         zdhcf            =  ht_s_b(ji) + zdh_s_sub(ji) 
326         ht_s_b   (ji)    =  MAX( zzero , zdhcf )
327         ! we recompute dh_s_tot
328         dh_s_tot (ji)    =  ht_s_b(ji) - zhsold(ji)
329         qt_s_in  (ji,jl) =  qt_s_in(ji,jl) + zdh_s_sub(ji)*q_s_b(ji,1)
330      END DO
331
332      zqt_dummy(:) = 0.e0
333      DO jk = 1, nlay_s
334         DO ji = kideb,kiut
335            q_s_b    (ji,jk) = rhosn * ( cpic * ( rtt - t_s_b(ji,jk) ) + lfus )
336            zqt_dummy(ji)    =  zqt_dummy(ji) + q_s_b(ji,jk) * ht_s_b(ji) / nlay_s            ! heat conservation
337         END DO
338      END DO
339
340      DO jk = 1, nlay_s
341         DO ji = kideb, kiut
342            ! In case of disparition of the snow, we have to update the snow temperatures
343            zhisn  =  MAX( zzero , SIGN( zone, - ht_s_b(ji) ) )
344            t_s_b(ji,jk) = ( 1.0 - zhisn ) * t_s_b(ji,jk) + zhisn * rtt
345            q_s_b(ji,jk) = ( 1.0 - zhisn ) * q_s_b(ji,jk)
346         END DO
347      END DO
348
349      !
350      !------------------------------------------------------------------------------!
351      ! 4) Basal growth / melt                                                       !
352      !------------------------------------------------------------------------------!
353      !
354      ! Ice basal growth / melt is given by the ratio of heat budget over basal
355      ! ice heat content.  Basal heat budget is given by the difference between
356      ! the inner conductive flux  (fc_bo_i), from the open water heat flux
357      ! (qlbbqb) and the turbulent ocean flux (fbif).
358      ! fc_bo_i is positive downwards. fbif and qlbbq are positive to the ice
359
360      !-----------------------------------------------------
361      ! 4.1 Basal growth - (a) salinity not varying in time
362      !-----------------------------------------------------
363      IF(  num_sal /= 2  .AND.  num_sal /= 4  ) THEN
364         DO ji = kideb, kiut
365            IF(  ( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) < 0.0  ) THEN
366               s_i_new(ji)         =  sm_i_b(ji)
367               ! Melting point in K
368               ztmelts             =  - tmut * s_i_new(ji) + rtt 
369               ! New ice heat content (Bitz and Lipscomb, 1999)
370               ztform              =  t_i_b(ji,nlay_i)  ! t_bo_b crashes in the
371               ! Baltic
372               q_i_b(ji,nlay_i+1)  = rhoic * (  cpic * ( ztmelts - ztform )                                &
373                  &                           + lfus * (  1.0 - ( ztmelts - rtt ) / ( ztform - rtt )  )    &
374                  &                           - rcp  * ( ztmelts - rtt )                                 )
375               ! Basal growth rate = - F*dt / q
376               dh_i_bott(ji)       =  - rdt_ice*( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) / q_i_b(ji,nlay_i+1) 
377            ENDIF
378         END DO
379      ENDIF
380
381      !-------------------------------------------------
382      ! 4.1 Basal growth - (b) salinity varying in time
383      !-------------------------------------------------
384      IF(  num_sal == 2 .OR.  num_sal == 4  ) THEN
385         ! the growth rate (dh_i_bott) is function of the new ice
386         ! heat content (q_i_b(nlay_i+1)). q_i_b depends on the new ice
387         ! salinity (snewice). snewice depends on dh_i_bott
388         ! it converges quickly, so, no problem
389         ! See Vancoppenolle et al., OM08 for more info on this
390
391         ! Initial value (tested 1D, can be anything between 1 and 20)
392         num_iter_max = 4
393         s_i_new(:)   = 4.0
394
395         ! Iterative procedure
396         DO iter = 1, num_iter_max
397            DO ji = kideb, kiut
398               IF(  fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) < 0.e0  ) THEN
399                  zji = MOD( npb(ji) - 1, jpi ) + 1
400                  zjj = ( npb(ji) - 1 ) / jpi + 1
401                  ! Melting point in K
402                  ztmelts             =   - tmut * s_i_new(ji) + rtt 
403                  ! New ice heat content (Bitz and Lipscomb, 1999)
404                  q_i_b(ji,nlay_i+1)  =  rhoic * (  cpic * ( ztmelts - t_bo_b(ji) )                             &
405                     &                            + lfus * ( 1.0 - ( ztmelts - rtt ) / ( t_bo_b(ji) - rtt ) )   &
406                     &                            - rcp * ( ztmelts-rtt )                                     )
407                  ! Bottom growth rate = - F*dt / q
408                  dh_i_bott(ji) =  - rdt_ice * ( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) / q_i_b(ji,nlay_i+1)
409                  ! New ice salinity ( Cox and Weeks, JGR, 1988 )
410                  ! zswi2  (1) if dh_i_bott/rdt .GT. 3.6e-7
411                  ! zswi12 (1) if dh_i_bott/rdt .LT. 3.6e-7 and .GT. 2.0e-8
412                  ! zswi1  (1) if dh_i_bott/rdt .LT. 2.0e-8
413                  zgrr   = MIN( 1.0e-3, MAX ( dh_i_bott(ji) / rdt_ice , epsi13 ) )
414                  zswi2  = MAX( zzero , SIGN( zone , zgrr - 3.6e-7 ) ) 
415                  zswi12 = MAX( zzero , SIGN( zone , zgrr - 2.0e-8 ) ) * ( 1.0 - zswi2 )
416                  zswi1  = 1. - zswi2 * zswi12 
417                  zfracs = zswi1  * 0.12 + zswi12 * ( 0.8925 + 0.0568 * LOG( 100.0 * zgrr ) )   &
418                     &                   + zswi2  * 0.26 / ( 0.26 + 0.74 * EXP ( - 724300.0 * zgrr ) ) 
419                  zds         = zfracs * sss_m(zji,zjj) - s_i_new(ji)
420                  s_i_new(ji) = zfracs * sss_m(zji,zjj)
421               ENDIF ! fc_bo_i
422            END DO ! ji
423         END DO ! iter
424
425         ! Final values
426         DO ji = kideb, kiut
427            IF( ( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) .LT. 0.0  ) THEN
428               ! New ice salinity must not exceed 15 psu
429               s_i_new(ji) = MIN( s_i_new(ji), s_i_max )
430               ! Metling point in K
431               ztmelts     =   - tmut * s_i_new(ji) + rtt 
432               ! New ice heat content (Bitz and Lipscomb, 1999)
433               q_i_b(ji,nlay_i+1)  =  rhoic * (  cpic * ( ztmelts - t_bo_b(ji) )                              &
434                  &                            + lfus * ( 1.0 - ( ztmelts - rtt ) / ( t_bo_b(ji) - rtt ) )    &
435                  &                            - rcp * ( ztmelts - rtt )                                    )
436               ! Basal growth rate = - F*dt / q
437               dh_i_bott(ji)       =  - rdt_ice*( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) / q_i_b(ji,nlay_i+1) 
438               ! Salinity update
439               ! entrapment during bottom growth
440               dsm_i_se_1d(ji) = ( s_i_new(ji) * dh_i_bott(ji) + sm_i_b(ji) * ht_i_b(ji) )    &
441                  &            / MAX( ht_i_b(ji) + dh_i_bott(ji) ,epsi13 ) - sm_i_b(ji)
442            ENDIF ! heat budget
443         END DO
444      ENDIF
445
446      !----------------
447      ! 4.2 Basal melt
448      !----------------
449      meance_dh = 0._wp
450      numce_dh  = 0
451      zinnermelt(:) = 0._wp
452
453      DO ji = kideb, kiut
454         ! heat convergence at the surface > 0
455         IF(  ( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) >= 0._wp  ) THEN
456            s_i_new(ji)   =  s_i_b(ji,nlay_i)
457            zqfont_bo(ji) =  rdt_ice * ( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) )
458            zfbase(ji)    =  zqfont_bo(ji) / rdt_ice     ! heat conservation test
459            zdq_i(ji)     =  0._wp
460            dh_i_bott(ji) =  0._wp
461         ENDIF
462      END DO
463
464      DO jk = nlay_i, 1, -1
465         DO ji = kideb, kiut
466            IF (  ( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) .GE. 0.0  ) THEN
467               ztmelts            =   - tmut * s_i_b(ji,jk) + rtt 
468               IF( t_i_b(ji,jk) >= ztmelts ) THEN
469                  zdeltah(ji,jk)  = - zh_i(ji)
470                  dh_i_bott(ji)   = dh_i_bott(ji) + zdeltah(ji,jk)
471                  zinnermelt(ji)   = 1._wp
472               ELSE  ! normal ablation
473                  zdeltah(ji,jk)  = - zqfont_bo(ji) / q_i_b(ji,jk)
474                  zqfont_bo(ji)   = MAX( 0.0 , - zh_i(ji) - zdeltah(ji,jk) ) * q_i_b(ji,jk)
475                  zdeltah(ji,jk)  = MAX(zdeltah(ji,jk), - zh_i(ji) )
476                  dh_i_bott(ji)   = dh_i_bott(ji) + zdeltah(ji,jk)
477                  zdq_i(ji)       = zdq_i(ji) + zdeltah(ji,jk) * q_i_b(ji,jk) / rdt_ice
478                  ! contribution to salt flux
479                  zji             = MOD( npb(ji) - 1, jpi ) + 1
480                  zjj             = ( npb(ji) - 1 ) / jpi + 1
481                  zfsalt_melt(ji) = zfsalt_melt(ji) + ( sss_m(zji,zjj) - sm_i_b(ji)   ) * a_i_b(ji)   &
482                     &                              * MIN( zdeltah(ji,jk) , 0.0 ) * rhoic / rdt_ice 
483               ENDIF
484            ENDIF
485         END DO ! ji
486      END DO ! jk
487
488      !                     !-------------------
489      IF( con_i ) THEN      ! Conservation test
490      !                     !-------------------
491         DO ji = kideb, kiut
492            IF(  ( fc_bo_i(ji) + fbif_1d(ji) + qlbbq_1d(ji) ) >= 0.e0  ) THEN
493               IF( ( zfbase(ji) + zdq_i(ji) ) >= 1.e-3 ) THEN
494                  numce_dh  = numce_dh + 1
495                  meance_dh = meance_dh + zfbase(ji) + zdq_i(ji)
496               ENDIF
497               IF ( zfbase(ji) + zdq_i(ji) .GE. 1.0e-3  ) THEN
498                  WRITE(numout,*) ' ALERTE heat loss for basal melt : zji, zjj, jl :', zji, zjj, jl
499                  WRITE(numout,*) ' ht_i_b    : ', ht_i_b(ji)
500                  WRITE(numout,*) ' zfbase    : ', zfbase(ji)
501                  WRITE(numout,*) ' zdq_i     : ', zdq_i(ji)
502                  WRITE(numout,*) ' ht_i_b    : ', ht_i_b(ji)
503                  WRITE(numout,*) ' fc_bo_i   : ', fc_bo_i(ji)
504                  WRITE(numout,*) ' fbif_1d   : ', fbif_1d(ji)
505                  WRITE(numout,*) ' qlbbq_1d  : ', qlbbq_1d(ji)
506                  WRITE(numout,*) ' s_i_new   : ', s_i_new(ji)
507                  WRITE(numout,*) ' sss_m     : ', sss_m(zji,zjj)
508                  WRITE(numout,*) ' dh_i_bott : ', dh_i_bott(ji)
509                  WRITE(numout,*) ' innermelt : ', INT( zinnermelt(ji) )
510               ENDIF
511            ENDIF
512         END DO
513         IF( numce_dh > 0 )   meance_dh = meance_dh / numce_dh
514         WRITE(numout,*) ' Number of points where there is bas. me. error : ', numce_dh
515         WRITE(numout,*) ' Mean basal melt error on error points : ', meance_dh
516         WRITE(numout,*) ' Remaining bottom heat : ', zqfont_bo(jiindex_1d)
517         !
518      ENDIF
519
520      !
521      !------------------------------------------------------------------------------!
522      !  5) Pathological cases                                                       !
523      !------------------------------------------------------------------------------!
524      !
525      !----------------------------------------------
526      ! 5.1 Excessive ablation in a 1-category model
527      !----------------------------------------------
528
529      DO ji = kideb, kiut
530         !                     ! in a 1-category sea ice model, bottom ablation must not exceed hmelt (-0.15)
531         IF( jpl == 1 ) THEN   ;   zdhbf = MAX( hmelt , dh_i_bott(ji) )
532         ELSE                  ;   zdhbf =              dh_i_bott(ji) 
533         ENDIF
534         !                     ! excessive energy is sent to lateral ablation
535         fsup     (ji) =  rhoic * lfus * at_i_b(ji) / MAX( 1.0 - at_i_b(ji) , epsi13 )   &
536            &                          * ( zdhbf - dh_i_bott(ji) ) / rdt_ice
537         dh_i_bott(ji)  = zdhbf
538         !                     !since ice volume is only used for outputs, we keep it global for all categories
539         dvbbq_1d (ji) = a_i_b(ji) * dh_i_bott(ji)
540         !                     !new ice thickness
541         zhgnew   (ji) = ht_i_b(ji) + dh_i_surf(ji) + dh_i_bott(ji)
542         !                     ! diagnostic ( bottom ice growth )
543         zji = MOD( npb(ji) - 1, jpi ) + 1
544         zjj = ( npb(ji) - 1 ) / jpi + 1
545         diag_bot_gr(zji,zjj) = diag_bot_gr(zji,zjj) + MAX(dh_i_bott(ji),0.0)*a_i_b(ji) / rdt_ice
546         diag_sur_me(zji,zjj) = diag_sur_me(zji,zjj) + MIN(dh_i_surf(ji),0.0)*a_i_b(ji) / rdt_ice
547         diag_bot_me(zji,zjj) = diag_bot_me(zji,zjj) + MIN(dh_i_bott(ji),0.0)*a_i_b(ji) / rdt_ice
548      END DO
549
550      !-----------------------------------
551      ! 5.2 More than available ice melts
552      !-----------------------------------
553      ! then heat applied minus heat content at previous time step
554      ! should equal heat remaining
555      !
556      DO ji = kideb, kiut
557         ! Adapt the remaining energy if too much ice melts
558         !--------------------------------------------------
559         zihgnew    =  1.0 - MAX( zzero , SIGN( zone , - zhgnew(ji) ) ) !1 if ice
560         ! 0 if no more ice
561         zhgnew    (ji) =         zihgnew   * zhgnew(ji)      ! ice thickness is put to 0
562         ! remaining heat
563         zfdt_final(ji) = ( 1.0 - zihgnew ) * ( zqfont_su(ji) +  zqfont_bo(ji) ) 
564
565         ! If snow remains, energy is used to melt snow
566         zhni =  ht_s_b(ji)      ! snow depth at previous time step
567         zihg =  MAX( zzero , SIGN ( zone , - ht_s_b(ji) ) ) ! 0 if snow
568
569         ! energy of melting of remaining snow
570         zqt_s(ji) =    ( 1. - zihg ) * zqt_s(ji) / MAX( zhni, epsi13 )
571         zdhnm     =  - ( 1. - zihg ) * ( 1. - zihgnew ) * zfdt_final(ji) / MAX( zqt_s(ji) , epsi13 )
572         zhnfi          =  zhni + zdhnm
573         zfdt_final(ji) =  MAX( zfdt_final(ji) + zqt_s(ji) * zdhnm , 0.0 )
574         ht_s_b(ji)     =  MAX( zzero , zhnfi )
575         zqt_s(ji)      =  zqt_s(ji) * ht_s_b(ji)
576
577         ! Mass variations of ice and snow
578         !---------------------------------
579         !                                              ! mass variation of the jl category
580         zzfmass_s = - a_i_b(ji) * ( zhni       - ht_s_b(ji) ) * rhosn   ! snow
581         zzfmass_i =   a_i_b(ji) * ( zhgnew(ji) - ht_i_b(ji) ) * rhoic   ! ice 
582         !
583         zfmass_i(ji) = zzfmass_i                       ! ice variation saved to compute salt flux (see below)
584         !
585         !                                              ! mass variation cumulated over category
586         rdmsnif_1d(ji) = rdmsnif_1d(ji) + zzfmass_s                     ! snow
587         rdmicif_1d(ji) = rdmicif_1d(ji) + zzfmass_i                     ! ice
588
589         ! Remaining heat to the ocean
590         !---------------------------------
591         focea(ji)  = - zfdt_final(ji) / rdt_ice         ! focea is in W.m-2 * dt
592
593      END DO
594
595      ftotal_fin (:) = zfdt_final(:)  / rdt_ice
596
597      !---------------------------
598      ! Salt flux and heat fluxes                   
599      !---------------------------
600      DO ji = kideb, kiut
601         zihgnew    =  1.0 - MAX( zzero , SIGN( zone , - zhgnew(ji) ) )   !1 if ice
602
603         ! Salt flux
604         zji = MOD( npb(ji) - 1, jpi ) + 1
605         zjj = ( npb(ji) - 1 ) / jpi + 1
606         ! new lines
607         IF( num_sal == 4 ) THEN
608            fseqv_1d(ji) = fseqv_1d(ji) +        zihgnew  * zfsalt_melt(ji)                                &
609               &                        + (1.0 - zihgnew) * zfmass_i(ji) * ( sss_m(zji,zjj) - bulk_sal   ) / rdt_ice
610         ELSE
611            fseqv_1d(ji) = fseqv_1d(ji) +        zihgnew  * zfsalt_melt(ji)                                &
612               &                        + (1.0 - zihgnew) * zfmass_i(ji) * ( sss_m(zji,zjj) - sm_i_b(ji) ) / rdt_ice
613         ENDIF
614         ! Heat flux
615         ! excessive bottom ablation energy (fsup) - 0 except if jpl = 1
616         ! excessive total ablation energy (focea) sent to the ocean
617         qfvbq_1d(ji)  = qfvbq_1d(ji) + fsup(ji) + ( 1.0 - zihgnew ) * focea(ji) * a_i_b(ji) * rdt_ice
618
619         zihic   = 1.0 - MAX( zzero , SIGN( zone , -ht_i_b(ji) ) )
620         ! equals 0 if ht_i = 0, 1 if ht_i gt 0
621         fscbq_1d(ji) =  a_i_b(ji) * fstbif_1d(ji)
622         qldif_1d(ji)  = qldif_1d(ji) + fsup(ji) + ( 1.0 - zihgnew ) * focea(ji)    * a_i_b(ji) * rdt_ice   &
623            &                                    + ( 1.0 - zihic   ) * fscbq_1d(ji)             * rdt_ice
624      END DO  ! ji
625
626      !-------------------------------------------
627      ! Correct temperature, energy and thickness
628      !-------------------------------------------
629      DO ji = kideb, kiut
630         zihgnew    =  1.0 - MAX( zzero , SIGN( zone , - zhgnew(ji) ) ) 
631         t_su_b(ji) =  zihgnew * t_su_b(ji) + ( 1.0 - zihgnew ) * rtt
632      END DO  ! ji
633
634      DO jk = 1, nlay_i
635         DO ji = kideb, kiut
636            zihgnew      =  1.0 - MAX( zzero , SIGN( zone , - zhgnew(ji) ) ) 
637            t_i_b(ji,jk) =  zihgnew * t_i_b(ji,jk) + ( 1.0 - zihgnew ) * rtt
638            q_i_b(ji,jk) =  zihgnew * q_i_b(ji,jk)
639         END DO
640      END DO  ! ji
641
642      DO ji = kideb, kiut
643         ht_i_b(ji) = zhgnew(ji)
644      END DO  ! ji
645      !
646      !------------------------------------------------------------------------------|
647      !  6) Snow-Ice formation                                                       |
648      !------------------------------------------------------------------------------|
649      ! When snow load excesses Archimede's limit, snow-ice interface goes down under sea-level,
650      ! flooding of seawater transforms snow into ice dh_snowice is positive for the ice
651      DO ji = kideb, kiut
652         !
653         dh_snowice(ji) = MAX(  zzero , ( rhosn * ht_s_b(ji) + (rhoic-rau0) * ht_i_b(ji) ) / ( rhosn+rau0-rhoic )  )
654         zhgnew(ji)     = MAX(  zhgnew(ji) , zhgnew(ji) + dh_snowice(ji)  )
655         zhnnew         = MIN(  ht_s_b(ji) , ht_s_b(ji) - dh_snowice(ji)  )
656
657         !  Changes in ice volume and ice mass.
658         dvnbq_1d  (ji) =                a_i_b(ji) * ( zhgnew(ji)-ht_i_b(ji) )
659         dmgwi_1d  (ji) = dmgwi_1d(ji) + a_i_b(ji) * ( ht_s_b(ji) - zhnnew ) * rhosn
660
661         rdmicif_1d(ji) = rdmicif_1d(ji) + a_i_b(ji) * ( zhgnew(ji) - ht_i_b(ji) ) * rhoic 
662         rdmsnif_1d(ji) = rdmsnif_1d(ji) + a_i_b(ji) * ( zhnnew     - ht_s_b(ji) ) * rhosn
663
664         !        Equivalent salt flux (1) Snow-ice formation component
665         !        -----------------------------------------------------
666         zji = MOD( npb(ji) - 1, jpi ) + 1
667         zjj =    ( npb(ji) - 1 ) / jpi + 1
668
669         IF( num_sal /= 2 ) THEN   ;   zsm_snowice = sm_i_b(ji)
670         ELSE                      ;   zsm_snowice = ( rhoic - rhosn ) / rhoic * sss_m(zji,zjj) 
671         ENDIF
672         IF( num_sal == 4 ) THEN
673            fseqv_1d(ji) = fseqv_1d(ji) + ( sss_m(zji,zjj) - bulk_sal    ) * a_i_b(ji)   &
674               &                        * ( zhgnew(ji) - ht_i_b(ji) ) * rhoic / rdt_ice
675         ELSE
676            fseqv_1d(ji) = fseqv_1d(ji) + ( sss_m(zji,zjj) - zsm_snowice ) * a_i_b(ji)   &
677               &                        * ( zhgnew(ji) - ht_i_b(ji) ) * rhoic / rdt_ice
678         ENDIF
679         ! entrapment during snow ice formation
680         i_ice_switch = 1.0 - MAX( 0.e0 , SIGN( 1.0 , - ht_i_b(ji) + 1.0e-6 ) )
681         isnowic      = 1.0 - MAX( 0.e0 , SIGN( 1.0 , - dh_snowice(ji)      ) ) * i_ice_switch
682         IF(  num_sal == 2  .OR.  num_sal == 4  )   &
683            dsm_i_si_1d(ji) = ( zsm_snowice*dh_snowice(ji) &
684            &               + sm_i_b(ji) * ht_i_b(ji) / MAX( ht_i_b(ji) + dh_snowice(ji), epsi13)   &
685            &               - sm_i_b(ji) ) * isnowic     
686
687         !  Actualize new snow and ice thickness.
688         ht_s_b(ji)  = zhnnew
689         ht_i_b(ji)  = zhgnew(ji)
690
691         ! Total ablation ! new lines added to debug
692         IF( ht_i_b(ji) <= 0._wp )   a_i_b(ji) = 0._wp
693
694         ! diagnostic ( snow ice growth )
695         zji = MOD( npb(ji) - 1, jpi ) + 1
696         zjj =    ( npb(ji) - 1 ) / jpi + 1
697         diag_sni_gr(zji,zjj)  = diag_sni_gr(zji,zjj) + dh_snowice(ji)*a_i_b(ji) / rdt_ice
698         !
699      END DO !ji
700      !
701      IF( wrk_not_released(1, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) )   &
702          CALL ctl_stop('lim_thd_dh : failed to release workspace arrays')
703      !
704   END SUBROUTINE lim_thd_dh
705   
706#else
707   !!----------------------------------------------------------------------
708   !!   Default option                               NO  LIM3 sea-ice model
709   !!----------------------------------------------------------------------
710CONTAINS
711   SUBROUTINE lim_thd_dh          ! Empty routine
712   END SUBROUTINE lim_thd_dh
713#endif
714
715   !!======================================================================
716END MODULE limthd_dh
Note: See TracBrowser for help on using the repository browser.