SUEWS API Site
Documentation of SUEWS source code
suews_phys_evap.f95
Go to the documentation of this file.
2 IMPLICIT NONE
3
4CONTAINS
5 SUBROUTINE cal_evap( &
6 EvapMethod, state_is, WetThresh_is, capStore_is, & !input
7 vpd_hPa, avdens, avcp, qn_e, s_hPa, psyc_hPa, RS, RA, RB, tlv, &
8 RSS, ev, qe) !output
9 !------------------------------------------------------------------------------
10 !-Calculates evaporation for each surface from modified Penman-Monteith eqn
11 !-State determines whether each surface type is dry or wet (wet/transition)
12 !-Wet surfaces below storage capacity are in transition
13 ! and QE depends on the state and storage capacity (i.e. varies with surface);
14 ! for wet or dry surfaces QE does not vary between surface types
15 !-See Sect 2.4 of Jarvi et al. (2011) Ja11
16 !
17 !Last modified:
18 ! HCW 06 Jul 2016
19 ! Moved rss declaration to LUMPS_Module_Constants so it can be written out
20 ! HCW 11 Jun 2015
21 ! Added WetThresh to distinguish wet/partially wet surfaces from the storage capacities used in SUEWS_drain
22 ! HCW 30 Jan 2015
23 ! Removed StorCap input because it is provided by module allocateArray
24 ! Tidied and commented code
25 ! LJ 10/2010
26 !------------------------------------------------------------------------------
27
28 IMPLICIT NONE
29 INTEGER, INTENT(in) :: EvapMethod !Evaporation calculated according to Rutter (1) or Shuttleworth (2)
30
31 REAL(KIND(1D0)), INTENT(in) :: state_is ! wetness status
32 REAL(KIND(1D0)), INTENT(in) :: WetThresh_is !When State > WetThresh, RS=0 limit in SUEWS_evap [mm] (specified in input files)
33 REAL(KIND(1D0)), INTENT(in) :: capStore_is ! = StoreDrainPrm(6,is), current storage capacity [mm]
34
35 REAL(KIND(1D0)), INTENT(in) :: vpd_hPa ! vapour pressure deficit [hPa]
36 REAL(KIND(1D0)), INTENT(in) :: avdens ! air density
37 REAL(KIND(1D0)), INTENT(in) :: avcp ! air heat capacity
38 REAL(KIND(1D0)), INTENT(in) :: qn_e !net available energy for evaporation
39 REAL(KIND(1D0)), INTENT(in) :: s_hPa !Vapour pressure versus temperature slope in hPa
40 REAL(KIND(1D0)), INTENT(in) :: psyc_hPa !Psychometric constant in hPa
41 REAL(KIND(1D0)), INTENT(in) :: RS !Surface resistance
42 ! REAL(KIND(1d0)),INTENT(in)::sp!Term in calculation of E
43 REAL(KIND(1D0)), INTENT(in) :: RA !Aerodynamic resistance
44 REAL(KIND(1D0)), INTENT(in) :: RB !Boundary layer resistance
45 REAL(KIND(1D0)), INTENT(in) :: tlv !Latent heat of vaporization per timestep [J kg-1 s-1], (tlv=lv_J_kg/tstep_real)
46
47 REAL(KIND(1D0)), INTENT(out) :: RSS !Redefined surface resistance for wet
48 REAL(KIND(1D0)), INTENT(out) :: ev ! evapotranspiration [mm]
49 REAL(KIND(1D0)), INTENT(out) :: qe ! latent heat flux [W m-2]
50
51 REAL(KIND(1D0)) :: numPM !numerator of P-M eqn
52 REAL(KIND(1D0)) :: RB_SG !Boundary-layer resistance x (slope/psychrometric const + 1) [s m-1]
53 REAL(KIND(1D0)) :: rsrbsg !RS + rbsg [s m-1]
54 REAL(KIND(1D0)) :: flag_dry
55 REAL(KIND(1D0)) :: W !Depends on the amount of water on the canopy [-]
56 REAL(KIND(1D0)) :: x
57 REAL(KIND(1D0)) :: r
58
59 REAL(KIND(1D0)), PARAMETER :: NAN = -999
60
61 ! Use Penman-Monteith eqn modified for urban areas (Eq6, Jarvi et al. 2011)
62 ! Calculation independent of surface characteristics
63 ! Uses value of RS for whole area (calculated based on LAI of veg surfaces in SUEWS_SurfaceResistance.f95)
64
65 !numerator of P-M eqn, refer to Eq6, Jarvi et al. 2011
66 numpm = s_hpa*qn_e + vpd_hpa*avdens*avcp/ra !s_haPa - slope of svp vs t curve.
67
68 IF (state_is <= 0.001) THEN
69 ! Dry surface ---------------------------------------------------------------
70 qe = numpm/(s_hpa + psyc_hpa*(1 + rs/ra)) !QE [W m-2] (numPM = numerator of P-M eqn)
71 ev = qe/tlv !Ev [mm] (qe[W m-2]/tlv[J kg-1 s-1]*1/density_water[1000 kg m-3])
72 w = nan !W not needed for dry surfaces (set to -999)
73 flag_dry = 1 !Set flag indicating dry surface(1)
74 rss = rs
75
76 ELSE
77 ! Wet surface ---------------------------------------------------------------
78 flag_dry = 0 !Set flag=0 indicating wet surface(0)
79
80 ! Evaporation calculated according to Rutter(EvapMethod=1) or Shuttleworth(EvapMethod=2).
81 !Set in SUEWS_initial (so not an input to the model)
82 IF (evapmethod == 2) THEN !-- Shuttleworth (1978): https://doi.org/10.1007/bf00123986 --
83 rb_sg = rb*(s_hpa/psyc_hpa + 1) !Boundary-layer resistance x (slope/psychro + 1)
84 rsrbsg = rs + rb_sg !RS + rsbg
85
86 ! If surface is completely wet, set RS to zero -------------------
87 !if(state(is)>=StoreDrainPrm(6,is).or.ResistSurf<25) then !If at storage capacity or RS is small
88 IF (state_is >= wetthresh_is .OR. rs < 25) THEN !If at storage capacity or RS is small
89 w = 1 !So that RS=0 (Eq7, Jarvi et al. 2011)
90 ! If surface is in transition, use rss ---------------------------
91 ELSE !if((state(is)<StorCap).and.(state(is)>0.001).or.(ResistSurf<50)) then
92 r = (rs/ra)*(ra - rb)/rsrbsg
93 w = (r - 1)/(r - (wetthresh_is/state_is))
94 END IF
95
96 ! PRINT*, 'r',r
97 ! PRINT*, 'W',W
98
99 rss = (1/((w/rb_sg) + ((1 - w)/rsrbsg))) - rb_sg !Redefined surface resistance for wet
100 ! PRINT*, 'resistances:',rbsg,rsrbsg,rss
101 !surfaces (zero if W=1). Eq7, Jarvi et al. (2011)
102 qe = numpm/(s_hpa + psyc_hpa*(1 + rss/ra)) !QE [W m-2]
103 ev = qe/tlv !Ev [mm]
104 ! PRINT*, 'numPM',numPM
105 ! PRINT*, 'qe',qe
106
107 ELSEIF (evapmethod == 1) THEN !-- Rutter --
108 qe = numpm/(s_hpa + psyc_hpa)
109 ev = qe/tlv
110
111 x = merge(1d0, state_is/capstore_is, state_is > capstore_is)
112 ev = ev*x !QE [W m-2]
113 qe = ev*tlv !Ev [mm]
114 END IF !Rutter/Shuttleworth calculation
115 END IF !Wet/dry surface
116
117 END SUBROUTINE cal_evap
118
119 SUBROUTINE cal_evap_multi( &
120 EvapMethod, & !input
121 sfr_multi, state_multi, WetThresh_multi, capStore_multi, & !input
122 vpd_hPa, avdens, avcp, qn_e_multi, s_hPa, psyc_hPa, RS, RA, RB, tlv, &
123 RSS_multi, ev_multi, qe_multi) !output
124 IMPLICIT NONE
125 INTEGER, INTENT(in) :: EvapMethod !Evaporation calculated according to Rutter (1) or Shuttleworth (2)
126
127 REAL(KIND(1D0)), DIMENSION(:), INTENT(in) :: sfr_multi ! facet fraction of surface
128 REAL(KIND(1D0)), DIMENSION(:), INTENT(in) :: state_multi ! wetness status
129 REAL(KIND(1D0)), DIMENSION(:), INTENT(in) :: WetThresh_multi !When State > WetThresh, RS=0 limit in SUEWS_evap [mm] (specified in input files)
130 REAL(KIND(1D0)), DIMENSION(:), INTENT(in) :: capStore_multi ! = StoreDrainPrm(6,is), current storage capacity [mm]
131 REAL(KIND(1D0)), DIMENSION(:), INTENT(in) :: qn_e_multi !net available energy for evaporation [W m-2]
132
133 REAL(KIND(1D0)), INTENT(in) :: vpd_hPa ! vapour pressure deficit [hPa]
134 REAL(KIND(1D0)), INTENT(in) :: avdens ! air density [kg m-3]
135 REAL(KIND(1D0)), INTENT(in) :: avcp ! air heat capacity [J kg-1 K-1]
136 REAL(KIND(1D0)), INTENT(in) :: s_hPa !Vapour pressure versus temperature slope [hPa K-1]]
137 REAL(KIND(1D0)), INTENT(in) :: psyc_hPa !Psychometric constant [hPa]
138 REAL(KIND(1D0)), INTENT(in) :: RS !Surface resistance [s m-1]
139 REAL(KIND(1D0)), INTENT(in) :: RA !Aerodynamic resistance [s m-1]
140 REAL(KIND(1D0)), INTENT(in) :: RB !Boundary layer resistance [s m-1]
141 REAL(KIND(1D0)), INTENT(in) :: tlv !Latent heat of vaporization per timestep [J kg-1 s-1], (tlv=lv_J_kg/tstep_real)
142
143 REAL(KIND(1D0)), DIMENSION(:), INTENT(out) :: RSS_multi !Redefined surface resistance for wet surfaces [s m-1]
144 REAL(KIND(1D0)), DIMENSION(:), INTENT(out) :: ev_multi ! evapotranspiration [mm]
145 REAL(KIND(1D0)), DIMENSION(:), INTENT(out) :: qe_multi ! latent heat flux [W m-2]
146 ! REAL(KIND(1D0)), INTENT(out) :: qe_total ! latent heat flux [W m-2]
147
148 ! REAL(KIND(1D0)) :: numPM !numerator of P-M eqn
149 ! REAL(KIND(1D0)) :: RB_SG !Boundary-layer resistance x (slope/psychrometric const + 1) [s m-1]
150 ! REAL(KIND(1D0)) :: rsrbsg !RS + rbsg [s m-1]
151 ! REAL(KIND(1D0)) :: flag_dry
152 ! REAL(KIND(1D0)) :: W !Depends on the amount of water on the canopy [-]
153 ! REAL(KIND(1D0)) :: x
154 INTEGER :: n_facet !number of facets
155 INTEGER :: i
156
157 REAL(KIND(1D0)), PARAMETER :: NAN = -999
158
159 n_facet = SIZE(sfr_multi)
160
161 DO i = 1, n_facet
162 CALL cal_evap( &
163 evapmethod, state_multi(i), wetthresh_multi(i), capstore_multi(i), &
164 vpd_hpa, avdens, avcp, qn_e_multi(i), s_hpa, psyc_hpa, rs, ra, rb, tlv, &
165 rss_multi(i), ev_multi(i), qe_multi(i))
166 END DO
167
168 ! Sum latent heat flux from different surfaces to find total latent heat flux
169 ! qe_total = DOT_PRODUCT(qe_multi, sfr_multi)
170
171 END SUBROUTINE cal_evap_multi
172
173END MODULE evap_module
subroutine cal_evap_multi(evapmethod, sfr_multi, state_multi, wetthresh_multi, capstore_multi, vpd_hpa, avdens, avcp, qn_e_multi, s_hpa, psyc_hpa, rs, ra, rb, tlv, rss_multi, ev_multi, qe_multi)
subroutine cal_evap(evapmethod, state_is, wetthresh_is, capstore_is, vpd_hpa, avdens, avcp, qn_e, s_hpa, psyc_hpa, rs, ra, rb, tlv, rss, ev, qe)