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/2014/dev_CNRS_2014/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2014/dev_CNRS_2014/NEMOGCM/NEMO/LIM_SRC_3/limthd_dh.F90 @ 4902

Last change on this file since 4902 was 4902, checked in by cetlod, 9 years ago

2014/dev_CNRS_2014 : Merge in the trunk changes between 4728 and 4879, see ticket #1415

  • Property svn:keywords set to Id
File size: 36.5 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 wfx_snw & wfx_ice
9   !!            3.4  ! 2011-02 (G. Madec) dynamical allocation
10   !!            3.5  ! 2012-10 (G. Madec & co) salt flux + bug fixes
11   !!----------------------------------------------------------------------
12#if defined key_lim3
13   !!----------------------------------------------------------------------
14   !!   'key_lim3'                                      LIM3 sea-ice model
15   !!----------------------------------------------------------------------
16   !!   lim_thd_dh    : vertical accr./abl. and lateral ablation of sea ice
17   !!----------------------------------------------------------------------
18   USE par_oce        ! ocean parameters
19   USE phycst         ! physical constants (OCE directory)
20   USE sbc_oce        ! Surface boundary condition: ocean fields
21   USE ice            ! LIM variables
22   USE par_ice        ! LIM parameters
23   USE thd_ice        ! LIM thermodynamics
24   USE in_out_manager ! I/O manager
25   USE lib_mpp        ! MPP library
26   USE wrk_nemo       ! work arrays
27   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
28   
29   IMPLICIT NONE
30   PRIVATE
31
32   PUBLIC   lim_thd_dh   ! called by lim_thd
33
34   REAL(wp) ::   epsi20 = 1.e-20   ! constant values
35   REAL(wp) ::   epsi10 = 1.e-10   !
36
37   !!----------------------------------------------------------------------
38   !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2010)
39   !! $Id$
40   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
41   !!----------------------------------------------------------------------
42CONTAINS
43
44   SUBROUTINE lim_thd_dh( kideb, kiut )
45      !!------------------------------------------------------------------
46      !!                ***  ROUTINE lim_thd_dh  ***
47      !!
48      !! ** Purpose :   determines variations of ice and snow thicknesses.
49      !!
50      !! ** Method  :   Ice/Snow surface melting arises from imbalance in surface fluxes
51      !!              Bottom accretion/ablation arises from flux budget
52      !!              Snow thickness can increase by precipitation and decrease by sublimation
53      !!              If snow load excesses Archmiede limit, snow-ice is formed by
54      !!              the flooding of sea-water in the snow
55      !!
56      !!                 1) Compute available flux of heat for surface ablation
57      !!                 2) Compute snow and sea ice enthalpies
58      !!                 3) Surface ablation and sublimation
59      !!                 4) Bottom accretion/ablation
60      !!                 5) Case of Total ablation
61      !!                 6) Snow ice formation
62      !!
63      !! References : Bitz and Lipscomb, 1999, J. Geophys. Res.
64      !!              Fichefet T. and M. Maqueda 1997, J. Geophys. Res., 102(C6), 12609-12646   
65      !!              Vancoppenolle, Fichefet and Bitz, 2005, Geophys. Res. Let.
66      !!              Vancoppenolle et al.,2009, Ocean Modelling
67      !!------------------------------------------------------------------
68      INTEGER , INTENT(in) ::   kideb, kiut   ! Start/End point on which the  the computation is applied
69      !!
70      INTEGER  ::   ji , jk        ! dummy loop indices
71      INTEGER  ::   ii, ij         ! 2D corresponding indices to ji
72      INTEGER  ::   iter
73
74      REAL(wp) ::   ztmelts             ! local scalar
75      REAL(wp) ::   zdh, zfdum  !
76      REAL(wp) ::   zfracs       ! fractionation coefficient for bottom salt entrapment
77      REAL(wp) ::   zcoeff       ! dummy argument for snowfall partitioning over ice and leads
78      REAL(wp) ::   zs_snic  ! snow-ice salinity
79      REAL(wp) ::   zswi1        ! switch for computation of bottom salinity
80      REAL(wp) ::   zswi12       ! switch for computation of bottom salinity
81      REAL(wp) ::   zswi2        ! switch for computation of bottom salinity
82      REAL(wp) ::   zgrr         ! bottom growth rate
83      REAL(wp) ::   zt_i_new     ! bottom formation temperature
84
85      REAL(wp) ::   zQm          ! enthalpy exchanged with the ocean (J/m2), >0 towards the ocean
86      REAL(wp) ::   zEi          ! specific enthalpy of sea ice (J/kg)
87      REAL(wp) ::   zEw          ! specific enthalpy of exchanged water (J/kg)
88      REAL(wp) ::   zdE          ! specific enthalpy difference (J/kg)
89      REAL(wp) ::   zfmdt        ! exchange mass flux x time step (J/m2), >0 towards the ocean
90      REAL(wp) ::   zsstK        ! SST in Kelvin
91
92      REAL(wp), POINTER, DIMENSION(:) ::   zh_s        ! snow layer thickness
93      REAL(wp), POINTER, DIMENSION(:) ::   zqprec      ! energy of fallen snow                       (J.m-3)
94      REAL(wp), POINTER, DIMENSION(:) ::   zq_su       ! heat for surface ablation                   (J.m-2)
95      REAL(wp), POINTER, DIMENSION(:) ::   zq_bo       ! heat for bottom ablation                    (J.m-2)
96      REAL(wp), POINTER, DIMENSION(:) ::   zq_1cat     ! corrected heat in case 1-cat and hmelt>15cm (J.m-2)
97      REAL(wp), POINTER, DIMENSION(:) ::   zq_rema     ! remaining heat at the end of the routine    (J.m-2)
98      REAL(wp), POINTER, DIMENSION(:) ::   zf_tt     ! Heat budget to determine melting or freezing(W.m-2)
99      INTEGER , POINTER, DIMENSION(:) ::   icount      ! number of layers vanished by melting
100
101      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_mel   ! snow melt
102      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_pre   ! snow precipitation
103      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_sub   ! snow sublimation
104
105      REAL(wp), POINTER, DIMENSION(:,:) ::   zdeltah
106      REAL(wp), POINTER, DIMENSION(:,:) ::   zh_i      ! ice layer thickness
107
108      REAL(wp), POINTER, DIMENSION(:) ::   zqh_i       ! total ice heat content  (J.m-2)
109      REAL(wp), POINTER, DIMENSION(:) ::   zqh_s       ! total snow heat content (J.m-2)
110      REAL(wp), POINTER, DIMENSION(:) ::   zq_s        ! total snow enthalpy     (J.m-3)
111
112      ! mass and salt flux (clem)
113      REAL(wp) :: zdvres, zswitch_sal, zswitch
114
115      ! Heat conservation
116      INTEGER  ::   num_iter_max
117      REAL(wp) ::   zinda, zindq, zindh 
118      REAL(wp), POINTER, DIMENSION(:) ::   zintermelt   ! debug
119
120      !!------------------------------------------------------------------
121
122      ! Discriminate between varying salinity (num_sal=2) and prescribed cases (other values)
123      SELECT CASE( num_sal )                       ! varying salinity or not
124         CASE( 1, 3, 4 ) ;   zswitch_sal = 0       ! prescribed salinity profile
125         CASE( 2 )       ;   zswitch_sal = 1       ! varying salinity profile
126      END SELECT
127
128      CALL wrk_alloc( jpij, zh_s, zqprec, zq_su, zq_bo, zf_tt, zq_1cat, zq_rema )
129      CALL wrk_alloc( jpij, zdh_s_mel, zdh_s_pre, zdh_s_sub, zqh_i, zqh_s, zq_s )
130      CALL wrk_alloc( jpij, zintermelt )
131      CALL wrk_alloc( jpij, nlay_i+1, zdeltah, zh_i )
132      CALL wrk_alloc( jpij, icount )
133     
134      dh_i_surf  (:) = 0._wp ; dh_i_bott  (:) = 0._wp ; dh_snowice(:) = 0._wp
135      dsm_i_se_1d(:) = 0._wp ; dsm_i_si_1d(:) = 0._wp   
136 
137      zqprec (:) = 0._wp ; zq_su  (:) = 0._wp ; zq_bo  (:) = 0._wp ; zf_tt  (:) = 0._wp
138      zq_1cat(:) = 0._wp ; zq_rema(:) = 0._wp
139
140      zh_s     (:) = 0._wp       
141      zdh_s_pre(:) = 0._wp
142      zdh_s_mel(:) = 0._wp
143      zdh_s_sub(:) = 0._wp
144      zqh_s    (:) = 0._wp     
145      zqh_i    (:) = 0._wp   
146
147      zh_i      (:,:) = 0._wp       
148      zdeltah   (:,:) = 0._wp       
149      zintermelt(:)   = 0._wp
150      icount    (:)   = 0
151
152      ! initialize layer thicknesses and enthalpies
153      h_i_old (:,0:nlay_i+1) = 0._wp
154      qh_i_old(:,0:nlay_i+1) = 0._wp
155      DO jk = 1, nlay_i
156         DO ji = kideb, kiut
157            h_i_old (ji,jk) = ht_i_1d(ji) / REAL( nlay_i )
158            qh_i_old(ji,jk) = q_i_1d(ji,jk) * h_i_old(ji,jk)
159         ENDDO
160      ENDDO
161      !
162      !------------------------------------------------------------------------------!
163      !  1) Calculate available heat for surface and bottom ablation                 !
164      !------------------------------------------------------------------------------!
165      !
166      DO ji = kideb, kiut
167         zinda         = 1._wp - MAX(  0._wp , SIGN( 1._wp , - ht_s_1d(ji) ) )
168         ztmelts       = zinda * rtt + ( 1._wp - zinda ) * rtt
169
170         zfdum      = qns_ice_1d(ji) + ( 1._wp - i0(ji) ) * qsr_ice_1d(ji) - fc_su(ji) 
171         zf_tt(ji)  = fc_bo_i(ji) + fhtur_1d(ji) + fhld_1d(ji) 
172
173         zq_su (ji) = MAX( 0._wp, zfdum     * rdt_ice ) * MAX( 0._wp , SIGN( 1._wp, t_su_1d(ji) - ztmelts ) )
174         zq_bo (ji) = MAX( 0._wp, zf_tt(ji) * rdt_ice )
175      END DO
176
177      !
178      !------------------------------------------------------------------------------!
179      ! If snow temperature is above freezing point, then snow melts
180      ! (should not happen but sometimes it does)
181      !------------------------------------------------------------------------------!
182      DO ji = kideb, kiut
183         IF( t_s_1d(ji,1) > rtt ) THEN !!! Internal melting
184            ! Contribution to heat flux to the ocean [W.m-2], < 0 
185            hfx_res_1d(ji) = hfx_res_1d(ji) + q_s_1d(ji,1) * ht_s_1d(ji) * a_i_1d(ji) * r1_rdtice
186            ! Contribution to mass flux
187            wfx_snw_1d(ji) = wfx_snw_1d(ji) + rhosn * ht_s_1d(ji) * a_i_1d(ji) * r1_rdtice
188            ! updates
189            ht_s_1d(ji)   = 0._wp
190            q_s_1d (ji,1) = 0._wp
191            t_s_1d (ji,1) = rtt
192         END IF
193      END DO
194
195      !------------------------------------------------------------!
196      !  2) Computing layer thicknesses and enthalpies.            !
197      !------------------------------------------------------------!
198      !
199      DO ji = kideb, kiut     
200         zh_s(ji) = ht_s_1d(ji) / REAL( nlay_s )
201      END DO
202      !
203      DO jk = 1, nlay_s
204         DO ji = kideb, kiut
205            zqh_s(ji) =  zqh_s(ji) + q_s_1d(ji,jk) * zh_s(ji)
206         END DO
207      END DO
208      !
209      DO jk = 1, nlay_i
210         DO ji = kideb, kiut
211            zh_i(ji,jk) = ht_i_1d(ji) / REAL( nlay_i )
212            zqh_i(ji)   = zqh_i(ji) + q_i_1d(ji,jk) * zh_i(ji,jk)
213         END DO
214      END DO
215      !
216      !------------------------------------------------------------------------------|
217      !  3) Surface ablation and sublimation                                         |
218      !------------------------------------------------------------------------------|
219      !
220      !-------------------------
221      ! 3.1 Snow precips / melt
222      !-------------------------
223      ! Snow accumulation in one thermodynamic time step
224      ! snowfall is partitionned between leads and ice
225      ! if snow fall was uniform, a fraction (1-at_i) would fall into leads
226      ! but because of the winds, more snow falls on leads than on sea ice
227      ! and a greater fraction (1-at_i)^beta of the total mass of snow
228      ! (beta < 1) falls in leads.
229      ! In reality, beta depends on wind speed,
230      ! and should decrease with increasing wind speed but here, it is
231      ! considered as a constant. an average value is 0.66
232      ! Martin Vancoppenolle, December 2006
233
234      DO ji = kideb, kiut
235         !-----------
236         ! Snow fall
237         !-----------
238         ! thickness change
239         zcoeff = ( 1._wp - ( 1._wp - at_i_1d(ji) )**betas ) / at_i_1d(ji) 
240         zdh_s_pre(ji) = zcoeff * sprecip_1d(ji) * rdt_ice / rhosn
241         ! enthalpy of the precip (>0, J.m-3) (tatm_ice is now in K)
242         zqprec   (ji) = rhosn * ( cpic * ( rtt - MIN( tatm_ice_1d(ji), rt0_snow) ) + lfus )   
243         IF( sprecip_1d(ji) == 0._wp ) zqprec(ji) = 0._wp
244         ! heat flux from snow precip (>0, W.m-2)
245         hfx_spr_1d(ji) = hfx_spr_1d(ji) + zdh_s_pre(ji) * a_i_1d(ji) * zqprec(ji) * r1_rdtice
246         ! mass flux, <0
247         wfx_spr_1d(ji) = wfx_spr_1d(ji) - rhosn * a_i_1d(ji) * zdh_s_pre(ji) * r1_rdtice
248         ! update thickness
249         ht_s_1d    (ji) = MAX( 0._wp , ht_s_1d(ji) + zdh_s_pre(ji) )
250
251         !---------------------
252         ! Melt of falling snow
253         !---------------------
254         ! thickness change
255         IF( zdh_s_pre(ji) > 0._wp ) THEN
256         zindq          = 1._wp - MAX( 0._wp , SIGN( 1._wp , - zqprec(ji) + epsi20 ) )
257         zdh_s_mel (ji) = - zindq * zq_su(ji) / MAX( zqprec(ji) , epsi20 )
258         zdh_s_mel (ji) = MAX( - zdh_s_pre(ji), zdh_s_mel(ji) ) ! bound melting
259         ! heat used to melt snow (W.m-2, >0)
260         hfx_snw_1d(ji) = hfx_snw_1d(ji) - zdh_s_mel(ji) * a_i_1d(ji) * zqprec(ji) * r1_rdtice
261         ! snow melting only = water into the ocean (then without snow precip), >0
262         wfx_snw_1d(ji) = wfx_snw_1d(ji) - rhosn * a_i_1d(ji) * zdh_s_mel(ji) * r1_rdtice
263         
264         ! updates available heat + thickness
265         zq_su (ji) = MAX( 0._wp , zq_su (ji) + zdh_s_mel(ji) * zqprec(ji) )     
266         ht_s_1d(ji) = MAX( 0._wp , ht_s_1d(ji) + zdh_s_mel(ji) )
267         zh_s  (ji) = ht_s_1d(ji) / REAL( nlay_s )
268
269         ENDIF
270      END DO
271
272      ! If heat still available, then melt more snow
273      zdeltah(:,:) = 0._wp ! important
274      DO jk = 1, nlay_s
275         DO ji = kideb, kiut
276            ! thickness change
277            zindh            = 1._wp - MAX( 0._wp, SIGN( 1._wp, - ht_s_1d(ji) ) ) 
278            zindq            = 1._wp - MAX( 0._wp, SIGN( 1._wp, - q_s_1d(ji,jk) + epsi20 ) ) 
279            zdeltah  (ji,jk) = - zindh * zindq * zq_su(ji) / MAX( q_s_1d(ji,jk), epsi20 )
280            zdeltah  (ji,jk) = MAX( zdeltah(ji,jk) , - zh_s(ji) ) ! bound melting
281            zdh_s_mel(ji)    = zdh_s_mel(ji) + zdeltah(ji,jk)   
282            ! heat used to melt snow(W.m-2, >0)
283            hfx_snw_1d(ji)   = hfx_snw_1d(ji) - zdeltah(ji,jk) * a_i_1d(ji) * q_s_1d(ji,jk) * r1_rdtice 
284            ! snow melting only = water into the ocean (then without snow precip)
285            wfx_snw_1d(ji)   = wfx_snw_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
286
287            ! updates available heat + thickness
288            zq_su (ji) = MAX( 0._wp , zq_su (ji) + zdeltah(ji,jk) * q_s_1d(ji,jk) )
289            ht_s_1d(ji) = MAX( 0._wp , ht_s_1d(ji) + zdeltah(ji,jk) )
290
291         END DO
292      END DO
293
294      !----------------------
295      ! 3.2 Snow sublimation
296      !----------------------
297      ! qla_ice is always >=0 (upwards), heat goes to the atmosphere, therefore snow sublimates
298      ! clem comment: not counted in mass exchange in limsbc since this is an exchange with atm. (not ocean)
299      ! clem comment: ice should also sublimate
300      IF( lk_cpl ) THEN
301         ! coupled mode: sublimation already included in emp_ice (to do in limsbc_ice)
302         zdh_s_sub(:)      =  0._wp 
303      ELSE
304         ! forced  mode: snow thickness change due to sublimation
305         DO ji = kideb, kiut
306            zdh_s_sub(ji)  =  MAX( - ht_s_1d(ji) , - parsub * qla_ice_1d(ji) / ( rhosn * lsub ) * rdt_ice )
307            ! Heat flux by sublimation [W.m-2], < 0
308            !      sublimate first snow that had fallen, then pre-existing snow
309            zcoeff         =      ( MAX( zdh_s_sub(ji), - MAX( 0._wp, zdh_s_pre(ji) + zdh_s_mel(ji) ) )   * zqprec(ji) +   &
310               &  ( zdh_s_sub(ji) - MAX( zdh_s_sub(ji), - MAX( 0._wp, zdh_s_pre(ji) + zdh_s_mel(ji) ) ) ) * q_s_1d(ji,1) )  &
311               &  * a_i_1d(ji) * r1_rdtice
312            hfx_sub_1d(ji) = hfx_sub_1d(ji) + zcoeff
313            ! Mass flux by sublimation
314            wfx_sub_1d(ji) =  wfx_sub_1d(ji) - rhosn * a_i_1d(ji) * zdh_s_sub(ji) * r1_rdtice
315            ! new snow thickness
316            ht_s_1d(ji)     =  MAX( 0._wp , ht_s_1d(ji) + zdh_s_sub(ji) )
317         END DO
318      ENDIF
319
320      ! --- Update snow diags --- !
321      DO ji = kideb, kiut
322         dh_s_tot(ji)   = zdh_s_mel(ji) + zdh_s_pre(ji) + zdh_s_sub(ji)
323         zh_s(ji)       = ht_s_1d(ji) / REAL( nlay_s )
324      END DO ! ji
325
326      !-------------------------------------------
327      ! 3.3 Update temperature, energy
328      !-------------------------------------------
329      ! new temp and enthalpy of the snow (remaining snow precip + remaining pre-existing snow)
330      zq_s(:) = 0._wp 
331      DO jk = 1, nlay_s
332         DO ji = kideb,kiut
333            zindh  =  MAX(  0._wp , SIGN( 1._wp, - ht_s_1d(ji) + epsi20 )  )
334            q_s_1d(ji,jk) = ( 1._wp - zindh ) / MAX( ht_s_1d(ji), epsi20 ) *             &
335              &            ( (   MAX( 0._wp, dh_s_tot(ji) )              ) * zqprec(ji) +  &
336              &              ( - MAX( 0._wp, dh_s_tot(ji) ) + ht_s_1d(ji) ) * rhosn * ( cpic * ( rtt - t_s_1d(ji,jk) ) + lfus ) )
337            zq_s(ji)     =  zq_s(ji) + q_s_1d(ji,jk)
338         END DO
339      END DO
340
341      !--------------------------
342      ! 3.4 Surface ice ablation
343      !--------------------------
344      zdeltah(:,:) = 0._wp ! important
345      DO jk = 1, nlay_i
346         DO ji = kideb, kiut 
347            zEi            = - q_i_1d(ji,jk) / rhoic                ! Specific enthalpy of layer k [J/kg, <0]
348
349            ztmelts        = - tmut * s_i_1d(ji,jk) + rtt           ! Melting point of layer k [K]
350
351            zEw            =    rcp * ( ztmelts - rt0 )            ! Specific enthalpy of resulting meltwater [J/kg, <0]
352
353            zdE            =    zEi - zEw                          ! Specific enthalpy difference < 0
354
355            zfmdt          = - zq_su(ji) / zdE                     ! Mass flux to the ocean [kg/m2, >0]
356
357            zdeltah(ji,jk) = - zfmdt / rhoic                       ! Melt of layer jk [m, <0]
358
359            zdeltah(ji,jk) = MIN( 0._wp , MAX( zdeltah(ji,jk) , - zh_i(ji,jk) ) )    ! Melt of layer jk cannot exceed the layer thickness [m, <0]
360
361            zq_su(ji)      = MAX( 0._wp , zq_su(ji) - zdeltah(ji,jk) * rhoic * zdE ) ! update available heat
362
363            dh_i_surf(ji)  = dh_i_surf(ji) + zdeltah(ji,jk)        ! Cumulate surface melt
364
365            zfmdt          = - rhoic * zdeltah(ji,jk)              ! Recompute mass flux [kg/m2, >0]
366
367            zQm            = zfmdt * zEw                           ! Energy of the melt water sent to the ocean [J/m2, <0]
368
369            ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
370            sfx_sum_1d(ji)   = sfx_sum_1d(ji) - sm_i_1d(ji) * a_i_1d(ji) * zdeltah(ji,jk) * rhoic * r1_rdtice
371
372            ! Contribution to heat flux [W.m-2], < 0
373            hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
374
375            ! Total heat flux used in this process [W.m-2], > 0 
376            hfx_sum_1d(ji) = hfx_sum_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
377
378            ! Contribution to mass flux
379            wfx_sum_1d(ji) =  wfx_sum_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
380           
381            ! record which layers have disappeared (for bottom melting)
382            !    => icount=0 : no layer has vanished
383            !    => icount=5 : 5 layers have vanished
384            zindh       = NINT( MAX( 0._wp , SIGN( 1._wp , - ( zh_i(ji,jk) + zdeltah(ji,jk) ) ) ) ) 
385            icount(ji)  = icount(ji) + zindh
386            zh_i(ji,jk) = MAX( 0._wp , zh_i(ji,jk) + zdeltah(ji,jk) )
387
388            ! update heat content (J.m-2) and layer thickness
389            qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
390            h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
391         END DO
392      END DO
393      ! update ice thickness
394      DO ji = kideb, kiut
395         ht_i_1d(ji) =  MAX( 0._wp , ht_i_1d(ji) + dh_i_surf(ji) )
396      END DO
397
398      !
399      !------------------------------------------------------------------------------!
400      ! 4) Basal growth / melt                                                       !
401      !------------------------------------------------------------------------------!
402      !
403      !------------------
404      ! 4.1 Basal growth
405      !------------------
406      ! Basal growth is driven by heat imbalance at the ice-ocean interface,
407      ! between the inner conductive flux  (fc_bo_i), from the open water heat flux
408      ! (fhld) and the turbulent ocean flux (fhtur).
409      ! fc_bo_i is positive downwards. fhtur and fhld are positive to the ice
410
411      ! If salinity varies in time, an iterative procedure is required, because
412      ! the involved quantities are inter-dependent.
413      ! Basal growth (dh_i_bott) depends upon new ice specific enthalpy (zEi),
414      ! which depends on forming ice salinity (s_i_new), which depends on dh/dt (dh_i_bott)
415      ! -> need for an iterative procedure, which converges quickly
416
417      IF ( num_sal == 2 ) THEN
418         num_iter_max = 5
419      ELSE
420         num_iter_max = 1
421      ENDIF
422
423      !clem debug. Just to be sure that enthalpy at nlay_i+1 is null
424      DO ji = kideb, kiut
425         q_i_1d(ji,nlay_i+1) = 0._wp
426      END DO
427
428      ! Iterative procedure
429      DO iter = 1, num_iter_max
430         DO ji = kideb, kiut
431            IF(  zf_tt(ji) < 0._wp  ) THEN
432
433               ! New bottom ice salinity (Cox & Weeks, JGR88 )
434               !--- zswi1  if dh/dt < 2.0e-8
435               !--- zswi12 if 2.0e-8 < dh/dt < 3.6e-7
436               !--- zswi2  if dh/dt > 3.6e-7
437               zgrr               = MIN( 1.0e-3, MAX ( dh_i_bott(ji) * r1_rdtice , epsi10 ) )
438               zswi2              = MAX( 0._wp , SIGN( 1._wp , zgrr - 3.6e-7 ) )
439               zswi12             = MAX( 0._wp , SIGN( 1._wp , zgrr - 2.0e-8 ) ) * ( 1.0 - zswi2 )
440               zswi1              = 1. - zswi2 * zswi12
441               zfracs             = MIN ( zswi1  * 0.12 + zswi12 * ( 0.8925 + 0.0568 * LOG( 100.0 * zgrr ) )   &
442                  &               + zswi2  * 0.26 / ( 0.26 + 0.74 * EXP ( - 724300.0 * zgrr ) )  , 0.5 )
443
444               ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
445
446               s_i_new(ji)        = zswitch_sal * zfracs * sss_m(ii,ij)  &  ! New ice salinity
447                                  + ( 1. - zswitch_sal ) * sm_i_1d(ji) 
448               ! New ice growth
449               ztmelts            = - tmut * s_i_new(ji) + rtt          ! New ice melting point (K)
450
451               zt_i_new           = zswitch_sal * t_bo_1d(ji) + ( 1. - zswitch_sal) * t_i_1d(ji, nlay_i)
452               
453               zEi                = cpic * ( zt_i_new - ztmelts ) &     ! Specific enthalpy of forming ice (J/kg, <0)     
454                  &               - lfus * ( 1.0 - ( ztmelts - rtt ) / ( zt_i_new - rtt ) )   &
455                  &               + rcp  * ( ztmelts-rtt )         
456
457               zEw                = rcp  * ( t_bo_1d(ji) - rt0 )         ! Specific enthalpy of seawater (J/kg, < 0)
458
459               zdE                = zEi - zEw                           ! Specific enthalpy difference (J/kg, <0)
460
461               dh_i_bott(ji)      = rdt_ice * MAX( 0._wp , zf_tt(ji) / ( zdE * rhoic ) )
462
463               q_i_1d(ji,nlay_i+1) = -zEi * rhoic                        ! New ice energy of melting (J/m3, >0)
464               
465            ENDIF ! fc_bo_i
466         END DO ! ji
467      END DO ! iter
468
469      ! Contribution to Energy and Salt Fluxes
470      DO ji = kideb, kiut
471         IF(  zf_tt(ji) < 0._wp  ) THEN
472            ! New ice growth
473                                   
474            zfmdt          = - rhoic * dh_i_bott(ji)             ! Mass flux x time step (kg/m2, < 0)
475
476            ztmelts        = - tmut * s_i_new(ji) + rtt          ! New ice melting point (K)
477           
478            zt_i_new       = zswitch_sal * t_bo_1d(ji) + ( 1. - zswitch_sal) * t_i_1d(ji, nlay_i)
479           
480            zEi            = cpic * ( zt_i_new - ztmelts ) &     ! Specific enthalpy of forming ice (J/kg, <0)     
481               &               - lfus * ( 1.0 - ( ztmelts - rtt ) / ( zt_i_new - rtt ) )   &
482               &               + rcp  * ( ztmelts-rtt )         
483           
484            zEw            = rcp  * ( t_bo_1d(ji) - rt0 )         ! Specific enthalpy of seawater (J/kg, < 0)
485           
486            zdE            = zEi - zEw                           ! Specific enthalpy difference (J/kg, <0)
487           
488            ! Contribution to heat flux to the ocean [W.m-2], >0 
489            hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
490
491            ! Total heat flux used in this process [W.m-2], <0 
492            hfx_bog_1d(ji) = hfx_bog_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
493           
494            ! Contribution to salt flux, <0
495            sfx_bog_1d(ji) = sfx_bog_1d(ji) + s_i_new(ji) * a_i_1d(ji) * zfmdt * r1_rdtice
496
497            ! Contribution to mass flux, <0
498            wfx_bog_1d(ji) =  wfx_bog_1d(ji) - rhoic * a_i_1d(ji) * dh_i_bott(ji) * r1_rdtice
499
500            ! update heat content (J.m-2) and layer thickness
501            qh_i_old(ji,nlay_i+1) = qh_i_old(ji,nlay_i+1) + dh_i_bott(ji) * q_i_1d(ji,nlay_i+1)
502            h_i_old (ji,nlay_i+1) = h_i_old (ji,nlay_i+1) + dh_i_bott(ji)
503         ENDIF
504      END DO
505
506      !----------------
507      ! 4.2 Basal melt
508      !----------------
509      zdeltah(:,:) = 0._wp ! important
510      DO jk = nlay_i, 1, -1
511         DO ji = kideb, kiut
512            IF(  zf_tt(ji)  >=  0._wp  .AND. jk > icount(ji) ) THEN   ! do not calculate where layer has already disappeared from surface melting
513
514               ztmelts = - tmut * s_i_1d(ji,jk) + rtt  ! Melting point of layer jk (K)
515
516               IF( t_i_1d(ji,jk) >= ztmelts ) THEN !!! Internal melting
517                  zintermelt(ji)    = 1._wp
518
519                  zEi               = - q_i_1d(ji,jk) / rhoic        ! Specific enthalpy of melting ice (J/kg, <0)
520
521                  !!zEw               = rcp * ( t_i_1d(ji,jk) - rtt )  ! Specific enthalpy of meltwater at T = t_i_1d (J/kg, <0)
522
523                  zdE               = 0._wp                         ! Specific enthalpy difference   (J/kg, <0)
524                                                                    ! set up at 0 since no energy is needed to melt water...(it is already melted)
525
526                  zdeltah   (ji,jk) = MIN( 0._wp , - zh_i(ji,jk) ) ! internal melting occurs when the internal temperature is above freezing     
527                                                                   ! this should normally not happen, but sometimes, heat diffusion leads to this
528
529                  dh_i_bott (ji)    = dh_i_bott(ji) + zdeltah(ji,jk)
530
531                  zfmdt             = - zdeltah(ji,jk) * rhoic          ! Mass flux x time step > 0
532
533                  ! Contribution to heat flux to the ocean [W.m-2], <0 (ice enthalpy zEi is "sent" to the ocean)
534                  hfx_res_1d(ji) = hfx_res_1d(ji) + zfmdt * a_i_1d(ji) * zEi * r1_rdtice
535
536                  ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
537                  sfx_res_1d(ji) = sfx_res_1d(ji) - sm_i_1d(ji) * a_i_1d(ji) * zdeltah(ji,jk) * rhoic * r1_rdtice
538                                   
539                  ! Contribution to mass flux
540                  wfx_res_1d(ji) =  wfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
541
542                  ! update heat content (J.m-2) and layer thickness
543                  qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
544                  h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
545
546               ELSE                               !!! Basal melting
547
548                  zEi               = - q_i_1d(ji,jk) / rhoic ! Specific enthalpy of melting ice (J/kg, <0)
549
550                  zEw               = rcp * ( ztmelts - rtt )! Specific enthalpy of meltwater (J/kg, <0)
551
552                  zdE               = zEi - zEw              ! Specific enthalpy difference   (J/kg, <0)
553
554                  zfmdt             = - zq_bo(ji) / zdE  ! Mass flux x time step (kg/m2, >0)
555
556                  zdeltah(ji,jk)    = - zfmdt / rhoic        ! Gross thickness change
557
558                  zdeltah(ji,jk)    = MIN( 0._wp , MAX( zdeltah(ji,jk), - zh_i(ji,jk) ) ) ! bound thickness change
559                 
560                  zq_bo(ji)         = MAX( 0._wp , zq_bo(ji) - zdeltah(ji,jk) * rhoic * zdE ) ! update available heat. MAX is necessary for roundup errors
561
562                  dh_i_bott(ji)     = dh_i_bott(ji) + zdeltah(ji,jk)    ! Update basal melt
563
564                  zfmdt             = - zdeltah(ji,jk) * rhoic          ! Mass flux x time step > 0
565
566                  zQm               = zfmdt * zEw         ! Heat exchanged with ocean
567
568                  ! Contribution to heat flux to the ocean [W.m-2], <0 
569                  hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
570
571                  ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
572                  sfx_bom_1d(ji) = sfx_bom_1d(ji) - sm_i_1d(ji) * a_i_1d(ji) * zdeltah(ji,jk) * rhoic * r1_rdtice
573                 
574                  ! Total heat flux used in this process [W.m-2], >0 
575                  hfx_bom_1d(ji) = hfx_bom_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
576                 
577                  ! Contribution to mass flux
578                  wfx_bom_1d(ji) =  wfx_bom_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
579
580                  ! update heat content (J.m-2) and layer thickness
581                  qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
582                  h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
583               ENDIF
584           
585            ENDIF
586         END DO ! ji
587      END DO ! jk
588
589      !------------------------------------------------------------------------------!
590      ! Excessive ablation in a 1-category model
591      !     in a 1-category sea ice model, bottom ablation must not exceed hmelt (-0.15)
592      !------------------------------------------------------------------------------!
593      ! ??? keep ???
594      ! clem bug: I think this should be included above, so we would not have to
595      !           track heat/salt/mass fluxes backwards
596!      IF( jpl == 1 ) THEN
597!         DO ji = kideb, kiut
598!            IF(  zf_tt(ji)  >=  0._wp  ) THEN
599!               zdh            = MAX( hmelt , dh_i_bott(ji) )
600!               zdvres         = zdh - dh_i_bott(ji) ! >=0
601!               dh_i_bott(ji)  = zdh
602!
603!               ! excessive energy is sent to lateral ablation
604!               zinda = MAX( 0._wp, SIGN( 1._wp , 1._wp - at_i_1d(ji) - epsi20 ) )
605!               zq_1cat(ji) =  zinda * rhoic * lfus * at_i_1d(ji) / MAX( 1._wp - at_i_1d(ji) , epsi20 ) * zdvres ! J.m-2 >=0
606!
607!               ! correct salt and mass fluxes
608!               sfx_bom_1d(ji) = sfx_bom_1d(ji) - sm_i_1d(ji) * a_i_1d(ji) * zdvres * rhoic * r1_rdtice ! this is only a raw approximation
609!               wfx_bom_1d(ji) = wfx_bom_1d(ji) - rhoic * a_i_1d(ji) * zdvres * r1_rdtice
610!            ENDIF
611!         END DO
612!      ENDIF
613
614      !-------------------------------------------
615      ! Update temperature, energy
616      !-------------------------------------------
617      DO ji = kideb, kiut
618         ht_i_1d(ji) =  MAX( 0._wp , ht_i_1d(ji) + dh_i_bott(ji) )
619      END DO 
620
621      !-------------------------------------------
622      ! 5. What to do with remaining energy
623      !-------------------------------------------
624      ! If heat still available for melting and snow remains, then melt more snow
625      !-------------------------------------------
626      zdeltah(:,:) = 0._wp ! important
627      DO ji = kideb, kiut
628         zq_rema(ji)     = zq_su(ji) + zq_bo(ji) 
629!         zindh           = 1._wp - MAX( 0._wp, SIGN( 1._wp, - ht_s_1d(ji) ) )   ! =1 if snow
630!         zindq           = 1._wp - MAX( 0._wp, SIGN( 1._wp, - zq_s(ji) + epsi20 ) )
631!         zdeltah  (ji,1) = - zindh * zindq * zq_rema(ji) / MAX( zq_s(ji), epsi20 )
632!         zdeltah  (ji,1) = MIN( 0._wp , MAX( zdeltah(ji,1) , - ht_s_1d(ji) ) ) ! bound melting
633!         zdh_s_mel(ji)   = zdh_s_mel(ji) + zdeltah(ji,1)   
634!         dh_s_tot (ji)   = dh_s_tot(ji) + zdeltah(ji,1)
635!         ht_s_1d   (ji)   = ht_s_1d(ji)   + zdeltah(ji,1)
636!       
637!         zq_rema(ji)     = zq_rema(ji) + zdeltah(ji,1) * zq_s(ji)                ! update available heat (J.m-2)
638!         ! heat used to melt snow
639!         hfx_snw_1d(ji)  = hfx_snw_1d(ji) - zdeltah(ji,1) * a_i_1d(ji) * zq_s(ji) * r1_rdtice ! W.m-2 (>0)
640!         ! Contribution to mass flux
641!         wfx_snw_1d(ji)  =  wfx_snw_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,1) * r1_rdtice
642!   
643         ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
644         ! Remaining heat flux (W.m-2) is sent to the ocean heat budget
645         hfx_out(ii,ij)  = hfx_out(ii,ij) + ( zq_1cat(ji) + zq_rema(ji) * a_i_1d(ji) ) * r1_rdtice
646
647         IF( ln_nicep .AND. zq_rema(ji) < 0. .AND. lwp ) WRITE(numout,*) 'ALERTE zq_rema <0 = ', zq_rema(ji)
648      END DO
649     
650      !
651      !------------------------------------------------------------------------------|
652      !  6) Snow-Ice formation                                                       |
653      !------------------------------------------------------------------------------|
654      ! When snow load excesses Archimede's limit, snow-ice interface goes down under sea-level,
655      ! flooding of seawater transforms snow into ice dh_snowice is positive for the ice
656      DO ji = kideb, kiut
657         !
658         dh_snowice(ji) = MAX(  0._wp , ( rhosn * ht_s_1d(ji) + (rhoic-rau0) * ht_i_1d(ji) ) / ( rhosn+rau0-rhoic )  )
659
660         ht_i_1d(ji)     = ht_i_1d(ji) + dh_snowice(ji)
661         ht_s_1d(ji)     = ht_s_1d(ji) - dh_snowice(ji)
662
663         ! Salinity of snow ice
664         ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
665         zs_snic = zswitch_sal * sss_m(ii,ij) * ( rhoic - rhosn ) / rhoic + ( 1. - zswitch_sal ) * sm_i_1d(ji)
666
667         ! entrapment during snow ice formation
668         ! new salinity difference stored (to be used in limthd_ent.F90)
669         IF (  num_sal == 2  ) THEN
670            zswitch = MAX( 0._wp , SIGN( 1._wp , ht_i_1d(ji) - epsi10 ) )
671            ! salinity dif due to snow-ice formation
672            dsm_i_si_1d(ji) = ( zs_snic - sm_i_1d(ji) ) * dh_snowice(ji) / MAX( ht_i_1d(ji), epsi10 ) * zswitch     
673            ! salinity dif due to bottom growth
674            IF (  zf_tt(ji)  < 0._wp ) THEN
675               dsm_i_se_1d(ji) = ( s_i_new(ji) - sm_i_1d(ji) ) * dh_i_bott(ji) / MAX( ht_i_1d(ji), epsi10 ) * zswitch
676            ENDIF
677         ENDIF
678
679         ! Contribution to energy flux to the ocean [J/m2], >0 (if sst<0)
680         ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
681         zfmdt          = ( rhosn - rhoic ) * MAX( dh_snowice(ji), 0._wp )    ! <0
682         zsstK          = sst_m(ii,ij) + rt0                               
683         zEw            = rcp * ( zsstK - rt0 )
684         zQm            = zfmdt * zEw 
685         
686         ! Contribution to heat flux
687         hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice 
688
689         ! Contribution to salt flux
690         sfx_sni_1d(ji) = sfx_sni_1d(ji) + sss_m(ii,ij) * a_i_1d(ji) * zfmdt * r1_rdtice 
691         
692         ! Contribution to mass flux
693         ! All snow is thrown in the ocean, and seawater is taken to replace the volume
694         wfx_sni_1d(ji) = wfx_sni_1d(ji) - a_i_1d(ji) * dh_snowice(ji) * rhoic * r1_rdtice
695         wfx_snw_1d(ji) = wfx_snw_1d(ji) + a_i_1d(ji) * dh_snowice(ji) * rhosn * r1_rdtice
696
697         ! update heat content (J.m-2) and layer thickness
698         qh_i_old(ji,0) = qh_i_old(ji,0) + dh_snowice(ji) * q_s_1d(ji,1) + zfmdt * zEw
699         h_i_old (ji,0) = h_i_old (ji,0) + dh_snowice(ji)
700         
701         ! Total ablation (to debug)
702         IF( ht_i_1d(ji) <= 0._wp )   a_i_1d(ji) = 0._wp
703
704      END DO !ji
705
706      !
707      !-------------------------------------------
708      ! Update temperature, energy
709      !-------------------------------------------
710      !clem bug: we should take snow into account here
711      DO ji = kideb, kiut
712         zindh    =  1.0 - MAX( 0._wp , SIGN( 1._wp , - ht_i_1d(ji) ) ) 
713         t_su_1d(ji) =  zindh * t_su_1d(ji) + ( 1.0 - zindh ) * rtt
714      END DO  ! ji
715
716      DO jk = 1, nlay_s
717         DO ji = kideb,kiut
718            ! mask enthalpy
719            zinda        =  MAX(  0._wp , SIGN( 1._wp, - ht_s_1d(ji) )  )
720            q_s_1d(ji,jk) = ( 1.0 - zinda ) * q_s_1d(ji,jk)
721            ! recalculate t_s_1d from q_s_1d
722            t_s_1d(ji,jk) = rtt + ( 1._wp - zinda ) * ( - q_s_1d(ji,jk) / ( rhosn * cpic ) + lfus / cpic )
723         END DO
724      END DO
725
726      CALL wrk_dealloc( jpij, zh_s, zqprec, zq_su, zq_bo, zf_tt, zq_1cat, zq_rema )
727      CALL wrk_dealloc( jpij, zdh_s_mel, zdh_s_pre, zdh_s_sub, zqh_i, zqh_s, zq_s )
728      CALL wrk_dealloc( jpij, zintermelt )
729      CALL wrk_dealloc( jpij, nlay_i+1, zdeltah, zh_i )
730      CALL wrk_dealloc( jpij, icount )
731      !
732      !
733   END SUBROUTINE lim_thd_dh
734   
735#else
736   !!----------------------------------------------------------------------
737   !!   Default option                               NO  LIM3 sea-ice model
738   !!----------------------------------------------------------------------
739CONTAINS
740   SUBROUTINE lim_thd_dh          ! Empty routine
741   END SUBROUTINE lim_thd_dh
742#endif
743
744   !!======================================================================
745END MODULE limthd_dh
Note: See TracBrowser for help on using the repository browser.