SURFEX v8.1
General documentation of Surfex
thermal_layers_conf.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! ######################################################################
6  SUBROUTINE thermal_layers_conf(HTYPE,PD,PD_OUT,PHC,PHC_OUT,PTC,PTC_OUT)
7 ! ######################################################################
8 !
9 !!**** *THERMAL_LAYERS_CONF*
10 !!
11 !! PURPOSE
12 !! -------
13 ! Adjust the thermal characteristics of the layers in road, wall, roof or
14 ! floor depending on the number of layers that the user wants to use during
15 ! the simulations.
16 ! Initial data are prescribed depending on user preference.
17 ! They have to be averaged on the layers use in the simulation
18 !
19 !!
20 !!** METHOD
21 !! ------
22 !!
23 !! EXTERNAL
24 !! --------
25 !!
26 !! IMPLICIT ARGUMENTS
27 !! ------------------
28 !!
29 !! REFERENCE
30 !! ---------
31 !!
32 !! AUTHOR
33 !! ------
34 !! V. Masson *Meteo France*
35 !!
36 !! MODIFICATIONS
37 !! -------------
38 !! Original 05/2012
39 !-------------------------------------------------------------------------------
40 !
41 !* 0. DECLARATIONS
42 ! ------------
43 !
44 USE modd_surf_par, ONLY : xundef
45 USE modi_abor1_sfx
46 !
47 USE yomhook ,ONLY : lhook, dr_hook
48 USE parkind1 ,ONLY : jprb
49 !
50 IMPLICIT NONE
51 !
52 !* 0.1 Declarations of arguments
53 ! -------------------------
54 !
55  CHARACTER(LEN=5), INTENT(IN) :: HTYPE ! type of surface
56 REAL, DIMENSION(:,:), INTENT(IN) :: PD ! input Layer Thickness
57 REAL, DIMENSION(:,:), INTENT(OUT) :: PD_OUT ! output Layer Thickness
58 REAL, DIMENSION(:,:), INTENT(IN), OPTIONAL :: PHC ! input Heat Capacity
59 REAL, DIMENSION(:,:), INTENT(OUT), OPTIONAL :: PHC_OUT ! output Heat Capacity
60 REAL, DIMENSION(:,:), INTENT(IN), OPTIONAL :: PTC ! input Thermal conductivity
61 REAL, DIMENSION(:,:), INTENT(OUT), OPTIONAL :: PTC_OUT ! output Thermal conductivity
62 !
63 !* 0.2 Declarations of local variables
64 !
65 REAL :: ZD_TOT ! Total depth
66 REAL :: ZD_HALF ! Depth of the half of the total surface
67 ! ! (excluding central layer in case
68 ! ! of odd number of layers)
69 REAL :: ZD_MID ! Thickness of the layer in the middle
70 ! ! in case of odd number of layers
71 REAL, DIMENSION(0:SIZE(PD ,2))::ZD_IN ! Depth from the surface
72 ! ! to the layer bottom
73 REAL, DIMENSION(0:SIZE(PD_OUT,2))::ZD_OUT ! Depth from the surface
74 ! ! to the layer bottom
75 REAL, DIMENSION(SIZE(PD,2)) :: ZW, ZHC ! 1/TC
76 REAL, DIMENSION(SIZE(PD_OUT,2)) :: ZW_OUT, ZHC_OUT ! 1/TC
77 INTEGER :: IIN ! Number of layer in input data
78 INTEGER :: IOUT ! Number of layer in output fields
79 INTEGER :: JIN, JI ! Loop counter on input layers
80 INTEGER :: JOUT ! Loop counter on output layers
81 !
82 REAL, PARAMETER :: ZD_G1 = 0.001 ! uppermost soil layer
83 ! ! thickness/depth ( m)
84 ! ! Can not be too thin as
85 ! ! then definition of soil
86 ! ! properties (i.e. phyiscal
87 ! ! representation of) and
88 ! ! accuarcy of
89 ! ! numerical solution come
90 ! ! into question. If it is too
91 ! ! thick, then resolution of
92 ! ! diurnal cycle not as valid.
93 REAL(KIND=JPRB) :: ZHOOK_HANDLE, ZHOOK_HANDLE_OMP
94 !-------------------------------------------------------------------------------
95 !
96 IF (lhook) CALL dr_hook('THERMAL_LAYER_CONF_1',0,zhook_handle)
97 !
98 IF (PRESENT(phc_out).AND..NOT.PRESENT(phc)) THEN
99  CALL abor1_sfx("THERMAL_LAYERS_CONF:IF HC_OUT IS PRESENT, HC MUST BE PRESENT TOO.")
100 ELSEIF (PRESENT(ptc_out).AND..NOT.PRESENT(ptc)) THEN
101  CALL abor1_sfx("THERMAL_LAYERS_CONF:IF TC_OUT IS PRESENT, TC MUST BE PRESENT TOO.")
102 ENDIF
103 !
104 iout= SIZE(pd_out,2)
105 !
106 iin = SIZE(pd,2)
107 !
108 IF (lhook) CALL dr_hook('THERMAL_LAYER_CONF_1',1,zhook_handle)
109 !
110 !$OMP PARALLEL PRIVATE(ZHOOK_HANDLE_OMP)
111 IF (lhook) CALL dr_hook('THERMAL_LAYER_CONF_2',0,zhook_handle_omp)
112 !$OMP DO PRIVATE(JI,ZD_IN,ZD_TOT,ZD_OUT,ZD_HALF,ZD_MID,ZW,ZHC,ZW_OUT,ZHC_OUT)
113 DO ji=1,SIZE(pd_out,1)
114  !
115  zd_in(0) = 0.
116  DO jin=1,iin
117  zd_in(jin) = zd_in(jin-1) + pd(ji,jin)
118  END DO
119  zd_tot = zd_in(iin)
120  !
121  !* Depths for the computational grid
122  !
123  !* surface like road or floor (thin grid at the surface, coarse at the bottom)
124  !
125  zd_out(0) = 0.
126  !
127  IF (htype=='ROAD ' .OR. htype=='FLOOR') THEN
128  !
129  CALL tebgrid(zd_tot,zd_out(1:),zd_g1)
130  !
131  DO jout=1,iout
132  pd_out(ji,jout) = zd_out(jout) - zd_out(jout-1) ! Depths => Thickness of layer
133  END DO
134  !
135  ELSE
136  !
137  !* surface like roof or wall (thin grid on both sides, coarse in the middle)
138  !
139  IF (mod(iout,2)==0) THEN ! even number of output layers
140  zd_half = zd_tot / 2.
141  ELSE ! odd number of output layers
142  zd_mid = 2. * zd_tot / iout ! middle layer is arbitrarily fixed
143  IF (iout==3) zd_mid = max(zd_mid,zd_tot-2.*zd_g1) ! to impose layers equal
144  ! to ZD_G1 on both sides
145  zd_half = (zd_tot-zd_mid) / 2.
146  pd_out(ji,iout/2+1) = zd_mid
147  END IF
148  !
149  CALL tebgrid(zd_half,zd_out(1:iout/2),zd_g1)
150  !
151  DO jout=1,iout
152  !
153  IF (jout<=iout/2) THEN
154  pd_out(ji,jout) = zd_out(jout) - zd_out(jout-1) ! Depths => Thickness of layer
155  pd_out(ji,iout+1-jout) = pd_out(ji,jout)
156  ENDIF
157  !
158  !* recomputes Depths for further averagings
159  IF (jout>1) zd_out(jout) = zd_out(jout-1) + pd_out(ji,jout)
160  !
161  END DO
162  !
163  ENDIF
164  !
165  IF (pd(ji,1)==xundef) pd_out(ji,1:iout) = xundef
166  !
167  !-------------------------------------------------------------------------------
168  !
169  !* Averaging of the Heat Capacity and the Thermal conductivity
170  !
171  IF (PRESENT(ptc)) THEN
172  zw(:) =1./ptc(ji,:)
173  ELSE
174  zw(:) =1.
175  ENDIF
176  IF (PRESENT(phc)) THEN
177  zhc(:) = phc(ji,:)
178  ELSE
179  zhc(:) = 1.
180  ENDIF
181  !
182  CALL av_thermal_data(iout,pd(ji,:),zd_in(1:iin),zd_out(1:iout),zhc,zw,zhc_out,zw_out)
183  !
184  IF (PRESENT(ptc_out)) THEN
185  ptc_out(ji,:)=xundef
186  WHERE (zw_out(:)/=xundef) ptc_out(ji,:)=1./zw_out(:)
187  ENDIF
188  IF (PRESENT(phc_out)) phc_out(ji,:) = zhc_out(:)
189  !
190 ENDDO
191 !$OMP END DO
192 IF (lhook) CALL dr_hook('THERMAL_LAYER_CONF_2',1,zhook_handle_omp)
193 !$OMP END PARALLEL
194 !
195 !-------------------------------------------------------------------------------
196 CONTAINS
197 !-------------------------------------------------------------------------------
198 SUBROUTINE av_thermal_data(KOUT,PDD,PDD_IN,PDD_OUT,PF1,PF2,PF1_OUT,PF2_OUT)
199 !
200 IMPLICIT NONE
201 !
202 INTEGER, INTENT(IN) :: KOUT
203 REAL, DIMENSION(:), INTENT(IN) :: PDD
204 REAL, DIMENSION(:), INTENT(IN) :: PDD_IN
205 REAL, DIMENSION(:), INTENT(IN) :: PDD_OUT
206 REAL, DIMENSION(:), INTENT(IN) :: PF1
207 REAL, DIMENSION(:), INTENT(IN) :: PF2
208 REAL, DIMENSION(:), INTENT(OUT) :: PF1_OUT
209 REAL, DIMENSION(:), INTENT(OUT) :: PF2_OUT
210 !
211 REAL :: ZF1! ponderated field
212 REAL :: ZF2! ponderated field
213 REAL :: ZS ! sum of weights
214 REAL :: ZC ! coefficient of ponderation
215 REAL :: ZD_LIM ! limit of previous layer that has been treated
216 !
217 REAL :: ZEPS=1.e-6
218 !
219 INTEGER :: JOUT, JIN
220 !
221 REAL(KIND=JPRB) :: ZHOOK_HANDLE
222 !
223 !* total depth:
224 !
225 !
226 IF (pdd(1)==xundef) THEN
227  pf1_out(:) = xundef
228  pf2_out(:) = xundef
229  !
230 ELSE
231  !
232  zf1 = 0.
233  zf2 = 0.
234  zs = 0.
235  jin = 1
236  jout= 1
237  zd_lim = 0.
238  !
239  DO
240  !
241  IF (jout>kout) EXIT
242  !
243  IF (pdd_in(jin)< pdd_out(jout)-zeps) THEN
244  !
245  !ZC = PDD_IN(JIN) - MAX(PDD_IN(JIN-1),PDD_OUT(JOUT-1))
246  zc = pdd_in(jin) - zd_lim
247  zf1 = zf1 + zc * pf1(jin)
248  zf2 = zf2 + zc * pf2(jin)
249  zs = zs + zc
250  zd_lim = pdd_in(jin)
251  !
252  jin=jin+1
253  !
254  ELSE
255  !
256  !ZC = PDD_OUT(JOUT) - MAX(PDD_IN(JIN-1),PDD_OUT(JOUT-1))
257  zc = pdd_out(jout) - zd_lim
258  zf1 = zf1 + zc * pf1(jin)
259  zf2 = zf2 + zc * pf2(jin)
260  zs = zs + zc
261  pf1_out(jout) = zf1/zs
262  pf2_out(jout) = zf2/zs
263  zd_lim = pdd_out(jout)
264  !
265  jout = jout+1
266  zf1 = 0.
267  zf2 = 0.
268  zs = 0.
269  !
270  END IF
271  !
272  END DO
273  !
274 ENDIF
275 !
276 END SUBROUTINE av_thermal_data
277 !
278 ! #########
279  SUBROUTINE tebgrid( PSOILDEPTH, PD_G, PD_G1 )
281 ! ##########################################################################
282 !
283 !!**** *TEBGRID*
284 !!
285 !! PURPOSE
286 !! -------
287 !
288 ! Calculates the soil grid configuration using a simple
289 ! geometric relation for all sub-surface layers.
290 ! This algorithm assumes the total soil depth > 0 m
291 !
292 !
293 !!** METHOD
294 !! ------
295 !
296 ! Direct calculation
297 !
298 !! EXTERNAL
299 !! --------
300 !
301 ! None
302 !!
303 !! IMPLICIT ARGUMENTS
304 !! ------------------
305 !!
306 !! REFERENCE
307 !! ---------
308 !!
309 !! Noilhan and Planton (1989)
310 !! Belair (1995)
311 !! Boone (2000)
312 !! Boone et al. (2000)
313 !! Habets et al. (2003)
314 !!
315 !! AUTHOR
316 !! ------
317 !! A. Boone * Meteo-France *
318 !!
319 !! MODIFICATIONS
320 !! -------------
321 !! Original 12/04/03
322 !! B. Decharme 12/10 uppermost soil layer set to 1cm
323 !-------------------------------------------------------------------------------
324 !
325 !* 0. DECLARATIONS
326 ! ------------
327 !
328 !
329 USE yomhook ,ONLY : lhook, dr_hook
330 USE parkind1 ,ONLY : jprb
331 !
332 IMPLICIT NONE
333 !
334 !* 0.1 declarations of arguments
335 !
336 !
337 REAL, INTENT(IN) :: PSOILDEPTH ! total soil depth (m)
338 !
339 REAL, DIMENSION(:), INTENT(OUT) :: PD_G ! depth of base of soil layers (m)
340 REAL, OPTIONAL, INTENT(IN) :: PD_G1 ! depth of first layer
341 !
342 !
343 !* 0.2 declarations of local variables
344 !
345 INTEGER :: JJ, JI, JNLVL
346 !
347 !
348 REAL, PARAMETER :: ZGRIDFACTOR = 3.0 ! soil depth factor
349 ! ! of increase with depth
350 ! ! for all *sub-surface*
351 ! ! layers. Note, uppermost
352 ! ! layer fixed by other
353 ! ! constraints. (-)
354 !
355 REAL :: ZD_G1 = 0.01 ! uppermost soil layer
356 ! ! thickness/depth (m)
357 ! ! Can not be too thin as
358 ! ! then definition of soil
359 ! ! properties (i.e. phyiscal
360 ! ! representation of) and
361 ! ! accuarcy of
362 ! ! numerical solution come
363 ! ! into question. If it is too
364 ! ! thick, then resolution of
365 ! ! diurnal cycle not as valid.
366 ! ! Also chosen to comply with
367 ! ! remotely sensed soil moisture.
368 REAL(KIND=JPRB) :: ZHOOK_HANDLE
369 !-------------------------------------------------------------------------------
370 ! 0. Initialization
371 ! --------------
372 !
373 jnlvl = SIZE(pd_g)
374 !
375 IF (PRESENT(pd_g1)) zd_g1 = pd_g1
376 !
377 IF (psoildepth < jnlvl*zd_g1) THEN
378  !
379  !* 3. In the LIMIT For extremely thin soils
380  ! ------------------------------------------
381  ! This should be a RARE occurance, but
382  ! accounted for none-the-less ...:
383  ! hold the ratio between all layer
384  ! thicknesses constant.
385  DO jj = 1,jnlvl
386  pd_g(jj) = jj*psoildepth/jnlvl
387  ENDDO
388  !
389 ELSE
390  !
391  pd_g(1) = zd_g1
392  pd_g(jnlvl) = psoildepth
393  !
394  DO jj=jnlvl-1,2,-1
395  !* 1. Assign soil layer depths
396  ! ------------------------
397  ! using a geometric relation
398  ! for layers 2...N
399  ! This is GENERAL rule.
400  ! Note that the first soil layer
401  ! is FIXED except for VERY thin
402  ! soils (see #3 below).
403  pd_g(jj) = pd_g(jj+1)/zgridfactor
404  !* 2. When the soil is sufficiently thin
405  ! ------------------------------------------
406  ! We recalculate layer depths such
407  ! that all layer thicknesses are >= ZD_G1
408  ! We favor keeping a minimum grid thickness
409  ! OVER maintaining geometric relation
410  ! for increasingly thin soils. This means
411  ! that uppermost soil moisture is readily
412  ! comparable (i.e. for same layer thickness)
413  ! EVERYWHERE except for most thin soils (below).
414  pd_g(jj) = max(pd_g(jj), jj*zd_g1)
415  !
416  ENDDO
417  !
418 ENDIF
419 !
420 !-------------------------------------------------------------------------------
421 !
422 END SUBROUTINE tebgrid
423 !
424 END SUBROUTINE thermal_layers_conf
subroutine av_thermal_data(KOUT, PDD, PDD_IN, PDD_OUT, PF1, PF2, PF1_OUT, PF2_O
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:7
real, parameter xundef
integer, parameter jprb
Definition: parkind1.F90:32
logical lhook
Definition: yomhook.F90:15
subroutine thermal_layers_conf(HTYPE, PD, PD_OUT, PHC, PHC_OUT, PTC, PTC
subroutine tebgrid(PSOILDEPTH, PD_G, PD_G1)