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/2017/dev_r8183_ICEMODEL/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2017/dev_r8183_ICEMODEL/NEMOGCM/NEMO/LIM_SRC_3/limthd_dh.F90 @ 8239

Last change on this file since 8239 was 8239, checked in by clem, 7 years ago

merge with v3_6_CMIP6_ice_diagnostics@r8238

  • Property svn:keywords set to Id
File size: 37.1 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 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    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
27   
28   IMPLICIT NONE
29   PRIVATE
30
31   PUBLIC   lim_thd_dh      ! called by lim_thd
32   PUBLIC   lim_thd_snwblow ! called in sbcblk/sbcclio/sbccpl and here
33
34   INTERFACE lim_thd_snwblow
35      MODULE PROCEDURE lim_thd_snwblow_1d, lim_thd_snwblow_2d
36   END INTERFACE
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 )
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      !!
71      INTEGER  ::   ji , jk        ! dummy loop indices
72      INTEGER  ::   ii, ij         ! 2D corresponding indices to ji
73      INTEGER  ::   iter
74
75      REAL(wp) ::   ztmelts             ! local scalar
76      REAL(wp) ::   zdum       
77      REAL(wp) ::   zfracs       ! fractionation coefficient for bottom salt entrapment
78      REAL(wp) ::   zswi1        ! switch for computation of bottom salinity
79      REAL(wp) ::   zswi12       ! switch for computation of bottom salinity
80      REAL(wp) ::   zswi2        ! switch for computation of bottom salinity
81      REAL(wp) ::   zgrr         ! bottom growth rate
82      REAL(wp) ::   zt_i_new     ! bottom formation temperature
83
84      REAL(wp) ::   zQm          ! enthalpy exchanged with the ocean (J/m2), >0 towards the ocean
85      REAL(wp) ::   zEi          ! specific enthalpy of sea ice (J/kg)
86      REAL(wp) ::   zEw          ! specific enthalpy of exchanged water (J/kg)
87      REAL(wp) ::   zdE          ! specific enthalpy difference (J/kg)
88      REAL(wp) ::   zfmdt        ! exchange mass flux x time step (J/m2), >0 towards the ocean
89      REAL(wp) ::   zsstK        ! SST (K)
90
91      REAL(wp), POINTER, DIMENSION(:) ::   zqprec      ! energy of fallen snow                       (J.m-3)
92      REAL(wp), POINTER, DIMENSION(:) ::   zq_su       ! heat for surface ablation                   (J.m-2)
93      REAL(wp), POINTER, DIMENSION(:) ::   zq_bo       ! heat for bottom ablation                    (J.m-2)
94      REAL(wp), POINTER, DIMENSION(:) ::   zq_rema     ! remaining heat at the end of the routine    (J.m-2)
95      REAL(wp), POINTER, DIMENSION(:) ::   zf_tt       ! Heat budget to determine melting or freezing(W.m-2)
96      REAL(wp), POINTER, DIMENSION(:) ::   zevap_rema  ! remaining mass flux from sublimation        (kg.m-2)
97
98      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_mel   ! snow melt
99      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_pre   ! snow precipitation
100      REAL(wp), POINTER, DIMENSION(:) ::   zdh_s_sub   ! snow sublimation
101
102      REAL(wp), POINTER, DIMENSION(:,:) ::   zdeltah
103      REAL(wp), POINTER, DIMENSION(:,:) ::   zh_i      ! ice layer thickness
104      INTEGER , POINTER, DIMENSION(:,:) ::   icount    ! number of layers vanished by melting
105
106      REAL(wp), POINTER, DIMENSION(:) ::   zqh_i       ! total ice heat content  (J.m-2)
107      REAL(wp), POINTER, DIMENSION(:) ::   zsnw        ! distribution of snow after wind blowing
108
109      REAL(wp) :: zswitch_sal
110
111      ! Heat conservation
112      INTEGER  ::   num_iter_max
113
114      !!------------------------------------------------------------------
115
116      ! Discriminate between varying salinity (nn_icesal=2) and prescribed cases (other values)
117      SELECT CASE( nn_icesal )                  ! varying salinity or not
118         CASE( 1, 3 ) ;   zswitch_sal = 0       ! prescribed salinity profile
119         CASE( 2 )    ;   zswitch_sal = 1       ! varying salinity profile
120      END SELECT
121
122      CALL wrk_alloc( jpij, zqprec, zq_su, zq_bo, zf_tt, zq_rema, zsnw, zevap_rema )
123      CALL wrk_alloc( jpij, zdh_s_mel, zdh_s_pre, zdh_s_sub, zqh_i )
124      CALL wrk_alloc( jpij, nlay_i, zdeltah, zh_i )
125      CALL wrk_alloc( jpij, nlay_i, icount )
126       
127      zqprec   (:) = 0._wp ; zq_su    (:) = 0._wp ; zq_bo    (:) = 0._wp ; zf_tt(:) = 0._wp
128      zq_rema  (:) = 0._wp ; zsnw     (:) = 0._wp ; zevap_rema(:) = 0._wp ;
129      zdh_s_mel(:) = 0._wp ; zdh_s_pre(:) = 0._wp ; zdh_s_sub(:) = 0._wp ; zqh_i(:) = 0._wp
130
131      zdeltah(:,:) = 0._wp ; zh_i(:,:) = 0._wp       
132      icount (:,:) = 0
133
134      ! Initialize enthalpy at nlay_i+1
135      DO ji = kideb, kiut
136         q_i_1d(ji,nlay_i+1) = 0._wp
137      END DO
138
139      ! initialize layer thicknesses and enthalpies
140      h_i_old (:,0:nlay_i+1) = 0._wp
141      qh_i_old(:,0:nlay_i+1) = 0._wp
142      DO jk = 1, nlay_i
143         DO ji = kideb, kiut
144            h_i_old (ji,jk) = ht_i_1d(ji) * r1_nlay_i
145            qh_i_old(ji,jk) = q_i_1d(ji,jk) * h_i_old(ji,jk)
146         ENDDO
147      ENDDO
148      !
149      !------------------------------------------------------------------------------!
150      !  1) Calculate available heat for surface and bottom ablation                 !
151      !------------------------------------------------------------------------------!
152      !
153      DO ji = kideb, kiut
154         zdum       = qns_ice_1d(ji) + ( 1._wp - i0(ji) ) * qsr_ice_1d(ji) - fc_su(ji) 
155         zf_tt(ji)  = fc_bo_i(ji) + fhtur_1d(ji) + fhld_1d(ji) 
156
157         zq_su (ji) = MAX( 0._wp, zdum      * rdt_ice ) * MAX( 0._wp , SIGN( 1._wp, t_su_1d(ji) - rt0 ) )
158         zq_bo (ji) = MAX( 0._wp, zf_tt(ji) * rdt_ice )
159      END DO
160
161      !
162      !------------------------------------------------------------------------------!
163      ! If snow temperature is above freezing point, then snow melts
164      ! (should not happen but sometimes it does)
165      !------------------------------------------------------------------------------!
166      DO ji = kideb, kiut
167         IF( t_s_1d(ji,1) > rt0 ) THEN !!! Internal melting
168            ! Contribution to heat flux to the ocean [W.m-2], < 0 
169            hfx_res_1d(ji) = hfx_res_1d(ji) + q_s_1d(ji,1) * ht_s_1d(ji) * a_i_1d(ji) * r1_rdtice
170            ! Contribution to mass flux
171            wfx_snw_sum_1d(ji) = wfx_snw_sum_1d(ji) + rhosn * ht_s_1d(ji) * a_i_1d(ji) * r1_rdtice
172            ! updates
173            ht_s_1d(ji)   = 0._wp
174            q_s_1d (ji,1) = 0._wp
175            t_s_1d (ji,1) = rt0
176         END IF
177      END DO
178
179      !------------------------------------------------------------!
180      !  2) Computing layer thicknesses and enthalpies.            !
181      !------------------------------------------------------------!
182      !
183      DO jk = 1, nlay_i
184         DO ji = kideb, kiut
185            zh_i(ji,jk) = ht_i_1d(ji) * r1_nlay_i
186            zqh_i(ji)   = zqh_i(ji) + q_i_1d(ji,jk) * zh_i(ji,jk)
187         END DO
188      END DO
189      !
190      !------------------------------------------------------------------------------|
191      !  3) Surface ablation and sublimation                                         |
192      !------------------------------------------------------------------------------|
193      !
194      !-------------------------
195      ! 3.1 Snow precips / melt
196      !-------------------------
197      ! Snow accumulation in one thermodynamic time step
198      ! snowfall is partitionned between leads and ice
199      ! if snow fall was uniform, a fraction (1-at_i) would fall into leads
200      ! but because of the winds, more snow falls on leads than on sea ice
201      ! and a greater fraction (1-at_i)^beta of the total mass of snow
202      ! (beta < 1) falls in leads.
203      ! In reality, beta depends on wind speed,
204      ! and should decrease with increasing wind speed but here, it is
205      ! considered as a constant. an average value is 0.66
206      ! Martin Vancoppenolle, December 2006
207
208      CALL lim_thd_snwblow( 1. - at_i_1d(kideb:kiut), zsnw(kideb:kiut) ) ! snow distribution over ice after wind blowing
209
210      zdeltah(:,:) = 0._wp
211      DO ji = kideb, kiut
212         !-----------
213         ! Snow fall
214         !-----------
215         ! thickness change
216         zdh_s_pre(ji) = zsnw(ji) * sprecip_1d(ji) * rdt_ice * r1_rhosn / at_i_1d(ji)
217         ! enthalpy of the precip (>0, J.m-3)
218         zqprec   (ji) = - qprec_ice_1d(ji)   
219         IF( sprecip_1d(ji) == 0._wp ) zqprec(ji) = 0._wp
220         ! heat flux from snow precip (>0, W.m-2)
221         hfx_spr_1d(ji) = hfx_spr_1d(ji) + zdh_s_pre(ji) * a_i_1d(ji) * zqprec(ji) * r1_rdtice
222         ! mass flux, <0
223         wfx_spr_1d(ji) = wfx_spr_1d(ji) - rhosn * a_i_1d(ji) * zdh_s_pre(ji) * r1_rdtice
224
225         !---------------------
226         ! Melt of falling snow
227         !---------------------
228         ! thickness change
229         rswitch        = MAX( 0._wp , SIGN( 1._wp , zqprec(ji) - epsi20 ) )
230         zdeltah (ji,1) = - rswitch * zq_su(ji) / MAX( zqprec(ji) , epsi20 )
231         zdeltah (ji,1) = MAX( - zdh_s_pre(ji), zdeltah(ji,1) ) ! bound melting
232         ! heat used to melt snow (W.m-2, >0)
233         hfx_snw_1d(ji) = hfx_snw_1d(ji) - zdeltah(ji,1) * a_i_1d(ji) * zqprec(ji) * r1_rdtice
234         ! snow melting only = water into the ocean (then without snow precip), >0
235         wfx_snw_sum_1d(ji) = wfx_snw_sum_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,1) * r1_rdtice
236         ! updates available heat + precipitations after melting
237         zq_su     (ji) = MAX( 0._wp , zq_su (ji) + zdeltah(ji,1) * zqprec(ji) )     
238         zdh_s_pre (ji) = zdh_s_pre(ji) + zdeltah(ji,1)
239
240         ! update thickness
241         ht_s_1d(ji) = MAX( 0._wp , ht_s_1d(ji) + zdh_s_pre(ji) )
242      END DO
243
244      ! If heat still available (zq_su > 0), then melt more snow
245      zdeltah(:,:) = 0._wp
246      DO jk = 1, nlay_s
247         DO ji = kideb, kiut
248            ! thickness change
249            rswitch          = 1._wp - MAX( 0._wp, SIGN( 1._wp, - ht_s_1d(ji) ) ) 
250            rswitch          = rswitch * ( MAX( 0._wp, SIGN( 1._wp, q_s_1d(ji,jk) - epsi20 ) ) ) 
251            zdeltah  (ji,jk) = - rswitch * zq_su(ji) / MAX( q_s_1d(ji,jk), epsi20 )
252            zdeltah  (ji,jk) = MAX( zdeltah(ji,jk) , - ht_s_1d(ji) ) ! bound melting
253            zdh_s_mel(ji)    = zdh_s_mel(ji) + zdeltah(ji,jk)   
254            ! heat used to melt snow(W.m-2, >0)
255            hfx_snw_1d(ji)   = hfx_snw_1d(ji) - zdeltah(ji,jk) * a_i_1d(ji) * q_s_1d(ji,jk) * r1_rdtice 
256            ! snow melting only = water into the ocean (then without snow precip)
257            wfx_snw_sum_1d(ji)   = wfx_snw_sum_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
258            ! updates available heat + thickness
259            zq_su (ji)  = MAX( 0._wp , zq_su (ji) + zdeltah(ji,jk) * q_s_1d(ji,jk) )
260            ht_s_1d(ji) = MAX( 0._wp , ht_s_1d(ji) + zdeltah(ji,jk) )
261         END DO
262      END DO
263
264      !------------------------------
265      ! 3.2 Sublimation (part1: snow)
266      !------------------------------
267      ! qla_ice is always >=0 (upwards), heat goes to the atmosphere, therefore snow sublimates
268      ! clem comment: not counted in mass/heat exchange in limsbc since this is an exchange with atm. (not ocean)
269      zdeltah(:,:) = 0._wp
270      DO ji = kideb, kiut
271         zdh_s_sub(ji)  = MAX( - ht_s_1d(ji) , - evap_ice_1d(ji) * r1_rhosn * rdt_ice )
272         ! remaining evap in kg.m-2 (used for ice melting later on)
273         zevap_rema(ji)  = evap_ice_1d(ji) * rdt_ice + zdh_s_sub(ji) * rhosn
274         ! Heat flux by sublimation [W.m-2], < 0 (sublimate first snow that had fallen, then pre-existing snow)
275         zdeltah(ji,1)  = MAX( zdh_s_sub(ji), - zdh_s_pre(ji) )
276         hfx_sub_1d(ji) = hfx_sub_1d(ji) + ( zdeltah(ji,1) * zqprec(ji) + ( zdh_s_sub(ji) - zdeltah(ji,1) ) * q_s_1d(ji,1)  &
277            &                              ) * a_i_1d(ji) * r1_rdtice
278         ! Mass flux by sublimation
279         wfx_snw_sub_1d(ji) = wfx_snw_sub_1d(ji) - rhosn * a_i_1d(ji) * zdh_s_sub(ji) * r1_rdtice
280
281         ! new snow thickness
282         ht_s_1d(ji)    =  MAX( 0._wp , ht_s_1d(ji) + zdh_s_sub(ji) )
283         ! update precipitations after sublimation and correct sublimation
284         zdh_s_pre(ji) = zdh_s_pre(ji) + zdeltah(ji,1)
285         zdh_s_sub(ji) = zdh_s_sub(ji) - zdeltah(ji,1)
286      END DO
287     
288      ! --- Update snow diags --- !
289      DO ji = kideb, kiut
290         dh_s_tot(ji) = zdh_s_mel(ji) + zdh_s_pre(ji) + zdh_s_sub(ji)
291      END DO
292
293      !-------------------------------------------
294      ! 3.3 Update temperature, energy
295      !-------------------------------------------
296      ! new temp and enthalpy of the snow (remaining snow precip + remaining pre-existing snow)
297      DO jk = 1, nlay_s
298         DO ji = kideb,kiut
299            rswitch       = MAX( 0._wp , SIGN( 1._wp, ht_s_1d(ji) - epsi20 ) )
300            q_s_1d(ji,jk) = rswitch / MAX( ht_s_1d(ji), epsi20 ) *           &
301              &            ( ( zdh_s_pre(ji)               ) * zqprec(ji) +  &
302              &              ( ht_s_1d(ji) - zdh_s_pre(ji) ) * rhosn * ( cpic * ( rt0 - t_s_1d(ji,jk) ) + lfus ) )
303         END DO
304      END DO
305
306      !--------------------------
307      ! 3.4 Surface ice ablation
308      !--------------------------
309      zdeltah(:,:) = 0._wp ! important
310      DO jk = 1, nlay_i
311         DO ji = kideb, kiut
312            ztmelts           = - tmut * s_i_1d(ji,jk) + rt0          ! Melting point of layer k [K]
313           
314            IF( t_i_1d(ji,jk) >= ztmelts ) THEN !!! Internal melting
315
316               zEi            = - q_i_1d(ji,jk) * r1_rhoic            ! Specific enthalpy of layer k [J/kg, <0]       
317               zdE            = 0._wp                                 ! Specific enthalpy difference   (J/kg, <0)
318                                                                      ! set up at 0 since no energy is needed to melt water...(it is already melted)
319               zdeltah(ji,jk) = MIN( 0._wp , - zh_i(ji,jk) )          ! internal melting occurs when the internal temperature is above freezing     
320                                                                      ! this should normally not happen, but sometimes, heat diffusion leads to this
321               zfmdt          = - zdeltah(ji,jk) * rhoic              ! Mass flux x time step > 0
322                         
323               dh_i_surf(ji)  = dh_i_surf(ji) + zdeltah(ji,jk)        ! Cumulate surface melt
324               
325               zfmdt          = - rhoic * zdeltah(ji,jk)              ! Recompute mass flux [kg/m2, >0]
326
327               ! Contribution to heat flux to the ocean [W.m-2], <0 (ice enthalpy zEi is "sent" to the ocean)
328               hfx_res_1d(ji) = hfx_res_1d(ji) + zfmdt * a_i_1d(ji) * zEi * r1_rdtice
329               
330               ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
331               sfx_res_1d(ji) = sfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
332               
333               ! Contribution to mass flux
334               wfx_res_1d(ji) =  wfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
335
336            ELSE                                !!! Surface melting
337               
338               zEi            = - q_i_1d(ji,jk) * r1_rhoic            ! Specific enthalpy of layer k [J/kg, <0]
339               zEw            =    rcp * ( ztmelts - rt0 )            ! Specific enthalpy of resulting meltwater [J/kg, <0]
340               zdE            =    zEi - zEw                          ! Specific enthalpy difference < 0
341               
342               zfmdt          = - zq_su(ji) / zdE                     ! Mass flux to the ocean [kg/m2, >0]
343               
344               zdeltah(ji,jk) = - zfmdt * r1_rhoic                    ! Melt of layer jk [m, <0]
345               
346               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]
347               
348               zq_su(ji)      = MAX( 0._wp , zq_su(ji) - zdeltah(ji,jk) * rhoic * zdE ) ! update available heat
349               
350               dh_i_surf(ji)  = dh_i_surf(ji) + zdeltah(ji,jk)        ! Cumulate surface melt
351               
352               zfmdt          = - rhoic * zdeltah(ji,jk)              ! Recompute mass flux [kg/m2, >0]
353               
354               zQm            = zfmdt * zEw                           ! Energy of the melt water sent to the ocean [J/m2, <0]
355               
356               ! Contribution to salt flux >0 (clem: using sm_i_1d and not s_i_1d(jk) is ok)
357               sfx_sum_1d(ji) = sfx_sum_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
358               
359               ! Contribution to heat flux [W.m-2], < 0
360               hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
361               
362               ! Total heat flux used in this process [W.m-2], > 0 
363               hfx_sum_1d(ji) = hfx_sum_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
364               
365               ! Contribution to mass flux
366               wfx_sum_1d(ji) =  wfx_sum_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
367               
368            END IF
369            ! ----------------------
370            ! Sublimation part2: ice
371            ! ----------------------
372            zdum      = MAX( - ( zh_i(ji,jk) + zdeltah(ji,jk) ) , - zevap_rema(ji) * r1_rhoic )
373            zdeltah(ji,jk) = zdeltah(ji,jk) + zdum
374            dh_i_sub(ji)  = dh_i_sub(ji) + zdum
375            ! Salt flux > 0 (clem2016: flux is sent to the ocean for simplicity but salt should remain in the ice except if all ice is melted.
376            !                          It must be corrected at some point)
377            sfx_sub_1d(ji) = sfx_sub_1d(ji) - rhoic * a_i_1d(ji) * zdum * sm_i_1d(ji) * r1_rdtice
378            ! Heat flux [W.m-2], < 0
379            hfx_sub_1d(ji) = hfx_sub_1d(ji) + zdum * q_i_1d(ji,jk) * a_i_1d(ji) * r1_rdtice
380            ! Mass flux > 0
381            wfx_ice_sub_1d(ji) =  wfx_ice_sub_1d(ji) - rhoic * a_i_1d(ji) * zdum * r1_rdtice
382
383            ! update remaining mass flux
384            zevap_rema(ji)  = zevap_rema(ji) + zdum * rhoic
385           
386            ! record which layers have disappeared (for bottom melting)
387            !    => icount=0 : no layer has vanished
388            !    => icount=5 : 5 layers have vanished
389            rswitch       = MAX( 0._wp , SIGN( 1._wp , - ( zh_i(ji,jk) + zdeltah(ji,jk) ) ) ) 
390            icount(ji,jk) = NINT( rswitch )
391            zh_i(ji,jk)   = MAX( 0._wp , zh_i(ji,jk) + zdeltah(ji,jk) )
392                       
393            ! update heat content (J.m-2) and layer thickness
394            qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
395            h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
396         END DO
397      END DO
398      ! update ice thickness
399      DO ji = kideb, kiut
400         ht_i_1d(ji) =  MAX( 0._wp , ht_i_1d(ji) + dh_i_surf(ji) + dh_i_sub(ji) )
401      END DO
402
403      ! remaining "potential" evap is sent to ocean
404      DO ji = kideb, kiut
405         ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
406         wfx_err_sub(ii,ij) = wfx_err_sub(ii,ij) - zevap_rema(ji) * a_i_1d(ji) * r1_rdtice  ! <=0 (net evap for the ocean in kg.m-2.s-1)
407      END DO
408
409      !
410      !------------------------------------------------------------------------------!
411      ! 4) Basal growth / melt                                                       !
412      !------------------------------------------------------------------------------!
413      !
414      !------------------
415      ! 4.1 Basal growth
416      !------------------
417      ! Basal growth is driven by heat imbalance at the ice-ocean interface,
418      ! between the inner conductive flux  (fc_bo_i), from the open water heat flux
419      ! (fhld) and the turbulent ocean flux (fhtur).
420      ! fc_bo_i is positive downwards. fhtur and fhld are positive to the ice
421
422      ! If salinity varies in time, an iterative procedure is required, because
423      ! the involved quantities are inter-dependent.
424      ! Basal growth (dh_i_bott) depends upon new ice specific enthalpy (zEi),
425      ! which depends on forming ice salinity (s_i_new), which depends on dh/dt (dh_i_bott)
426      ! -> need for an iterative procedure, which converges quickly
427
428      num_iter_max = 1
429      IF( nn_icesal == 2 ) num_iter_max = 5
430
431      ! Iterative procedure
432      DO iter = 1, num_iter_max
433         DO ji = kideb, kiut
434            IF(  zf_tt(ji) < 0._wp  ) THEN
435
436               ! New bottom ice salinity (Cox & Weeks, JGR88 )
437               !--- zswi1  if dh/dt < 2.0e-8
438               !--- zswi12 if 2.0e-8 < dh/dt < 3.6e-7
439               !--- zswi2  if dh/dt > 3.6e-7
440               zgrr               = MIN( 1.0e-3, MAX ( dh_i_bott(ji) * r1_rdtice , epsi10 ) )
441               zswi2              = MAX( 0._wp , SIGN( 1._wp , zgrr - 3.6e-7 ) )
442               zswi12             = MAX( 0._wp , SIGN( 1._wp , zgrr - 2.0e-8 ) ) * ( 1.0 - zswi2 )
443               zswi1              = 1. - zswi2 * zswi12
444               zfracs             = MIN ( zswi1  * 0.12 + zswi12 * ( 0.8925 + 0.0568 * LOG( 100.0 * zgrr ) )   &
445                  &               + zswi2  * 0.26 / ( 0.26 + 0.74 * EXP ( - 724300.0 * zgrr ) )  , 0.5 )
446
447               ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
448
449               s_i_new(ji)        = zswitch_sal * zfracs * sss_m(ii,ij)  &  ! New ice salinity
450                                  + ( 1. - zswitch_sal ) * sm_i_1d(ji) 
451               ! New ice growth
452               ztmelts            = - tmut * s_i_new(ji) + rt0          ! New ice melting point (K)
453
454               zt_i_new           = zswitch_sal * t_bo_1d(ji) + ( 1. - zswitch_sal) * t_i_1d(ji, nlay_i)
455               
456               zEi                = cpic * ( zt_i_new - ztmelts ) &     ! Specific enthalpy of forming ice (J/kg, <0)     
457                  &               - lfus * ( 1.0 - ( ztmelts - rt0 ) / ( zt_i_new - rt0 ) )   &
458                  &               + rcp  * ( ztmelts-rt0 )         
459
460               zEw                = rcp  * ( t_bo_1d(ji) - rt0 )         ! Specific enthalpy of seawater (J/kg, < 0)
461
462               zdE                = zEi - zEw                           ! Specific enthalpy difference (J/kg, <0)
463
464               dh_i_bott(ji)      = rdt_ice * MAX( 0._wp , zf_tt(ji) / ( zdE * rhoic ) )
465
466               q_i_1d(ji,nlay_i+1) = -zEi * rhoic                        ! New ice energy of melting (J/m3, >0)
467               
468            ENDIF
469         END DO
470      END DO
471
472      ! Contribution to Energy and Salt Fluxes
473      DO ji = kideb, kiut
474         IF(  zf_tt(ji) < 0._wp  ) THEN
475            ! New ice growth
476                                   
477            zfmdt          = - rhoic * dh_i_bott(ji)             ! Mass flux x time step (kg/m2, < 0)
478
479            ztmelts        = - tmut * s_i_new(ji) + rt0          ! New ice melting point (K)
480           
481            zt_i_new       = zswitch_sal * t_bo_1d(ji) + ( 1. - zswitch_sal) * t_i_1d(ji, nlay_i)
482           
483            zEi            = cpic * ( zt_i_new - ztmelts ) &     ! Specific enthalpy of forming ice (J/kg, <0)     
484               &               - lfus * ( 1.0 - ( ztmelts - rt0 ) / ( zt_i_new - rt0 ) )   &
485               &               + rcp  * ( ztmelts-rt0 )         
486           
487            zEw            = rcp  * ( t_bo_1d(ji) - rt0 )         ! Specific enthalpy of seawater (J/kg, < 0)
488           
489            zdE            = zEi - zEw                           ! Specific enthalpy difference (J/kg, <0)
490           
491            ! Contribution to heat flux to the ocean [W.m-2], >0 
492            hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
493
494            ! Total heat flux used in this process [W.m-2], <0 
495            hfx_bog_1d(ji) = hfx_bog_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
496           
497            ! Contribution to salt flux, <0
498            sfx_bog_1d(ji) = sfx_bog_1d(ji) - rhoic * a_i_1d(ji) * dh_i_bott(ji) * s_i_new(ji) * r1_rdtice
499
500            ! Contribution to mass flux, <0
501            wfx_bog_1d(ji) =  wfx_bog_1d(ji) - rhoic * a_i_1d(ji) * dh_i_bott(ji) * r1_rdtice
502
503            ! update heat content (J.m-2) and layer thickness
504            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)
505            h_i_old (ji,nlay_i+1) = h_i_old (ji,nlay_i+1) + dh_i_bott(ji)
506         ENDIF
507      END DO
508
509      !----------------
510      ! 4.2 Basal melt
511      !----------------
512      zdeltah(:,:) = 0._wp ! important
513      DO jk = nlay_i, 1, -1
514         DO ji = kideb, kiut
515            IF(  zf_tt(ji)  >  0._wp  .AND. jk > icount(ji,jk) ) THEN   ! do not calculate where layer has already disappeared by surface melting
516
517               ztmelts = - tmut * s_i_1d(ji,jk) + rt0  ! Melting point of layer jk (K)
518
519               IF( t_i_1d(ji,jk) >= ztmelts ) THEN !!! Internal melting
520
521                  zEi               = - q_i_1d(ji,jk) * r1_rhoic    ! Specific enthalpy of melting ice (J/kg, <0)
522                  zdE               = 0._wp                         ! Specific enthalpy difference   (J/kg, <0)
523                                                                    ! set up at 0 since no energy is needed to melt water...(it is already melted)
524                  zdeltah   (ji,jk) = MIN( 0._wp , - zh_i(ji,jk) )  ! internal melting occurs when the internal temperature is above freezing     
525                                                                    ! this should normally not happen, but sometimes, heat diffusion leads to this
526
527                  dh_i_bott (ji)    = dh_i_bott(ji) + zdeltah(ji,jk)
528
529                  zfmdt             = - zdeltah(ji,jk) * rhoic      ! Mass flux x time step > 0
530
531                  ! Contribution to heat flux to the ocean [W.m-2], <0 (ice enthalpy zEi is "sent" to the ocean)
532                  hfx_res_1d(ji) = hfx_res_1d(ji) + zfmdt * a_i_1d(ji) * zEi * r1_rdtice
533
534                  ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
535                  sfx_res_1d(ji) = sfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
536                                   
537                  ! Contribution to mass flux
538                  wfx_res_1d(ji) =  wfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
539
540                  ! update heat content (J.m-2) and layer thickness
541                  qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
542                  h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
543
544               ELSE                               !!! Basal melting
545
546                  zEi             = - q_i_1d(ji,jk) * r1_rhoic ! Specific enthalpy of melting ice (J/kg, <0)
547                  zEw             = rcp * ( ztmelts - rt0 )    ! Specific enthalpy of meltwater (J/kg, <0)
548                  zdE             = zEi - zEw                  ! Specific enthalpy difference   (J/kg, <0)
549
550                  zfmdt           = - zq_bo(ji) / zdE          ! Mass flux x time step (kg/m2, >0)
551
552                  zdeltah(ji,jk)  = - zfmdt * r1_rhoic         ! Gross thickness change
553
554                  zdeltah(ji,jk)  = MIN( 0._wp , MAX( zdeltah(ji,jk), - zh_i(ji,jk) ) ) ! bound thickness change
555                 
556                  zq_bo(ji)       = MAX( 0._wp , zq_bo(ji) - zdeltah(ji,jk) * rhoic * zdE ) ! update available heat. MAX is necessary for roundup errors
557
558                  dh_i_bott(ji)   = dh_i_bott(ji) + zdeltah(ji,jk)    ! Update basal melt
559
560                  zfmdt           = - zdeltah(ji,jk) * rhoic          ! Mass flux x time step > 0
561
562                  zQm             = zfmdt * zEw         ! Heat exchanged with ocean
563
564                  ! Contribution to heat flux to the ocean [W.m-2], <0 
565                  hfx_thd_1d(ji)  = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
566
567                  ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
568                  sfx_bom_1d(ji)  = sfx_bom_1d(ji) - rhoic *  a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
569                 
570                  ! Total heat flux used in this process [W.m-2], >0 
571                  hfx_bom_1d(ji)  = hfx_bom_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
572                 
573                  ! Contribution to mass flux
574                  wfx_bom_1d(ji)  =  wfx_bom_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
575
576                  ! update heat content (J.m-2) and layer thickness
577                  qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
578                  h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
579               ENDIF
580           
581            ENDIF
582         END DO
583      END DO
584
585      !-------------------------------------------
586      ! Update temperature, energy
587      !-------------------------------------------
588      DO ji = kideb, kiut
589         ht_i_1d(ji) =  MAX( 0._wp , ht_i_1d(ji) + dh_i_bott(ji) )
590      END DO 
591
592      !-------------------------------------------
593      ! 5. What to do with remaining energy
594      !-------------------------------------------
595      ! If heat still available for melting and snow remains, then melt more snow
596      !-------------------------------------------
597      zdeltah(:,:) = 0._wp ! important
598      DO ji = kideb, kiut
599         zq_rema(ji)     = zq_su(ji) + zq_bo(ji) 
600         rswitch         = 1._wp - MAX( 0._wp, SIGN( 1._wp, - ht_s_1d(ji) ) )   ! =1 if snow
601         rswitch         = rswitch * MAX( 0._wp, SIGN( 1._wp, q_s_1d(ji,1) - epsi20 ) )
602         zdeltah  (ji,1) = - rswitch * zq_rema(ji) / MAX( q_s_1d(ji,1), epsi20 )
603         zdeltah  (ji,1) = MIN( 0._wp , MAX( zdeltah(ji,1) , - ht_s_1d(ji) ) ) ! bound melting
604         dh_s_tot (ji)   = dh_s_tot(ji)  + zdeltah(ji,1)
605         ht_s_1d   (ji)  = ht_s_1d(ji)   + zdeltah(ji,1)
606       
607         zq_rema(ji)     = zq_rema(ji) + zdeltah(ji,1) * q_s_1d(ji,1)                ! update available heat (J.m-2)
608         ! heat used to melt snow
609         hfx_snw_1d(ji)  = hfx_snw_1d(ji) - zdeltah(ji,1) * a_i_1d(ji) * q_s_1d(ji,1) * r1_rdtice ! W.m-2 (>0)
610         ! Contribution to mass flux
611         wfx_snw_sum_1d(ji)  =  wfx_snw_sum_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,1) * r1_rdtice
612         !   
613         ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
614         ! Remaining heat flux (W.m-2) is sent to the ocean heat budget
615         hfx_out(ii,ij)  = hfx_out(ii,ij) + ( zq_rema(ji) * a_i_1d(ji) ) * r1_rdtice
616
617         IF( ln_limctl .AND. zq_rema(ji) < 0. .AND. lwp ) WRITE(numout,*) 'ALERTE zq_rema <0 = ', zq_rema(ji)
618      END DO
619
620      ! Water fluxes
621      DO ji = kideb, kiut
622         wfx_sub_1d(ji) = wfx_snw_sub_1d(ji) + wfx_ice_sub_1d(ji) ! sum ice and snow sublimation contributions
623      END DO
624
625      !
626      !------------------------------------------------------------------------------|
627      !  6) Snow-Ice formation                                                       |
628      !------------------------------------------------------------------------------|
629      ! When snow load excesses Archimede's limit, snow-ice interface goes down under sea-level,
630      ! flooding of seawater transforms snow into ice dh_snowice is positive for the ice
631      DO ji = kideb, kiut
632         !
633         dh_snowice(ji) = MAX(  0._wp , ( rhosn * ht_s_1d(ji) + (rhoic-rau0) * ht_i_1d(ji) ) / ( rhosn+rau0-rhoic )  )
634
635         ht_i_1d(ji)    = ht_i_1d(ji) + dh_snowice(ji)
636         ht_s_1d(ji)    = ht_s_1d(ji) - dh_snowice(ji)
637
638         ! Contribution to energy flux to the ocean [J/m2], >0 (if sst<0)
639         ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
640         zfmdt          = ( rhosn - rhoic ) * dh_snowice(ji)    ! <0
641         zsstK          = sst_m(ii,ij) + rt0                               
642         zEw            = rcp * ( zsstK - rt0 )
643         zQm            = zfmdt * zEw 
644         
645         ! Contribution to heat flux
646         hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice 
647
648         ! Contribution to salt flux
649         sfx_sni_1d(ji) = sfx_sni_1d(ji) + sss_m(ii,ij) * a_i_1d(ji) * zfmdt * r1_rdtice 
650
651         ! virtual salt flux to keep salinity constant
652         IF( nn_icesal == 1 .OR. nn_icesal == 3 )  THEN
653            sfx_bri_1d(ji) = sfx_bri_1d(ji) - sss_m(ii,ij) * a_i_1d(ji) * zfmdt                  * r1_rdtice  & ! put back sss_m     into the ocean
654               &                            - sm_i_1d(ji)  * a_i_1d(ji) * dh_snowice(ji) * rhoic * r1_rdtice    ! and get  rn_icesal from the ocean
655         ENDIF
656
657         ! Contribution to mass flux
658         ! All snow is thrown in the ocean, and seawater is taken to replace the volume
659         wfx_sni_1d(ji) = wfx_sni_1d(ji) - a_i_1d(ji) * dh_snowice(ji) * rhoic * r1_rdtice
660         wfx_snw_1d(ji) = wfx_snw_1d(ji) + a_i_1d(ji) * dh_snowice(ji) * rhosn * r1_rdtice
661
662         ! update heat content (J.m-2) and layer thickness
663         qh_i_old(ji,0) = qh_i_old(ji,0) + dh_snowice(ji) * q_s_1d(ji,1) + zfmdt * zEw
664         h_i_old (ji,0) = h_i_old (ji,0) + dh_snowice(ji)
665         
666      END DO
667
668      !
669      !-------------------------------------------
670      ! Update temperature, energy
671      !-------------------------------------------
672      DO ji = kideb, kiut
673         rswitch     =  1.0 - MAX( 0._wp , SIGN( 1._wp , - ht_i_1d(ji) ) ) 
674         t_su_1d(ji) =  rswitch * t_su_1d(ji) + ( 1.0 - rswitch ) * rt0
675      END DO
676
677      DO jk = 1, nlay_s
678         DO ji = kideb,kiut
679            ! mask enthalpy
680            rswitch       = 1._wp - MAX(  0._wp , SIGN( 1._wp, - ht_s_1d(ji) )  )
681            q_s_1d(ji,jk) = rswitch * q_s_1d(ji,jk)
682            ! recalculate t_s_1d from q_s_1d
683            t_s_1d(ji,jk) = rt0 + rswitch * ( - q_s_1d(ji,jk) / ( rhosn * cpic ) + lfus / cpic )
684         END DO
685      END DO
686
687      ! --- ensure that a_i = 0 where ht_i = 0 ---
688      WHERE( ht_i_1d == 0._wp ) a_i_1d = 0._wp
689     
690      CALL wrk_dealloc( jpij, zqprec, zq_su, zq_bo, zf_tt, zq_rema, zsnw, zevap_rema )
691      CALL wrk_dealloc( jpij, zdh_s_mel, zdh_s_pre, zdh_s_sub, zqh_i )
692      CALL wrk_dealloc( jpij, nlay_i, zdeltah, zh_i )
693      CALL wrk_dealloc( jpij, nlay_i, icount )
694      !
695      !
696   END SUBROUTINE lim_thd_dh
697
698
699   !!--------------------------------------------------------------------------
700   !! INTERFACE lim_thd_snwblow
701   !! ** Purpose :   Compute distribution of precip over the ice
702   !!--------------------------------------------------------------------------
703   SUBROUTINE lim_thd_snwblow_2d( pin, pout )
704      REAL(wp), DIMENSION(:,:), INTENT(in   ) :: pin   ! previous fraction lead ( pfrld or (1. - a_i_b) )
705      REAL(wp), DIMENSION(:,:), INTENT(inout) :: pout
706      pout = ( 1._wp - ( pin )**rn_betas )
707   END SUBROUTINE lim_thd_snwblow_2d
708
709   SUBROUTINE lim_thd_snwblow_1d( pin, pout )
710      REAL(wp), DIMENSION(:), INTENT(in   ) :: pin
711      REAL(wp), DIMENSION(:), INTENT(inout) :: pout
712      pout = ( 1._wp - ( pin )**rn_betas )
713   END SUBROUTINE lim_thd_snwblow_1d
714
715   
716#else
717   !!----------------------------------------------------------------------
718   !!   Default option                               NO  LIM3 sea-ice model
719   !!----------------------------------------------------------------------
720CONTAINS
721   SUBROUTINE lim_thd_dh          ! Empty routine
722   END SUBROUTINE lim_thd_dh
723#endif
724
725   !!======================================================================
726END MODULE limthd_dh
Note: See TracBrowser for help on using the repository browser.