SURFEX v8.1
General documentation of Surfex
prep_ver_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_ver_snow(TPSNOW,PZS_LS,PZS,PTG_LS,PTG,KDEEP_SOIL)
7 ! ###########################################
8 !
9 !
10 !!**** *PREP_VER_SNOW* - change in snow variables due to altitude change
11 !!
12 !! PURPOSE
13 !! -------
14 !
15 !!** METHOD
16 !! ------
17 !!
18 !! REFERENCE
19 !! ---------
20 !!
21 !!
22 !! AUTHOR
23 !! ------
24 !! V. Masson
25 !!
26 !! MODIFICATIONS
27 !! -------------
28 !! Original 01/2004
29 !! 02/2014 E. Martin, vertical correction applied to snow cover and not by layers
30 !! 09/2014 B. Decharme, Bug : Coherence between snow layer and depth
31 !!------------------------------------------------------------------
32 !
33 
35 USE modd_csts, ONLY : xtt
36 USE modd_prep, ONLY : xt_clim_grad
38 USE modd_surf_par, ONLY : xundef
39 !
42 USE modi_mkflag_snow
43 !
44 USE mode_snow3l
45 !
46 USE yomhook ,ONLY : lhook, dr_hook
47 USE parkind1 ,ONLY : jprb
48 !
49 IMPLICIT NONE
50 !
51 !* 0.1 declarations of arguments
52 !
53 TYPE(surf_snow), INTENT(INOUT) :: TPSNOW ! snow mantel characteristics
54 REAL, DIMENSION(:), INTENT(IN) :: PZS_LS ! initial orography
55 REAL, DIMENSION(:), INTENT(IN) :: PZS ! final orography
56 REAL, DIMENSION(:,:),INTENT(IN),OPTIONAL:: PTG_LS ! soil temperature on initial orography
57 REAL, DIMENSION(:,:),INTENT(IN),OPTIONAL:: PTG ! soil temperature on final orography
58 INTEGER, INTENT(IN),OPTIONAL:: KDEEP_SOIL ! index of deep soil temperature
59 !
60 !* 0.2 declarations of local variables
61 !
62 REAL, DIMENSION(:,:), ALLOCATABLE :: ZWSNOW_LS ! snow reservoir on initial orography
63 REAL, DIMENSION(:,:), ALLOCATABLE :: ZTSNOW_LS ! snow temperature on initial orography
64 REAL, DIMENSION(:,:), ALLOCATABLE :: ZWSNOW ! snow content on final orography
65 REAL, DIMENSION(:,:), ALLOCATABLE :: ZTSNOW ! snow temperature on final orography
66 REAL, DIMENSION(:,:), ALLOCATABLE :: ZWSNOW2 ! snow content on final orography
67 REAL, DIMENSION(:,:), ALLOCATABLE :: ZTSNOW2 ! snow temperature on final orography
68 REAL, DIMENSION(:,:), ALLOCATABLE :: ZWLIQ ! snow liquid water content
69 REAL, DIMENSION(:), ALLOCATABLE :: ZZSFREEZE ! altitude where deep soil freezes
70 REAL, DIMENSION(:), ALLOCATABLE :: ZDTOT ! snow depth
71 REAL, DIMENSION(:,:), ALLOCATABLE :: ZDZSN ! snow layer thickness
72 !
73 INTEGER :: JL ! loop counter on snow layers
74 !
75 REAL(KIND=JPRB) :: ZHOOK_HANDLE
76 !
77 !-------------------------------------------------------------------------------------
78 !
79 IF (lhook) CALL dr_hook('PREP_VER_SNOW',0,zhook_handle)
80 !
81 !* 1. Snow reservoir on initial orography
82 ! -----------------------------------
83 !
84 ALLOCATE(zwsnow_ls(SIZE(tpsnow%WSNOW,1),SIZE(tpsnow%WSNOW,2)))
85 zwsnow_ls(:,:) = tpsnow%WSNOW(:,:)
86 !
87 !-------------------------------------------------------------------------------------
88 !
89 !* 2. temperature of snow on initial orography
90 ! ----------------------------------------
91 !
92 ALLOCATE(ztsnow_ls(SIZE(tpsnow%WSNOW,1),SIZE(tpsnow%WSNOW,2)))
93 SELECT CASE(tpsnow%SCHEME)
94  CASE ('D95','EBA')
95  IF (PRESENT(ptg_ls)) THEN
96  ztsnow_ls(:,1) = min(ptg_ls(:,1),xtt)
97  ELSE
98  ztsnow_ls = xundef
99  END IF
100  CASE ('1-L')
101  ztsnow_ls(:,:) = tpsnow%T(:,:)
102  CASE ('3-L','CRO')
103  CALL snow_heat_to_t_wliq(tpsnow%HEAT(:,:),tpsnow%RHO(:,:),ztsnow_ls(:,:))
104 END SELECT
105 !
106 !-------------------------------------------------------------------------------------
107 !
108 !* 3. vertical shift of temperature
109 ! -----------------------------
110 !
111 ALLOCATE(ztsnow(SIZE(tpsnow%WSNOW,1),SIZE(tpsnow%WSNOW,2)))
112 DO jl=1,tpsnow%NLAYER
113  ztsnow(:,jl) = ztsnow_ls(:,jl) + xt_clim_grad * (pzs(:) - pzs_ls(:))
114 END DO
115 !
116 !-------------------------------------------------------------------------------------
117 !
118 !* 4. vertical shift of snow content where snow already exists
119 ! ------------------------------
120 !
121 !* use of climatological snow content gradient
122 !
123 ALLOCATE(zwsnow(SIZE(tpsnow%WSNOW,1),SIZE(tpsnow%WSNOW,2)))
124 !
125 zwsnow(:,:) = zwsnow_ls(:,:)
126 !
127 IF (PRESENT(ptg)) THEN
128  DO jl=1,tpsnow%NLAYER
129  WHERE(zwsnow_ls(:,jl)>0..AND.((ptg(:,kdeep_soil)-xtt >= 2.).OR.(pzs(:) > pzs_ls(:))))
130  zwsnow(:,jl) = zwsnow_ls(:,jl) + ( xwsnow_clim_grad * (pzs(:) - pzs_ls(:))/tpsnow%NLAYER)
131  zwsnow(:,jl) = max(zwsnow(:,jl),0.)
132  END WHERE
133  END DO
134 ELSE
135  DO jl=1,tpsnow%NLAYER
136  WHERE(zwsnow_ls(:,jl)>0.)
137  zwsnow(:,jl) = zwsnow_ls(:,jl) + ( xwsnow_clim_grad * (pzs(:) - pzs_ls(:))/tpsnow%NLAYER)
138  zwsnow(:,jl) = max(zwsnow(:,jl),0.)
139  END WHERE
140  END DO
141 ENDIF
142 !
143 WHERE(tpsnow%WSNOW(:,:)/=xundef) tpsnow%WSNOW = zwsnow
144 !
145 !-------------------------------------------------------------------------------------
146 !
147 ! 5. Where snow did not exist on initial orography
148 ! ---------------------------------------------
149 !
150 !* in this case, new snow can appear only if orography differences in larger
151 ! than 1000m, and starts at an altitude where the deep soil temperature becomes negative
152 !
153 !* the same climatological gradient is used, but the value zero for the snow
154 ! content is defined as the altitude where deep soil freezes.
155 !
156 !* 5.1 Altitude where deep soil freezes (only if soil temperatures are provided)
157 ! --------------------------------
158 !
159 IF (PRESENT(ptg)) THEN
160 
161  ALLOCATE(zzsfreeze(SIZE(tpsnow%WSNOW,1)))
162  zzsfreeze(:) = pzs + (xtt - ptg(:,kdeep_soil)) / xt_clim_grad
163 !
164 !* 5.2 Amount and Temperature of new snow (only if soil temperatures are provided)
165 ! ----------------------------------
166 !
167 !* Snow temperature is then defined as the deep soil temperature at the final
168 ! altitude.
169 !
170  ALLOCATE(zwsnow2(SIZE(tpsnow%WSNOW,1),tpsnow%NLAYER))
171  ALLOCATE(ztsnow2(SIZE(tpsnow%WSNOW,1),tpsnow%NLAYER))
172  DO jl=1,tpsnow%NLAYER
173  zwsnow2(:,jl) = xwsnow_clim_grad * (pzs(:) - zzsfreeze(:))/tpsnow%NLAYER
174  zwsnow2(:,jl) = max(zwsnow2(:,jl),0.)
175  ztsnow2(:,jl) = ptg(:,kdeep_soil)
176  END DO
177 !
178 !* 5.3 Apply maximum between this value and the shifted one
179 ! ----------------------------------------------------
180 !
181  DO jl=1,tpsnow%NLAYER
182  WHERE(tpsnow%WSNOW(:,jl)/=xundef .AND. zwsnow_ls(:,jl)==0. .AND. (pzs(:)-pzs_ls(:))>1000. )
183  tpsnow%WSNOW(:,jl) = zwsnow2(:,jl)
184  ztsnow(:,jl) = ztsnow2(:,jl)
185  END WHERE
186  END DO
187 
188  DEALLOCATE(zzsfreeze)
189  DEALLOCATE(zwsnow2 )
190  DEALLOCATE(ztsnow2 )
191 END IF
192 !
193 !-------------------------------------------------------------------------------------
194 !
195 !* 6.1 Coherence between temperature and snow content
196 ! ----------------------------------------------
197 !
198 SELECT CASE(tpsnow%SCHEME)
199  CASE('1-L')
200  !* snow temperature cannot be larger than 0 C
201  tpsnow%T (:,:) = min( ztsnow(:,:), xtt )
202  CASE('3-L','CRO')
203  ALLOCATE(zwliq(SIZE(tpsnow%WSNOW,1),SIZE(tpsnow%WSNOW,2)))
204  CALL snow_t_wliq_to_heat(tpsnow%HEAT,tpsnow%RHO,ztsnow)
205  CALL snow_heat_to_t_wliq(tpsnow%HEAT,tpsnow%RHO,ztsnow,zwliq)
206  CALL snow_t_wliq_to_heat(tpsnow%HEAT,tpsnow%RHO,ztsnow,zwliq)
207  DEALLOCATE(zwliq)
208 END SELECT
209 !
210 !* 6.2 Coherence between snow layer and depth
211 ! --------------------------------------
212 !
213 SELECT CASE(tpsnow%SCHEME)
214  CASE('3-L','CRO')
215  ALLOCATE(zdtot(SIZE(tpsnow%WSNOW,1)))
216  ALLOCATE(zdzsn(SIZE(tpsnow%WSNOW,1),SIZE(tpsnow%WSNOW,2)))
217  zdtot(:)=0.0
218  DO jl=1,tpsnow%NLAYER
219  WHERE(tpsnow%WSNOW(:,jl)/=xundef.AND.tpsnow%RHO(:,jl)/=xundef)
220  zdtot(:)=zdtot(:)+tpsnow%WSNOW(:,jl)/tpsnow%RHO(:,jl)
221  ENDWHERE
222  END DO
223  CALL snow3lgrid(zdzsn(:,:),zdtot(:))
224  DO jl=1,tpsnow%NLAYER
225  WHERE(tpsnow%RHO(:,jl)/=xundef.AND.zdtot(:)>0.)
226  tpsnow%WSNOW(:,jl) = tpsnow%RHO(:,jl) * zdzsn(:,jl)
227  ELSEWHERE(tpsnow%RHO(:,jl)==xundef.OR.zdtot(:)==0.0)
228  tpsnow%WSNOW(:,jl) = 0.0
229  ELSEWHERE
230  tpsnow%WSNOW(:,jl) = xundef
231  END WHERE
232  END DO
233  DEALLOCATE(zdtot)
234  DEALLOCATE(zdzsn)
235 END SELECT
236 !
237 !-------------------------------------------------------------------------------------
238 !
239 !* 7. Masking where there is no snow
240 ! ------------------------------
241 !
242  CALL mkflag_snow(tpsnow)
243 !
244 !-------------------------------------------------------------------------------------
245 DEALLOCATE(zwsnow_ls)
246 DEALLOCATE(ztsnow_ls)
247 DEALLOCATE(zwsnow )
248 DEALLOCATE(ztsnow )
249 IF (lhook) CALL dr_hook('PREP_VER_SNOW',1,zhook_handle)
250 !-------------------------------------------------------------------------------------
251 !
252 END SUBROUTINE prep_ver_snow
subroutine prep_ver_snow(TPSNOW, PZS_LS, PZS, PTG_LS, PTG, KDEEP_SOIL)
real, parameter xundef
integer, parameter jprb
Definition: parkind1.F90:32
subroutine mkflag_snow(TPSNOW)
Definition: mkflag_snow.F90:7
logical lhook
Definition: yomhook.F90:15
real, parameter xt_clim_grad
Definition: modd_prep.F90:53
real, save xtt
Definition: modd_csts.F90:66
real, parameter xwsnow_clim_grad