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_dif.F90 in branches/2013/dev_r4028_CNRS_LIM3/NEMOGCM/NEMO/LIM_SRC_3 – NEMO

source: branches/2013/dev_r4028_CNRS_LIM3/NEMOGCM/NEMO/LIM_SRC_3/limthd_dif.F90 @ 4649

Last change on this file since 4649 was 4649, checked in by clem, 10 years ago

finalizing LIM3 heat budget conservation + multiple minor bugs corrections

  • Property svn:keywords set to Id
File size: 37.4 KB
Line 
1MODULE limthd_dif
2   !!======================================================================
3   !!                       ***  MODULE limthd_dif ***
4   !!                       heat diffusion in sea ice
5   !!                   computation of surface and inner T 
6   !!======================================================================
7   !! History :  LIM  ! 02-2003 (M. Vancoppenolle) original 1D code
8   !!                 ! 06-2005 (M. Vancoppenolle) 3d version
9   !!                 ! 11-2006 (X Fettweis) Vectorization by Xavier
10   !!                 ! 04-2007 (M. Vancoppenolle) Energy conservation
11   !!            4.0  ! 2011-02 (G. Madec) dynamical allocation
12   !!             -   ! 2012-05 (C. Rousset) add penetration solar flux
13   !!----------------------------------------------------------------------
14#if defined key_lim3
15   !!----------------------------------------------------------------------
16   !!   'key_lim3'                                      LIM3 sea-ice model
17   !!----------------------------------------------------------------------
18   USE par_oce        ! ocean parameters
19   USE phycst         ! physical constants (ocean directory)
20   USE ice            ! LIM-3 variables
21   USE par_ice        ! LIM-3 parameters
22   USE thd_ice        ! LIM-3: 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   USE cpl_oasis3, ONLY : lk_cpl
28
29   IMPLICIT NONE
30   PRIVATE
31
32   PUBLIC   lim_thd_dif   ! called by lim_thd
33
34   REAL(wp) ::   epsi10 = 1.e-10_wp    !
35   !!----------------------------------------------------------------------
36   !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2011)
37   !! $Id$
38   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
39   !!----------------------------------------------------------------------
40CONTAINS
41
42   SUBROUTINE lim_thd_dif( kideb , kiut , jl )
43      !!------------------------------------------------------------------
44      !!                ***  ROUTINE lim_thd_dif  ***
45      !! ** Purpose :
46      !!           This routine determines the time evolution of snow and sea-ice
47      !!           temperature profiles.
48      !! ** Method  :
49      !!           This is done by solving the heat equation diffusion with
50      !!           a Neumann boundary condition at the surface and a Dirichlet one
51      !!           at the bottom. Solar radiation is partially absorbed into the ice.
52      !!           The specific heat and thermal conductivities depend on ice salinity
53      !!           and temperature to take into account brine pocket melting. The
54      !!           numerical
55      !!           scheme is an iterative Crank-Nicolson on a non-uniform multilayer grid
56      !!           in the ice and snow system.
57      !!
58      !!           The successive steps of this routine are
59      !!           1.  Thermal conductivity at the interfaces of the ice layers
60      !!           2.  Internal absorbed radiation
61      !!           3.  Scale factors due to non-uniform grid
62      !!           4.  Kappa factors
63      !!           Then iterative procedure begins
64      !!           5.  specific heat in the ice
65      !!           6.  eta factors
66      !!           7.  surface flux computation
67      !!           8.  tridiagonal system terms
68      !!           9.  solving the tridiagonal system with Gauss elimination
69      !!           Iterative procedure ends according to a criterion on evolution
70      !!           of temperature
71      !!
72      !! ** Arguments :
73      !!           kideb , kiut : Starting and ending points on which the
74      !!                         the computation is applied
75      !!
76      !! ** Inputs / Ouputs : (global commons)
77      !!           surface temperature : t_su_b
78      !!           ice/snow temperatures   : t_i_b, t_s_b
79      !!           ice salinities          : s_i_b
80      !!           number of layers in the ice/snow: nlay_i, nlay_s
81      !!           profile of the ice/snow layers : z_i, z_s
82      !!           total ice/snow thickness : ht_i_b, ht_s_b
83      !!
84      !! ** External :
85      !!
86      !! ** References :
87      !!
88      !! ** History :
89      !!           (02-2003) Martin Vancoppenolle, Louvain-la-Neuve, Belgium
90      !!           (06-2005) Martin Vancoppenolle, 3d version
91      !!           (11-2006) Vectorized by Xavier Fettweis (UCL-ASTR)
92      !!           (04-2007) Energy conservation tested by M. Vancoppenolle
93      !!------------------------------------------------------------------
94      INTEGER , INTENT(in) ::   kideb, kiut   ! Start/End point on which the  the computation is applied
95      INTEGER , INTENT(in) ::   jl            ! Thickness cateogry number
96
97      !! * Local variables
98      INTEGER ::   ji          ! spatial loop index
99      INTEGER ::   ii, ij      ! temporary dummy loop index
100      INTEGER ::   numeq       ! current reference number of equation
101      INTEGER ::   layer       ! vertical dummy loop index
102      INTEGER ::   nconv       ! number of iterations in iterative procedure
103      INTEGER ::   minnumeqmin, maxnumeqmax
104      INTEGER, POINTER, DIMENSION(:) ::   numeqmin   ! reference number of top equation
105      INTEGER, POINTER, DIMENSION(:) ::   numeqmax   ! reference number of bottom equation
106      INTEGER, POINTER, DIMENSION(:) ::   isnow      ! switch for presence (1) or absence (0) of snow
107      REAL(wp) ::   zg1s      =  2._wp        ! for the tridiagonal system
108      REAL(wp) ::   zg1       =  2._wp        !
109      REAL(wp) ::   zgamma    =  18009._wp    ! for specific heat
110      REAL(wp) ::   zbeta     =  0.117_wp     ! for thermal conductivity (could be 0.13)
111      REAL(wp) ::   zraext_s  =  1.e+8_wp     ! extinction coefficient of radiation in the snow
112      REAL(wp) ::   zkimin    =  0.10_wp      ! minimum ice thermal conductivity
113      REAL(wp) ::   ztsu_err  =  1.e-5_wp     ! range around which t_su is considered as 0°C
114      REAL(wp) ::   ztmelt_i    ! ice melting temperature
115      REAL(wp) ::   zerritmax   ! current maximal error on temperature
116      REAL(wp), POINTER, DIMENSION(:) ::   ztfs        ! ice melting point
117      REAL(wp), POINTER, DIMENSION(:) ::   ztsuold     ! old surface temperature (before the iterative procedure )
118      REAL(wp), POINTER, DIMENSION(:) ::   ztsuoldit   ! surface temperature at previous iteration
119      REAL(wp), POINTER, DIMENSION(:) ::   zh_i        ! ice layer thickness
120      REAL(wp), POINTER, DIMENSION(:) ::   zh_s        ! snow layer thickness
121      REAL(wp), POINTER, DIMENSION(:) ::   zfsw        ! solar radiation absorbed at the surface
122      REAL(wp), POINTER, DIMENSION(:) ::   zf          ! surface flux function
123      REAL(wp), POINTER, DIMENSION(:) ::   dzf         ! derivative of the surface flux function
124      REAL(wp), POINTER, DIMENSION(:) ::   zerrit      ! current error on temperature
125      REAL(wp), POINTER, DIMENSION(:) ::   zdifcase    ! case of the equation resolution (1->4)
126      REAL(wp), POINTER, DIMENSION(:) ::   zftrice     ! solar radiation transmitted through the ice
127      REAL(wp), POINTER, DIMENSION(:) ::   zihic, zhsu
128      REAL(wp), POINTER, DIMENSION(:,:) ::   ztcond_i    ! Ice thermal conductivity
129      REAL(wp), POINTER, DIMENSION(:,:) ::   zradtr_i    ! Radiation transmitted through the ice
130      REAL(wp), POINTER, DIMENSION(:,:) ::   zradab_i    ! Radiation absorbed in the ice
131      REAL(wp), POINTER, DIMENSION(:,:) ::   zkappa_i    ! Kappa factor in the ice
132      REAL(wp), POINTER, DIMENSION(:,:) ::   ztiold      ! Old temperature in the ice
133      REAL(wp), POINTER, DIMENSION(:,:) ::   zeta_i      ! Eta factor in the ice
134      REAL(wp), POINTER, DIMENSION(:,:) ::   ztitemp     ! Temporary temperature in the ice to check the convergence
135      REAL(wp), POINTER, DIMENSION(:,:) ::   zspeche_i   ! Ice specific heat
136      REAL(wp), POINTER, DIMENSION(:,:) ::   z_i         ! Vertical cotes of the layers in the ice
137      REAL(wp), POINTER, DIMENSION(:,:) ::   zradtr_s    ! Radiation transmited through the snow
138      REAL(wp), POINTER, DIMENSION(:,:) ::   zradab_s    ! Radiation absorbed in the snow
139      REAL(wp), POINTER, DIMENSION(:,:) ::   zkappa_s    ! Kappa factor in the snow
140      REAL(wp), POINTER, DIMENSION(:,:) ::   zeta_s       ! Eta factor in the snow
141      REAL(wp), POINTER, DIMENSION(:,:) ::   ztstemp      ! Temporary temperature in the snow to check the convergence
142      REAL(wp), POINTER, DIMENSION(:,:) ::   ztsold       ! Temporary temperature in the snow
143      REAL(wp), POINTER, DIMENSION(:,:) ::   z_s          ! Vertical cotes of the layers in the snow
144      REAL(wp), POINTER, DIMENSION(:,:) ::   zindterm   ! Independent term
145      REAL(wp), POINTER, DIMENSION(:,:) ::   zindtbis   ! temporary independent term
146      REAL(wp), POINTER, DIMENSION(:,:) ::   zdiagbis
147      REAL(wp), POINTER, DIMENSION(:,:,:) ::   ztrid   ! tridiagonal system terms
148      !!------------------------------------------------------------------     
149      !
150      CALL wrk_alloc( jpij, numeqmin, numeqmax, isnow )
151      CALL wrk_alloc( jpij, ztfs, ztsuold, ztsuoldit, zh_i, zh_s, zfsw )
152      CALL wrk_alloc( jpij, zf, dzf, zerrit, zdifcase, zftrice, zihic, zhsu )
153      CALL wrk_alloc( jpij, nlay_i+1, ztcond_i, zradtr_i, zradab_i, zkappa_i, ztiold, zeta_i, ztitemp, z_i, zspeche_i, kjstart=0)
154      CALL wrk_alloc( jpij, nlay_s+1,           zradtr_s, zradab_s, zkappa_s, ztsold, zeta_s, ztstemp, z_s, kjstart=0)
155      CALL wrk_alloc( jpij, jkmax+2, zindterm, zindtbis, zdiagbis  )
156      CALL wrk_alloc( jpij, jkmax+2, 3, ztrid )
157
158      !------------------------------------------------------------------------------!
159      ! 1) Initialization                                                            !
160      !------------------------------------------------------------------------------!
161      ! clem clean: replace just ztfs by rtt
162      DO ji = kideb , kiut
163         ! is there snow or not
164         isnow(ji)= NINT(  1._wp - MAX( 0._wp , SIGN(1._wp, - ht_s_b(ji) ) )  )
165         ! surface temperature of fusion
166         ztfs(ji) = REAL( isnow(ji) ) * rtt + REAL( 1 - isnow(ji) ) * rtt
167         ! layer thickness
168         zh_i(ji) = ht_i_b(ji) / REAL( nlay_i )
169         zh_s(ji) = ht_s_b(ji) / REAL( nlay_s )
170      END DO
171
172      !--------------------
173      ! Ice / snow layers
174      !--------------------
175
176      z_s(:,0) = 0._wp   ! vert. coord. of the up. lim. of the 1st snow layer
177      z_i(:,0) = 0._wp   ! vert. coord. of the up. lim. of the 1st ice layer
178
179      DO layer = 1, nlay_s            ! vert. coord of the up. lim. of the layer-th snow layer
180         DO ji = kideb , kiut
181            z_s(ji,layer) = z_s(ji,layer-1) + ht_s_b(ji) / REAL( nlay_s )
182         END DO
183      END DO
184
185      DO layer = 1, nlay_i            ! vert. coord of the up. lim. of the layer-th ice layer
186         DO ji = kideb , kiut
187            z_i(ji,layer) = z_i(ji,layer-1) + ht_i_b(ji) / REAL( nlay_i )
188         END DO
189      END DO
190      !
191      !------------------------------------------------------------------------------|
192      ! 2) Radiations                                                                |
193      !------------------------------------------------------------------------------|
194      !
195      !-------------------
196      ! Computation of i0
197      !-------------------
198      ! i0 describes the fraction of solar radiation which does not contribute
199      ! to the surface energy budget but rather penetrates inside the ice.
200      ! We assume that no radiation is transmitted through the snow
201      ! If there is no no snow
202      ! zfsw    = (1-i0).qsr_ice   is absorbed at the surface
203      ! zftrice = io.qsr_ice       is below the surface
204      ! ftr_ice = io.qsr_ice.exp(-k(h_i)) transmitted below the ice
205
206      DO ji = kideb , kiut
207         ! switches
208         isnow(ji) = NINT(  1._wp - MAX( 0._wp , SIGN( 1._wp , - ht_s_b(ji) ) )  ) 
209         ! hs > 0, isnow = 1
210         zhsu (ji) = hnzst  ! threshold for the computation of i0
211         zihic(ji) = MAX( 0._wp , 1._wp - ( ht_i_b(ji) / zhsu(ji) ) )     
212
213         i0(ji)    = REAL( 1 - isnow(ji) ) * ( fr1_i0_1d(ji) + zihic(ji) * fr2_i0_1d(ji) )
214         !fr1_i0_1d = i0 for a thin ice surface
215         !fr1_i0_2d = i0 for a thick ice surface
216         !            a function of the cloud cover
217         !
218         !i0(ji)     =  (1.0-FLOAT(isnow(ji)))*3.0/(100*ht_s_b(ji)+10.0)
219         !formula used in Cice
220      END DO
221
222      !-------------------------------------------------------
223      ! Solar radiation absorbed / transmitted at the surface
224      ! Derivative of the non solar flux
225      !-------------------------------------------------------
226      DO ji = kideb , kiut
227         zfsw   (ji) =  qsr_ice_1d(ji) * ( 1 - i0(ji) )   ! Shortwave radiation absorbed at surface
228         zftrice(ji) =  qsr_ice_1d(ji) *       i0(ji)     ! Solar radiation transmitted below the surface layer
229         dzf    (ji) = dqns_ice_1d(ji)                    ! derivative of incoming nonsolar flux
230      END DO
231
232      !---------------------------------------------------------
233      ! Transmission - absorption of solar radiation in the ice
234      !---------------------------------------------------------
235
236      DO ji = kideb, kiut           ! snow initialization
237         zradtr_s(ji,0) = zftrice(ji)     ! radiation penetrating through snow
238      END DO
239
240      DO layer = 1, nlay_s          ! Radiation through snow
241         DO ji = kideb, kiut
242            !                             ! radiation transmitted below the layer-th snow layer
243            zradtr_s(ji,layer) = zradtr_s(ji,0) * EXP( - zraext_s * ( MAX ( 0._wp , z_s(ji,layer) ) ) )
244            !                             ! radiation absorbed by the layer-th snow layer
245            zradab_s(ji,layer) = zradtr_s(ji,layer-1) - zradtr_s(ji,layer)
246         END DO
247      END DO
248
249      DO ji = kideb, kiut           ! ice initialization
250         zradtr_i(ji,0) = zradtr_s(ji,nlay_s) * REAL( isnow(ji) ) + zftrice(ji) * REAL( 1 - isnow(ji) )
251      END DO
252
253      DO layer = 1, nlay_i          ! Radiation through ice
254         DO ji = kideb, kiut
255            !                             ! radiation transmitted below the layer-th ice layer
256            zradtr_i(ji,layer) = zradtr_i(ji,0) * EXP( - kappa_i * ( MAX ( 0._wp , z_i(ji,layer) ) ) )
257            !                             ! radiation absorbed by the layer-th ice layer
258            zradab_i(ji,layer) = zradtr_i(ji,layer-1) - zradtr_i(ji,layer)
259         END DO
260      END DO
261
262      DO ji = kideb, kiut           ! Radiation transmitted below the ice
263         !!!ftr_ice_1d(ji) = ftr_ice_1d(ji) + iatte_1d(ji) * zradtr_i(ji,nlay_i) * a_i_b(ji) / at_i_b(ji) ! clem modif
264         ftr_ice_1d(ji) = zradtr_i(ji,nlay_i) 
265      END DO
266
267      !
268      !------------------------------------------------------------------------------|
269      !  3) Iterative procedure begins                                               |
270      !------------------------------------------------------------------------------|
271      !
272      DO ji = kideb, kiut        ! Old surface temperature
273         ztsuold  (ji) =  t_su_b(ji)                              ! temperature at the beg of iter pr.
274         ztsuoldit(ji) =  t_su_b(ji)                              ! temperature at the previous iter
275         t_su_b   (ji) =  MIN( t_su_b(ji), ztfs(ji) - ztsu_err )  ! necessary
276         !!ztsuold  (ji) =  t_su_b(ji)                              ! temperature at the beg of iter pr.
277         !!ztsuoldit(ji) =  t_su_b(ji)                              ! temperature at the previous iter
278         zerrit   (ji) =  1000._wp                                ! initial value of error
279      END DO
280
281      DO layer = 1, nlay_s       ! Old snow temperature
282         DO ji = kideb , kiut
283            ztsold(ji,layer) =  t_s_b(ji,layer)
284         END DO
285      END DO
286
287      DO layer = 1, nlay_i       ! Old ice temperature
288         DO ji = kideb , kiut
289            ztiold(ji,layer) =  t_i_b(ji,layer)
290         END DO
291      END DO
292
293      nconv     =  0           ! number of iterations
294      zerritmax =  1000._wp    ! maximal value of error on all points
295
296      DO WHILE ( zerritmax > maxer_i_thd .AND. nconv < nconv_i_thd )
297         !
298         nconv = nconv + 1
299         !
300         !------------------------------------------------------------------------------|
301         ! 4) Sea ice thermal conductivity                                              |
302         !------------------------------------------------------------------------------|
303         !
304         IF( thcon_i_swi == 0 ) THEN      ! Untersteiner (1964) formula
305            DO ji = kideb , kiut
306               ztcond_i(ji,0)        = rcdic + zbeta*s_i_b(ji,1) / MIN(-epsi10,t_i_b(ji,1)-rtt)
307               ztcond_i(ji,0)        = MAX(ztcond_i(ji,0),zkimin)
308            END DO
309            DO layer = 1, nlay_i-1
310               DO ji = kideb , kiut
311                  ztcond_i(ji,layer) = rcdic + zbeta*( s_i_b(ji,layer) + s_i_b(ji,layer+1) ) /  &
312                     MIN(-2.0_wp * epsi10, t_i_b(ji,layer)+t_i_b(ji,layer+1) - 2.0_wp * rtt)
313                  ztcond_i(ji,layer) = MAX(ztcond_i(ji,layer),zkimin)
314               END DO
315            END DO
316         ENDIF
317
318         IF( thcon_i_swi == 1 ) THEN      ! Pringle et al formula included: 2.11 + 0.09 S/T - 0.011.T
319            DO ji = kideb , kiut
320               ztcond_i(ji,0) = rcdic + 0.090_wp * s_i_b(ji,1) / MIN( -epsi10, t_i_b(ji,1)-rtt )   &
321                  &                   - 0.011_wp * ( t_i_b(ji,1) - rtt ) 
322               ztcond_i(ji,0) = MAX( ztcond_i(ji,0), zkimin )
323            END DO
324            DO layer = 1, nlay_i-1
325               DO ji = kideb , kiut
326                  ztcond_i(ji,layer) = rcdic + 0.090_wp * ( s_i_b(ji,layer) + s_i_b(ji,layer+1) )   &
327                     &                                  / MIN(-2.0_wp * epsi10, t_i_b(ji,layer)+t_i_b(ji,layer+1) - 2.0_wp * rtt)   &
328                     &                       - 0.0055_wp* ( t_i_b(ji,layer) + t_i_b(ji,layer+1) - 2.0*rtt ) 
329                  ztcond_i(ji,layer) = MAX( ztcond_i(ji,layer), zkimin )
330               END DO
331            END DO
332            DO ji = kideb , kiut
333               ztcond_i(ji,nlay_i) = rcdic + 0.090_wp * s_i_b(ji,nlay_i) / MIN(-epsi10,t_bo_b(ji)-rtt)   &
334                  &                        - 0.011_wp * ( t_bo_b(ji) - rtt ) 
335               ztcond_i(ji,nlay_i) = MAX( ztcond_i(ji,nlay_i), zkimin )
336            END DO
337         ENDIF
338         !
339         !------------------------------------------------------------------------------|
340         !  5) kappa factors                                                            |
341         !------------------------------------------------------------------------------|
342         !
343         DO ji = kideb, kiut
344
345            !-- Snow kappa factors
346            zkappa_s(ji,0)         = rcdsn / MAX(epsi10,zh_s(ji))
347            zkappa_s(ji,nlay_s)    = rcdsn / MAX(epsi10,zh_s(ji))
348         END DO
349
350         DO layer = 1, nlay_s-1
351            DO ji = kideb , kiut
352               zkappa_s(ji,layer)  = 2.0 * rcdsn / &
353                  MAX(epsi10,2.0*zh_s(ji))
354            END DO
355         END DO
356
357         DO layer = 1, nlay_i-1
358            DO ji = kideb , kiut
359               !-- Ice kappa factors
360               zkappa_i(ji,layer)  = 2.0*ztcond_i(ji,layer)/ &
361                  MAX(epsi10,2.0*zh_i(ji)) 
362            END DO
363         END DO
364
365         DO ji = kideb , kiut
366            zkappa_i(ji,0)        = ztcond_i(ji,0)/MAX(epsi10,zh_i(ji))
367            zkappa_i(ji,nlay_i)   = ztcond_i(ji,nlay_i) / MAX(epsi10,zh_i(ji))
368            !-- Interface
369            zkappa_s(ji,nlay_s)   = 2.0*rcdsn*ztcond_i(ji,0)/MAX(epsi10, &
370               (ztcond_i(ji,0)*zh_s(ji) + rcdsn*zh_i(ji)))
371            zkappa_i(ji,0)        = zkappa_s(ji,nlay_s)*REAL( isnow(ji) ) &
372               + zkappa_i(ji,0)*REAL( 1 - isnow(ji) )
373         END DO
374         !
375         !------------------------------------------------------------------------------|
376         ! 6) Sea ice specific heat, eta factors                                        |
377         !------------------------------------------------------------------------------|
378         !
379         DO layer = 1, nlay_i
380            DO ji = kideb , kiut
381               ztitemp(ji,layer)   = t_i_b(ji,layer)
382               zspeche_i(ji,layer) = cpic + zgamma*s_i_b(ji,layer)/ &
383                  MAX((t_i_b(ji,layer)-rtt)*(ztiold(ji,layer)-rtt),epsi10)
384               zeta_i(ji,layer)    = rdt_ice / MAX(rhoic*zspeche_i(ji,layer)*zh_i(ji), &
385                  epsi10)
386            END DO
387         END DO
388
389         DO layer = 1, nlay_s
390            DO ji = kideb , kiut
391               ztstemp(ji,layer) = t_s_b(ji,layer)
392               zeta_s(ji,layer)  = rdt_ice / MAX(rhosn*cpic*zh_s(ji),epsi10)
393            END DO
394         END DO
395         !
396         !------------------------------------------------------------------------------|
397         ! 7) surface flux computation                                                  |
398         !------------------------------------------------------------------------------|
399         !
400         DO ji = kideb , kiut
401            ! update of the non solar flux according to the update in T_su
402            qns_ice_1d(ji) = qns_ice_1d(ji) + dqns_ice_1d(ji) * ( t_su_b(ji) - ztsuoldit(ji) )
403
404            ! update incoming flux
405            zf(ji)    =   zfsw(ji)              & ! net absorbed solar radiation
406               + qns_ice_1d(ji)                  ! non solar total flux
407            ! (LWup, LWdw, SH, LH)
408         END DO
409
410         !
411         !------------------------------------------------------------------------------|
412         ! 8) tridiagonal system terms                                                  |
413         !------------------------------------------------------------------------------|
414         !
415         !!layer denotes the number of the layer in the snow or in the ice
416         !!numeq denotes the reference number of the equation in the tridiagonal
417         !!system, terms of tridiagonal system are indexed as following :
418         !!1 is subdiagonal term, 2 is diagonal and 3 is superdiagonal one
419
420         !!ice interior terms (top equation has the same form as the others)
421
422         DO numeq=1,jkmax+2
423            DO ji = kideb , kiut
424               ztrid(ji,numeq,1) = 0.
425               ztrid(ji,numeq,2) = 0.
426               ztrid(ji,numeq,3) = 0.
427               zindterm(ji,numeq)= 0.
428               zindtbis(ji,numeq)= 0.
429               zdiagbis(ji,numeq)= 0.
430            ENDDO
431         ENDDO
432
433         DO numeq = nlay_s + 2, nlay_s + nlay_i 
434            DO ji = kideb , kiut
435               layer              = numeq - nlay_s - 1
436               ztrid(ji,numeq,1)  =  - zeta_i(ji,layer)*zkappa_i(ji,layer-1)
437               ztrid(ji,numeq,2)  =  1.0 + zeta_i(ji,layer)*(zkappa_i(ji,layer-1) + &
438                  zkappa_i(ji,layer))
439               ztrid(ji,numeq,3)  =  - zeta_i(ji,layer)*zkappa_i(ji,layer)
440               zindterm(ji,numeq) =  ztiold(ji,layer) + zeta_i(ji,layer)* &
441                  zradab_i(ji,layer)
442            END DO
443         ENDDO
444
445         numeq =  nlay_s + nlay_i + 1
446         DO ji = kideb , kiut
447            !!ice bottom term
448            ztrid(ji,numeq,1)  =  - zeta_i(ji,nlay_i)*zkappa_i(ji,nlay_i-1)   
449            ztrid(ji,numeq,2)  =  1.0 + zeta_i(ji,nlay_i)*( zkappa_i(ji,nlay_i)*zg1 &
450               +  zkappa_i(ji,nlay_i-1) )
451            ztrid(ji,numeq,3)  =  0.0
452            zindterm(ji,numeq) =  ztiold(ji,nlay_i) + zeta_i(ji,nlay_i)* &
453               ( zradab_i(ji,nlay_i) + zkappa_i(ji,nlay_i)*zg1 &
454               *  t_bo_b(ji) ) 
455         ENDDO
456
457
458         DO ji = kideb , kiut
459            IF ( ht_s_b(ji).gt.0.0 ) THEN
460               !
461               !------------------------------------------------------------------------------|
462               !  snow-covered cells                                                          |
463               !------------------------------------------------------------------------------|
464               !
465               !!snow interior terms (bottom equation has the same form as the others)
466               DO numeq = 3, nlay_s + 1
467                  layer =  numeq - 1
468                  ztrid(ji,numeq,1)   =  - zeta_s(ji,layer)*zkappa_s(ji,layer-1)
469                  ztrid(ji,numeq,2)   =  1.0 + zeta_s(ji,layer)*( zkappa_s(ji,layer-1) + &
470                     zkappa_s(ji,layer) )
471                  ztrid(ji,numeq,3)   =  - zeta_s(ji,layer)*zkappa_s(ji,layer)
472                  zindterm(ji,numeq)  =  ztsold(ji,layer) + zeta_s(ji,layer)* &
473                     zradab_s(ji,layer)
474               END DO
475
476               !!case of only one layer in the ice (ice equation is altered)
477               IF ( nlay_i.eq.1 ) THEN
478                  ztrid(ji,nlay_s+2,3)    =  0.0
479                  zindterm(ji,nlay_s+2)   =  zindterm(ji,nlay_s+2) + zkappa_i(ji,1)* &
480                     t_bo_b(ji) 
481               ENDIF
482
483               IF ( t_su_b(ji) .LT. rtt ) THEN
484
485                  !------------------------------------------------------------------------------|
486                  !  case 1 : no surface melting - snow present                                  |
487                  !------------------------------------------------------------------------------|
488                  zdifcase(ji)    =  1.0
489                  numeqmin(ji)    =  1
490                  numeqmax(ji)    =  nlay_i + nlay_s + 1
491
492                  !!surface equation
493                  ztrid(ji,1,1) = 0.0
494                  ztrid(ji,1,2) = dzf(ji) - zg1s*zkappa_s(ji,0)
495                  ztrid(ji,1,3) = zg1s*zkappa_s(ji,0)
496                  zindterm(ji,1) = dzf(ji)*t_su_b(ji)   - zf(ji)
497
498                  !!first layer of snow equation
499                  ztrid(ji,2,1)  =  - zkappa_s(ji,0)*zg1s*zeta_s(ji,1)
500                  ztrid(ji,2,2)  =  1.0 + zeta_s(ji,1)*(zkappa_s(ji,1) + zkappa_s(ji,0)*zg1s)
501                  ztrid(ji,2,3)  =  - zeta_s(ji,1)* zkappa_s(ji,1)
502                  zindterm(ji,2) =  ztsold(ji,1) + zeta_s(ji,1)*zradab_s(ji,1)
503
504               ELSE 
505                  !
506                  !------------------------------------------------------------------------------|
507                  !  case 2 : surface is melting - snow present                                  |
508                  !------------------------------------------------------------------------------|
509                  !
510                  zdifcase(ji)    =  2.0
511                  numeqmin(ji)    =  2
512                  numeqmax(ji)    =  nlay_i + nlay_s + 1
513
514                  !!first layer of snow equation
515                  ztrid(ji,2,1)  =  0.0
516                  ztrid(ji,2,2)  =  1.0 + zeta_s(ji,1) * ( zkappa_s(ji,1) + &
517                     zkappa_s(ji,0) * zg1s )
518                  ztrid(ji,2,3)  =  - zeta_s(ji,1)*zkappa_s(ji,1) 
519                  zindterm(ji,2) = ztsold(ji,1) + zeta_s(ji,1) *            &
520                     ( zradab_s(ji,1) +                         &
521                     zkappa_s(ji,0) * zg1s * t_su_b(ji) ) 
522               ENDIF
523            ELSE
524               !
525               !------------------------------------------------------------------------------|
526               !  cells without snow                                                          |
527               !------------------------------------------------------------------------------|
528               !
529               IF (t_su_b(ji) .LT. rtt) THEN
530                  !
531                  !------------------------------------------------------------------------------|
532                  !  case 3 : no surface melting - no snow                                       |
533                  !------------------------------------------------------------------------------|
534                  !
535                  zdifcase(ji)      =  3.0
536                  numeqmin(ji)      =  nlay_s + 1
537                  numeqmax(ji)      =  nlay_i + nlay_s + 1
538
539                  !!surface equation   
540                  ztrid(ji,numeqmin(ji),1)   =  0.0
541                  ztrid(ji,numeqmin(ji),2)   =  dzf(ji) - zkappa_i(ji,0)*zg1   
542                  ztrid(ji,numeqmin(ji),3)   =  zkappa_i(ji,0)*zg1
543                  zindterm(ji,numeqmin(ji))  =  dzf(ji)*t_su_b(ji) - zf(ji)
544
545                  !!first layer of ice equation
546                  ztrid(ji,numeqmin(ji)+1,1) =  - zkappa_i(ji,0) * zg1 * zeta_i(ji,1)
547                  ztrid(ji,numeqmin(ji)+1,2) =  1.0 + zeta_i(ji,1) * ( zkappa_i(ji,1) & 
548                     + zkappa_i(ji,0) * zg1 )
549                  ztrid(ji,numeqmin(ji)+1,3) =  - zeta_i(ji,1)*zkappa_i(ji,1) 
550                  zindterm(ji,numeqmin(ji)+1)=  ztiold(ji,1) + zeta_i(ji,1)*zradab_i(ji,1) 
551
552                  !!case of only one layer in the ice (surface & ice equations are altered)
553
554                  IF (nlay_i.eq.1) THEN
555                     ztrid(ji,numeqmin(ji),1)    =  0.0
556                     ztrid(ji,numeqmin(ji),2)    =  dzf(ji) - zkappa_i(ji,0)*2.0
557                     ztrid(ji,numeqmin(ji),3)    =  zkappa_i(ji,0)*2.0
558                     ztrid(ji,numeqmin(ji)+1,1)  =  -zkappa_i(ji,0)*2.0*zeta_i(ji,1)
559                     ztrid(ji,numeqmin(ji)+1,2)  =  1.0 + zeta_i(ji,1)*(zkappa_i(ji,0)*2.0 + &
560                        zkappa_i(ji,1))
561                     ztrid(ji,numeqmin(ji)+1,3)  =  0.0
562
563                     zindterm(ji,numeqmin(ji)+1) =  ztiold(ji,1) + zeta_i(ji,1)* &
564                        ( zradab_i(ji,1) + zkappa_i(ji,1)*t_bo_b(ji) )
565                  ENDIF
566
567               ELSE
568
569                  !
570                  !------------------------------------------------------------------------------|
571                  ! case 4 : surface is melting - no snow                                        |
572                  !------------------------------------------------------------------------------|
573                  !
574                  zdifcase(ji)    =  4.0
575                  numeqmin(ji)    =  nlay_s + 2
576                  numeqmax(ji)    =  nlay_i + nlay_s + 1
577
578                  !!first layer of ice equation
579                  ztrid(ji,numeqmin(ji),1)      =  0.0
580                  ztrid(ji,numeqmin(ji),2)      =  1.0 + zeta_i(ji,1)*(zkappa_i(ji,1) + zkappa_i(ji,0)* &
581                     zg1) 
582                  ztrid(ji,numeqmin(ji),3)      =  - zeta_i(ji,1) * zkappa_i(ji,1)
583                  zindterm(ji,numeqmin(ji))     =  ztiold(ji,1) + zeta_i(ji,1)*( zradab_i(ji,1) + &
584                     zkappa_i(ji,0) * zg1 * t_su_b(ji) ) 
585
586                  !!case of only one layer in the ice (surface & ice equations are altered)
587                  IF (nlay_i.eq.1) THEN
588                     ztrid(ji,numeqmin(ji),1)  =  0.0
589                     ztrid(ji,numeqmin(ji),2)  =  1.0 + zeta_i(ji,1)*(zkappa_i(ji,0)*2.0 + &
590                        zkappa_i(ji,1))
591                     ztrid(ji,numeqmin(ji),3)  =  0.0
592                     zindterm(ji,numeqmin(ji)) =  ztiold(ji,1) + zeta_i(ji,1)* &
593                        (zradab_i(ji,1) + zkappa_i(ji,1)*t_bo_b(ji)) &
594                        + t_su_b(ji)*zeta_i(ji,1)*zkappa_i(ji,0)*2.0
595                  ENDIF
596
597               ENDIF
598            ENDIF
599
600         END DO
601
602         !
603         !------------------------------------------------------------------------------|
604         ! 9) tridiagonal system solving                                                |
605         !------------------------------------------------------------------------------|
606         !
607
608         ! Solve the tridiagonal system with Gauss elimination method.
609         ! Thomas algorithm, from Computational fluid Dynamics, J.D. ANDERSON,
610         ! McGraw-Hill 1984. 
611
612         maxnumeqmax = 0
613         minnumeqmin = jkmax+4
614
615         DO ji = kideb , kiut
616            zindtbis(ji,numeqmin(ji)) =  zindterm(ji,numeqmin(ji))
617            zdiagbis(ji,numeqmin(ji)) =  ztrid(ji,numeqmin(ji),2)
618            minnumeqmin               =  MIN(numeqmin(ji),minnumeqmin)
619            maxnumeqmax               =  MAX(numeqmax(ji),maxnumeqmax)
620         END DO
621
622         DO layer = minnumeqmin+1, maxnumeqmax
623            DO ji = kideb , kiut
624               numeq               =  min(max(numeqmin(ji)+1,layer),numeqmax(ji))
625               zdiagbis(ji,numeq)  =  ztrid(ji,numeq,2) - ztrid(ji,numeq,1)* &
626                  ztrid(ji,numeq-1,3)/zdiagbis(ji,numeq-1)
627               zindtbis(ji,numeq)  =  zindterm(ji,numeq) - ztrid(ji,numeq,1)* &
628                  zindtbis(ji,numeq-1)/zdiagbis(ji,numeq-1)
629            END DO
630         END DO
631
632         DO ji = kideb , kiut
633            ! ice temperatures
634            t_i_b(ji,nlay_i)    =  zindtbis(ji,numeqmax(ji))/zdiagbis(ji,numeqmax(ji))
635         END DO
636
637         DO numeq = nlay_i + nlay_s + 1, nlay_s + 2, -1
638            DO ji = kideb , kiut
639               layer    =  numeq - nlay_s - 1
640               t_i_b(ji,layer)  =  (zindtbis(ji,numeq) - ztrid(ji,numeq,3)* &
641                  t_i_b(ji,layer+1))/zdiagbis(ji,numeq)
642            END DO
643         END DO
644
645         DO ji = kideb , kiut
646            ! snow temperatures     
647            IF (ht_s_b(ji).GT.0._wp) &
648               t_s_b(ji,nlay_s)     =  (zindtbis(ji,nlay_s+1) - ztrid(ji,nlay_s+1,3) &
649               *  t_i_b(ji,1))/zdiagbis(ji,nlay_s+1) &
650               *        MAX(0.0,SIGN(1.0,ht_s_b(ji))) 
651
652            ! surface temperature
653            isnow(ji)     = NINT(  1.0 - MAX( 0.0 , SIGN( 1.0 , -ht_s_b(ji) )  )  )
654            ztsuoldit(ji) = t_su_b(ji)
655            IF( t_su_b(ji) < ztfs(ji) ) &
656               t_su_b(ji) = ( zindtbis(ji,numeqmin(ji)) - ztrid(ji,numeqmin(ji),3)* ( REAL( isnow(ji) )*t_s_b(ji,1)   &
657               &          + REAL( 1 - isnow(ji) )*t_i_b(ji,1) ) ) / zdiagbis(ji,numeqmin(ji)) 
658         END DO
659         !
660         !--------------------------------------------------------------------------
661         !  10) Has the scheme converged ?, end of the iterative procedure         |
662         !--------------------------------------------------------------------------
663         !
664         ! check that nowhere it has started to melt
665         ! zerrit(ji) is a measure of error, it has to be under maxer_i_thd
666         DO ji = kideb , kiut
667            t_su_b(ji) =  MAX(  MIN( t_su_b(ji) , ztfs(ji) ) , 190._wp  )
668            zerrit(ji) =  ABS( t_su_b(ji) - ztsuoldit(ji) )     
669         END DO
670
671         DO layer  =  1, nlay_s
672            DO ji = kideb , kiut
673               ii = MOD( npb(ji) - 1, jpi ) + 1
674               ij = ( npb(ji) - 1 ) / jpi + 1
675               t_s_b(ji,layer) = MAX(  MIN( t_s_b(ji,layer), rtt ), 190._wp  )
676               zerrit(ji)      = MAX(zerrit(ji),ABS(t_s_b(ji,layer) - ztstemp(ji,layer)))
677            END DO
678         END DO
679
680         DO layer  =  1, nlay_i
681            DO ji = kideb , kiut
682               ztmelt_i        = -tmut * s_i_b(ji,layer) + rtt 
683               t_i_b(ji,layer) =  MAX(MIN(t_i_b(ji,layer),ztmelt_i), 190._wp)
684               zerrit(ji)      =  MAX(zerrit(ji),ABS(t_i_b(ji,layer) - ztitemp(ji,layer)))
685            END DO
686         END DO
687
688         ! Compute spatial maximum over all errors
689         ! note that this could be optimized substantially by iterating only the non-converging points
690         zerritmax = 0._wp
691         DO ji = kideb, kiut
692            zerritmax = MAX( zerritmax, zerrit(ji) )   
693         END DO
694         IF( lk_mpp ) CALL mpp_max( zerritmax, kcom=ncomm_ice )
695
696      END DO  ! End of the do while iterative procedure
697
698      IF( ln_nicep .AND. lwp ) THEN
699         WRITE(numout,*) ' zerritmax : ', zerritmax
700         WRITE(numout,*) ' nconv     : ', nconv
701      ENDIF
702
703      !
704      !-------------------------------------------------------------------------!
705      !   11) Fluxes at the interfaces                                          !
706      !-------------------------------------------------------------------------!
707      DO ji = kideb, kiut
708         ! forced mode only : update of latent heat fluxes (sublimation) (always >=0, upward flux)
709         IF( .NOT. lk_cpl) qla_ice_1d (ji) = MAX( 0._wp, qla_ice_1d (ji) + dqla_ice_1d(ji) * ( t_su_b(ji) - ztsuold(ji) ) )
710         !                                ! surface ice conduction flux
711         isnow(ji)       = NINT(  1._wp - MAX( 0._wp, SIGN( 1._wp, -ht_s_b(ji) ) )  )
712         fc_su(ji)       =  -     REAL( isnow(ji) ) * zkappa_s(ji,0) * zg1s * (t_s_b(ji,1) - t_su_b(ji))   &
713            &               - REAL( 1 - isnow(ji) ) * zkappa_i(ji,0) * zg1  * (t_i_b(ji,1) - t_su_b(ji))
714         !                                ! bottom ice conduction flux
715         fc_bo_i(ji)     =  - zkappa_i(ji,nlay_i) * ( zg1*(t_bo_b(ji) - t_i_b(ji,nlay_i)) )
716      END DO
717
718      !-----------------------------------------
719      ! Heat flux used to warm/cool ice in W.m-2
720      !-----------------------------------------
721      DO ji = kideb, kiut
722         IF( t_su_b(ji) < rtt ) THEN  ! case T_su < 0degC
723            hfx_dif_1d(ji) = hfx_dif_1d(ji) + ( qns_ice_1d(ji) + qsr_ice_1d(ji) - zradtr_i(ji,nlay_i) - fc_bo_i(ji) ) * a_i_b(ji)
724         ELSE                                    ! case T_su = 0degC
725            hfx_dif_1d(ji) = hfx_dif_1d(ji) + ( fc_su(ji) + i0(ji) * qsr_ice_1d(ji) - zradtr_i(ji,nlay_i) - fc_bo_i(ji) ) * a_i_b(ji)
726         ENDIF
727      END DO
728
729      !
730      CALL wrk_dealloc( jpij, numeqmin, numeqmax, isnow )
731      CALL wrk_dealloc( jpij, ztfs, ztsuold, ztsuoldit, zh_i, zh_s, zfsw )
732      CALL wrk_dealloc( jpij, zf, dzf, zerrit, zdifcase, zftrice, zihic, zhsu )
733      CALL wrk_dealloc( jpij, nlay_i+1, ztcond_i, zradtr_i, zradab_i, zkappa_i, ztiold, zeta_i, ztitemp, z_i, zspeche_i, kjstart = 0 )
734      CALL wrk_dealloc( jpij, nlay_s+1,           zradtr_s, zradab_s, zkappa_s, ztsold, zeta_s, ztstemp, z_s, kjstart = 0 )
735      CALL wrk_dealloc( jpij, jkmax+2, zindterm, zindtbis, zdiagbis )
736      CALL wrk_dealloc( jpij, jkmax+2, 3, ztrid )
737
738   END SUBROUTINE lim_thd_dif
739
740#else
741   !!----------------------------------------------------------------------
742   !!                   Dummy Module                 No LIM-3 sea-ice model
743   !!----------------------------------------------------------------------
744CONTAINS
745   SUBROUTINE lim_thd_dif          ! Empty routine
746   END SUBROUTINE lim_thd_dif
747#endif
748   !!======================================================================
749END MODULE limthd_dif
Note: See TracBrowser for help on using the repository browser.