source: branches/publications/ORCHIDEE_GLUC_r6545/src_sechiba/thermosoilc.f90 @ 6737

Last change on this file since 6737 was 5089, checked in by albert.jornet, 6 years ago

Fix: missing OpenMP threadprivate declarations ( LMDZ+MICT )
Fix: group variable (stics module) was defined as real but passed as an integer
Fix: masec variable (stics module) it was modified but passed as input argument only

  • Property svn:keywords set to Revision Date HeadURL Date Author Revision
File size: 143.6 KB
Line 
1! =================================================================================================================================
2! MODULE       : thermosoilc
3!
4! CONTACT      : orchidee-help _at_ listes.ipsl.fr
5!
6! LICENCE      : IPSL (2006)
7! This software is governed by the CeCILL licence see ORCHIDEE/ORCHIDEE_CeCILL.LIC
8!
9!>\BRIEF        Calculates the soil temperatures by solving the heat
10!! diffusion equation within the soil. This module is only used with Choisnel hydrology.
11!!
12!!\n DESCRIPTION : General important informations about the numerical scheme and
13!!                 the soil vertical discretization:\n
14!!               - the soil is divided into "ngrnd" (=7 by default) layers, reaching to as
15!!                 deep as 5.5m down within the soil, with thiscknesses
16!!                 following a geometric series of ration 2.\n
17!!               - "jg" is usually used as the index going from 1 to ngrnd to describe the
18!!                  layers, from top (jg=1) to bottom (jg=ngrnd)\n
19!!               - the thermal numerical scheme is implicit finite differences.\n
20!!                 -- When it is resolved in thermosoilc_profile at the present timestep t, the
21!!                 dependancy from the previous timestep (t-1) is hidden in the
22!!                 integration coefficients cgrnd and dgrnd, which are therefore
23!!                 calculated at the very end of thermosoilc_main (call to
24!!                 thermosoilc_coef) for use in the next timestep.\n
25!!                 -- At timestep t, the system becomes :\n
26!!
27!!                              T(k+1)=cgrnd(k)+dgrnd(k)*T(k) \n
28!!                                      -- EQ1 -- \n
29!!
30!!                 (the bottom boundary condition has been used to obtained this equation).\n
31!!                 To solve it, the uppermost soil temperature T(1) is required.
32!!                 It is obtained from the surface temperature Ts, which is
33!!                 considered a linear extrapolation of T(1) and T(2)\n
34!!
35!!                           Ts=(1-lambda)*T(1) -lambda*T(2) \n
36!!                                      -- EQ2--\n
37!!
38!!                 -- caveat 1 : Ts is called 'temp_soil_new' in this routine,
39!!                 don' t act.\n
40!!                 -- caveat 2 : actually, the surface temperature at time t Ts
41!!                 depends on the soil temperature at time t through the
42!!                 ground heat flux. This is again implicitly solved, with Ts(t)
43!!                 expressed as :\n
44!!
45!!                 soilcap*(Ts(t)-Ts(t-1))/dt=soilflux+otherfluxes(Ts(t))\n
46!!                                      -- EQ3 --\n
47!!
48!!                 and the dependency from the previous timestep is hidden in
49!!                 soilcap and soilflux (apparent surface heat capacity and heat
50!!                 flux respectively). Soilcap and soilflux are therefore
51!!                 calculated at the previsou timestep, at the very end of thermosoilc
52!!                 (final call to thermosoilc_coef) and stored to be used at the next time step.
53!!                 At timestep t, EQ3 is solved for Ts in enerbil, and Ts
54!!                 is used in thermosoilc to get T(1) and solve EQ1.\n
55!!
56!! - lambda is the @tex $\mu$ @endtex of F. Hourdin' s PhD thesis, equation (A28); ie the
57!! coefficient of the linear extrapolation of Ts (surface temperature) from T1 and T2 (ptn(jg=1) and ptn(jg=2)), so that:\n
58!! Ts= (1+lambda)*T(1)-lambda*T(2) --EQ2-- \n
59!! lambda = (zz_coeff(1))/((zz_coef(2)-zz_coef(1))) \n
60!!
61!! - cstgrnd is the attenuation depth of the diurnal temperature signal
62!! (period : one_day) as a result of the heat conduction equation
63!! with no coefficients :
64!!\latexonly
65!!\input{thermosoilc_var_init0.tex}
66!!\endlatexonly
67!!  -- EQ4 --\n
68!! This equation results from the change of variables :
69!! z' =z*sqrt(Cp/K) where z' is the new depth (homogeneous
70!! to sqrt(time) ), z the real depth (in m), Cp and K the soil heat
71!! capacity and conductivity respectively.\n
72!!
73!! the attenuation depth of a diurnal thermal signal for EQ4 is therefore homogeneous to sqrt(time) and
74!! equals : \n
75!! cstgrnd = sqrt(oneday/Pi)
76!!
77!! - lskin is the attenuation depth of the diurnal temperature signal
78!! (period : one_day) within the soil for the complete heat conduction equation
79!! (ie : with coefficients)
80!!\latexonly
81!!\input{thermosoilc_var_init00.tex}
82!!\endlatexonly
83!! -- EQ5 --  \n
84!! it can be retrieved from cstgrnd using the change of variable  z' =z*sqrt(Cp/K):\n
85!! lskin = sqrt(K/Cp)*cstgrnd =  sqrt(K/Cp)*sqrt(oneday//Pi)\n
86!!
87!! In thermosoilc, the ratio lskin/cstgrnd is frequently used as the
88!! multiplicative factor to go from
89!!'adimensional' depths (like z' ) to real depths (z). z' is not really
90!! adimensional but is reffered to like this in the code.
91!!
92!!---------------------------------------------------------------------------------------
93!!   Modified by Dmitry Khvorostyanov and Gerhard Krinner 12-14/12/06 to account
94!for permafrost
95!!
96!!    - new subroutine 'thermosoilc_getdiff' that computes soil heat conductivity
97!!      and heat capacity with account for liquid and frozen phases
98!!
99!!    - new subroutine 'thermosoilc_wlupdate' that computes long-term soil
100!!      humidity ensuring energy conservation when soil freezes
101!!
102!!    - in 'thermosoilc_coef' and 'thermosoilc_var_init' the part computing the
103!!      soil capa and kappa has been rewritten in terms of the new routine 'thermosoilc_getdiff'
104!!
105!!    - in the call to 'thermosoilc_var_init' the variable 'snow' is now passed
106!!      as an input argument in order to be able to use 'thermosoilc_getdiff'
107!!
108!!    -  'thermosoilc_wlupdate' is called in 'thermosoilc_main', just after
109!!       'thermosoilc_humlev', to update the long-term humidity
110!!
111!!    - new module constants related to permafrost have been added
112!!
113!!    - modifications related to the thermosoilc autonomy (optional output using
114!!      flio, no use of restart files, initial and boundary conditions specified in the call to
115!!      thermosoilc_main)
116!!---------------------------------------------------------------------------------------
117!!  Modified by Charlie Koven 2008-2010 and Tao Wang 2014 to:
118!! 
119!!  - added PFT dimension to soil thermal calculations
120!!
121!!  - three-layer snow module from ISBA-ES
122!! 
123!!  - take into account soil carbon in the thermal properties of soil
124!!    Two possible modes, with separate organic layer on top of soil, or mixed mieral/organic soils
125!! 
126!!  - take into account exothermic heat of decomposition in heat budget of soil layers
127!! 
128!!  - output some diagnostic properties (soil moisture, etc) on soil temperature grid for use in
129!!    calculations within the permafrost soil carbon code.
130!!
131!!---------------------------------------------------------------------------------------
132!!
133!!
134!! RECENT CHANGE(S) : thermosoilc module is a copy of thermosoil before the vertical discretization was changed.
135!!                    This module is used only for the Choisnel hydrology.
136!!
137!! REFERENCE(S) : None
138!!
139!! SVN          :
140!! $HeadURL$
141!! $Date$
142!! $Revision$
143!! \n
144!_ ================================================================================================================================
145
146MODULE thermosoilc
147
148  USE ioipsl_para
149  USE xios_orchidee
150  USE constantes
151  USE time, ONLY : one_day, dt_sechiba
152  USE constantes_soil
153  USE sechiba_io_p
154  USE grid
155  USE pft_parameters_var
156  USE constantes_var
157  USE mod_orchidee_para
158
159  IMPLICIT NONE
160
161  !private and public routines :
162  PRIVATE
163  PUBLIC :: thermosoilc_main, thermosoilc_clear, thermosoilc_vert_axes, thermosoilc_levels, thermosoilc_initialize, thermosoilc_finalize 
164
165  REAL(r_std), SAVE                                  :: lambda, cstgrnd, lskin!! See Module description
166!$OMP THREADPRIVATE(lambda, cstgrnd, lskin)
167  REAL(r_std), SAVE                                  :: fz1                   !! usefull constants for diverse use
168!$OMP THREADPRIVATE(fz1)
169  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: ptn                   !! vertically discretized
170!$OMP THREADPRIVATE(ptn)
171
172                                                                              !! soil temperatures @tex ($K$) @endtex.
173  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:)    :: ptn_pftmean           !! Different levels soil temperature, mean across all pfts
174!$OMP THREADPRIVATE(ptn_pftmean)
175  REAL(r_std),  ALLOCATABLE, SAVE, DIMENSION (:)     :: zz                    !! depths of the soil thermal numerical nodes.
176                                                                              !! Caveats: they are not exactly the centers of the
177                                                                              !! thermal layers, see the calculation in
178                                                                              !! ::thermosoilc_var_init  @tex ($m$) @endtex.
179!$OMP THREADPRIVATE(zz)
180  REAL(r_std),  ALLOCATABLE,SAVE, DIMENSION (:)      :: zz_coef               !! depths of the boundaries of the thermal layers,
181                                                                              !! see the calculation in
182                                                                              !! thermosoilc_var_init  @tex ($m$) @endtex.
183!$OMP THREADPRIVATE(zz_coef)
184  REAL(r_std),  ALLOCATABLE,SAVE, DIMENSION (:)      :: dz1                   !! numerical constant used in the thermal numerical
185                                                                              !! scheme  @tex ($m^{-1}$) @endtex. ; it corresponds
186                                                                              !! to the coefficient  @tex $d_k$ @endtex of equation
187                                                                              !! (A.12) in F. Hourdin PhD thesis.
188!$OMP THREADPRIVATE(dz1)
189  REAL(r_std),  ALLOCATABLE,SAVE, DIMENSION (:)      :: dz2                   !! thicknesses of the thermal layers  @tex ($m$)
190                                                                              !! @endtex; typically:
191                                                                              !! dz2(jg)=zz_coef(jg+1)-zz_coef(jg); calculated once
192                                                                              !! and for all in thermosoilc_var_init
193!$OMP THREADPRIVATE(dz2)
194  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:)      :: z1                    !! constant of the numerical scheme; it is an
195                                                                              !! intermediate buffer for the calculation of the
196                                                                              !! integration coefficients cgrnd and dgrnd.
197!$OMP THREADPRIVATE(z1)
198  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: cgrnd                 !! integration coefficient for the numerical scheme,
199                                                                              !! see eq.1
200!$OMP THREADPRIVATE(cgrnd)
201  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: dgrnd                 !! integration coefficient for the numerical scheme,
202                                                                              !! see eq.1
203!$OMP THREADPRIVATE(dgrnd)
204  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: pcapa                 !! volumetric vertically discretized soil heat
205!$OMP THREADPRIVATE(pcapa)
206
207                                                                              !! capacity  @tex ($J K^{-1} m^{-3}$) @endtex.
208                                                                              !! It depends on the soil
209                                                                              !! moisture content (shum_ngrnd_perma) and is calculated at
210                                                                              !! each time step in thermosoilc_coef.
211  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: pkappa                !! vertically discretized soil thermal conductivity
212                                                                              !!  @tex ($W K^{-1} m^{-1}$) @endtex. Same as pcapa.
213!$OMP THREADPRIVATE(pkappa)
214  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: pcapa_en              !! heat capacity used for surfheat_incr and
215!$OMP THREADPRIVATE(pcapa_en)
216  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:) :: pcapa_snow               !! volumetric vertically discretized snow heat
217                                                                              !! capacity @tex ($J K^{-1} m^{-3}$) @endtex.
218!$OMP THREADPRIVATE(pcapa_snow)
219  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:) :: pkappa_snow              !! vertically discretized snow thermal conductivity
220                                                                              !! @tex ($W K^{-1} m^{-1}$) @endtex.
221!$OMP THREADPRIVATE(pkappa_snow)
222
223  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: ptn_beg               !! vertically discretized temperature at the
224                                                                              !! beginning of the time step  @tex ($K$) @endtex;
225                                                                              !! is used in
226                                                                              !! thermosoilc_energy for energy-related diagnostic of
227                                                                              !! the routine.
228!$OMP THREADPRIVATE(ptn_beg)
229  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:)      :: temp_sol_beg          !! Surface temperature at the beginning of the
230                                                                              !! timestep  @tex ($K$) @endtex
231!$OMP THREADPRIVATE(temp_sol_beg)
232  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:)      :: surfheat_incr         !! Change in soil heat content during the timestep
233                                                                              !!  @tex ($J$) @endtex.
234!$OMP THREADPRIVATE(surfheat_incr)
235  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:)      :: coldcont_incr         !! Change in snow heat content  @tex ($J$) @endtex.
236!$OMP THREADPRIVATE(coldcont_incr)
237  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: shum_ngrnd_perma      !! Saturation degree on the thermal axes (0-1, dimensionless)
238!$OMP THREADPRIVATE(shum_ngrnd_perma)
239
240  REAL(r_std), SAVE                                  :: so_cond = 1.5396      !! Thermix soil layer discretization constant
241!$OMP THREADPRIVATE(so_cond)
242  REAL(r_std), SAVE                                  :: so_capa = 2.0514e+6   !! Thermix soil layer discretization constant
243!$OMP THREADPRIVATE(so_capa)
244
245!  Variables related to soil freezing
246  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: profil_froz           !! Frozen fraction of the soil on hydrological levels (-)
247!$OMP THREADPRIVATE(profil_froz)
248  REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:,:,:)  :: shum_ngrnd_permalong  !! Long-term soil humidity (for permafrost) if ok_freeze_thermix ; shum_ngrnd_perma sinon.
249!$OMP THREADPRIVATE(shum_ngrnd_permalong)
250        LOGICAL, SAVE    :: ok_shum_ngrnd_permalong
251!$OMP THREADPRIVATE(ok_shum_ngrnd_permalong)
252
253    REAL(r_std),ALLOCATABLE, SAVE, DIMENSION (:,:,:) :: pcappa_supp           !! Additional heat capacity due to soil freezing for each soil layer (J/K)
254!$OMP THREADPRIVATE(pcappa_supp)
255    REAL(r_std),ALLOCATABLE, SAVE, DIMENSION (:,:)   :: e_soil_lat            !! Accumulated latent heat for the whole soil (J)
256!$OMP THREADPRIVATE(e_soil_lat)
257    REAL(r_std), ALLOCATABLE, SAVE,DIMENSION(:,:)    :: reftemp               !! Flag to initialize soil temperature using climatological temperature
258!$OMP THREADPRIVATE(reftemp)
259
260!Vertical Permafrost Carbon
261  LOGICAL, SAVE                                      :: use_toporganiclayer_tempdiff = .FALSE. 
262!$OMP THREADPRIVATE(use_toporganiclayer_tempdiff)
263  LOGICAL, SAVE                                      :: use_soilc_tempdiff = .TRUE. 
264!$OMP THREADPRIVATE(use_soilc_tempdiff)
265  LOGICAL, SAVE                                      :: satsoil = .FALSE.
266!$OMP THREADPRIVATE(satsoil)
267
268CONTAINS
269!!
270!=============================================================================================================================
271!! SUBROUTINE                             : thermosoilc_initialize
272!!
273!>\BRIEF                                  Allocate module variables, read from restart file or initialize with default values
274!!
275!! DESCRIPTION                            : Allocate module variables, read from restart file or initialize with default values.
276!!                                          Call thermosoilc_var_init to calculate physical constants. 
277!!                                          Call thermosoilc_coef to calculate thermal soil properties.
278!!
279!! RECENT CHANGE(S)                       : None
280!!
281!! REFERENCE(S)                           : None
282!! 
283!! FLOWCHART                              : None
284!! \n
285!_
286!==============================================================================================================================
287  SUBROUTINE thermosoilc_initialize(kjit, kjpindex, lalo, rest_id, veget_max, &
288                      snowdz, shumdiag_perma, snow, thawed_humidity, soilc_total, &
289                      temp_sol_new, & 
290                      organic_layer_thick, stempdiag, soilcap, soilflx, &
291                      gtemp, frac_snow_veg, frac_snow_nobio, totfrac_nobio, &
292                      snowrho, snowtemp, lambda_snow, cgrnd_snow, dgrnd_snow, pb )
293    !! 0. Variable and parameter declaration
294    !! 0.1 Input variables
295    INTEGER(i_std), INTENT (in)                         :: kjit               !! Time step number (unitless)
296    INTEGER(i_std), INTENT (in)                         :: kjpindex           !! Domain size (unitless)
297    REAL(r_std), DIMENSION (kjpindex,2), INTENT(in)     :: lalo               !! coordinates
298    INTEGER(i_std), INTENT (in)                         :: rest_id            !! Restart file identifier (unitless)
299    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT (in)  :: veget_max          !! Fraction of vegetation type
300    REAL(r_std), DIMENSION (kjpindex,nsnow),INTENT (in) :: snowdz
301    REAL(r_std), DIMENSION (kjpindex,nslm), INTENT (in) :: shumdiag_perma     !! Soil saturation degree on the diagnostic axis (0-1, unitless) 
302    REAL(r_std), DIMENSION (kjpindex), INTENT (in)      :: snow               !! Snow mass @tex ($kg$) @endtex.
303    REAL(r_std), DIMENSION(kjpindex),   INTENT (in)     :: thawed_humidity    !! specified humidity of thawed soil
304    REAL(r_std), DIMENSION(kjpindex,ndeep,nvm),   INTENT (in) :: soilc_total  !! total soil carbon for use in thermal calcs
305    REAL(r_std), DIMENSION (kjpindex), INTENT (in)      :: temp_sol_new       !! Surface temperature at the present time-step,
306
307    REAL(r_std),DIMENSION (kjpindex), INTENT(in)          :: frac_snow_veg    !! Snow cover fraction on vegeted area
308    REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in)   :: frac_snow_nobio  !! Snow cover fraction on non-vegeted area
309    REAL(r_std),DIMENSION (kjpindex),INTENT(in)           :: totfrac_nobio    !! Total fraction of continental ice+lakes+cities+...
310                                                                              !! (unitless,0-1)
311    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT(in)    :: snowrho         !! Snow density
312    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT(in) :: snowtemp        !! Snow temperature
313    REAL(r_std), DIMENSION (kjpindex), INTENT (in)         :: pb              !! Surface presure (hPa)
314
315
316    !! 0.2 Output variables
317    !! 0.3 Modified variables
318    REAL(r_std), DIMENSION(kjpindex),   INTENT (inout)  :: organic_layer_thick!! how deep is the organic soil?
319    REAL(r_std),DIMENSION (kjpindex,nslm), INTENT (inout) :: stempdiag        !! diagnostic temperature profile @tex ($K$) @endtex
320                                                                              !! , eg on the
321                                                                              !! diagnostic axis (levels:1:nslm). The soil
322                                                                              !! temperature is put on this diagnostic axis to be
323                                                                              !! used by other modules (slowproc.f90; routing.f90;
324                                                                              !! hydrol or hydrolc when a frozen soil
325                                                                              !! parametrization is used..)
326    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)    :: soilcap            !! apparent surface heat capacity
327    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)    :: soilflx            !! apparent soil heat flux @tex ($W m^{-2}$) @endtex
328    REAL(r_std),DIMENSION (kjpindex),INTENT(out)          :: gtemp            !! First soil layer temperature
329
330    !! 0.3 Modified variables
331    REAL(r_std), DIMENSION (kjpindex), INTENT(inout)       :: lambda_snow     !! Coefficient of the linear extrapolation of surface temperature
332    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (inout):: cgrnd_snow      !! Integration coefficient for snow numerical scheme
333    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (inout):: dgrnd_snow      !! Integration coefficient for snow numerical scheme
334
335    !! 0.4 Local variables
336    REAL(r_std),DIMENSION (kjpindex,ngrnd,nvm)          :: reftemp_3d
337    INTEGER(i_std)                                      :: ier, i, m 
338    INTEGER(i_std)  :: jv
339
340    CHARACTER(LEN=80)                                   :: var_name           !! To store variables names for I/O
341    CHARACTER(LEN=10) :: part_str                                             !! String suffix indicating an index
342    REAL(r_std), DIMENSION (kjpindex,nvm)               :: veget_max_bg
343    REAL(r_std), DIMENSION (kjpindex,nvm)               :: veget_mask_real
344
345    LOGICAL, SAVE                                       :: ok_zimov
346    REAL(r_std),DIMENSION (kjpindex,ngrnd)              :: temp               !! buffer
347    REAL(r_std),DIMENSION (kjpindex,ngrnd-1)            :: temp1              !! buffer
348    REAL(r_std),DIMENSION (kjpindex)                    :: temp2              !! buffer
349    LOGICAL                                               :: calculate_coef   !! Local flag to initialize variables by call to thermosoilc_coef   
350!_ ================================================================================================================================
351
352  !! 1. Initialisation
353
354     ok_shum_ngrnd_permalong = .FALSE.
355     CALL getin_p ('OK_WETDIAGLONG',ok_shum_ngrnd_permalong)
356
357    IF (ok_freeze_thermix .AND. ok_pc) THEN
358        ok_shum_ngrnd_permalong = .TRUE.
359    ENDIF
360
361    CALL getin_p('satsoil', satsoil)
362    IF (ok_freeze_thermix .AND. ok_pc) THEN
363        use_toporganiclayer_tempdiff = .false.
364        CALL getin_p('USE_TOPORGANICLAYER_TEMPDIFF',use_toporganiclayer_tempdiff)
365
366        use_soilc_tempdiff = .false.
367        CALL getin_p('USE_SOILC_TEMPDIFF', use_soilc_tempdiff)
368        IF (use_toporganiclayer_tempdiff .AND. use_soilc_tempdiff) THEN
369           WRITE(*,*) 'warning: thermosoilc_getdiff: cant have both use_toporganiclayer_tempdiff and'
370           WRITE(*,*) 'use_soilc_tempdiff set to .true.. using only use_soilc_tempdiff.'
371           use_toporganiclayer_tempdiff = .FALSE.
372        ENDIF
373    ENDIF
374
375  !! 2. Arrays allocations
376
377    ALLOCATE (ptn(kjpindex,ngrnd,nvm),stat=ier)
378    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of ptn','','')
379
380    ALLOCATE (ptn_pftmean(kjpindex,ngrnd),stat=ier)
381    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of ptn_pftmean','','')
382
383    ALLOCATE (zz(ngrnd),stat=ier)
384    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of zz','','')
385
386    ALLOCATE (zz_coef(ngrnd),stat=ier)
387    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of zz_coef','','')
388
389    ALLOCATE (dz1(ngrnd),stat=ier)
390    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of dz1','','')
391
392    ALLOCATE (dz2(ngrnd),stat=ier)
393    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of dz2','','')
394
395    ALLOCATE (z1(kjpindex),stat=ier)
396    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of z1','','')
397
398    ALLOCATE (cgrnd(kjpindex,ngrnd-1,nvm),stat=ier)
399    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of cgrnd','','')
400
401    ALLOCATE (dgrnd(kjpindex,ngrnd-1,nvm),stat=ier)
402    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of dgrnd','','')
403
404    ALLOCATE (pcapa(kjpindex,ngrnd,nvm),stat=ier)
405    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of pcapa','','')
406
407    ALLOCATE (pkappa_snow(kjpindex,nsnow),stat=ier)
408    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of pkappa_snow','','')
409
410    ALLOCATE (pcapa_snow(kjpindex,nsnow),stat=ier)
411    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of pcapa_snow','','')
412
413    ALLOCATE (pkappa(kjpindex,ngrnd,nvm),stat=ier)
414    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of pkappa','','')
415
416    ! Temporary fix: Initialize following variable because they are output to xios before the first calculation
417    pcapa  = 0
418    pkappa = 0
419    pcapa_snow  = 0
420    pkappa_snow = 0
421
422    ALLOCATE (surfheat_incr(kjpindex),stat=ier)
423    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of surfheat_incr','','')
424
425    ALLOCATE (coldcont_incr(kjpindex),stat=ier)
426    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of coldcont_incr','','')
427
428    ALLOCATE (pcapa_en(kjpindex,ngrnd,nvm),stat=ier)
429    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of pcapa_en','','')
430
431    ALLOCATE (ptn_beg(kjpindex,ngrnd,nvm),stat=ier)
432    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of ptn_beg','','')
433
434    ALLOCATE (temp_sol_beg(kjpindex),stat=ier)
435    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of temp_sol_beg','','')
436
437    ALLOCATE (shum_ngrnd_perma(kjpindex,ngrnd,nvm),stat=ier)
438    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of shum_ngrnd_perma','','')
439
440    shum_ngrnd_perma(:,:,:)=val_exp
441    ALLOCATE (shum_ngrnd_permalong(kjpindex,ngrnd,nvm),stat=ier)
442    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of shum_ngrnd_permalong','','')
443
444    ALLOCATE (profil_froz(kjpindex,ngrnd,nvm),stat=ier)
445    IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of profil_froz','','')
446   
447    IF (ok_freeze_thermix) THEN
448        ALLOCATE (pcappa_supp(kjpindex,ngrnd,nvm),stat=ier)
449        IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of pcapa_supp','','')
450    END IF
451   
452    IF (ok_Ecorr) THEN
453        ALLOCATE (e_soil_lat(kjpindex,nvm),stat=ier)
454        IF (ier /= 0) CALL ipslerr_p(3,'thermosoilc_initialize', 'Error in allocation of e_soil_lat','','')
455    END IF
456
457    !! 2. Initialize variable from restart file or with default values
458   
459    !! Reads restart files for soil temperatures only. If no restart file is
460    !! found,  the initial soil temperature is by default set to 280K at all depths. The user
461    !! can decide to initialize soil temperatures at an other value, in which case he should set the flag THERMOSOIL_TPRO
462    !! to this specific value in the run.def.
463
464       IF (printlev>=3) WRITE (numout,*) ' we have to READ a restart file for THERMOSOIL variables'
465
466        ptn(:,:,:) = val_exp
467        CALL ioconf_setatt_p('UNITS', 'K')
468        CALL ioconf_setatt_p('LONG_NAME','Soil Temperature profile')
469        CALL restget_p (rest_id, 'ptn', nbp_glo, ngrnd, nvm, kjit, .TRUE., ptn, "gather", nbp_glo, index_g) !need to add veg dim
470
471        ! Initialize ptn if it was not found in restart file
472        IF (ALL(ptn(:,:,:)==val_exp)) THEN 
473            ! ptn was not found in restart file
474            IF (read_reftemp) THEN
475                ! Read variable ptn from file
476                CALL thermosoilc_read_reftempfile(kjpindex,lalo,reftemp)
477                DO jv = 1,nvm
478                   reftemp_3d(:,:,jv)=reftemp(:,:)
479                ENDDO ! jv = 1,nvm
480                ptn(:,:,:) = reftemp_3d(:,:,:)
481                !CALL setvar_p (ptn, val_exp, 'NO_KEYWORD' ,reftemp_3d)
482            ELSE
483                ! Initialize ptn with a constant value which can be set in run.def
484
485                !Config Key   = THERMOSOIL_TPRO
486                !Config Desc  = Initial soil temperature profile if not found in restart
487                !Config Def   = 280.
488                !Config If    = OK_SECHIBA
489                !Config Help  = The initial value of the temperature profile in the soil if
490                !Config         its value is not found in the restart file. This should only
491                !Config         be used if the model is started without a restart file. Here
492                !Config         we only require one value as we will assume a constant
493                !Config         throughout the column.
494                !Config Units = Kelvin [K]
495                CALL setvar_p (ptn, val_exp,'THERMOSOIL_TPRO',272._r_std)
496            ENDIF
497        ENDIF
498 
499        ! Initialize ptn_beg (variable needed in thermosoilc_coef before calucation in thermosoilc_energy)
500        ptn_beg(:,:,:) = ptn(:,:,:)
501
502        ! Initialize temp_sol_beg with values from previous time-step
503        temp_sol_beg(:) = temp_sol_new(:) 
504
505        shum_ngrnd_permalong(:,:,:) = val_exp
506        CALL ioconf_setatt_p('UNITS', '-')
507        CALL ioconf_setatt_p('LONG_NAME','Long-term soil humidity')
508        CALL restget_p (rest_id, 'shum_ngrnd_prmlng', nbp_glo, ngrnd, nvm, kjit, .TRUE.,shum_ngrnd_permalong, "gather", nbp_glo, index_g) !need to add veg dim
509
510        shum_ngrnd_perma(:,:,:) = val_exp
511        CALL ioconf_setatt_p('UNITS', '-')
512        CALL ioconf_setatt_p('LONG_NAME','soil humidity')
513        CALL restget_p (rest_id, 'shum_ngrnd_perma', nbp_glo, ngrnd, nvm, kjit, .TRUE.,shum_ngrnd_perma, "gather", nbp_glo, index_g) !need to add veg dim
514
515        IF ( ALL(ABS(shum_ngrnd_perma(:,:,:)-val_exp).LT.EPSILON(val_exp)) ) THEN
516           shum_ngrnd_perma = 1.
517        ENDIF
518        IF ( ALL(ABS(shum_ngrnd_permalong(:,:,:)-val_exp).LT.EPSILON(val_exp)) ) THEN
519           shum_ngrnd_permalong = 1.
520        ENDIF
521
522        IF (ok_Ecorr) THEN
523            CALL restget_p (rest_id, 'e_soil_lat', nbp_glo, nvm, 1, kjit,.TRUE.,e_soil_lat, "gather", nbp_glo, index_g)
524            CALL setvar_p (e_soil_lat, val_exp,'NO_KEYWORD',zero)
525        ENDIF
526
527    IF (printlev>=3) WRITE (numout,*) ' thermosoilc_init done '
528
529        veget_max_bg(:,2:nvm) = veget_max(:,2:nvm)
530        veget_max_bg(:,1) = MAX((un - SUM(veget_max(:,2:nvm), 2)), zero)
531        ! IF (printlev >= 2) WRITE (numout,*) ' l_first_thermosoilc : call thermosoilc_init '
532        CALL getin_p('OK_ZIMOV',ok_zimov)
533       
534        !! 1.1. Allocate and initialize soil temperatures variables
535        !! by reading restart files or using default values.
536        ! CALL thermosoilc_init (kjit, ldrestart_read, kjpindex, index, lalo, rest_id, &
537        !                      & snowdz)
538
539        !! 1.2.Computes physical constants and arrays; initializes soil thermal properties; produces the first stempdiag
540        !!  Computes some physical constants and arrays depending on the soil vertical discretization
541        !! (lskin, cstgrnd, zz, zz_coef, dz1, dz2); get the vertical humidity onto the thermal levels, and
542        !! initializes soil thermal properties (pkappa, pcapa); produces the first temperature diagnostic stempdiag.
543       
544        CALL thermosoilc_var_init (kjpindex, zz, zz_coef, dz1, dz2, &
545        &        shumdiag_perma, stempdiag, profil_froz, snowdz, &
546        & thawed_humidity, organic_layer_thick, soilc_total, veget_max_bg, &
547          snowrho, snowtemp, pb)
548        !
549        !! 1.3. Computes cgrd, dgrd, soilflx and soilcap coefficients from restart values or initialisation values.
550        ! computes cgrd and dgrd coefficient from previous time step (restart)
551        !
552        CALL thermosoilc_coef (kjpindex, temp_sol_new, snow, soilcap, soilflx, &
553           & cgrnd, dgrnd, profil_froz, &
554           & organic_layer_thick, soilc_total, veget_max_bg, snowdz, &
555           & snowrho,  snowtemp,     pb, & 
556           & frac_snow_veg, frac_snow_nobio, totfrac_nobio, &
557           & lambda_snow,    cgrnd_snow,    dgrnd_snow)
558       
559
560    !     make vegetation masks so that we don't bother to calculated pfts on
561    !     gridcells where they don's exist
562    veget_max_bg(:,2:nvm) = veget_max(:,2:nvm)
563    veget_max_bg(:,1) = MAX((un - SUM(veget_max(:,2:nvm), 2)), zero)
564
565    ! Read gtemp from restart file
566    CALL restget_p (rest_id, 'gtemp', nbp_glo, 1, 1, kjit, .TRUE., &
567         gtemp, "gather", nbp_glo, index_g)
568    CALL setvar_p (gtemp, val_exp,'NO_KEYWORD',zero)
569   
570    ! Read variables calculated in thermosoilc_coef from restart file
571    ! If the variables were not found in the restart file, the logical
572    ! calculate_coef will be true and thermosoilc_coef will be called further below.
573    ! These variables need to be in the restart file to avoid a time shift that
574    ! would be done using thermosoilc_coef at this stage.
575    calculate_coef=.FALSE.
576    CALL ioconf_setatt_p('UNITS', 'J m-2 K-1')
577    CALL ioconf_setatt_p('LONG_NAME','Apparent surface heat capacity')
578    CALL restget_p (rest_id, 'soilcap', nbp_glo, 1, 1, kjit, .TRUE., &
579         soilcap, "gather", nbp_glo, index_g)
580    IF (ALL(soilcap(:)==val_exp)) calculate_coef=.TRUE.
581
582    CALL ioconf_setatt_p('UNITS', 'W m-2')
583    CALL ioconf_setatt_p('LONG_NAME','Apparent soil heat flux')
584    CALL restget_p (rest_id, 'soilflx', nbp_glo, 1, 1, kjit, .TRUE., &
585         soilflx, "gather", nbp_glo, index_g)
586    IF (ALL(soilflx(:)==val_exp)) calculate_coef=.TRUE.
587
588    CALL ioconf_setatt_p('UNITS', 'J m-2 K-1') 
589    CALL ioconf_setatt_p('LONG_NAME','Integration coefficient for the numerical scheme') 
590    CALL restget_p (rest_id, 'cgrnd', nbp_glo, ngrnd-1, 1, kjit, .TRUE., & 
591          cgrnd, "gather", nbp_glo, index_g) 
592    IF (ALL(cgrnd(:,:,:)==val_exp)) calculate_coef=.TRUE. 
593
594    CALL ioconf_setatt_p('UNITS', '') 
595    CALL ioconf_setatt_p('LONG_NAME','Integration coefficient for the numerical scheme') 
596    CALL restget_p (rest_id, 'dgrnd', nbp_glo, ngrnd-1, 1, kjit, .TRUE., & 
597          dgrnd, "gather", nbp_glo, index_g) 
598    IF (ALL(dgrnd(:,:,:)==val_exp)) calculate_coef=.TRUE. 
599
600    CALL ioconf_setatt_p('UNITS', '')
601    CALL ioconf_setatt_p('LONG_NAME','Integration coefficient for the numerical scheme')
602    CALL restget_p (rest_id, 'cgrnd_snow', nbp_glo, nsnow, 1, kjit, .TRUE., &
603         cgrnd_snow, "gather", nbp_glo, index_g)
604    IF (ALL(cgrnd_snow(:,:)==val_exp)) calculate_coef=.TRUE.
605
606    CALL ioconf_setatt_p('UNITS', '')
607    CALL ioconf_setatt_p('LONG_NAME','Integration coefficient for the numerical scheme')
608    CALL restget_p (rest_id, 'dgrnd_snow', nbp_glo, nsnow, 1, kjit, .TRUE., &
609         dgrnd_snow, "gather", nbp_glo, index_g)
610    IF (ALL(dgrnd_snow(:,:)==val_exp)) calculate_coef=.TRUE.
611
612    CALL ioconf_setatt_p('UNITS', '')
613    CALL ioconf_setatt_p('LONG_NAME','Coefficient of the linear extrapolation of surface temperature')
614    CALL restget_p (rest_id, 'lambda_snow', nbp_glo, 1, 1, kjit, .TRUE., &
615         lambda_snow, "gather", nbp_glo, index_g)
616    IF (ALL(lambda_snow(:)==val_exp)) calculate_coef=.TRUE.
617
618
619    !! 2.2.Computes physical constants and arrays; initializes soil thermal properties; produces the first stempdiag
620    !!  Computes some physical constants and arrays depending on the soil vertical discretization
621    !! (lskin, cstgrnd, zz, zz_coef, dz1, dz2); get the vertical humidity onto the thermal levels
622    CALL thermosoilc_var_init (kjpindex, zz, zz_coef, dz1, dz2, &
623                        shumdiag_perma, stempdiag, profil_froz, snowdz, &
624                        thawed_humidity, organic_layer_thick, soilc_total, veget_max, &
625                        snowrho, snowtemp, pb)
626   
627    !! 2.3. Computes cgrd, dgrd, soilflx and soilcap coefficients from restart values or initialisation values.
628    !!      This is done only if they were not found in restart file.
629    IF (calculate_coef) THEN
630       IF (printlev>=3) WRITE (numout,*) 'thermosoilc_coef will be called in the intialization phase'
631           CALL thermosoilc_coef (kjpindex,     temp_sol_new,           snow,                           &
632                         soilcap,               soilflx,                                                &
633                         cgrnd,         dgrnd,                                                          &
634                         profil_froz,                                                                   &
635                         organic_layer_thick,   soilc_total,    veget_max,      snowdz,                 &
636                         snowrho,                snowtemp,       pb,                                    &
637                         frac_snow_veg, frac_snow_nobio,        totfrac_nobio,                          &
638                         lambda_snow, cgrnd_snow, dgrnd_snow)
639
640    END IF
641
642  END SUBROUTINE thermosoilc_initialize
643
644
645!! ================================================================================================================================
646!! SUBROUTINE   : thermosoilc_main
647!!
648!>\BRIEF        Thermosoil_main computes the soil thermal properties and dynamics, ie solves
649!! the heat diffusion equation within the soil. The soil temperature profile is
650!! then interpolated onto the diagnostic axis.
651!!
652!! DESCRIPTION : The resolution of the soil heat diffusion equation
653!! relies on a numerical finite-difference implicit scheme
654!! fully described in the reference and in the header of the thermosoilc module.
655!! - The dependency of the previous timestep hidden in the
656!! integration coefficients cgrnd and dgrnd (EQ1), calculated in thermosoilc_coef, and
657!! called at the end of the routine to prepare for the next timestep.
658!! - The effective computation of the new soil temperatures is performed in thermosoilc_profile.
659!!
660!! - thermosoilc_coef calculates the coefficients for the numerical scheme for the very first iteration of thermosoilc;
661!! after that, thermosoilc_coef is called only at the end of the module to calculate the coefficients for the next timestep.
662!! - thermosoilc_profile solves the numerical scheme.\n
663!!
664!! - Flags : one unique flag : THERMOSOIL_TPRO (to be set to the desired initial soil in-depth temperature in K; by default 280K)
665!!
666!! RECENT CHANGE(S) : None
667!!
668!! MAIN OUTPUT VARIABLE(S): vertically discretized soil temperatures ptn, soil
669!! thermal properties (pcapa, pkappa), apparent surface heat capacity (soilcap)
670!! and heat flux (soilflux) to be used in enerbil at the next timestep to solve
671!! the surface energy balance.
672!!
673!! REFERENCE(S) :
674!! - Hourdin, F. (1992). Study and numerical simulation of the general circulation of planetary atmospheres,
675!!  Ph.D. thesis, Paris VII University. Remark: the part of F. Hourdin' s PhD thesis relative to the thermal
676!!  integration scheme has been scanned and is provided along with the documentation, with name :
677!!  Hourdin_1992_PhD_thermal_scheme.pdf
678!!
679!! FLOWCHART    :
680!! \latexonly
681!! \includegraphics[scale = 1]{thermosoilc_flowchart.png}
682!! \endlatexonly
683!!
684!! \n
685!_ ================================================================================================================================
686  SUBROUTINE thermosoilc_main (kjit, kjpindex, index, indexgrnd, &
687       & indexnslm, &
688       & temp_sol_new, snow, soilcap, soilflx,  &
689       & shumdiag_perma, stempdiag, ptnlev1, hist_id, hist2_id, &
690       & snowdz,snowrho, gtemp, pb, &
691       & thawed_humidity, organic_layer_thick, heat_Zimov, deeptemp_prof, deephum_prof,&
692       & soilc_total, veget_max, snowtemp,  &
693       & frac_snow_veg,frac_snow_nobio, totfrac_nobio, temp_sol_add, &
694       & lambda_snow, cgrnd_snow, dgrnd_snow)
695
696  !! 0. Variable and parameter declaration
697
698    !! 0.1 Input variables
699
700    INTEGER(i_std), INTENT(in)                            :: kjit             !! Time step number (unitless)
701    INTEGER(i_std), INTENT(in)                            :: kjpindex         !! Domain size (unitless)
702    INTEGER(i_std),INTENT (in)                            :: hist_id          !! Restart_ history file identifier
703                                                                              !! (unitless)
704    INTEGER(i_std),INTENT (in)                            :: hist2_id         !! history file 2 identifier (unitless)
705    INTEGER(i_std),DIMENSION (kjpindex), INTENT (in)      :: index            !! Indeces of the points on the map (unitless)
706    INTEGER(i_std),DIMENSION (kjpindex*ngrnd), INTENT (in):: indexgrnd        !! Indeces of the points on the 3D map (vertical
707                                                                              !! dimension towards the ground) (unitless)
708    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)      :: temp_sol_new     !! Surface temperature at the present time-step,
709                                                                              !! temp_sol_new is only modified for the case ok_explicitsnow
710                                                                              !! Ts @tex ($K$) @endtex
711    REAL(r_std),DIMENSION (kjpindex), INTENT (in)         :: snow             !! Snow mass @tex ($kg$) @endtex.
712                                                                              !! Caveat: when there is snow on the
713                                                                              !! ground, the snow is integrated into the soil for
714                                                                              !! the calculation of the thermal dynamics. It means
715                                                                              !! that the uppermost soil layers can completely or
716                                                                              !! partially consist in snow. In the second case, zx1
717                                                                              !! and zx2 are the fraction of the soil layer
718                                                                              !! consisting in snow and 'normal' soil, respectively
719                                                                              !! This is calculated in thermosoilc_coef.
720    REAL(r_std),DIMENSION (kjpindex,nslm), INTENT (in)    :: shumdiag_perma   !! Soil saturation degree on the diagnostic axis (0-1, unitless)
721    INTEGER(i_std),DIMENSION (kjpindex*nslm), INTENT (in) :: indexnslm        !! Indeces of the points on the 3D map
722    REAL(r_std), DIMENSION(kjpindex),   INTENT (in)       :: thawed_humidity  !! specified humidity of thawed soil
723    REAL(r_std), DIMENSION(kjpindex,ndeep,nvm), INTENT (in)   :: heat_Zimov   !! heating associated with decomposition
724    REAL(r_std), DIMENSION(kjpindex,ndeep,nvm),   INTENT (in) :: soilc_total  !! total soil carbon for use in thermal calcs
725    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT (in)    :: veget_max        !! Fraction of vegetation type
726    REAL(r_std),DIMENSION (kjpindex,nsnow),INTENT (in)    :: snowrho          !! Snow density
727    REAL(r_std), DIMENSION (kjpindex), INTENT (in)        :: pb               !! Surface presure (hPa)
728    REAL(r_std),DIMENSION (kjpindex,nsnow),INTENT (in)    :: snowdz           !! Snow  depth
729    REAL(r_std),DIMENSION (kjpindex,nsnow),INTENT (inout)    :: snowtemp         !! Snow temperature
730    REAL(r_std), DIMENSION(kjpindex),INTENT (in)          :: organic_layer_thick !! how deep is the organic soil?
731
732    REAL(r_std),DIMENSION (kjpindex), INTENT(in)          :: frac_snow_veg    !! Snow cover fraction on vegeted area
733    REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in)   :: frac_snow_nobio  !! Snow cover fraction on non-vegeted area
734    REAL(r_std),DIMENSION (kjpindex),INTENT(in)           :: totfrac_nobio    !! Total fraction of continental ice+lakes+cities+...
735                                                                              !!(unitless,0-1)
736    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)      :: temp_sol_add     !! additional surface temperature due to the melt of first layer
737                                                                              !!at the present time-step @tex ($K$) @endtex
738
739    !! 0.2 Output variables
740
741    REAL(r_std),DIMENSION (kjpindex), INTENT (out)        :: ptnlev1          !! 1st level soil temperature   
742    REAL(r_std), DIMENSION (kjpindex,ndeep,nvm), INTENT (out) :: deephum_prof !! moisture on a deep thermodynamic profile for permafrost calcs
743    REAL(r_std), DIMENSION (kjpindex,ndeep,nvm), INTENT (out) :: deeptemp_prof!! temp on a deep thermodynamic profile for permafrost calcs
744    REAL(r_std),DIMENSION (kjpindex),INTENT(out)          :: gtemp            !! the first soil layer temperature
745
746    !! 0.3 Modified variables
747
748    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)      :: soilcap          !! apparent surface heat capacity
749                                                                              !! @tex ($J m^{-2} K^{-1}$) @endtex
750    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)      :: soilflx          !! apparent soil heat flux @tex ($W m^{-2}$) @endtex
751                                                                              !! , positive
752                                                                              !! towards the soil, writen as Qg (ground heat flux)
753                                                                              !! in the history files, and computed at the end of
754                                                                              !! thermosoilc for the calculation of Ts in enerbil,
755                                                                              !! see EQ3.
756    REAL(r_std),DIMENSION (kjpindex,nslm), INTENT (inout) :: stempdiag        !! diagnostic temperature profile @tex ($K$) @endtex
757                                                                              !! , eg on the
758                                                                              !! diagnostic axis (levels:1:nslm). The soil
759                                                                              !! temperature is put on this diagnostic axis to be
760                                                                              !! used by other modules (slowproc.f90; routing.f90;
761                                                                              !! hydrol or hydrolc when a frozen soil
762                                                                              !! parametrization is used..)
763    REAL(r_std), DIMENSION (kjpindex), INTENT(inout)       :: lambda_snow     !! Coefficient of the linear extrapolation of surface temperature
764    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (inout):: cgrnd_snow      !! Integration coefficient for snow numerical scheme
765    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (inout):: dgrnd_snow      !! Integration coefficient for snow numerical scheme
766
767    !! 0.4 Local variables
768
769    REAL(r_std), DIMENSION (kjpindex,nvm)                 :: veget_max_bg     !! Fraction of vegetation type
770    LOGICAL, SAVE                                         :: ok_zimov
771    REAL(r_std),DIMENSION (kjpindex,ngrnd)                :: pkappa_pftmean           
772    INTEGER(i_std)                                        :: jv,ji,m,jg
773    CHARACTER(LEN=10)                                     :: part_str        !! string suffix indicating an index
774   
775   
776!_ ================================================================================================================================
777
778    veget_max_bg(:,2:nvm) = veget_max(:,2:nvm)
779    veget_max_bg(:,1) = MAX((un - SUM(veget_max(:,2:nvm), 2)), zero)
780
781  !! 3. Put the soil wetness diagnostic on the levels of the soil temperature
782
783    CALL thermosoilc_humlev(kjpindex, shumdiag_perma, thawed_humidity)
784   
785    ! Compute long-term soil humidity (for permafrost)
786    !   
787    IF (ok_shum_ngrnd_permalong) THEN
788        CALL thermosoilc_wlupdate( kjpindex, ptn, shum_ngrnd_perma, shum_ngrnd_permalong )
789    ELSE
790        shum_ngrnd_permalong(:,:,:)=shum_ngrnd_perma(:,:,:)
791    ENDIF
792
793  !! 4. Effective computation of the soil temperatures profile, using the cgrd and !dgrd coefficients from previsou tstep.
794    CALL thermosoilc_profile (kjpindex, temp_sol_new, ptn, &
795                &stempdiag, snowtemp, frac_snow_veg, &
796                &frac_snow_nobio, totfrac_nobio, veget_max, &
797                &cgrnd_snow, dgrnd_snow )
798
799  !! 5. Call to thermosoilc_energy, still to be clarified..
800
801    CALL thermosoilc_energy (kjpindex, temp_sol_new, soilcap, veget_max_bg)
802    ptn_pftmean(:,:) = zero
803    DO m=1,nvm
804       DO jg = 1, ngrnd
805          ptn_pftmean(:,jg) = ptn_pftmean(:,jg) + ptn(:,jg,m) * veget_max_bg(:,m)
806       ENDDO ! jg = 1, ngrnd
807    ENDDO ! m=1,nvm
808
809    !in only one file (hist2_id <=0) or in 2 different files (hist2_id >0).
810    CALL xios_orchidee_send_field("ptn",ptn)
811    CALL xios_orchidee_send_field("soilflx",soilflx)
812    CALL xios_orchidee_send_field("surfheat_incr",surfheat_incr)
813    CALL xios_orchidee_send_field("coldcont_incr",coldcont_incr)
814    CALL xios_orchidee_send_field("pkappa",pkappa)
815    CALL xios_orchidee_send_field("pkappa_snow",pkappa_snow)
816    CALL xios_orchidee_send_field("pcapa",pcapa)
817    CALL xios_orchidee_send_field("pcapa_snow",pcapa_snow)
818    CALL xios_orchidee_send_field("snowtemp",snowtemp) 
819 
820    IF ( .NOT. almaoutput ) THEN
821       !!need to write with PFT dimension
822       DO jv = 1, nvm
823          WRITE(part_str,'(I2)') jv
824          IF (jv < 10) part_str(1:1) = '0'
825          CALL histwrite_p(hist_id, 'ptn_'//part_str(1:LEN_TRIM(part_str)), &
826               kjit, ptn(:,:,jv), kjpindex*ngrnd, indexgrnd)
827       END DO
828       CALL histwrite_p(hist_id, 'ptn_pftmean', kjit, ptn_pftmean, kjpindex*ngrnd, indexgrnd)
829       IF (hydrol_cwrr) THEN
830         DO jv = 1, nvm
831             WRITE(part_str,'(I2)') jv
832             IF (jv < 10) part_str(1:1) = '0'
833
834             IF (ok_freeze_thermix .AND. permafrost_veg_exists(jv)) THEN
835                 CALL histwrite_p(hist_id, 'pcapa_'//part_str(1:LEN_TRIM(part_str)), &
836                      kjit, pcapa(:,:,jv), kjpindex*ngrnd, indexgrnd)
837                 !CALL histwrite_p(hist_id, 'pcappa_supp_'//part_str(1:LEN_TRIM(part_str)), &
838                 !     kjit, pcappa_supp(:,:,jv), kjpindex*ngrnd, indexgrnd)
839                 CALL histwrite_p(hist_id, 'pkappa_'//part_str(1:LEN_TRIM(part_str)), &
840                      kjit, pkappa(:,:,jv), kjpindex*ngrnd, indexgrnd)
841             ENDIF
842
843             CALL histwrite_p(hist_id, 'shum_ngrnd_perma_'//part_str(1:LEN_TRIM(part_str)), &
844                  kjit, shum_ngrnd_perma(:,:,jv), kjpindex*ngrnd, indexgrnd)
845             CALL histwrite_p(hist_id,'shum_ngrnd_prmlng_'//part_str(1:LEN_TRIM(part_str)), &
846                  kjit, shum_ngrnd_permalong(:,:,jv), kjpindex*ngrnd, indexgrnd)
847             !CALL histwrite_p(hist_id,'ptn_beg_'//part_str(1:LEN_TRIM(part_str)), &
848             !     kjit, ptn_beg(:,:,jv), kjpindex*ngrnd, indexgrnd)
849             !CALL histwrite_p(hist_id,'profil_froz_'//part_str(1:LEN_TRIM(part_str)), &
850             !     kjit, profil_froz(:,:,jv), kjpindex*ngrnd, indexgrnd)
851         END DO
852         !CALL histwrite_p(hist_id, 'shumdiag_perma', kjit, shumdiag_perma, kjpindex*nslm, indexnslm)
853         CALL histwrite_p(hist_id, 'stempdiag', kjit, stempdiag, kjpindex*nslm,indexnslm)
854       END IF
855      CALL histwrite_p(hist_id, 'Qg', kjit, soilflx, kjpindex, index)
856
857    ELSE !IF ( .NOT. almaoutput ) THEN
858      CALL histwrite_p(hist_id, 'SoilTemp', kjit, ptn, kjpindex*ngrnd, indexgrnd)
859      CALL histwrite_p(hist_id, 'Qg', kjit, soilflx, kjpindex, index)
860      CALL histwrite_p(hist_id, 'DelSurfHeat', kjit, surfheat_incr, kjpindex, index)
861      CALL histwrite_p(hist_id, 'DelColdCont', kjit, coldcont_incr, kjpindex, index)
862    ENDIF  !IF ( .NOT. almaoutput ) THEN
863    IF ( hist2_id > 0 ) THEN
864       IF ( .NOT. almaoutput ) THEN
865          CALL histwrite_p(hist_id, 'ptn_pftmean', kjit, ptn_pftmean, kjpindex*ngrnd, indexgrnd)
866       ELSE
867          CALL histwrite_p(hist2_id, 'SoilTemp', kjit, ptn, kjpindex*ngrnd, indexgrnd)
868          CALL histwrite_p(hist2_id, 'Qg', kjit, soilflx, kjpindex, index)
869          CALL histwrite_p(hist2_id, 'DelSurfHeat', kjit, surfheat_incr, kjpindex, index)
870          CALL histwrite_p(hist2_id, 'DelColdCont', kjit, coldcont_incr, kjpindex, index)
871       ENDIF
872    ENDIF
873   
874  !! 7. Considering the heat released by microbial respiration
875    IF (ok_zimov) THEN
876       CALL add_heat_Zimov(kjpindex, veget_max_bg, ptn, heat_zimov)
877    END IF
878
879  !! 8. A last final call to thermosoilc_coef
880 
881    !! A last final call to thermosoilc_coef, which calculates the different
882    !!coefficients (cgrnd, dgrnd, dz1, z1, zdz2, soilcap, soilflx) from this time step to be
883    !!used at the next time step, either in the surface temperature calculation
884    !!(soilcap, soilflx) or in the soil thermal numerical scheme.
885    !
886    CALL thermosoilc_coef (kjpindex, temp_sol_new, snow, soilcap, soilflx, &
887    & cgrnd, dgrnd, profil_froz, &
888    & organic_layer_thick, soilc_total, veget_max_bg, &
889    & snowdz,snowrho,  snowtemp,     pb, & 
890    & frac_snow_veg, frac_snow_nobio, totfrac_nobio, &
891    & lambda_snow,    cgrnd_snow,    dgrnd_snow)
892
893    !save some useful variables for new snow model
894    ptn_pftmean(:,:) = zero
895    pkappa_pftmean(:,:) = zero
896    DO m=1,nvm
897       DO jg = 1, ngrnd
898          ptn_pftmean(:,jg) = ptn_pftmean(:,jg) + ptn(:,jg,m) * veget_max_bg(:,m)
899          pkappa_pftmean(:,jg) = pkappa_pftmean(:,jg) + pkappa(:,jg,m) * veget_max_bg(:,m)
900       END DO
901    END DO
902
903    DO ji=1,kjpindex
904       gtemp(ji) = ptn_pftmean(ji,1)
905    ENDDO
906
907    ptnlev1(:) = ptn_pftmean(:,1)
908
909    !++cdk prep updated temp and moisture fields so they can be sent to stomate
910    !permafrost calcs
911    deephum_prof = shum_ngrnd_permalong
912    deeptemp_prof = ptn
913    !--cdk
914
915
916    !! Surface temperature is forced to zero celcius if its value is larger than melting point, only for explicit snow scheme
917    IF  (ok_explicitsnow) THEN
918       DO ji=1,kjpindex
919          IF  (SUM(snowdz(ji,:)) .GT. 0.0) THEN
920             IF (temp_sol_new(ji) .GE. tp_00) THEN
921                temp_sol_new(ji) = tp_00
922             ENDIF
923          END IF
924       END DO
925    ENDIF
926
927
928    IF (printlev>=3) WRITE (numout,*) ' thermosoilc_main done '
929
930  END SUBROUTINE thermosoilc_main
931
932!! ================================================================================================================================
933!! SUBROUTINE   : thermosoilc_clear
934!!
935!>\BRIEF        Desallocates the allocated arrays.
936!! The call of thermosoilc_clear originates from sechiba_clear but the calling sequence and
937!! its purpose require further investigation.
938!!
939!! DESCRIPTION  : None
940!!
941!! RECENT CHANGE(S) : None
942!!
943!! MAIN OUTPUT VARIABLE(S): None
944!!
945!! REFERENCE(S) : None
946!!
947!! FLOWCHART    : None
948!! \n
949!_ ================================================================================================================================
950 SUBROUTINE thermosoilc_clear()
951 
952        IF ( ALLOCATED (ptn)) DEALLOCATE (ptn)
953        IF ( ALLOCATED (ptn_pftmean)) DEALLOCATE (ptn_pftmean)
954        IF ( ALLOCATED (z1)) DEALLOCATE (z1) 
955        IF ( ALLOCATED (cgrnd)) DEALLOCATE (cgrnd) 
956        IF ( ALLOCATED (dgrnd)) DEALLOCATE (dgrnd) 
957        IF ( ALLOCATED (pcapa)) DEALLOCATE (pcapa)
958        IF ( ALLOCATED (pkappa))  DEALLOCATE (pkappa)
959        IF ( ALLOCATED (pcapa_en)) DEALLOCATE (pcapa_en)
960        IF ( ALLOCATED (ptn_beg)) DEALLOCATE (ptn_beg)
961        IF ( ALLOCATED (temp_sol_beg)) DEALLOCATE (temp_sol_beg)
962        IF ( ALLOCATED (surfheat_incr)) DEALLOCATE (surfheat_incr)
963        IF ( ALLOCATED (coldcont_incr)) DEALLOCATE (coldcont_incr)
964        IF ( ALLOCATED (shum_ngrnd_perma)) DEALLOCATE (shum_ngrnd_perma)
965        IF ( ALLOCATED (profil_froz)) DEALLOCATE (profil_froz)
966        IF ( ALLOCATED (shum_ngrnd_permalong)) DEALLOCATE (shum_ngrnd_permalong)
967
968  END SUBROUTINE thermosoilc_clear
969
970!!
971!=============================================================================================================================
972!! SUBROUTINE                             : thermosoilc_finalize
973!!
974!>\BRIEF                                    Write to restart file
975!!
976!! DESCRIPTION                            : This subroutine writes the module variables and variables calculated in thermosoilc
977!!                                          to restart file
978!! \n
979!_
980!==============================================================================================================================
981SUBROUTINE thermosoilc_finalize(kjit, kjpindex, rest_id, gtemp, &
982                                  soilcap, soilflx, lambda_snow, cgrnd_snow, dgrnd_snow)
983    !! 0. Variable and parameter declaration
984    !! 0.1 Input variables
985    INTEGER(i_std), INTENT(in)                            :: kjit             !! Time step number (unitless) 
986    INTEGER(i_std), INTENT(in)                            :: kjpindex         !! Domain size (unitless)
987    INTEGER(i_std),INTENT (in)                            :: rest_id          !! Restart file identifier(unitless)
988    REAL(r_std), DIMENSION (kjpindex), INTENT(in)         :: lambda_snow      !! Coefficient of the linear extrapolation of surface temperature 
989    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (in)  :: cgrnd_snow       !! Integration coefficient for snow numerical scheme
990    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (in)  :: dgrnd_snow       !! Integration coefficient for snow numerical scheme
991
992    !! 0.2 Modified variables
993    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)      :: soilcap          !! apparent surface heat capacity
994                                                                              !! @tex ($J m^{-2} K^{-1}$) @endtex
995    REAL(r_std),DIMENSION (kjpindex), INTENT (inout)      :: soilflx          !! apparent soil heat flux @tex ($W m^{-2}$) @endtex
996                                                                              !! , positive
997                                                                              !! towards the soil, writen as Qg (ground heat flux)
998                                                                              !! in the history files, and computed at the end of
999                                                                              !! thermosoilc for the calculation of Ts in enerbil,
1000                                                                              !! see EQ3.
1001
1002    REAL(r_std),DIMENSION (kjpindex),INTENT(in)          :: gtemp            !! the first soil layer temperature
1003    !! 0.3 Local variables
1004    INTEGER(i_std)                                        :: m
1005    CHARACTER(LEN=10)                                     :: part_str        !! string suffix indicating an index
1006    CHARACTER(LEN=80)                                     :: var_name         !! To store variables names for I/O
1007
1008
1009    !! 2. Prepares the restart files for the next simulation
1010
1011        IF (printlev>=3) WRITE (numout,*) ' we have to complete restart file with THERMOSOIL variables'
1012
1013        CALL restput_p (rest_id, 'ptn', nbp_glo, ngrnd, nvm, kjit, ptn, 'scatter', nbp_glo, index_g)
1014
1015        IF (ok_shum_ngrnd_permalong) THEN
1016           CALL restput_p (rest_id, 'shum_ngrnd_prmlng', nbp_glo, ngrnd, nvm, kjit,shum_ngrnd_permalong, 'scatter', nbp_glo, index_g) !need to add veg dim   
1017        END IF
1018
1019        CALL restput_p (rest_id, 'shum_ngrnd_perma', nbp_glo, ngrnd, nvm, kjit, shum_ngrnd_perma, 'scatter', nbp_glo, index_g)      !need to add veg dim
1020
1021        IF (ok_Ecorr) THEN
1022           var_name = 'e_soil_lat' 
1023           CALL restput_p (rest_id, var_name, nbp_glo, nvm, 1, kjit, e_soil_lat, 'scatter', nbp_glo, index_g)
1024        END IF
1025
1026        CALL restput_p (rest_id, 'cgrnd', nbp_glo, ngrnd-1, nvm, kjit, cgrnd, 'scatter', nbp_glo, index_g)
1027
1028        CALL restput_p (rest_id, 'dgrnd', nbp_glo, ngrnd-1, nvm, kjit, dgrnd, 'scatter', nbp_glo, index_g)
1029
1030        var_name= 'z1'
1031        CALL restput_p(rest_id, var_name, nbp_glo, 1, 1, kjit, z1, 'scatter', nbp_glo, index_g)
1032
1033        CALL restput_p (rest_id, 'pcapa', nbp_glo, ngrnd, nvm, kjit, pcapa, 'scatter', nbp_glo, index_g)
1034
1035        CALL restput_p (rest_id, 'pcapa_en', nbp_glo, ngrnd, nvm, kjit, pcapa_en, 'scatter', nbp_glo, index_g)
1036
1037        CALL restput_p (rest_id, 'pkappa', nbp_glo, ngrnd, nvm, kjit, pkappa, 'scatter', nbp_glo, index_g)
1038
1039        var_name= 'temp_sol_beg'
1040        CALL restput_p(rest_id, var_name, nbp_glo, 1, 1, kjit, temp_sol_beg, 'scatter', nbp_glo, index_g)
1041 
1042        CALL restput_p(rest_id, 'gtemp', nbp_glo, 1, 1, kjit, gtemp, 'scatter', nbp_glo, index_g)
1043
1044        var_name= 'soilcap' 
1045        CALL restput_p(rest_id, var_name, nbp_glo,   1, 1, kjit,  soilcap, 'scatter',  nbp_glo, index_g)
1046       
1047        var_name= 'soilflx' 
1048        CALL restput_p(rest_id, var_name, nbp_glo,   1, 1, kjit,  soilflx, 'scatter',  nbp_glo, index_g)
1049        CALL restput_p(rest_id, 'cgrnd_snow', nbp_glo, nsnow, 1, kjit, cgrnd_snow, 'scatter', nbp_glo, index_g) 
1050        CALL restput_p(rest_id, 'dgrnd_snow', nbp_glo, nsnow, 1, kjit, dgrnd_snow, 'scatter', nbp_glo, index_g) 
1051        CALL restput_p(rest_id, 'lambda_snow', nbp_glo, 1, 1, kjit, lambda_snow, 'scatter', nbp_glo, index_g) 
1052
1053END SUBROUTINE thermosoilc_finalize
1054 
1055!!
1056!================================================================================================================================
1057!! FUNCTION     : fz
1058!!
1059!>\BRIEF        fz(rk), the function's result, is the "rk"th element of a geometric series 
1060!! with first element fz1 and ration zalph.
1061!!
1062!! DESCRIPTION  : This function is used to calculate the depths of the boudaries of the thermal layers (zz_coef) and 
1063!! of the numerical nodes (zz) of the thermal scheme. Formulae to get the adimensional depths are followings :
1064!!      zz(jg)      = fz(REAL(jg,r_std) - undemi); \n
1065!!      zz_coef(jg) = fz(REAL(jg,r_std))
1066!!
1067!! RECENT CHANGE(S) : None
1068!!
1069!! RETURN VALUE : fz(rk)
1070!!
1071!! REFERENCE(S) : None 
1072!!
1073!! FLOWCHART    : None
1074!! \n
1075!_
1076!================================================================================================================================
1077  FUNCTION fz(rk) RESULT (fz_result)
1078
1079  !! 0. Variables and parameter declaration
1080
1081    !! 0.1 Input variables
1082
1083    REAL(r_std), INTENT(in)                        :: rk
1084   
1085    !! 0.2 Output variables
1086
1087    REAL(r_std)                                    :: fz_result
1088   
1089    !! 0.3 Modified variables
1090
1091    !! 0.4 Local variables
1092
1093!_ ================================================================================================================================
1094
1095    fz_result = fz1 * (zalph ** rk - un) / (zalph - un)
1096
1097  END FUNCTION fz
1098
1099
1100!! ================================================================================================================================
1101!! SUBROUTINE   : thermosoilc_var_init
1102!!
1103!>\BRIEF        Define and initializes the soil thermal parameters
1104!!               
1105!! DESCRIPTION  : This routine\n
1106!! 1. Defines the parameters ruling the vertical grid of the thermal scheme (fz1, zalpha).\n
1107!! 2. Defines the scaling coefficients for adimensional depths (lskin, cstgrnd, see explanation in the
1108!!    variables description of thermosoilc_main). \n
1109!! 3. Calculates the vertical discretization of the soil (zz, zz_coef, dz2) and the constants used
1110!!    in the numerical scheme and which depend only on the discretization (dz1, lambda).\n
1111!! 4. Initializes the soil thermal parameters (capacity, conductivity) based on initial soil moisture content.\n
1112!! 5. Produces a first temperature diagnostic based on temperature initialization.\n
1113!!
1114!! The scheme comprizes ngrnd=7 layers by default.
1115!! The layer' s boundaries depths (zz_coef) follow a geometric series of ratio zalph=2 and first term fz1.\n
1116!! zz_coef(jg)=fz1.(1-zalph^jg)/(1-zalph) \n
1117!! The layers' boudaries depths are first calculated 'adimensionally', ie with a
1118!! discretization adapted to EQ5. This discretization is chosen for its ability at
1119!! reproducing a thermal signal with periods ranging from days to centuries. (see
1120!! Hourdin, 1992). Typically, fz1 is chosen as : fz1=0.3*cstgrnd (with cstgrnd the
1121!! adimensional attenuation depth). \n
1122!! The factor lskin/cstgrnd is then used to go from adimensional depths to
1123!! depths in m.\n
1124!! zz(real)=lskin/cstgrnd*zz(adimensional)\n
1125!! Similarly, the depths of the numerical nodes are first calculated
1126!! adimensionally, then the conversion factor is applied.\n
1127!! the numerical nodes (zz) are not exactly the layers' centers : their depths are calculated as follows:\n
1128!! zz(jg)=fz1.(1-zalph^(jg-1/2))/(1-zalph)\n
1129!! The values of zz and zz_coef used in the default thermal discretization are in the following table.
1130!! \latexonly
1131!! \includegraphics{thermosoilc_var_init1.jpg}
1132!! \endlatexonly\n
1133!!
1134!! RECENT CHANGE(S) : None
1135!!
1136!! MAIN OUTPUT VARIABLE(S) : None
1137!!
1138!! REFERENCE(S) :
1139!! - Hourdin, F. (1992). Study and numerical simulation of the general circulation of
1140!! planetary atmospheres, Ph.D. thesis, Paris VII University.
1141!!
1142!! FLOWCHART    : None
1143!! \n
1144!_ ================================================================================================================================
1145
1146  SUBROUTINE thermosoilc_var_init(kjpindex, zz, zz_coef, dz1, dz2, &
1147  & shumdiag_perma, stempdiag, &
1148    profil_froz,snowdz, &
1149    thawed_humidity,organic_layer_thick, soilc_total, veget_max, &
1150    snowrho, snowtemp, pb)
1151
1152
1153  !! 0. Variables and parameter declaration
1154
1155    !! 0.1 Input variables
1156
1157    INTEGER(i_std), INTENT(in)                               :: kjpindex          !! Domain size (unitless)
1158    REAL(r_std), DIMENSION (kjpindex,nslm), INTENT (in)      :: shumdiag_perma    !! Relative soil humidity on the diagnostic axis
1159                                                                                  !! (unitless), [0,1]. (see description of the
1160                                                                                  !! variables of thermosoilc_main for more
1161                                                                                  !! explanations)
1162    REAL(r_std),DIMENSION(kjpindex,nsnow),INTENT(in)         :: snowrho           !! Snow density
1163    REAL(r_std),DIMENSION(kjpindex,nsnow),INTENT(in)         :: snowtemp          !! Snow temperature
1164    REAL(r_std),DIMENSION(kjpindex),INTENT(in)               :: pb                !! Surface pressure
1165   
1166    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT (in)       :: veget_max         !! Fraction of vegetation type
1167    REAL(r_std), DIMENSION (kjpindex), INTENT (in)           :: thawed_humidity   !! specified humidity of thawed soil
1168
1169    REAL(r_std), DIMENSION (kjpindex,nsnow),INTENT(in)       :: snowdz
1170    REAL(r_std), DIMENSION (kjpindex), INTENT (in)           :: organic_layer_thick      !! how deep is the organic soil?   
1171    REAL(r_std), DIMENSION (kjpindex,ndeep,nvm), INTENT (in) :: soilc_total       !! total soil carbon for use in thermal calcs
1172
1173    !! 0.2 Output variables
1174
1175    REAL(r_std), DIMENSION (ngrnd), INTENT(out)              :: zz                !! depths of the layers'numerical nodes
1176                                                                                  !! @tex ($m$)@endtex
1177    REAL(r_std), DIMENSION (ngrnd), INTENT(out)              :: zz_coef           !! depths of the layers'boundaries
1178                                                                                  !! @tex ($m$)@endtex
1179    REAL(r_std), DIMENSION (ngrnd), INTENT(out)              :: dz1               !! numerical constant depending on the vertical
1180                                                                                  !! thermal grid only @tex  ($m^{-1}$) @endtex.
1181                                                                                  !! (see description
1182                                                                                  !! of the variables of thermosoilc_main for more
1183                                                                                  !! explanations)
1184    REAL(r_std), DIMENSION (ngrnd), INTENT(out)              :: dz2               !! thicknesses of the soil thermal layers
1185                                                                                  !! @tex ($m$) @endtex
1186    REAL(r_std), DIMENSION (kjpindex,nslm), INTENT (out)     :: stempdiag         !! Diagnostic temperature profile @tex ($K$)
1187                                                                                  !! @endtex                                                                                 
1188    REAL(r_std), DIMENSION (kjpindex,ngrnd,nvm), INTENT(out) :: profil_froz
1189
1190    ! 0.3 Modified variables
1191
1192    ! 0.4 Local variables
1193
1194    REAL(r_std)                                              :: sum
1195    INTEGER(r_std)                                           :: jg 
1196    REAL(r_std)                                              :: so_cond_cnt, so_capa_cnt
1197
1198
1199  !! 1. Initialization of the parameters of the vertical discretization and of the attenuation depths
1200    CALL get_discretization_constants(so_capa_cnt, so_cond_cnt) 
1201    cstgrnd=SQRT(one_day / pi)
1202    lskin = SQRT(so_cond_cnt / so_capa_cnt * one_day / pi)
1203    fz1 = 0.3_r_std * cstgrnd
1204    !zalph = deux !this value has been changed to 1.18 in the src_parameter
1205    !directory if 32 levels have been
1206    !used
1207   
1208  !! 2.  Computing the depth of the thermal levels (numerical nodes) and the layers boundaries
1209   
1210    !! Computing the depth of the thermal levels (numerical nodes) and
1211    !! the layers boundariesusing the so-called
1212    !! adimentional variable z' = z/lskin*cstgrnd (with z in m)
1213   
1214    !! 2.1 adimensional thicknesses of the layers
1215    DO jg=1,ngrnd
1216
1217    !!?? code simplification hopefully possible here with up-to-date compilers !
1218    !!! This needs to be solved soon. Either we allow CPP options in SECHIBA or the VPP
1219    !!! fixes its compiler
1220    !!!#ifdef VPP5000
1221      dz2(jg) = fz(REAL(jg,r_std)-undemi+undemi) - fz(REAL(jg-1,r_std)-undemi+undemi)
1222    !!!#else
1223    !!!      dz2(jg) = fz(REAL(jg,r_std)) - fz(REAL(jg-1,r_std))
1224    !!!#endif
1225    ENDDO
1226   
1227    !! 2.2 Call thermosoilc depth nodes
1228    CALL thermosoilc_vert_axes(zz, zz_coef)
1229
1230    !! 2.3 Converting to meters
1231    DO jg=1,ngrnd
1232      dz2(jg)     = dz2(jg) /  cstgrnd * lskin
1233    ENDDO
1234
1235    !! 2.4 Computing some usefull constants for the numerical scheme
1236    DO jg=1,ngrnd-1
1237      dz1(jg)  = un / (zz(jg+1) - zz(jg))
1238    ENDDO
1239    lambda = zz(1) * dz1(1)
1240
1241    !! 2.6 Get the wetness profile on the thermal vertical grid from the diagnostic axis
1242    CALL thermosoilc_humlev(kjpindex, shumdiag_perma, thawed_humidity)
1243    !
1244    ! Compute long-term soil humidity (for permafrost)
1245    !CALL setvar_p (shum_ngrnd_permalong, val_exp,'NO_KEYWORD',shum_ngrnd_perma(:,:)) !has already
1246    !been considered in thermosoilc_init
1247    ! cette routine veut dire que shum_ngrnd_permalong=shum_ngrnd_perma si shum_ngrnd_permalong=val_exp
1248
1249    !! 2.7 Thermal conductivity at all levels
1250    if (ok_explicitsnow) then
1251       CALL thermosoilc_getdiff( kjpindex, ptn, shum_ngrnd_permalong, & 
1252                profil_froz, organic_layer_thick, soilc_total, snowrho, &
1253                snowtemp, pb)
1254       ! this is for the thin snow in order to prevent the warm surface
1255       CALL thermosoilc_getdiff_thinsnow (kjpindex, shum_ngrnd_permalong, snowdz, profil_froz)
1256    else
1257       !if (ok_thermix_trunc) then
1258       !    ! pour convergence avec le trunc
1259       !    CALL thermosoilc_getdiff_old_thermix_trunc2( kjpindex, pkappa, pcapa, pcapa_en )
1260       !else
1261       !    CALL thermosoilc_getdiff_old_thermix_with_snow( kjpindex, ptn, wetdiaglong, snow, pkappa, pcapa, pcapa_en,profil_froz )
1262       !endif
1263    endif
1264  !! 3. Diagnostics : consistency checks on the vertical grid.
1265    sum = zero
1266    DO jg=1,ngrnd
1267      sum = sum + dz2(jg)
1268      WRITE (numout,*) zz(jg),sum
1269    ENDDO
1270
1271  !! 4. Compute a first diagnostic temperature profile
1272
1273    CALL thermosoilc_diaglev(kjpindex, stempdiag, veget_max)
1274
1275    IF (printlev>=3) WRITE (numout,*) ' thermosoilc_var_init done '
1276
1277  END SUBROUTINE thermosoilc_var_init
1278
1279
1280 
1281
1282!! ================================================================================================================================
1283!! SUBROUTINE   : thermosoilc_coef
1284!!
1285!>\BRIEF        Calculate soil thermal properties, integration coefficients, apparent heat flux,
1286!! surface heat capacity, 
1287!!
1288!! DESCRIPTION  : This routine computes : \n
1289!!              1. the soil thermal properties. \n
1290!!              2. the integration coefficients of the thermal numerical scheme, cgrnd and dgrnd,
1291!!              which depend on the vertical grid and on soil properties, and are used at the next
1292!!              timestep.\n
1293!!              3. the soil apparent heat flux and surface heat capacity soilflux
1294!!              and soilcap, used by enerbil to compute the surface temperature at the next
1295!!              timestep.\n
1296!!             -  The soil thermal properties depend on water content (shum_ngrnd_perma) and on the presence
1297!!              of snow : snow is integrated into the soil for the thermal calculations, ie if there
1298!!              is snow on the ground, the first thermal layer(s) consist in snow, depending on the
1299!!              snow-depth. If a layer consists out of snow and soil, wheighed soil properties are
1300!!              calculated\n
1301!!             - The coefficients cgrnd and dgrnd are the integration
1302!!              coefficients for the thermal scheme \n
1303!!                              T(k+1)=cgrnd(k)+dgrnd(k)*T(k) \n
1304!!                                      -- EQ1 -- \n
1305!!              They correspond respectively to $\beta$ and $\alpha$ from F. Hourdin\'s thesis and
1306!!              their expression can be found in this document (eq A19 and A20)
1307!!             - soilcap and soilflux are the apparent surface heat capacity and flux
1308!!               used in enerbil at the next timestep to solve the surface
1309!!               balance for Ts (EQ3); they correspond to $C_s$ and $F_s$ in F.
1310!!               Hourdin\'s PhD thesis and are expressed in eq. A30 and A31. \n
1311!!                 soilcap*(Ts(t)-Ts(t-1))/dt=soilflux+otherfluxes(Ts(t)) \n
1312!!                                      -- EQ3 --\n
1313!!
1314!! RECENT CHANGE(S) : None
1315!!
1316!! MAIN OUTPUT VARIABLE(S): cgrnd, dgrnd, pcapa, pkappa, soilcap, soilflx
1317!!
1318!! REFERENCE(S) :
1319!! - Hourdin, F. (1992). Study and numerical simulation of the general circulation of planetary atmospheres,
1320!! Ph.D. thesis, Paris VII University. Remark: the part of F. Hourdin's PhD thesis relative to the thermal
1321!! integration scheme has been scanned and is provided along with the documentation, with name :
1322!! Hourdin_1992_PhD_thermal_scheme.pdf
1323!!
1324!! FLOWCHART    : None
1325!! \n
1326!_ ================================================================================================================================
1327
1328  SUBROUTINE thermosoilc_coef (kjpindex, temp_sol_new, snow, &
1329          soilcap, soilflx, &
1330        & cgrnd, dgrnd, profil_froz, &
1331        & organic_layer_thick, soilc_total, veget_max, snowdz, &
1332        & snowrho,  snowtemp,     pb, & 
1333        & frac_snow_veg, frac_snow_nobio, totfrac_nobio, &
1334        & lambda_snow,    cgrnd_snow,    dgrnd_snow)
1335
1336  !! 0. Variables and parameter declaration
1337
1338    !! 0.1 Input variables
1339
1340    INTEGER(i_std), INTENT(in)                                :: kjpindex     !! Domain size (unitless)
1341    REAL(r_std), DIMENSION (kjpindex), INTENT (in)            :: temp_sol_new !! soil surface temperature @tex ($K$) @endtex
1342    REAL(r_std), DIMENSION (kjpindex), INTENT (in)            :: snow         !! snow mass @tex ($Kg$) @endtex
1343    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT (in)        :: veget_max    !!Fraction of vegetation type
1344    REAL(r_std), DIMENSION(kjpindex),   INTENT (in)           :: organic_layer_thick !! how deep is the organic soil?
1345    REAL(r_std), DIMENSION(kjpindex,ndeep,nvm),   INTENT (in) :: soilc_total  !! total soil carbon for use in thermal calcs
1346    REAL(r_std),DIMENSION (kjpindex), INTENT(in)              :: frac_snow_veg   !! Snow cover fraction on vegeted area
1347    REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in)       :: frac_snow_nobio !! Snow cover fraction on non-vegeted area
1348    REAL(r_std),DIMENSION (kjpindex),INTENT(in)               :: totfrac_nobio   !! Total fraction of continental ice+lakes+cities+...
1349                                                                                 !!(unitless,0-1)
1350    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT(in)    :: snowdz        !!Snow depth
1351    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT(in)    :: snowrho        !!Snow density
1352    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT(in)    :: snowtemp       !! Snow temperature
1353    REAL(r_std), DIMENSION (kjpindex), INTENT (in)         :: pb         !! Surface presure (hPa)
1354
1355    !! 0.2 Output variables
1356
1357    REAL(r_std), DIMENSION (kjpindex,ngrnd-1,nvm), INTENT(out):: cgrnd        !! matrix coefficient for the computation of soil
1358                                                                              !! temperatures (beta in F. Hourdin thesis)
1359    REAL(r_std), DIMENSION (kjpindex,ngrnd-1,nvm), INTENT(out):: dgrnd        !! matrix coefficient for the computation of soil
1360                                                                              !! temperatures (alpha in F. Hourdin thesis)
1361    REAL(r_std), DIMENSION (kjpindex,ngrnd,nvm), INTENT(out)  :: profil_froz
1362    REAL(r_std), DIMENSION (kjpindex), INTENT (out)           :: soilcap      !! surface heat capacity considering snow and soil surface
1363                                                                              !! @tex ($J m^{-2} K^{-1}$) @endtex
1364    REAL(r_std), DIMENSION (kjpindex), INTENT (out)           :: soilflx      !! surface heat flux @tex ($W m^{-2}$) @endtex,
1365                                                                              !! positive towards the
1366                                                                              !! soil, writen as Qg (ground heat flux) in the history
1367                                                                              !! files.
1368
1369    !! 0.3 Modified variable
1370
1371    REAL(r_std), DIMENSION (kjpindex), INTENT(inout)       :: lambda_snow  !! Coefficient of the linear extrapolation of surface temperature
1372    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (inout):: cgrnd_snow   !! Integration coefficient for snow numerical scheme
1373    REAL(r_std), DIMENSION (kjpindex,nsnow), INTENT (inout):: dgrnd_snow   !! Integration coefficient for snow numerical scheme
1374
1375    !! 0.4 Local variables
1376
1377    REAL(r_std), DIMENSION (kjpindex,nvm)                     :: soilcap_pft 
1378    REAL(r_std), DIMENSION (kjpindex,nvm)                     :: soilflx_pft 
1379    REAL(r_std), DIMENSION (kjpindex,nvm)                     :: soilcap_pft_nosnow 
1380    REAL(r_std), DIMENSION (kjpindex,nvm)                     :: soilflx_pft_nosnow 
1381    REAL(r_std), DIMENSION (kjpindex)                      :: snowcap             !! apparent snow heat capacity @tex ($J m^{-2} K^{-1}$)
1382    REAL(r_std), DIMENSION (kjpindex)                      :: snowflx             !! apparent snow-atmosphere heat flux @tex ($W m^{-2}$) @endtex
1383    REAL(r_std), DIMENSION (kjpindex,nsnow)                :: dz1_snow
1384    REAL(r_std), DIMENSION (kjpindex,nsnow)                :: ZSNOWDZM
1385    REAL(r_std), DIMENSION (kjpindex,nsnow)                :: dz2_snow
1386    REAL(r_std), DIMENSION (kjpindex,nsnow)                :: zdz1_snow
1387    REAL(r_std), DIMENSION (kjpindex,nsnow)                :: zdz2_snow
1388    REAL(r_std), DIMENSION (kjpindex)                      :: z1_snow
1389
1390    INTEGER(i_std)                                            :: ji, jg,jv
1391    REAL(r_std), DIMENSION (kjpindex,ngrnd-1,nvm)             :: zdz1
1392
1393    REAL(r_std), DIMENSION (kjpindex,ngrnd,nvm)               :: zdz2
1394    REAL(r_std), DIMENSION (kjpindex)                         :: z1           !! numerical constant @tex ($W m^{-1} K^{-1}$) @endtex
1395
1396
1397    REAL(r_std), DIMENSION (kjpindex)                         :: soilcap_nosnow!! surface heat capacity
1398                                                                               !! @tex ($J m^{-2} K^{-1}$)
1399                                                                               !! @endtex
1400    REAL(r_std), DIMENSION (kjpindex)                         :: soilflx_nosnow!! surface heat flux @tex ($W m^{-2}$) @endtex,
1401                                                                               !! positive towards the soil, written as Qg
1402                                                                               !!(ground heat flux in the history files).
1403
1404    REAL(r_std), DIMENSION (kjpindex)                      :: cgrnd_soil   !! surface soil layer
1405    REAL(r_std), DIMENSION (kjpindex)                      :: dgrnd_soil   !! surface soil layer
1406    REAL(r_std), DIMENSION (kjpindex)                      :: zdz1_soil    !! surface soil layer
1407    REAL(r_std), DIMENSION (kjpindex)                      :: zdz2_soil    !! surface soil layer
1408!_ ================================================================================================================================
1409
1410  !! 1. Computation of the soil thermal properties
1411    ! Computation of the soil thermal properties; snow properties are also accounted for
1412
1413
1414    IF (ok_explicitsnow) THEN
1415       CALL thermosoilc_getdiff( kjpindex, ptn, shum_ngrnd_permalong,&
1416                profil_froz, organic_layer_thick, soilc_total, &
1417                snowrho, snowtemp, pb)
1418       ! this is for the thin snow in order to prevent the warm surface
1419       ! CALL thermosoilc_getdiff_thinsnow (kjpindex, shum_ngrnd_permalong, snowdz,profil_froz)
1420    ELSE
1421           CALL thermosoilc_getdiff_old_thermix_with_snow( kjpindex, snow )
1422    ENDIF
1423
1424    ! ok_freeze_thermix must be true
1425    IF (ok_Ecorr) THEN
1426        CALL thermosoilc_readjust(kjpindex, ptn)
1427    ENDIF
1428
1429    !! 2. Computation of the coefficients of the numerical integration scheme for the soil layers
1430
1431    !! 2.1 Calculate numerical coefficients zdz1 and zdz2
1432
1433     DO jv=1,nvm
1434       DO jg=1,ngrnd
1435           zdz2(:,jg,jv)=pcapa(:,jg,jv) * dlt(jg)/dt_sechiba
1436       ENDDO ! DO jg=1,ngrnd
1437       
1438       DO jg=1,ngrnd-1
1439           zdz1(:,jg,jv) = dz1(jg) * pkappa(:,jg,jv)
1440       ENDDO !DO jg=1,ngrnd-1
1441
1442   
1443    !! 2.2 Calculate coefficients cgrnd and dgrnd for soil
1444        z1(:) = zdz2(:,ngrnd,jv) + zdz1(:,ngrnd-1,jv)
1445        cgrnd(:,ngrnd-1,jv) = (phigeoth + zdz2(:,ngrnd,jv) * ptn(:,ngrnd,jv)) / z1(:)
1446        dgrnd(:,ngrnd-1,jv) = zdz1(:,ngrnd-1,jv) / z1(:)
1447       DO jg = ngrnd-1,2,-1
1448          z1(:) = un / (zdz2(:,jg,jv) + zdz1(:,jg-1,jv) + zdz1(:,jg,jv) * (un - dgrnd(:,jg,jv)))
1449          cgrnd(:,jg-1,jv) = (ptn(:,jg,jv) * zdz2(:,jg,jv) + zdz1(:,jg,jv) * cgrnd(:,jg,jv)) * z1(:)
1450          dgrnd(:,jg-1,jv) = zdz1(:,jg-1,jv) * z1(:)
1451       ENDDO ! jg = ngrnd-1,2,-1
1452
1453     !! 3. Computation of the apparent ground heat flux
1454       
1455       !! Computation of the apparent ground heat flux (> towards the soil) and
1456       !! apparent surface heat capacity, used at the next timestep by enerbil to
1457       !! compute the surface temperature.
1458         soilflx_pft_nosnow(:,jv) = zdz1(:,1,jv) * (cgrnd(:,1,jv) + (dgrnd(:,1,jv)-1.) * ptn(:,1,jv))
1459         soilcap_pft_nosnow(:,jv) = (zdz2(:,1,jv) * dt_sechiba + dt_sechiba * (un - dgrnd(:,1,jv)) * zdz1(:,1,jv))
1460         z1(:) = lambda * (un - dgrnd(:,1,jv)) + un
1461         soilcap_pft_nosnow(:,jv) = soilcap_pft_nosnow(:,jv) / z1(:)
1462         soilflx_pft_nosnow(:,jv) = soilflx_pft_nosnow(:,jv) + &
1463            & soilcap_pft_nosnow(:,jv) * (ptn(:,1,jv) * z1(:) - lambda * cgrnd(:,1,jv) - temp_sol_new(:)) / dt_sechiba 
1464    ENDDO ! jv=1,nvm
1465
1466    ! 4 here is where I normalize to take the weighted means of each of the
1467    ! PFTs for surface energy fluxes
1468    soilflx(:) = zero
1469    soilcap(:) = zero
1470    soilflx_nosnow(:) = zero
1471    soilcap_nosnow(:) = zero
1472    cgrnd_soil(:) = zero
1473    dgrnd_soil(:) = zero
1474    zdz1_soil(:) = zero
1475    zdz2_soil(:) = zero
1476
1477  !! 3. Computation of the apparent ground heat flux
1478    IF (ok_explicitsnow) THEN
1479        DO ji = 1,kjpindex
1480              DO jv=1,nvm !pft
1481                 !IF ( SUM(snowdz(ji,:)) .LE. 0.01) THEN
1482                    soilflx_nosnow(ji) = soilflx_nosnow(ji) + (soilflx_pft_nosnow(ji,jv)*veget_max(ji,jv))
1483                    soilcap_nosnow(ji) = soilcap_nosnow(ji) + (soilcap_pft_nosnow(ji,jv)*veget_max(ji,jv))
1484                    cgrnd_soil(ji) = cgrnd_soil(ji) + (cgrnd(ji,1,jv)*veget_max(ji,jv))
1485                    dgrnd_soil(ji) = dgrnd_soil(ji) + (dgrnd(ji,1,jv)*veget_max(ji,jv))
1486                    zdz1_soil(ji)  = zdz1_soil(ji)  + (zdz1(ji,1,jv)*veget_max(ji,jv))
1487                    zdz2_soil(ji)  = zdz2_soil(ji)  + (zdz2(ji,1,jv)*veget_max(ji,jv))
1488
1489              END DO
1490        END DO
1491    ELSE
1492        DO ji = 1,kjpindex
1493              DO jv=1,nvm !pft
1494                    soilflx(ji) = soilflx(ji) + (soilflx_pft(ji,jv)*veget_max(ji,jv))
1495                    soilcap(ji) = soilcap(ji) + (soilcap_pft(ji,jv)*veget_max(ji,jv))
1496
1497                    cgrnd_soil(ji) = cgrnd_soil(ji) + (cgrnd(ji,1,jv)*veget_max(ji,jv))
1498                    dgrnd_soil(ji) = dgrnd_soil(ji) + (dgrnd(ji,1,jv)*veget_max(ji,jv))
1499                    zdz1_soil(ji)  = zdz1_soil(ji)  + (zdz1(ji,1,jv)*veget_max(ji,jv))
1500                    zdz2_soil(ji)  = zdz2_soil(ji)  + (zdz2(ji,1,jv)*veget_max(ji,jv))
1501
1502              END DO
1503        END DO
1504    ENDIF
1505
1506    !! 3. Computation of the coefficients of the numerical integration scheme for the snow layers
1507
1508    !! 3.1 Calculate numerical coefficients zdz1_snow, zdz2_snow and lambda_snow
1509    DO ji = 1, kjpindex
1510
1511       IF ( ok_explicitsnow ) THEN
1512
1513          ! Calculate internal values
1514          DO jg = 1, nsnow
1515             ZSNOWDZM(ji,jg) = MAX(snowdz(ji,jg),psnowdzmin)
1516          ENDDO
1517          dz2_snow(ji,:)=ZSNOWDZM(ji,:)
1518
1519          DO jg = 1, nsnow-1
1520             dz1_snow(ji,jg)  = 2.0 / (dz2_snow(ji,jg+1)+dz2_snow(ji,jg))
1521          ENDDO
1522
1523          lambda_snow(ji) = dz2_snow(ji,1)/2.0 * dz1_snow(ji,1)
1524
1525          DO jg=1,nsnow
1526             zdz2_snow(ji,jg)=pcapa_snow(ji,jg) * dz2_snow(ji,jg)/dt_sechiba
1527          ENDDO
1528
1529          DO jg=1,nsnow-1
1530             zdz1_snow(ji,jg) = dz1_snow(ji,jg) * pkappa_snow(ji,jg)
1531          ENDDO
1532
1533          ! the bottom snow
1534          zdz1_snow(ji,nsnow) = pkappa_snow(ji,nsnow) / ( zlt(1) + dz2_snow(ji,nsnow)/2 )
1535
1536       ELSE
1537          ! Without explict snow
1538          lambda_snow(ji) = lambda
1539       ENDIF
1540
1541    ENDDO
1542
1543
1544
1545    !! 3.2 Calculate coefficients cgrnd_snow and dgrnd_snow for snow
1546      DO ji = 1,kjpindex
1547       IF ( ok_explicitsnow ) THEN
1548          ! bottom level
1549          z1_snow(ji) = zdz2(ji,1,jv)+(un-dgrnd_soil(ji))*zdz1_soil(ji)+zdz1_snow(ji,nsnow)
1550          cgrnd_snow(ji,nsnow) = (zdz2_soil(ji) * ptn_pftmean(ji,1) + zdz1_soil(ji) * cgrnd_soil(ji) ) / z1_snow(ji)
1551          dgrnd_snow(ji,nsnow) = zdz1_snow(ji,nsnow) / z1_snow(ji)
1552
1553          ! next-to-bottom level
1554          z1_snow(ji) = zdz2_snow(ji,nsnow)+(un-dgrnd_snow(ji,nsnow))*zdz1_snow(ji,nsnow)+zdz1_snow(ji,nsnow-1)
1555          cgrnd_snow(ji,nsnow-1) = (zdz2_snow(ji,nsnow)*snowtemp(ji,nsnow)+&
1556               zdz1_snow(ji,nsnow)*cgrnd_snow(ji,nsnow))/z1_snow(ji)
1557          dgrnd_snow(ji,nsnow-1) = zdz1_snow(ji,nsnow-1) / z1_snow(ji)
1558
1559          DO jg = nsnow-1,2,-1
1560             z1_snow(ji) = un / (zdz2_snow(ji,jg) + zdz1_snow(ji,jg-1) + zdz1_snow(ji,jg) * (un - dgrnd_snow(ji,jg)))
1561             cgrnd_snow(ji,jg-1) = (snowtemp(ji,jg) * zdz2_snow(ji,jg) + zdz1_snow(ji,jg) * cgrnd_snow(ji,jg)) * z1_snow(ji)
1562             dgrnd_snow(ji,jg-1) = zdz1_snow(ji,jg-1) * z1_snow(ji)
1563          ENDDO
1564       ELSE
1565          ! Without explict snow
1566          cgrnd_snow(ji,:) = zero
1567          dgrnd_snow(ji,:) = zero
1568       ENDIF
1569      ENDDO
1570
1571  !! 4. Computation of the apparent ground heat flux
1572    !! Computation of apparent snow-atmosphere flux 
1573    DO ji = 1,kjpindex
1574       IF ( ok_explicitsnow ) THEN
1575          snowflx(ji) = zdz1_snow(ji,1) * (cgrnd_snow(ji,1) + (dgrnd_snow(ji,1)-1.) * snowtemp(ji,1))
1576          snowcap(ji) = (zdz2_snow(ji,1) * dt_sechiba + dt_sechiba * (un - dgrnd_snow(ji,1)) * zdz1_snow(ji,1))
1577          z1_snow(ji) = lambda_snow(ji) * (un - dgrnd_snow(ji,1)) + un 
1578          snowcap(ji) = snowcap(ji) / z1_snow(ji)
1579          snowflx(ji) = snowflx(ji) + &
1580               & snowcap(ji) * (snowtemp(ji,1) * z1_snow(ji) - lambda_snow(ji) * cgrnd_snow(ji,1) - temp_sol_new(ji)) / dt_sechiba
1581       ELSE
1582          snowflx(ji) = zero
1583          snowcap(ji) = zero
1584       ENDIF
1585    ENDDO
1586
1587    !! Add snow fraction
1588    IF ( ok_explicitsnow ) THEN
1589       ! Using an effective heat capacity and heat flux by a simple pondering of snow and soil fraction
1590       DO ji = 1, kjpindex
1591          soilcap(ji) = snowcap(ji)*frac_snow_veg(ji)*(1-totfrac_nobio(ji))+    & ! weights related to snow cover fraction on vegetation 
1592               soilcap_nosnow(ji)*SUM(frac_snow_nobio(ji,:))*totfrac_nobio(ji)+ & ! weights related to SCF on nobio
1593               soilcap_nosnow(ji)*(1-(frac_snow_veg(ji)*(1-totfrac_nobio(ji))+SUM(frac_snow_nobio(ji,:))*totfrac_nobio(ji))) ! weights related to non snow fraction
1594          soilflx(ji) = snowflx(ji)*frac_snow_veg(ji)*(1-totfrac_nobio(ji))+    & ! weights related to snow cover fraction on vegetation 
1595               soilflx_nosnow(ji)*SUM(frac_snow_nobio(ji,:))*totfrac_nobio(ji)+ & ! weights related to SCF on nobio
1596               soilflx_nosnow(ji)*(1-(frac_snow_veg(ji)*(1-totfrac_nobio(ji))+SUM(frac_snow_nobio(ji,:))*totfrac_nobio(ji))) ! weights related to non snow fraction
1597       ENDDO
1598    ELSE
1599       ! Do not consider snow fraction
1600       soilcap(:)=soilcap_nosnow(:)
1601       soilflx(:)=soilflx_nosnow(:)
1602    END IF
1603
1604    IF (printlev>=3) WRITE (numout,*) ' thermosoil_coef done '
1605
1606  END SUBROUTINE thermosoilc_coef
1607 
1608 
1609!! ================================================================================================================================
1610!! SUBROUTINE   : thermosoilc_profile
1611!!
1612!>\BRIEF        In this routine solves the numerical soil thermal scheme, ie calculates the new soil temperature profile;
1613!! This profile is then exported onto the diagnostic axis (call thermosoilc_diaglev)
1614!!
1615!! DESCRIPTION  : The calculation of the new soil temperature profile is based on
1616!! the cgrnd and dgrnd values from the previous timestep and the surface temperature Ts aka temp_sol_new. (see detailed
1617!! explanation in the header of the thermosoilc module or in the reference).\n
1618!!                              T(k+1)=cgrnd(k)+dgrnd(k)*T(k)\n
1619!!                                      -- EQ1 --\n
1620!!                           Ts=(1-lambda)*T(1) -lambda*T(2)\n
1621!!                                      -- EQ2--\n
1622!!
1623!! RECENT CHANGE(S) : None
1624!!
1625!! MAIN OUTPUT VARIABLE(S): ptn (soil temperature profile on the thermal axis),
1626!!                          stempdiag (soil temperature profile on the diagnostic axis)
1627!!
1628!! REFERENCE(S) :
1629!! - Hourdin, F. (1992). Study and numerical simulation of the general circulation of planetary atmospheres,
1630!! Ph.D. thesis, Paris VII University. Remark: the part of F. Hourdin's PhD thesis relative to the thermal
1631!! integration scheme has been scanned and is provided along with the documentation, with name :
1632!! Hourdin_1992_PhD_thermal_scheme.pdf
1633!!
1634!! FLOWCHART    : None
1635!! \n
1636!_ ================================================================================================================================
1637 SUBROUTINE thermosoilc_profile (kjpindex, temp_sol_new, ptn, stempdiag,&
1638                                snowtemp, frac_snow_veg, frac_snow_nobio, &
1639                                totfrac_nobio, veget_max,                 &
1640                                cgrnd_snow,    dgrnd_snow)
1641
1642  !! 0. Variables and parameter declaration
1643
1644    !! 0.1 Input variables
1645
1646    INTEGER(i_std), INTENT(in)                               :: kjpindex       !! Domain size (unitless)
1647    REAL(r_std),DIMENSION (kjpindex), INTENT (in)            :: temp_sol_new   !! Surface temperature at the present time-step
1648                                                                               !! @tex ($K$) @endtex
1649    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT (in)       :: veget_max      !! Fraction of vegetation type
1650    REAL(r_std),DIMENSION (kjpindex), INTENT(in)             :: frac_snow_veg  !! Snow cover fraction on vegeted area
1651    REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in)      :: frac_snow_nobio!! Snow cover fraction on non-vegeted area
1652    REAL(r_std),DIMENSION (kjpindex),INTENT(in)              :: totfrac_nobio  !! Total fraction of continental ice+lakes+cities+...(unitless,0-1)
1653    REAL(r_std),DIMENSION (kjpindex,nsnow), INTENT(in)       :: snowtemp       !! Snow temperature
1654    REAL(r_std),DIMENSION (kjpindex,nsnow), INTENT(in)       :: cgrnd_snow     !! Integration coefficient for snow numerical scheme
1655    REAL(r_std),DIMENSION (kjpindex,nsnow), INTENT(in)       :: dgrnd_snow     !! Integration coefficient for snow numerical scheme
1656
1657   
1658    !! 0.2 Output variables
1659    REAL(r_std),DIMENSION (kjpindex,nslm), INTENT (out)      :: stempdiag      !! diagnostic temperature profile
1660                                                                               !! @tex ($K$) @endtex
1661    REAL(r_std),DIMENSION (kjpindex,ngrnd, nvm), INTENT (out) :: ptn           !! vertically discretized soil temperatures
1662                                                                               !! @tex ($K$) @endtex
1663
1664    !! 0.3 Modified variables
1665
1666
1667    !! 0.4 Local variables
1668
1669    INTEGER(i_std)                                           :: ji, jg, jv
1670    REAL(r_std)                                              :: temp_sol_eff
1671     
1672!_ ================================================================================================================================
1673   
1674  !! 1. Computes the soil temperatures ptn.
1675
1676    !! 1.1. ptn(jg=1) using EQ1 and EQ2
1677    DO jv = 1,nvm 
1678      DO ji = 1,kjpindex
1679           IF (ok_explicitsnow) THEN
1680              ! using an effective surface temperature by a simple pondering 
1681              temp_sol_eff=snowtemp(ji,nsnow)*frac_snow_veg(ji)*(1-totfrac_nobio(ji))+ & ! weights related to snow cover fraction on vegetation   
1682                           temp_sol_new(ji)*SUM(frac_snow_nobio(ji,:))*totfrac_nobio(ji)+ & ! weights related to SCF on nobio     
1683                           temp_sol_new(ji)*(1-(frac_snow_veg(ji)*(1-totfrac_nobio(ji))+SUM(frac_snow_nobio(ji,:))*totfrac_nobio(ji)))
1684              ! weights related to non snow fraction
1685              ! Soil temperature calculation with explicit snow if there is snow on the ground
1686              ptn(ji,1,jv) = cgrnd_snow(ji,nsnow) + dgrnd_snow(ji,nsnow) * temp_sol_eff
1687
1688           ELSE
1689              ptn(ji,1,jv) = (lambda * cgrnd(ji,1,jv) + temp_sol_new(ji)) / (lambda *(un - dgrnd(ji,1,jv)) + un)
1690           ENDIF
1691      ENDDO
1692     
1693      !! 1.2. ptn(jg=2:ngrnd) using EQ1.
1694      DO jg = 1,ngrnd-1
1695        DO ji = 1,kjpindex
1696          ptn(ji,jg+1,jv) = cgrnd(ji,jg,jv) + dgrnd(ji,jg,jv) * ptn(ji,jg,jv)
1697        ENDDO
1698      ENDDO
1699    ENDDO
1700  !! 2. Put the soil temperatures onto the diagnostic axis
1701 
1702    !! Put the soil temperatures onto the diagnostic axis for convenient
1703    !! use in other routines (stomate..)
1704    CALL thermosoilc_diaglev(kjpindex, stempdiag, veget_max)
1705
1706    IF (printlev>=3) WRITE (numout,*) ' thermosoilc_profile done '
1707
1708  END SUBROUTINE thermosoilc_profile
1709
1710!!
1711!! ================================================================================================================================
1712!! SUBROUTINE   : thermosoilc_diaglev
1713!!
1714!>\BRIEF        Interpolation of the soil in-depth temperatures onto the diagnostic profile.
1715!!
1716!! DESCRIPTION  : This is a very easy linear interpolation, with intfact(jsl, jg) the fraction
1717!! the thermal layer jg comprised within the diagnostic layer jsl. The depths of
1718!! the diagnostic levels are diaglev(1:nslm), computed in slowproc.f90.
1719!!
1720!! RECENT CHANGE(S) : None
1721!!
1722!! MAIN OUTPUT VARIABLE(S): stempdiag (soil temperature profile on the diagnostic axis)
1723!!
1724!! REFERENCE(S) : None
1725!!
1726!! FLOWCHART    : None
1727!! \n
1728!_ ================================================================================================================================
1729  SUBROUTINE thermosoilc_diaglev(kjpindex, stempdiag, veget_max)
1730
1731  !! 0. Variables and parameter declaration
1732
1733    !! 0.1 Input variables
1734 
1735    INTEGER(i_std), INTENT(in)                          :: kjpindex       !! Domain size (unitless)
1736    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT (in)  :: veget_max      !! Fraction of vegetation type
1737    !! 0.2 Output variables
1738
1739    REAL(r_std),DIMENSION (kjpindex,nslm), INTENT (out) :: stempdiag      !! Diagnostoc soil temperature profile @tex ($K$) @endtex
1740   
1741    !! 0.3 Modified variables
1742
1743    !! 0.4 Local variables
1744
1745    INTEGER(i_std)                                      :: ji, jd, jg,jv, jsl
1746    REAL(r_std)                                         :: lev_diag, prev_diag, lev_prog, prev_prog
1747    REAL(r_std), SAVE, ALLOCATABLE, DIMENSION(:,:)      :: intfact
1748    REAL(r_std),DIMENSION (kjpindex,ngrnd)              :: ptnmoy
1749    LOGICAL, PARAMETER                                  :: check=.FALSE.
1750!_ ================================================================================================================================
1751   
1752  !! 1. Computes intfact(jsl, jg)
1753
1754    !! Computes intfact(jsl, jg), the fraction
1755    !! the thermal layer jg comprised within the diagnostic layer jsl.
1756
1757    IF ( .NOT. ALLOCATED(intfact)) THEN
1758       
1759        ALLOCATE(intfact(nslm, ngrnd))
1760       
1761        prev_diag = zero
1762        DO jsl = 1, nslm
1763          lev_diag = diaglev(jsl)
1764          prev_prog = zero
1765          DO jg = 1, ngrnd
1766             IF ( jg == ngrnd .AND. (prev_prog + dz2(jg)) < lev_diag ) THEN
1767                lev_prog = lev_diag
1768             ELSE
1769                lev_prog = prev_prog + dz2(jg)
1770             ENDIF
1771            intfact(jsl,jg) = MAX(MIN(lev_diag,lev_prog)-MAX(prev_diag, prev_prog),&
1772                        & zero)/(lev_diag-prev_diag)
1773            prev_prog = lev_prog
1774          ENDDO
1775           prev_diag = lev_diag
1776        ENDDO
1777
1778        IF ( check ) THEN
1779           WRITE(numout,*) 'thermosoilc_diagev -- thermosoilc_diaglev -- thermosoilc_diaglev --' 
1780           DO jsl = 1, nslm
1781              WRITE(numout,*) jsl, '-', intfact(jsl,1:ngrnd)
1782           ENDDO
1783           WRITE(numout,*) "SUM -- SUM -- SUM SUM -- SUM -- SUM"
1784           DO jsl = 1, nslm
1785              WRITE(numout,*) jsl, '-', SUM(intfact(jsl,1:ngrnd))
1786           ENDDO
1787           WRITE(numout,*) 'thermosoilc_diaglev -- thermosoilc_diaglev -- thermosoilc_diaglev --' 
1788        ENDIF
1789       
1790    ENDIF
1791
1792 !! 2. does the interpolation
1793    ptnmoy(:,:) = 0.
1794    DO jv = 1, nvm
1795      DO jg = 1, ngrnd
1796        ptnmoy(:,jg) = ptnmoy(:,jg) + ptn(:,jg,jv)*veget_max(:,jv)
1797      ENDDO
1798    ENDDO
1799
1800    stempdiag(:,:) = zero
1801    DO jg = 1, ngrnd
1802      DO jsl = 1, nslm
1803        DO ji = 1, kjpindex
1804          stempdiag(ji,jsl) = stempdiag(ji,jsl) + ptnmoy(ji,jg)*intfact(jsl,jg)
1805        ENDDO
1806      ENDDO
1807    ENDDO
1808
1809  END SUBROUTINE thermosoilc_diaglev
1810
1811!! ================================================================================================================================
1812!! SUBROUTINE   : thermosoilc_humlev
1813!!
1814!>\BRIEF        Interpolates the diagnostic soil humidity profile shumdiag_perma(nslm, diagnostic axis) onto
1815!!              the thermal axis, which gives shum_ngrnd_perma(ngrnd, thermal axis).
1816!!
1817!! DESCRIPTION  : Same as in thermosoilc_diaglev : This is a very easy linear interpolation, with intfactw(jsl, jg) the fraction
1818!! the thermal layer jsl comprised within the diagnostic layer jg.
1819!!?? I would think wise to change the indeces here, to keep jD for Diagnostic
1820!!?? and jG for Ground thermal levels...
1821!!
1822!! The depths of the diagnostic levels are diaglev(1:nslm), computed in slowproc.f90.
1823!! Recall that when the 11-layer hydrology is used,
1824!! shum_ngrnd_perma and shumdiag_perma are with reference to the moisture content (mc)
1825!! at the wilting point mcw : shum_ngrnd_perma=(mc-mcw)/(mcs-mcw).
1826!! with mcs the saturated soil moisture content.
1827!!
1828!! RECENT CHANGE(S) : None
1829!!
1830!! MAIN OUTPUT VARIABLE(S): shum_ngrnd_perma (soil humidity profile on the thermal axis)
1831!!
1832!! REFERENCE(S) : None
1833!!
1834!! FLOWCHART    : None
1835!! \n
1836!_ ================================================================================================================================
1837  SUBROUTINE thermosoilc_humlev(kjpindex, shumdiag_perma, thawed_humidity)
1838 
1839  !! 0. Variables and parameter declaration
1840
1841    !! 0.1 Input variables
1842 
1843    INTEGER(i_std), INTENT(in)                            :: kjpindex    !! Domain size (unitless)
1844    REAL(r_std),DIMENSION (kjpindex,nslm), INTENT (in)    :: shumdiag_perma    !! Relative soil humidity on the diagnostic axis.
1845                                                                         !! (0-1, unitless). Caveats : when "hydrol" (the 11-layers
1846                                                                         !! hydrology) is used, this humidity is calculated with
1847                                                                         !! respect to the wilting point :
1848                                                                         !! shumdiag_perma= (mc-mcw)/(mcs-mcw), with mc : moisture
1849                                                                         !! content; mcs : saturated soil moisture content; mcw:
1850                                                                         !! soil moisture content at the wilting point. when the 2-layers
1851                                                                         !! hydrology "hydrolc" is used, shumdiag_perma is just
1852                                                                         !! a diagnostic humidity index, with no real physical
1853                                                                         !! meaning.
1854   
1855    !! 0.2 Output variables
1856
1857    !! 0.3 Modified variables
1858
1859    !! 0.4 Local variables
1860    INTEGER(i_std)                                       :: ji, jsl, jg, jv
1861    REAL(r_std)                                          :: lev_diag, prev_diag, lev_prog, prev_prog
1862    REAL(r_std), DIMENSION(ngrnd,nslm)                   :: intfactw     !! fraction of each diagnostic layer (jsl) comprized within
1863                                                                         !! a given thermal layer (jg)(0-1, unitless)
1864    INTEGER(i_std), SAVE                :: proglevel_bottomdiaglev       !! for keeping track of where the base of the diagnostic level meets the prognostic level
1865    INTEGER(i_std), SAVE                :: proglevel_zdeep               !! for keeping track of where the prognostic levels meet zdeep
1866    LOGICAL                             :: at_zdeep=.FALSE.
1867    LOGICAL                             :: at_bottomdiaglev=.FALSE.
1868    REAL(r_std), DIMENSION(kjpindex), INTENT (in)  :: thawed_humidity    !! specified humidity of thawed soil
1869
1870    LOGICAL, PARAMETER :: check=.FALSE.
1871
1872!_ ================================================================================================================================
1873   
1874  !! 1. computes intfactw(jsl,jg), the fraction of each diagnostic layer (jg) comprized within a given thermal layer (jsl)
1875    IF ( check ) &
1876         WRITE(numout,*) 'thermosoilc_humlev --' 
1877
1878    shum_ngrnd_perma(:,:,:) = zero
1879    prev_diag = zero
1880    DO jsl = 1, ngrnd
1881       lev_diag = prev_diag + dz2(jsl)
1882       prev_prog = zero
1883       DO jg = 1, nslm
1884          IF ( jg == nslm .AND. diaglev(jg) < lev_diag ) THEN
1885             lev_prog = lev_diag
1886          ELSE
1887             lev_prog = diaglev(jg)
1888          ENDIF
1889          intfactw(jsl,jg) = MAX(MIN(lev_diag,lev_prog)-MAX(prev_diag, prev_prog), zero)/(lev_diag-prev_diag)
1890          prev_prog = lev_prog
1891       ENDDO
1892       prev_diag = lev_diag
1893    ENDDO
1894
1895    !!calculate the indices where the thermodynamic levels meet the base of the
1896    !!moisture levels and zdeep
1897    jsl = 1
1898    DO WHILE (jsl .LT. ngrnd .AND. (.not. at_zdeep ) )
1899       IF (zz(jsl) .GE. z_deepsoil) THEN
1900          at_zdeep = .TRUE.
1901          proglevel_zdeep = jsl
1902       END IF
1903       jsl = jsl + 1
1904    END DO
1905    !
1906    jsl = 1
1907    DO WHILE (jsl .LT. ngrnd .AND. ( .not. at_bottomdiaglev ) )
1908       IF (zz(jsl) .GE. diaglev(nslm)) THEN
1909          at_bottomdiaglev = .TRUE.
1910          proglevel_bottomdiaglev = jsl
1911       END IF
1912       jsl = jsl + 1
1913    END DO
1914
1915    IF ( check ) THEN
1916       WRITE(*,*) 'cdk: proglevel_zdeep = ', proglevel_zdeep
1917       WRITE(*,*) 'cdk: proglevel_bottomdiaglev = ', proglevel_bottomdiaglev
1918    END IF
1919
1920    IF (.NOT. satsoil ) THEN
1921       !++cdk separate permafrost and non-permafrost
1922       ! only to z_deep for the permafrost
1923       DO jsl = 1, proglevel_zdeep
1924             shum_ngrnd_perma(:,jsl,:) = 0.0
1925       ENDDO
1926
1927
1928       DO jv = 1, nvm
1929          DO ji = 1, kjpindex
1930                DO jg = 1, nslm
1931                   DO jsl = 1, proglevel_zdeep
1932                      shum_ngrnd_perma(ji,jsl,jv) = shum_ngrnd_perma(ji,jsl,jv) + shumdiag_perma(ji,jg)*intfactw(jsl,jg)
1933                   END DO
1934                ENDDO
1935          END DO
1936       END DO
1937
1938
1939       ! now update the deep permafrost soil moisture separately
1940       CALL update_deep_soil_moisture(kjpindex, shumdiag_perma,proglevel_bottomdiaglev, proglevel_zdeep, &
1941            thawed_humidity)
1942
1943    ELSE
1944       shum_ngrnd_perma(:,:,:) = 1.
1945    ENDIF
1946
1947  END SUBROUTINE thermosoilc_humlev
1948
1949!!
1950!================================================================================================================================
1951!! SUBROUTINE   : update_deep_soil_moisture
1952!!
1953!>\BRIEF        updating deep soil moisture
1954!!   
1955!! DESCRIPTION  :   
1956!!
1957!! RECENT CHANGE(S) : None
1958!!
1959!! MAIN OUTPUT VARIABLE(S): 
1960!!
1961!! REFERENCE(S) : None
1962!!
1963!! FLOWCHART    : None 
1964!! \n 
1965!_
1966!================================================================================================================================
1967    SUBROUTINE update_deep_soil_moisture (kjpindex, shumdiag_perma, proglevel_bottomdiaglev, &
1968         proglevel_zdeep, thawed_humidity)
1969
1970    !! 0. Variables and parameter declaration
1971
1972    !! 0.1 Input variables
1973    INTEGER(i_std), INTENT(in)                            :: kjpindex            !! Domain size
1974    REAL(r_std),DIMENSION (kjpindex,nslm), INTENT (in)    :: shumdiag_perma      !! Diagnostoc profile
1975    INTEGER(i_std), INTENT (in)                           :: proglevel_bottomdiaglev !! for keeping track of where the base of the diagnostic level meets the prognostic level
1976    INTEGER(i_std), INTENT (in)                           :: proglevel_zdeep     !! for keeping track of where the prognostic levels meet zdeep
1977    REAL(r_std), DIMENSION(kjpindex),   INTENT (in)       :: thawed_humidity     !! specified humidity of thawed soil
1978
1979    !! 0.2 Modified variables
1980
1981    !! 0.3 Output variables
1982
1983    !! 0.4 Local variables
1984    INTEGER(i_std) :: ji, jd, jv
1985
1986    IF (printlev>=3) WRITE (numout,*) 'entering update_deep_soil_misture'
1987
1988
1989    DO ji = 1, kjpindex
1990       DO jv = 1,nvm
1991             DO jd = proglevel_zdeep, ngrnd
1992                IF ( (ptn(ji,jd,jv) .GT. (ZeroCelsius+fr_dT/2.)) ) THEN
1993                   shum_ngrnd_perma(ji,jd,jv) = thawed_humidity(ji)
1994                END IF
1995             END DO
1996       END DO
1997    END DO
1998
1999    DO jd =  proglevel_bottomdiaglev, proglevel_zdeep-1
2000       DO ji = 1, kjpindex
2001          DO jv = 1,nvm
2002                CALL lint (diaglev(nslm), shumdiag_perma(ji,nslm), z_deepsoil,shum_ngrnd_perma(ji,proglevel_zdeep,jv), &
2003                     zz(jd), shum_ngrnd_perma(ji,jd,jv), 1)
2004          END DO
2005       END DO
2006    END DO
2007
2008    IF (printlev>=3) WRITE (numout,*) ' update_deep_soil_misture done'
2009   
2010    END SUBROUTINE update_deep_soil_moisture
2011
2012!!
2013!================================================================================================================================
2014!! SUBROUTINE   : lint
2015!!
2016!>\BRIEF        Simple interpolation
2017!!
2018!! DESCRIPTION  :     ! Interpolation linéaire entre des points (x1,y1) et(x2,y2))
2019!! Ces commentaires en mauvais français permettent savoir qui a
2020!! ecrit la subroutine :-) - DK           
2021!!
2022!! RECENT CHANGE(S) : None
2023!!
2024!! MAIN OUTPUT VARIABLE(S): 
2025!!
2026!! REFERENCE(S) : None
2027!!
2028!! FLOWCHART    : None 
2029!! \n 
2030!_
2031!================================================================================================================================
2032  SUBROUTINE lint(x1,y1,x2,y2,x,y,NY)
2033    !! 0. Variables and parameter declaration
2034
2035    !! 0.1 Input variables   
2036
2037    REAL, INTENT(in)                   ::  x1,x2,y1,y2,x
2038    INTEGER, INTENT(in)                ::  NY
2039
2040    !! 0.2 Modified variables
2041    REAL, DIMENSION(NY), INTENT(inout) :: y
2042
2043    !! 0.3 Local variables
2044    REAL, PARAMETER                    :: EPSILON = 1.E-10
2045   
2046    IF (ABS(x1 - x2) .LT. EPSILON) THEN
2047       PRINT *, 'ERROR IN lint(x1,y1,x2,y2,y,NY) : x1==x2!'
2048       PRINT *, 'x1=',x1,'  x2=',x2
2049       PRINT *, 'y1=',y1,'  y2=',y2
2050       STOP
2051    END IF
2052   
2053    IF (x1 .LE. x .AND. x .LE. x2) THEN
2054       y = x*(y2-y1)/(x2-x1) + (y1*x2 - y2*x1)/(x2-x1)
2055       !      ELSE
2056       !        y = UNDEF
2057    END IF
2058   
2059  END SUBROUTINE lint
2060
2061
2062!!
2063!================================================================================================================================
2064!! SUBROUTINE   : thermosoilc_energy
2065!!
2066!>\BRIEF         Energy check-up.
2067!!
2068!! DESCRIPTION  : I didn\'t comment this routine since at do not understand its
2069!! ask initial designers (Jan ? Nathalie ?).
2070!!
2071!! RECENT CHANGE(S) : None
2072!!
2073!! MAIN OUTPUT VARIABLE(S) : ??
2074!!
2075!! REFERENCE(S) : None
2076!!
2077!! FLOWCHART    : None
2078!! \n
2079!_
2080!===============================================================================================================
2081  SUBROUTINE thermosoilc_energy(kjpindex, temp_sol_new, soilcap, veget_max)
2082    !! 0. Variables and parameter declaration
2083
2084    !! 0.1 Input variables
2085    INTEGER(i_std), INTENT(in)                           :: kjpindex    !! Domain size
2086    REAL(r_std),DIMENSION (kjpindex), INTENT (in)        :: temp_sol_new!! New soil temperature
2087    REAL(r_std),DIMENSION (kjpindex), INTENT (in)        :: soilcap     !! Soil capacity
2088    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT (in)   :: veget_max   !! Fraction of vegetation type
2089
2090    !! 0.2 Local variables
2091    INTEGER(i_std)  :: ji, jg
2092
2093    IF (printlev>=3) WRITE (numout,*) 'entering thermosoilc_energy'
2094    !
2095
2096     DO ji = 1, kjpindex
2097      surfheat_incr(ji) = zero
2098      coldcont_incr(ji) = zero
2099     ENDDO
2100    !
2101    !  Sum up the energy content of all layers in the soil.
2102    !
2103    DO ji = 1, kjpindex
2104    !
2105       IF (SUM(pcapa_en(ji,1,:)*veget_max(ji,:)) .LE. sn_capa) THEN
2106          !
2107          ! Verify the energy conservation in the surface layer
2108          !
2109          coldcont_incr(ji) = soilcap(ji) * (temp_sol_new(ji) - temp_sol_beg(ji))
2110          surfheat_incr(ji) = zero
2111       ELSE
2112          !
2113          ! Verify the energy conservation in the surface layer
2114          !
2115          surfheat_incr(ji) = soilcap(ji) * (temp_sol_new(ji) - temp_sol_beg(ji))
2116          coldcont_incr(ji) = zero
2117       ENDIF
2118    ENDDO
2119   
2120    ptn_beg(:,:,:)      = ptn(:,:,:)
2121    temp_sol_beg(:)   = temp_sol_new(:)
2122
2123  END SUBROUTINE thermosoilc_energy
2124
2125
2126!!
2127!================================================================================================================================
2128!! SUBROUTINE   : thermosoilc_readjust
2129!!
2130!>\BRIEF         
2131!!
2132!! DESCRIPTION  : Energy conservation : Correction to make sure that the same latent heat is released and 
2133!!                consumed during freezing and thawing   
2134!!
2135!! RECENT CHANGE(S) : None
2136!! 
2137!! MAIN OUTPUT VARIABLE(S): ptn (soil temperature profile on the thermal axis), 
2138!!                           
2139!! REFERENCE(S) :
2140!! FLOWCHART    : None 
2141!! \n 
2142!_
2143  SUBROUTINE thermosoilc_readjust(kjpindex, ptn)
2144
2145    !! 0. Variables and parameter declaration
2146
2147    !! 0.1 Input variables
2148 
2149    INTEGER(i_std), INTENT(in)                                :: kjpindex
2150
2151    !! 0.2 Modified variables
2152
2153    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(inout)   :: ptn
2154
2155    !! 0.3 Local variables
2156
2157    INTEGER(i_std)  :: ji, jg, jv
2158    REAL(r_std) :: ptn_tmp
2159    DO jv = 1,nvm
2160      DO jg=1, ngrnd
2161          DO ji=1, kjpindex
2162               ! All soil latent energy is put into e_soil_lat(ji, 1)
2163               ! because the variable soil layers make it difficult to keep track of all
2164               ! layers in this version
2165               ! NOTE : pcapa has unit J/K/m3 and pcappa_supp has J/K
2166               e_soil_lat(ji, jv)=e_soil_lat(ji, jv)+pcappa_supp(ji,jg,jv)*(ptn(ji,jg,jv)-ptn_beg(ji,jg,jv))
2167          ENDDO ! ji=1, kjpindex
2168      ENDDO ! jg=1, ngrnd
2169    ENDDO ! jv = 1,nvm
2170
2171    DO jv = 1,nvm
2172      DO ji=1, kjpindex
2173          IF (e_soil_lat(ji,jv).GT.min_sechiba.AND.MINVAL(ptn(ji,:,jv)).GT.ZeroCelsius+fr_dT/2.) THEN
2174                ! The soil is thawed: we spread the excess of energy over the uppermost 6 levels e.g. 2.7m
2175                ! Here we increase the temperatures
2176                DO jg=1,6
2177                  ptn_tmp=ptn(ji,jg,jv)
2178
2179                  ptn(ji,jg,jv)=ptn(ji,jg,jv)+MIN(e_soil_lat(ji,jv)/pcapa(ji,jg,jv)/zz_coef(6), 0.5)
2180                  e_soil_lat(ji,jv)=e_soil_lat(ji,jv)-(ptn(ji,jg,jv)-ptn_tmp)*pcapa(ji,jg,jv)*dz2(jg)
2181                ENDDO ! jg=1,6
2182          ELSE IF (e_soil_lat(ji,jv).LT.-min_sechiba.AND.MINVAL(ptn(ji,:,jv)).GT.ZeroCelsius+fr_dT/2.) THEN
2183                ! The soil is thawed
2184                ! Here we decrease the temperatures
2185                DO jg=1,6
2186                  ptn_tmp=ptn(ji,jg,jv)
2187                  ptn(ji,jg,jv)=MAX(ZeroCelsius+fr_dT/2., ptn_tmp+e_soil_lat(ji,jv)/pcapa(ji,jg,jv)/zz_coef(6))
2188                  e_soil_lat(ji,jv)=e_soil_lat(ji,jv)+(ptn_tmp-ptn(ji,jg,jv))*pcapa(ji,jg,jv)*dz2(jg)
2189                ENDDO ! jg=1,6
2190          ENDIF
2191      ENDDO ! ji=1, kjpindex
2192    ENDDO ! jv = 1,nvm
2193
2194  END SUBROUTINE thermosoilc_readjust
2195
2196!!
2197!================================================================================================================================
2198!! SUBROUTINE   : thermosoilc_wlupdate
2199!!
2200!>\BRIEF          Updates the long-term soil humidity     
2201!!
2202!! DESCRIPTION  : 
2203!!
2204!! RECENT CHANGE(S) : None
2205!! 
2206!! MAIN OUTPUT VARIABLE(S): 
2207!!                           
2208!! REFERENCE(S) :
2209!!
2210!! FLOWCHART    : None 
2211!! \n 
2212!_
2213!================================================================================================================================
2214  SUBROUTINE thermosoilc_wlupdate( kjpindex, ptn, hsd, hsdlong )
2215    !! 0. Variables and parameter declaration
2216
2217    !! 0.1 Input variables
2218    INTEGER(i_std),INTENT(in)                           :: kjpindex
2219    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(in)        :: ptn
2220    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(in)        :: hsd
2221
2222    !! 0.2 Modified variables
2223    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(inout)     :: hsdlong
2224
2225    !! 0.3 Local variables
2226    INTEGER(i_std) ::  il
2227    REAL(r_std), PARAMETER               :: tau_freezesoil = 30.*86400. 
2228
2229    !
2230    DO il = 1, ndeep
2231       WHERE ( ( ptn(:,il,:) .GT. ZeroCelsius + fr_dT/2. ) )
2232          hsdlong(:,il,:) = ( hsd(:,il,:) * dt_sechiba + hsdlong(:,il,:) *(tau_freezesoil-dt_sechiba) ) / tau_freezesoil
2233       ENDWHERE
2234    END DO
2235
2236    IF (printlev>=3) WRITE (numout,*) 'entering thermosoilc_wlupdate'
2237
2238   END SUBROUTINE thermosoilc_wlupdate
2239   
2240
2241!!
2242!================================================================================================================================
2243!! SUBROUTINE   : thermosoilc_getdiff
2244!!
2245!>\BRIEF          Computes soil and snow heat capacity and conductivity     
2246!!
2247!! DESCRIPTION  : Computation of the soil and snow thermal properties; snow properties
2248!are also accounted for
2249!!
2250!! RECENT CHANGE(S) : None
2251!! 
2252!! MAIN OUTPUT VARIABLE(S):
2253!!                           
2254!! REFERENCE(S) :
2255!!
2256!! FLOWCHART    : None 
2257!! \n 
2258!_
2259!================================================================================================================================         
2260  SUBROUTINE thermosoilc_getdiff( kjpindex, ptn, shum_ngrnd_permalong, profil_froz, &
2261                              organic_layer_thick, soilc_total, snowrho, snowtemp, pb )
2262    !! 0. Variables and parameter declaration
2263
2264    !! 0.1 Input variables
2265       
2266    INTEGER(i_std), INTENT(in)                               :: kjpindex
2267    REAL(r_std), DIMENSION(kjpindex,ngrnd,nvm),INTENT(in)    :: shum_ngrnd_permalong
2268    REAL(r_std), DIMENSION(kjpindex), INTENT (in)            :: organic_layer_thick    !! how deep is the organic soil?
2269    REAL(r_std), DIMENSION(kjpindex,ndeep,nvm), INTENT (in)  :: soilc_total            !! total soil carbon for use in thermal calcs
2270    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(in)     :: ptn                    !! Soil temperature profile
2271    REAL(r_std),DIMENSION(kjpindex,nsnow),INTENT(in)         :: snowrho                !! Snow density
2272    REAL(r_std),DIMENSION(kjpindex,nsnow),INTENT(in)         :: snowtemp               !! Snow temperature
2273    REAL(r_std),DIMENSION(kjpindex),INTENT(in)               :: pb                     !! Surface pressure
2274
2275    !! 0.2 Output variables
2276
2277    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(out)    :: profil_froz
2278
2279    !! 0.3 Modified variables
2280
2281
2282    !! 0.4 Local variables
2283   
2284    REAL(r_std)                                              :: x                      !! Unfrozen fraction of the soil
2285    REAL(r_std)                                              :: p
2286    REAL(r_std), DIMENSION(kjpindex,ngrnd,nvm)               :: zx1, zx2   
2287    REAL(r_std)                                              :: cap_iw                 !! Heat capacity of ice/water mixture
2288    REAL(r_std)                                              :: csat                   !! Thermal conductivity for saturated soil
2289    REAL(r_std)                                              :: so_capa_dry_net
2290    REAL(r_std), DIMENSION(kjpindex,ngrnd,nvm)               :: poros_net
2291    REAL(r_std)                                              :: cond_solid_net
2292    REAL(r_std)                                              :: so_cond_dry_net
2293    INTEGER(i_std)                                           :: ji,jg,jv
2294
2295     ! Organic and anorgaic layer fraction
2296     !
2297     ! Default: organic layer not taken into account
2298     zx1(:,:,:) = 0.
2299     !
2300     IF ( use_toporganiclayer_tempdiff ) THEN
2301       !
2302       ! level 1
2303       !
2304       DO jv = 1,nvm
2305         DO ji = 1,kjpindex
2306           IF ( organic_layer_thick(ji) .GT. zz_coef(1) ) THEN
2307             !! the 1st level is in the organic => the 1st layer is entirely organic
2308             zx1(ji,1,jv) = 1. !!zx1 being the fraction of each level that is organic, zx2 is the remainder
2309           ELSE IF ( organic_layer_thick(ji) .GT. zero ) THEN
2310             !! the 1st level is beyond the organic and the organic is present
2311             zx1(ji,1,jv) = organic_layer_thick(ji) / zz_coef(1)
2312           ELSE
2313             ! there is no organic at all
2314             zx1(ji,1,jv) = 0.
2315           ENDIF
2316         ENDDO
2317       ENDDO
2318       !
2319       ! other levels
2320       !
2321       DO jg = 2, ngrnd !- 2
2322         DO ji = 1,kjpindex
2323           IF ( organic_layer_thick(ji) .GT. zz_coef(jg) ) THEN
2324             ! the current level is in the organic => the current layer is
2325             ! entirely organic
2326             zx1(ji,jg,1) = 1.
2327           ELSE IF ( organic_layer_thick(ji) .GT. zz_coef(jg-1) ) THEN
2328             ! the current layer is partially organic
2329             zx1(ji,jg,1) = (organic_layer_thick(ji) - zz_coef(jg-1)) / (zz_coef(jg) - zz_coef(jg-1))
2330           ELSE
2331             ! both levels are out of organic => the current layer is entirely
2332             ! mineral soil       
2333             zx1(ji,jg,1) = 0.
2334           ENDIF
2335         ENDDO
2336       ENDDO
2337       DO jv = 2, nvm
2338         zx1(ji,jg,jv) = zx1(ji,jg,1)
2339       ENDDO
2340       ! IF ( use_toporganiclayer_tempdiff ) THE
2341     ELSEIF ( use_soilc_tempdiff ) THEN
2342       !
2343       DO jv = 1,nvm
2344         DO jg = 1, ngrnd
2345           DO ji = 1,kjpindex
2346             zx1(ji,jg,jv) = MIN((soilc_total(ji,jg,jv)/soilc_max),1.)   !after lawrence and slater
2347           ENDDO
2348         ENDDO
2349       ENDDO
2350       !
2351     ENDIF ! ( use_soilc_tempdiff ) THEN
2352     !
2353     zx2(:,:,:) = 1.-zx1(:,:,:)
2354
2355     DO jv = 1,nvm
2356       DO jg = 1, ngrnd
2357         DO ji = 1,kjpindex
2358             !
2359             ! 1. Calculate dry heat capacity and conductivity, taking
2360             ! into account the organic and mineral fractions in the layer
2361             !
2362             so_capa_dry_net = zx1(ji,jg,jv) * so_capa_dry_org + zx2(ji,jg,jv) * so_capa_dry
2363             cond_solid_net  = un / ( zx1(ji,jg,jv) / cond_solid_org  + zx2(ji,jg,jv) / cond_solid  )
2364             poros_net(ji,jg,jv) = zx1(ji,jg,jv) * poros_org + zx2(ji,jg,jv) * poros
2365             !
2366             so_cond_dry_net = un / ( zx1(ji,jg,jv) / cond_dry_org + zx2(ji,jg,jv) / so_cond_dry )
2367             !
2368             ! 2. Calculate heat capacity with allowance for permafrost
2369
2370             IF (ok_freeze_thermix) THEN
2371                ! 2.1. soil heat capacity depending on temperature and humidity
2372                IF (ptn(ji,jg,jv) .LT. ZeroCelsius-fr_dT/2.) THEN
2373                  ! frozen soil
2374                  !! this is from Koven's version: pcapa(ji,jg,jv) = so_capa_dry_net + shum_ngrnd_permalong(ji,jg,jv)*poros_net(ji,jg,jv)*capa_ice*rho_ice
2375                  pcapa(ji,jg,jv) = so_capa_dry_net + shum_ngrnd_permalong(ji,jg,jv)*(so_capa_ice - so_capa_dry_net)!Isa : old version, proved to be correct
2376                  pcappa_supp(ji,jg, jv)= 0.
2377                  profil_froz(ji,jg,jv) = 1.
2378                ELSEIF (ptn(ji,jg,jv) .GT. ZeroCelsius+fr_dT/2.) THEN
2379                  ! unfrozen soil         
2380                  !! this is from Koven's version: pcapa(ji,jg,jv) =  so_capa_dry_net + shum_ngrnd_permalong(ji,jg,jv)*poros_net(ji,jg,jv)*capa_water*rho_water
2381                  pcapa(ji,jg,jv) = so_capa_dry_net + shum_ngrnd_permalong(ji,jg,jv)*(so_capa_wet - so_capa_dry_net) 
2382                  pcappa_supp(ji,jg,jv)= 0.
2383                  profil_froz(ji,jg,jv) = 0.
2384                ELSE
2385   
2386                ! x is the unfrozen fraction of soil water             
2387                x = (ptn(ji,jg,jv)-(ZeroCelsius-fr_dT/2.)) / fr_dT
2388                profil_froz(ji,jg,jv) = (1. - x)
2389                ! net heat capacity of the ice/water mixture
2390                cap_iw = x * so_capa_wet + (1.-x) * so_capa_ice
2391                ! cap_iw = x * 4.E6 + (1.-x) * 2.E6 !DKtest - compar. w/ theor. sol.
2392                pcapa(ji,jg,jv) = so_capa_dry_net + shum_ngrnd_permalong(ji,jg,jv)*(cap_iw-so_capa_dry_net) + &
2393                                  shum_ngrnd_permalong(ji,jg,jv)*poros_net(ji,jg,jv)*lhf*rho_water/fr_dT
2394                pcappa_supp(ji,jg,jv)= shum_ngrnd_permalong(ji,jg,jv)*poros_net(ji,jg,jv)*lhf*rho_water/fr_dT*dz2(jg)
2395
2396                ENDIF
2397             ELSE !++cdk this is physically wrong and only to be used to test the influence of latent heat
2398                pcapa(ji,jg,jv) = so_capa_dry_net + shum_ngrnd_perma(ji,jg,jv)*(so_capa_wet - so_capa_dry_net)
2399                profil_froz(ji,jg,jv) = 0.
2400             ENDIF
2401             !
2402             ! 3. Calculate the heat conductivity with allowance for permafrost (Farouki,
2403             ! 1981, Cold Reg. Sci. Technol.)
2404             !
2405             ! 3.1. unfrozen fraction
2406             p = poros_net(ji,jg,jv)
2407             x = (ptn(ji,jg,jv)-(ZeroCelsius-fr_dT/2.)) / fr_dT * p
2408             x = MIN( p, MAX( 0., x ) )
2409             !++cdk: DKorig: x = (ptn(ji,jg)-(ZeroCelsius-fr_dT/2.)) / fr_dT * poros
2410             !++cdk: DKorig: x = MIN( poros, MAX( 0., x ) )
2411
2412             ! 3.2. saturated conductivity
2413             csat = cond_solid_net**(1.-p) * cond_ice**(p-x) * cond_water**x
2414             !++cdk: DKorig: csat = cond_solid**(1.-poros) * cond_ice**(poros-x)
2415             !* cond_water**x
2416
2417             ! 3.3. unsaturated conductivity
2418             pkappa(ji,jg,jv) = (csat - so_cond_dry_net)*shum_ngrnd_permalong(ji,jg,jv) + so_cond_dry_net
2419             !++cdk: DKorig: pkappa(ji,jg) = (csat - so_cond_dry)*humdiag(ji,jg)
2420             !+ so_cond_dry
2421             !
2422          ENDDO
2423         ENDDO
2424        ENDDO
2425
2426        pcapa_en(:,:,:) = pcapa(:,:,:)
2427
2428        ! 4. Calculate snow heat capacity and conductivity
2429        DO ji = 1,kjpindex 
2430            pcapa_snow(ji,:) = snowrho(ji,:) * xci 
2431            pkappa_snow(ji,:) = (ZSNOWTHRMCOND1 + ZSNOWTHRMCOND2*snowrho(ji,:)*snowrho(ji,:)) +      &     
2432                    MAX(0.0,(ZSNOWTHRMCOND_AVAP+(ZSNOWTHRMCOND_BVAP/(snowtemp(ji,:)+ & 
2433            ZSNOWTHRMCOND_CVAP)))*(XP00/(pb(ji)*100.))) 
2434        END DO
2435
2436   END SUBROUTINE thermosoilc_getdiff
2437
2438
2439!!
2440!================================================================================================================================
2441!! SUBROUTINE   : thermosoilc_getdiff_thinsnow
2442!!
2443!>\BRIEF          Computes soil heat capacity and conductivity     
2444!!
2445!! DESCRIPTION  : Computation of the soil thermal properties; snow properties are also accounted for
2446!!
2447!! RECENT CHANGE(S) : None
2448!! 
2449!! MAIN OUTPUT VARIABLE(S):
2450!!                           
2451!! REFERENCE(S) :
2452!!
2453!! FLOWCHART    : None 
2454!! \n 
2455!_
2456!================================================================================================================================
2457     SUBROUTINE thermosoilc_getdiff_thinsnow (kjpindex, shum_ngrnd_permalong, snowdz, profil_froz)
2458
2459    !! 0. Variables and parameter declaration
2460
2461    !! 0.1 Input variables
2462    INTEGER(i_std),INTENT(in)                                   :: kjpindex
2463    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(in)        :: shum_ngrnd_permalong
2464    REAL(r_std),DIMENSION(kjpindex,nsnow),INTENT (in)           :: snowdz
2465
2466    !! 0.2 Output variables
2467    REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(out)    :: profil_froz
2468
2469    !! 0.3 Local variables
2470    REAL(r_std)                                         :: x
2471    REAL(r_std), DIMENSION(kjpindex)                    :: snow_h
2472    REAL(r_std), DIMENSION(kjpindex,ngrnd)              :: zx1, zx2
2473    INTEGER(i_std)                                      :: ji,jg,jv
2474
2475
2476    DO ji = 1,kjpindex
2477
2478      ! 1. Determine the fractions of snow and soil
2479
2480      snow_h(ji) = SUM(snowdz(ji,:))
2481
2482      IF (snow_h(ji) .LE. 0.01) THEN
2483
2484         !
2485         !  1.1. The first level
2486         !
2487         IF ( snow_h(ji) .GT. zz_coef(1) ) THEN
2488
2489             ! the 1st level is in the snow => the 1st layer is entirely snow
2490             zx1(ji,1) = 1.
2491             zx2(ji,1) = 0.
2492               
2493         ELSE IF ( snow_h(ji) .GT. zero ) THEN
2494
2495             ! the 1st level is beyond the snow and the snow is present
2496             zx1(ji,1) = snow_h(ji) / zz_coef(1)
2497             zx2(ji,1) = ( zz_coef(1) - snow_h(ji)) / zz_coef(1)       
2498         ENDIF
2499
2500         !
2501         DO jv = 1,nvm
2502          DO jg = 1, 1
2503            !
2504            ! 2. Calculate frozen profile for hydrolc.f90
2505        !
2506            IF (ptn(ji,jg,jv) .LT. ZeroCelsius-fr_dT/2.) THEN
2507                profil_froz(ji,jg,jv) = 1.
2508
2509                 ELSEIF (ptn(ji,jg,jv) .GT. ZeroCelsius+fr_dT/2.) THEN
2510                profil_froz(ji,jg,jv) = 0.
2511                 ELSE
2512
2513                   ! x is the unfrozen fraction of soil water             
2514                   x = (ptn(ji,jg,jv)-(ZeroCelsius-fr_dT/2.)) / fr_dT   
2515              profil_froz(ji,jg,jv) = (1. - x)
2516
2517            ENDIF
2518
2519            ! 3. heat capacity calculation
2520        !
2521            ! 3.0 old heat capacity calculation
2522            pcapa(ji,jg,jv) = so_capa_dry + shum_ngrnd_permalong(ji,jg,jv)*(so_capa_wet - so_capa_dry)
2523
2524        ! 3.1. Still some improvement from the old_version : Take into account the snow and soil fractions in the layer
2525
2526            pcapa(ji,jg,jv) = zx1(ji,jg) * sn_capa + zx2(ji,jg) * pcapa(ji,jg,jv)
2527
2528        ! 3.2. Calculate the heat capacity for energy conservation check
2529        IF ( zx1(ji,jg).GT.0. ) THEN
2530               pcapa_en(ji,jg,jv) = sn_capa
2531        ELSE
2532               pcapa_en(ji,jg,jv) = pcapa(ji,jg,jv)
2533        ENDIF
2534            !
2535            !4. heat conductivity calculation
2536        !
2537            !4.0 old heat conductivity calculation
2538            pkappa(ji,jg,jv) = so_cond_dry + shum_ngrnd_permalong(ji,jg,jv)*(so_cond_wet - so_cond_dry)
2539
2540            !4.0 Still some improvement from the old_version : Take into account the snow and soil fractions in the layer
2541
2542            pkappa(ji,jg,jv) = un / ( zx1(ji,jg) / sn_cond + zx2(ji,jg) / pkappa(ji,jg,jv) )
2543
2544         END DO
2545        END DO
2546      ENDIF
2547    ENDDO
2548
2549
2550   END SUBROUTINE thermosoilc_getdiff_thinsnow
2551
2552!! ================================================================================================================================
2553!! SUBROUTINE   : thermosoilc_getdiff_old_thermix_with_snow
2554!!
2555!>\BRIEF          Computes soil heat capacity and conductivity   
2556!!
2557!! DESCRIPTION  : Computes soil heat capacity and conductivity
2558!!                Special case with old snow without soil freezing
2559!!
2560!! RECENT CHANGE(S) : None
2561!!
2562!! MAIN OUTPUT VARIABLE(S):
2563!!                         
2564!! REFERENCE(S) :
2565!!
2566!! FLOWCHART    : None
2567!! \n
2568!_ ================================================================================================================================
2569   SUBROUTINE thermosoilc_getdiff_old_thermix_with_snow( kjpindex, snow)
2570
2571   !! 0. Variables and parameter declaration
2572
2573    !! 0.1 Input variables
2574    INTEGER(i_std), INTENT(in) :: kjpindex
2575    REAL(r_std),DIMENSION(kjpindex),INTENT (in) :: snow
2576
2577    !! 0.2 Local variables
2578    INTEGER                                     :: ji,jg
2579    REAL(r_std)                                 :: snow_h       !! snow_h is the snow height @tex ($m$) @endtex
2580    REAL(r_std)                                 :: zx1, zx2     !! zx1 and zx2 are the layer fraction consisting in snow and soil respectively.
2581
2582     
2583    ! Computation of the soil thermal properties; snow properties are also accounted for
2584    DO ji = 1,kjpindex
2585      snow_h = snow(ji) / sn_dens
2586
2587      ! First layer
2588      IF ( snow_h .GT. zz_coef(1) ) THEN
2589          pcapa(ji,1,:) = sn_capa
2590          pcapa_en(ji,1,:) = sn_capa
2591          pkappa(ji,1,:) = sn_cond
2592      ELSE IF ( snow_h .GT. zero ) THEN
2593          pcapa_en(ji,1,:) = sn_capa
2594          zx1 = snow_h / zz_coef(1)
2595          zx2 = ( zz_coef(1) - snow_h) / zz_coef(1)
2596          pcapa(ji,1,:) = zx1 * sn_capa + zx2 * so_capa_wet
2597          pkappa(ji,1,:) = un / ( zx1 / sn_cond + zx2 / so_cond_wet )
2598      ELSE
2599          pcapa(ji,1,:) = so_capa_dry + shum_ngrnd_perma(ji,1,:)*(so_capa_wet - so_capa_dry)
2600          pkappa(ji,1,:) = so_cond_dry + shum_ngrnd_perma(ji,1,:)*(so_cond_wet - so_cond_dry)
2601          pcapa_en(ji,1,:) = so_capa_dry + shum_ngrnd_perma(ji,1,:)*(so_capa_wet - so_capa_dry)
2602      ENDIF
2603
2604      ! Mid layers
2605      DO jg = 2, ngrnd - 2
2606        IF ( snow_h .GT. zz_coef(jg) ) THEN
2607            pcapa(ji,jg,:) = sn_capa
2608            pkappa(ji,jg,:) = sn_cond
2609            pcapa_en(ji,jg,:) = sn_capa
2610        ELSE IF ( snow_h .GT. zz_coef(jg-1) ) THEN
2611            zx1 = (snow_h - zz_coef(jg-1)) / (zz_coef(jg) - zz_coef(jg-1))
2612            zx2 = ( zz_coef(jg) - snow_h) / (zz_coef(jg) - zz_coef(jg-1))
2613            pcapa(ji,jg,:) = zx1 * sn_capa + zx2 * so_capa_wet
2614            pkappa(ji,jg,:) = un / ( zx1 / sn_cond + zx2 / so_cond_wet )
2615            pcapa_en(ji,jg,:) = sn_capa
2616        ELSE
2617            pcapa(ji,jg,:) = so_capa_dry + shum_ngrnd_perma(ji,jg,:)*(so_capa_wet - so_capa_dry)
2618            pkappa(ji,jg,:) = so_cond_dry + shum_ngrnd_perma(ji,jg,:)*(so_cond_wet - so_cond_dry)
2619            pcapa_en(ji,jg,:) = so_capa_dry + shum_ngrnd_perma(ji,jg,:)*(so_capa_wet - so_capa_dry)
2620        ENDIF
2621      ENDDO
2622
2623      ! Last two layers: These layers can not be filled with snow
2624      DO jg = ngrnd - 1, ngrnd
2625         pcapa(ji,jg,:) = so_capa_dry
2626         pkappa(ji,jg,:) = so_cond_dry
2627         pcapa_en(ji,jg,:) = so_capa_dry
2628      END DO
2629     
2630    ENDDO ! DO ji = 1,kjpindex
2631
2632
2633    END SUBROUTINE thermosoilc_getdiff_old_thermix_with_snow
2634
2635!!
2636!================================================================================================================================
2637!! SUBROUTINE   : add_heat_Zimov
2638!!
2639!>\BRIEF          heat
2640!!
2641!! DESCRIPTION  : 
2642!!
2643!! RECENT CHANGE(S) : None
2644!!
2645!! MAIN OUTPUT VARIABLE(S):
2646!!
2647!! REFERENCE(S) :
2648!!
2649!! FLOWCHART    : None
2650!! \n
2651!_
2652!================================================================================================================================
2653   SUBROUTINE add_heat_Zimov(kjpindex, veget_max_bg, ptn, heat_Zimov)
2654    !! 0. Variables and parameter declaration
2655
2656    !! 0.1 Input variables
2657    INTEGER(i_std),INTENT(in)                                 :: kjpindex
2658    REAL(r_std), DIMENSION (kjpindex,nvm), INTENT(in)         :: veget_max_bg !! Fraction of vegetation type
2659
2660    REAL(r_std), DIMENSION(kjpindex,ndeep,nvm), INTENT (in)   :: heat_Zimov   !! heating associated with decomposition
2661
2662    !! 0.2 Modified variables
2663     REAL(r_std),DIMENSION(kjpindex,ngrnd,nvm),INTENT(inout)  :: ptn
2664
2665    !! 0.3 Local variables
2666    INTEGER(r_std) :: ji, jg, jv
2667
2668    IF (printlev>=3) WRITE (numout,*) 'entering add_heat_Zimov'
2669
2670    DO ji = 1, kjpindex
2671       DO jv = 1,nvm
2672             DO jg = 1, ngrnd
2673                ptn(ji,jg,jv) = ptn(ji,jg,jv) + heat_zimov(ji,jg,jv) * dt_sechiba / ( pcapa(ji,jg,jv) * dz2(jg) )
2674             END DO
2675       END DO
2676    END DO
2677
2678    ! ptn_pftmean needs to be updated to ensure consistency
2679    ptn_pftmean(:,:) = zero
2680    DO jv=1,nvm
2681       DO jg = 1, ngrnd
2682          ptn_pftmean(:,jg) = ptn_pftmean(:,jg) + ptn(:,jg,jv) * veget_max_bg(:,jv)
2683       ENDDO ! jg = 1, ngrnd
2684    ENDDO ! m=1,nvm
2685
2686    IF (printlev>=3) WRITE (numout,*) ' add_heat_Zimov done'
2687
2688  END SUBROUTINE add_heat_Zimov
2689
2690
2691!! ================================================================================================================================
2692!! SUBROUTINE   : thermosoilc_read_reftempfile
2693!!
2694!>\BRIEF           
2695!!
2696!! DESCRIPTION  : Read file with longterm temperature
2697!!                 
2698!!
2699!! RECENT CHANGE(S) : None
2700!! 
2701!! MAIN OUTPUT VARIABLE(S): reftemp : Reference temerature
2702!!                           
2703!! REFERENCE(S) :
2704!!
2705!! FLOWCHART    : None 
2706!! \n 
2707!_
2708!================================================================================================================================
2709 SUBROUTINE thermosoilc_read_reftempfile(kjpindex,lalo,reftemp)
2710   
2711    USE interpweight
2712
2713    IMPLICIT NONE
2714    !! 0. Variables and parameter declaration
2715
2716    !! 0.1 Input variables
2717    INTEGER(i_std), INTENT(in)                        :: kjpindex
2718    REAL(r_std), DIMENSION(kjpindex,2), INTENT(in)    :: lalo
2719   
2720    !! 0.2 Output variables
2721    REAL(r_std), DIMENSION(kjpindex, ngrnd), INTENT(out) :: reftemp
2722    REAL(r_std), DIMENSION(kjpindex)                     :: areftemp         !! Availability of data for  the interpolation
2723
2724    !! 0.3 Local variables
2725    INTEGER(i_std) :: ib
2726    CHARACTER(LEN=80) :: filename
2727    REAL(r_std),DIMENSION(kjpindex)                      :: reftemp_file     !! Horizontal temperature field interpolated from file [C]
2728    REAL(r_std)                                          :: vmin, vmax       !! min/max values to use for the
2729                                                                             !!   renormalization
2730    CHARACTER(LEN=80)                                    :: variablename     !! Variable to interpolate
2731                                                                             !!   the file
2732    CHARACTER(LEN=80)                                    :: lonname, latname !! lon, lat names in input file
2733    REAL(r_std), DIMENSION(:), ALLOCATABLE               :: variabletypevals !! Values for all the types of the variable
2734                                                                             !!   (variabletypevals(1) = -un, not used)
2735    CHARACTER(LEN=50)                                    :: fractype         !! method of calculation of fraction
2736                                                                             !!   'XYKindTime': Input values are kinds
2737                                                                             !!     of something with a temporal
2738                                                                             !!     evolution on the dx*dy matrix'
2739    LOGICAL                                              :: nonegative       !! whether negative values should be removed
2740    CHARACTER(LEN=50)                                    :: maskingtype      !! Type of masking
2741                                                                             !!   'nomask': no-mask is applied
2742                                                                             !!   'mbelow': take values below maskvals(1)
2743                                                                             !!   'mabove': take values above maskvals(1)
2744                                                                             !!   'msumrange': take values within 2 ranges;
2745                                                                             !!      maskvals(2) <= SUM(vals(k)) <= maskvals(1)
2746                                                                             !!      maskvals(1) < SUM(vals(k)) <= maskvals(3)
2747                                                                             !!       (normalized by maskvals(3))
2748                                                                             !!   'var': mask values are taken from a
2749                                                                             !!     variable inside the file (>0)
2750    REAL(r_std), DIMENSION(3)                            :: maskvals         !! values to use to mask (according to
2751                                                                             !!   `maskingtype')
2752    CHARACTER(LEN=250)                                   :: namemaskvar      !! name of the variable to use to mask
2753    REAL(r_std)                                          :: reftemp_norefinf
2754    REAL(r_std)                                          :: reftemp_default  !! Default value
2755       
2756   
2757    !Config Key   = REFTEMP_FILE
2758    !Config Desc  = File with climatological soil temperature
2759    !Config If    = READ_REFTEMP
2760    !Config Def   = reftemp.nc
2761    !Config Help  =
2762    !Config Units = [FILE]
2763    filename = 'reftemp.nc'
2764    CALL getin_p('REFTEMP_FILE',filename)
2765
2766    variablename = 'temperature'
2767
2768    IF (printlev >= 1) WRITE(numout,*) "thermosoilc_read_reftempfile: Read and interpolate file " &
2769         // TRIM(filename) //" for variable " //TRIM(variablename)
2770
2771    ! For this case there are not types/categories. We have 'only' a continuos
2772    ! field
2773    ! Assigning values to vmin, vmax
2774
2775    vmin = 0.
2776    vmax = 9999.
2777
2778!   For this file we do not need neightbours!
2779    neighbours = 0
2780
2781    !! Variables for interpweight
2782    ! Type of calculation of cell fractions
2783    fractype = 'default'
2784    ! Name of the longitude and latitude in the input file
2785    lonname = 'nav_lon'
2786    latname = 'nav_lat'
2787    ! Default value when no value is get from input file
2788    reftemp_default = 1.
2789    ! Reference value when no value is get from input file
2790    reftemp_norefinf = 1.
2791    ! Should negative values be set to zero from input file?
2792    nonegative = .FALSE.
2793    ! Type of mask to apply to the input data (see header for more details)
2794    maskingtype = 'nomask'
2795    ! Values to use for the masking (here not used)
2796    maskvals = (/ undef_sechiba, undef_sechiba, undef_sechiba /)
2797    ! Name of the variable with the values for the mask in the input file (only if maskkingtype='var') (here not used)
2798    namemaskvar = ''
2799
2800    CALL interpweight_2Dcont(kjpindex, 0, 0, lalo, resolution, neighbours,                            &
2801      contfrac, filename, variablename, lonname, latname, vmin, vmax, nonegative, maskingtype,        &
2802      maskvals, namemaskvar, -1, fractype, reftemp_default, reftemp_norefinf,                         &
2803      reftemp_file, areftemp)
2804    IF (printlev >= 5) WRITE(numout,*)'  thermosoilc_read_reftempfile after interpweight2D_cont'
2805
2806    ! Copy reftemp_file temperature to all ground levels and transform into Kelvin
2807    DO ib=1, kjpindex
2808      reftemp(ib, :) = reftemp_file(ib)+ZeroCelsius
2809    END DO
2810
2811    ! Write diagnostics
2812    CALL xios_orchidee_send_field("areftemp",areftemp)
2813       
2814  END SUBROUTINE thermosoilc_read_reftempfile
2815 
2816
2817!!
2818!================================================================================================================================
2819!! FUNCTION     : thermosoilc_vert_axes
2820!!
2821!>\BRIEF          Depth of nodes for the thermal layers in meters.
2822!!
2823!! DESCRIPTION  : Calculate and return the depth in meters of the nodes of the soil layers.
2824!!
2825!! RECENT CHANGE(S) : None
2826!!
2827!! RETURN VALUE : Vector of soil depth for the nodes in meters
2828!!                Vector of soil depth coeficient for the nodes in meters
2829!!
2830!! REFERENCE(S) : None
2831!!
2832!! FLOWCHART    : None
2833!! \n
2834!_
2835!================================================================================================================================
2836  SUBROUTINE thermosoilc_vert_axes( zz, zz_coef)
2837    !! 0. Variables and parameter declaration
2838
2839    !! 0.1 Output variables
2840    REAL(r_std), DIMENSION (ngrnd), INTENT(out)             :: zz
2841    REAL(r_std), DIMENSION (ngrnd), INTENT(out)             :: zz_coef
2842
2843    !! 0.2 Local variables
2844    INTEGER(i_std)                                          ::  jg
2845    REAL(r_std)                                             :: so_capa_cnt
2846    REAL(r_std)                                             :: so_cond_cnt
2847
2848    IF (printlev>=3) WRITE (numout,*) 'entering thermosoilc_vert_axes'
2849
2850    !! 1. Define so_cond and so_capa depending in soil layer discretization method
2851    CALL get_discretization_constants(so_capa_cnt, so_cond_cnt)
2852
2853    !
2854    !     2. initialisation
2855    !
2856    cstgrnd=SQRT(one_day / pi)
2857    lskin = SQRT(so_cond_cnt / so_capa_cnt * one_day / pi)
2858    fz1 = 0.3_r_std * cstgrnd
2859
2860    !
2861    !     1.  Computing the depth of the Temperature level, using a
2862    !         non dimentional variable x = z/lskin, lskin beeing
2863    !         the skin depth
2864    !
2865
2866    !
2867    !     1.2 The undimentional depth is computed.
2868    !         ------------------------------------
2869    DO jg=1,ngrnd
2870      zz(jg)      = fz(REAL(jg,r_std) - undemi)
2871      zz_coef(jg) = fz(REAL(jg,r_std)-undemi+undemi)
2872    ENDDO
2873    !
2874    !     1.3 Converting to meters.
2875    !         --------------------
2876    DO jg=1,ngrnd
2877      zz(jg)      = zz(jg) /  cstgrnd * lskin
2878      zz_coef(jg) = zz_coef(jg) / cstgrnd * lskin
2879    ENDDO
2880
2881    IF (printlev>=3) WRITE (numout,*) ' thermosoilc_vert_axes done'
2882
2883  END SUBROUTINE thermosoilc_vert_axes
2884
2885!!
2886!================================================================================================================================
2887!! FUNCTION     : get_discretization_constants
2888!!
2889!>\BRIEF          Get constants values so_capa and so_cond depending on the soil layers discretization selected method
2890!!
2891!! DESCRIPTION  : Get constants values so_capa and so_cond depending on soil layers discretization selected method.
2892!!    SOIL_LAYERS_DISCRE_METHOD is defined in run.def.
2893!!
2894!! RECENT CHANGE(S) : None
2895!!
2896!! RETURN VALUE : Real soil capa value
2897!!                Real soil cond value
2898!!
2899!! REFERENCE(S) : None
2900!!
2901!! FLOWCHART    : None
2902!! \n
2903!_
2904!================================================================================================================================
2905  SUBROUTINE get_discretization_constants(soil_capa, soil_cond)
2906    !! 0. Variables and parameter declaration
2907
2908    !! 0.1 Output variables
2909    REAL(r_std), INTENT(out)             :: soil_capa
2910    REAL(r_std), INTENT(out)             :: soil_cond
2911
2912    IF (SO_DISCRETIZATION_METHOD .EQ. SLD_THERMIX) THEN
2913        soil_capa = so_capa
2914        soil_cond = so_cond 
2915    ELSE IF (SO_DISCRETIZATION_METHOD .EQ. SLD_PERMAFROST) THEN
2916        soil_capa = (so_capa_dry + so_capa_wet)/deux
2917        soil_cond = (so_cond_dry + so_cond_wet)/deux
2918    ELSE
2919        CALL ipslerr_p(3,'thermosoilc_vert_axes','SOIL_LAYERS_DISCRE_METHOD  &
2920                        method id do not exists','','')
2921    ENDIF
2922
2923  END SUBROUTINE ! get_discretization_constants
2924
2925!!
2926!================================================================================================================================
2927!! FUNCTION     : thermosoilc_levels
2928!!
2929!>\BRIEF          Depth of nodes for the thermal layers in meters.
2930!!
2931!! DESCRIPTION  : Calculate and return the depth in meters of the nodes of the soil layers. This calculation is the same
2932!!                as done in thermosoilc_var_init for zz. See thermosoilc_var_init for more details.
2933!!
2934!! RECENT CHANGE(S) : None
2935!!
2936!! RETURN VALUE : Vector of soil depth for the nodes in meters
2937!!
2938!! REFERENCE(S) : None
2939!!
2940!! FLOWCHART    : None
2941!! \n
2942!_
2943!================================================================================================================================
2944  FUNCTION thermosoilc_levels() RESULT (zz_out)
2945    !! 0. Variables and parameter declaration
2946
2947    !! 0.1 Return variable
2948
2949    REAL(r_std), DIMENSION (ngrnd)  :: zz_out      !! Depth of soil layers in meters
2950
2951    !! 0.2 Local variables
2952    INTEGER(i_std)                  :: jg
2953    REAL(r_std)                     :: so_capa_total
2954    REAL(r_std)                     :: so_cond_total
2955
2956!_
2957!================================================================================================================================
2958
2959    !! 1. Define some parameters
2960    CALL get_discretization_constants(so_capa_total, so_cond_total)
2961
2962    cstgrnd=SQRT(one_day / pi)
2963    lskin = SQRT(so_cond_total / so_capa_total * one_day / pi)
2964
2965    !! Parameters needed by fz function
2966    fz1 = 0.3_r_std * cstgrnd
2967    !zalph = deux
2968
2969    !!  2. Get adimentional depth of the numerical nodes
2970    DO jg=1,ngrnd
2971       zz_out(jg) = fz(REAL(jg,r_std) - undemi)
2972    ENDDO
2973
2974    !! 3. Convert to meters
2975    DO jg=1,ngrnd
2976       zz_out(jg) = zz_out(jg) /  cstgrnd * lskin
2977    END DO
2978
2979  END FUNCTION thermosoilc_levels
2980
2981END MODULE thermosoilc
Note: See TracBrowser for help on using the repository browser.