SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
prep_perm_snow.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_perm_snow (I, &
7  tpsnow,ptg,pperm_snow_frac,ksnow)
8 ! ################################################
9 !
10 !
11 !!**** *PREP_PERM_SNOW* - takes into account permanent snow into prognostic snow
12 !!
13 !! PURPOSE
14 !! -------
15 !
16 !!** METHOD
17 !! ------
18 !!
19 !! REFERENCE
20 !! ---------
21 !!
22 !!
23 !! AUTHOR
24 !! ------
25 !! V. Masson
26 !!
27 !! MODIFICATIONS
28 !! -------------
29 !! Original 01/2004
30 !! B. Decharme 03/2009: Consistency with Arpege permanent
31 !! snow/ice treatment
32 !! B. Decharme 07/2012: 3-L or Crocus adjustments
33 !! M. Lafaysse 09/2012: adaptation with new snow age in Crocus
34 !!------------------------------------------------------------------
35 !
36 
37 !
38 USE modd_isba_n, ONLY : isba_t
39 !
41 USE modd_csts, ONLY : xtt
42 USE modd_data_cover_par, ONLY : nvt_snow
43 USE modd_snow_par, ONLY : xrhosmax, xansmax, xansmin, &
44  xaglamax, xaglamin, xhgla, &
45  xrhosmax_es
46 USE modd_surf_par, ONLY : xundef
47 !
48 USE modd_isba_par, ONLY : xwgmin
49 !
52 USE modi_mkflag_snow
54 USE mode_snow3l
55 !
56 USE yomhook ,ONLY : lhook, dr_hook
57 USE parkind1 ,ONLY : jprb
58 !
59 IMPLICIT NONE
60 !
61 !* 0.1 declarations of arguments
62 !
63 !
64 TYPE(isba_t), INTENT(INOUT) :: i
65 !
66 TYPE(surf_snow), INTENT(INOUT) :: tpsnow ! snow mantel characteristics
67 REAL, DIMENSION(:,:), INTENT(IN):: ptg ! soil temperature for patch KSNOW
68 REAL, DIMENSION(:,:), INTENT(IN):: pperm_snow_frac ! fraction of permanent snow for patch KSNOW
69 INTEGER, INTENT(IN):: ksnow ! patch number where permanent snow is
70 !
71 !* 0.2 declarations of local parameter
72 !
73 REAL, PARAMETER :: zrhol1 = 150.
74 !
75 !* 0.3 declarations of local variables
76 !
77 INTEGER :: jlayer ! loop counter on snow layers
78 REAL, DIMENSION(:), ALLOCATABLE :: zwsnow_perm ! snow total reservoir due to perm. snow
79 REAL, DIMENSION(:), ALLOCATABLE :: zwsnow ! initial snow total reservoir
80 REAL, DIMENSION(:), ALLOCATABLE :: zd ! new snow total depth
81 REAL, DIMENSION(:,:), ALLOCATABLE :: zdepth ! depth of each layer
82 REAL, DIMENSION(:,:,:), ALLOCATABLE :: zt ! new snow temperature profile
83 REAL, DIMENSION(:), ALLOCATABLE :: zpsn ! permanent snow fraction
84 REAL, DIMENSION(:,:), ALLOCATABLE :: zwat !
85 !
86 LOGICAL, DIMENSION(:,:), ALLOCATABLE :: gwork
87 INTEGER :: iwork
88 !
89 REAL ::zrhosmax
90 REAL ::zage_now
91 !
92 REAL(KIND=JPRB) :: zhook_handle
93 !
94 !-------------------------------------------------------------------------------------
95 !
96 !* 1. Snow where permanent snow is
97 ! ----------------------------
98 !
99 !* snow fraction must be at least equal to permanent snow fraction
100 ! The snow fraction is computed as Wsnow/(Wsnow+XWCRN)
101 !
102 !
103 IF (lhook) CALL dr_hook('PREP_PERM_SNOW',0,zhook_handle)
104 !
105 zrhosmax=xrhosmax
106 IF(tpsnow%SCHEME=='3-L'.OR.tpsnow%SCHEME=='CRO')THEN
107  zrhosmax=xrhosmax_es
108 ENDIF
109 !
110 ALLOCATE(zpsn(SIZE(ptg,1)))
111 zpsn(:) = min( pperm_snow_frac(:,nvt_snow) , 0.9999 )
112 !
113 !* if no permanent snow present
114 !
115 IF (all(zpsn(:)==0.)) THEN
116  DEALLOCATE(zpsn)
117  IF (lhook) CALL dr_hook('PREP_PERM_SNOW',1,zhook_handle)
118  RETURN
119 END IF
120 !
121 !* total snow amount due to permanent snow
122 !
123 ALLOCATE(zwsnow_perm(SIZE(ptg,1)))
124 zwsnow_perm(:) = wsnow_from_snow_frac_ground(zpsn)
125 !
126 !* limitation of maximum snow amount
127 !
128 IF(i%LGLACIER)THEN
129 ! limited to 33.3 meters of aged snow
130  zwsnow_perm(:) = min(zwsnow_perm(:),xhgla * zrhosmax )
131 ELSE
132 ! limited to 2. meters of aged snow
133  zwsnow_perm(:) = min(zwsnow_perm(:),2.0 * zrhosmax )
134 ENDIF
135 !
136 !* permanent snow can be added only if deep soil temperature is below 5 C
137 ! (glaciers on subgrid mountains tops that are contained in the grid mesh are neglected)
138 !
139 IF(.NOT.i%LGLACIER)THEN
140  WHERE(ptg(:,SIZE(ptg,2))>xtt+5.) zwsnow_perm(:) = 0.
141 ENDIF
142 !
143 !-------------------------------------------------------------------------------------
144 !
145 !* 2. Other parameters of new snow, except temperature
146 ! ------------------------------------------------
147 !
148 !* rho must be defined for snow 3-L before temperature and heat computations
149 !
150 ALLOCATE(gwork(SIZE(ptg,1),tpsnow%NLAYER))
151 !
152 DO jlayer=1,tpsnow%NLAYER
153 !
154  gwork(:,jlayer)=.false.
155 !
156  IF(i%LGLACIER)THEN
157  WHERE(zwsnow_perm(:)>0.)gwork(:,jlayer)=.true.
158  ELSE
159  WHERE(zwsnow_perm(:)>0..AND.tpsnow%WSNOW(:,jlayer,ksnow)==0.)gwork(:,jlayer)=.true.
160  ENDIF
161 !
162 !* rho
163 !
164  WHERE(gwork(:,jlayer))
165  tpsnow%RHO(:,jlayer,ksnow) = zrhosmax
166  END WHERE
167 !
168 !* albedo
169 !
170  IF(i%LGLACIER)THEN
171  WHERE(gwork(:,jlayer))
172  tpsnow%ALB(:,ksnow) = (xaglamax+xaglamin)/2.0
173  END WHERE
174  ELSE
175  WHERE(gwork(:,jlayer))
176  tpsnow%ALB(:,ksnow) = (xansmax+xansmin)/2.0
177  END WHERE
178  ENDIF
179 !
180 END DO
181 !
182 IF (tpsnow%SCHEME=='3-L'.OR.tpsnow%SCHEME=='CRO') THEN
183 !
184 ! * optimized rho perm snow profile
185 !
186  IF(i%LGLACIER.AND.tpsnow%NLAYER>=6)THEN
187  WHERE(gwork(:,1))
188  tpsnow%RHO(:,1,ksnow) = zrhol1
189  END WHERE
190  IF(tpsnow%NLAYER>=6.AND.tpsnow%NLAYER<12)THEN
191  WHERE(gwork(:,2))
192  tpsnow%RHO(:,2,ksnow) = zrhol1 + 100.
193  END WHERE
194  WHERE(gwork(:,3))
195  tpsnow%RHO(:,3,ksnow) = zrhol1 + 250.
196  END WHERE
197  ELSE
198  DO jlayer=2,tpsnow%NLAYER
199  WHERE(gwork(:,jlayer))
200  tpsnow%RHO(:,jlayer,ksnow) = min(zrhosmax,tpsnow%RHO(:,jlayer-1,ksnow)+100.)
201  END WHERE
202  ENDDO
203  ENDIF
204  ENDIF
205 !
206 ! * Snow age profile
207 !
208  DO jlayer=1,tpsnow%NLAYER/4
209  WHERE(gwork(:,jlayer))
210  tpsnow%AGE(:,jlayer,ksnow) = 365.0*float(jlayer-1)/ &
211  float(tpsnow%NLAYER)
212  END WHERE
213  END DO
214  DO jlayer=1+tpsnow%NLAYER/4,tpsnow%NLAYER
215  WHERE(gwork(:,jlayer))
216  tpsnow%AGE(:,jlayer,ksnow) = 3650.*float(jlayer-1)/ &
217  float(tpsnow%NLAYER)
218  END WHERE
219  END DO
220 !
221  IF(i%LGLACIER)THEN
222  WHERE(gwork(:,:))tpsnow%AGE(:,:,ksnow) = 0.0
223  ENDIF
224 !
225 END IF
226 !
227 IF (tpsnow%SCHEME=='CRO') THEN
228 DO jlayer=1,tpsnow%NLAYER/4
229  WHERE(gwork(:,jlayer))
230  tpsnow%GRAN1(:,jlayer,ksnow) = min(-1.,-99.* &
231  (1.-4*float(jlayer)/float(tpsnow%NLAYER)))
232  tpsnow%GRAN2(:,jlayer,ksnow) = 50.
233  tpsnow%HIST(:,jlayer,ksnow) = 0
234  END WHERE
235 END DO
236 DO jlayer=1+tpsnow%NLAYER/4,tpsnow%NLAYER
237  WHERE(gwork(:,jlayer))
238  tpsnow%GRAN1(:,jlayer,ksnow) = 99.
239  tpsnow%GRAN2(:,jlayer,ksnow) = 0.0003
240  tpsnow%HIST(:,jlayer,ksnow) = 0
241  END WHERE
242 END DO
243 END IF
244 !
245 !-------------------------------------------------------------------------------------
246 !
247 !* 3. Modification of snow reservoir profile
248 ! --------------------------------------
249 !
250 !* initial snow content
251 !
252 ALLOCATE(zwsnow(SIZE(ptg,1)))
253 zwsnow(:) = 0.
254 DO jlayer=1,tpsnow%NLAYER
255  zwsnow(:) = zwsnow(:) + tpsnow%WSNOW(:,jlayer,ksnow)
256 END DO
257 !
258 !* new total snow content
259 !
260 zwsnow_perm(:) = max(zwsnow_perm(:),zwsnow(:))
261 !
262 !* new total snow depth
263 !
264 ALLOCATE(zd(SIZE(ptg,1)))
265 zd(:) = 0.
266 DO jlayer=1,tpsnow%NLAYER
267  zd(:) = zd(:) + tpsnow%WSNOW(:,jlayer,ksnow)/tpsnow%RHO(:,jlayer,ksnow)
268 END DO
269 zd(:) = zd(:) + (zwsnow_perm(:)-zwsnow(:))/zrhosmax
270 !
271 !* modified snow content profile
272 !
273 SELECT CASE(tpsnow%SCHEME)
274  CASE('D95','1-L','EBA')
275  gwork(:,1)=.false.
276  IF(i%LGLACIER)THEN
277  WHERE(zwsnow(:)>=0..AND.tpsnow%WSNOW(:,1,ksnow)/=xundef)gwork(:,1)=.true.
278  ELSE
279  WHERE(zwsnow(:)==0..AND.tpsnow%WSNOW(:,1,ksnow)/=xundef)gwork(:,1)=.true.
280  ENDIF
281  WHERE(gwork(:,1))
282  tpsnow%WSNOW(:,1,ksnow) = zwsnow_perm(:)
283  END WHERE
284  CASE('3-L','CRO')
285  !* grid
286  ALLOCATE(zdepth(SIZE(ptg,1),tpsnow%NLAYER))
287  CALL snow3lgrid(zdepth,zd)
288  DO jlayer=1,tpsnow%NLAYER
289  WHERE(zwsnow(:)>= 0. .AND. tpsnow%WSNOW(:,jlayer,ksnow)/=xundef)
290  tpsnow%WSNOW(:,jlayer,ksnow) = zdepth(:,jlayer) * tpsnow%RHO(:,jlayer,ksnow)
291  END WHERE
292  END DO
293  DEALLOCATE(zdepth)
294 
295 END SELECT
296 !
297 DEALLOCATE(zd)
298 !-------------------------------------------------------------------------------------
299 !
300 !* 4. Temperature of new snow
301 ! -----------------------
302 !
303 ALLOCATE(zt(SIZE(tpsnow%WSNOW,1),SIZE(tpsnow%WSNOW,2),SIZE(tpsnow%WSNOW,3)))
304 !
305 SELECT CASE(tpsnow%SCHEME)
306  CASE('1-L')
307  zt(:,:,:) = tpsnow%T (:,:,:)
308  CASE('3-L','CRO')
309  CALL snow_heat_to_t_wliq(tpsnow%HEAT,tpsnow%RHO,zt)
310 END SELECT
311 !
312 !* new snow is set to deep ground temperature
313 !
314 DO jlayer=1,tpsnow%NLAYER
315 !
316  gwork(:,jlayer)=.false.
317 !
318  IF(i%LGLACIER)THEN
319  WHERE(zwsnow_perm(:)>0.)gwork(:,jlayer)=.true.
320  ELSE
321  WHERE(zwsnow_perm(:)>0. .AND. zwsnow(:)==0)gwork(:,jlayer)=.true.
322  ENDIF
323 !
324  WHERE(gwork(:,jlayer))
325  zt(:,jlayer,ksnow) = min(ptg(:,SIZE(ptg,2)),xtt)
326  END WHERE
327 !
328 END DO
329 !
330 !
331 SELECT CASE(tpsnow%SCHEME)
332  CASE('1-L')
333  tpsnow%T (:,:,:) = zt(:,:,:)
334  CASE('3-L','CRO')
335  CALL snow_t_wliq_to_heat(tpsnow%HEAT,tpsnow%RHO,zt)
336 END SELECT
337 !
338 DEALLOCATE(zt )
339 DEALLOCATE(gwork)
340 !
341 !
342 !-------------------------------------------------------------------------------------
343 !
344 !* 5. Soil ice initialization for LGLACIER
345 ! -----------------------
346 !
347 ALLOCATE(zwat(SIZE(ptg,1),SIZE(ptg,2)))
348 !
349 IF(i%LGLACIER)THEN
350 !
351  IF (i%CISBA == 'DIF') THEN
352  iwork=i%NGROUND_LAYER
353  zwat(:,:)=i%XWFC(:,:)
354  ELSE
355  iwork=2
356  zwat(:,:)=i%XWSAT(:,:)
357  ENDIF
358 !
359  DO jlayer=1,iwork
360  WHERE(pperm_snow_frac(:,nvt_snow)>0.0)
361  i%XWGI(:,jlayer,ksnow) = max(i%XWGI(:,jlayer,ksnow),zwat(:,jlayer)*zpsn(:))
362  i%XWG (:,jlayer,ksnow) = min(i%XWG (:,jlayer,ksnow),max(i%XWSAT(:,jlayer)-i%XWGI(:,jlayer,ksnow),xwgmin))
363  END WHERE
364  WHERE(i%XWG(:,jlayer,ksnow) /= xundef .AND. (i%XWG(:,jlayer,ksnow) + i%XWGI(:,jlayer,ksnow)) > i%XWSAT(:,jlayer) )
365  i%XWGI(:,jlayer,ksnow) = i%XWSAT(:,jlayer)-i%XWG (:,jlayer,ksnow) !WGT<=WSAT
366  END WHERE
367  ENDDO
368 !
369 ENDIF
370 !
371 DEALLOCATE(zwat)
372 DEALLOCATE(zpsn)
373 !
374 !-------------------------------------------------------------------------------------
375 !
376 !* 6. Masking where there is no snow
377 ! ------------------------------
378 !
379  CALL mkflag_snow(tpsnow)
380 IF (lhook) CALL dr_hook('PREP_PERM_SNOW',1,zhook_handle)
381 !
382 !-------------------------------------------------------------------------------------
383 !
384 END SUBROUTINE prep_perm_snow
subroutine mkflag_snow(TPSNOW)
Definition: mkflag_snow.F90:6
real function, dimension(size(ppsng)) wsnow_from_snow_frac_ground(PPSNG)
subroutine prep_perm_snow(I, TPSNOW, PTG, PPERM_SNOW_FRAC, KSNOW)