epanet-plus 0.0.1__cp310-cp310-macosx_10_9_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of epanet-plus might be problematic. Click here for more details.
- docs/conf.py +67 -0
- epanet-msx-src/dispersion.h +27 -0
- epanet-msx-src/hash.c +107 -0
- epanet-msx-src/hash.h +28 -0
- epanet-msx-src/include/epanetmsx.h +104 -0
- epanet-msx-src/include/epanetmsx_export.h +42 -0
- epanet-msx-src/mathexpr.c +937 -0
- epanet-msx-src/mathexpr.h +39 -0
- epanet-msx-src/mempool.c +204 -0
- epanet-msx-src/mempool.h +24 -0
- epanet-msx-src/msxchem.c +1285 -0
- epanet-msx-src/msxcompiler.c +368 -0
- epanet-msx-src/msxdict.h +42 -0
- epanet-msx-src/msxdispersion.c +586 -0
- epanet-msx-src/msxerr.c +116 -0
- epanet-msx-src/msxfile.c +260 -0
- epanet-msx-src/msxfuncs.c +175 -0
- epanet-msx-src/msxfuncs.h +35 -0
- epanet-msx-src/msxinp.c +1504 -0
- epanet-msx-src/msxout.c +398 -0
- epanet-msx-src/msxproj.c +791 -0
- epanet-msx-src/msxqual.c +2011 -0
- epanet-msx-src/msxrpt.c +400 -0
- epanet-msx-src/msxtank.c +422 -0
- epanet-msx-src/msxtoolkit.c +1164 -0
- epanet-msx-src/msxtypes.h +551 -0
- epanet-msx-src/msxutils.c +524 -0
- epanet-msx-src/msxutils.h +56 -0
- epanet-msx-src/newton.c +158 -0
- epanet-msx-src/newton.h +34 -0
- epanet-msx-src/rk5.c +287 -0
- epanet-msx-src/rk5.h +39 -0
- epanet-msx-src/ros2.c +293 -0
- epanet-msx-src/ros2.h +35 -0
- epanet-msx-src/smatrix.c +816 -0
- epanet-msx-src/smatrix.h +29 -0
- epanet-src/AUTHORS +60 -0
- epanet-src/LICENSE +21 -0
- epanet-src/enumstxt.h +151 -0
- epanet-src/epanet.c +5937 -0
- epanet-src/epanet2.c +961 -0
- epanet-src/epanet2.def +131 -0
- epanet-src/errors.dat +79 -0
- epanet-src/flowbalance.c +186 -0
- epanet-src/funcs.h +219 -0
- epanet-src/genmmd.c +1000 -0
- epanet-src/hash.c +177 -0
- epanet-src/hash.h +28 -0
- epanet-src/hydcoeffs.c +1303 -0
- epanet-src/hydraul.c +1164 -0
- epanet-src/hydsolver.c +781 -0
- epanet-src/hydstatus.c +442 -0
- epanet-src/include/epanet2.h +466 -0
- epanet-src/include/epanet2_2.h +1962 -0
- epanet-src/include/epanet2_enums.h +518 -0
- epanet-src/inpfile.c +884 -0
- epanet-src/input1.c +672 -0
- epanet-src/input2.c +970 -0
- epanet-src/input3.c +2265 -0
- epanet-src/leakage.c +527 -0
- epanet-src/mempool.c +146 -0
- epanet-src/mempool.h +24 -0
- epanet-src/output.c +853 -0
- epanet-src/project.c +1691 -0
- epanet-src/quality.c +695 -0
- epanet-src/qualreact.c +800 -0
- epanet-src/qualroute.c +696 -0
- epanet-src/report.c +1559 -0
- epanet-src/rules.c +1500 -0
- epanet-src/smatrix.c +871 -0
- epanet-src/text.h +508 -0
- epanet-src/types.h +928 -0
- epanet-src/util/cstr_helper.c +59 -0
- epanet-src/util/cstr_helper.h +38 -0
- epanet-src/util/errormanager.c +92 -0
- epanet-src/util/errormanager.h +39 -0
- epanet-src/util/filemanager.c +212 -0
- epanet-src/util/filemanager.h +81 -0
- epanet-src/validate.c +408 -0
- epanet.cpython-310-darwin.so +0 -0
- epanet_plus/VERSION +1 -0
- epanet_plus/__init__.py +8 -0
- epanet_plus/epanet_plus.c +118 -0
- epanet_plus/epanet_toolkit.py +2730 -0
- epanet_plus/epanet_wrapper.py +2414 -0
- epanet_plus/include/epanet_plus.h +9 -0
- epanet_plus-0.0.1.dist-info/METADATA +152 -0
- epanet_plus-0.0.1.dist-info/RECORD +105 -0
- epanet_plus-0.0.1.dist-info/WHEEL +6 -0
- epanet_plus-0.0.1.dist-info/licenses/LICENSE +21 -0
- epanet_plus-0.0.1.dist-info/top_level.txt +11 -0
- examples/basic_usage.py +35 -0
- python-extension/ext.c +344 -0
- python-extension/pyepanet.c +2133 -0
- python-extension/pyepanet.h +143 -0
- python-extension/pyepanet2.c +1823 -0
- python-extension/pyepanet2.h +141 -0
- python-extension/pyepanet_plus.c +37 -0
- python-extension/pyepanet_plus.h +4 -0
- python-extension/pyepanetmsx.c +388 -0
- python-extension/pyepanetmsx.h +35 -0
- tests/test_epanet.py +16 -0
- tests/test_epanetmsx.py +36 -0
- tests/test_epyt.py +114 -0
- tests/test_load_inp_from_buffer.py +18 -0
epanet-src/hydstatus.c
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
/*
|
|
2
|
+
******************************************************************************
|
|
3
|
+
Project: OWA EPANET
|
|
4
|
+
Version: 2.3
|
|
5
|
+
Module: hydstatus.c
|
|
6
|
+
Description: updates hydraulic status of network elements
|
|
7
|
+
Authors: see AUTHORS
|
|
8
|
+
Copyright: see AUTHORS
|
|
9
|
+
License: see LICENSE
|
|
10
|
+
Last Updated: 02/03/2023
|
|
11
|
+
******************************************************************************
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
#include <stdlib.h>
|
|
15
|
+
#include <stdio.h>
|
|
16
|
+
|
|
17
|
+
#include "types.h"
|
|
18
|
+
#include "funcs.h"
|
|
19
|
+
|
|
20
|
+
// Exported functions
|
|
21
|
+
int valvestatus(Project *);
|
|
22
|
+
int linkstatus(Project *);
|
|
23
|
+
|
|
24
|
+
// Local functions
|
|
25
|
+
static StatusType cvstatus(Project *, StatusType, double, double);
|
|
26
|
+
static StatusType pumpstatus(Project *, int, double);
|
|
27
|
+
static StatusType prvstatus(Project *, int, StatusType, double, double, double);
|
|
28
|
+
static StatusType psvstatus(Project *, int, StatusType, double, double, double);
|
|
29
|
+
static StatusType fcvstatus(Project *, int, StatusType, double, double);
|
|
30
|
+
static void tankstatus(Project *, int, int, double);
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
int valvestatus(Project *pr)
|
|
34
|
+
/*
|
|
35
|
+
**-----------------------------------------------------------------
|
|
36
|
+
** Input: none
|
|
37
|
+
** Output: returns 1 if any pressure or flow control valve
|
|
38
|
+
** changes status, 0 otherwise
|
|
39
|
+
** Purpose: updates status for PRVs & PSVs whose status
|
|
40
|
+
** is not fixed to OPEN/CLOSED
|
|
41
|
+
**-----------------------------------------------------------------
|
|
42
|
+
*/
|
|
43
|
+
{
|
|
44
|
+
Network *net = &pr->network;
|
|
45
|
+
Hydraul *hyd = &pr->hydraul;
|
|
46
|
+
Report *rpt = &pr->report;
|
|
47
|
+
|
|
48
|
+
int change = FALSE, // Status change flag
|
|
49
|
+
i, k, // Valve & link indexes
|
|
50
|
+
n1, n2; // Start & end nodes
|
|
51
|
+
double hset; // Valve head setting
|
|
52
|
+
StatusType status; // Valve status settings
|
|
53
|
+
Slink *link;
|
|
54
|
+
|
|
55
|
+
// Examine each valve
|
|
56
|
+
for (i = 1; i <= net->Nvalves; i++)
|
|
57
|
+
{
|
|
58
|
+
// Get valve's link and its index
|
|
59
|
+
k = net->Valve[i].Link;
|
|
60
|
+
link = &net->Link[k];
|
|
61
|
+
|
|
62
|
+
// Ignore valve if its status is fixed to OPEN/CLOSED
|
|
63
|
+
if (hyd->LinkSetting[k] == MISSING) continue;
|
|
64
|
+
|
|
65
|
+
// Get start/end node indexes & save current status
|
|
66
|
+
n1 = link->N1;
|
|
67
|
+
n2 = link->N2;
|
|
68
|
+
status = hyd->LinkStatus[k];
|
|
69
|
+
|
|
70
|
+
// Evaluate valve's new status
|
|
71
|
+
switch (link->Type)
|
|
72
|
+
{
|
|
73
|
+
case PRV:
|
|
74
|
+
hset = net->Node[n2].El + hyd->LinkSetting[k];
|
|
75
|
+
hyd->LinkStatus[k] = prvstatus(pr, k, status, hset,
|
|
76
|
+
hyd->NodeHead[n1], hyd->NodeHead[n2]);
|
|
77
|
+
break;
|
|
78
|
+
case PSV:
|
|
79
|
+
hset = net->Node[n1].El + hyd->LinkSetting[k];
|
|
80
|
+
hyd->LinkStatus[k] = psvstatus(pr, k, status, hset,
|
|
81
|
+
hyd->NodeHead[n1], hyd->NodeHead[n2]);
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Check for a status change
|
|
88
|
+
if (status != hyd->LinkStatus[k])
|
|
89
|
+
{
|
|
90
|
+
if (rpt->Statflag == FULL)
|
|
91
|
+
{
|
|
92
|
+
writestatchange(pr, k, status, hyd->LinkStatus[k]);
|
|
93
|
+
}
|
|
94
|
+
change = TRUE;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return change;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
int linkstatus(Project *pr)
|
|
102
|
+
/*
|
|
103
|
+
**--------------------------------------------------------------
|
|
104
|
+
** Input: none
|
|
105
|
+
** Output: returns 1 if any link changes status, 0 otherwise
|
|
106
|
+
** Purpose: determines new status for pumps, CVs, FCVs & pipes
|
|
107
|
+
** to tanks.
|
|
108
|
+
**--------------------------------------------------------------
|
|
109
|
+
*/
|
|
110
|
+
{
|
|
111
|
+
Network *net = &pr->network;
|
|
112
|
+
Hydraul *hyd = &pr->hydraul;
|
|
113
|
+
Report *rpt = &pr->report;
|
|
114
|
+
|
|
115
|
+
int change = FALSE, // Status change flag
|
|
116
|
+
k, // Link index
|
|
117
|
+
n1, // Start node index
|
|
118
|
+
n2; // End node index
|
|
119
|
+
double dh; // Head difference across link
|
|
120
|
+
StatusType status; // Current status
|
|
121
|
+
Slink *link;
|
|
122
|
+
|
|
123
|
+
// Examine each link
|
|
124
|
+
for (k = 1; k <= net->Nlinks; k++)
|
|
125
|
+
{
|
|
126
|
+
link = &net->Link[k];
|
|
127
|
+
n1 = link->N1;
|
|
128
|
+
n2 = link->N2;
|
|
129
|
+
dh = hyd->NodeHead[n1] - hyd->NodeHead[n2];
|
|
130
|
+
|
|
131
|
+
// Re-open temporarily closed links (status = XHEAD or TEMPCLOSED)
|
|
132
|
+
status = hyd->LinkStatus[k];
|
|
133
|
+
if (status == XHEAD || status == TEMPCLOSED)
|
|
134
|
+
{
|
|
135
|
+
hyd->LinkStatus[k] = OPEN;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check for status changes in CVs and pumps
|
|
139
|
+
if (link->Type == CVPIPE)
|
|
140
|
+
{
|
|
141
|
+
hyd->LinkStatus[k] = cvstatus(pr, hyd->LinkStatus[k], dh,
|
|
142
|
+
hyd->LinkFlow[k]);
|
|
143
|
+
}
|
|
144
|
+
if (link->Type == PUMP && hyd->LinkStatus[k] >= OPEN &&
|
|
145
|
+
hyd->LinkSetting[k] > 0.0)
|
|
146
|
+
{
|
|
147
|
+
hyd->LinkStatus[k] = pumpstatus(pr, k, -dh);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Check for status changes in non-fixed FCVs
|
|
151
|
+
if (link->Type == FCV && hyd->LinkSetting[k] != MISSING)
|
|
152
|
+
{
|
|
153
|
+
hyd->LinkStatus[k] = fcvstatus(pr, k, status, hyd->NodeHead[n1],
|
|
154
|
+
hyd->NodeHead[n2]);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Check for flow into (out of) full (empty) tanks
|
|
158
|
+
if (n1 > net->Njuncs) tankstatus(pr, k, n1, hyd->LinkFlow[k]);
|
|
159
|
+
if (n2 > net->Njuncs) tankstatus(pr, k, n2, -hyd->LinkFlow[k]);
|
|
160
|
+
|
|
161
|
+
// Note any change in link status; do not revise link flow
|
|
162
|
+
if (status != hyd->LinkStatus[k])
|
|
163
|
+
{
|
|
164
|
+
change = TRUE;
|
|
165
|
+
if (rpt->Statflag == FULL)
|
|
166
|
+
{
|
|
167
|
+
writestatchange(pr, k, status, hyd->LinkStatus[k]);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return change;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
StatusType cvstatus(Project *pr, StatusType s, double dh, double q)
|
|
176
|
+
/*
|
|
177
|
+
**--------------------------------------------------
|
|
178
|
+
** Input: s = current link status
|
|
179
|
+
** dh = head loss across link
|
|
180
|
+
** q = link flow
|
|
181
|
+
** Output: returns new link status
|
|
182
|
+
** Purpose: updates status of a check valve link.
|
|
183
|
+
**--------------------------------------------------
|
|
184
|
+
*/
|
|
185
|
+
{
|
|
186
|
+
Hydraul *hyd = &pr->hydraul;
|
|
187
|
+
|
|
188
|
+
// Prevent reverse flow through CVs
|
|
189
|
+
if (ABS(dh) > hyd->Htol)
|
|
190
|
+
{
|
|
191
|
+
if (dh < -hyd->Htol) return CLOSED;
|
|
192
|
+
else if (q < -hyd->Qtol) return CLOSED;
|
|
193
|
+
else return OPEN;
|
|
194
|
+
}
|
|
195
|
+
else
|
|
196
|
+
{
|
|
197
|
+
if (q < -hyd->Qtol) return CLOSED;
|
|
198
|
+
else return s;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
StatusType pumpstatus(Project *pr, int k, double dh)
|
|
204
|
+
/*
|
|
205
|
+
**--------------------------------------------------
|
|
206
|
+
** Input: k = link index
|
|
207
|
+
** dh = head gain across link
|
|
208
|
+
** Output: returns new pump status
|
|
209
|
+
** Purpose: updates status of an open pump.
|
|
210
|
+
**--------------------------------------------------
|
|
211
|
+
*/
|
|
212
|
+
{
|
|
213
|
+
Hydraul *hyd = &pr->hydraul;
|
|
214
|
+
Network *net = &pr->network;
|
|
215
|
+
|
|
216
|
+
int p;
|
|
217
|
+
double hmax;
|
|
218
|
+
|
|
219
|
+
// Find maximum head (hmax) pump can deliver
|
|
220
|
+
p = findpump(net, k);
|
|
221
|
+
if (net->Pump[p].Ptype == CONST_HP)
|
|
222
|
+
{
|
|
223
|
+
// Use huge value for constant HP pump
|
|
224
|
+
hmax = BIG;
|
|
225
|
+
if (hyd->LinkFlow[k] < TINY) return TEMPCLOSED;
|
|
226
|
+
}
|
|
227
|
+
else
|
|
228
|
+
{
|
|
229
|
+
// Use speed-adjusted shut-off head for other pumps
|
|
230
|
+
hmax = SQR(hyd->LinkSetting[k]) * net->Pump[p].Hmax;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Check if currrent head gain exceeds pump's max. head
|
|
234
|
+
if (dh > hmax + hyd->Htol) return XHEAD;
|
|
235
|
+
|
|
236
|
+
// No check is made to see if flow exceeds pump's max. flow
|
|
237
|
+
return OPEN;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
StatusType prvstatus(Project *pr, int k, StatusType s, double hset,
|
|
242
|
+
double h1, double h2)
|
|
243
|
+
/*
|
|
244
|
+
**-----------------------------------------------------------
|
|
245
|
+
** Input: k = link index
|
|
246
|
+
** s = current status
|
|
247
|
+
** hset = valve head setting
|
|
248
|
+
** h1 = head at upstream node
|
|
249
|
+
** h2 = head at downstream node
|
|
250
|
+
** Output: returns new valve status
|
|
251
|
+
** Purpose: updates status of a pressure reducing valve.
|
|
252
|
+
**-----------------------------------------------------------
|
|
253
|
+
*/
|
|
254
|
+
{
|
|
255
|
+
Hydraul *hyd = &pr->hydraul;
|
|
256
|
+
|
|
257
|
+
StatusType status; // Valve's new status
|
|
258
|
+
double hml; // Head loss when fully opened
|
|
259
|
+
double htol;
|
|
260
|
+
Slink *link;
|
|
261
|
+
|
|
262
|
+
htol = hyd->Htol;
|
|
263
|
+
link = &pr->network.Link[k];
|
|
264
|
+
|
|
265
|
+
// Head loss when fully open
|
|
266
|
+
hml = link->Km * SQR(hyd->LinkFlow[k]);
|
|
267
|
+
|
|
268
|
+
// Rules for updating valve's status from current value s
|
|
269
|
+
status = s;
|
|
270
|
+
switch (s)
|
|
271
|
+
{
|
|
272
|
+
case ACTIVE:
|
|
273
|
+
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
|
274
|
+
else if (h1 - hml < hset - htol) status = OPEN;
|
|
275
|
+
else status = ACTIVE;
|
|
276
|
+
break;
|
|
277
|
+
|
|
278
|
+
case OPEN:
|
|
279
|
+
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
|
280
|
+
else if (h2 >= hset + htol) status = ACTIVE;
|
|
281
|
+
else status = OPEN;
|
|
282
|
+
break;
|
|
283
|
+
|
|
284
|
+
case CLOSED:
|
|
285
|
+
if (h1 >= hset + htol && h2 < hset - htol) status = ACTIVE;
|
|
286
|
+
else if (h1 < hset - htol && h1 > h2 + htol) status = OPEN;
|
|
287
|
+
else status = CLOSED;
|
|
288
|
+
break;
|
|
289
|
+
|
|
290
|
+
case XPRESSURE:
|
|
291
|
+
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
|
292
|
+
break;
|
|
293
|
+
|
|
294
|
+
default:
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
return status;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
StatusType psvstatus(Project *pr, int k, StatusType s, double hset,
|
|
302
|
+
double h1, double h2)
|
|
303
|
+
/*
|
|
304
|
+
**-----------------------------------------------------------
|
|
305
|
+
** Input: k = link index
|
|
306
|
+
** s = current status
|
|
307
|
+
** hset = valve head setting
|
|
308
|
+
** h1 = head at upstream node
|
|
309
|
+
** h2 = head at downstream node
|
|
310
|
+
** Output: returns new valve status
|
|
311
|
+
** Purpose: updates status of a pressure sustaining valve.
|
|
312
|
+
**-----------------------------------------------------------
|
|
313
|
+
*/
|
|
314
|
+
{
|
|
315
|
+
Hydraul *hyd = &pr->hydraul;
|
|
316
|
+
|
|
317
|
+
StatusType status; // Valve's new status
|
|
318
|
+
double hml; // Head loss when fully opened
|
|
319
|
+
double htol;
|
|
320
|
+
Slink *link;
|
|
321
|
+
|
|
322
|
+
htol = hyd->Htol;
|
|
323
|
+
link = &pr->network.Link[k];
|
|
324
|
+
|
|
325
|
+
// Head loss when fully open
|
|
326
|
+
hml = link->Km * SQR(hyd->LinkFlow[k]);
|
|
327
|
+
|
|
328
|
+
// Rules for updating valve's status from current value s
|
|
329
|
+
status = s;
|
|
330
|
+
switch (s)
|
|
331
|
+
{
|
|
332
|
+
case ACTIVE:
|
|
333
|
+
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
|
334
|
+
else if (h2 + hml > hset + htol) status = OPEN;
|
|
335
|
+
else status = ACTIVE;
|
|
336
|
+
break;
|
|
337
|
+
|
|
338
|
+
case OPEN:
|
|
339
|
+
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
|
340
|
+
else if (h1 < hset - htol) status = ACTIVE;
|
|
341
|
+
else status = OPEN;
|
|
342
|
+
break;
|
|
343
|
+
|
|
344
|
+
case CLOSED:
|
|
345
|
+
if (h2 > hset + htol && h1 > h2 + htol) status = OPEN;
|
|
346
|
+
else if (h1 >= hset + htol && h1 > h2 + htol) status = ACTIVE;
|
|
347
|
+
else status = CLOSED;
|
|
348
|
+
break;
|
|
349
|
+
|
|
350
|
+
case XPRESSURE:
|
|
351
|
+
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
|
352
|
+
break;
|
|
353
|
+
|
|
354
|
+
default:
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
return status;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
StatusType fcvstatus(Project *pr, int k, StatusType s, double h1, double h2)
|
|
362
|
+
/*
|
|
363
|
+
**-----------------------------------------------------------
|
|
364
|
+
** Input: k = link index
|
|
365
|
+
** s = current status
|
|
366
|
+
** h1 = head at upstream node
|
|
367
|
+
** h2 = head at downstream node
|
|
368
|
+
** Output: returns new valve status
|
|
369
|
+
** Purpose: updates status of a flow control valve.
|
|
370
|
+
**
|
|
371
|
+
** Valve status changes to XFCV if flow reversal.
|
|
372
|
+
** If current status is XFCV and current flow is
|
|
373
|
+
** above setting, then valve becomes active.
|
|
374
|
+
** If current status is XFCV, and current flow
|
|
375
|
+
** positive but still below valve setting, then
|
|
376
|
+
** status remains same.
|
|
377
|
+
**-----------------------------------------------------------
|
|
378
|
+
*/
|
|
379
|
+
{
|
|
380
|
+
Hydraul *hyd = &pr->hydraul;
|
|
381
|
+
StatusType status; // New valve status
|
|
382
|
+
|
|
383
|
+
status = s;
|
|
384
|
+
if (h1 - h2 < -hyd->Htol)
|
|
385
|
+
{
|
|
386
|
+
status = XFCV;
|
|
387
|
+
}
|
|
388
|
+
else if (hyd->LinkFlow[k] < -hyd->Qtol)
|
|
389
|
+
{
|
|
390
|
+
status = XFCV;
|
|
391
|
+
}
|
|
392
|
+
else if (s == XFCV && hyd->LinkFlow[k] >= hyd->LinkSetting[k])
|
|
393
|
+
{
|
|
394
|
+
status = ACTIVE;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Active valve's loss coeff. can't be < fully open loss coeff.
|
|
398
|
+
else if (status == ACTIVE)
|
|
399
|
+
{
|
|
400
|
+
if ((h1 - h2) / SQR(hyd->LinkFlow[k]) < pr->network.Link[k].Km)
|
|
401
|
+
{
|
|
402
|
+
status = XFCV;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return status;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
void tankstatus(Project *pr, int k, int n, double q)
|
|
410
|
+
/*
|
|
411
|
+
**----------------------------------------------------------------
|
|
412
|
+
** Input: k = link index
|
|
413
|
+
** n = tank node index
|
|
414
|
+
** q = link flow rate out of (+) or into (-) tank
|
|
415
|
+
** Output: none
|
|
416
|
+
** Purpose: closes link flowing into full or out of empty tank
|
|
417
|
+
**----------------------------------------------------------------
|
|
418
|
+
*/
|
|
419
|
+
{
|
|
420
|
+
Network *net = &pr->network;
|
|
421
|
+
Hydraul *hyd = &pr->hydraul;
|
|
422
|
+
|
|
423
|
+
int i;
|
|
424
|
+
Stank *tank;
|
|
425
|
+
Slink *link = &net->Link[k];
|
|
426
|
+
|
|
427
|
+
// Return if link is closed
|
|
428
|
+
if (hyd->LinkStatus[k] <= CLOSED) return;
|
|
429
|
+
|
|
430
|
+
// Ignore reservoirs
|
|
431
|
+
i = n - net->Njuncs;
|
|
432
|
+
tank = &net->Tank[i];
|
|
433
|
+
if (tank->A == 0.0) return;
|
|
434
|
+
|
|
435
|
+
// Can't add flow to a full tank
|
|
436
|
+
if (hyd->NodeHead[n] >= tank->Hmax && !tank->CanOverflow && q < 0.0)
|
|
437
|
+
hyd->LinkStatus[k] = TEMPCLOSED;
|
|
438
|
+
|
|
439
|
+
// Can't remove flow from an empty tank
|
|
440
|
+
else if (hyd->NodeHead[n] <= tank->Hmin && q > 0.0)
|
|
441
|
+
hyd->LinkStatus[k] = TEMPCLOSED;
|
|
442
|
+
}
|