epanet-plus 0.0.1__cp312-cp312-win_amd64.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.

Files changed (105) hide show
  1. docs/conf.py +67 -0
  2. epanet-msx-src/dispersion.h +27 -0
  3. epanet-msx-src/hash.c +107 -0
  4. epanet-msx-src/hash.h +28 -0
  5. epanet-msx-src/include/epanetmsx.h +104 -0
  6. epanet-msx-src/include/epanetmsx_export.h +42 -0
  7. epanet-msx-src/mathexpr.c +937 -0
  8. epanet-msx-src/mathexpr.h +39 -0
  9. epanet-msx-src/mempool.c +204 -0
  10. epanet-msx-src/mempool.h +24 -0
  11. epanet-msx-src/msxchem.c +1285 -0
  12. epanet-msx-src/msxcompiler.c +368 -0
  13. epanet-msx-src/msxdict.h +42 -0
  14. epanet-msx-src/msxdispersion.c +586 -0
  15. epanet-msx-src/msxerr.c +116 -0
  16. epanet-msx-src/msxfile.c +260 -0
  17. epanet-msx-src/msxfuncs.c +175 -0
  18. epanet-msx-src/msxfuncs.h +35 -0
  19. epanet-msx-src/msxinp.c +1504 -0
  20. epanet-msx-src/msxout.c +398 -0
  21. epanet-msx-src/msxproj.c +791 -0
  22. epanet-msx-src/msxqual.c +2011 -0
  23. epanet-msx-src/msxrpt.c +400 -0
  24. epanet-msx-src/msxtank.c +422 -0
  25. epanet-msx-src/msxtoolkit.c +1164 -0
  26. epanet-msx-src/msxtypes.h +551 -0
  27. epanet-msx-src/msxutils.c +524 -0
  28. epanet-msx-src/msxutils.h +56 -0
  29. epanet-msx-src/newton.c +158 -0
  30. epanet-msx-src/newton.h +34 -0
  31. epanet-msx-src/rk5.c +287 -0
  32. epanet-msx-src/rk5.h +39 -0
  33. epanet-msx-src/ros2.c +293 -0
  34. epanet-msx-src/ros2.h +35 -0
  35. epanet-msx-src/smatrix.c +816 -0
  36. epanet-msx-src/smatrix.h +29 -0
  37. epanet-src/AUTHORS +60 -0
  38. epanet-src/LICENSE +21 -0
  39. epanet-src/enumstxt.h +151 -0
  40. epanet-src/epanet.c +5937 -0
  41. epanet-src/epanet2.c +961 -0
  42. epanet-src/epanet2.def +131 -0
  43. epanet-src/errors.dat +79 -0
  44. epanet-src/flowbalance.c +186 -0
  45. epanet-src/funcs.h +219 -0
  46. epanet-src/genmmd.c +1000 -0
  47. epanet-src/hash.c +177 -0
  48. epanet-src/hash.h +28 -0
  49. epanet-src/hydcoeffs.c +1303 -0
  50. epanet-src/hydraul.c +1164 -0
  51. epanet-src/hydsolver.c +781 -0
  52. epanet-src/hydstatus.c +442 -0
  53. epanet-src/include/epanet2.h +466 -0
  54. epanet-src/include/epanet2_2.h +1962 -0
  55. epanet-src/include/epanet2_enums.h +518 -0
  56. epanet-src/inpfile.c +884 -0
  57. epanet-src/input1.c +672 -0
  58. epanet-src/input2.c +970 -0
  59. epanet-src/input3.c +2265 -0
  60. epanet-src/leakage.c +527 -0
  61. epanet-src/mempool.c +146 -0
  62. epanet-src/mempool.h +24 -0
  63. epanet-src/output.c +853 -0
  64. epanet-src/project.c +1691 -0
  65. epanet-src/quality.c +695 -0
  66. epanet-src/qualreact.c +800 -0
  67. epanet-src/qualroute.c +696 -0
  68. epanet-src/report.c +1559 -0
  69. epanet-src/rules.c +1500 -0
  70. epanet-src/smatrix.c +871 -0
  71. epanet-src/text.h +508 -0
  72. epanet-src/types.h +928 -0
  73. epanet-src/util/cstr_helper.c +59 -0
  74. epanet-src/util/cstr_helper.h +38 -0
  75. epanet-src/util/errormanager.c +92 -0
  76. epanet-src/util/errormanager.h +39 -0
  77. epanet-src/util/filemanager.c +212 -0
  78. epanet-src/util/filemanager.h +81 -0
  79. epanet-src/validate.c +408 -0
  80. epanet.cp312-win_amd64.pyd +0 -0
  81. epanet_plus/VERSION +1 -0
  82. epanet_plus/__init__.py +8 -0
  83. epanet_plus/epanet_plus.c +118 -0
  84. epanet_plus/epanet_toolkit.py +2730 -0
  85. epanet_plus/epanet_wrapper.py +2414 -0
  86. epanet_plus/include/epanet_plus.h +9 -0
  87. epanet_plus-0.0.1.dist-info/METADATA +152 -0
  88. epanet_plus-0.0.1.dist-info/RECORD +105 -0
  89. epanet_plus-0.0.1.dist-info/WHEEL +5 -0
  90. epanet_plus-0.0.1.dist-info/licenses/LICENSE +21 -0
  91. epanet_plus-0.0.1.dist-info/top_level.txt +11 -0
  92. examples/basic_usage.py +35 -0
  93. python-extension/ext.c +344 -0
  94. python-extension/pyepanet.c +2133 -0
  95. python-extension/pyepanet.h +143 -0
  96. python-extension/pyepanet2.c +1823 -0
  97. python-extension/pyepanet2.h +141 -0
  98. python-extension/pyepanet_plus.c +37 -0
  99. python-extension/pyepanet_plus.h +4 -0
  100. python-extension/pyepanetmsx.c +388 -0
  101. python-extension/pyepanetmsx.h +35 -0
  102. tests/test_epanet.py +16 -0
  103. tests/test_epanetmsx.py +36 -0
  104. tests/test_epyt.py +114 -0
  105. 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
+ }