SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
mode_hydro_dif.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 ! ######spl
6  MODULE mode_hydro_dif
7 ! ################
8 !
9 !!**** *MODE_HYDRO_DIF * - pedo-transfert functions
10 !!
11 !! PURPOSE
12 !! -------
13 !
14 !!** METHOD
15 !! ------
16 !!
17 !!
18 !! EXTERNAL
19 !! --------
20 !!
21 !! IMPLICIT ARGUMENTS
22 !! ------------------
23 !!
24 !! REFERENCE
25 !! ---------
26 !!
27 !!
28 !! AUTHOR
29 !! ------
30 !! B. Decharme * Meteo France *
31 !!
32 !! MODIFICATIONS
33 !! -------------
34 !! Original 11/2010
35 !-----------------------------------------------------------------------------
36 !
37 !* 0. DECLARATIONS
38 !
39 !
40 INTERFACE vapcondcf
41  MODULE PROCEDURE vapcondcf
42 END INTERFACE
43 !
44 INTERFACE infmax_func
45  MODULE PROCEDURE infmax_func
46 END INTERFACE
47 !
48 INTERFACE tridiag_dif
49  MODULE PROCEDURE tridiag_dif
50 END INTERFACE
51 !
52 !-------------------------------------------------------------------------------
53  CONTAINS
54 !-------------------------------------------------------------------------------
55 !
56 !-------------------------------------------------------------------------------
57 !vapor conductivity (m s-1)
58 !-------------------------------------------------------------------------------
59 !
60 FUNCTION vapcondcf(PTG,PPS,PWG,PWGI,PPSIA,PWSAT,PWFC,PQSAT,PQSATI,KWG_LAYER,KNL) RESULT(PVAPCOND)
61 !
62 ! Uses method of Braud et al. (1993) for
63 !
64 USE modd_csts, ONLY : xmv, xmd, xtt, xp00, xg, xrv, xrholw
65 USE modd_isba_par, ONLY : xwgmin
66 USE modd_surf_par, ONLY : xundef
67 USE yomhook ,ONLY : lhook, dr_hook
68 USE parkind1 ,ONLY : jprb
69 !
70 IMPLICIT NONE
71 !
72 !
73 !* 0.1 declarations of arguments
74 !
75 REAL, DIMENSION(: ), INTENT(IN) :: pps
76 REAL, DIMENSION(:,:), INTENT(IN) :: pwg,pwgi,ppsia,pwsat, &
77  pwfc,ptg,pqsat,pqsati
78 INTEGER, DIMENSION(:), INTENT(IN) :: kwg_layer !Moisture layer
79 INTEGER, INTENT(IN) :: knl ! number of vertical levels
80 !
81 REAL, DIMENSION(SIZE(PWG,1),SIZE(PWG,2)) :: pvapcond
82 !
83 !
84 !* 0.2 declarations of local variables
85 !
86 REAL :: zdva, zfva, zchi, zhum, zwork, &
87  zpv, zesat, zesati, zwg, zvc
88 !
89 INTEGER :: ini, jj, jl, idepth
90 !
91 ! Parameters:
92 !
93 REAL, PARAMETER :: ztorty = 0.66 ! (-)
94 REAL, PARAMETER :: znv = 1.88 ! (-)
95 REAL, PARAMETER :: zcv = 2.17e-5 ! (m2/s)
96 REAL, PARAMETER :: zwk = 0.05 ! (m3 m-3)
97 REAL, PARAMETER :: zlim = tiny(1.0)
98 !
99 REAL(KIND=JPRB) :: zhook_handle
100 !-------------------------------------------------------------------------------
101 !
102 IF (lhook) CALL dr_hook('MODE_HYDRO_DIF:VAPCONDCF',0,zhook_handle)
103 !
104 ini = SIZE(pwg,1)
105 !
106 pvapcond(:,:) = 0.0
107 !
108 ! Only perform this computation if the soil is sufficiently
109 ! dry (as otherwise the hydraulic conductivity dominates
110 ! the diffusion coefficient). Arbitrarily base threshold on field
111 ! capacity water content:
112 !
113 DO jl=1,knl
114  DO jj=1,ini
115 !
116  idepth = kwg_layer(jj)
117  zwg = pwg(jj,jl) + pwgi(jj,jl)
118 !
119  IF(jl<=idepth .AND. zwg < pwfc(jj,jl) .AND. zwg > xwgmin)THEN
120 !
121 ! Vapor pressure over liquid and solid water surfaces (Pa), respectively:
122 !
123  zesat = pqsat(jj,jl)* pps(jj)/((xmv/xmd)+pqsat(jj,jl) *(1.-(xmv/xmd)))
124 !
125  zesati = pqsati(jj,jl)*pps(jj)/((xmv/xmd)+pqsati(jj,jl)*(1.-(xmv/xmd)))
126 !
127 ! molecular diffusivity of water vapor (m2 s-1):
128 !
129  zwork = znv*log(ptg(jj,jl)/xtt)
130  zdva = zcv*(xp00/pps(jj))*exp(zwork)
131 !
132 ! function of pore space:
133 !
134  zfva = (pwsat(jj,jl) - zwg)*(1.+(zwg/(pwsat(jj,jl)-zwk)))
135  zfva = min(zfva,pwsat(jj,jl))
136 !
137 ! relative humidity of air in soil pores:
138 !
139  zhum = max(zlim,exp(ppsia(jj,jl)*xg/(xrv*ptg(jj,jl))))
140 !
141 ! fraction of frozen water:
142 !
143  zchi = pwgi(jj,jl)/zwg
144 !
145 ! vapor pressure within pore space (Pa):
146 !
147  zpv = zhum*(zchi*zesat + (1.-zchi)*zesati)
148 !
149 ! vapor conductivity (kg m-2 s-1)
150 !
151  zvc = ztorty*pps(jj)*zdva*zfva*xg*zpv/ &
152  ((pps(jj)-zpv)*(xrv*xrv*ptg(jj,jl)*ptg(jj,jl)))
153 !
154 ! vapor conductivity (m s-1)
155 !
156  pvapcond(jj,jl) = zvc/xrholw
157 !
158  ENDIF
159 !
160  ENDDO
161 ENDDO
162 !
163 IF (lhook) CALL dr_hook('MODE_HYDRO_DIF:VAPCONDCF',1,zhook_handle)
164 !
165 END FUNCTION vapcondcf
166 !
167 !-------------------------------------------------------------------------------
168 !Green-Ampt approximation (derived form) for maximum infiltration
169 !-------------------------------------------------------------------------------
170 !
171 FUNCTION infmax_func(PWG,PWSAT,PFRZ,PCONDSAT,PMPOTSAT,PBCOEF,PDZG,PDG,KLAYER_HORT)
172 USE yomhook ,ONLY : lhook, dr_hook
173 USE modd_sgh_par, ONLY : xhort_depth
174 USE parkind1 ,ONLY : jprb
175 IMPLICIT NONE
176 REAL, DIMENSION(:,:), INTENT(IN) :: pwg
177 REAL, DIMENSION(:,:), INTENT(IN) :: pwsat
178 REAL, DIMENSION(:,:), INTENT(IN) :: pfrz
179 REAL, DIMENSION(:,:), INTENT(IN) :: pcondsat
180 REAL, DIMENSION(:,:), INTENT(IN) :: pmpotsat
181 REAL, DIMENSION(:,:), INTENT(IN) :: pbcoef
182 REAL, DIMENSION(:,:), INTENT(IN) :: pdzg
183 REAL, DIMENSION(:,:), INTENT(IN) :: pdg
184 INTEGER, INTENT(IN) :: klayer_hort
185 !
186 REAL, DIMENSION(SIZE(PWG,1)) :: zgreen_ampt, zdepth
187 REAL :: zs, zcoef
188 INTEGER :: jj,jl,ini
189 !
190 REAL, DIMENSION(SIZE(PWG,1)) :: infmax_func
191 !
192 REAL(KIND=JPRB) :: zhook_handle
193 !
194 IF (lhook) CALL dr_hook('MODE_HYDRO_DIF:INFMAX_FUNC',0,zhook_handle)
195 !
196 ini =SIZE(pwg,1)
197 !
198 zgreen_ampt(:) = 0.0
199 zdepth(:) = 0.0
200 !
201 DO jl=1,klayer_hort
202  DO jj=1,ini
203  IF(zdepth(jj)<xhort_depth)THEN
204  zs = min(1.0,pwg(jj,jl)/pwsat(jj,jl))
205  zcoef = pbcoef(jj,jl)*pmpotsat(jj,jl)*(zs-1.0)/pdzg(jj,jl)
206  zgreen_ampt(jj) = zgreen_ampt(jj)+pdzg(jj,jl)*pfrz(jj,jl)*pcondsat(jj,jl)*(zcoef+1.0)
207  zdepth(jj) = pdg(jj,jl)
208  ENDIF
209  ENDDO
210 ENDDO
211 !
212 infmax_func(:) = zgreen_ampt(:)/zdepth(:)
213 !
214 IF (lhook) CALL dr_hook('MODE_HYDRO_DIF:INFMAX_FUNC',1,zhook_handle)
215 END FUNCTION infmax_func
216 !
217 !-------------------------------------------------------------------------------
218 !Solve tridiagonal matrix (for method see tridiag_ground.F90)
219 !-------------------------------------------------------------------------------
220 !
221 SUBROUTINE tridiag_dif(PAMTRX,PBMTRX,PCMTRX,PFRC,KWG_LAYER,KNL,PSOL)
222 USE modd_surf_par, ONLY : xundef
223 USE yomhook ,ONLY : lhook, dr_hook
224 USE parkind1 ,ONLY : jprb
225 IMPLICIT NONE
226 REAL, DIMENSION(:,:), INTENT(IN) :: pamtrx ! lower diag. elements of A matrix
227 REAL, DIMENSION(:,:), INTENT(IN) :: pbmtrx ! main diag. elements of A matrix
228 REAL, DIMENSION(:,:), INTENT(IN) :: pcmtrx ! upper diag. elements of A matrix
229 REAL, DIMENSION(:,:), INTENT(IN) :: pfrc ! Forcing term
230 INTEGER, DIMENSION(:), INTENT(IN) :: kwg_layer !Moisture layer
231 INTEGER, INTENT(IN) :: knl ! number of vertical levels
232 REAL, DIMENSION(:,:), INTENT(OUT) :: psol ! solution of A.SOL = FRC
233 !
234 REAL, DIMENSION(SIZE(PFRC,1),SIZE(PFRC,2)) :: zwork! work array
235 REAL, DIMENSION(SIZE(PFRC,1)) :: zdet ! work array
236 INTEGER :: jl ! vertical loop control
237 INTEGER :: jj, ini, idepth
238 !
239 REAL(KIND=JPRB) :: zhook_handle
240 !
241 IF (lhook) CALL dr_hook('MODE_HYDRO_DIF:TRIDIAG_DIF',0,zhook_handle)
242 !
243 ini=SIZE(pfrc,1)
244 !
245 psol(:,:)=xundef
246 zwork(:,:)=xundef
247 !
248 !first level
249 zdet(:) = pbmtrx(:,1)
250 psol(:,1) = pfrc(:,1) / zdet(:)
251 !
252 !other levels
253 DO jl=2,knl
254  DO jj=1,ini
255  idepth=kwg_layer(jj)
256  IF(jl<=idepth)THEN
257  zwork(jj,jl) = pcmtrx(jj,jl-1)/zdet(jj)
258  zdet(jj) = pbmtrx(jj,jl) - pamtrx(jj,jl)*zwork(jj,jl)
259  psol(jj,jl) = (pfrc(jj,jl) - pamtrx(jj,jl)*psol(jj,jl-1))/zdet(jj)
260  ENDIF
261  ENDDO
262 ENDDO
263 !
264 !levels going down
265 DO jl=knl-1,1,-1
266  DO jj=1,ini
267  idepth=kwg_layer(jj)
268  IF(jl<idepth)THEN
269  psol(jj,jl) = psol(jj,jl)-zwork(jj,jl+1)*psol(jj,jl+1)
270  ENDIF
271  ENDDO
272 ENDDO
273 !
274 IF (lhook) CALL dr_hook('MODE_HYDRO_DIF:TRIDIAG_DIF',1,zhook_handle)
275 !
276 END SUBROUTINE tridiag_dif
277 !
278 !-------------------------------------------------------------------------------
279 !
280 END MODULE mode_hydro_dif