SURFEX v8.1
General documentation of Surfex
prep_hor_snow_fields.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 prep_hor_snow_fields (DTCO, G, U, GCP, HPROGRAM,HSURF,&
7  HFILE,HFILETYPE, &
8  HFILEPGD,HFILEPGDTYPE, &
9  KLUOUT,OUNIF,KPATCH, &
10  KTEB_PATCH, KL,TNPSNOW, TPTIME, &
11  PUNIF_WSNOW, PUNIF_RSNOW, &
12  PUNIF_TSNOW, PUNIF_LWCSNOW, &
13  PUNIF_ASNOW, OSNOW_IDEAL, &
14  PUNIF_SG1SNOW, PUNIF_SG2SNOW,&
15  PUNIF_HISTSNOW,PUNIF_AGESNOW, YDCTL,&
16  PVEGTYPE_PATCH, KSIZE_P, KR_P,&
17  PPATCH, OKEY )
18 ! #######################################################
19 !
20 !
21 !!**** *PREP_HOR_SNOW_FIELDS* - prepares all snow fields for one surface scheme.
22 !!
23 !! PURPOSE
24 !! -------
25 !
26 !!** METHOD
27 !! ------
28 !!
29 !! REFERENCE
30 !! ---------
31 !!
32 !!
33 !! AUTHOR
34 !! ------
35 !! V. Masson
36 !!
37 !! MODIFICATIONS
38 !! -------------
39 !! Original 01/2004
40 !! B. Decharme 10/2013, Phasage Arpege-Climat
41 !! B. Decharme 04/2014, Init permsnow
42 !! P. Marguinaud10/2014, Support for a 2-part PREP
43 !!------------------------------------------------------------------
44 !
45 !
47 !
48 USE modd_sfx_grid_n, ONLY : grid_t
49 USE modd_surf_atm_n, ONLY : surf_atm_t
51 !
54 !
55 USE modd_surf_par, ONLY : xundef
56 USE modd_snow_par, ONLY : xaglamin, xaglamax
57 !
58 USE modd_data_cover_par, ONLY : nvegtype
59 !
61 !
62 USE modi_allocate_gr_snow
63 USE modi_prep_hor_snow_field
64 USE mode_snow3l
65 USE modi_open_aux_io_surf
67 USE modi_close_aux_io_surf
68 !
69 USE yomhook ,ONLY : lhook, dr_hook
70 USE parkind1 ,ONLY : jprb
71 !
72 IMPLICIT NONE
73 !
74 !* 0.1 declarations of arguments
75 !
76 !
77 !
78 TYPE(data_cover_t), INTENT(INOUT) :: DTCO
79 !
80 TYPE(grid_t), INTENT(INOUT) :: G
81 TYPE(surf_atm_t), INTENT(INOUT) :: U
82 TYPE(grid_conf_proj_t),INTENT(INOUT) :: GCP
83 !
84 type(prep_ctl), INTENT (INOUT) :: ydctl
85 !
86  CHARACTER(LEN=6), INTENT(IN) :: HPROGRAM ! program calling surf. schemes
87  CHARACTER(LEN=7), INTENT(IN) :: HSURF ! type of field
88  CHARACTER(LEN=28), INTENT(IN) :: HFILE ! file name
89  CHARACTER(LEN=6), INTENT(IN) :: HFILETYPE ! file type
90  CHARACTER(LEN=28), INTENT(IN) :: HFILEPGD ! file name
91  CHARACTER(LEN=6), INTENT(IN) :: HFILEPGDTYPE ! file type
92 INTEGER, INTENT(IN) :: KLUOUT ! logical unit of output listing
93 LOGICAL, INTENT(IN) :: OUNIF ! flag for prescribed uniform field
94 INTEGER, INTENT(IN) :: KPATCH ! patch number for output scheme
95 INTEGER, INTENT(IN) :: KTEB_PATCH
96 INTEGER, INTENT(IN) :: KL ! number of points
97 TYPE(nsurf_snow), INTENT(INOUT) :: TNPSNOW ! snow fields
98 TYPE(date_time), INTENT(IN) :: TPTIME ! date and time
99 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_WSNOW ! prescribed snow content (kg/m2)
100 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_RSNOW ! prescribed density (kg/m3)
101 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_TSNOW ! prescribed temperature (K)
102 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_LWCSNOW ! prescribed snow liquid water content (kg/m3)
103 REAL, INTENT(IN) :: PUNIF_ASNOW ! prescribed albedo (-)
104 LOGICAL, INTENT(INOUT) :: OSNOW_IDEAL
105 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_SG1SNOW !
106 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_SG2SNOW !
107 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_HISTSNOW !
108 REAL, DIMENSION(:), INTENT(IN) :: PUNIF_AGESNOW !
109 
110 REAL,DIMENSION(:,:,:), INTENT(IN ), OPTIONAL :: PVEGTYPE_PATCH ! fraction of each vegtype per patch
111 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: KSIZE_P
112 INTEGER, DIMENSION(:,:), INTENT(IN), OPTIONAL :: KR_P
113 REAL,DIMENSION(:,:), INTENT(IN ), OPTIONAL :: PPATCH ! fraction of each patch
114 LOGICAL, INTENT(OUT), OPTIONAL :: OKEY
115 !
116 !
117 !* 0.2 declarations of local variables
118 !
119 TYPE(surf_snow), POINTER :: SK
120  CHARACTER(LEN=10) :: YSNSURF ! type of field
121 REAL,ALLOCATABLE,DIMENSION(:) :: ZWRHO ! total snow content from rho profile alone
122 REAL,ALLOCATABLE,DIMENSION(:,:,:) :: ZDEPTH ! snow depth of each layer
123 REAL,ALLOCATABLE,DIMENSION(:) :: ZDTOT ! total snow depth
124 INTEGER, DIMENSION(KPATCH) :: ISIZE_P
125 INTEGER,DIMENSION(KL,KPATCH) :: IR_P ! fraction of each patch
126 REAL,DIMENSION(KL,KPATCH) :: ZPATCH ! fraction of each patch
127 REAL,DIMENSION(:,:,:), ALLOCATABLE :: ZVEGTYPE_PATCH ! fraction of each vegtype per patch
128 !
129 INTEGER :: JP, ISNOW_NLAYER ! loop counter on patches
130 INTEGER :: JL, JI, ISIZE ! loop counter on layers
131 INTEGER :: IVERSION ! surface version
132  CHARACTER(LEN=16) :: YRECFM ! record name
133 INTEGER :: IRESP ! error return code
134 LOGICAL :: GGLACIER
135 !
136 REAL(KIND=JPRB) :: ZHOOK_HANDLE
137 !---------------------------------------------------------------------------
138 !
139 IF (lhook) CALL dr_hook('PREP_HOR_SNOW_FIELDS',0,zhook_handle)
140 !
141 isnow_nlayer = tnpsnow%AL(1)%NLAYER
142 !
143 IF (PRESENT(ksize_p)) THEN
144  isize_p(:) = ksize_p(:)
145 ELSE
146  isize_p(:) = kl
147 ENDIF
148 !
149 IF (PRESENT(kr_p)) THEN
150  ir_p(:,:) = kr_p(:,:)
151 ELSE
152  DO ji = 1,kl
153  ir_p(ji,:) = ji
154  ENDDO
155 ENDIF
156 !
157 IF (PRESENT(ppatch)) THEN
158  zpatch = ppatch
159 ELSE
160  zpatch = 1.
161 ENDIF
162 IF (PRESENT(pvegtype_patch)) THEN
163  ALLOCATE(zvegtype_patch(kl,SIZE(pvegtype_patch,2),kpatch))
164  zvegtype_patch = pvegtype_patch
165 ELSE
166  ALLOCATE(zvegtype_patch(kl,1,kpatch))
167  zvegtype_patch = 1.
168 ENDIF
169 !
170 !* 1. Allocation of output field
171 !
172 DO jp = 1,kpatch
173  CALL allocate_gr_snow(tnpsnow%AL(jp),isize_p(jp))
174 ENDDO
175 !
176 !---------------------------------------------------------------------------
177 !
178 !* 2. Find if PERMSNOW must be done
179 !
180 IF(PRESENT(okey))THEN
181  !
182  IF ( (hfiletype=='MESONH' .OR. hfiletype=='ASCII ' .OR. hfiletype=='LFI '.OR. hfiletype=='FA ') &
183  .AND. (hsurf=='SN_VEG ') ) THEN
184  !
185  CALL open_aux_io_surf(hfile,hfiletype,'FULL ')
186  yrecfm='VERSION'
187  CALL read_surf(hfiletype,yrecfm,iversion,iresp)
188  CALL close_aux_io_surf(hfile,hfiletype)
189  !
190  IF(iversion>7)THEN
191  CALL open_aux_io_surf(hfile,hfiletype,'NATURE')
192  yrecfm='GLACIER'
193  CALL read_surf(hfiletype,yrecfm,gglacier,iresp)
194  CALL close_aux_io_surf(hfile,hfiletype)
195  IF(gglacier)okey=.false.
196  ENDIF
197  !
198  ENDIF
199  !
200  IF(osnow_ideal)okey=.false.
201  !
202 ENDIF
203 !
204 !---------------------------------------------------------------------------
205 !
206 !* 3. Treatment of total snow content (kg/m2)
207 !
208 ysnsurf='WWW'//hsurf
209  CALL prep_hor_snow_field(dtco, g, u, gcp, &
210  hprogram, hfile, hfiletype, hfilepgd, hfilepgdtype, &
211  kluout, ounif, ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
212  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow,&
213  punif_asnow, osnow_ideal, punif_sg1snow, &
214  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
215  zvegtype_patch, zpatch, isize_p, ir_p )
216 !
217 !----------------------------------------------------------------------------
218 !
219 !* 4. Treatment of total snow depth
220 !
221 DO jp = 1,kpatch
222  ALLOCATE(tnpsnow%AL(jp)%DEPTH(isize_p(jp),isnow_nlayer))
223 ENDDO
224 !
225 ysnsurf='DEP'//hsurf
226  CALL prep_hor_snow_field(dtco, g, u, gcp, &
227  hprogram, hfile, hfiletype, hfilepgd, hfilepgdtype, &
228  kluout, ounif, ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
229  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow,&
230  punif_asnow, osnow_ideal, punif_sg1snow, &
231  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
232  zvegtype_patch, zpatch, isize_p, ir_p )
233 !
234 !* snow layer thickness definition
235 !
236 ALLOCATE(zdepth(kl,isnow_nlayer,kpatch))
237 !
238 DO jp = 1,kpatch
239  !
240  IF (osnow_ideal .OR. isnow_nlayer==1 .OR. tnpsnow%AL(jp)%SCHEME=='3-L') THEN
241  zdepth(1:isize_p(jp),:,jp) = tnpsnow%AL(jp)%DEPTH(:,:)
242  ELSEIF (tnpsnow%AL(1)%SCHEME=='CRO') THEN
243  ALLOCATE(zdtot(isize_p(jp)))
244  zdtot(:) = 0.0
245  DO jl=1,isnow_nlayer
246  zdtot(:) = zdtot(:) + tnpsnow%AL(jp)%DEPTH(:,jl)
247  END DO
248  CALL snow3lgrid(zdepth(1:isize_p(jp),:,jp),zdtot(:))
249  DEALLOCATE(zdtot)
250  ENDIF
251  !
252 ENDDO
253 !
254 DO jp = 1,kpatch
255  DEALLOCATE(tnpsnow%AL(jp)%DEPTH)
256 ENDDO
257 !
258 !----------------------------------------------------------------------------
259 !
260 !* 4. Snow density profile
261 ! --------------------
262 !
263 !* density profile
264 ysnsurf='RHO'//hsurf
265  CALL prep_hor_snow_field(dtco, g, u, gcp, &
266  hprogram,hfile,hfiletype,hfilepgd,hfilepgdtype, &
267  kluout,ounif,ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
268  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow, &
269  punif_asnow, osnow_ideal, punif_sg1snow, &
270  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
271  zvegtype_patch, zpatch, isize_p, ir_p, pdepth=zdepth )
272 !
273 !----------------------------------------------------------------------------
274 !
275 !* 5. Snow water content profile
276 ! --------------------------
277 !
278 IF (.NOT.osnow_ideal) THEN
279  !
280  ALLOCATE(zwrho(kl))
281  ALLOCATE(zdtot(kl))
282  !
283  DO jp = 1,kpatch
284  !
285  sk => tnpsnow%AL(jp)
286  !
287  zwrho(:) = 0.0
288  zdtot(:) = 0.0
289  !
290  isize = isize_p(jp)
291  !
292  !* snow depth estimated from rho profile
293  DO jl=1,isnow_nlayer
294  WHERE (zpatch(1:isize,jp)>0. .AND. sk%RHO(:,jl)/=xundef)
295  zwrho(1:isize) = zwrho(1:isize) + sk%RHO(:,jl) * zdepth(1:isize,jl,jp)
296  ELSEWHERE
297  zwrho(1:isize) = xundef
298  END WHERE
299  ENDDO
300  !
301  DO jl = 1,isnow_nlayer
302  !* modification of snow depth: coherence between rho profile, total snow and total depth
303  WHERE(zpatch(1:isize,jp)>0. .AND. zwrho(1:isize)/=0. &
304  .AND. zwrho(1:isize)/=xundef .AND. sk%WSNOW(:,1)>0.0)
305  zdtot(1:isize) = zdtot(1:isize) + zdepth(1:isize,jl,jp) * sk%WSNOW(:,1) / zwrho(1:isize)
306  ENDWHERE
307  END DO
308  !
309  IF (isnow_nlayer > 1) THEN
310  CALL snow3lgrid(zdepth(1:isize,:,jp),zdtot(1:isize))
311  ELSE
312  zdepth(1:isize,1,jp) = zdtot(1:isize)
313  ENDIF
314  !
315  !* snow content profile for each grid level
316  DO jl=1,isnow_nlayer
317  WHERE(zpatch(1:isize,jp)>0..AND.sk%RHO(:,jl)/=xundef.AND.zdtot(1:isize)>0.)
318  sk%WSNOW(:,jl) = sk%RHO(:,jl) * zdepth(1:isize,jl,jp)
319  ELSEWHERE(zpatch(1:isize,jp)>0..AND.(sk%RHO(:,jl)==xundef.OR.zdtot(1:isize)==0.0))
320  sk%WSNOW(:,jl) = 0.0
321  ELSEWHERE
322  sk%WSNOW(:,jl) = xundef
323  END WHERE
324  END DO
325  !
326  END DO
327  !
328  DEALLOCATE(zwrho)
329  DEALLOCATE(zdtot)
330  !
331 ENDIF
332 !
333 !----------------------------------------------------------------------------
334 !
335 !* 6. Albedo, snow heat content, and age
336 ! ----------------------------------
337 !
338 !* albedo
339 ysnsurf='ALB'//hsurf
340  CALL prep_hor_snow_field(dtco, g, u, gcp, &
341  hprogram,hfile,hfiletype,hfilepgd,hfilepgdtype, &
342  kluout,ounif,ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
343  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow, &
344  punif_asnow, osnow_ideal, punif_sg1snow, &
345  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
346  zvegtype_patch, zpatch, isize_p, ir_p, pdepth=zdepth )
347 !
348 IF (tnpsnow%AL(1)%SCHEME/='D95') THEN
349  !
350  !* heat in snowpack profile
351  ysnsurf='HEA'//hsurf
352  CALL prep_hor_snow_field(dtco, g, u, gcp, &
353  hprogram,hfile,hfiletype,hfilepgd,hfilepgdtype, &
354  kluout,ounif,ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
355  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow, &
356  punif_asnow, osnow_ideal, punif_sg1snow, &
357  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
358  zvegtype_patch, zpatch, isize_p, ir_p, pdepth=zdepth )
359  !
360 ENDIF
361 !
362 IF (tnpsnow%AL(1)%SCHEME=='CRO'.OR. tnpsnow%AL(1)%SCHEME=='3-L') THEN
363  !
364  !* age in snowpack profile
365  ysnsurf='AGE'//hsurf
366  CALL prep_hor_snow_field(dtco, g, u, gcp, &
367  hprogram,hfile,hfiletype,hfilepgd,hfilepgdtype, &
368  kluout,ounif,ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
369  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow, &
370  punif_asnow, osnow_ideal, punif_sg1snow, &
371  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
372  zvegtype_patch, zpatch, isize_p, ir_p, pdepth=zdepth )
373  !
374  DO jp = 1,kpatch
375  WHERE(tnpsnow%AL(jp)%WSNOW(:,1)>0.0 .AND. tnpsnow%AL(jp)%WSNOW(:,1)/=xundef .AND. &
376  tnpsnow%AL(jp)%AGE(:,1)==0.0 .AND. tnpsnow%AL(jp)%ALB(:)<xaglamin)
377  tnpsnow%AL(jp)%ALB(:)=(xaglamin+xaglamax)/2.0
378  ENDWHERE
379  ENDDO
380  !
381 ENDIF
382 !
383 !----------------------------------------------------------------------------
384 !
385 !* 7. Crocus specific parameters
386 ! --------------------------
387 !
388 IF (tnpsnow%AL(1)%SCHEME=='CRO') THEN
389  !
390  ysnsurf='SG1'//hsurf
391  CALL prep_hor_snow_field(dtco, g, u, gcp, &
392  hprogram,hfile,hfiletype,hfilepgd,hfilepgdtype, &
393  kluout,ounif,ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
394  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow, &
395  punif_asnow, osnow_ideal, punif_sg1snow, &
396  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
397  zvegtype_patch, zpatch, isize_p, ir_p, pdepth=zdepth )
398  !
399  ysnsurf='SG2'//hsurf
400  CALL prep_hor_snow_field(dtco, g, u, gcp, &
401  hprogram,hfile,hfiletype,hfilepgd,hfilepgdtype, &
402  kluout,ounif,ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
403  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow, &
404  punif_asnow, osnow_ideal, punif_sg1snow, &
405  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
406  zvegtype_patch, zpatch, isize_p, ir_p, pdepth=zdepth )
407  !
408  ysnsurf='HIS'//hsurf
409  CALL prep_hor_snow_field(dtco, g, u, gcp, &
410  hprogram,hfile,hfiletype,hfilepgd,hfilepgdtype, &
411  kluout,ounif,ysnsurf, kpatch, kteb_patch, kl, tnpsnow, tptime, &
412  punif_wsnow, punif_rsnow, punif_tsnow, punif_lwcsnow, &
413  punif_asnow, osnow_ideal, punif_sg1snow, &
414  punif_sg2snow, punif_histsnow,punif_agesnow, ydctl, &
415  zvegtype_patch, zpatch, isize_p, ir_p, pdepth=zdepth )
416  !
417 ENDIF
418 !
419 !* 8. Deallocations
420 !
421 DEALLOCATE(zdepth )
422 DEALLOCATE(zvegtype_patch)
423 !
424 IF (lhook) CALL dr_hook('PREP_HOR_SNOW_FIELDS',1,zhook_handle)
425 !
426 !----------------------------------------------------------------------------
427 !
428 END SUBROUTINE prep_hor_snow_fields
subroutine prep_hor_snow_fields(DTCO, G, U, GCP, HPROGRAM, HSURF, HFILE, HFILETYPE, HFILEPGD, HFILEPGDTYPE, KLUOUT, OUNIF, KPATCH, KTEB_PATCH, KL, TNPSNOW, TPTIME, PUNIF_WSNOW, PUNIF_RSNOW, PUNIF_TSNOW, PUNIF_LWCSNOW, PUNIF_ASNOW, OSNOW_IDEAL, PUNIF_SG1SNOW, PUNIF_SG2SNOW, PUNIF_HISTSNOW, PUNIF_AGESNOW, YDCTL, PVEGTYPE_PATCH, KSIZE_P, KR_P, PPATCH, OKEY)
subroutine close_aux_io_surf(HFILE, HFILETYPE)
real, parameter xundef
integer, parameter jprb
Definition: parkind1.F90:32
subroutine allocate_gr_snow(TPSNOW, KLU)
logical lhook
Definition: yomhook.F90:15
subroutine prep_hor_snow_field(DTCO, G, U, GCP, HPROGRAM, HFILE, HFILETYPE, HFILEPGD, HFILEPGDTYPE, KLUOUT, OUNIF, HSNSURF, KPATCH, KTEB_PATCH, KL, TNPSNOW, TPTIME, PUNIF_WSNOW, PUNIF_RSNOW, PUNIF_TSNOW, PUNIF_LWCSNOW, PUNIF_ASNOW, OSNOW_IDEAL, PUNIF_SG1SNOW, PUNIF_SG2SNOW, PUNIF_HISTSNOW, PUNIF_AGESNOW, YDCTL, PVEGTYPE_PATCH, PPATCH, KSIZE_P, KR_P, PDEPTH)
subroutine open_aux_io_surf(HFILE, HFILETYPE, HMASK, HDIR)