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 branches/2013/dev_r3406_CNRS_LIM3/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2013/dev_r3406_CNRS_LIM3/NEMOGCM/NEMO/LIM_SRC_3/limthd_dh.F90 @ 3938

Last change on this file since 3938 was 3938, checked in by flavoni, 11 years ago

dev_r3406_CNRS_LIM3: update LIM3, see ticket #1116

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