epyt-flow 0.14.2__py3-none-any.whl → 0.15.0b1__py3-none-any.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.
Files changed (102) hide show
  1. epyt_flow/VERSION +1 -1
  2. epyt_flow/__init__.py +0 -37
  3. epyt_flow/data/benchmarks/battledim.py +2 -2
  4. epyt_flow/data/benchmarks/leakdb.py +12 -9
  5. epyt_flow/gym/scenario_control_env.py +32 -33
  6. epyt_flow/simulation/events/actuator_events.py +24 -18
  7. epyt_flow/simulation/events/leakages.py +59 -57
  8. epyt_flow/simulation/events/quality_events.py +21 -30
  9. epyt_flow/simulation/events/system_event.py +3 -3
  10. epyt_flow/simulation/scada/complex_control.py +14 -12
  11. epyt_flow/simulation/scada/custom_control.py +22 -21
  12. epyt_flow/simulation/scada/scada_data.py +107 -104
  13. epyt_flow/simulation/scada/simple_control.py +38 -31
  14. epyt_flow/simulation/scenario_simulator.py +367 -395
  15. epyt_flow/simulation/sensor_config.py +31 -32
  16. epyt_flow/topology.py +11 -10
  17. epyt_flow/uncertainty/model_uncertainty.py +146 -122
  18. epyt_flow/utils.py +0 -66
  19. epyt_flow/visualization/visualization_utils.py +2 -4
  20. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/METADATA +12 -18
  21. epyt_flow-0.15.0b1.dist-info/RECORD +65 -0
  22. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +0 -28
  23. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +0 -21
  24. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +0 -18
  25. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +0 -134
  26. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +0 -5578
  27. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +0 -865
  28. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +0 -131
  29. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +0 -73
  30. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +0 -193
  31. epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +0 -1000
  32. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +0 -177
  33. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +0 -28
  34. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +0 -1151
  35. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +0 -1117
  36. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +0 -720
  37. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +0 -476
  38. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +0 -431
  39. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +0 -1786
  40. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +0 -468
  41. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +0 -810
  42. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +0 -707
  43. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +0 -864
  44. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +0 -2170
  45. epyt_flow/EPANET/EPANET/SRC_engines/main.c +0 -93
  46. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +0 -142
  47. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +0 -24
  48. epyt_flow/EPANET/EPANET/SRC_engines/output.c +0 -852
  49. epyt_flow/EPANET/EPANET/SRC_engines/project.c +0 -1359
  50. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +0 -685
  51. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +0 -743
  52. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +0 -694
  53. epyt_flow/EPANET/EPANET/SRC_engines/report.c +0 -1489
  54. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +0 -1362
  55. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +0 -871
  56. epyt_flow/EPANET/EPANET/SRC_engines/text.h +0 -497
  57. epyt_flow/EPANET/EPANET/SRC_engines/types.h +0 -874
  58. epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +0 -53
  59. epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +0 -27
  60. epyt_flow/EPANET/EPANET-MSX/Src/hash.c +0 -107
  61. epyt_flow/EPANET/EPANET-MSX/Src/hash.h +0 -28
  62. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +0 -102
  63. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +0 -42
  64. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +0 -937
  65. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +0 -39
  66. epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +0 -204
  67. epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +0 -24
  68. epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +0 -1285
  69. epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +0 -368
  70. epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +0 -42
  71. epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +0 -586
  72. epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +0 -116
  73. epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +0 -260
  74. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +0 -175
  75. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +0 -35
  76. epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +0 -1504
  77. epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +0 -401
  78. epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +0 -791
  79. epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +0 -2010
  80. epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +0 -400
  81. epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +0 -422
  82. epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +0 -1164
  83. epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +0 -551
  84. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +0 -524
  85. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +0 -56
  86. epyt_flow/EPANET/EPANET-MSX/Src/newton.c +0 -158
  87. epyt_flow/EPANET/EPANET-MSX/Src/newton.h +0 -34
  88. epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +0 -287
  89. epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +0 -39
  90. epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +0 -293
  91. epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +0 -35
  92. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +0 -816
  93. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +0 -29
  94. epyt_flow/EPANET/EPANET-MSX/readme.txt +0 -14
  95. epyt_flow/EPANET/compile_linux.sh +0 -4
  96. epyt_flow/EPANET/compile_macos.sh +0 -4
  97. epyt_flow/simulation/backend/__init__.py +0 -1
  98. epyt_flow/simulation/backend/my_epyt.py +0 -1101
  99. epyt_flow-0.14.2.dist-info/RECORD +0 -142
  100. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/WHEEL +0 -0
  101. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/licenses/LICENSE +0 -0
  102. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/top_level.txt +0 -0
@@ -1,476 +0,0 @@
1
- /*
2
- ******************************************************************************
3
- Project: OWA EPANET
4
- Version: 2.2
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: 05/15/2019
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, int);
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 || n2 > net->Njuncs)
159
- {
160
- tankstatus(pr, k, n1, n2);
161
- }
162
-
163
- // Note any change in link status; do not revise link flow
164
- if (status != hyd->LinkStatus[k])
165
- {
166
- change = TRUE;
167
- if (rpt->Statflag == FULL)
168
- {
169
- writestatchange(pr, k, status, hyd->LinkStatus[k]);
170
- }
171
- }
172
- }
173
- return change;
174
- }
175
-
176
-
177
- StatusType cvstatus(Project *pr, StatusType s, double dh, double q)
178
- /*
179
- **--------------------------------------------------
180
- ** Input: s = current link status
181
- ** dh = head loss across link
182
- ** q = link flow
183
- ** Output: returns new link status
184
- ** Purpose: updates status of a check valve link.
185
- **--------------------------------------------------
186
- */
187
- {
188
- Hydraul *hyd = &pr->hydraul;
189
-
190
- // Prevent reverse flow through CVs
191
- if (ABS(dh) > hyd->Htol)
192
- {
193
- if (dh < -hyd->Htol) return CLOSED;
194
- else if (q < -hyd->Qtol) return CLOSED;
195
- else return OPEN;
196
- }
197
- else
198
- {
199
- if (q < -hyd->Qtol) return CLOSED;
200
- else return s;
201
- }
202
- }
203
-
204
-
205
- StatusType pumpstatus(Project *pr, int k, double dh)
206
- /*
207
- **--------------------------------------------------
208
- ** Input: k = link index
209
- ** dh = head gain across link
210
- ** Output: returns new pump status
211
- ** Purpose: updates status of an open pump.
212
- **--------------------------------------------------
213
- */
214
- {
215
- Hydraul *hyd = &pr->hydraul;
216
- Network *net = &pr->network;
217
-
218
- int p;
219
- double hmax;
220
-
221
- // Find maximum head (hmax) pump can deliver
222
- p = findpump(net, k);
223
- if (net->Pump[p].Ptype == CONST_HP)
224
- {
225
- // Use huge value for constant HP pump
226
- hmax = BIG;
227
- }
228
- else
229
- {
230
- // Use speed-adjusted shut-off head for other pumps
231
- hmax = SQR(hyd->LinkSetting[k]) * net->Pump[p].Hmax;
232
- }
233
-
234
- // Check if currrent head gain exceeds pump's max. head
235
- if (dh > hmax + hyd->Htol) return XHEAD;
236
-
237
- // No check is made to see if flow exceeds pump's max. flow
238
- return OPEN;
239
- }
240
-
241
-
242
- StatusType prvstatus(Project *pr, int k, StatusType s, double hset,
243
- double h1, double h2)
244
- /*
245
- **-----------------------------------------------------------
246
- ** Input: k = link index
247
- ** s = current status
248
- ** hset = valve head setting
249
- ** h1 = head at upstream node
250
- ** h2 = head at downstream node
251
- ** Output: returns new valve status
252
- ** Purpose: updates status of a pressure reducing valve.
253
- **-----------------------------------------------------------
254
- */
255
- {
256
- Hydraul *hyd = &pr->hydraul;
257
-
258
- StatusType status; // Valve's new status
259
- double hml; // Head loss when fully opened
260
- double htol;
261
- Slink *link;
262
-
263
- htol = hyd->Htol;
264
- link = &pr->network.Link[k];
265
-
266
- // Head loss when fully open
267
- hml = link->Km * SQR(hyd->LinkFlow[k]);
268
-
269
- // Rules for updating valve's status from current value s
270
- status = s;
271
- switch (s)
272
- {
273
- case ACTIVE:
274
- if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
275
- else if (h1 - hml < hset - htol) status = OPEN;
276
- else status = ACTIVE;
277
- break;
278
-
279
- case OPEN:
280
- if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
281
- else if (h2 >= hset + htol) status = ACTIVE;
282
- else status = OPEN;
283
- break;
284
-
285
- case CLOSED:
286
- if (h1 >= hset + htol && h2 < hset - htol) status = ACTIVE;
287
- else if (h1 < hset - htol && h1 > h2 + htol) status = OPEN;
288
- else status = CLOSED;
289
- break;
290
-
291
- case XPRESSURE:
292
- if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
293
- break;
294
-
295
- default:
296
- break;
297
- }
298
- return status;
299
- }
300
-
301
-
302
- StatusType psvstatus(Project *pr, int k, StatusType s, double hset,
303
- double h1, double h2)
304
- /*
305
- **-----------------------------------------------------------
306
- ** Input: k = link index
307
- ** s = current status
308
- ** hset = valve head setting
309
- ** h1 = head at upstream node
310
- ** h2 = head at downstream node
311
- ** Output: returns new valve status
312
- ** Purpose: updates status of a pressure sustaining valve.
313
- **-----------------------------------------------------------
314
- */
315
- {
316
- Hydraul *hyd = &pr->hydraul;
317
-
318
- StatusType status; // Valve's new status
319
- double hml; // Head loss when fully opened
320
- double htol;
321
- Slink *link;
322
-
323
- htol = hyd->Htol;
324
- link = &pr->network.Link[k];
325
-
326
- // Head loss when fully open
327
- hml = link->Km * SQR(hyd->LinkFlow[k]);
328
-
329
- // Rules for updating valve's status from current value s
330
- status = s;
331
- switch (s)
332
- {
333
- case ACTIVE:
334
- if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
335
- else if (h2 + hml > hset + htol) status = OPEN;
336
- else status = ACTIVE;
337
- break;
338
-
339
- case OPEN:
340
- if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
341
- else if (h1 < hset - htol) status = ACTIVE;
342
- else status = OPEN;
343
- break;
344
-
345
- case CLOSED:
346
- if (h2 > hset + htol && h1 > h2 + htol) status = OPEN;
347
- else if (h1 >= hset + htol && h1 > h2 + htol) status = ACTIVE;
348
- else status = CLOSED;
349
- break;
350
-
351
- case XPRESSURE:
352
- if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
353
- break;
354
-
355
- default:
356
- break;
357
- }
358
- return status;
359
- }
360
-
361
-
362
- StatusType fcvstatus(Project *pr, int k, StatusType s, double h1, double h2)
363
- /*
364
- **-----------------------------------------------------------
365
- ** Input: k = link index
366
- ** s = current status
367
- ** h1 = head at upstream node
368
- ** h2 = head at downstream node
369
- ** Output: returns new valve status
370
- ** Purpose: updates status of a flow control valve.
371
- **
372
- ** Valve status changes to XFCV if flow reversal.
373
- ** If current status is XFCV and current flow is
374
- ** above setting, then valve becomes active.
375
- ** If current status is XFCV, and current flow
376
- ** positive but still below valve setting, then
377
- ** status remains same.
378
- **-----------------------------------------------------------
379
- */
380
- {
381
- Hydraul *hyd = &pr->hydraul;
382
- StatusType status; // New valve status
383
-
384
- status = s;
385
- if (h1 - h2 < -hyd->Htol)
386
- {
387
- status = XFCV;
388
- }
389
- else if (hyd->LinkFlow[k] < -hyd->Qtol)
390
- {
391
- status = XFCV;
392
- }
393
- else if (s == XFCV && hyd->LinkFlow[k] >= hyd->LinkSetting[k])
394
- {
395
- status = ACTIVE;
396
- }
397
- return status;
398
- }
399
-
400
-
401
- void tankstatus(Project *pr, int k, int n1, int n2)
402
- /*
403
- **----------------------------------------------------------------
404
- ** Input: k = link index
405
- ** n1 = start node of link
406
- ** n2 = end node of link
407
- ** Output: none
408
- ** Purpose: closes link flowing into full or out of empty tank
409
- **----------------------------------------------------------------
410
- */
411
- {
412
- Network *net = &pr->network;
413
- Hydraul *hyd = &pr->hydraul;
414
-
415
- int i, n;
416
- double h, q;
417
- Stank *tank;
418
- Slink *link = &net->Link[k];
419
-
420
- // Return if link is closed
421
- if (hyd->LinkStatus[k] <= CLOSED) return;
422
-
423
- // Make node n1 be the tank, reversing flow (q) if need be
424
- q = hyd->LinkFlow[k];
425
- i = n1 - net->Njuncs;
426
- if (i <= 0)
427
- {
428
- i = n2 - net->Njuncs;
429
- if (i <= 0) return;
430
- n = n1;
431
- n1 = n2;
432
- n2 = n;
433
- q = -q;
434
- }
435
-
436
- // Ignore reservoirs
437
- tank = &net->Tank[i];
438
- if (tank->A == 0.0) return;
439
-
440
- // Find head difference across link
441
- h = hyd->NodeHead[n1] - hyd->NodeHead[n2];
442
-
443
- // If tank is full, then prevent flow into it
444
- if (hyd->NodeHead[n1] >= tank->Hmax - hyd->Htol && !tank->CanOverflow)
445
- {
446
- // Case 1: Link is a pump discharging into tank
447
- if (link->Type == PUMP)
448
- {
449
- if (link->N2 == n1) hyd->LinkStatus[k] = TEMPCLOSED;
450
- }
451
-
452
- // Case 2: Downstream head > tank head
453
- // (e.g., an open outflow check valve would close)
454
- else if (cvstatus(pr, OPEN, h, q) == CLOSED)
455
- {
456
- hyd->LinkStatus[k] = TEMPCLOSED;
457
- }
458
- }
459
-
460
- // If tank is empty, then prevent flow out of it
461
- if (hyd->NodeHead[n1] <= tank->Hmin + hyd->Htol)
462
- {
463
- // Case 1: Link is a pump discharging from tank
464
- if (link->Type == PUMP)
465
- {
466
- if (link->N1 == n1) hyd->LinkStatus[k] = TEMPCLOSED;
467
- }
468
-
469
- // Case 2: Tank head > downstream head
470
- // (e.g., a closed outflow check valve would open)
471
- else if (cvstatus(pr, CLOSED, h, q) == OPEN)
472
- {
473
- hyd->LinkStatus[k] = TEMPCLOSED;
474
- }
475
- }
476
- }