32
32
# ROUTING FUNCTIONS
33
33
# -------------------------------------------------------------------------------------------------
34
34
@njit (parallel = True , fastmath = False , cache = True )
35
- def kinematicRouting (discharge , lateral_inflow , constant , upstream_lookup ,\
36
- num_upstream_pixels , ordered_pixels , start_stop , beta , inv_beta ,\
37
- b_minus_1 , a_dx_div_dt , b_a_dx_div_dt ):
35
+ def kinematicRouting (discharge_avg , discharge , lateral_inflow , constant , upstream_lookup ,\
36
+ num_upstream_pixels , ordered_pixels , start_stop , inv_time_delta , beta , inv_beta ,\
37
+ b_minus_1 , a_dx_div_dt , b_a_dx_div_dt , a_dx ):
38
38
"""
39
39
This function performs the kinematic wave routing algorithm to simulate the movement of water through a network of interconnected channels.
40
40
:param discharge:
@@ -49,6 +49,7 @@ def kinematicRouting(discharge, lateral_inflow, constant, upstream_lookup,\
49
49
:param b_minus_1:
50
50
:param a_dx_div_dt:
51
51
:param b_a_dx_div_dt:
52
+ :param a_dx: ChannelAlpha * ChanLength
52
53
:return:
53
54
"""
54
55
num_orders = start_stop .shape [0 ]
@@ -59,34 +60,43 @@ def kinematicRouting(discharge, lateral_inflow, constant, upstream_lookup,\
59
60
# Iterate through each pixel in the current order in parallel
60
61
for index in prange (first , last ):
61
62
# Solve the kinematic wave for the current pixel
62
- solve1Pixel (ordered_pixels [index ], discharge , lateral_inflow , constant , upstream_lookup ,\
63
- num_upstream_pixels , a_dx_div_dt , b_a_dx_div_dt , beta , inv_beta , b_minus_1 )
63
+ solve1Pixel (ordered_pixels [index ], discharge_avg , discharge , lateral_inflow , constant , upstream_lookup ,\
64
+ num_upstream_pixels , a_dx_div_dt , b_a_dx_div_dt , inv_time_delta , beta , inv_beta , b_minus_1 , a_dx )
64
65
65
66
@njit (nogil = True , fastmath = False , cache = True )
66
- def solve1Pixel (pix , discharge , lateral_inflow , constant ,\
67
+ def solve1Pixel (pix , discharge_avg , discharge , lateral_inflow , constant ,\
67
68
upstream_lookup , num_upstream_pixels , a_dx_div_dt ,\
68
- b_a_dx_div_dt , beta , inv_beta , b_minus_1 ):
69
+ b_a_dx_div_dt , inv_time_delta , beta , inv_beta , b_minus_1 , a_dx ):
69
70
"""
70
71
Te Chow et al. 1988 - Applied Hydrology - Chapter 9.6
71
72
:param pix:
72
- :param discharge:
73
+ :param discharge_avg: average outflow discharge
74
+ :param discharge: instantaneous outflow discharge
73
75
:param lateral_inflow:
74
76
:param constant:
75
77
:param upstream_lookup:
76
78
:param num_upstream_pixels:
77
79
:param a_dx_div_dt:
78
80
:param b_a_dx_div_dt:
81
+ :param inv_time_delta: 1/DtRouting
79
82
:param beta:
80
83
:param inv_beta:
81
84
:param b_minus_1:
85
+ :param a_dx: ChannelAlpha * ChanLength
82
86
:return:
83
87
"""
84
88
count = 0
85
89
previous_estimate = - 1.0
86
90
upstream_inflow = 0.0
91
+ upstream_inflow_avg = 0.0
92
+
93
+ # volume of water in channel at beginning of computation step
94
+ channel_volume_start = a_dx * discharge [pix ]** beta
95
+
87
96
# Inflow from upstream pixels
88
97
for ups_ix in range (num_upstream_pixels [pix ]):
89
98
upstream_inflow += discharge [upstream_lookup [pix ,ups_ix ]]
99
+ upstream_inflow_avg += discharge_avg [upstream_lookup [pix , ups_ix ]]
90
100
const_plus_ups_infl = upstream_inflow + constant [pix ] # upstream_inflow + alpha*dx/dt*Qold**beta + dx*specific_lateral_inflow
91
101
# If old discharge, upstream inflow and lateral inflow are below accuracy: set discharge to 0 and exit
92
102
if const_plus_ups_infl <= NEWTON_TOL :
@@ -111,6 +121,17 @@ def solve1Pixel(pix, discharge, lateral_inflow, constant,\
111
121
# If iterations converge to NEWTON_TOL, set value to 0
112
122
if discharge [pix ] == NEWTON_TOL :
113
123
discharge [pix ] = 0
124
+
125
+ # cmcheck
126
+ # avoid negative discharge
127
+ if discharge [pix ] < 0 :
128
+ discharge [pix ] = 0
129
+ # volume of water in channel at end of computation step
130
+ channel_volume_end = a_dx * discharge [pix ]** beta
131
+ # mass water balance to calc average outflow
132
+ discharge_avg [pix ] = upstream_inflow_avg + lateral_inflow + (channel_volume_start - channel_volume_end ) * inv_time_delta
133
+
134
+
114
135
# to simulate inf or nan: discharge[pix] = 1.0/0.0
115
136
# with gil:
116
137
# got_valid_value = np.isfinite(discharge[pix])
0 commit comments