SUEWS API Site
Documentation of SUEWS source code
suews_phys_waterdist.f95
Go to the documentation of this file.
2 USE allocatearray, ONLY: nsurf, &
6
7 IMPLICIT NONE
8 ! INTEGER, PARAMETER :: nsurf = 7
9 ! INTEGER, PARAMETER :: PavSurf = 1
10 ! INTEGER, PARAMETER :: BldgSurf = 2
11 ! INTEGER, PARAMETER :: ConifSurf = 3
12 ! INTEGER, PARAMETER :: DecidSurf = 4
13 ! INTEGER, PARAMETER :: GrassSurf = 5
14 ! INTEGER, PARAMETER :: BSoilSurf = 6
15 ! INTEGER, PARAMETER :: WaterSurf = 7
16 ! INTEGER, PARAMETER :: ExcessSurf = 8
17CONTAINS
18
19 !------------------------------------------------------------------------------
20 SUBROUTINE drainage( &
21 is, & !input
22 state_is, &
23 StorCap, &
24 DrainEq, &
25 DrainCoef1, &
26 DrainCoef2, &
27 nsh_real, &
28 drain_is) !output
29
30 !Calculation of drainage for each land surface.
31 !INPUT: Storage capacity, type of drainage equation used, drainage coefficients
32 ! used in the equation
33 !Modified by HCW 16 Feb 2015
34 ! Removed option of Eq 4 (calculation needs to be checked before re-implementing).
35 ! Code writes an error if calculated drainage exceeds surface state_id (but code continues).
36 ! This may indicate inappropriate drainage equation, storage capacities or model tstep.
37 !Modified by LJ in Aug 2011. Drainage cannot exceed the surface storage.
38 !Modified LJ in 10/2010
39 !------------------------------------------------------------------------------
40
41 IMPLICIT NONE
42 INTEGER, INTENT(in) :: is ! surface type number
43
44 REAL(KIND(1D0)), INTENT(in) :: state_is !Wetness status of surface type "is" [mm]
45 REAL(KIND(1D0)), INTENT(in) :: StorCap !current storage capacity [mm]
46 REAL(KIND(1D0)), INTENT(in) :: DrainCoef1 !Drainage coeff 1 [units depend on choice of eqn]
47 REAL(KIND(1D0)), INTENT(in) :: DrainCoef2 !Drainage coeff 2 [units depend on choice of eqn]
48 REAL(KIND(1D0)), INTENT(in) :: DrainEq !Drainage equation to use
49 REAL(KIND(1D0)), INTENT(in) :: nsh_real !nsh cast as a real for use in calculations
50 REAL(KIND(1D0)), INTENT(out) :: drain_is !Drainage of surface type "is" [mm]
51
52 !If surface is dry, no drainage occurs
53 IF (state_is < 0.000000001) THEN
54 drain_is = 0.0
55 ELSE
56 IF (int(draineq) == 1) THEN !Falk and Niemczynowicz (1978): Drainage equation for paved, buildings and irrigated grass
57
58 IF (state_is < storcap) THEN
59 drain_is = 0 !No drainage if state_id is less than storage capacity
60 ELSE
61 drain_is = (draincoef1*(state_is - storcap)**draincoef2)/nsh_real
62 END IF
63
64 ELSEIF (int(draineq) == 2) THEN !Rutter eqn corrected for c=0, see Eq 9 of Calder & Wright 1986
65 drain_is = (draincoef1*(exp(draincoef2*state_is) - 1))/nsh_real
66 ! N.B. -1 is correct here but brackets are wrong in G&O 1991 Eq 5 & Ja11 Eq 18.
67
68 ELSEIF (int(draineq) == 3) THEN !Falk and Niemczynowicz (1978)
69 drain_is = (draincoef1*(state_is**draincoef2))/nsh_real
70
71 END IF
72
73 ! Check value obtained is physically reasonable
74 ! More water cannot drain than is in the surface state_id
75 ! although high initial rate of drainage tries to drain more water than is in state_id within tstep
76 ! May indicate shorter tstep needed, or a more suitable equation
77 IF (drain_is > state_is) THEN
78 !write(*,*) 'Drainage:', is, drain(is), state_id(is), drain(is)-state_id(is), DrainEq, DrainCoef1, DrainCoef2, nsh_real
79 CALL errorhint(61, 'SUEWS_drain: drain_is > state_is for surface is ', drain_is, state_is, is)
80 drain_is = state_is !All water in state_id is drained (but no more)
81 ELSEIF (drain_is < 0.0001) THEN
82 drain_is = 0
83 END IF
84 END IF
85
86 RETURN
87
88 END SUBROUTINE drainage
89 !------------------------------------------------------------------------------
90
91 !--------------Calculation of water storage change of specific land cover------------------------------
92 SUBROUTINE cal_water_storage( &
93 is, sfr_surf, PipeCapacity, RunoffToWater, pin, & ! input:
94 WU_surf, &
95 drain_surf, AddWater, addImpervious, nsh_real, state_in, frac_water2runoff, &
96 PervFraction, addVeg, SoilStoreCap, addWaterBody, FlowChange, StateLimit, &
97 runoffAGimpervious, runoffAGveg, runoffPipes, ev, soilstore_id, & ! inout:
98 surplusWaterBody, SurplusEvap, runoffWaterBody, & ! inout:
99 runoff, state_out) !output:
100 !------------------------------------------------------------------------------
101 !Calculation of storage change
102 ! TS 30 Nov 2019
103 ! - Allow irrigation on all surfaces (previously only on vegetated surfaces)
104 ! LJ 27 Jan 2016
105 ! - Removed tabs and cleaned the code
106 ! HCW 08 Dec 2015
107 ! -Added if-loop check for no Paved surfaces
108 ! LJ 6 May 2015
109 ! - Calculations of the piperunoff exceedings moved to separate subroutine updateFlood.
110 ! - Now also called from snow subroutine
111 ! - Evaporation is modified using EvapPart
112 ! - when no water on impervious surfaces, evap occurs above pervious surfaces instead
113 ! Rewritten by HCW 12 Feb 2015
114 ! - Old variable 'p' for water input to the surface renamed to 'p_mm'
115 ! - All water now added to p_mm first, before threshold checks or other calculations
116 ! - Water from other grids now added to p_mm (instead of state_id for impervious surfaces)
117 ! - Removed division of runoff by nsh, as whole model now runs at the same timestep
118 ! - Adjusted transfer of ev between surfaces to conserve mass (not depth)
119 ! - Volumes used for water transport between grids to account for SurfaceArea changing between grids
120 ! - Added threshold check for state_id(WaterSurf) - was going negative
121 ! Last modified HCW 09 Feb 2015
122 ! - Removed StorCap input because it is provided by module allocateArray
123 ! - Tidied and commented code
124 ! Modified by LJ in November 2012:
125 ! - P>10 was not taken into account for impervious surfaces - Was fixed.
126 ! - Above impervious surfaces possibility of the state_id to exceed max capacity was limited
127 ! although this should be possible - was fixed
128 ! Modified by LJ 10/2010
129 ! Rewritten mostly by LJ in 2010
130 ! To do:
131 ! - Finish area normalisation for RG2G & finish coding GridConnections
132 ! - What is the 10 mm hr-1 threshold for?
133 ! - Decide upon and correct storage capacities here & in evap subroutine
134 ! - FlowChange units should be mm hr-1 - need to update everywhere
135 ! - Add SurfaceFlood(is)?
136 ! - What happens if sfr_surf(is) = 0 or 1?
137 ! - Consider how irrigated trees actually works...
138 !------------------------------------------------------------------------------
139
140 IMPLICIT NONE
141
142 !Stores flood water when surface state_id exceeds storage capacity [mm]
143 INTEGER, INTENT(in) :: is ! surface type
144
145 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: sfr_surf ! surface fractions
146 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: AddWater !Water from other surfaces (WGWaterDist in SUEWS_ReDistributeWater.f95) [mm]
147 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: state_in !Wetness status of each surface type from previous timestep [mm]
148 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: frac_water2runoff !Fraction of water going to runoff/sub-surface soil (WGWaterDist) [-]
149 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: SoilStoreCap !Capacity of soil store for each surface [mm]
150 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: StateLimit !Limit for state_id of each surface type [mm] (specified in input files)
151 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: drain_surf !Drainage of each surface type [mm]
152 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: WU_surf !external water use of each surface type [mm]
153
154 REAL(KIND(1D0)), INTENT(in) :: PipeCapacity !Capacity of pipes to transfer water
155 REAL(KIND(1D0)), INTENT(in) :: RunoffToWater !Fraction of surface runoff going to water body
156 REAL(KIND(1D0)), INTENT(in) :: pin !Rain per time interval
157 REAL(KIND(1D0)), INTENT(in) :: addImpervious !Water from impervious surfaces of other grids [mm] for whole surface area
158 REAL(KIND(1D0)), INTENT(in) :: nsh_real !nsh cast as a real for use in calculations
159 REAL(KIND(1D0)), INTENT(in) :: PervFraction ! sum of surface cover fractions for impervious surfaces
160 REAL(KIND(1D0)), INTENT(in) :: addVeg !Water from vegetated surfaces of other grids [mm] for whole surface area
161 REAL(KIND(1D0)), INTENT(in) :: addWaterBody !Water from water surface of other grids [mm] for whole surface area
162 REAL(KIND(1D0)), INTENT(in) :: FlowChange !Difference between the input and output flow in the water body
163
164 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(inout) :: soilstore_id !Soil moisture of each surface type [mm]
165 REAL(KIND(1D0)), DIMENSION(2), INTENT(inout) :: SurplusEvap !Surplus for evaporation in 5 min timestep
166
167 REAL(KIND(1D0)), DIMENSION(nsurf) :: chang !Change in state_id [mm]
168 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: runoff !Runoff from each surface type [mm]
169 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: state_out !Wetness status of each surface type [mm]
170
171 ! =============================
172 ! TS 01 Apr 2022:
173 ! these variables were used as inout variables in the original code for water transfer between grids
174 ! but they are not used in the new code, so they are removed here
175 REAL(KIND(1D0)), INTENT(inout) :: surplusWaterBody !Extra runoff that goes to water body [mm] as specified by RunoffToWater
176 REAL(KIND(1D0)), INTENT(inout) :: runoffAGimpervious !Above ground runoff from impervious surface [mm] for whole surface area
177 REAL(KIND(1D0)), INTENT(inout) :: runoffAGveg !Above ground runoff from vegetated surfaces [mm] for whole surface area
178 REAL(KIND(1D0)), INTENT(inout) :: runoffPipes !Runoff in pipes [mm] for whole surface area
179 REAL(KIND(1D0)), INTENT(inout) :: ev !Evaporation
180 REAL(KIND(1D0)), INTENT(inout) :: runoffWaterBody !Above ground runoff from water surface [mm] for whole surface area
181
182 REAL(KIND(1D0)) :: p_mm !Inputs to surface water balance
183
184 !Extra evaporation [mm] from impervious surfaces which cannot happen due to lack of water
185 REAL(KIND(1D0)) :: EvPart
186 REAL(KIND(1D0)), PARAMETER :: NotUsed = -55.5
187
188 !Threshold for intense precipitation [mm hr-1]
189 REAL(KIND(1D0)), PARAMETER :: IPThreshold_mmhr = 10 ! NB:this should be an input and can be specified. SG 25 Apr 2018
190
191 !Initialise extra evaporation to zero
192 evpart = 0
193
194 !Initialise runoff to zero
195 runoff(is) = 0
196
197 !SurfaceFlood(is) = 0 !!This probably needs to be carried over between timesteps, but reset for now
198
199 !==================================================================
200 ! Combine water inputs to the current surface
201 ! Add external water use for each surface type
202 p_mm = pin + wu_surf(is)
203
204 ! Add water from other surfaces within the same grid (RS2S) ----
205 ! AddWater is the water supplied to the current surface from other surfaces
206 ! i.e. drain*WaterDist (see SUEWS_ReDistributeWater)
207 p_mm = p_mm + addwater(is)
208 !==================================================================
209
210 !========surface-specific calculation=========================
211 SELECT CASE (is)
212 CASE (pavsurf, bldgsurf)
213 !==== Impervious surfaces (Paved, Buildings) ======================
214 ! Add water from neighbouring grids (RG2G)
215 ! Add to PavSurf only, as water cannot flow onto buildings
216 IF (is == pavsurf) THEN
217 IF (sfr_surf(pavsurf) /= 0) THEN ! If loop added HCW 08 Dec 2015
218 p_mm = p_mm + addimpervious/sfr_surf(pavsurf)
219 END IF
220 END IF
221
222 ! Calculate change in surface state_id (inputs - outputs)
223 chang(is) = p_mm - (drain_surf(is) + ev)
224
225 ! If p_mm is too large, excess goes to runoff (i.e. the rate of water supply is too fast)
226 ! and does not affect state_id
227 IF (p_mm > ipthreshold_mmhr/nsh_real) THEN
228 runoff(is) = runoff(is) + (p_mm - ipthreshold_mmhr/nsh_real)
229 chang(is) = ipthreshold_mmhr/nsh_real - (drain_surf(is) + ev)
230 END IF
231
232 ! Calculate updated state_id using chang
233 state_out(is) = state_in(is) + chang(is)
234
235 ! Check state_id is within physical limits between zero (dry) and max. storage capacity
236 IF (state_out(is) < 0.0) THEN ! Cannot have a negative surface state_id
237 ! If there is not sufficient water on the surface, then don't allow this evaporation to happen
238 ! Allow evaporation only until surface is dry (state_id(is)=0); additional evaporation -> evaporation surplus
239 surplusevap(is) = abs(state_out(is)) !Surplus evaporation is that which tries to evaporate non-existent water
240 ev = ev - surplusevap(is) !Limit evaporation according to water availability
241 state_out(is) = 0.0 !Now surface is dry
242 ! elseif (state_id(is)>StoreDrainPrm(6,is)) then !!This should perhaps be StateLimit(is)
243 ! !! If state_id exceeds the storage capacity, then the excess goes to surface flooding
244 ! !SurfaceFlood(is)=SurfaceFlood(is)+(state_id(is)-StoreDrainPrm(6,is)) !!Need to deal with this properly
245 ! runoff(is)=runoff(is)+(state_id(is)-StoreDrainPrm(6,is)) !!needs to go to flooding
246 ! state_id(is)=StoreDrainPrm(6,is) !Now surface state_id is at max (storage) capacity
247 END IF
248
249 ! Recalculate change in surface state_id from difference with previous timestep
250 chang(is) = state_out(is) - state_in(is)
251
252 ! Runoff -------------------------------------------------------
253 ! For impervious surfaces, some of drain(is) becomes runoff
254 runoff(is) = runoff(is) + drain_surf(is)*frac_water2runoff(is) !Drainage (that is not flowing to other surfaces) goes to runoff
255
256 !So, up to this point, runoff(is) can have contributions if
257 ! p_mm > ipthreshold (water input too fast)
258 ! state_id > StoreDrainPrm(6,is) (net water exceeds storage capacity)
259 ! WaterDist specifies some fraction of drain(is) -> runoff
260
261 CASE (conifsurf:bsoilsurf)
262 !==== For Conif, Decid, Grass, BSoil surfaces ==================
263 ! Transfer evaporation surplus from impervious surfaces to pervious surfaces
264 evpart = merge( &
265 dot_product(surplusevap(pavsurf:bldgsurf), sfr_surf(pavsurf:bldgsurf)/pervfraction), &
266 0d0, &
267 pervfraction /= 0)
268
269 ! Add surplus evaporation to ev for pervious surfaces
270 ev = ev + evpart
271
272 ! ---- Add water from neighbouring grids (RG2G) ----
273 ! Add to Grass and BSoil only, as water cannot flow onto trees
274 IF (is == grasssurf .OR. is == bsoilsurf) THEN
275 IF ((sfr_surf(grasssurf) + sfr_surf(bsoilsurf)) /= 0) THEN
276 p_mm = p_mm + addveg/(sfr_surf(grasssurf) + sfr_surf(bsoilsurf))
277 END IF
278 END IF
279
280 ! Calculate change in surface state_id (inputs - outputs)
281 chang(is) = p_mm - (drain_surf(is) + ev)
282
283 ! If p_mm is too large, excess goes to runoff (i.e. the rate of water supply is too fast)
284 ! and does not affect state_id
285 IF (p_mm > ipthreshold_mmhr/nsh_real) THEN
286 runoff(is) = runoff(is) + (p_mm - ipthreshold_mmhr/nsh_real)
287 chang(is) = ipthreshold_mmhr/nsh_real - (drain_surf(is) + ev)
288 END IF
289
290 ! Calculate updated state_id using chang
291 state_out(is) = state_in(is) + chang(is)
292
293 ! Check state_id is within physical limits between zero (dry) and max. storage capacity
294 IF (state_out(is) < 0.0) THEN ! Cannot have a negative surface state_id
295 ! If there is not sufficient water on the surface, then remove water from soilstore
296 ! Allow evaporation until soilstore_id is depleted and surface is dry
297 IF ((soilstore_id(is) + state_out(is)) >= 0) THEN
298 soilstore_id(is) = soilstore_id(is) + state_out(is)
299 state_out(is) = 0.0
300 ! If there is not sufficient water on the surface or soilstore, then don't allow this evaporation to happen
301 ELSE
302 ev = ev - abs(state_out(is)) !Limit evaporation according to water availability
303 state_out(is) = 0.0 !Now surface is dry
304 END IF
305
306 !elseif (state_id(is)>StoreDrainPrm(6,is)) then !!This should perhaps be StateLimit(is)
307 ! !! If state_id exceeds the storage capacity, then the excess goes to surface flooding
308 ! !SurfaceFlood(is)=SurfaceFlood(is)+(state_id(is)-StoreDrainPrm(6,is)) !!Need to deal with this properly
309 ! runoff(is)=runoff(is)+(state_id(is)-StoreDrainPrm(6,is)) !!needs to go to flooding
310 ! state_id(is)=StoreDrainPrm(6,is) !Now surface state_id is at max (storage) capacity
311 END IF
312
313 ! Recalculate change in surface state_id from difference with previous timestep
314 chang(is) = state_out(is) - state_in(is)
315
316 !Where should this go? Used to be before previous part!!
317 ! soilstore_id -------------------------------------------------
318 ! For pervious surfaces (not water), some of drain(is) goes to soil storage
319 ! Drainage (that is not flowing to other surfaces) goes to soil storages
320 soilstore_id(is) = soilstore_id(is) + drain_surf(is)*frac_water2runoff(is)
321
322 ! If soilstore is full, the excess will go to runoff
323 IF (soilstore_id(is) > soilstorecap(is)) THEN ! TODO: this should also go to flooding of some sort
324 runoff(is) = runoff(is) + (soilstore_id(is) - soilstorecap(is))
325 soilstore_id(is) = soilstorecap(is)
326 ELSEIF (soilstore_id(is) < 0) THEN !! QUESTION: But where does this lack of water go? !!Can this really happen here?
327 CALL errorhint(62, 'SUEWS_store: soilstore_id(is) < 0 ', soilstore_id(is), notused, is)
328 ! Code this properly - soilstore_id(is) < 0 shouldn't happen given the above loops
329 !soilstore_id(is)=0 !Groundwater / deeper soil should kick in
330 END IF
331
332 CASE (watersurf)
333 IF (sfr_surf(watersurf) /= 0) THEN
334
335 ! ---- Add water from neighbouring grids (RG2G) ----
336 p_mm = p_mm + addwaterbody/sfr_surf(watersurf)
337
338 ! Calculate change in surface state_id (inputs - outputs)
339 ! No drainage for water surface
340 ! FlowChange is the difference in input and output flows [mm hr-1]
341 chang(is) = p_mm + flowchange/nsh_real - ev
342
343 ! Calculate updated state_id using chang
344 state_out(is) = state_in(is) + chang(is)
345
346 ! Check state_id is within physical limits between zero (dry) and max. storage capacity
347 IF (state_out(is) < 0.0) THEN ! Cannot have a negative surface state_id
348 ! If there is not sufficient water on the surface, then don't allow this evaporation to happen
349 ev = ev - abs(state_out(is)) !Limit evaporation according to water availability
350 state_out(is) = 0.0 !Now surface is dry
351 !elseif (state_id(is)>StoreDrainPrm(6,is)) then !!This should perhaps be StateLimit(is)
352 ! !! If state_id exceeds the storage capacity, then the excess goes to surface flooding
353 ! !SurfaceFlood(is)=SurfaceFlood(is)+(state_id(is)-StoreDrainPrm(6,is)) !!Need to deal with this properly
354 ! runoff(is)=runoff(is)+(state_id(is)-StoreDrainPrm(6,is)) !!needs to go to flooding
355 ! state_id(is)=StoreDrainPrm(6,is) !Now surface state_id is at max (storage) capacity
356 END IF
357
358 ! Recalculate change in surface state_id from difference with previous timestep
359 chang(is) = state_out(is) - state_in(is)
360
361 ! If state_id exceeds limit, then excess goes to runoff (currently applies to water StoreDrainPrm only)
362 IF (state_out(watersurf) > statelimit(watersurf)) THEN
363 runoff(watersurf) = runoff(watersurf) + (state_out(watersurf) - statelimit(watersurf))
364 state_out(watersurf) = statelimit(watersurf)
365 runoffwaterbody = runoffwaterbody + runoff(watersurf)*sfr_surf(watersurf)
366 ELSE
367 state_out(watersurf) = state_out(watersurf) + surpluswaterbody
368 IF (state_out(watersurf) > statelimit(watersurf)) THEN
369 runoffwaterbody = runoffwaterbody + (state_out(watersurf) - statelimit(watersurf))*sfr_surf(watersurf)
370 state_out(watersurf) = statelimit(watersurf)
371 END IF
372 END IF
373
374 ! Recalculate change in surface state_id from difference with previous timestep
375 chang(is) = state_out(is) - state_in(is)
376 END IF
377 END SELECT
378 !==================================================================
379
380 !==== RUNOFF ======================================================
381 ! TODO: to consider areas here - SurfaceArea may vary between grids too
382 ! - also implement where water for next surface is calculated (RunoffFromGrid subroutine)
383 ! Calculations of the piperunoff exceedensances moved to separate subroutine so that from snow same
384 ! calculations can be made. LJ in May 2015
385
386 IF (is < watersurf) THEN !Not for water body
387 ! CALL updateFlood
388 CALL updateflood( &
389 is, runoff, & ! input:
390 sfr_surf, pipecapacity, runofftowater, &
391 runoffagimpervious, surpluswaterbody, runoffagveg, runoffpipes) ! inout:
392 END IF
393
394 END SUBROUTINE cal_water_storage
395 !------------------------------------------------------------------------------
396
397 ! TODO: continue here for the multi-facet case
399 pin, nsh_real, & ! input:
400 PipeCapacity, RunoffToWater, &
401 addImpervious, addVeg, addWaterBody, FlowChange, &
402 SoilStoreCap_surf, StateLimit_surf, &
403 PervFraction, &
404 sfr_surf, drain_surf, AddWater_surf, frac_water2runoff_surf, WU_surf, &
405 ev_surf_in, state_surf_in, soilstore_surf_in, &
406 ev_surf_out, state_surf_out, soilstore_surf_out, & ! output:
407 runoff_surf, &
408 runoffAGimpervious_grid, runoffAGveg_grid, runoffPipes_grid, runoffWaterBody_grid & ! output
409 ) !output:
410 IMPLICIT NONE
411
412 !Stores flood water when surface state_id exceeds storage capacity [mm]
413 INTEGER :: is ! surface type
414
415 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: sfr_surf ! surface fractions
416 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: AddWater_surf !Water from other surfaces (WGWaterDist in SUEWS_ReDistributeWater.f95) [mm]
417 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: state_surf_in !Wetness status of each surface type from previous timestep [mm]
418 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: frac_water2runoff_surf !Fraction of water going to runoff/sub-surface soil (WGWaterDist) [-]
419 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: SoilStoreCap_surf !Capacity of soil store for each surface [mm]
420 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: StateLimit_surf !Limit for state_id of each surface type [mm] (specified in input files)
421 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: drain_surf !Drainage of each surface type [mm]
422 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: WU_surf !external water use of each surface type [mm]
423 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: ev_surf_in !Evaporation
424 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: soilstore_surf_in !Evaporation
425
426 ! REAL(KIND(1D0)), INTENT(in) :: NonWaterFraction !Capacity of pipes to transfer water
427 REAL(KIND(1D0)), INTENT(in) :: PipeCapacity !Capacity of pipes to transfer water
428 REAL(KIND(1D0)), INTENT(in) :: RunoffToWater !Fraction of surface runoff going to water body
429 REAL(KIND(1D0)), INTENT(in) :: pin !Rain per time interval
430 REAL(KIND(1D0)), INTENT(in) :: addImpervious !Water from impervious surfaces of other grids [mm] for whole surface area
431 REAL(KIND(1D0)), INTENT(in) :: nsh_real !nsh cast as a real for use in calculations
432 REAL(KIND(1D0)), INTENT(in) :: PervFraction ! sum of surface cover fractions for impervious surfaces
433 REAL(KIND(1D0)), INTENT(in) :: addVeg !Water from vegetated surfaces of other grids [mm] for whole surface area
434 REAL(KIND(1D0)), INTENT(in) :: addWaterBody !Water from water surface of other grids [mm] for whole surface area
435 REAL(KIND(1D0)), INTENT(in) :: FlowChange !Difference between the input and output flow in the water body
436
437 ! REAL(KIND(1D0)), INTENT(out) :: runoff_grid !Wetness status of each surface type [mm]
438 ! REAL(KIND(1D0)), INTENT(out) :: state_grid !Wetness status of each surface type [mm]
439 ! REAL(KIND(1D0)), INTENT(out) :: ev_grid !Wetness status of each surface type [mm]
440 ! REAL(KIND(1D0)), INTENT(out) :: surf_chang_grid !Wetness status of each surface type [mm]
441 REAL(KIND(1D0)), INTENT(out) :: runoffAGimpervious_grid !Above ground runoff from impervious surface [mm] for whole surface area
442 REAL(KIND(1D0)), INTENT(out) :: runoffAGveg_grid !Above ground runoff from vegetated surfaces [mm] for whole surface area
443 REAL(KIND(1D0)), INTENT(out) :: runoffPipes_grid !Runoff in pipes [mm] for whole surface area
444 REAL(KIND(1D0)), INTENT(out) :: runoffWaterBody_grid !Above ground runoff from water surface [mm] for whole surface area
445 ! REAL(KIND(1D0)), INTENT(out) :: NWstate_grid !Above ground runoff from water surface [mm] for whole surface area
446
447 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: ev_surf_out !evaporation each surface type [mm]
448 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: state_surf_out !Wetness status of each surface type [mm]
449 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: soilstore_surf_out !Wetness status of each surface type [mm]
450
451 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: runoff_surf !Runoff from each surface type [mm]
452 REAL(KIND(1D0)), DIMENSION(nsurf) :: soilstore !Soil moisture of each surface type [mm]
453 ! REAL(KIND(1D0)), DIMENSION(nsurf) :: chang !Change in state_id [mm]
454 REAL(KIND(1D0)), DIMENSION(2) :: SurplusEvap !Surplus for evaporation in 5 min timestep
455
456 ! =============================
457 ! TS 01 Apr 2022:
458 ! these variables were used as inout variables in the original code for water transfer between grids
459 ! but they are not used in the new code, so they are removed here
460 REAL(KIND(1D0)) :: surplusWaterBody !Extra runoff that goes to water body [mm] as specified by RunoffToWater
461
462 ! REAL(KIND(1D0)) :: p_mm !Inputs to surface water balance
463
464 REAL(KIND(1D0)), DIMENSION(nsurf) :: ev_surf !Evaporation
465
466 !Extra evaporation [mm] from impervious surfaces which cannot happen due to lack of water
467 ! REAL(KIND(1D0)) :: EvPart
468 REAL(KIND(1D0)), PARAMETER :: NotUsed = -55.5
469
470 !Threshold for intense precipitation [mm hr-1]
471 REAL(KIND(1D0)), PARAMETER :: IPThreshold_mmhr = 10 ! NB:this should be an input and can be specified. SG 25 Apr 2018
472
473 ev_surf = ev_surf_in
474 soilstore = soilstore_surf_in
475
476 surplusevap = 0
477 runoffagveg_grid = 0
478 runoffpipes_grid = 0
479 runoffagimpervious_grid = 0
480 runoffwaterbody_grid = 0
481 surpluswaterbody = 0
482
483 ! surf_chang_grid = 0
484 runoff_surf = 0
485 state_surf_out = 0
486 ! state_grid = 0
487 ! NWstate_grid = 0
488 ! print *, 'cal_water_storage_surf: entering'
489
490 DO is = 1, nsurf !For each surface in turn
491 ! print *, 'cal_water_storage_surf: is = ', is
492 IF (sfr_surf(is) > 0) THEN
493
494 !Surface water balance and soil store updates (can modify ev, updates state_id)
495 CALL cal_water_storage( &
496 is, sfr_surf, pipecapacity, runofftowater, pin, & ! input:
497 wu_surf, &
498 drain_surf, addwater_surf, addimpervious, nsh_real, state_surf_in, frac_water2runoff_surf, &
499 pervfraction, addveg, soilstorecap_surf, addwaterbody, flowchange, statelimit_surf, &
500 runoffagimpervious_grid, runoffagveg_grid, runoffpipes_grid, ev_surf(is), soilstore, & ! inout:
501 surpluswaterbody, surplusevap, runoffwaterbody_grid, & ! inout:
502 runoff_surf, state_surf_out) !output:
503 END IF
504
505 END DO !end loop over surfaces
506
507 ! update soilstore
508 soilstore_surf_out = soilstore
509
510 ! update evaporation
511 ev_surf_out = ev_surf
512 ! print *, 'cal_water_storage_surf: exiting'
513
514 END SUBROUTINE cal_water_storage_surf
515
517 pin, nsh_real, nlayer, &
518 sfr_roof, StateLimit_roof, SoilStoreCap_roof, WetThresh_roof, & ! input:
519 ev_roof_in, state_roof_in, soilstore_roof_in, & ! input:
520 sfr_wall, StateLimit_wall, SoilStoreCap_wall, WetThresh_wall, & ! input:
521 ev_wall_in, state_wall_in, soilstore_wall_in, & ! input:
522 ev_roof_out, state_roof_out, soilstore_roof_out, runoff_roof, & ! general output:
523 ev_wall_out, state_wall_out, soilstore_wall_out, runoff_wall, & ! general output:
524 state_building, soilstore_building, runoff_building, SoilStoreCap_building)
525
526 IMPLICIT NONE
527
528 INTEGER, INTENT(in) :: nlayer !number of layers
529 REAL(KIND(1D0)), INTENT(in) :: pin !Rain per time interval
530 REAL(KIND(1D0)), INTENT(in) :: nsh_real !timesteps per hour
531
532 ! input for generic roof facets
533 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: sfr_roof
534 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: StateLimit_roof !Limit for state_id of each surface type [mm] (specified in input files)
535 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: WetThresh_roof
536 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: SoilStoreCap_roof
537 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: state_roof_in
538 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: soilstore_roof_in
539 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: ev_roof_in
540
541 ! input for generic wall facets
542 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: sfr_wall
543 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: StateLimit_wall
544 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: WetThresh_wall
545 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: SoilStoreCap_wall
546 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: state_wall_in
547 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: soilstore_wall_in
548 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(in) :: ev_wall_in
549
550 ! output for generic roof facets
551 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: ev_roof_out
552 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: state_roof_out
553 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: soilstore_roof_out
554 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: runoff_roof
555
556 ! output for generic wall facets
557 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: ev_wall_out
558 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: state_wall_out
559 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: soilstore_wall_out
560 REAL(KIND(1D0)), DIMENSION(nlayer), INTENT(out) :: runoff_wall
561
562 REAL(KIND(1D0)), INTENT(out) :: state_building !aggregated surface water of building facets [mm]
563 REAL(KIND(1D0)), INTENT(out) :: soilstore_building ! aggregated soilstore of building facets[mm]
564 REAL(KIND(1D0)), INTENT(out) :: runoff_building !aggregated Runoff of building facets [mm]
565 REAL(KIND(1D0)), INTENT(out) :: SoilStoreCap_building
566
567 REAL(KIND(1D0)) :: precip_excess_roof !precipitation excess above IPThreshold_mmhr [mm]
568 REAL(KIND(1D0)) :: precip_excess_wall !precipitation excess above limit [mm]
569 REAL(KIND(1D0)) :: pin_wall !input water to wall facet [mm]
570
571 REAL(KIND(1D0)), DIMENSION(nlayer) :: chang_roof !Runoff from each surface type [mm]
572 REAL(KIND(1D0)), DIMENSION(nlayer) :: chang_wall !Runoff from each surface type [mm]
573 REAL(KIND(1D0)), DIMENSION(nlayer) :: drain_roof !drainage to sewer [mm]
574 REAL(KIND(1D0)), DIMENSION(nlayer) :: drain_wall !drainage to sewer [mm]
575 REAL(KIND(1D0)), DIMENSION(nlayer) :: infil_roof !infiltration to replenish soil water [mm]
576 REAL(KIND(1D0)), DIMENSION(nlayer) :: infil_wall !infiltration to replenish soil water [mm]
577 REAL(KIND(1D0)), DIMENSION(nlayer) :: evap_roof !evapotranpiration from each surface type [mm]
578 REAL(KIND(1D0)), DIMENSION(nlayer) :: evap_wall !evapotranpiration from each surface type [mm]
579 ! REAL(KIND(1D0)), DIMENSION(nsurf) :: soilstore !Soil moisture of each surface type [mm]
580 ! REAL(KIND(1D0)), DIMENSION(nsurf) :: chang !Change in state_id [mm]
581 ! REAL(KIND(1D0)), DIMENSION(2) :: SurplusEvap !Surplus for evaporation in 5 min timestep
582
583 !Threshold for intense precipitation [mm hr-1]
584 REAL(KIND(1D0)), PARAMETER :: IPThreshold_mmhr = 10 ! NB:this should be an input and can be specified. SG 25 Apr 2018
585 REAL(KIND(1D0)) :: IPThreshold ! NB:this should be an input and can be specified. SG 25 Apr 2018
586
587 INTEGER :: n_layer, i_layer
588
589 ! Threshold for intense precipitation in each timestep
590 ipthreshold = ipthreshold_mmhr/nsh_real
591
592 ! precipitation excess above IPThreshold_mmhr
593 precip_excess_roof = pin - ipthreshold
594
595 ! n_layer = SIZE(sfr_roof)
596 DO i_layer = 1, nlayer
597
598 ! ===== roof part =====
599 ! initialize temporary variables
600 runoff_roof(i_layer) = 0.0
601 chang_roof(i_layer) = 0.0
602
603 ! let's assume so for now
604 ! TODO: introduce a more sophisticated drinage function for green roofs
605 drain_roof(i_layer) = state_roof_in(i_layer)*.0
606
607 ! infiltration to replenish soil water
608 infil_roof(i_layer) = state_roof_in(i_layer)*.3
609
610 IF (precip_excess_roof > 0) THEN
611 ! runoff generated from roof
612 runoff_roof(i_layer) = precip_excess_roof
613 chang_roof(i_layer) = ipthreshold - ev_roof_in(i_layer) - drain_roof(i_layer) - infil_roof(i_layer)
614 ELSE
615 chang_roof(i_layer) = pin - ev_roof_in(i_layer) - drain_roof(i_layer) - infil_roof(i_layer)
616 END IF
617
618 ! change in surface water
619 state_roof_out(i_layer) = state_roof_in(i_layer) + chang_roof(i_layer)
620
621 ! Check state_id is within physical limits between zero (dry) and max. storage capacity
622 IF (state_roof_out(i_layer) < 0.0) THEN ! Cannot have a negative surface state_id
623 ! If there is not sufficient water on the surface, then remove water from soilstore
624 ! Allow evaporation until soilstore_id is depleted and surface is dry
625 IF ((soilstore_roof_in(i_layer) + state_roof_out(i_layer)) >= 0) THEN
626 ! update soilstore with deficit in surface state
627 soilstore_roof_out(i_layer) = soilstore_roof_in(i_layer) + state_roof_out(i_layer)
628 ! If there is not sufficient water on the surface or soilstore, then don't allow this evaporation to happen
629 ELSE
630 ev_roof_out(i_layer) = ev_roof_in(i_layer) - abs(state_roof_out(i_layer)) !Limit evaporation according to water availability
631 END IF
632 ! force surface to dry
633 state_roof_out(i_layer) = 0.0
634 ELSE
635 ! If there is sufficient water on the surface, then allow surface water to replenish soilstore
636 IF (soilstore_roof_in(i_layer) + infil_roof(i_layer) > soilstorecap_roof(i_layer)) THEN
637 ! cap soilstore_id at max. storage capacity if saturated
638 soilstore_roof_out(i_layer) = soilstorecap_roof(i_layer)
639
640 ! excessive infiltration goes into runoff
641 runoff_roof = runoff_roof + (soilstore_roof_in(i_layer) + infil_roof(i_layer) - soilstorecap_roof(i_layer))
642 ELSE
643 soilstore_roof_out(i_layer) = soilstore_roof_in(i_layer) + infil_roof(i_layer)
644 END IF
645
646 END IF
647
648 ! ===== wall part =====
649 ! initialize temporary variables
650 runoff_wall(i_layer) = 0.0
651 chang_wall(i_layer) = 0.0
652 pin_wall = 0.0
653
654 ! runoff from roof goes into wall as water supply
655 ! NB: only a fraction of precipitation is diverted to the wall
656 pin_wall = runoff_roof(i_layer) + pin*.2
657 precip_excess_wall = pin_wall - statelimit_wall(i_layer)
658
659 ! let's assume so for now
660 ! TODO: introduce a more sophisticated drinage function for green roofs
661 drain_wall(i_layer) = state_wall_in(i_layer)*.0
662
663 ! infiltration to replenish soil water
664 infil_wall(i_layer) = state_wall_in(i_layer)*.1
665
666 IF (precip_excess_wall > 0) THEN
667 ! runoff generated from roof
668 runoff_wall(i_layer) = precip_excess_wall
669 chang_wall(i_layer) = statelimit_wall(i_layer) - ev_wall_in(i_layer) - drain_wall(i_layer) - infil_wall(i_layer)
670 ELSE
671 chang_wall(i_layer) = pin_wall - ev_wall_in(i_layer) - drain_wall(i_layer) - infil_wall(i_layer)
672 END IF
673
674 ! change in surface water
675 state_wall_out(i_layer) = state_wall_in(i_layer) + chang_wall(i_layer)
676
677 ! Check state_id is within physical limits between zero (dry) and max. storage capacity
678 IF (state_wall_out(i_layer) < 0.0) THEN ! Cannot have a negative surface state_id
679 ! If there is not sufficient water on the surface, then remove water from soilstore
680 ! Allow evaporation until soilstore_id is depleted and surface is dry
681 IF ((soilstore_wall_in(i_layer) + state_wall_out(i_layer)) >= 0) THEN
682 ! update soilstore with deficit in surface state
683 soilstore_wall_out(i_layer) = soilstore_wall_in(i_layer) + state_wall_out(i_layer)
684 ! If there is not sufficient water on the surface or soilstore, then don't allow this evaporation to happen
685 ELSE
686 ev_wall_out(i_layer) = ev_wall_in(i_layer) - abs(state_wall_out(i_layer)) !Limit evaporation according to water availability
687 END IF
688 ! force surface to dry
689 state_wall_out(i_layer) = 0.0
690 ELSE
691 ! If there is sufficient water on the surface, then allow surface water to replenish soilstore
692 IF (soilstore_wall_in(i_layer) + infil_wall(i_layer) > soilstorecap_wall(i_layer)) THEN
693 ! cap soilstore_id at max. storage capacity if saturated
694 soilstore_wall_out(i_layer) = soilstorecap_wall(i_layer)
695
696 ! excessive infiltration goes into runoff
697 runoff_wall(i_layer) = &
698 runoff_wall(i_layer) + &
699 (soilstore_wall_in(i_layer) + infil_wall(i_layer) - soilstorecap_wall(i_layer))
700 ELSE
701 soilstore_wall_out(i_layer) = soilstore_wall_in(i_layer) + infil_wall(i_layer)
702 END IF
703
704 END IF
705
706 END DO
707
708 ! diagnostics info:
709 ! call r8vec_print(SIZE(soilstore_roof_out), soilstore_roof_in, 'soilstore_roof_in in layer')
710 ! call r8vec_print(SIZE(soilstore_roof_out), SoilStoreCap_roof, 'SoilStoreCap_roof in layer')
711 ! call r8vec_print(SIZE(soilstore_roof_out), infil_roof, 'infil_roof in layer')
712 ! call r8vec_print(SIZE(soilstore_wall_out), soilstore_roof_out, 'soilstore_roof_out in layer')
713
714 ! aggregated values
715 state_building = dot_product(state_roof_out, sfr_roof) + dot_product(state_wall_out, sfr_wall)
716 soilstore_building = dot_product(soilstore_roof_out, sfr_roof) + dot_product(soilstore_wall_out, sfr_wall)
717 soilstorecap_building = dot_product(soilstorecap_roof, sfr_roof) + dot_product(soilstorecap_wall, sfr_wall)
718 ! only allow runoff from walls
719 runoff_building = dot_product(runoff_wall, sfr_wall)
720
721 END SUBROUTINE cal_water_storage_building
722
723 !------------------------------------------------------------------------------
724 SUBROUTINE updateflood( &
725 is, runoff, & ! input:
726 sfr_surf, PipeCapacity, RunoffToWater, &
727 runoffAGimpervious, surplusWaterBody, runoffAGveg, runoffPipes) ! inout:
728
729 IMPLICIT NONE
730
731 INTEGER, INTENT(in) :: is
732 REAL(KIND(1D0)), INTENT(in) :: sfr_surf(nsurf), runoff(nsurf), PipeCapacity, RunoffToWater
733 REAL(KIND(1D0)), INTENT(inout) :: runoffAGimpervious, surplusWaterBody, runoffAGveg, runoffPipes
734
735 ! Add runoff to pipes
736 runoffpipes = runoffpipes + (runoff(is)*sfr_surf(is))
737
738 ! If pipe capacity is full, surface runoff occurs
739 ! N.B. this will happen each loop (replicates pipes filling up)
740 IF (runoffpipes > pipecapacity) THEN
741
742 !------Paved and building surface
743 IF (is == pavsurf .OR. is == bldgsurf) THEN
744 IF (sfr_surf(watersurf) > 0.0000001) THEN
745 ! If there is some water present, the water surface will take some of the flood water (fraction RunoffToWater)
746 ! RunoffToWater is specified in SUEWS_SiteSelect.txt
747 runoffagimpervious = runoffagimpervious + (runoffpipes - pipecapacity)*(1 - runofftowater)
748 surpluswaterbody = surpluswaterbody + (runoffpipes - pipecapacity)*runofftowater
749 ELSE
750 ! Otherwise, all flood water must go to runoff
751 runoffagimpervious = runoffagimpervious + (runoffpipes - pipecapacity)
752 END IF
753 !------other surfaces
754 ELSEIF (is >= conifsurf .AND. is <= bsoilsurf) THEN
755 IF (sfr_surf(watersurf) > 0.0000001) THEN
756 ! If there is some water present, the water surface will take some of the flood water (fraction RunoffToWater)
757 runoffagveg = runoffagveg + (runoffpipes - pipecapacity)*(1 - runofftowater)
758 surpluswaterbody = surpluswaterbody + (runoffpipes - pipecapacity)*runofftowater
759 ELSE
760 ! Otherwise, all flood water must go to runoff
761 runoffagveg = runoffagveg + (runoffpipes - pipecapacity)
762 END IF
763 END IF
764
765 runoffpipes = pipecapacity !Pipes are at their max capacity
766
767 END IF !If runoff exceed pipe capacity
768
769 END SUBROUTINE updateflood
770 !------------------------------------------------------------------------------
771
772 !------------------------------------------------------------------------------
773 SUBROUTINE redistributewater( &
774 SnowUse, WaterDist, sfr_surf, Drain, & ! input:
775 AddWaterRunoff, AddWater) ! output:
776 !Drainage moves into different parts defined by WaterDistSS_YYYY.txt. LJ 2010
777 !AddWater(is) is that amount of water that is gained for each surface
778 !Latest update takes snow into account. 22/03/2013 LJ
779 !-------------------------------------------------------------------
780
781 IMPLICIT NONE
782 INTEGER, INTENT(in) :: SnowUse !Snow part used (1) or not used (0)
783
784 REAL(KIND(1D0)), INTENT(in) :: WaterDist(nsurf + 1, nsurf - 1) !Within-grid water distribution to other surfaces and runoff/soil store [-]
785 REAL(KIND(1D0)), INTENT(in) :: sfr_surf(nsurf) !Surface fractions [-]
786 REAL(KIND(1D0)), INTENT(in) :: Drain(nsurf) !Drainage of each surface type [mm]
787
788 REAL(KIND(1D0)), INTENT(out) :: AddWaterRunoff(nsurf) !Fraction of water going to runoff/sub-surface soil (WGWaterDist) [-]
789 REAL(KIND(1D0)), INTENT(out) :: AddWater(nsurf) !Water from other surfaces (WGWaterDist in SUEWS_ReDistributeWater.f95) [mm]
790
791 INTEGER :: ii, jj
792 INTEGER :: NSurfDoNotReceiveDrainage = 0 !Number of surfaces that do not receive drainage water (green roof)
793
794 !Fractions that go to runoff from each surface
795 DO ii = 1, nsurf - 1 !not water in the calculation
796 addwaterrunoff(ii) = waterdist(8, ii)
797 END DO
798 addwaterrunoff(watersurf) = 0
799 addwater = 0
800
801 DO ii = 1, nsurf - nsurfdonotreceivedrainage !go through surfaces from 1 to 7. These gain water through drainage
802 DO jj = 1, nsurf - (nsurfdonotreceivedrainage + 1) !From where surface ii can gain water - can't gain water from itself
803
804 IF (sfr_surf(ii) /= 0) THEN !Water movement takes place only if surface fraction exists
805
806 !No snow calculations!
807 IF (snowuse == 0) THEN
808 addwater(ii) = addwater(ii) + (drain(jj)*sfr_surf(jj)/sfr_surf(ii))*waterdist(ii, jj) !Original
809
810 !Snow included, This needs to be fixed at some point. LJ Mar 2013
811 ELSE
812 addwaterrunoff(jj) = addwaterrunoff(jj) + waterdist(ii, jj) !No receiving surface -> runoff
813 END IF
814
815 ELSE
816 addwaterrunoff(jj) = addwaterrunoff(jj) + waterdist(ii, jj) !If no receiving surface exists,
817 !water fraction goes to AddWaterRunoff
818 END IF
819 END DO
820 END DO
821
822 END SUBROUTINE redistributewater
823 !------------------------------------------------------------------------------
824
825 !------------------------------------------------------------------------------
827 NonWaterFraction, & !input
828 SoilStoreCap, sfr_surf, soilstore_id, &
829 SoilMoistCap, SoilState, & !output
830 vsmd, smd)
831 IMPLICIT NONE
832
833 ! INTEGER,INTENT(in)::nsurf,ConifSurf,DecidSurf,GrassSurf
834 REAL(KIND(1D0)), INTENT(in) :: NonWaterFraction
835 REAL(KIND(1D0)), INTENT(in), DIMENSION(nsurf) :: SoilStoreCap, sfr_surf, soilstore_id
836
837 REAL(KIND(1D0)), INTENT(out) :: SoilMoistCap, SoilState
838 REAL(KIND(1D0)), INTENT(out) :: vsmd, smd
839
840 INTEGER :: is
841 REAL(KIND(1D0)) :: fveg
842
843 soilmoistcap = 0 !Maximum capacity of soil store [mm] for whole surface
844 soilstate = 0 !Area-averaged soil moisture [mm] for whole surface
845
846 IF (nonwaterfraction /= 0) THEN !Soil states only calculated if soil exists. LJ June 2017
847 DO is = 1, nsurf - 1 !No water body included
848 soilmoistcap = soilmoistcap + (soilstorecap(is)*sfr_surf(is)/nonwaterfraction)
849 soilstate = soilstate + (soilstore_id(is)*sfr_surf(is)/nonwaterfraction)
850 END DO
851 END IF
852
853 !If loop removed HCW 26 Feb 2015
854 !if (ir==1) then !Calculate initial smd
855 smd = soilmoistcap - soilstate
856 !endif
857
858 ! Calculate soil moisture for vegetated surfaces only (for use in surface conductance)
859 ! vsmd = 0
860 ! IF ((sfr_surf(ConifSurf) + sfr_surf(DecidSurf) + sfr_surf(GrassSurf)) > 0) THEN
861
862 ! fveg = sfr_surf(is)/(sfr_surf(ConifSurf) + sfr_surf(DecidSurf) + sfr_surf(GrassSurf))
863 ! ELSE
864 ! fveg = 0
865 ! END IF
866 ! DO is = ConifSurf, GrassSurf !Vegetated surfaces only
867 ! IF (fveg == 0) THEN
868 ! vsmd = 0
869 ! ELSE
870 ! vsmd = vsmd + (SoilStoreCap(is) - soilstore_id(is))*sfr_surf(is)/fveg
871 ! END IF
872 ! !write(*,*) is, vsmd, smd
873 ! END DO
874
875 vsmd = cal_smd_veg(soilstorecap, soilstore_id, sfr_surf)
876
877 END SUBROUTINE suews_update_soilmoist
878
880 NonWaterFraction, &
881 sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, & !input
882 SoilStoreCap_paved, SoilStoreCap_bldg, SoilStoreCap_evetr, &
883 SoilStoreCap_dectr, SoilStoreCap_grass, SoilStoreCap_bsoil, SoilStoreCap_water, &
884 soilstore_id, &
885 SoilMoistCap, SoilState, & !output
886 vsmd, smd)
887 IMPLICIT NONE
888
889 ! INTEGER,INTENT(in)::nsurf,ConifSurf,DecidSurf,GrassSurf
890 REAL(KIND(1D0)), INTENT(in) :: NonWaterFraction
891 REAL(KIND(1D0)), INTENT(in), DIMENSION(nsurf) :: soilstore_id
892
893 REAL(KIND(1D0)), INTENT(IN) :: sfr_paved
894 REAL(KIND(1D0)), INTENT(IN) :: sfr_bldg
895 REAL(KIND(1D0)), INTENT(IN) :: sfr_evetr
896 REAL(KIND(1D0)), INTENT(IN) :: sfr_dectr
897 REAL(KIND(1D0)), INTENT(IN) :: sfr_grass
898 REAL(KIND(1D0)), INTENT(IN) :: sfr_bsoil
899 REAL(KIND(1D0)), INTENT(IN) :: sfr_water
900 REAL(KIND(1D0)), DIMENSION(nsurf) :: sfr_surf
901
902 REAL(KIND(1D0)), INTENT(IN) :: SoilStoreCap_paved
903 REAL(KIND(1D0)), INTENT(IN) :: SoilStoreCap_bldg
904 REAL(KIND(1D0)), INTENT(IN) :: SoilStoreCap_evetr
905 REAL(KIND(1D0)), INTENT(IN) :: SoilStoreCap_dectr
906 REAL(KIND(1D0)), INTENT(IN) :: SoilStoreCap_grass
907 REAL(KIND(1D0)), INTENT(IN) :: SoilStoreCap_bsoil
908 REAL(KIND(1D0)), INTENT(IN) :: SoilStoreCap_water
909 REAL(KIND(1D0)), DIMENSION(nsurf) :: SoilStoreCap
910
911 REAL(KIND(1D0)), INTENT(out) :: SoilMoistCap, SoilState
912 REAL(KIND(1D0)), INTENT(out) :: vsmd, smd
913
914 INTEGER :: is
915 REAL(KIND(1D0)) :: fveg
916
917 sfr_surf = [sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water]
918 soilstorecap(1) = soilstorecap_paved
919 soilstorecap(2) = soilstorecap_bldg
920 soilstorecap(3) = soilstorecap_evetr
921 soilstorecap(4) = soilstorecap_dectr
922 soilstorecap(5) = soilstorecap_grass
923 soilstorecap(6) = soilstorecap_bsoil
924 soilstorecap(7) = soilstorecap_water
925
926 soilmoistcap = 0 !Maximum capacity of soil store [mm] for whole surface
927 soilstate = 0 !Area-averaged soil moisture [mm] for whole surface
928
929 IF (nonwaterfraction /= 0) THEN !Soil states only calculated if soil exists. LJ June 2017
930 DO is = 1, nsurf - 1 !No water body included
931 soilmoistcap = soilmoistcap + (soilstorecap(is)*sfr_surf(is)/nonwaterfraction)
932 soilstate = soilstate + (soilstore_id(is)*sfr_surf(is)/nonwaterfraction)
933 END DO
934 END IF
935
936 !If loop removed HCW 26 Feb 2015
937 !if (ir==1) then !Calculate initial smd
938 smd = soilmoistcap - soilstate
939 !endif
940
941 ! Calculate soil moisture for vegetated surfaces only (for use in surface conductance)
942 ! vsmd = 0
943 ! IF ((sfr_surf(ConifSurf) + sfr_surf(DecidSurf) + sfr_surf(GrassSurf)) > 0) THEN
944
945 ! fveg = sfr_surf(is)/(sfr_surf(ConifSurf) + sfr_surf(DecidSurf) + sfr_surf(GrassSurf))
946 ! ELSE
947 ! fveg = 0
948 ! END IF
949 ! DO is = ConifSurf, GrassSurf !Vegetated surfaces only
950 ! IF (fveg == 0) THEN
951 ! vsmd = 0
952 ! ELSE
953 ! vsmd = vsmd + (SoilStoreCap(is) - soilstore_id(is))*sfr_surf(is)/fveg
954 ! END IF
955 ! !write(*,*) is, vsmd, smd
956 ! END DO
957
958 vsmd = cal_smd_veg(soilstorecap, soilstore_id, sfr_surf)
959
960 END SUBROUTINE suews_update_soilmoist_dts
961 !------------------------------------------------------------------------------
962
963 ! calculate soil moisture deficit for vegetated surfaces only (for use in surface conductance)
964 FUNCTION cal_smd_veg(SoilStoreCap, soilstore_id, sfr_surf) RESULT(vsmd)
965 IMPLICIT NONE
966
967 REAL(kind(1d0)), INTENT(in), DIMENSION(nsurf) :: soilstorecap, soilstore_id, sfr_surf
968 REAL(kind(1d0)) :: vsmd
969
970 REAL(kind(1d0)), DIMENSION(nsurf) :: smd_surf
971 REAL(kind(1d0)), DIMENSION(3) :: surf_veg, smd_veg
972 INTEGER :: is
973
974 vsmd = 0
975
976 ! calculate the soil moisture deficit for each vegetated surface
977 smd_surf = soilstorecap - soilstore_id
978 smd_veg = [(smd_surf(is), is=conifsurf, grasssurf)]
979
980 ! calculate the fraction of each vegetated surface among all vegetated surfaces
981 surf_veg = [(sfr_surf(is), is=conifsurf, grasssurf)]
982 surf_veg = surf_veg/sum(surf_veg)
983
984 ! calculate the weighted soil moisture deficit for vegetated surfaces
985 vsmd = dot_product(smd_veg, surf_veg)
986
987 END FUNCTION cal_smd_veg
988
989 !========== Calculate soil moisture of a whole grid ============
991 SMDMethod, xsmd, NonWaterFraction, SoilMoistCap, & !input
992 SoilStoreCap, surf_chang_per_tstep, &
993 soilstore_id, soilstoreOld, sfr_surf, &
994 smd, smd_nsurf, tot_chang_per_tstep, SoilState) !output
995
996 IMPLICIT NONE
997 ! INTEGER, PARAMETER :: nsurf = 7
998
999 INTEGER, INTENT(in) :: SMDMethod
1000 REAL(KIND(1D0)), INTENT(in) :: xsmd
1001 REAL(KIND(1D0)), INTENT(in) :: NonWaterFraction
1002 REAL(KIND(1D0)), INTENT(in) :: SoilMoistCap
1003
1004 REAL(KIND(1D0)), INTENT(in) :: surf_chang_per_tstep
1005 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: soilstore_id !Soil moisture of each surface type [mm]
1006 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: soilstoreOld !Soil moisture of each surface type from previous timestep [mm]
1007 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: sfr_surf
1008 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: SoilStoreCap !Capacity of soil store for each surface [mm]
1009
1010 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: smd_nsurf !smd for each surface
1011 REAL(KIND(1D0)), INTENT(out) :: SoilState !Area-averaged soil moisture [mm] for whole surface
1012 REAL(KIND(1D0)), INTENT(out) :: smd !One value for whole surface
1013 REAL(KIND(1D0)), INTENT(out) :: tot_chang_per_tstep !Change in surface state_id
1014
1015 REAL(KIND(1D0)), PARAMETER :: NotUsed = -999
1016 REAL(KIND(1D0)), PARAMETER :: NAN = -999
1017 INTEGER :: is
1018
1019 soilstate = 0 !Area-averaged soil moisture [mm] for whole surface
1020 IF (nonwaterfraction /= 0) THEN !Fixed for water surfaces only
1021 DO is = 1, nsurf - 1 !No water body included
1022 soilstate = soilstate + (soilstore_id(is)*sfr_surf(is)/nonwaterfraction)
1023 IF (soilstate < 0) THEN
1024 CALL errorhint(62, 'SUEWS_Calculations: total SoilState < 0 (just added surface is) ', soilstate, notused, is)
1025 ELSEIF (soilstate > soilmoistcap) THEN
1026 CALL errorhint(62, 'SUEWS_Calculations: total SoilState > capacity (just added surface is) ', soilstate, notused, is)
1027 !SoilMoist_state=SoilMoistCap !What is this LJ 10/2010 - QUESTION: SM exceeds capacity, but where does extra go?HCW 11/2014
1028 END IF
1029 END DO !end loop over surfaces
1030 ! SoilState = DOT_PRODUCT(soilstore_id(1:nsurf - 1), sfr_surf(1:nsurf - 1))/NonWaterFraction
1031 ! IF (SoilState < 0) THEN
1032 ! CALL ErrorHint(62, 'SUEWS_Calculations: total SoilState < 0 (just added surface is) ', SoilState, NotUsed, is)
1033 ! ELSEIF (SoilState > SoilMoistCap) THEN
1034 ! CALL ErrorHint(62, 'SUEWS_Calculations: total SoilState > capacity (just added surface is) ', SoilState, NotUsed, is)
1035 ! !SoilMoist_state=SoilMoistCap !What is this LJ 10/2010 - QUESTION: SM exceeds capacity, but where does extra go?HCW 11/2014
1036 ! ENDIF
1037 END IF
1038
1039 ! Calculate soil moisture deficit
1040 smd = soilmoistcap - soilstate !One value for whole surface
1041 smd_nsurf = soilstorecap - soilstore_id !smd for each surface
1042
1043 ! Soil stores can change after horizontal water movements
1044 ! Calculate total change in surface and soil state_id
1045 tot_chang_per_tstep = surf_chang_per_tstep !Change in surface state_id
1046 DO is = 1, (nsurf - 1) !No soil for water surface (so change in soil moisture is zero)
1047 tot_chang_per_tstep = tot_chang_per_tstep + ((soilstore_id(is) - soilstoreold(is))*sfr_surf(is)) !Add change in soil state_id
1048 END DO
1049
1050 IF (smdmethod > 0) THEN ! use observed value
1051 ! smd_nsurf=NAN
1052 smd_nsurf = nan
1053 smd = xsmd
1054 END IF
1055
1056 END SUBROUTINE suews_cal_soilstate
1057
1059 SMDMethod, xsmd, NonWaterFraction, SoilMoistCap, & !input
1060 SoilStoreCap_paved, SoilStoreCap_bldg, SoilStoreCap_evetr, &
1061 SoilStoreCap_dectr, SoilStoreCap_grass, SoilStoreCap_bsoil, SoilStoreCap_water, &
1062 surf_chang_per_tstep, &
1063 soilstore_id, soilstoreOld, &
1064 sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, &
1065 smd, smd_nsurf, tot_chang_per_tstep, SoilState) !output
1066
1067 IMPLICIT NONE
1068 ! INTEGER, PARAMETER :: nsurf = 7
1069
1070 INTEGER, INTENT(in) :: SMDMethod
1071 REAL(KIND(1D0)), INTENT(in) :: xsmd
1072 REAL(KIND(1D0)), INTENT(in) :: NonWaterFraction
1073 REAL(KIND(1D0)), INTENT(in) :: SoilMoistCap
1074
1075 REAL(KIND(1D0)), INTENT(in) :: surf_chang_per_tstep
1076 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: soilstore_id !Soil moisture of each surface type [mm]
1077 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: soilstoreOld !Soil moisture of each surface type from previous timestep [mm]
1078
1079 REAL(KIND(1D0)), INTENT(IN) :: sfr_paved
1080 REAL(KIND(1D0)), INTENT(IN) :: sfr_bldg
1081 REAL(KIND(1D0)), INTENT(IN) :: sfr_evetr
1082 REAL(KIND(1D0)), INTENT(IN) :: sfr_dectr
1083 REAL(KIND(1D0)), INTENT(IN) :: sfr_grass
1084 REAL(KIND(1D0)), INTENT(IN) :: sfr_bsoil
1085 REAL(KIND(1D0)), INTENT(IN) :: sfr_water
1086 REAL(KIND(1D0)), DIMENSION(NSURF) :: sfr_surf !surface fraction [-]
1087
1088 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_paved
1089 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_bldg
1090 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_evetr
1091 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_dectr
1092 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_grass
1093 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_bsoil
1094 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_water
1095 REAL(KIND(1D0)), DIMENSION(nsurf) :: SoilStoreCap !Capacity of soil store for each surface [mm]
1096
1097 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: smd_nsurf !smd for each surface
1098 REAL(KIND(1D0)), INTENT(out) :: SoilState !Area-averaged soil moisture [mm] for whole surface
1099 REAL(KIND(1D0)), INTENT(out) :: smd !One value for whole surface
1100 REAL(KIND(1D0)), INTENT(out) :: tot_chang_per_tstep !Change in surface state_id
1101
1102 REAL(KIND(1D0)), PARAMETER :: NotUsed = -999
1103 REAL(KIND(1D0)), PARAMETER :: NAN = -999
1104 INTEGER :: is
1105
1106 sfr_surf = [sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water]
1107 soilstorecap(1) = soilstorecap_paved
1108 soilstorecap(2) = soilstorecap_bldg
1109 soilstorecap(3) = soilstorecap_evetr
1110 soilstorecap(4) = soilstorecap_dectr
1111 soilstorecap(5) = soilstorecap_grass
1112 soilstorecap(6) = soilstorecap_bsoil
1113 soilstorecap(7) = soilstorecap_water
1114
1115 soilstate = 0 !Area-averaged soil moisture [mm] for whole surface
1116 IF (nonwaterfraction /= 0) THEN !Fixed for water surfaces only
1117 DO is = 1, nsurf - 1 !No water body included
1118 soilstate = soilstate + (soilstore_id(is)*sfr_surf(is)/nonwaterfraction)
1119 IF (soilstate < 0) THEN
1120 CALL errorhint(62, 'SUEWS_Calculations: total SoilState < 0 (just added surface is) ', soilstate, notused, is)
1121 ELSEIF (soilstate > soilmoistcap) THEN
1122 CALL errorhint(62, 'SUEWS_Calculations: total SoilState > capacity (just added surface is) ', soilstate, notused, is)
1123 !SoilMoist_state=SoilMoistCap !What is this LJ 10/2010 - QUESTION: SM exceeds capacity, but where does extra go?HCW 11/2014
1124 END IF
1125 END DO !end loop over surfaces
1126 ! SoilState = DOT_PRODUCT(soilstore_id(1:nsurf - 1), sfr_surf(1:nsurf - 1))/NonWaterFraction
1127 ! IF (SoilState < 0) THEN
1128 ! CALL ErrorHint(62, 'SUEWS_Calculations: total SoilState < 0 (just added surface is) ', SoilState, NotUsed, is)
1129 ! ELSEIF (SoilState > SoilMoistCap) THEN
1130 ! CALL ErrorHint(62, 'SUEWS_Calculations: total SoilState > capacity (just added surface is) ', SoilState, NotUsed, is)
1131 ! !SoilMoist_state=SoilMoistCap !What is this LJ 10/2010 - QUESTION: SM exceeds capacity, but where does extra go?HCW 11/2014
1132 ! ENDIF
1133 END IF
1134
1135 ! Calculate soil moisture deficit
1136 smd = soilmoistcap - soilstate !One value for whole surface
1137 smd_nsurf = soilstorecap - soilstore_id !smd for each surface
1138
1139 ! Soil stores can change after horizontal water movements
1140 ! Calculate total change in surface and soil state_id
1141 tot_chang_per_tstep = surf_chang_per_tstep !Change in surface state_id
1142 DO is = 1, (nsurf - 1) !No soil for water surface (so change in soil moisture is zero)
1143 tot_chang_per_tstep = tot_chang_per_tstep + ((soilstore_id(is) - soilstoreold(is))*sfr_surf(is)) !Add change in soil state_id
1144 END DO
1145
1146 IF (smdmethod > 0) THEN ! use observed value
1147 ! smd_nsurf=NAN
1148 smd_nsurf = nan
1149 smd = xsmd
1150 END IF
1151
1152 END SUBROUTINE suews_cal_soilstate_dts
1153 !===================================================================================
1154
1156 sfr_surf, & ! input: ! surface fractions
1157 SoilStoreCap, & !Capacity of soil store for each surface [mm]
1158 SoilDepth, & !Depth of sub-surface soil store for each surface [mm]
1159 SatHydraulicConduct, & !Saturated hydraulic conductivity for each soil subsurface [mm s-1]
1160 SurfaceArea, & !Surface area of the study area [m2]
1161 NonWaterFraction, & ! sum of surface cover fractions for all except water surfaces
1162 tstep_real, & !tstep cast as a real for use in calculations
1163 soilstore_id, & ! inout: !Soil moisture of each surface type [mm]
1164 runoffSoil, & !Soil runoff from each soil sub-surface [mm]
1165 runoffSoil_per_tstep & ! output:!Runoff to deep soil per timestep [mm] (for whole surface, excluding water body)
1166 )
1167 !Transfers water in soil stores of land surfaces LJ (2010)
1168 !Change the model to use varying hydraulic conductivity instead of constant value LJ (7/2011)
1169 !If one of the surface's soildepth is zero, no water movement is considered
1170 ! LJ 15/06/2017 Modification: - Moved location of runoffSoil_per_tstep within previous if-loop to avoid dividing with zero with 100% water surface
1171 ! HCW 22/02/2017 Modifications: - Minor bug fixed in VWC1/B_r1 comparison - if statements reversed
1172 ! HCW 13/08/2014 Modifications: - Order of surfaces reversed (for both is and jj loops)
1173 ! - Number of units (e.g. properties) added to distance calculation
1174 ! HCW 12/08/2014 Modifications: - Distance changed from m to mm in dI_dt calculation
1175 ! - dI_dt [mm s-1] multiplied by no. seconds in timestep -> dI [mm]
1176 ! - if MatPot is set to max. value (100000 mm), Km set to 0 mm s-1
1177 ! - Provide parameters for residual volumetric soil moisture [m3 m-3]
1178 ! (currently hard coded as 0.1 m3 m-3 for testing)
1179 !
1180 !------------------------------------------------------
1181 ! use SUES_data
1182 ! use gis_data
1183 ! use time
1184 ! use allocateArray
1185
1186 IMPLICIT NONE
1187
1188 REAL(KIND(1D0)), INTENT(in) :: sfr_surf(nsurf) ! surface fractions
1189 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap(nsurf) !Capacity of soil store for each surface [mm]
1190 REAL(KIND(1D0)), INTENT(in) :: SoilDepth(nsurf) !Depth of sub-surface soil store for each surface [mm]
1191 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct(nsurf) !Saturated hydraulic conductivity for each soil subsurface [mm s-1]
1192 REAL(KIND(1D0)), INTENT(in) :: SurfaceArea !Surface area of the study area [m2]
1193 REAL(KIND(1D0)), INTENT(in) :: NonWaterFraction ! sum of surface cover fractions for all except water surfaces
1194 REAL(KIND(1D0)), INTENT(in) :: tstep_real !tstep cast as a real for use in calculations
1195
1196 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(inout) :: soilstore_id !Soil moisture of each surface type [mm]
1197 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: runoffSoil !Soil runoff from each soil sub-surface [mm]
1198
1199 REAL(KIND(1D0)), INTENT(out) :: runoffSoil_per_tstep !Runoff to deep soil per timestep [mm] (for whole surface, excluding water body)
1200
1201 INTEGER :: jj, is
1202 REAL(KIND(1D0)) :: &
1203 DimenWaterCon1, DimenWaterCon2, &
1204 SoilMoistCap_Vol1, &
1205 SoilMoist_vol1, &
1206 SoilMoistCap_Vol2, &
1207 SoilMoist_vol2, &
1208 B_r1, MatPot1, Km1, &
1209 B_r2, MatPot2, Km2, &
1210 Distance, KmWeight, dI, &
1211 dI_dt !Water flow between two stores
1212
1213 REAL(KIND(1D0)), PARAMETER :: &
1214 alphavG = 0.0005, & !Set alphavG to match value in van Genuchten (1980) [mm-1]
1215 nunits = 1 !Can change to represent plot/base unit size
1216
1217 ! SoilMoist_vol1,2 = Volumetric soil moisture [m3 m-3]
1218 ! SoilMoistCap_vol1,2 = Volumetric soil moisture capacity [m3 m-3] (from FunctionalTypes)
1219 ! MatPot1,2 = Water potential (i.e. pressure head) of store [mm]
1220 ! DimenWaterCon1,2 = Dimensionless water content, or relative saturation [-]
1221 ! Distance = Distance between two stores [m]
1222 ! B_r1,2 = Residual volumetric soil moisture [m3 m-3]
1223 ! Km1,2 = Hydraulic conductivity of store [mm s-1]
1224 ! KmWeight = Weighted hydraulic conductivity [mm s-1]
1225 ! alphavG = Parameter (could depend on soil texture) [mm-1]
1226 ! dI = Water flow between stores [mm] dI = dI_dt * no. secs in each timestep
1227 ! if dI > 0, first surface gains water, second surface loses water
1228 ! NUnits = Number of repeating units (e.g. properties, blocks) for distance calculation [-]
1229 runoffsoil = 0
1230 runoffsoil_per_tstep = 0
1231
1232 DO is = 1, nsurf - 1 !nsurf-1,1,-1 !Loop through each surface, excluding water surface (runs backwards as of 13/08/2014, HCW)
1233
1234 IF (sfr_surf(is) /= 0 .AND. soilstorecap(is) > 0) THEN !If particular surface area exists
1235 ! and is capable of storing water (SoilStoreCap [mm])
1236 DO jj = is + 1, nsurf - 1 !is-1,1,-1 !Sub-loop through remaining surfaces (runs backwards as of 13/08/2014, HCW)
1237
1238 IF (sfr_surf(jj) /= 0 .AND. soilstorecap(jj) > 0) THEN !If other surface area exists
1239 ! and is capable of storing water
1240
1241 ! ---- For surface 1 -----------------------------------------------------
1242 ! Calculate non-saturated VWC
1243 soilmoistcap_vol1 = soilstorecap(is)/soildepth(is) !Volumetric soil moisture capacity [m3 m-3] (i.e. saturated VWC)
1244 soilmoist_vol1 = soilstore_id(is)/soildepth(is) !Volumetric soil moisture [m3 m-3]
1245
1246 !B_r1=SoilMoistCap_Vol1-SoilMoist_vol1 !Residual soil moisture content [m3 m-3]
1247 b_r1 = 0.1 !HCW 12/08/2014 Temporary fix
1248 ! Need to add residual soil moisture values to FunctionalTypes
1249 !B_r1=VolSoilMoistRes(is) !Residual soil moisture content [m3 m-3]
1250
1251 !Order of if statements reversed HCW 22 Feb 2017
1252 !If soil moisture less than or equal to residual value, set MatPot to max and Km to 0 to suppress water movement
1253 IF (b_r1 >= soilmoist_vol1) THEN
1254 matpot1 = 100000
1255 km1 = 0 !Added by LJ in Nov 2013
1256 ! Otherwise, there should be enough water in the soil to allow horizontal transfer
1257 ELSE
1258 dimenwatercon1 = (soilmoist_vol1 - b_r1)/(soilmoistcap_vol1 - b_r1) !Dimensionless water content [-]
1259
1260 ! If very large or very small, adjust for calculation of MatPot and Km
1261 IF (dimenwatercon1 > 0.99999) THEN
1262 dimenwatercon1 = dimenwatercon1 - 0.0001 !This cannot equal 1
1263 END IF
1264
1265 IF (dimenwatercon1 < 0.00000005) THEN
1266 dimenwatercon1 = dimenwatercon1 + 0.0000001 !Added HCW 22 Feb 2017
1267 END IF
1268
1269 !van Genuchten (1980), with n=2 and m = 1-1/n = 1/2
1270 !Water potential of first store [mm] (van Genuchten 1980, Eq 3 rearranged)
1271 matpot1 = sqrt(1/dimenwatercon1**2 - 1)/alphavg
1272
1273 !Hydraulic conductivity of first store [mm s-1] (van Genuchten 1980, Eq 8)
1274 km1 = sathydraulicconduct(is)*sqrt(dimenwatercon1)*(1 - (1 - dimenwatercon1**2)**0.5)**2
1275
1276 !Check this value (HCW 12/08/2014)
1277 IF (matpot1 > 100000) THEN
1278 matpot1 = 100000 !Max. potential is 100000 mm (van Genuchten 1980)
1279 km1 = 0 !Added by HCW 12/08/2014
1280 END IF
1281
1282 END IF
1283
1284 ! ---- For surface 2 -----------------------------------------------------
1285 ! Calculate non-saturated VWC
1286 soilmoistcap_vol2 = soilstorecap(jj)/soildepth(jj) !Volumetric soil moisture capacity [m3 m-3] (i.e. saturated VWC)
1287 soilmoist_vol2 = soilstore_id(jj)/soildepth(jj) !Volumetric soil moisture [m3 m-3]
1288
1289 !B_r2=SoilMoistCap_Vol2-SoilMoist_vol2 !Residual soil moisture content [m3 m-3]
1290 b_r2 = 0.1 !HCW 12/08/2014 Temporary fix
1291 ! Need to add residual soil moisture values to FunctionalTypes
1292 !B_r2=VolSoilMoistRes(jj) !Residual soil moisture content [m3 m-3]
1293
1294 !If soil moisture below residual value, set MatPot to maximum
1295 IF (b_r2 >= soilmoist_vol2) THEN
1296 matpot2 = 100000
1297 km2 = 0 !Added by LJ in Nov 2013
1298 ELSE
1299 dimenwatercon2 = (soilmoist_vol2 - b_r2)/(soilmoistcap_vol2 - b_r2) !Dimensionless water content [-]
1300
1301 IF (dimenwatercon2 > 0.99999) THEN
1302 dimenwatercon2 = dimenwatercon2 - 0.0001 !This cannot equal 1
1303 END IF
1304
1305 IF (dimenwatercon2 < 0.00000005) THEN
1306 dimenwatercon2 = dimenwatercon2 + 0.0000001 !Added HCW 22 Feb 2017
1307 END IF
1308 ! print*, 'soilstore_id = ', soilstore_id
1309 ! print*, 'SoilStoreCap = ', SoilStoreCap
1310 ! print*, 'SoilDepth = ', SoilDepth
1311 ! print*, 'SoilMoist_vol2 = ', SoilMoist_vol2
1312 ! print*, 'SoilMoistCap_Vol2 = ', SoilMoistCap_Vol2
1313 ! print*, 'is = ', is, ' jj = ', jj, ' DimenWaterCon2 = ', DimenWaterCon2
1314 !van Genuchten (1980), with n=2 and m = 1-1/n = 1/2
1315 !Water potential of second store [mm] (van Genuchten 1980, Eq 3 rearranged)
1316 matpot2 = sqrt(1/dimenwatercon2**2 - 1)/alphavg
1317
1318 !Hydraulic conductivity of second store [mm s-1] (van Genuchten 1980, Eq 8)
1319 km2 = sathydraulicconduct(jj)*sqrt(dimenwatercon2)*(1 - (1 - dimenwatercon2**2)**0.5)**2
1320
1321 IF ((matpot2) > 100000) THEN
1322 matpot2 = 100000 !Max. potential is 100000 mm (van Genuchten 1980)
1323 km2 = 0 !Added by HCW 12/08/2014
1324 END IF
1325
1326 END IF
1327
1328 ! ------------------------------------------------------------------------
1329
1330 !Find distance between the two stores (see Jarvi et al. 2011)
1331 !SurfaceArea in m2 (changed from ha to m2 n SUEWS_Initial), so Distance in m
1332 distance = (sqrt(sfr_surf(is)*surfacearea/nunits) + sqrt(sfr_surf(jj)*surfacearea/nunits))/2
1333
1334 !Calculate areally-weighted hydraulic conductivity [mm s-1]
1335 kmweight = (sfr_surf(is)*km1 + sfr_surf(jj)*km2)/(sfr_surf(is) + sfr_surf(jj))
1336
1337 !Find water flow between the two stores [mm s-1] (Green-Ampt equation, Hillel 1971)
1338 !Multiply Distance by 1000 to convert m to mm (HCW 12/08/2014)
1339 di_dt = -(kmweight)*(-matpot1 + matpot2)/(distance*1000)
1340
1341 !Multiply dI_dt by number of seconds in timestep to convert mm s-1 to mm
1342 !Added by HCW 12/08/2014
1343 di = di_dt*tstep_real !Use dI instead of dI_dt in the following calculations
1344
1345 !Move water (in mm) ------------------------------------------------------
1346 !Water moves only if (i) there is sufficient water to move and (ii) there is space to move it
1347
1348 ! If there is sufficient water in both surfaces, allow movement of dI to occur
1349 IF ((soilstore_id(jj) >= di*sfr_surf(is)/sfr_surf(jj)) .AND. ((soilstore_id(is) + di) >= 0)) THEN
1350 soilstore_id(is) = soilstore_id(is) + di
1351 soilstore_id(jj) = soilstore_id(jj) - di*sfr_surf(is)/sfr_surf(jj) !Check (HCW 13/08/2014) - QUESTION: why adjust for jj and not is?
1352
1353 ! If insufficient water in first surface to move dI, instead move as much as possible
1354 ELSEIF ((soilstore_id(is) + di) < 0) THEN
1355 soilstore_id(jj) = soilstore_id(jj) + soilstore_id(is)*sfr_surf(is)/sfr_surf(jj) !HCW 12/08/2014 switched order of these two lines
1356 soilstore_id(is) = 0 !Check (HCW 13/08/2014) - QUESTION: can SM actually go to zero, or is this inconsistent with SMres?
1357
1358 ! If insufficient water in second surface to move dI, instead move as much as possible
1359 ELSE
1360 soilstore_id(is) = soilstore_id(is) + soilstore_id(jj)*sfr_surf(jj)/sfr_surf(is)
1361 soilstore_id(jj) = 0
1362 END IF
1363
1364 !If soil moisture exceeds capacity, excess goes to soil runoff (first surface)
1365 IF (soilstore_id(is) > soilstorecap(is)) THEN
1366 runoffsoil(is) = runoffsoil(is) + (soilstore_id(is) - soilstorecap(is))
1367 soilstore_id(is) = soilstorecap(is)
1368 !elseif (soilstore_id(is)<0) then !HCW 13/08/2014 commented out as should never be true here anyway...
1369 ! soilstore_id(is)=0 ! ... and if so, need to do more here (i.e. account for other water too)
1370 END IF
1371
1372 !If soil moisture exceeds capacity, excess goes to soil runoff (second surface)
1373 IF (soilstore_id(jj) > soilstorecap(jj)) THEN
1374 runoffsoil(jj) = runoffsoil(jj) + (soilstore_id(jj) - soilstorecap(jj))
1375 soilstore_id(jj) = soilstorecap(jj)
1376 !elseif (soilstore_id(jj)<0) then !HCW 13/08/2014 commented out (as above)
1377 ! soilstore_id(jj)=0
1378 END IF
1379
1380 END IF !end if second surface exists and is capable of storing water
1381
1382 END DO !end jj loop over second surface
1383
1384 runoffsoil_per_tstep = runoffsoil_per_tstep + (runoffsoil(is)*sfr_surf(is)/nonwaterfraction) !Excludes water body. Moved here as otherwise code crashed when NonWaterFraction=0
1385
1386 END IF !end if first surface exists and is capable of storing water
1387
1388 !runoffSoil_per_tstep=runoffSoil_per_tstep+(runoffSoil(is)*sfr_surf(is)/NonWaterFraction) !Excludes water body
1389
1390 END DO !is loop over first surface
1391
1392 END SUBROUTINE suews_cal_horizontalsoilwater
1393
1395 sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, & ! input: ! surface fractions
1396 SoilStoreCap_paved, SoilStoreCap_bldg, SoilStoreCap_evetr, &
1397 SoilStoreCap_dectr, SoilStoreCap_grass, SoilStoreCap_bsoil, SoilStoreCap_water, & !Capacity of soil store for each surface [mm]
1398 SoilDepth_paved, SoilDepth_bldg, SoilDepth_evetr, SoilDepth_dectr, SoilDepth_grass, SoilDepth_bsoil, SoilDepth_water, & !Depth of sub-surface soil store for each surface [mm]
1399 SatHydraulicConduct_paved, SatHydraulicConduct_bldg, &
1400 SatHydraulicConduct_evetr, SatHydraulicConduct_dectr, &
1401 SatHydraulicConduct_grass, SatHydraulicConduct_bsoil, SatHydraulicConduct_water, & !Saturated hydraulic conductivity for each soil subsurface [mm s-1]
1402 SurfaceArea, & !Surface area of the study area [m2]
1403 NonWaterFraction, & ! sum of surface cover fractions for all except water surfaces
1404 tstep_real, & !tstep cast as a real for use in calculations
1405 soilstore_id, & ! inout: !Soil moisture of each surface type [mm]
1406 runoffSoil, & !Soil runoff from each soil sub-surface [mm]
1407 runoffSoil_per_tstep & ! output:!Runoff to deep soil per timestep [mm] (for whole surface, excluding water body)
1408 )
1409 !Transfers water in soil stores of land surfaces LJ (2010)
1410 !Change the model to use varying hydraulic conductivity instead of constant value LJ (7/2011)
1411 !If one of the surface's soildepth is zero, no water movement is considered
1412 ! LJ 15/06/2017 Modification: - Moved location of runoffSoil_per_tstep within previous if-loop to avoid dividing with zero with 100% water surface
1413 ! HCW 22/02/2017 Modifications: - Minor bug fixed in VWC1/B_r1 comparison - if statements reversed
1414 ! HCW 13/08/2014 Modifications: - Order of surfaces reversed (for both is and jj loops)
1415 ! - Number of units (e.g. properties) added to distance calculation
1416 ! HCW 12/08/2014 Modifications: - Distance changed from m to mm in dI_dt calculation
1417 ! - dI_dt [mm s-1] multiplied by no. seconds in timestep -> dI [mm]
1418 ! - if MatPot is set to max. value (100000 mm), Km set to 0 mm s-1
1419 ! - Provide parameters for residual volumetric soil moisture [m3 m-3]
1420 ! (currently hard coded as 0.1 m3 m-3 for testing)
1421 !
1422 !------------------------------------------------------
1423 ! use SUES_data
1424 ! use gis_data
1425 ! use time
1426 ! use allocateArray
1427
1428 IMPLICIT NONE
1429
1430 REAL(KIND(1D0)), INTENT(IN) :: sfr_paved
1431 REAL(KIND(1D0)), INTENT(IN) :: sfr_bldg
1432 REAL(KIND(1D0)), INTENT(IN) :: sfr_evetr
1433 REAL(KIND(1D0)), INTENT(IN) :: sfr_dectr
1434 REAL(KIND(1D0)), INTENT(IN) :: sfr_grass
1435 REAL(KIND(1D0)), INTENT(IN) :: sfr_bsoil
1436 REAL(KIND(1D0)), INTENT(IN) :: sfr_water
1437 REAL(KIND(1D0)), DIMENSION(NSURF) :: sfr_surf !surface fraction [-]
1438
1439 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_paved
1440 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_bldg
1441 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_evetr
1442 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_dectr
1443 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_grass
1444 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_bsoil
1445 REAL(KIND(1D0)), INTENT(in) :: SoilStoreCap_water
1446 REAL(KIND(1D0)), DIMENSION(nsurf) :: SoilStoreCap !Capacity of soil store for each surface [mm]
1447
1448 REAL(KIND(1D0)), INTENT(in) :: SoilDepth_paved
1449 REAL(KIND(1D0)), INTENT(in) :: SoilDepth_bldg
1450 REAL(KIND(1D0)), INTENT(in) :: SoilDepth_evetr
1451 REAL(KIND(1D0)), INTENT(in) :: SoilDepth_dectr
1452 REAL(KIND(1D0)), INTENT(in) :: SoilDepth_grass
1453 REAL(KIND(1D0)), INTENT(in) :: SoilDepth_bsoil
1454 REAL(KIND(1D0)), INTENT(in) :: SoilDepth_water
1455 REAL(KIND(1D0)), DIMENSION(nsurf) :: SoilDepth !Depth of sub-surface soil store for each surface [mm]
1456
1457 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct_paved
1458 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct_bldg
1459 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct_evetr
1460 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct_dectr
1461 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct_grass
1462 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct_bsoil
1463 REAL(KIND(1D0)), INTENT(in) :: SatHydraulicConduct_water
1464 REAL(KIND(1D0)), DIMENSION(nsurf) :: SatHydraulicConduct !Saturated hydraulic conductivity for each soil subsurface [mm s-1]
1465
1466 REAL(KIND(1D0)), INTENT(in) :: SurfaceArea !Surface area of the study area [m2]
1467 REAL(KIND(1D0)), INTENT(in) :: NonWaterFraction ! sum of surface cover fractions for all except water surfaces
1468 REAL(KIND(1D0)), INTENT(in) :: tstep_real !tstep cast as a real for use in calculations
1469
1470 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(inout) :: soilstore_id !Soil moisture of each surface type [mm]
1471 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: runoffSoil !Soil runoff from each soil sub-surface [mm]
1472
1473 REAL(KIND(1D0)), INTENT(out) :: runoffSoil_per_tstep !Runoff to deep soil per timestep [mm] (for whole surface, excluding water body)
1474
1475 INTEGER :: jj, is
1476 REAL(KIND(1D0)) :: &
1477 DimenWaterCon1, DimenWaterCon2, &
1478 SoilMoistCap_Vol1, &
1479 SoilMoist_vol1, &
1480 SoilMoistCap_Vol2, &
1481 SoilMoist_vol2, &
1482 B_r1, MatPot1, Km1, &
1483 B_r2, MatPot2, Km2, &
1484 Distance, KmWeight, dI, &
1485 dI_dt !Water flow between two stores
1486
1487 REAL(KIND(1D0)), PARAMETER :: &
1488 alphavG = 0.0005, & !Set alphavG to match value in van Genuchten (1980) [mm-1]
1489 nunits = 1 !Can change to represent plot/base unit size
1490
1491 ! SoilMoist_vol1,2 = Volumetric soil moisture [m3 m-3]
1492 ! SoilMoistCap_vol1,2 = Volumetric soil moisture capacity [m3 m-3] (from FunctionalTypes)
1493 ! MatPot1,2 = Water potential (i.e. pressure head) of store [mm]
1494 ! DimenWaterCon1,2 = Dimensionless water content, or relative saturation [-]
1495 ! Distance = Distance between two stores [m]
1496 ! B_r1,2 = Residual volumetric soil moisture [m3 m-3]
1497 ! Km1,2 = Hydraulic conductivity of store [mm s-1]
1498 ! KmWeight = Weighted hydraulic conductivity [mm s-1]
1499 ! alphavG = Parameter (could depend on soil texture) [mm-1]
1500 ! dI = Water flow between stores [mm] dI = dI_dt * no. secs in each timestep
1501 ! if dI > 0, first surface gains water, second surface loses water
1502 ! NUnits = Number of repeating units (e.g. properties, blocks) for distance calculation [-]
1503 runoffsoil = 0
1504 runoffsoil_per_tstep = 0
1505
1506 sfr_surf = [sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water]
1507 soilstorecap(1) = soilstorecap_paved
1508 soilstorecap(2) = soilstorecap_bldg
1509 soilstorecap(3) = soilstorecap_evetr
1510 soilstorecap(4) = soilstorecap_dectr
1511 soilstorecap(5) = soilstorecap_grass
1512 soilstorecap(6) = soilstorecap_bsoil
1513 soilstorecap(7) = soilstorecap_water
1514
1515 soildepth(1) = soildepth_paved
1516 soildepth(2) = soildepth_bldg
1517 soildepth(3) = soildepth_evetr
1518 soildepth(4) = soildepth_dectr
1519 soildepth(5) = soildepth_grass
1520 soildepth(6) = soildepth_bsoil
1521 soildepth(7) = soildepth_water
1522
1523 sathydraulicconduct(1) = sathydraulicconduct_paved
1524 sathydraulicconduct(2) = sathydraulicconduct_bldg
1525 sathydraulicconduct(3) = sathydraulicconduct_evetr
1526 sathydraulicconduct(4) = sathydraulicconduct_dectr
1527 sathydraulicconduct(5) = sathydraulicconduct_grass
1528 sathydraulicconduct(6) = sathydraulicconduct_bsoil
1529 sathydraulicconduct(7) = sathydraulicconduct_water
1530
1531 DO is = 1, nsurf - 1 !nsurf-1,1,-1 !Loop through each surface, excluding water surface (runs backwards as of 13/08/2014, HCW)
1532
1533 IF (sfr_surf(is) /= 0 .AND. soilstorecap(is) > 0) THEN !If particular surface area exists
1534 ! and is capable of storing water (SoilStoreCap [mm])
1535 DO jj = is + 1, nsurf - 1 !is-1,1,-1 !Sub-loop through remaining surfaces (runs backwards as of 13/08/2014, HCW)
1536
1537 IF (sfr_surf(jj) /= 0 .AND. soilstorecap(jj) > 0) THEN !If other surface area exists
1538 ! and is capable of storing water
1539
1540 ! ---- For surface 1 -----------------------------------------------------
1541 ! Calculate non-saturated VWC
1542 soilmoistcap_vol1 = soilstorecap(is)/soildepth(is) !Volumetric soil moisture capacity [m3 m-3] (i.e. saturated VWC)
1543 soilmoist_vol1 = soilstore_id(is)/soildepth(is) !Volumetric soil moisture [m3 m-3]
1544
1545 !B_r1=SoilMoistCap_Vol1-SoilMoist_vol1 !Residual soil moisture content [m3 m-3]
1546 b_r1 = 0.1 !HCW 12/08/2014 Temporary fix
1547 ! Need to add residual soil moisture values to FunctionalTypes
1548 !B_r1=VolSoilMoistRes(is) !Residual soil moisture content [m3 m-3]
1549
1550 !Order of if statements reversed HCW 22 Feb 2017
1551 !If soil moisture less than or equal to residual value, set MatPot to max and Km to 0 to suppress water movement
1552 IF (b_r1 >= soilmoist_vol1) THEN
1553 matpot1 = 100000
1554 km1 = 0 !Added by LJ in Nov 2013
1555 ! Otherwise, there should be enough water in the soil to allow horizontal transfer
1556 ELSE
1557 dimenwatercon1 = (soilmoist_vol1 - b_r1)/(soilmoistcap_vol1 - b_r1) !Dimensionless water content [-]
1558
1559 ! If very large or very small, adjust for calculation of MatPot and Km
1560 IF (dimenwatercon1 > 0.99999) THEN
1561 dimenwatercon1 = dimenwatercon1 - 0.0001 !This cannot equal 1
1562 END IF
1563
1564 IF (dimenwatercon1 < 0.00000005) THEN
1565 dimenwatercon1 = dimenwatercon1 + 0.0000001 !Added HCW 22 Feb 2017
1566 END IF
1567
1568 !van Genuchten (1980), with n=2 and m = 1-1/n = 1/2
1569 !Water potential of first store [mm] (van Genuchten 1980, Eq 3 rearranged)
1570 matpot1 = sqrt(1/dimenwatercon1**2 - 1)/alphavg
1571
1572 !Hydraulic conductivity of first store [mm s-1] (van Genuchten 1980, Eq 8)
1573 km1 = sathydraulicconduct(is)*sqrt(dimenwatercon1)*(1 - (1 - dimenwatercon1**2)**0.5)**2
1574
1575 !Check this value (HCW 12/08/2014)
1576 IF (matpot1 > 100000) THEN
1577 matpot1 = 100000 !Max. potential is 100000 mm (van Genuchten 1980)
1578 km1 = 0 !Added by HCW 12/08/2014
1579 END IF
1580
1581 END IF
1582
1583 ! ---- For surface 2 -----------------------------------------------------
1584 ! Calculate non-saturated VWC
1585 soilmoistcap_vol2 = soilstorecap(jj)/soildepth(jj) !Volumetric soil moisture capacity [m3 m-3] (i.e. saturated VWC)
1586 soilmoist_vol2 = soilstore_id(jj)/soildepth(jj) !Volumetric soil moisture [m3 m-3]
1587
1588 !B_r2=SoilMoistCap_Vol2-SoilMoist_vol2 !Residual soil moisture content [m3 m-3]
1589 b_r2 = 0.1 !HCW 12/08/2014 Temporary fix
1590 ! Need to add residual soil moisture values to FunctionalTypes
1591 !B_r2=VolSoilMoistRes(jj) !Residual soil moisture content [m3 m-3]
1592
1593 !If soil moisture below residual value, set MatPot to maximum
1594 IF (b_r2 >= soilmoist_vol2) THEN
1595 matpot2 = 100000
1596 km2 = 0 !Added by LJ in Nov 2013
1597 ELSE
1598 dimenwatercon2 = (soilmoist_vol2 - b_r2)/(soilmoistcap_vol2 - b_r2) !Dimensionless water content [-]
1599
1600 IF (dimenwatercon2 > 0.99999) THEN
1601 dimenwatercon2 = dimenwatercon2 - 0.0001 !This cannot equal 1
1602 END IF
1603
1604 IF (dimenwatercon2 < 0.00000005) THEN
1605 dimenwatercon2 = dimenwatercon2 + 0.0000001 !Added HCW 22 Feb 2017
1606 END IF
1607 ! print*, 'soilstore_id = ', soilstore_id
1608 ! print*, 'SoilStoreCap = ', SoilStoreCap
1609 ! print*, 'SoilDepth = ', SoilDepth
1610 ! print*, 'SoilMoist_vol2 = ', SoilMoist_vol2
1611 ! print*, 'SoilMoistCap_Vol2 = ', SoilMoistCap_Vol2
1612 ! print*, 'is = ', is, ' jj = ', jj, ' DimenWaterCon2 = ', DimenWaterCon2
1613 !van Genuchten (1980), with n=2 and m = 1-1/n = 1/2
1614 !Water potential of second store [mm] (van Genuchten 1980, Eq 3 rearranged)
1615 matpot2 = sqrt(1/dimenwatercon2**2 - 1)/alphavg
1616
1617 !Hydraulic conductivity of second store [mm s-1] (van Genuchten 1980, Eq 8)
1618 km2 = sathydraulicconduct(jj)*sqrt(dimenwatercon2)*(1 - (1 - dimenwatercon2**2)**0.5)**2
1619
1620 IF ((matpot2) > 100000) THEN
1621 matpot2 = 100000 !Max. potential is 100000 mm (van Genuchten 1980)
1622 km2 = 0 !Added by HCW 12/08/2014
1623 END IF
1624
1625 END IF
1626
1627 ! ------------------------------------------------------------------------
1628
1629 !Find distance between the two stores (see Jarvi et al. 2011)
1630 !SurfaceArea in m2 (changed from ha to m2 n SUEWS_Initial), so Distance in m
1631 distance = (sqrt(sfr_surf(is)*surfacearea/nunits) + sqrt(sfr_surf(jj)*surfacearea/nunits))/2
1632
1633 !Calculate areally-weighted hydraulic conductivity [mm s-1]
1634 kmweight = (sfr_surf(is)*km1 + sfr_surf(jj)*km2)/(sfr_surf(is) + sfr_surf(jj))
1635
1636 !Find water flow between the two stores [mm s-1] (Green-Ampt equation, Hillel 1971)
1637 !Multiply Distance by 1000 to convert m to mm (HCW 12/08/2014)
1638 di_dt = -(kmweight)*(-matpot1 + matpot2)/(distance*1000)
1639
1640 !Multiply dI_dt by number of seconds in timestep to convert mm s-1 to mm
1641 !Added by HCW 12/08/2014
1642 di = di_dt*tstep_real !Use dI instead of dI_dt in the following calculations
1643
1644 !Move water (in mm) ------------------------------------------------------
1645 !Water moves only if (i) there is sufficient water to move and (ii) there is space to move it
1646
1647 ! If there is sufficient water in both surfaces, allow movement of dI to occur
1648 IF ((soilstore_id(jj) >= di*sfr_surf(is)/sfr_surf(jj)) .AND. ((soilstore_id(is) + di) >= 0)) THEN
1649 soilstore_id(is) = soilstore_id(is) + di
1650 soilstore_id(jj) = soilstore_id(jj) - di*sfr_surf(is)/sfr_surf(jj) !Check (HCW 13/08/2014) - QUESTION: why adjust for jj and not is?
1651
1652 ! If insufficient water in first surface to move dI, instead move as much as possible
1653 ELSEIF ((soilstore_id(is) + di) < 0) THEN
1654 soilstore_id(jj) = soilstore_id(jj) + soilstore_id(is)*sfr_surf(is)/sfr_surf(jj) !HCW 12/08/2014 switched order of these two lines
1655 soilstore_id(is) = 0 !Check (HCW 13/08/2014) - QUESTION: can SM actually go to zero, or is this inconsistent with SMres?
1656
1657 ! If insufficient water in second surface to move dI, instead move as much as possible
1658 ELSE
1659 soilstore_id(is) = soilstore_id(is) + soilstore_id(jj)*sfr_surf(jj)/sfr_surf(is)
1660 soilstore_id(jj) = 0
1661 END IF
1662
1663 !If soil moisture exceeds capacity, excess goes to soil runoff (first surface)
1664 IF (soilstore_id(is) > soilstorecap(is)) THEN
1665 runoffsoil(is) = runoffsoil(is) + (soilstore_id(is) - soilstorecap(is))
1666 soilstore_id(is) = soilstorecap(is)
1667 !elseif (soilstore_id(is)<0) then !HCW 13/08/2014 commented out as should never be true here anyway...
1668 ! soilstore_id(is)=0 ! ... and if so, need to do more here (i.e. account for other water too)
1669 END IF
1670
1671 !If soil moisture exceeds capacity, excess goes to soil runoff (second surface)
1672 IF (soilstore_id(jj) > soilstorecap(jj)) THEN
1673 runoffsoil(jj) = runoffsoil(jj) + (soilstore_id(jj) - soilstorecap(jj))
1674 soilstore_id(jj) = soilstorecap(jj)
1675 !elseif (soilstore_id(jj)<0) then !HCW 13/08/2014 commented out (as above)
1676 ! soilstore_id(jj)=0
1677 END IF
1678
1679 END IF !end if second surface exists and is capable of storing water
1680
1681 END DO !end jj loop over second surface
1682
1683 runoffsoil_per_tstep = runoffsoil_per_tstep + (runoffsoil(is)*sfr_surf(is)/nonwaterfraction) !Excludes water body. Moved here as otherwise code crashed when NonWaterFraction=0
1684
1685 END IF !end if first surface exists and is capable of storing water
1686
1687 !runoffSoil_per_tstep=runoffSoil_per_tstep+(runoffSoil(is)*sfr_surf(is)/NonWaterFraction) !Excludes water body
1688
1689 END DO !is loop over first surface
1690
1692 !===================================================================================
1693
1694 !===================================================================================
1696 nsh_real, & ! input:
1697 wu_m3, SurfaceArea, sfr_surf, &
1698 IrrFracPaved, IrrFracBldgs, &
1699 IrrFracEveTr, IrrFracDecTr, IrrFracGrass, &
1700 IrrFracBSoil, IrrFracWater, &
1701 DayofWeek_id, WUProfA_24hr, WUProfM_24hr, &
1702 InternalWaterUse_h, HDD_id, WUDay_id, &
1703 WaterUseMethod, NSH, it, imin, DLS, &
1704 wu_surf, wu_int, wu_ext) ! output:
1705 ! Conversion of water use (irrigation)
1706 ! Last modified:
1707 ! TS 30 Nov 2019 - allow external water use for all surfaces
1708 ! (previously only on vegetated surfaces)
1709 ! TS 30 Oct 2018 - fixed a bug in external water use
1710 ! TS 08 Aug 2017 - addded explicit interface
1711 ! LJ 6 Apr 2017 - WUchoice changed to WaterUseMethod
1712 ! TK 14 Mar 2017 - Corrected the variable name WUAreaEveTr_m2 -> WUAreaGrass_m2 (row 35)
1713 ! Corrected conversion from m to mm /1000 -> *1000 (row 47 and 60)
1714 ! LJ 27 Jan 2016 - Removing Tab:s and cleaning the code
1715 ! HCW 12 Feb 2015 - Water use [mm] now inidcates the amount of water supplied for each surface
1716 ! HCW 26 Jan 2015 - Water use [mm] is the same for each surface at the moment and indicates the
1717 ! amount of water supplied for each irrigated area
1718 !
1719 ! To Do:
1720 ! - Add functionality for water on paved surfaces (street cleaning, fountains)
1721
1722 IMPLICIT NONE
1723 ! INTEGER, PARAMETER :: nsurf = 7
1724
1725 REAL(KIND(1D0)), INTENT(in) :: nsh_real
1726 REAL(KIND(1D0)), INTENT(in) :: wu_m3 ! external water input (e.g., irrigation) [m3]
1727 REAL(KIND(1D0)), INTENT(in) :: SurfaceArea !Surface area of the study area [m2]
1728 REAL(KIND(1D0)), INTENT(IN) :: IrrFracPaved !Fraction of paved which are irrigated
1729 REAL(KIND(1D0)), INTENT(IN) :: IrrFracBldgs !Fraction of buildings (e.g., green roofs) which are irrigated
1730 REAL(KIND(1D0)), INTENT(IN) :: IrrFracEveTr !Fraction of evergreen trees which are irrigated
1731 REAL(KIND(1D0)), INTENT(IN) :: IrrFracDecTr !Fraction of deciduous trees which are irrigated
1732 REAL(KIND(1D0)), INTENT(IN) :: IrrFracGrass !Fraction of grass which is irrigated
1733 REAL(KIND(1D0)), INTENT(IN) :: IrrFracBSoil !Fraction of bare soil trees which are irrigated
1734 REAL(KIND(1D0)), INTENT(IN) :: IrrFracWater !Fraction of water which are irrigated
1735 REAL(KIND(1D0)), INTENT(in) :: InternalWaterUse_h !Internal water use [mm h-1]
1736 REAL(KIND(1D0)), DIMENSION(0:23, 2), INTENT(in) :: WUProfA_24hr !Automatic water use profiles at hourly scales
1737 REAL(KIND(1D0)), DIMENSION(0:23, 2), INTENT(in) :: WUProfM_24hr !Manual water use profiles at hourly scales
1738 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(in) :: sfr_surf !Surface fractions [-]
1739
1740 REAL(KIND(1D0)), DIMENSION(12), INTENT(in) :: HDD_id !HDD(id-1), Heating Degree Days (see SUEWS_DailyState.f95)
1741 REAL(KIND(1D0)), DIMENSION(9), INTENT(in) :: WUDay_id !WUDay(id-1), Daily water use for EveTr, DecTr, Grass [mm] (see SUEWS_DailyState.f95)
1742
1743 INTEGER, INTENT(in) :: DayofWeek_id(3) !DayofWeek(id) 1 - day of week; 2 - month; 3 - season
1744 INTEGER, INTENT(in) :: WaterUseMethod !Use modelled (0) or observed (1) water use
1745 INTEGER, INTENT(in) :: NSH !Number of timesteps per hour
1746 INTEGER, INTENT(in) :: it !Hour
1747 INTEGER, INTENT(in) :: imin !Minutes
1748 INTEGER, INTENT(in) :: DLS !day lightsavings =1 + 1h) =0
1749
1750 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: wu_surf !external Water use for each surface [mm]
1751 REAL(KIND(1D0)), INTENT(out) :: wu_int !Internal water use for the model timestep [mm] (over whole study area)
1752 REAL(KIND(1D0)), INTENT(out) :: wu_ext !External water use for the model timestep [mm] (over whole study area)
1753
1754 REAL(KIND(1D0)) :: wu_EveTr !Water use for evergreen trees/shrubs [mm]
1755 REAL(KIND(1D0)) :: wu_DecTr !Water use for deciduous trees/shrubs [mm]
1756 REAL(KIND(1D0)) :: wu_Grass !Water use for grass [mm]
1757
1758 REAL(KIND(1D0)), DIMENSION(nsurf) :: WUDay_A_id !modelled Automatic Daily water use for each surface [mm] (see SUEWS_DailyState.f95)
1759 REAL(KIND(1D0)), DIMENSION(nsurf) :: WUDay_M_id !modelled Manual Daily water use for each surface [mm] (see SUEWS_DailyState.f95)
1760 REAL(KIND(1D0)), DIMENSION(nsurf) :: IrrFrac !faction of irrigated part in each surface [-]
1761 REAL(KIND(1D0)), DIMENSION(nsurf) :: WUArea !water use area [m2] for each surface type
1762
1763 REAL(KIND(1D0)) :: WUAreaTotal_m2
1764 REAL(KIND(1D0)) :: InternalWaterUse !Internal water use for the model timestep [mm]
1765 REAL(KIND(1D0)) :: flag_WuM = 1
1766 REAL(KIND(1D0)) :: wu !Water use for the model timestep [mm]
1767 INTEGER :: ih !Hour corrected for Daylight savings
1768 INTEGER :: iu !1=weekday OR 2=weekend
1769 INTEGER :: tstep ! timestep in second
1770 REAL(KIND(1D0)), PARAMETER :: NAN = -999.
1771 REAL(KIND(1D0)) :: OverUse
1772 REAL(KIND(1D0)) :: rain_cum_daily ! accumulated daily rainfall
1773
1774 REAL(KIND(1D0)) :: get_Prof_SpecTime_sum
1775
1776 REAL(KIND(1D0)) :: WUProfA_tstep ! automatic water use profile value at tstep
1777 REAL(KIND(1D0)) :: WUProfM_tstep ! mannual water use profile value at tstep
1778
1779 ! NB: set OverUse as 0 as done module_constants, TS 22 Oct 2017
1780 ! and the logic for calculating OverUse to be determined
1781 overuse = 0
1782
1783 ! initialise wu
1784 wu = 0
1785
1786 ! timestep in second
1787 tstep = int(3600/nsh)
1788
1789 ! accumulated daily rainfall
1790 rain_cum_daily = hdd_id(11)
1791
1792 ! Irrigated Fraction of each surface
1793 ! TS: as of 20191130, assuming irrigation fraction as ONE except for vegetated surfaces
1794
1795 ! Irrigated Fraction of each surface
1796 ! TS: 20200409, add irrigation fractions for all surfaces
1797 irrfrac = [irrfracpaved, irrfracbldgs, &
1798 irrfracevetr, irrfracdectr, irrfracgrass, &
1799 irrfracbsoil, irrfracwater]
1800
1801 ! --------------------------------------------------------------------------------
1802 ! If water used is observed and provided in the met forcing file, units are m3
1803 ! Divide observed water use (in m3) by water use area to find water use (in mm)
1804 IF (waterusemethod == 1) THEN !If water use is observed
1805 ! Calculate water use area [m2] for each surface type
1806
1807 wuarea = irrfrac*sfr_surf*surfacearea
1808 wuareatotal_m2 = sum(wuarea)
1809
1810 !Set water use [mm] for each surface type to zero initially
1811 wu_evetr = 0
1812 wu_dectr = 0
1813 wu_grass = 0
1814
1815 wu_surf = 0
1816 IF (wu_m3 == nan .OR. wu_m3 == 0) THEN !If no water use
1817 ! wu_m3=0
1818 wu = 0
1819 ELSE !If water use
1820 IF (wuareatotal_m2 > 0) THEN
1821 wu = (wu_m3/wuareatotal_m2*1000) !Water use in mm for the whole irrigated area
1822
1823 wu_surf = wu*irrfrac
1824
1825 wu = (wu_m3/surfacearea*1000) !Water use for the whole study area in mm
1826 END IF
1827 END IF
1828
1829 ! --------------------------------------------------------------------------------
1830 ! If water use is modelled, calculate at timestep of model resolution [mm]
1831 ELSEIF (waterusemethod == 0) THEN !If water use is modelled
1832
1833 ! Account for Daylight saving
1834 ih = it - dls
1835 IF (ih < 0) ih = 23
1836
1837 ! Weekday or weekend profile
1838 iu = 1 !Set to 1=weekday
1839 ! IF(DayofWeek(id,1)==1.OR.DayofWeek(id,1)==7) THEN
1840 IF (dayofweek_id(1) == 1 .OR. dayofweek_id(1) == 7) THEN
1841 iu = 2 !Set to 2=weekend
1842 END IF
1843
1844 !write(*,*) (NSH*(ih+1-1)+imin*NSH/60+1)
1845 wuday_a_id = 0
1846 wuday_a_id(conifsurf) = wuday_id(2)
1847 wuday_a_id(decidsurf) = wuday_id(5)
1848 wuday_a_id(grasssurf) = wuday_id(8)
1849
1850 wuday_m_id = 0
1851 wuday_m_id(conifsurf) = wuday_id(3)
1852 wuday_m_id(decidsurf) = wuday_id(6)
1853 wuday_m_id(grasssurf) = wuday_id(9)
1854
1855 ! ---- Automatic irrigation ----
1856 wuprofa_tstep = get_prof_spectime_sum(ih, imin, 0, wuprofa_24hr(:, iu), tstep)
1857
1858 ! ---- Manual irrigation ----
1859 flag_wum = 1 !Initialize flag_WuM to 1, but if raining, reduce manual fraction of water use
1860 ! If cumulative daily precipitation exceeds 2 mm
1861 IF (rain_cum_daily > 2) THEN !.and.WUDay(id-1,3)>0) then !Commented out HCW 23/01/2015
1862 flag_wum = 0 ! 0 -> No manual irrigation if raining
1863 END IF
1864
1865 ! Add manual to automatic to find total irrigation
1866 wuprofm_tstep = get_prof_spectime_sum(ih, imin, 0, wuprofm_24hr(:, iu), tstep)
1867
1868 ! sum up irrigation amount of automatic and manual approaches
1869 wu_surf = wuprofa_tstep*wuday_a_id + wuprofm_tstep*wuday_m_id*flag_wum
1870 ! apply irrigation fraction: part of land covers are not irrigated
1871 wu_surf = wu_surf*irrfrac
1872
1873 ! Total water use for the whole study area [mm]
1874 ! wu = wu_EveTr*sfr_surf(ConifSurf) + wu_DecTr*sfr_surf(DecidSurf) + wu_Grass*sfr_surf(GrassSurf)
1875 wu = dot_product(wu_surf, sfr_surf)
1876
1877 END IF !End WU_choice
1878 ! --------------------------------------------------------------------------------
1879
1880 ! Internal water use is supplied in SUEWS_Irrigation in mm h-1
1881 ! Convert to mm for the model timestep
1882 internalwateruse = internalwateruse_h/nsh_real
1883
1884 ! Remove InternalWaterUse from the total water use
1885 wu_ext = wu - (internalwateruse + overuse)
1886 ! Check ext_wu cannot be negative
1887 IF (wu_ext < 0) THEN
1888 overuse = abs(wu_ext)
1889 wu_ext = 0
1890 ELSE
1891 overuse = 0
1892 END IF
1893
1894 wu_int = wu - wu_ext
1895
1896 ! Decrease the water use for each surface by the same proportion
1897 IF (wu_ext /= 0 .AND. wu /= 0) THEN
1898 wu_surf = wu_surf*wu_ext/wu
1899 END IF
1900
1901 END SUBROUTINE suews_cal_wateruse
1902
1904 nsh_real, & ! input:
1905 wu_m3, SurfaceArea, &
1906 sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, &
1907 IrrFracPaved, IrrFracBldgs, &
1908 IrrFracEveTr, IrrFracDecTr, IrrFracGrass, &
1909 IrrFracBSoil, IrrFracWater, &
1910 DayofWeek_id, &
1911 WUProfA_24hr_working, WUProfA_24hr_holiday, &
1912 wuprofm_24hr_working, wuprofm_24hr_holiday, &
1913 InternalWaterUse_h, HDD_id, WUDay_id, &
1914 WaterUseMethod, NSH, it, imin, DLS, &
1915 wu_surf, wu_int, wu_ext) ! output:
1916 ! Conversion of water use (irrigation)
1917 ! Last modified:
1918 ! TS 30 Nov 2019 - allow external water use for all surfaces
1919 ! (previously only on vegetated surfaces)
1920 ! TS 30 Oct 2018 - fixed a bug in external water use
1921 ! TS 08 Aug 2017 - addded explicit interface
1922 ! LJ 6 Apr 2017 - WUchoice changed to WaterUseMethod
1923 ! TK 14 Mar 2017 - Corrected the variable name WUAreaEveTr_m2 -> WUAreaGrass_m2 (row 35)
1924 ! Corrected conversion from m to mm /1000 -> *1000 (row 47 and 60)
1925 ! LJ 27 Jan 2016 - Removing Tab:s and cleaning the code
1926 ! HCW 12 Feb 2015 - Water use [mm] now inidcates the amount of water supplied for each surface
1927 ! HCW 26 Jan 2015 - Water use [mm] is the same for each surface at the moment and indicates the
1928 ! amount of water supplied for each irrigated area
1929 !
1930 ! To Do:
1931 ! - Add functionality for water on paved surfaces (street cleaning, fountains)
1932
1933 IMPLICIT NONE
1934 ! INTEGER, PARAMETER :: nsurf = 7
1935
1936 REAL(KIND(1D0)), INTENT(in) :: nsh_real
1937 REAL(KIND(1D0)), INTENT(in) :: wu_m3 ! external water input (e.g., irrigation) [m3]
1938 REAL(KIND(1D0)), INTENT(in) :: SurfaceArea !Surface area of the study area [m2]
1939 REAL(KIND(1D0)), INTENT(IN) :: IrrFracPaved !Fraction of paved which are irrigated
1940 REAL(KIND(1D0)), INTENT(IN) :: IrrFracBldgs !Fraction of buildings (e.g., green roofs) which are irrigated
1941 REAL(KIND(1D0)), INTENT(IN) :: IrrFracEveTr !Fraction of evergreen trees which are irrigated
1942 REAL(KIND(1D0)), INTENT(IN) :: IrrFracDecTr !Fraction of deciduous trees which are irrigated
1943 REAL(KIND(1D0)), INTENT(IN) :: IrrFracGrass !Fraction of grass which is irrigated
1944 REAL(KIND(1D0)), INTENT(IN) :: IrrFracBSoil !Fraction of bare soil trees which are irrigated
1945 REAL(KIND(1D0)), INTENT(IN) :: IrrFracWater !Fraction of water which are irrigated
1946 REAL(KIND(1D0)), INTENT(in) :: InternalWaterUse_h !Internal water use [mm h-1]
1947
1948 REAL(KIND(1D0)), DIMENSION(0:23), INTENT(in) :: WUProfA_24hr_working
1949 REAL(KIND(1D0)), DIMENSION(0:23), INTENT(in) :: WUProfA_24hr_holiday
1950 REAL(KIND(1D0)), DIMENSION(0:23, 2) :: WUProfA_24hr !Automatic water use profiles at hourly scales
1951 REAL(KIND(1D0)), DIMENSION(0:23), INTENT(in) :: WUProfM_24hr_working
1952 REAL(KIND(1D0)), DIMENSION(0:23), INTENT(in) :: WUProfM_24hr_holiday
1953 REAL(KIND(1D0)), DIMENSION(0:23, 2) :: WUProfM_24hr !Manual water use profiles at hourly scales
1954
1955 REAL(KIND(1D0)), INTENT(IN) :: sfr_paved
1956 REAL(KIND(1D0)), INTENT(IN) :: sfr_bldg
1957 REAL(KIND(1D0)), INTENT(IN) :: sfr_evetr
1958 REAL(KIND(1D0)), INTENT(IN) :: sfr_dectr
1959 REAL(KIND(1D0)), INTENT(IN) :: sfr_grass
1960 REAL(KIND(1D0)), INTENT(IN) :: sfr_bsoil
1961 REAL(KIND(1D0)), INTENT(IN) :: sfr_water
1962 REAL(KIND(1D0)), DIMENSION(nsurf) :: sfr_surf !Surface fractions [-]
1963
1964 REAL(KIND(1D0)), DIMENSION(12), INTENT(in) :: HDD_id !HDD(id-1), Heating Degree Days (see SUEWS_DailyState.f95)
1965 REAL(KIND(1D0)), DIMENSION(9), INTENT(in) :: WUDay_id !WUDay(id-1), Daily water use for EveTr, DecTr, Grass [mm] (see SUEWS_DailyState.f95)
1966
1967 INTEGER, INTENT(in) :: DayofWeek_id(3) !DayofWeek(id) 1 - day of week; 2 - month; 3 - season
1968 INTEGER, INTENT(in) :: WaterUseMethod !Use modelled (0) or observed (1) water use
1969 INTEGER, INTENT(in) :: NSH !Number of timesteps per hour
1970 INTEGER, INTENT(in) :: it !Hour
1971 INTEGER, INTENT(in) :: imin !Minutes
1972 INTEGER, INTENT(in) :: DLS !day lightsavings =1 + 1h) =0
1973
1974 REAL(KIND(1D0)), DIMENSION(nsurf), INTENT(out) :: wu_surf !external Water use for each surface [mm]
1975 REAL(KIND(1D0)), INTENT(out) :: wu_int !Internal water use for the model timestep [mm] (over whole study area)
1976 REAL(KIND(1D0)), INTENT(out) :: wu_ext !External water use for the model timestep [mm] (over whole study area)
1977
1978 REAL(KIND(1D0)) :: wu_EveTr !Water use for evergreen trees/shrubs [mm]
1979 REAL(KIND(1D0)) :: wu_DecTr !Water use for deciduous trees/shrubs [mm]
1980 REAL(KIND(1D0)) :: wu_Grass !Water use for grass [mm]
1981
1982 REAL(KIND(1D0)), DIMENSION(nsurf) :: WUDay_A_id !modelled Automatic Daily water use for each surface [mm] (see SUEWS_DailyState.f95)
1983 REAL(KIND(1D0)), DIMENSION(nsurf) :: WUDay_M_id !modelled Manual Daily water use for each surface [mm] (see SUEWS_DailyState.f95)
1984 REAL(KIND(1D0)), DIMENSION(nsurf) :: IrrFrac !faction of irrigated part in each surface [-]
1985 REAL(KIND(1D0)), DIMENSION(nsurf) :: WUArea !water use area [m2] for each surface type
1986
1987 REAL(KIND(1D0)) :: WUAreaTotal_m2
1988 REAL(KIND(1D0)) :: InternalWaterUse !Internal water use for the model timestep [mm]
1989 REAL(KIND(1D0)) :: flag_WuM = 1
1990 REAL(KIND(1D0)) :: wu !Water use for the model timestep [mm]
1991 INTEGER :: ih !Hour corrected for Daylight savings
1992 INTEGER :: iu !1=weekday OR 2=weekend
1993 INTEGER :: tstep ! timestep in second
1994 REAL(KIND(1D0)), PARAMETER :: NAN = -999.
1995 REAL(KIND(1D0)) :: OverUse
1996 REAL(KIND(1D0)) :: rain_cum_daily ! accumulated daily rainfall
1997
1998 REAL(KIND(1D0)) :: get_Prof_SpecTime_sum
1999
2000 REAL(KIND(1D0)) :: WUProfA_tstep ! automatic water use profile value at tstep
2001 REAL(KIND(1D0)) :: WUProfM_tstep ! mannual water use profile value at tstep
2002
2003 sfr_surf = [sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water]
2004 wuprofa_24hr(:, 1) = wuprofa_24hr_working
2005 wuprofa_24hr(:, 2) = wuprofa_24hr_holiday
2006 wuprofm_24hr(:, 1) = wuprofm_24hr_working
2007 wuprofm_24hr(:, 2) = wuprofm_24hr_holiday
2008 ! NB: set OverUse as 0 as done module_constants, TS 22 Oct 2017
2009 ! and the logic for calculating OverUse to be determined
2010 overuse = 0
2011
2012 ! initialise wu
2013 wu = 0
2014
2015 ! timestep in second
2016 tstep = int(3600/nsh)
2017
2018 ! accumulated daily rainfall
2019 rain_cum_daily = hdd_id(11)
2020
2021 ! Irrigated Fraction of each surface
2022 ! TS: as of 20191130, assuming irrigation fraction as ONE except for vegetated surfaces
2023
2024 ! Irrigated Fraction of each surface
2025 ! TS: 20200409, add irrigation fractions for all surfaces
2026 irrfrac = [irrfracpaved, irrfracbldgs, &
2027 irrfracevetr, irrfracdectr, irrfracgrass, &
2028 irrfracbsoil, irrfracwater]
2029
2030 ! --------------------------------------------------------------------------------
2031 ! If water used is observed and provided in the met forcing file, units are m3
2032 ! Divide observed water use (in m3) by water use area to find water use (in mm)
2033 IF (waterusemethod == 1) THEN !If water use is observed
2034 ! Calculate water use area [m2] for each surface type
2035
2036 wuarea = irrfrac*sfr_surf*surfacearea
2037 wuareatotal_m2 = sum(wuarea)
2038
2039 !Set water use [mm] for each surface type to zero initially
2040 wu_evetr = 0
2041 wu_dectr = 0
2042 wu_grass = 0
2043
2044 wu_surf = 0
2045 IF (wu_m3 == nan .OR. wu_m3 == 0) THEN !If no water use
2046 ! wu_m3=0
2047 wu = 0
2048 ELSE !If water use
2049 IF (wuareatotal_m2 > 0) THEN
2050 wu = (wu_m3/wuareatotal_m2*1000) !Water use in mm for the whole irrigated area
2051
2052 wu_surf = wu*irrfrac
2053
2054 wu = (wu_m3/surfacearea*1000) !Water use for the whole study area in mm
2055 END IF
2056 END IF
2057
2058 ! --------------------------------------------------------------------------------
2059 ! If water use is modelled, calculate at timestep of model resolution [mm]
2060 ELSEIF (waterusemethod == 0) THEN !If water use is modelled
2061
2062 ! Account for Daylight saving
2063 ih = it - dls
2064 IF (ih < 0) ih = 23
2065
2066 ! Weekday or weekend profile
2067 iu = 1 !Set to 1=weekday
2068 ! IF(DayofWeek(id,1)==1.OR.DayofWeek(id,1)==7) THEN
2069 IF (dayofweek_id(1) == 1 .OR. dayofweek_id(1) == 7) THEN
2070 iu = 2 !Set to 2=weekend
2071 END IF
2072
2073 !write(*,*) (NSH*(ih+1-1)+imin*NSH/60+1)
2074 wuday_a_id = 0
2075 wuday_a_id(conifsurf) = wuday_id(2)
2076 wuday_a_id(decidsurf) = wuday_id(5)
2077 wuday_a_id(grasssurf) = wuday_id(8)
2078
2079 wuday_m_id = 0
2080 wuday_m_id(conifsurf) = wuday_id(3)
2081 wuday_m_id(decidsurf) = wuday_id(6)
2082 wuday_m_id(grasssurf) = wuday_id(9)
2083
2084 ! ---- Automatic irrigation ----
2085 wuprofa_tstep = get_prof_spectime_sum(ih, imin, 0, wuprofa_24hr(:, iu), tstep)
2086
2087 ! ---- Manual irrigation ----
2088 flag_wum = 1 !Initialize flag_WuM to 1, but if raining, reduce manual fraction of water use
2089 ! If cumulative daily precipitation exceeds 2 mm
2090 IF (rain_cum_daily > 2) THEN !.and.WUDay(id-1,3)>0) then !Commented out HCW 23/01/2015
2091 flag_wum = 0 ! 0 -> No manual irrigation if raining
2092 END IF
2093
2094 ! Add manual to automatic to find total irrigation
2095 wuprofm_tstep = get_prof_spectime_sum(ih, imin, 0, wuprofm_24hr(:, iu), tstep)
2096
2097 ! sum up irrigation amount of automatic and manual approaches
2098 wu_surf = wuprofa_tstep*wuday_a_id + wuprofm_tstep*wuday_m_id*flag_wum
2099 ! apply irrigation fraction: part of land covers are not irrigated
2100 wu_surf = wu_surf*irrfrac
2101
2102 ! Total water use for the whole study area [mm]
2103 ! wu = wu_EveTr*sfr_surf(ConifSurf) + wu_DecTr*sfr_surf(DecidSurf) + wu_Grass*sfr_surf(GrassSurf)
2104 wu = dot_product(wu_surf, sfr_surf)
2105
2106 END IF !End WU_choice
2107 ! --------------------------------------------------------------------------------
2108
2109 ! Internal water use is supplied in SUEWS_Irrigation in mm h-1
2110 ! Convert to mm for the model timestep
2111 internalwateruse = internalwateruse_h/nsh_real
2112
2113 ! Remove InternalWaterUse from the total water use
2114 wu_ext = wu - (internalwateruse + overuse)
2115 ! Check ext_wu cannot be negative
2116 IF (wu_ext < 0) THEN
2117 overuse = abs(wu_ext)
2118 wu_ext = 0
2119 ELSE
2120 overuse = 0
2121 END IF
2122
2123 wu_int = wu - wu_ext
2124
2125 ! Decrease the water use for each surface by the same proportion
2126 IF (wu_ext /= 0 .AND. wu /= 0) THEN
2127 wu_surf = wu_surf*wu_ext/wu
2128 END IF
2129
2130 END SUBROUTINE suews_cal_wateruse_dts
2131 !===================================================================================
2132
2133END MODULE waterdist_module
integer, parameter bldgsurf
integer, parameter conifsurf
real(kind(1d0)), dimension(nsurf) sfr_surf
integer, parameter watersurf
integer, parameter grasssurf
integer, parameter bsoilsurf
integer, parameter nsurf
integer, parameter pavsurf
integer, parameter excesssurf
integer, parameter decidsurf
subroutine updateflood(is, runoff, sfr_surf, pipecapacity, runofftowater, runoffagimpervious, surpluswaterbody, runoffagveg, runoffpipes)
subroutine suews_cal_wateruse(nsh_real, wu_m3, surfacearea, sfr_surf, irrfracpaved, irrfracbldgs, irrfracevetr, irrfracdectr, irrfracgrass, irrfracbsoil, irrfracwater, dayofweek_id, wuprofa_24hr, wuprofm_24hr, internalwateruse_h, hdd_id, wuday_id, waterusemethod, nsh, it, imin, dls, wu_surf, wu_int, wu_ext)
subroutine suews_update_soilmoist(nonwaterfraction, soilstorecap, sfr_surf, soilstore_id, soilmoistcap, soilstate, vsmd, smd)
subroutine suews_update_soilmoist_dts(nonwaterfraction, sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, soilstorecap_paved, soilstorecap_bldg, soilstorecap_evetr, soilstorecap_dectr, soilstorecap_grass, soilstorecap_bsoil, soilstorecap_water, soilstore_id, soilmoistcap, soilstate, vsmd, smd)
subroutine cal_water_storage_building(pin, nsh_real, nlayer, sfr_roof, statelimit_roof, soilstorecap_roof, wetthresh_roof, ev_roof_in, state_roof_in, soilstore_roof_in, sfr_wall, statelimit_wall, soilstorecap_wall, wetthresh_wall, ev_wall_in, state_wall_in, soilstore_wall_in, ev_roof_out, state_roof_out, soilstore_roof_out, runoff_roof, ev_wall_out, state_wall_out, soilstore_wall_out, runoff_wall, state_building, soilstore_building, runoff_building, soilstorecap_building)
subroutine suews_cal_horizontalsoilwater(sfr_surf, soilstorecap, soildepth, sathydraulicconduct, surfacearea, nonwaterfraction, tstep_real, soilstore_id, runoffsoil, runoffsoil_per_tstep)
subroutine cal_water_storage_surf(pin, nsh_real, pipecapacity, runofftowater, addimpervious, addveg, addwaterbody, flowchange, soilstorecap_surf, statelimit_surf, pervfraction, sfr_surf, drain_surf, addwater_surf, frac_water2runoff_surf, wu_surf, ev_surf_in, state_surf_in, soilstore_surf_in, ev_surf_out, state_surf_out, soilstore_surf_out, runoff_surf, runoffagimpervious_grid, runoffagveg_grid, runoffpipes_grid, runoffwaterbody_grid)
subroutine suews_cal_soilstate(smdmethod, xsmd, nonwaterfraction, soilmoistcap, soilstorecap, surf_chang_per_tstep, soilstore_id, soilstoreold, sfr_surf, smd, smd_nsurf, tot_chang_per_tstep, soilstate)
subroutine suews_cal_horizontalsoilwater_dts(sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, soilstorecap_paved, soilstorecap_bldg, soilstorecap_evetr, soilstorecap_dectr, soilstorecap_grass, soilstorecap_bsoil, soilstorecap_water, soildepth_paved, soildepth_bldg, soildepth_evetr, soildepth_dectr, soildepth_grass, soildepth_bsoil, soildepth_water, sathydraulicconduct_paved, sathydraulicconduct_bldg, sathydraulicconduct_evetr, sathydraulicconduct_dectr, sathydraulicconduct_grass, sathydraulicconduct_bsoil, sathydraulicconduct_water, surfacearea, nonwaterfraction, tstep_real, soilstore_id, runoffsoil, runoffsoil_per_tstep)
subroutine suews_cal_soilstate_dts(smdmethod, xsmd, nonwaterfraction, soilmoistcap, soilstorecap_paved, soilstorecap_bldg, soilstorecap_evetr, soilstorecap_dectr, soilstorecap_grass, soilstorecap_bsoil, soilstorecap_water, surf_chang_per_tstep, soilstore_id, soilstoreold, sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, smd, smd_nsurf, tot_chang_per_tstep, soilstate)
subroutine drainage(is, state_is, storcap, draineq, draincoef1, draincoef2, nsh_real, drain_is)
subroutine cal_water_storage(is, sfr_surf, pipecapacity, runofftowater, pin, wu_surf, drain_surf, addwater, addimpervious, nsh_real, state_in, frac_water2runoff, pervfraction, addveg, soilstorecap, addwaterbody, flowchange, statelimit, runoffagimpervious, runoffagveg, runoffpipes, ev, soilstore_id, surpluswaterbody, surplusevap, runoffwaterbody, runoff, state_out)
real(kind(1d0)) function cal_smd_veg(soilstorecap, soilstore_id, sfr_surf)
subroutine suews_cal_wateruse_dts(nsh_real, wu_m3, surfacearea, sfr_paved, sfr_bldg, sfr_evetr, sfr_dectr, sfr_grass, sfr_bsoil, sfr_water, irrfracpaved, irrfracbldgs, irrfracevetr, irrfracdectr, irrfracgrass, irrfracbsoil, irrfracwater, dayofweek_id, wuprofa_24hr_working, wuprofa_24hr_holiday, wuprofm_24hr_working, wuprofm_24hr_holiday, internalwateruse_h, hdd_id, wuday_id, waterusemethod, nsh, it, imin, dls, wu_surf, wu_int, wu_ext)
subroutine redistributewater(snowuse, waterdist, sfr_surf, drain, addwaterrunoff, addwater)
subroutine errorhint(errh, problemfile, value, value2, valuei)