SUEWS API Site
Documentation of SUEWS source code
Functions/Subroutines
waterdist_module Module Reference

Functions/Subroutines

subroutine drainage (is, state_is, StorCap, DrainEq, DrainCoef1, DrainCoef2, nsh_real, drain_is)
 
subroutine soilstore (is, sfr, PipeCapacity, RunoffToWater, pin, wu_EveTr, wu_DecTr, wu_Grass, drain, AddWater, addImpervious, nsh_real, stateOld, AddWaterRunoff, PervFraction, addVeg, SoilStoreCap, addWaterBody, FlowChange, StateLimit, runoffAGimpervious, surplusWaterBody, runoffAGveg, runoffPipes, ev, soilstore_id, SurplusEvap, runoffWaterBody, p_mm, chang, runoff, state_id)
 
subroutine updateflood (is, runoff, sfr, PipeCapacity, RunoffToWater, runoffAGimpervious, surplusWaterBody, runoffAGveg, runoffPipes)
 
subroutine redistributewater (snowUse, WaterDist, sfr, Drain, AddWaterRunoff, AddWater)
 
subroutine suews_update_soilmoist (NonWaterFraction, SoilStoreCap, sfr, soilstore_id, SoilMoistCap, SoilState, vsmd, smd)
 
subroutine suews_cal_soilstate (SMDMethod, xsmd, NonWaterFraction, SoilMoistCap, SoilStoreCap, surf_chang_per_tstep, soilstore_id, soilstoreOld, sfr, smd, smd_nsurf, tot_chang_per_tstep, SoilState)
 
subroutine suews_cal_horizontalsoilwater (sfr, SoilStoreCap, SoilDepth, SatHydraulicConduct, SurfaceArea, NonWaterFraction, tstep_real, soilstore_id, runoffSoil, runoffSoil_per_tstep)
 
subroutine suews_cal_wateruse (nsh_real, wu_m3, SurfaceArea, sfr, IrrFracConif, IrrFracDecid, IrrFracGrass, DayofWeek_id, WUProfA_24hr, WUProfM_24hr, InternalWaterUse_h, HDD_id, WUDay_id, WaterUseMethod, NSH, it, imin, DLS, wu_EveTr, wu_DecTr, wu_Grass, int_wu, ext_wu)
 

Function/Subroutine Documentation

◆ drainage()

subroutine waterdist_module::drainage ( integer, intent(in)  is,
real(kind(1d0)), intent(in)  state_is,
real(kind(1d0)), intent(in)  StorCap,
real(kind(1d0)), intent(in)  DrainEq,
real(kind(1d0)), intent(in)  DrainCoef1,
real(kind(1d0)), intent(in)  DrainCoef2,
real(kind(1d0)), intent(in)  nsh_real,
real(kind(1d0)), intent(out)  drain_is 
)

Definition at line 29 of file suews_phys_waterdist.f95.

References errorhint().

Referenced by suews_driver::suews_cal_water().

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  ENDIF
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  ENDIF
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  ENDIF
84  ENDIF
85 
86  RETURN
87 
subroutine errorhint(errh, ProblemFile, VALUE, value2, valueI)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ redistributewater()

subroutine waterdist_module::redistributewater ( integer, intent(in)  snowUse,
real(kind(1d0)), dimension(nsurf + 1, nsurf - 1), intent(in)  WaterDist,
real(kind(1d0)), dimension(nsurf), intent(in)  sfr,
real(kind(1d0)), dimension(nsurf), intent(in)  Drain,
real(kind(1d0)), dimension(nsurf), intent(out)  AddWaterRunoff,
real(kind(1d0)), dimension(nsurf), intent(out)  AddWater 
)

Definition at line 449 of file suews_phys_waterdist.f95.

References allocatearray::nsurf, and allocatearray::watersurf.

Referenced by suews_driver::suews_cal_water().

449  !Drainage moves into different parts defined by WaterDistSS_YYYY.txt. LJ 2010
450  !AddWater(is) is that amount of water that is gained for each surface
451  !Latest update takes snow into account. 22/03/2013 LJ
452  !-------------------------------------------------------------------
453 
454  IMPLICIT NONE
455  INTEGER, INTENT(in)::snowuse!Snow part used (1) or not used (0)
456 
457  REAL(KIND(1d0)), INTENT(in)::waterdist(nsurf + 1, nsurf - 1) !Within-grid water distribution to other surfaces and runoff/soil store [-]
458  REAL(KIND(1d0)), INTENT(in)::sfr(nsurf) !Surface fractions [-]
459  REAL(KIND(1d0)), INTENT(in)::drain(nsurf) !Drainage of each surface type [mm]
460 
461  REAL(KIND(1d0)), INTENT(out)::addwaterrunoff(nsurf)!Fraction of water going to runoff/sub-surface soil (WGWaterDist) [-]
462  REAL(KIND(1d0)), INTENT(out)::addwater(nsurf) !Water from other surfaces (WGWaterDist in SUEWS_ReDistributeWater.f95) [mm]
463 
464  INTEGER::ii, jj
465  INTEGER::nsurfdonotreceivedrainage = 0!Number of surfaces that do not receive drainage water (green roof)
466 
467  !Fractions that go to runoff from each surface
468  DO ii = 1, nsurf - 1 !not water in the calculation
469  addwaterrunoff(ii) = waterdist(8, ii)
470  ENDDO
472  addwater = 0
473 
474  DO ii = 1, nsurf - nsurfdonotreceivedrainage !go through surfaces from 1 to 7. These gain water through drainage
475  DO jj = 1, nsurf - (nsurfdonotreceivedrainage + 1) !From where surface ii can gain water - can't gain water from itself
476 
477  IF (sfr(ii) /= 0) THEN !Water movement takes place only if surface fraction exists
478 
479  !No snow calculations!
480  IF (snowuse == 0) THEN
481  addwater(ii) = addwater(ii) + (drain(jj)*sfr(jj)/sfr(ii))*waterdist(ii, jj) !Original
482 
483  !Snow included, This needs to be fixed at some point. LJ Mar 2013
484  ELSE
485  addwaterrunoff(jj) = addwaterrunoff(jj) + waterdist(ii, jj) !No receiving surface -> runoff
486  ENDIF
487 
488  ELSE
489  addwaterrunoff(jj) = addwaterrunoff(jj) + waterdist(ii, jj) !If no receiving surface exists,
490  !water fraction goes to AddWaterRunoff
491  ENDIF
492  ENDDO
493  ENDDO
494 
real(kind(1d0)), dimension(nsurf) drain
integer, parameter nsurf
integer, parameter nsurfdonotreceivedrainage
real(kind(1d0)), dimension(nsurf) addwater
real(kind(1d0)), dimension(nsurf) sfr
real(kind(1d0)), dimension(nsurf) addwaterrunoff
integer, parameter watersurf
real(kind(1d0)), dimension(nsurf+1, nsurf - 1) waterdist
Here is the caller graph for this function:

◆ soilstore()

subroutine waterdist_module::soilstore ( integer, intent(in)  is,
real(kind(1d0)), dimension(nsurf), intent(in)  sfr,
real(kind(1d0)), intent(in)  PipeCapacity,
real(kind(1d0)), intent(in)  RunoffToWater,
real(kind(1d0)), intent(in)  pin,
real(kind(1d0)), intent(in)  wu_EveTr,
real(kind(1d0)), intent(in)  wu_DecTr,
real(kind(1d0)), intent(in)  wu_Grass,
real(kind(1d0)), dimension(nsurf), intent(in)  drain,
real(kind(1d0)), dimension(nsurf), intent(in)  AddWater,
real(kind(1d0)), intent(in)  addImpervious,
real(kind(1d0)), intent(in)  nsh_real,
real(kind(1d0)), dimension(nsurf), intent(in)  stateOld,
real(kind(1d0)), dimension(nsurf), intent(in)  AddWaterRunoff,
real(kind(1d0)), intent(in)  PervFraction,
real(kind(1d0)), intent(in)  addVeg,
real(kind(1d0)), dimension(nsurf), intent(in)  SoilStoreCap,
real(kind(1d0)), intent(in)  addWaterBody,
real(kind(1d0)), intent(in)  FlowChange,
real(kind(1d0)), dimension(nsurf), intent(in)  StateLimit,
real(kind(1d0)), intent(inout)  runoffAGimpervious,
real(kind(1d0)), intent(inout)  surplusWaterBody,
real(kind(1d0)), intent(inout)  runoffAGveg,
real(kind(1d0)), intent(inout)  runoffPipes,
real(kind(1d0)), intent(inout)  ev,
real(kind(1d0)), dimension(nsurf), intent(inout)  soilstore_id,
real(kind(1d0)), dimension(2), intent(inout)  SurplusEvap,
real(kind(1d0)), intent(inout)  runoffWaterBody,
real(kind(1d0)), intent(out)  p_mm,
real(kind(1d0)), dimension(nsurf), intent(out)  chang,
real(kind(1d0)), dimension(nsurf), intent(out)  runoff,
real(kind(1d0)), dimension(nsurf), intent(out)  state_id 
)

Definition at line 99 of file suews_phys_waterdist.f95.

References allocatearray::bldgsurf, allocatearray::bsoilsurf, allocatearray::conifsurf, allocatearray::decidsurf, errorhint(), allocatearray::grasssurf, allocatearray::pavsurf, updateflood(), and allocatearray::watersurf.

Referenced by suews_driver::suews_cal_qe().

99  !------------------------------------------------------------------------------
100  !Calculation of storage change
101  ! LJ 27 Jan 2016
102  ! -Removed tabs and cleaned the code
103  ! HCW 08 Dec 2015
104  ! -Added if-loop check for no Paved surfaces
105  ! LJ 6 May 2015
106  ! - Calculations of the piperunoff exceedings moved to separate subroutine updateFlood.
107  ! - Now also called from snow subroutine
108  ! - Evaporation is modified using EvapPart
109  ! - when no water on impervious surfaces, evap occurs above pervious surfaces instead
110  ! Rewritten by HCW 12 Feb 2015
111  ! - Old variable 'p' for water input to the surface renamed to 'p_mm'
112  ! - All water now added to p_mm first, before threshold checks or other calculations
113  ! - Water from other grids now added to p_mm (instead of state_id for impervious surfaces)
114  ! - Removed division of runoff by nsh, as whole model now runs at the same timestep
115  ! - Adjusted transfer of ev between surfaces to conserve mass (not depth)
116  ! - Volumes used for water transport between grids to account for SurfaceArea changing between grids
117  ! - Added threshold check for state_id(WaterSurf) - was going negative
118  ! Last modified HCW 09 Feb 2015
119  ! - Removed StorCap input because it is provided by module allocateArray
120  ! - Tidied and commented code
121  ! Modified by LJ in November 2012:
122  ! - P>10 was not taken into account for impervious surfaces - Was fixed.
123  ! - Above impervious surfaces possibility of the state_id to exceed max capacity was limited
124  ! although this should be possible - was fixed
125  ! Modified by LJ 10/2010
126  ! Rewritten mostly by LJ in 2010
127  ! To do:
128  ! - Finish area normalisation for RG2G & finish coding GridConnections
129  ! - What is the 10 mm hr-1 threshold for?
130  ! - Decide upon and correct storage capacities here & in evap subroutine
131  ! - FlowChange units should be mm hr-1 - need to update everywhere
132  ! - Add SurfaceFlood(is)?
133  ! - What happens if sfr(is) = 0 or 1?
134  ! - Consider how irrigated trees actually works...
135  !------------------------------------------------------------------------------
136 
137  IMPLICIT NONE
138 
139  !Stores flood water when surface state_id exceeds storage capacity [mm]
140  INTEGER, INTENT(in)::is ! surface type
141 
142  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::sfr! surface fractions
143  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::addwater!Water from other surfaces (WGWaterDist in SUEWS_ReDistributeWater.f95) [mm]
144  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::stateold!Wetness status of each surface type from previous timestep [mm]
145  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::addwaterrunoff!Fraction of water going to runoff/sub-surface soil (WGWaterDist) [-]
146  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::soilstorecap!Capacity of soil store for each surface [mm]
147  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::statelimit!Limit for state_id of each surface type [mm] (specified in input files)
148 
149  REAL(KIND(1d0)), INTENT(in)::pipecapacity!Capacity of pipes to transfer water
150  REAL(KIND(1d0)), INTENT(in)::runofftowater!Fraction of surface runoff going to water body
151  REAL(KIND(1d0)), INTENT(in)::pin!Rain per time interval
152  REAL(KIND(1d0)), INTENT(in)::wu_evetr!Water use for evergreen trees/shrubs [mm]
153  REAL(KIND(1d0)), INTENT(in)::wu_dectr!Water use for deciduous trees/shrubs [mm]
154  REAL(KIND(1d0)), INTENT(in)::wu_grass!Water use for grass [mm]
155  REAL(KIND(1d0)), INTENT(in)::addimpervious!Water from impervious surfaces of other grids [mm] for whole surface area
156  REAL(KIND(1d0)), INTENT(in)::nsh_real!nsh cast as a real for use in calculations
157  REAL(KIND(1d0)), INTENT(in)::pervfraction! sum of surface cover fractions for impervious surfaces
158  REAL(KIND(1d0)), INTENT(in)::addveg!Water from vegetated surfaces of other grids [mm] for whole surface area
159  REAL(KIND(1d0)), INTENT(in)::addwaterbody!Water from water surface of other grids [mm] for whole surface area
160  REAL(KIND(1d0)), INTENT(in)::flowchange!Difference between the input and output flow in the water body
161 
162  REAL(KIND(1d0)), INTENT(inout)::runoffagimpervious!Above ground runoff from impervious surface [mm] for whole surface area
163  REAL(KIND(1d0)), INTENT(inout)::surpluswaterbody!Extra runoff that goes to water body [mm] as specified by RunoffToWater
164  REAL(KIND(1d0)), INTENT(inout)::runoffagveg!Above ground runoff from vegetated surfaces [mm] for whole surface area
165  REAL(KIND(1d0)), INTENT(inout)::runoffpipes!Runoff in pipes [mm] for whole surface area
166  REAL(KIND(1d0)), INTENT(inout)::ev!Evaporation
167  REAL(KIND(1d0)), INTENT(inout)::runoffwaterbody!Above ground runoff from water surface [mm] for whole surface area
168 
169  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(inout)::soilstore_id !Soil moisture of each surface type [mm]
170  REAL(KIND(1d0)), DIMENSION(2), INTENT(inout) ::surplusevap!Surplus for evaporation in 5 min timestep
171 
172  REAL(KIND(1d0)), INTENT(out)::p_mm!Inputs to surface water balance
173 
174  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(out)::chang !Change in state_id [mm]
175  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(out)::runoff!Runoff from each surface type [mm]
176  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in) ::drain !Drainage of each surface type [mm]
177  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(out)::state_id !Wetness status of each surface type [mm]
178 
179  !Extra evaporation [mm] from impervious surfaces which cannot happen due to lack of water
180  REAL(KIND(1d0)):: evpart
181  REAL(KIND(1d0)), PARAMETER:: notused = -55.5
182  REAL(KIND(1d0)), PARAMETER:: ipthreshold_mmhr = 10 ! NB:this should be an input and can be specified. SG 25 Apr 2018
183 
184  !Initialise extra evaporation to zero
185  evpart = 0
186 
187  !SurfaceFlood(is) = 0 !!This probably needs to be carried over between timesteps, but reset for now
188 
189  !==================================================================
190  ! Combine water inputs to the current surface
191  ! Add external water use for each surface type
192  SELECT CASE (is)
193  CASE (conifsurf)
194  p_mm = pin + wu_evetr
195  CASE (decidsurf)
196  p_mm = pin + wu_dectr
197  CASE (grasssurf)
198  p_mm = pin + wu_grass
199  CASE default
200  p_mm = pin
201  END SELECT
202 
203  ! Add water from other surfaces within the same grid (RS2S) ----
204  ! AddWater is the water supplied to the current surface from other surfaces
205  ! i.e. drain*WaterDist (see SUEWS_ReDistributeWater)
206  p_mm = p_mm + addwater(is)
207  !==================================================================
208 
209  !========surface-specific calculation=========================
210  SELECT CASE (is)
211  CASE (pavsurf, bldgsurf)
212  !==== Impervious surfaces (Paved, Buildings) ======================
213  ! Add water from neighbouring grids (RG2G)
214  ! Add to PavSurf only, as water cannot flow onto buildings
215  IF (is == pavsurf) THEN
216  IF (sfr(pavsurf) /= 0) THEN ! If loop added HCW 08 Dec 2015
217  p_mm = p_mm + addimpervious/sfr(pavsurf)
218  ENDIF
219  ENDIF
220 
221  ! Calculate change in surface state_id (inputs - outputs)
222  chang(is) = p_mm - (drain(is) + ev)
223 
224  ! If p_mm is too large, excess goes to runoff (i.e. the rate of water supply is too fast)
225  ! and does not affect state_id
226  IF (p_mm > ipthreshold_mmhr/nsh_real) THEN
227  runoff(is) = runoff(is) + (p_mm - ipthreshold_mmhr/nsh_real)
228  chang(is) = ipthreshold_mmhr/nsh_real - (drain(is) + ev)
229  ENDIF
230 
231  ! Calculate updated state_id using chang
232  state_id(is) = stateold(is) + chang(is)
233 
234  ! Check state_id is within physical limits between zero (dry) and max. storage capacity
235  IF (state_id(is) < 0.0) THEN ! Cannot have a negative surface state_id
236  ! If there is not sufficient water on the surface, then don't allow this evaporation to happen
237  ! Allow evaporation only until surface is dry (state_id(is)=0); additional evaporation -> evaporation surplus
238  surplusevap(is) = abs(state_id(is)) !Surplus evaporation is that which tries to evaporate non-existent water
239  ev = ev - surplusevap(is) !Limit evaporation according to water availability
240  state_id(is) = 0.0 !Now surface is dry
241  ! elseif (state_id(is)>StoreDrainPrm(6,is)) then !!This should perhaps be StateLimit(is)
242  ! !! If state_id exceeds the storage capacity, then the excess goes to surface flooding
243  ! !SurfaceFlood(is)=SurfaceFlood(is)+(state_id(is)-StoreDrainPrm(6,is)) !!Need to deal with this properly
244  ! runoff(is)=runoff(is)+(state_id(is)-StoreDrainPrm(6,is)) !!needs to go to flooding
245  ! state_id(is)=StoreDrainPrm(6,is) !Now surface state_id is at max (storage) capacity
246  ENDIF
247 
248  ! Recalculate change in surface state_id from difference with previous timestep
249  chang(is) = state_id(is) - stateold(is)
250 
251  ! Runoff -------------------------------------------------------
252  ! For impervious surfaces, some of drain(is) becomes runoff
253  runoff(is) = runoff(is) + drain(is)*addwaterrunoff(is) !Drainage (that is not flowing to other surfaces) goes to runoff
254 
255  !So, up to this point, runoff(is) can have contributions if
256  ! p_mm > ipthreshold (water input too fast)
257  ! state_id > StoreDrainPrm(6,is) (net water exceeds storage capacity)
258  ! WaterDist specifies some fraction of drain(is) -> runoff
259 
260  CASE (conifsurf:bsoilsurf)
261  !==== For Conif, Decid, Grass, BSoil surfaces ==================
262  ! Transfer evaporation surplus from impervious surfaces to pervious surfaces
263  evpart = merge( &
264  dot_product(surplusevap(pavsurf:bldgsurf), sfr(pavsurf:bldgsurf)/pervfraction), &
265  0d0, &
266  pervfraction /= 0)
267 
268  ! Add surplus evaporation to ev for pervious surfaces
269  ev = ev + evpart
270 
271  ! ---- Add water from neighbouring grids (RG2G) ----
272  ! Add to Grass and BSoil only, as water cannot flow onto trees
273  IF (is == grasssurf .OR. is == bsoilsurf) THEN
274  IF ((sfr(grasssurf) + sfr(bsoilsurf)) /= 0) THEN
275  p_mm = p_mm + addveg/(sfr(grasssurf) + sfr(bsoilsurf))
276  ENDIF
277  ENDIF
278 
279  ! Calculate change in surface state_id (inputs - outputs)
280  chang(is) = p_mm - (drain(is) + ev)
281 
282  ! If p_mm is too large, excess goes to runoff (i.e. the rate of water supply is too fast)
283  ! and does not affect state_id
284  IF (p_mm > ipthreshold_mmhr/nsh_real) THEN
285  runoff(is) = runoff(is) + (p_mm - ipthreshold_mmhr/nsh_real)
286  chang(is) = ipthreshold_mmhr/nsh_real - (drain(is) + ev)
287  ENDIF
288 
289  ! Calculate updated state_id using chang
290  state_id(is) = stateold(is) + chang(is)
291 
292  ! Check state_id is within physical limits between zero (dry) and max. storage capacity
293  IF (state_id(is) < 0.0) THEN ! Cannot have a negative surface state_id
294  ! If there is not sufficient water on the surface, then remove water from soilstore
295  ! Allow evaporation until soilstore_id is depleted and surface is dry
296  IF ((soilstore_id(is) + state_id(is)) >= 0) THEN
297  soilstore_id(is) = soilstore_id(is) + state_id(is)
298  state_id(is) = 0.0
299  ! If there is not sufficient water on the surface or soilstore, then don't allow this evaporation to happen
300  ELSE
301  ev = ev - abs(state_id(is)) !Limit evaporation according to water availability
302  state_id(is) = 0.0 !Now surface is dry
303  ENDIF
304 
305  !elseif (state_id(is)>StoreDrainPrm(6,is)) then !!This should perhaps be StateLimit(is)
306  ! !! If state_id exceeds the storage capacity, then the excess goes to surface flooding
307  ! !SurfaceFlood(is)=SurfaceFlood(is)+(state_id(is)-StoreDrainPrm(6,is)) !!Need to deal with this properly
308  ! runoff(is)=runoff(is)+(state_id(is)-StoreDrainPrm(6,is)) !!needs to go to flooding
309  ! state_id(is)=StoreDrainPrm(6,is) !Now surface state_id is at max (storage) capacity
310  ENDIF
311 
312  ! Recalculate change in surface state_id from difference with previous timestep
313  chang(is) = state_id(is) - stateold(is)
314 
315  !Where should this go? Used to be before previous part!!
316  ! soilstore_id -------------------------------------------------
317  ! For pervious surfaces (not water), some of drain(is) goes to soil storage
318  ! Drainage (that is not flowing to other surfaces) goes to soil storages
319  soilstore_id(is) = soilstore_id(is) + drain(is)*addwaterrunoff(is)
320 
321  ! If soilstore is full, the excess will go to runoff
322  IF (soilstore_id(is) > soilstorecap(is)) THEN ! TODO: this should also go to flooding of some sort
323  runoff(is) = runoff(is) + (soilstore_id(is) - soilstorecap(is))
324  soilstore_id(is) = soilstorecap(is)
325  ELSEIF (soilstore_id(is) < 0) THEN !! QUESTION: But where does this lack of water go? !!Can this really happen here?
326  CALL errorhint(62, 'SUEWS_store: soilstore_id(is) < 0 ', soilstore_id(is), notused, is)
327  ! Code this properly - soilstore_id(is) < 0 shouldn't happen given the above loops
328  !soilstore_id(is)=0 !Groundwater / deeper soil should kick in
329  ENDIF
330 
331  CASE (watersurf)
332  IF (sfr(watersurf) /= 0) THEN
333 
334  ! ---- Add water from neighbouring grids (RG2G) ----
335  p_mm = p_mm + addwaterbody/sfr(watersurf)
336 
337  ! Calculate change in surface state_id (inputs - outputs)
338  ! No drainage for water surface
339  ! FlowChange is the difference in input and output flows [mm hr-1]
340  chang(is) = p_mm + flowchange/nsh_real - ev
341 
342  ! Calculate updated state_id using chang
343  state_id(is) = stateold(is) + chang(is)
344 
345  ! Check state_id is within physical limits between zero (dry) and max. storage capacity
346  IF (state_id(is) < 0.0) THEN ! Cannot have a negative surface state_id
347  ! If there is not sufficient water on the surface, then don't allow this evaporation to happen
348  ev = ev - abs(state_id(is)) !Limit evaporation according to water availability
349  state_id(is) = 0.0 !Now surface is dry
350  !elseif (state_id(is)>StoreDrainPrm(6,is)) then !!This should perhaps be StateLimit(is)
351  ! !! If state_id exceeds the storage capacity, then the excess goes to surface flooding
352  ! !SurfaceFlood(is)=SurfaceFlood(is)+(state_id(is)-StoreDrainPrm(6,is)) !!Need to deal with this properly
353  ! runoff(is)=runoff(is)+(state_id(is)-StoreDrainPrm(6,is)) !!needs to go to flooding
354  ! state_id(is)=StoreDrainPrm(6,is) !Now surface state_id is at max (storage) capacity
355  ENDIF
356 
357  ! Recalculate change in surface state_id from difference with previous timestep
358  chang(is) = state_id(is) - stateold(is)
359 
360  ! If state_id exceeds limit, then excess goes to runoff (currently applies to water StoreDrainPrm only)
361  IF (state_id(watersurf) > statelimit(watersurf)) THEN
364  runoffwaterbody = runoffwaterbody + runoff(watersurf)*sfr(watersurf)
365  ELSE
366  state_id(watersurf) = state_id(watersurf) + surpluswaterbody
367  IF (state_id(watersurf) > statelimit(watersurf)) THEN
368  runoffwaterbody = runoffwaterbody + (state_id(watersurf) - statelimit(watersurf))*sfr(watersurf)
370  ENDIF
371  ENDIF
372 
373  ! Recalculate change in surface state_id from difference with previous timestep
374  chang(is) = state_id(is) - stateold(is)
375  ENDIF
376  END SELECT
377  !==================================================================
378 
379  !==== RUNOFF ======================================================
380  ! TODO: to consider areas here - SurfaceArea may vary between grids too
381  ! - also implement where water for next surface is calculated (RunoffFromGrid subroutine)
382  ! Calculations of the piperunoff exceedensances moved to separate subroutine so that from snow same
383  ! calculations can be made. LJ in May 2015
384 
385  IF (is < watersurf) THEN !Not for water body
386  ! CALL updateFlood
387  CALL updateflood( &
388  is, runoff, &! input:
389  sfr, pipecapacity, runofftowater, &
390  runoffagimpervious, surpluswaterbody, runoffagveg, runoffpipes)! inout:
391  ENDIF
392 
real(kind(1d0)), dimension(nsurf) state_id
real(kind(1d0)), dimension(nsurf) drain
integer, parameter bsoilsurf
real(kind(1d0)), dimension(nsurf) soilstore_id
real(kind(1d0)) notused
real(kind(1d0)), dimension(nsurf) soilstorecap
real(kind(1d0)), dimension(nsurf) chang
integer, parameter conifsurf
real(kind(1d0)), dimension(nsurf) statelimit
subroutine updateflood(is, runoff, sfr, PipeCapacity, RunoffToWater, runoffAGimpervious, surplusWaterBody, runoffAGveg, runoffPipes)
integer, parameter grasssurf
real(kind(1d0)), dimension(nsurf) stateold
real(kind(1d0)), dimension(nsurf) addwater
real(kind(1d0)), dimension(nsurf) sfr
real(kind(1d0)), dimension(nsurf) addwaterrunoff
integer, parameter decidsurf
integer, parameter pavsurf
subroutine errorhint(errh, ProblemFile, VALUE, value2, valueI)
integer, parameter bldgsurf
integer, parameter watersurf
real(kind(1d0)), dimension(nsurf) runoff
Here is the call graph for this function:
Here is the caller graph for this function:

◆ suews_cal_horizontalsoilwater()

subroutine waterdist_module::suews_cal_horizontalsoilwater ( real(kind(1d0)), dimension(nsurf), intent(in)  sfr,
real(kind(1d0)), dimension(nsurf), intent(in)  SoilStoreCap,
real(kind(1d0)), dimension(nsurf), intent(in)  SoilDepth,
real(kind(1d0)), dimension(nsurf), intent(in)  SatHydraulicConduct,
real(kind(1d0)), intent(in)  SurfaceArea,
real(kind(1d0)), intent(in)  NonWaterFraction,
real(kind(1d0)), intent(in)  tstep_real,
real(kind(1d0)), dimension(nsurf), intent(inout)  soilstore_id,
real(kind(1d0)), dimension(nsurf), intent(inout)  runoffSoil,
real(kind(1d0)), intent(out)  runoffSoil_per_tstep 
)

Definition at line 626 of file suews_phys_waterdist.f95.

References allocatearray::nsurf.

Referenced by suews_driver::suews_cal_main().

626  !Transfers water in soil stores of land surfaces LJ (2010)
627  !Change the model to use varying hydraulic conductivity instead of constant value LJ (7/2011)
628  !If one of the surface's soildepth is zero, no water movement is considered
629  ! LJ 15/06/2017 Modification: - Moved location of runoffSoil_per_tstep within previous if-loop to avoid dividing with zero with 100% water surface
630  ! HCW 22/02/2017 Modifications: - Minor bug fixed in VWC1/B_r1 comparison - if statements reversed
631  ! HCW 13/08/2014 Modifications: - Order of surfaces reversed (for both is and jj loops)
632  ! - Number of units (e.g. properties) added to distance calculation
633  ! HCW 12/08/2014 Modifications: - Distance changed from m to mm in dI_dt calculation
634  ! - dI_dt [mm s-1] multiplied by no. seconds in timestep -> dI [mm]
635  ! - if MatPot is set to max. value (100000 mm), Km set to 0 mm s-1
636  ! - Provide parameters for residual volumetric soil moisture [m3 m-3]
637  ! (currently hard coded as 0.1 m3 m-3 for testing)
638  !
639  !------------------------------------------------------
640  ! use SUES_data
641  ! use gis_data
642  ! use time
643  ! use allocateArray
644 
645  IMPLICIT NONE
646 
647  REAL(KIND(1d0)), INTENT(in) ::sfr(nsurf)! surface fractions
648  REAL(KIND(1d0)), INTENT(in) ::soilstorecap(nsurf)!Capacity of soil store for each surface [mm]
649  REAL(KIND(1d0)), INTENT(in) ::soildepth(nsurf)!Depth of sub-surface soil store for each surface [mm]
650  REAL(KIND(1d0)), INTENT(in) ::sathydraulicconduct(nsurf)!Saturated hydraulic conductivity for each soil subsurface [mm s-1]
651  REAL(KIND(1d0)), INTENT(in) ::surfacearea!Surface area of the study area [m2]
652  REAL(KIND(1d0)), INTENT(in) ::nonwaterfraction! sum of surface cover fractions for all except water surfaces
653  REAL(KIND(1d0)), INTENT(in) ::tstep_real !tstep cast as a real for use in calculations
654 
655  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(inout) ::soilstore_id!Soil moisture of each surface type [mm]
656  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(inout) ::runoffsoil!Soil runoff from each soil sub-surface [mm]
657 
658  REAL(KIND(1d0)), INTENT(out) :: runoffsoil_per_tstep!Runoff to deep soil per timestep [mm] (for whole surface, excluding water body)
659 
660  INTEGER::jj, is
661  REAL(KIND(1d0)):: &
662  dimenwatercon1, dimenwatercon2, &
663  soilmoistcap_vol1, &
664  soilmoist_vol1, &
665  soilmoistcap_vol2, &
666  soilmoist_vol2, &
667  b_r1, matpot1, km1, &
668  b_r2, matpot2, km2, &
669  distance, kmweight, di, &
670  di_dt!Water flow between two stores
671 
672  REAL(KIND(1d0)), PARAMETER:: &
673  alphavg = 0.0005, & !Set alphavG to match value in van Genuchten (1980) [mm-1]
674  nunits = 1 !Can change to represent plot/base unit size
675 
676  ! SoilMoist_vol1,2 = Volumetric soil moisture [m3 m-3]
677  ! SoilMoistCap_vol1,2 = Volumetric soil moisture capacity [m3 m-3] (from FunctionalTypes)
678  ! MatPot1,2 = Water potential (i.e. pressure head) of store [mm]
679  ! DimenWaterCon1,2 = Dimensionless water content, or relative saturation [-]
680  ! Distance = Distance between two stores [m]
681  ! B_r1,2 = Residual volumetric soil moisture [m3 m-3]
682  ! Km1,2 = Hydraulic conductivity of store [mm s-1]
683  ! KmWeight = Weighted hydraulic conductivity [mm s-1]
684  ! alphavG = Parameter (could depend on soil texture) [mm-1]
685  ! dI = Water flow between stores [mm] dI = dI_dt * no. secs in each timestep
686  ! if dI > 0, first surface gains water, second surface loses water
687  ! NUnits = Number of repeating units (e.g. properties, blocks) for distance calculation [-]
688 
689  runoffsoil_per_tstep = 0
690 
691  DO is = 1, nsurf - 1 !nsurf-1,1,-1 !Loop through each surface, excluding water surface (runs backwards as of 13/08/2014, HCW)
692 
693  IF (sfr(is) /= 0 .AND. soilstorecap(is) > 0) THEN !If particular surface area exists
694  ! and is capable of storing water (SoilStoreCap [mm])
695  DO jj = is + 1, nsurf - 1 !is-1,1,-1 !Sub-loop through remaining surfaces (runs backwards as of 13/08/2014, HCW)
696 
697  IF (sfr(jj) /= 0 .AND. soilstorecap(jj) > 0) THEN !If other surface area exists
698  ! and is capable of storing water
699 
700  ! ---- For surface 1 -----------------------------------------------------
701  ! Calculate non-saturated VWC
702  soilmoistcap_vol1 = soilstorecap(is)/soildepth(is) !Volumetric soil moisture capacity [m3 m-3] (i.e. saturated VWC)
703  soilmoist_vol1 = soilstore_id(is)/soildepth(is) !Volumetric soil moisture [m3 m-3]
704 
705  !B_r1=SoilMoistCap_Vol1-SoilMoist_vol1 !Residual soil moisture content [m3 m-3]
706  b_r1 = 0.1 !HCW 12/08/2014 Temporary fix
707  ! Need to add residual soil moisture values to FunctionalTypes
708  !B_r1=VolSoilMoistRes(is) !Residual soil moisture content [m3 m-3]
709 
710  !Order of if statements reversed HCW 22 Feb 2017
711  !If soil moisture less than or equal to residual value, set MatPot to max and Km to 0 to suppress water movement
712  IF (b_r1 >= soilmoist_vol1) THEN
713  matpot1 = 100000
714  km1 = 0 !Added by LJ in Nov 2013
715  ! Otherwise, there should be enough water in the soil to allow horizontal transfer
716  ELSE
717  dimenwatercon1 = (soilmoist_vol1 - b_r1)/(soilmoistcap_vol1 - b_r1) !Dimensionless water content [-]
718 
719  ! If very large or very small, adjust for calculation of MatPot and Km
720  IF (dimenwatercon1 > 0.99999) THEN
721  dimenwatercon1 = dimenwatercon1 - 0.0001 !This cannot equal 1
722  ENDIF
723 
724  IF (dimenwatercon1 < 0.00000005) THEN
725  dimenwatercon1 = dimenwatercon1 + 0.0000001 !Added HCW 22 Feb 2017
726  ENDIF
727 
728  !van Genuchten (1980), with n=2 and m = 1-1/n = 1/2
729  !Water potential of first store [mm] (van Genuchten 1980, Eq 3 rearranged)
730  matpot1 = sqrt(1/dimenwatercon1**2 - 1)/alphavg
731 
732  !Hydraulic conductivity of first store [mm s-1] (van Genuchten 1980, Eq 8)
733  km1 = sathydraulicconduct(is)*sqrt(dimenwatercon1)*(1 - (1 - dimenwatercon1**2)**0.5)**2
734 
735  !Check this value (HCW 12/08/2014)
736  IF (matpot1 > 100000) THEN
737  matpot1 = 100000 !Max. potential is 100000 mm (van Genuchten 1980)
738  km1 = 0 !Added by HCW 12/08/2014
739  ENDIF
740 
741  ENDIF
742 
743  ! ---- For surface 2 -----------------------------------------------------
744  ! Calculate non-saturated VWC
745  soilmoistcap_vol2 = soilstorecap(jj)/soildepth(jj) !Volumetric soil moisture capacity [m3 m-3] (i.e. saturated VWC)
746  soilmoist_vol2 = soilstore_id(jj)/soildepth(jj) !Volumetric soil moisture [m3 m-3]
747 
748  !B_r2=SoilMoistCap_Vol2-SoilMoist_vol2 !Residual soil moisture content [m3 m-3]
749  b_r2 = 0.1 !HCW 12/08/2014 Temporary fix
750  ! Need to add residual soil moisture values to FunctionalTypes
751  !B_r2=VolSoilMoistRes(jj) !Residual soil moisture content [m3 m-3]
752 
753  !If soil moisture below residual value, set MatPot to maximum
754  IF (b_r2 >= soilmoist_vol2) THEN
755  matpot2 = 100000
756  km2 = 0 !Added by LJ in Nov 2013
757  ELSE
758  dimenwatercon2 = (soilmoist_vol2 - b_r2)/(soilmoistcap_vol2 - b_r2) !Dimensionless water content [-]
759 
760  IF (dimenwatercon2 > 0.99999) THEN
761  dimenwatercon2 = dimenwatercon2 - 0.0001 !This cannot equal 1
762  ENDIF
763 
764  IF (dimenwatercon2 < 0.00000005) THEN
765  dimenwatercon2 = dimenwatercon2 + 0.0000001 !Added HCW 22 Feb 2017
766  ENDIF
767 
768  !van Genuchten (1980), with n=2 and m = 1-1/n = 1/2
769  !Water potential of second store [mm] (van Genuchten 1980, Eq 3 rearranged)
770  matpot2 = sqrt(1/dimenwatercon2**2 - 1)/alphavg
771 
772  !Hydraulic conductivity of second store [mm s-1] (van Genuchten 1980, Eq 8)
773  km2 = sathydraulicconduct(jj)*sqrt(dimenwatercon2)*(1 - (1 - dimenwatercon2**2)**0.5)**2
774 
775  IF ((matpot2) > 100000) THEN
776  matpot2 = 100000 !Max. potential is 100000 mm (van Genuchten 1980)
777  km2 = 0 !Added by HCW 12/08/2014
778  ENDIF
779 
780  ENDIF
781 
782  ! ------------------------------------------------------------------------
783 
784  !Find distance between the two stores (see Jarvi et al. 2011)
785  !SurfaceArea in m2 (changed from ha to m2 n SUEWS_Initial), so Distance in m
786  distance = (sqrt(sfr(is)*surfacearea/nunits) + sqrt(sfr(jj)*surfacearea/nunits))/2
787 
788  !Calculate areally-weighted hydraulic conductivity [mm s-1]
789  kmweight = (sfr(is)*km1 + sfr(jj)*km2)/(sfr(is) + sfr(jj))
790 
791  !Find water flow between the two stores [mm s-1] (Green-Ampt equation, Hillel 1971)
792  !Multiply Distance by 1000 to convert m to mm (HCW 12/08/2014)
793  di_dt = -(kmweight)*(-matpot1 + matpot2)/(distance*1000)
794 
795  !Multiply dI_dt by number of seconds in timestep to convert mm s-1 to mm
796  !Added by HCW 12/08/2014
797  di = di_dt*tstep_real !Use dI instead of dI_dt in the following calculations
798 
799  !Move water (in mm) ------------------------------------------------------
800  !Water moves only if (i) there is sufficient water to move and (ii) there is space to move it
801 
802  ! If there is sufficient water in both surfaces, allow movement of dI to occur
803  IF ((soilstore_id(jj) >= di*sfr(is)/sfr(jj)) .AND. ((soilstore_id(is) + di) >= 0)) THEN
804  soilstore_id(is) = soilstore_id(is) + di
805  soilstore_id(jj) = soilstore_id(jj) - di*sfr(is)/sfr(jj) !Check (HCW 13/08/2014) - QUESTION: why adjust for jj and not is?
806 
807  ! If insufficient water in first surface to move dI, instead move as much as possible
808  ELSEIF ((soilstore_id(is) + di) < 0) THEN
809  soilstore_id(jj) = soilstore_id(jj) + soilstore_id(is)*sfr(is)/sfr(jj) !HCW 12/08/2014 switched order of these two lines
810  soilstore_id(is) = 0 !Check (HCW 13/08/2014) - QUESTION: can SM actually go to zero, or is this inconsistent with SMres?
811 
812  ! If insufficient water in second surface to move dI, instead move as much as possible
813  ELSE
814  soilstore_id(is) = soilstore_id(is) + soilstore_id(jj)*sfr(jj)/sfr(is)
815  soilstore_id(jj) = 0
816  ENDIF
817 
818  !If soil moisture exceeds capacity, excess goes to soil runoff (first surface)
819  IF (soilstore_id(is) > soilstorecap(is)) THEN
820  runoffsoil(is) = runoffsoil(is) + (soilstore_id(is) - soilstorecap(is))
821  soilstore_id(is) = soilstorecap(is)
822  !elseif (soilstore_id(is)<0) then !HCW 13/08/2014 commented out as should never be true here anyway...
823  ! soilstore_id(is)=0 ! ... and if so, need to do more here (i.e. account for other water too)
824  ENDIF
825 
826  !If soil moisture exceeds capacity, excess goes to soil runoff (second surface)
827  IF (soilstore_id(jj) > soilstorecap(jj)) THEN
828  runoffsoil(jj) = runoffsoil(jj) + (soilstore_id(jj) - soilstorecap(jj))
829  soilstore_id(jj) = soilstorecap(jj)
830  !elseif (soilstore_id(jj)<0) then !HCW 13/08/2014 commented out (as above)
831  ! soilstore_id(jj)=0
832  ENDIF
833 
834  ENDIF !end if second surface exists and is capable of storing water
835 
836  ENDDO !end jj loop over second surface
837 
838  runoffsoil_per_tstep = runoffsoil_per_tstep + (runoffsoil(is)*sfr(is)/nonwaterfraction) !Excludes water body. Moved here as otherwise code crashed when NonWaterFraction=0
839 
840  ENDIF !end if first surface exists and is capable of storing water
841 
842  !runoffSoil_per_tstep=runoffSoil_per_tstep+(runoffSoil(is)*sfr(is)/NonWaterFraction) !Excludes water body
843 
844  ENDDO !is loop over first surface
845 
real(kind(1d0)), dimension(nsurf) soilstore_id
integer, parameter nsurf
real(kind(1d0)), dimension(nsurf) soilstorecap
real(kind(1d0)), dimension(nsurf) sathydraulicconduct
real(kind(1d0)), dimension(nsurf) soildepth
real(kind(1d0)), dimension(nsurf) runoffsoil
real(kind(1d0)), dimension(nsurf) sfr
Here is the caller graph for this function:

◆ suews_cal_soilstate()

subroutine waterdist_module::suews_cal_soilstate ( integer, intent(in)  SMDMethod,
real(kind(1d0)), intent(in)  xsmd,
real(kind(1d0)), intent(in)  NonWaterFraction,
real(kind(1d0)), intent(in)  SoilMoistCap,
real(kind(1d0)), dimension(nsurf), intent(in)  SoilStoreCap,
real(kind(1d0)), intent(in)  surf_chang_per_tstep,
real(kind(1d0)), dimension(nsurf), intent(in)  soilstore_id,
real(kind(1d0)), dimension(nsurf), intent(in)  soilstoreOld,
real(kind(1d0)), dimension(nsurf), intent(in)  sfr,
real(kind(1d0)), intent(out)  smd,
real(kind(1d0)), dimension(nsurf), intent(out)  smd_nsurf,
real(kind(1d0)), intent(out)  tot_chang_per_tstep,
real(kind(1d0)), intent(out)  SoilState 
)

Definition at line 550 of file suews_phys_waterdist.f95.

References errorhint().

Referenced by suews_driver::suews_cal_main().

550 
551  IMPLICIT NONE
552  INTEGER, PARAMETER :: nsurf = 7
553 
554  INTEGER, INTENT(in) ::smdmethod
555  REAL(KIND(1d0)), INTENT(in)::xsmd
556  REAL(KIND(1d0)), INTENT(in)::nonwaterfraction
557  REAL(KIND(1d0)), INTENT(in)::soilmoistcap
558 
559  REAL(KIND(1d0)), INTENT(in)::surf_chang_per_tstep
560  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::soilstore_id !Soil moisture of each surface type [mm]
561  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::soilstoreold !Soil moisture of each surface type from previous timestep [mm]
562  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::sfr
563  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(in)::soilstorecap !Capacity of soil store for each surface [mm]
564 
565  REAL(KIND(1d0)), DIMENSION(nsurf), INTENT(out)::smd_nsurf !smd for each surface
566  REAL(KIND(1d0)), INTENT(out)::soilstate !Area-averaged soil moisture [mm] for whole surface
567  REAL(KIND(1d0)), INTENT(out)::smd !One value for whole surface
568  REAL(KIND(1d0)), INTENT(out)::tot_chang_per_tstep !Change in surface state_id
569 
570  REAL(KIND(1d0)), PARAMETER::notused = -999
571  REAL(KIND(1d0)), PARAMETER::nan = -999
572  INTEGER :: is
573 
574  soilstate = 0 !Area-averaged soil moisture [mm] for whole surface
575  IF (nonwaterfraction /= 0) THEN !Fixed for water surfaces only
576  DO is = 1, nsurf - 1 !No water body included
577  soilstate = soilstate + (soilstore_id(is)*sfr(is)/nonwaterfraction)
578  IF (soilstate < 0) THEN
579  CALL errorhint(62, 'SUEWS_Calculations: total SoilState < 0 (just added surface is) ', soilstate, notused, is)
580  ELSEIF (soilstate > soilmoistcap) THEN
581  CALL errorhint(62, 'SUEWS_Calculations: total SoilState > capacity (just added surface is) ', soilstate, notused, is)
582  !SoilMoist_state=SoilMoistCap !What is this LJ 10/2010 - QUESTION: SM exceeds capacity, but where does extra go?HCW 11/2014
583  ENDIF
584  ENDDO !end loop over surfaces
585  ! SoilState = DOT_PRODUCT(soilstore_id(1:nsurf - 1), sfr(1:nsurf - 1))/NonWaterFraction
586  ! IF (SoilState < 0) THEN
587  ! CALL ErrorHint(62, 'SUEWS_Calculations: total SoilState < 0 (just added surface is) ', SoilState, NotUsed, is)
588  ! ELSEIF (SoilState > SoilMoistCap) THEN
589  ! CALL ErrorHint(62, 'SUEWS_Calculations: total SoilState > capacity (just added surface is) ', SoilState, NotUsed, is)
590  ! !SoilMoist_state=SoilMoistCap !What is this LJ 10/2010 - QUESTION: SM exceeds capacity, but where does extra go?HCW 11/2014
591  ! ENDIF
592  ENDIF
593 
594  ! Calculate soil moisture deficit
595  smd = soilmoistcap - soilstate !One value for whole surface
596  smd_nsurf = soilstorecap - soilstore_id !smd for each surface
597 
598  ! Soil stores can change after horizontal water movements
599  ! Calculate total change in surface and soil state_id
600  tot_chang_per_tstep = surf_chang_per_tstep !Change in surface state_id
601  DO is = 1, (nsurf - 1) !No soil for water surface (so change in soil moisture is zero)
602  tot_chang_per_tstep = tot_chang_per_tstep + ((soilstore_id(is) - soilstoreold(is))*sfr(is)) !Add change in soil state_id
603  ENDDO
604 
605  IF (smdmethod > 0) THEN ! use observed value
606  ! smd_nsurf=NAN
607  smd_nsurf = nan
608  smd = xsmd
609  ENDIF
610 
real(kind(1d0)) nan
real(kind(1d0)), dimension(nsurf) soilstore_id
real(kind(1d0)) notused
integer, parameter nsurf
real(kind(1d0)), dimension(nsurf) soilstorecap
real(kind(1d0)), dimension(nsurf) sfr
real(kind(1d0)), dimension(nsurf) smd_nsurf
subroutine errorhint(errh, ProblemFile, VALUE, value2, valueI)
real(kind(1d0)), dimension(nsurf) soilstoreold
Here is the call graph for this function:
Here is the caller graph for this function:

◆ suews_cal_wateruse()

subroutine waterdist_module::suews_cal_wateruse ( real(kind(1d0)), intent(in)  nsh_real,
real(kind(1d0)), intent(in)  wu_m3,
real(kind(1d0)), intent(in)  SurfaceArea,
real(kind(1d0)), dimension(nsurf), intent(in)  sfr,
real(kind(1d0)), intent(in)  IrrFracConif,
real(kind(1d0)), intent(in)  IrrFracDecid,
real(kind(1d0)), intent(in)  IrrFracGrass,
integer, dimension(3), intent(in)  DayofWeek_id,
real(kind(1d0)), dimension(0:23, 2), intent(in)  WUProfA_24hr,
real(kind(1d0)), dimension(0:23, 2), intent(in)  WUProfM_24hr,
real(kind(1d0)), intent(in)  InternalWaterUse_h,
real(kind(1d0)), dimension(12), intent(in)  HDD_id,
real(kind(1d0)), dimension(9), intent(in)  WUDay_id,
integer, intent(in)  WaterUseMethod,
integer, intent(in)  NSH,
integer, intent(in)  it,
integer, intent(in)  imin,
integer, intent(in)  DLS,
real(kind(1d0)), intent(out)  wu_EveTr,
real(kind(1d0)), intent(out)  wu_DecTr,
real(kind(1d0)), intent(out)  wu_Grass,
real(kind(1d0)), intent(out)  int_wu,
real(kind(1d0)), intent(out)  ext_wu 
)

Definition at line 858 of file suews_phys_waterdist.f95.

References allocatearray::conifsurf, allocatearray::decidsurf, and allocatearray::grasssurf.

Referenced by suews_driver::suews_cal_main().

858  ! Conversion of water use (irrigation)
859  ! Last modified:
860  ! TS 30 Oct 2018 - fixed a bug in external water use
861  ! TS 08 Aug 2017 - addded explicit interface
862  ! LJ 6 Apr 2017 - WUchoice changed to WaterUseMethod
863  ! TK 14 Mar 2017 - Corrected the variable name WUAreaEveTr_m2 -> WUAreaGrass_m2 (row 35)
864  ! Corrected conversion from m to mm /1000 -> *1000 (row 47 and 60)
865  ! LJ 27 Jan 2016 - Removing Tab:s and cleaning the code
866  ! HCW 12 Feb 2015 - Water use [mm] now inidcates the amount of water supplied for each surface
867  ! HCW 26 Jan 2015 - Water use [mm] is the same for each surface at the moment and indicates the
868  ! amount of water supplied for each irrigated area
869  !
870  ! To Do:
871  ! - Add functionality for water on paved surfaces (street cleaning, fountains)
872 
873  IMPLICIT NONE
874  INTEGER, PARAMETER :: nsurf = 7
875 
876  REAL(KIND(1d0)), INTENT(in)::nsh_real
877  REAL(KIND(1d0)), INTENT(in)::wu_m3 ! external water input (e.g., irrigation) in m^3
878  REAL(KIND(1d0)), INTENT(in)::surfacearea !Surface area of the study area [m2]
879  REAL(KIND(1d0)), INTENT(in)::sfr(nsurf)!Surface fractions [-]
880  REAL(KIND(1d0)), INTENT(in)::irrfracconif!Fraction of evergreen trees which are irrigated
881  REAL(KIND(1d0)), INTENT(in)::irrfracdecid!Fraction of deciduous trees which are irrigated
882  REAL(KIND(1d0)), INTENT(in)::irrfracgrass!Fraction of grass which is irrigated
883  REAL(KIND(1d0)), INTENT(in)::internalwateruse_h !Internal water use [mm h-1]
884  ! WUProfA_tstep(24*NSH,2),& !Automatic water use profiles at model timestep
885  ! WUProfM_tstep(24*NSH,2),& !Manual water use profiles at model timestep
886  REAL(KIND(1d0)), DIMENSION(0:23, 2), INTENT(in)::wuprofa_24hr !Automatic water use profiles at hourly scales
887  REAL(KIND(1d0)), DIMENSION(0:23, 2), INTENT(in)::wuprofm_24hr !Manual water use profiles at hourly scales
888 
889  REAL(KIND(1d0)), DIMENSION(12), INTENT(in)::hdd_id !HDD(id-1), Heating Degree Days (see SUEWS_DailyState.f95)
890  REAL(KIND(1d0)), DIMENSION(9), INTENT(in)::wuday_id!WUDay(id-1), Daily water use for EveTr, DecTr, Grass [mm] (see SUEWS_DailyState.f95)
891 
892  INTEGER, INTENT(in):: &
893  dayofweek_id(3), & !DayofWeek(id) 1 - day of week; 2 - month; 3 - season
894  waterusemethod, & !Use modelled (0) or observed (1) water use
895  nsh, &!Number of timesteps per hour
896  it, & !Hour
897  imin, & !Minutes
898  dls !day lightsavings =1 + 1h) =0
899  ! nsurf
900 
901  REAL(KIND(1d0)), INTENT(out):: &
902  wu_evetr, &
903  wu_dectr, &
904  wu_grass, &
905  int_wu, &
906  ext_wu
907 
908  REAL(KIND(1d0)):: &
909  wuareaevetr_m2, &
910  wuareadectr_m2, &
911  wuareagrass_m2, &
912  wuareatotal_m2, &
913  internalwateruse, & !Internal water use for the model timestep [mm]
914  wufr = 1, &
915  wu = 0!Water use for the model timestep [mm]
916  INTEGER:: ih !Hour corrected for Daylight savings
917  INTEGER:: iu !1=weekday OR 2=weekend
918  INTEGER :: tstep ! timestep in second
919  REAL(KIND(1d0)), PARAMETER::nan = -999.
920  REAL(KIND(1d0)):: overuse
921  REAL(KIND(1d0)):: rain_cum_daily ! accumulated daily rainfall
922 
923  REAL(KIND(1d0)):: get_prof_spectime_sum
924 
925  ! NB: set OverUse as 0 as done module_constants, TS 22 Oct 2017
926  ! and the logic for calculating OverUse to be determined
927  overuse = 0
928 
929  ! timestep in second
930  tstep = int(3600/nsh)
931 
932  ! accumulated daily rainfall
933  rain_cum_daily = hdd_id(11)
934 
935  ! --------------------------------------------------------------------------------
936  ! If water used is observed and provided in the met forcing file, units are m3
937  ! Divide observed water use (in m3) by water use area to find water use (in mm)
938  IF (waterusemethod == 1) THEN !If water use is observed
939  ! Calculate water use area [m2] for each surface type
940  wuareaevetr_m2 = irrfracconif*sfr(conifsurf)*surfacearea
941  wuareadectr_m2 = irrfracdecid*sfr(decidsurf)*surfacearea
942  wuareagrass_m2 = irrfracgrass*sfr(grasssurf)*surfacearea
943  wuareatotal_m2 = wuareaevetr_m2 + wuareadectr_m2 + wuareagrass_m2
944 
945  !Set water use [mm] for each surface type to zero initially
946  wu_evetr = 0
947  wu_dectr = 0
948  wu_grass = 0
949  IF (wu_m3 == nan .OR. wu_m3 == 0) THEN !If no water use
950  ! wu_m3=0
951  wu = 0
952  ELSE !If water use
953  IF (wuareatotal_m2 > 0) THEN
954  wu = (wu_m3/wuareatotal_m2*1000) !Water use in mm for the whole irrigated area
955  IF (wuareaevetr_m2 > 0) THEN
956  wu_evetr = wu !Water use for Irr EveTr in mm - these are all the same at the moment
957  wu_evetr = wu_evetr*irrfracconif !Water use for EveTr in mm
958  ENDIF
959  IF (wuareadectr_m2 > 0) THEN
960  wu_dectr = wu !Water use for Irr DecTr in mm - these are all the same at the moment
961  wu_dectr = wu_dectr*irrfracdecid !Water use for DecTr in mm
962  ENDIF
963  IF (wuareagrass_m2 > 0) THEN
964  wu_grass = wu !Water use for Irr Grass in mm - these are all the same at the moment
965  wu_grass = wu_grass*irrfracgrass !Water use for Grass in mm
966  ENDIF
967  wu = (wu_m3/surfacearea*1000) !Water use for the whole study area in mm
968  ENDIF
969  ENDIF
970 
971  ! --------------------------------------------------------------------------------
972  ! If water use is modelled, calculate at timestep of model resolution [mm]
973  ELSEIF (waterusemethod == 0) THEN !If water use is modelled
974 
975  ! Account for Daylight saving
976  ih = it - dls
977  IF (ih < 0) ih = 23
978 
979  ! Weekday or weekend profile
980  iu = 1 !Set to 1=weekday
981  ! IF(DayofWeek(id,1)==1.OR.DayofWeek(id,1)==7) THEN
982  IF (dayofweek_id(1) == 1 .OR. dayofweek_id(1) == 7) THEN
983  iu = 2 !Set to 2=weekend
984  ENDIF
985 
986  !write(*,*) (NSH*(ih+1-1)+imin*NSH/60+1)
987 
988  ! ---- Automatic irrigation ----
989  ! wu_EveTr = WUProfA_tstep((NSH*(ih+1-1)+imin*NSH/60+1),iu)*WUDay_id(2) !Automatic evergreen trees
990  ! wu_DecTr = WUProfA_tstep((NSH*(ih+1-1)+imin*NSH/60+1),iu)*WUDay_id(5) !Automatic deciduous trees
991  ! wu_Grass = WUProfA_tstep((NSH*(ih+1-1)+imin*NSH/60+1),iu)*WUDay_id(8) !Automatic grass
992  wu_evetr = get_prof_spectime_sum(ih, imin, 0, wuprofa_24hr(:, iu), tstep)*wuday_id(2) !Automatic evergreen trees
993  wu_dectr = get_prof_spectime_sum(ih, imin, 0, wuprofa_24hr(:, iu), tstep)*wuday_id(5) !Automatic deciduous trees
994  wu_grass = get_prof_spectime_sum(ih, imin, 0, wuprofa_24hr(:, iu), tstep)*wuday_id(8) !Automatic grass
995 
996  ! PRINT*, ''
997  ! PRINT*, 'WUDay_id(2) ',WUDay_id(2)
998  ! PRINT*, 'profile ',get_Prof_SpecTime_sum(ih,imin,0,WUProfA_24hr(:,iu),tstep)
999  ! PRINT*, 'manual:'
1000  ! PRINT*, 'wu_EveTr',wu_EveTr
1001  ! PRINT*, 'wu_DecTr',wu_DecTr
1002  ! PRINT*, 'wu_Grass',wu_Grass
1003 
1004  ! ---- Manual irrigation ----
1005  wufr = 1 !Initialize WuFr to 1, but if raining, reduce manual fraction of water use
1006  ! If cumulative daily precipitation exceeds 2 mm
1007  IF (rain_cum_daily > 2) THEN !.and.WUDay(id-1,3)>0) then !Commented out HCW 23/01/2015
1008  wufr = 0 ! 0 -> No manual irrigation if raining
1009  ENDIF
1010 
1011  ! Add manual to automatic to find total irrigation
1012  ! wu_EveTr = wu_EveTr + (WuFr*WUProfM_tstep((NSH*(ih+1-1)+imin*NSH/60+1),iu)*WUDay_id(3)) !Manual evergreen trees
1013  ! wu_DecTr = wu_DecTr + (WuFr*WUProfM_tstep((NSH*(ih+1-1)+imin*NSH/60+1),iu)*WUDay_id(6)) !Manual deciduous trees
1014  ! wu_Grass = wu_Grass + (WuFr*WUProfM_tstep((NSH*(ih+1-1)+imin*NSH/60+1),iu)*WUDay_id(9)) !Manual grass
1015  wu_evetr = wu_evetr + (get_prof_spectime_sum(ih, imin, 0, wuprofm_24hr(:, iu), tstep)*wufr*wuday_id(3)) !Manual evergreen trees
1016  wu_dectr = wu_dectr + (get_prof_spectime_sum(ih, imin, 0, wuprofm_24hr(:, iu), tstep)*wufr*wuday_id(6)) !Manual deciduous trees
1017  wu_grass = wu_grass + (get_prof_spectime_sum(ih, imin, 0, wuprofm_24hr(:, iu), tstep)*wufr*wuday_id(9)) !Manual grass
1018 
1019  ! PRINT*, 'auto:'
1020  ! PRINT*, 'wu_EveTr',wu_EveTr
1021  ! PRINT*, 'wu_DecTr',wu_DecTr
1022  ! PRINT*, 'wu_Grass',wu_Grass
1023  ! Added HCW 12 Feb 2015.
1024  !wu_EveTr=wu_EveTr*sfr(ConifSurf)*IrrFracConif !Water use for EveTr [mm]
1025  !wu_DecTr=wu_DecTr*sfr(DecidSurf)*IrrFracDecid !Water use for DecTr [mm]
1026  !wu_Grass=wu_Grass*sfr(GrassSurf)*IrrFracGrass !Water use for Grass [mm]
1027  wu_evetr = wu_evetr*irrfracconif !Water use for EveTr [mm]
1028  wu_dectr = wu_dectr*irrfracdecid !Water use for DecTr [mm]
1029  wu_grass = wu_grass*irrfracgrass !Water use for Grass [mm]
1030 
1031  ! PRINT*, 'auto:'
1032  ! PRINT*, 'IrrFracConif',IrrFracConif
1033  ! PRINT*, 'IrrFracDecid',IrrFracDecid
1034  ! PRINT*, 'IrrFracGrass',IrrFracGrass
1035 
1036  ! Total water use for the whole study area [mm]
1037  wu = wu_evetr*sfr(conifsurf) + wu_dectr*sfr(decidsurf) + wu_grass*sfr(grasssurf)
1038 
1039  ENDIF !End WU_choice
1040  ! --------------------------------------------------------------------------------
1041 
1042  ! Internal water use is supplied in SUEWS_Irrigation in mm h-1
1043  ! Convert to mm for the model timestep
1044  internalwateruse = internalwateruse_h/nsh_real
1045 
1046  ! Remove InternalWaterUse from the total water use
1047  ext_wu = wu - (internalwateruse + overuse)
1048  ! Check ext_wu cannot be negative
1049  IF (ext_wu < 0) THEN
1050  overuse = abs(ext_wu)
1051  ext_wu = 0
1052  ELSE
1053  overuse = 0
1054  ENDIF
1055 
1056  int_wu = wu - ext_wu
1057 
1058  ! Decrease the water use for each surface by the same proportion
1059  IF (ext_wu /= 0 .AND. wu /= 0) THEN
1060  wu_evetr = wu_evetr*ext_wu/wu
1061  wu_dectr = wu_dectr*ext_wu/wu
1062  wu_grass = wu_grass*ext_wu/wu
1063  ENDIF
1064 
real(kind(1d0)) function get_prof_spectime_sum(Hour, Min, Sec, Prof_24h, dt)
real(kind(1d0)) nan
integer dls
integer, parameter nsurf
integer, parameter conifsurf
real(kind(1d0)), dimension(12) hdd_id
integer imin
real(kind(1d0)), dimension(0:23, 2) wuprofm_24hr
integer, parameter grasssurf
real(kind(1d0)), dimension(nsurf) sfr
real(kind(1d0)), dimension(0:23, 2) wuprofa_24hr
real(kind(1d0)), dimension(9) wuday_id
integer it
integer, parameter decidsurf
Here is the caller graph for this function:

◆ suews_update_soilmoist()

subroutine waterdist_module::suews_update_soilmoist ( real(kind(1d0)), intent(in)  NonWaterFraction,
real(kind(1d0)), dimension(nsurf), intent(in)  SoilStoreCap,
real(kind(1d0)), dimension(nsurf), intent(in)  sfr,
real(kind(1d0)), dimension(nsurf), intent(in)  soilstore_id,
real(kind(1d0)), intent(out)  SoilMoistCap,
real(kind(1d0)), intent(out)  SoilState,
real(kind(1d0)), intent(out)  vsmd,
real(kind(1d0)), intent(out)  smd 
)

Definition at line 504 of file suews_phys_waterdist.f95.

References allocatearray::conifsurf, allocatearray::decidsurf, allocatearray::grasssurf, and allocatearray::nsurf.

Referenced by suews_driver::suews_cal_main().

504  IMPLICIT NONE
505 
506  ! INTEGER,INTENT(in)::nsurf,ConifSurf,DecidSurf,GrassSurf
507  REAL(KIND(1d0)), INTENT(in)::nonwaterfraction
508  REAL(KIND(1d0)), INTENT(in), DIMENSION(nsurf)::soilstorecap, sfr, soilstore_id
509 
510  REAL(KIND(1d0)), INTENT(out)::soilmoistcap, soilstate
511  REAL(KIND(1d0)), INTENT(out)::vsmd, smd
512 
513  INTEGER :: is
514 
515  soilmoistcap = 0 !Maximum capacity of soil store [mm] for whole surface
516  soilstate = 0 !Area-averaged soil moisture [mm] for whole surface
517 
518  IF (nonwaterfraction /= 0) THEN !Soil states only calculated if soil exists. LJ June 2017
519  DO is = 1, nsurf - 1 !No water body included
520  soilmoistcap = soilmoistcap + (soilstorecap(is)*sfr(is)/nonwaterfraction)
521  soilstate = soilstate + (soilstore_id(is)*sfr(is)/nonwaterfraction)
522  ENDDO
523  ENDIF
524 
525  !If loop removed HCW 26 Feb 2015
526  !if (ir==1) then !Calculate initial smd
527  smd = soilmoistcap - soilstate
528  !endif
529 
530  ! Calculate soil moisture for vegetated surfaces only (for use in surface conductance)
531  vsmd = 0
532  DO is = conifsurf, grasssurf !Vegetated surfaces only
533  IF (sfr(conifsurf) + sfr(decidsurf) + sfr(grasssurf) == 0) THEN
534  vsmd = 0
535  ELSE
536  vsmd = vsmd + (soilstorecap(is) - soilstore_id(is))*sfr(is)/(sfr(conifsurf) + sfr(decidsurf) + sfr(grasssurf))
537  END IF
538  !write(*,*) is, vsmd, smd
539  ENDDO
540 
real(kind(1d0)), dimension(nsurf) soilstore_id
integer, parameter nsurf
real(kind(1d0)), dimension(nsurf) soilstorecap
integer, parameter conifsurf
integer, parameter grasssurf
real(kind(1d0)), dimension(nsurf) sfr
integer, parameter decidsurf
Here is the caller graph for this function:

◆ updateflood()

subroutine waterdist_module::updateflood ( integer, intent(in)  is,
real(kind(1d0)), dimension(nsurf), intent(in)  runoff,
real(kind(1d0)), dimension(nsurf), intent(in)  sfr,
real(kind(1d0)), intent(in)  PipeCapacity,
real(kind(1d0)), intent(in)  RunoffToWater,
real(kind(1d0)), intent(inout)  runoffAGimpervious,
real(kind(1d0)), intent(inout)  surplusWaterBody,
real(kind(1d0)), intent(inout)  runoffAGveg,
real(kind(1d0)), intent(inout)  runoffPipes 
)

Definition at line 401 of file suews_phys_waterdist.f95.

References allocatearray::bldgsurf, allocatearray::bsoilsurf, allocatearray::conifsurf, allocatearray::pavsurf, and allocatearray::watersurf.

Referenced by snow_module::snowcalc(), and soilstore().

401 
402  IMPLICIT NONE
403 
404  INTEGER, INTENT(in) :: is
405  REAL(KIND(1d0)), INTENT(in) :: sfr(nsurf), runoff(nsurf), pipecapacity, runofftowater
406  REAL(KIND(1d0)), INTENT(inout) :: runoffagimpervious, surpluswaterbody, runoffagveg, runoffpipes
407 
408  ! Add runoff to pipes
409  runoffpipes = runoffpipes + (runoff(is)*sfr(is))
410 
411  ! If pipe capacity is full, surface runoff occurs
412  ! N.B. this will happen each loop (replicates pipes filling up)
413  IF (runoffpipes > pipecapacity) THEN
414 
415  !------Paved and building surface
416  IF (is == pavsurf .OR. is == bldgsurf) THEN
417  IF (sfr(watersurf) > 0.0000001) THEN
418  ! If there is some water present, the water surface will take some of the flood water (fraction RunoffToWater)
419  ! RunoffToWater is specified in SUEWS_SiteSelect.txt
420  runoffagimpervious = runoffagimpervious + (runoffpipes - pipecapacity)*(1 - runofftowater)
421  surpluswaterbody = surpluswaterbody + (runoffpipes - pipecapacity)*runofftowater
422  ELSE
423  ! Otherwise, all flood water must go to runoff
424  runoffagimpervious = runoffagimpervious + (runoffpipes - pipecapacity)
425  ENDIF
426  !------other surfaces
427  ELSEIF (is >= conifsurf .AND. is <= bsoilsurf) THEN
428  IF (sfr(watersurf) > 0.0000001) THEN
429  ! If there is some water present, the water surface will take some of the flood water (fraction RunoffToWater)
430  runoffagveg = runoffagveg + (runoffpipes - pipecapacity)*(1 - runofftowater)
431  surpluswaterbody = surpluswaterbody + (runoffpipes - pipecapacity)*runofftowater
432  ELSE
433  ! Otherwise, all flood water must go to runoff
434  runoffagveg = runoffagveg + (runoffpipes - pipecapacity)
435  ENDIF
436  ENDIF
437 
438  runoffpipes = pipecapacity !Pipes are at their max capacity
439 
440  ENDIF !If runoff exceed pipe capacity
441 
integer, parameter bsoilsurf
integer, parameter nsurf
integer, parameter conifsurf
real(kind(1d0)), dimension(nsurf) sfr
integer, parameter pavsurf
integer, parameter bldgsurf
integer, parameter watersurf
real(kind(1d0)), dimension(nsurf) runoff
Here is the caller graph for this function: