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_ent.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_ent.F90 @ 4635

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

major changes in heat budget

  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1MODULE limthd_ent
2   !!======================================================================
3   !!                       ***  MODULE limthd_ent   ***
4   !!                  Redistribution of Enthalpy in the ice
5   !!                        on the new vertical grid
6   !!                       after vertical growth/decay
7   !!======================================================================
8   !! History :  LIM  ! 2003-05 (M. Vancoppenolle) Original code in 1D
9   !!                 ! 2005-07 (M. Vancoppenolle) 3D version
10   !!                 ! 2006-11 (X. Fettweis) Vectorized
11   !!            3.0  ! 2008-03 (M. Vancoppenolle) Energy conservation and clean code
12   !!            3.4  ! 2011-02 (G. Madec) dynamical allocation
13   !!             -   ! 2014-05 (C. Rousset) complete rewriting
14   !!----------------------------------------------------------------------
15#if defined key_lim3
16   !!----------------------------------------------------------------------
17   !!   'key_lim3'                                      LIM3 sea-ice model
18   !!----------------------------------------------------------------------
19   !!   lim_thd_ent   : ice redistribution of enthalpy
20   !!----------------------------------------------------------------------
21   USE par_oce        ! ocean parameters
22   USE dom_oce        ! domain variables
23   USE domain         !
24   USE phycst         ! physical constants
25   USE sbc_oce        ! Surface boundary condition: ocean fields
26   USE ice            ! LIM variables
27   USE par_ice        ! LIM parameters
28   USE thd_ice        ! LIM thermodynamics
29   USE limvar         ! LIM variables
30   USE in_out_manager ! I/O manager
31   USE lib_mpp        ! MPP library
32   USE wrk_nemo       ! work arrays
33   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
34
35   IMPLICIT NONE
36   PRIVATE
37
38   PUBLIC   lim_thd_ent         ! called by lim_thd
39
40   REAL(wp) :: epsi20 = 1.e-20   ! constant values
41   REAL(wp) :: epsi10 = 1.e-10   ! constant values
42
43   !!----------------------------------------------------------------------
44   !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2011)
45   !! $Id$
46   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
47   !!----------------------------------------------------------------------
48CONTAINS
49 
50   SUBROUTINE lim_thd_ent( kideb, kiut, jl )
51      !!-------------------------------------------------------------------
52      !!               ***   ROUTINE lim_thd_ent  ***
53      !!
54      !! ** Purpose :
55      !!           This routine computes new vertical grids in the ice,
56      !!           and consistently redistributes temperatures.
57      !!           Redistribution is made so as to ensure to energy conservation
58      !!
59      !!
60      !! ** Method  : linear conservative remapping
61      !!           
62      !! ** Steps : 1) cumulative integrals of old enthalpies/thicknesses
63      !!            2) linear remapping on the new layers
64      !!            3) Ice salinity update + recover temperature from enthalpies
65      !!
66      !! References : Bitz & Lipscomb, JGR 99; Vancoppenolle et al., GRL, 2005
67      !!-------------------------------------------------------------------
68      INTEGER , INTENT(in) ::   kideb, kiut   ! Start/End point on which the  the computation is applied
69      INTEGER , INTENT(in) ::   jl            ! Thickness cateogry number
70
71      INTEGER  :: ji,ii,ij   !  dummy loop indices
72      INTEGER  :: jk0, jk1   !  old/new layer indices
73      REAL(wp) :: ztmelts    ! temperature of melting
74      REAL(wp) :: zswitch, zaaa, zbbb, zccc, zdiscrim ! converting enthalpy to temperature
75      !
76      REAL(wp), POINTER, DIMENSION(:,:) :: zqh_cum0, zh_cum0   ! old cumulative enthlapies and layers interfaces
77      REAL(wp), POINTER, DIMENSION(:,:) :: zqh_cum1, zh_cum1   ! new cumulative enthlapies and layers interfaces
78      !!-------------------------------------------------------------------
79
80      CALL wrk_alloc( jpij, nlay_i+3, zqh_cum0, zh_cum0, kjstart = 0 )
81      CALL wrk_alloc( jpij, nlay_i+1, zqh_cum1, zh_cum1, kjstart = 0 )
82
83      !--------------------------------------------------------------------------
84      !  1) Cumulative integral of old enthalpy * thicnkess and layers interfaces
85      !--------------------------------------------------------------------------
86      zqh_cum0(:,0:nlay_i+2) = 0._wp 
87      zh_cum0 (:,0:nlay_i+2) = 0._wp
88      DO jk0 = 1, nlay_i+2
89         DO ji = kideb, kiut
90            zqh_cum0(ji,jk0) = zqh_cum0(ji,jk0-1) + qh_i_old(ji,jk0-1)
91            zh_cum0 (ji,jk0) = zh_cum0 (ji,jk0-1) + h_i_old (ji,jk0-1)
92         ENDDO
93      ENDDO
94
95      !------------------------------------
96      !  2) Interpolation on the new layers
97      !------------------------------------
98      ! new layers interfaces
99      zh_cum1(:,0:nlay_i) = 0._wp
100      DO jk1 = 1, nlay_i
101         DO ji = kideb, kiut
102            zh_cum1(ji,jk1) = zh_cum1(ji,jk1-1) + ht_i_b(ji) / REAL( nlay_i )
103         ENDDO
104      ENDDO
105
106      zqh_cum1(:,0:nlay_i) = 0._wp 
107      ! new cumulative q*h => linear interpolation
108      DO jk0 = 1, nlay_i+1
109         DO jk1 = 1, nlay_i-1
110            DO ji = kideb, kiut
111               IF( zh_cum1(ji,jk1) <= zh_cum0(ji,jk0) .AND. zh_cum1(ji,jk1) > zh_cum0(ji,jk0-1) ) THEN
112                  zqh_cum1(ji,jk1) = ( zqh_cum0(ji,jk0-1) * ( zh_cum0(ji,jk0) - zh_cum1(ji,jk1  ) ) +  &
113                     &                 zqh_cum0(ji,jk0  ) * ( zh_cum1(ji,jk1) - zh_cum0(ji,jk0-1) ) )  &
114                     &             / ( zh_cum0(ji,jk0) - zh_cum0(ji,jk0-1) )
115               ENDIF
116            ENDDO
117         ENDDO
118      ENDDO
119      ! to ensure that total heat content is strictly conserved, set:
120      zqh_cum1(:,nlay_i) = zqh_cum0(:,nlay_i+2) 
121
122      ! new enthalpies
123      DO jk1 = 1, nlay_i
124         DO ji = kideb, kiut
125            zswitch       =  1._wp - MAX( 0._wp , SIGN( 1._wp , - ht_i_b(ji) + epsi20 ) ) 
126            q_i_b(ji,jk1) = zswitch * ( zqh_cum1(ji,jk1) - zqh_cum1(ji,jk1-1) ) * REAL( nlay_i ) / MAX( ht_i_b(ji), epsi20 )
127         ENDDO
128      ENDDO
129
130      !---------------------------------------------------------
131      !  3) Update ice salinity and recover ice temperature
132      !---------------------------------------------------------
133      ! Update salinity (basal entrapment, snow ice formation)
134      DO ji = kideb, kiut
135         sm_i_b(ji) = sm_i_b(ji) + dsm_i_se_1d(ji) + dsm_i_si_1d(ji)
136      END DO !ji
137
138      ! Recover ice temperature
139      DO jk1 = 1, nlay_i
140         DO ji = kideb, kiut
141            ztmelts       =  -tmut * s_i_b(ji,jk1) + rtt
142            ! Conversion q(S,T) -> T (second order equation)
143            zaaa          =  cpic
144            zbbb          =  ( rcp - cpic ) * ( ztmelts - rtt ) + q_i_b(ji,jk1) / rhoic - lfus
145            zccc          =  lfus * ( ztmelts - rtt )
146            zdiscrim      =  SQRT( MAX( zbbb * zbbb - 4._wp * zaaa * zccc, 0._wp ) )
147            t_i_b(ji,jk1) =  rtt - ( zbbb + zdiscrim ) / ( 2._wp * zaaa )
148           
149            ! mask temperature
150            zswitch       =  1._wp - MAX( 0._wp , SIGN( 1._wp , - ht_i_b(ji) ) ) 
151            t_i_b(ji,jk1) =  zswitch * t_i_b(ji,jk1) + ( 1._wp - zswitch ) * rtt
152         END DO
153      END DO 
154
155      !
156      CALL wrk_dealloc( jpij, nlay_i+3, zqh_cum0, zh_cum0, kjstart = 0 )
157      CALL wrk_dealloc( jpij, nlay_i+1, zqh_cum1, zh_cum1, kjstart = 0 )
158      !
159   END SUBROUTINE lim_thd_ent
160
161#else
162   !!----------------------------------------------------------------------
163   !!   Default option                               NO  LIM3 sea-ice model
164   !!----------------------------------------------------------------------
165CONTAINS
166   SUBROUTINE lim_thd_ent          ! Empty routine
167   END SUBROUTINE lim_thd_ent
168#endif
169
170   !!======================================================================
171END MODULE limthd_ent
Note: See TracBrowser for help on using the repository browser.