epanet-plus 0.0.1__cp313-cp313-win32.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.cp313-win32.pyd +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 +5 -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/validate.c
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
/*
|
|
2
|
+
******************************************************************************
|
|
3
|
+
Project: OWA EPANET
|
|
4
|
+
Version: 2.3
|
|
5
|
+
Module: validate.c
|
|
6
|
+
Description: validates project data
|
|
7
|
+
Authors: see AUTHORS
|
|
8
|
+
Copyright: see AUTHORS
|
|
9
|
+
License: see LICENSE
|
|
10
|
+
Last Updated: 03/18/2024
|
|
11
|
+
******************************************************************************
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
#include <stdlib.h>
|
|
15
|
+
#include <stdio.h>
|
|
16
|
+
#include <string.h>
|
|
17
|
+
#include <math.h>
|
|
18
|
+
|
|
19
|
+
#include "types.h"
|
|
20
|
+
#include "funcs.h"
|
|
21
|
+
#include "text.h"
|
|
22
|
+
|
|
23
|
+
// Exported functions
|
|
24
|
+
int validateproject(Project *);
|
|
25
|
+
void reindextanks(Project *);
|
|
26
|
+
|
|
27
|
+
int validatetanks(Project *pr)
|
|
28
|
+
/*
|
|
29
|
+
**-------------------------------------------------------------------
|
|
30
|
+
** Input: none
|
|
31
|
+
** Output: returns 1 if successful, 0 if not
|
|
32
|
+
** Purpose: checks for valid tank levels.
|
|
33
|
+
**-------------------------------------------------------------------
|
|
34
|
+
*/
|
|
35
|
+
{
|
|
36
|
+
Network *net = &pr->network;
|
|
37
|
+
int i, j, n, result = 1, levelerr;
|
|
38
|
+
char errmsg[MAXMSG+1] = "";
|
|
39
|
+
Stank *tank;
|
|
40
|
+
Scurve *curve;
|
|
41
|
+
double elev;
|
|
42
|
+
|
|
43
|
+
for (j = 1; j <= net->Ntanks; j++)
|
|
44
|
+
{
|
|
45
|
+
tank = &net->Tank[j];
|
|
46
|
+
if (tank->A == 0.0) continue; // Skip reservoirs
|
|
47
|
+
|
|
48
|
+
// Check for valid lower/upper tank levels
|
|
49
|
+
levelerr = 0;
|
|
50
|
+
if (tank->H0 > tank->Hmax ||
|
|
51
|
+
tank->Hmin > tank->Hmax ||
|
|
52
|
+
tank->H0 < tank->Hmin
|
|
53
|
+
) levelerr = 1;
|
|
54
|
+
|
|
55
|
+
// Check that tank heights are within volume curve
|
|
56
|
+
elev = net->Node[tank->Node].El;
|
|
57
|
+
i = tank->Vcurve;
|
|
58
|
+
if (i > 0)
|
|
59
|
+
{
|
|
60
|
+
curve = &net->Curve[i];
|
|
61
|
+
n = curve->Npts - 1;
|
|
62
|
+
if ((tank->Hmin - elev) * pr->Ucf[ELEV] < curve->X[0] - TINY ||
|
|
63
|
+
(tank->Hmax - elev) * pr->Ucf[ELEV] > curve->X[n] + TINY)
|
|
64
|
+
{
|
|
65
|
+
levelerr = 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Report error in levels if found
|
|
70
|
+
if (levelerr)
|
|
71
|
+
{
|
|
72
|
+
sprintf(pr->Msg, "Error 225: %s node %s", geterrmsg(225, errmsg),
|
|
73
|
+
net->Node[tank->Node].ID);
|
|
74
|
+
writeline(pr, pr->Msg);
|
|
75
|
+
result = 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
int validatepatterns(Project *pr)
|
|
82
|
+
/*
|
|
83
|
+
**-------------------------------------------------------------------
|
|
84
|
+
** Input: none
|
|
85
|
+
** Output: returns 1 if successful, 0 if not
|
|
86
|
+
** Purpose: checks if time patterns have data.
|
|
87
|
+
**-------------------------------------------------------------------
|
|
88
|
+
*/
|
|
89
|
+
{
|
|
90
|
+
Network *net = &pr->network;
|
|
91
|
+
int j, result = 1;
|
|
92
|
+
char errmsg[MAXMSG+1] = "";
|
|
93
|
+
|
|
94
|
+
if (pr->network.Pattern != NULL)
|
|
95
|
+
{
|
|
96
|
+
for (j = 0; j <= pr->network.Npats; j++)
|
|
97
|
+
{
|
|
98
|
+
if (pr->network.Pattern[j].Length == 0)
|
|
99
|
+
{
|
|
100
|
+
sprintf(pr->Msg, "Error 232: %s %s", geterrmsg(232, errmsg),
|
|
101
|
+
pr->network.Pattern[j].ID);
|
|
102
|
+
writeline(pr, pr->Msg);
|
|
103
|
+
result = 0;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
int validatecurves(Project *pr)
|
|
111
|
+
/*
|
|
112
|
+
**-------------------------------------------------------------------
|
|
113
|
+
** Input: none
|
|
114
|
+
** Output: returns 1 if successful, 0 if not
|
|
115
|
+
** Purpose: checks if data curves have data.
|
|
116
|
+
**-------------------------------------------------------------------
|
|
117
|
+
*/
|
|
118
|
+
{
|
|
119
|
+
int i, j, npts, result = 1;
|
|
120
|
+
char errmsg[MAXMSG+1] = "";
|
|
121
|
+
Scurve *curve;
|
|
122
|
+
|
|
123
|
+
if (pr->network.Curve != NULL)
|
|
124
|
+
{
|
|
125
|
+
for (j = 1; j <= pr->network.Ncurves; j++)
|
|
126
|
+
{
|
|
127
|
+
// Check that curve has data
|
|
128
|
+
curve = &pr->network.Curve[j];
|
|
129
|
+
npts = curve->Npts;
|
|
130
|
+
if (npts == 0)
|
|
131
|
+
{
|
|
132
|
+
sprintf(pr->Msg, "Error 231: %s %s", geterrmsg(231, errmsg),
|
|
133
|
+
curve->ID);
|
|
134
|
+
writeline(pr, pr->Msg);
|
|
135
|
+
result = 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check that x values are increasing
|
|
139
|
+
for (i = 1; i < npts; i++)
|
|
140
|
+
{
|
|
141
|
+
if (curve->X[i-1] >= curve->X[i])
|
|
142
|
+
{
|
|
143
|
+
sprintf(pr->Msg, "Error 230: %s %s", geterrmsg(230, errmsg),
|
|
144
|
+
curve->ID);
|
|
145
|
+
writeline(pr, pr->Msg);
|
|
146
|
+
result = 0;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
int powerfuncpump(double h0, double h1, double h2, double q1, double q2,
|
|
156
|
+
double *a, double *b, double *c)
|
|
157
|
+
/*
|
|
158
|
+
**---------------------------------------------------------
|
|
159
|
+
** Input: h0 = shutoff head
|
|
160
|
+
** h1 = design head
|
|
161
|
+
** h2 = head at max. flow
|
|
162
|
+
** q1 = design flow
|
|
163
|
+
** q2 = max. flow
|
|
164
|
+
** Output: *a, *b, *c = pump curve coeffs. (H = a-bQ^c),
|
|
165
|
+
** Returns 1 if successful, 0 otherwise.
|
|
166
|
+
** Purpose: computes coeffs. for a power function pump curve
|
|
167
|
+
**----------------------------------------------------------
|
|
168
|
+
*/
|
|
169
|
+
{
|
|
170
|
+
double h4, h5;
|
|
171
|
+
|
|
172
|
+
if (h0 < TINY || h0 - h1 < TINY || h1 - h2 < TINY ||
|
|
173
|
+
q1 < TINY || q2 - q1 < TINY
|
|
174
|
+
) return 0;
|
|
175
|
+
*a = h0;
|
|
176
|
+
h4 = h0 - h1;
|
|
177
|
+
h5 = h0 - h2;
|
|
178
|
+
*c = log(h5 / h4) / log(q2 / q1);
|
|
179
|
+
if (*c <= 0.0 || *c > 20.0) return 0;
|
|
180
|
+
*b = -h4 / pow(q1, *c);
|
|
181
|
+
if (*b >= 0.0) return 0;
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
int customcurvepump(Project *pr, Spump *pump, Scurve *curve)
|
|
186
|
+
/*
|
|
187
|
+
**-------------------------------------------------------------------
|
|
188
|
+
** Input: pump = a pump object
|
|
189
|
+
** curve = a data curve object
|
|
190
|
+
** Output: returns an error code
|
|
191
|
+
** Purpose: computes properties for a pump with a custom pump curve.
|
|
192
|
+
**-------------------------------------------------------------------
|
|
193
|
+
*/
|
|
194
|
+
{
|
|
195
|
+
int m, npts = curve->Npts;
|
|
196
|
+
pump->Ptype = CUSTOM;
|
|
197
|
+
for (m = 1; m < npts; m++)
|
|
198
|
+
{
|
|
199
|
+
// Curve must have continuously decreasing head (the Y value)
|
|
200
|
+
if (curve->Y[m] >= curve->Y[m - 1])
|
|
201
|
+
{
|
|
202
|
+
pump->Ptype = NOCURVE;
|
|
203
|
+
return 227;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
pump->Qmax = curve->X[npts - 1];
|
|
207
|
+
pump->Q0 = (curve->X[0] + pump->Qmax) / 2.0 / pr->Ucf[FLOW];
|
|
208
|
+
pump->Qmax /= pr->Ucf[FLOW];
|
|
209
|
+
pump->Hmax = curve->Y[0] / pr->Ucf[HEAD];
|
|
210
|
+
return 0;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
int pumpcurvepump(Project *pr, Spump *pump, Scurve *curve)
|
|
214
|
+
/*
|
|
215
|
+
**-------------------------------------------------------------------
|
|
216
|
+
** Input: pump = a pump object
|
|
217
|
+
** curve = a data curve object
|
|
218
|
+
** Output: returns an error code
|
|
219
|
+
** Purpose: computes properties for a pump assigned a pump curve.
|
|
220
|
+
**-------------------------------------------------------------------
|
|
221
|
+
*/
|
|
222
|
+
{
|
|
223
|
+
double a, b, c, h0 = 0.0, h1 = 0.0, h2 = 0.0, q1 = 0.0, q2 = 0.0;
|
|
224
|
+
int npts = curve->Npts;
|
|
225
|
+
|
|
226
|
+
curve->Type = PUMP_CURVE;
|
|
227
|
+
|
|
228
|
+
// Generic power function curve
|
|
229
|
+
if (npts == 1)
|
|
230
|
+
{
|
|
231
|
+
pump->Ptype = POWER_FUNC;
|
|
232
|
+
q1 = curve->X[0];
|
|
233
|
+
h1 = curve->Y[0];
|
|
234
|
+
h0 = 1.33334 * h1;
|
|
235
|
+
q2 = 2.0 * q1;
|
|
236
|
+
h2 = 0.0;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// 3 point curve with shutoff head
|
|
240
|
+
else if (npts == 3 && curve->X[0] == 0.0)
|
|
241
|
+
{
|
|
242
|
+
pump->Ptype = POWER_FUNC;
|
|
243
|
+
h0 = curve->Y[0];
|
|
244
|
+
q1 = curve->X[1];
|
|
245
|
+
h1 = curve->Y[1];
|
|
246
|
+
q2 = curve->X[2];
|
|
247
|
+
h2 = curve->Y[2];
|
|
248
|
+
}
|
|
249
|
+
else return customcurvepump(pr, pump, curve);
|
|
250
|
+
|
|
251
|
+
// Compute shape factors & limits of power function curves
|
|
252
|
+
if (!powerfuncpump(h0, h1, h2, q1, q2, &a, &b, &c))
|
|
253
|
+
{
|
|
254
|
+
pump->Ptype = NOCURVE;
|
|
255
|
+
return 227;
|
|
256
|
+
}
|
|
257
|
+
else
|
|
258
|
+
{
|
|
259
|
+
pump->H0 = -a / pr->Ucf[HEAD];
|
|
260
|
+
pump->R = -b * (pow(pr->Ucf[FLOW], c) / pr->Ucf[HEAD]);
|
|
261
|
+
pump->N = c;
|
|
262
|
+
pump->Q0 = q1 / pr->Ucf[FLOW];
|
|
263
|
+
pump->Qmax = pow((-a / b), (1.0 / c)) / pr->Ucf[FLOW];
|
|
264
|
+
pump->Hmax = h0 / pr->Ucf[HEAD];
|
|
265
|
+
}
|
|
266
|
+
return 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
int constpowerpump(Project *pr, Spump *pump)
|
|
270
|
+
/*
|
|
271
|
+
**-------------------------------------------------------------------
|
|
272
|
+
** Input: pump = a pump object
|
|
273
|
+
** Output: returns an error code
|
|
274
|
+
** Purpose: computes properties for a constant power pump.
|
|
275
|
+
**-------------------------------------------------------------------
|
|
276
|
+
*/
|
|
277
|
+
{
|
|
278
|
+
pump->Ptype = CONST_HP;
|
|
279
|
+
pump->H0 = 0.0;
|
|
280
|
+
pump->R = -8.814 * pr->network.Link[pump->Link].Km / pr->Ucf[POWER];
|
|
281
|
+
pump->N = -1.0;
|
|
282
|
+
pump->Hmax = BIG; // No head limit
|
|
283
|
+
pump->Qmax = BIG; // No flow limit
|
|
284
|
+
pump->Q0 = 1.0; // Init. flow = 1 cfs
|
|
285
|
+
return 0;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
int validatepumps(Project *pr)
|
|
289
|
+
/*
|
|
290
|
+
**-------------------------------------------------------------------
|
|
291
|
+
** Input: none
|
|
292
|
+
** Output: returns 1 if successful, 0 if not
|
|
293
|
+
** Purpose: checks if pumps are assigned valid pump curve data.
|
|
294
|
+
**-------------------------------------------------------------------
|
|
295
|
+
*/
|
|
296
|
+
{
|
|
297
|
+
Network *net = &pr->network;
|
|
298
|
+
int i, errcode, result = 1;
|
|
299
|
+
char errmsg[MAXMSG+1] = "";
|
|
300
|
+
Spump *pump;
|
|
301
|
+
|
|
302
|
+
for (i = 1; i <= net->Npumps; i++)
|
|
303
|
+
{
|
|
304
|
+
// Pump has a designated pump curve
|
|
305
|
+
pump = &net->Pump[i];
|
|
306
|
+
if (pump->Hcurve > 0)
|
|
307
|
+
errcode = pumpcurvepump(pr, pump, &net->Curve[pump->Hcurve]);
|
|
308
|
+
|
|
309
|
+
// Pump has a constant power setting
|
|
310
|
+
else if (net->Link[pump->Link].Km > 0.0)
|
|
311
|
+
errcode = constpowerpump(pr, pump);
|
|
312
|
+
|
|
313
|
+
// Pump has no pump curve info assigned
|
|
314
|
+
else
|
|
315
|
+
{
|
|
316
|
+
pump->Ptype = NOCURVE;
|
|
317
|
+
errcode = 226;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (errcode)
|
|
321
|
+
{
|
|
322
|
+
sprintf(pr->Msg, "Error %d: %s %s",
|
|
323
|
+
errcode, geterrmsg(errcode, errmsg), net->Link[pump->Link].ID);
|
|
324
|
+
writeline(pr, pr->Msg);
|
|
325
|
+
result = 0;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return result;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
int validateproject(Project *pr)
|
|
332
|
+
/*
|
|
333
|
+
*--------------------------------------------------------------
|
|
334
|
+
* Input: none
|
|
335
|
+
* Output: returns error code
|
|
336
|
+
* Purpose: checks for valid network data.
|
|
337
|
+
*--------------------------------------------------------------
|
|
338
|
+
*/
|
|
339
|
+
{
|
|
340
|
+
int errcode = 0;
|
|
341
|
+
if (pr->network.Nnodes < 2) return 223;
|
|
342
|
+
if (pr->network.Ntanks == 0) return 224;
|
|
343
|
+
if (!validatetanks(pr)) errcode = 110;
|
|
344
|
+
if (!validatepumps(pr)) errcode = 110;
|
|
345
|
+
if (!validatepatterns(pr)) errcode = 110;
|
|
346
|
+
if (!validatecurves(pr)) errcode = 110;
|
|
347
|
+
return errcode;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
void reindextanks(Project *pr)
|
|
351
|
+
/*
|
|
352
|
+
*--------------------------------------------------------------
|
|
353
|
+
* Input: none
|
|
354
|
+
* Output: none
|
|
355
|
+
* Purpose: adjusts tank node indexes when the number of
|
|
356
|
+
* junctions created from an input file is less than
|
|
357
|
+
* the total number of junction lines in the file.
|
|
358
|
+
*--------------------------------------------------------------
|
|
359
|
+
*/
|
|
360
|
+
{
|
|
361
|
+
Network *net = &pr->network;
|
|
362
|
+
Parser *parser = &pr->parser;
|
|
363
|
+
Quality *qual = &pr->quality;
|
|
364
|
+
Scontrol *control;
|
|
365
|
+
int i, j, ndiff, n1, n2, size;
|
|
366
|
+
|
|
367
|
+
// ndiff = # unused entries in Node array before first tank node
|
|
368
|
+
ndiff = parser->MaxJuncs - net->Njuncs;
|
|
369
|
+
if (ndiff > 0)
|
|
370
|
+
{
|
|
371
|
+
for (i = 1; i <= net->Ntanks; ++i)
|
|
372
|
+
{
|
|
373
|
+
// n1 is current tank index in Node array, n2 is adjusted index
|
|
374
|
+
n1 = net->Tank[i].Node;
|
|
375
|
+
n2 = n1 - ndiff;
|
|
376
|
+
|
|
377
|
+
// Update the tank node's hash table entry
|
|
378
|
+
hashtable_update(net->NodeHashTable, net->Node[n1].ID, n2);
|
|
379
|
+
|
|
380
|
+
// Update the tank's node index
|
|
381
|
+
net->Tank[i].Node = n2;
|
|
382
|
+
|
|
383
|
+
// Re-position tank node in Node array
|
|
384
|
+
net->Node[n2] = net->Node[n1];
|
|
385
|
+
|
|
386
|
+
// Replace all references to old tank node index with new one
|
|
387
|
+
for (j = 1; j <= net->Nlinks; ++j)
|
|
388
|
+
{
|
|
389
|
+
if (net->Link[j].N1 == n1) net->Link[j].N1 = n2;
|
|
390
|
+
if (net->Link[j].N2 == n1) net->Link[j].N2 = n2;
|
|
391
|
+
}
|
|
392
|
+
for (j = 1; j <= net->Ncontrols; ++j)
|
|
393
|
+
{
|
|
394
|
+
control = &net->Control[j];
|
|
395
|
+
if (control->Node == n1) control->Node = n2;
|
|
396
|
+
}
|
|
397
|
+
adjusttankrules(pr, -ndiff);
|
|
398
|
+
if (qual->TraceNode == n1) qual->TraceNode = n2;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Reallocate the Node array (shouldn't fail as new size < old size)
|
|
402
|
+
parser->MaxJuncs = net->Njuncs;
|
|
403
|
+
parser->MaxNodes = net->Njuncs + net->Ntanks;
|
|
404
|
+
size = (net->Nnodes + 2) * sizeof(Snode);
|
|
405
|
+
net->Node = (Snode *)realloc(net->Node, size);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
epanet.cp313-win32.pyd
ADDED
|
Binary file
|
epanet_plus/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.1
|
epanet_plus/__init__.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#include <stdlib.h>
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <string.h>
|
|
4
|
+
#include <float.h>
|
|
5
|
+
#include <math.h>
|
|
6
|
+
|
|
7
|
+
#include "epanet2.h"
|
|
8
|
+
#include "epanet2_2.h"
|
|
9
|
+
#include "types.h"
|
|
10
|
+
#include "text.h"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
extern Project *_defaultProject;
|
|
14
|
+
extern int read_data_from_buffer(Project *pr, const char *inpBuffer);
|
|
15
|
+
extern int netsize_from_buffer(Project *pr, const char *inpBuffer);
|
|
16
|
+
extern int allocdata(Project *pr);
|
|
17
|
+
extern int openhydfile(Project *pr);
|
|
18
|
+
extern int openfiles(Project *pr, const char *f1, const char *f2, const char *f3);
|
|
19
|
+
extern void writetime(Project *pr, char *fmt);
|
|
20
|
+
extern void writesummary(Project *pr);
|
|
21
|
+
extern void writewin(void(*vp)(char *), char *s);
|
|
22
|
+
extern void initpointers(Project *pr);
|
|
23
|
+
extern void errmsg(Project *pr, int errcode);
|
|
24
|
+
extern void convertunits(Project *pr);
|
|
25
|
+
extern void initunits(Project *pr);
|
|
26
|
+
extern void adjustdata(Project *pr);
|
|
27
|
+
extern void initreport(Report *rpt);
|
|
28
|
+
extern void inittanks(Project *pr);
|
|
29
|
+
extern void setdefaults(Project *pr);
|
|
30
|
+
extern void createtmpfiles();
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
int getdata_from_buffer(Project *pr, const char *inpBuffer)
|
|
34
|
+
{
|
|
35
|
+
int errcode = 0;
|
|
36
|
+
|
|
37
|
+
// Assign default data values & reporting options
|
|
38
|
+
setdefaults(pr);
|
|
39
|
+
initreport(&pr->report);
|
|
40
|
+
|
|
41
|
+
// Read in network data
|
|
42
|
+
//rewind(pr->parser.InFile);
|
|
43
|
+
ERRCODE(read_data_from_buffer(pr, inpBuffer));
|
|
44
|
+
|
|
45
|
+
// Adjust data and convert it to internal units
|
|
46
|
+
if (!errcode)
|
|
47
|
+
adjustdata(pr);
|
|
48
|
+
if (!errcode)
|
|
49
|
+
initunits(pr);
|
|
50
|
+
if (!errcode)
|
|
51
|
+
inittanks(pr);
|
|
52
|
+
if (!errcode)
|
|
53
|
+
convertunits(pr);
|
|
54
|
+
return errcode;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
int DLLEXPORT EN_openfrombuffer(EN_Project p, const char *inpBuffer, const char *inpFile, const char *rptFile, const char *outFile)
|
|
59
|
+
{
|
|
60
|
+
int errcode = 0;
|
|
61
|
+
|
|
62
|
+
// Set system flags
|
|
63
|
+
p->Openflag = FALSE;
|
|
64
|
+
p->hydraul.OpenHflag = FALSE;
|
|
65
|
+
p->quality.OpenQflag = FALSE;
|
|
66
|
+
p->outfile.SaveHflag = FALSE;
|
|
67
|
+
p->outfile.SaveQflag = FALSE;
|
|
68
|
+
p->Warnflag = FALSE;
|
|
69
|
+
p->report.Messageflag = TRUE;
|
|
70
|
+
p->report.Rptflag = 1;
|
|
71
|
+
|
|
72
|
+
// Initialize data arrays to NULL
|
|
73
|
+
initpointers(p);
|
|
74
|
+
|
|
75
|
+
// Open input & report files
|
|
76
|
+
ERRCODE(openfiles(p, "", rptFile, outFile));
|
|
77
|
+
if (errcode > 0)
|
|
78
|
+
{
|
|
79
|
+
errmsg(p, errcode);
|
|
80
|
+
return errcode;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Allocate memory for project's data arrays
|
|
84
|
+
writewin(p->viewprog, FMT100);
|
|
85
|
+
ERRCODE(netsize_from_buffer(p, inpBuffer));
|
|
86
|
+
ERRCODE(allocdata(p));
|
|
87
|
+
|
|
88
|
+
// Read input data
|
|
89
|
+
ERRCODE(getdata_from_buffer(p, inpBuffer));
|
|
90
|
+
|
|
91
|
+
// Close input file
|
|
92
|
+
if (p->parser.InFile != NULL)
|
|
93
|
+
{
|
|
94
|
+
fclose(p->parser.InFile);
|
|
95
|
+
p->parser.InFile = NULL;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// If using previously saved hydraulics file then open it
|
|
99
|
+
if (p->outfile.Hydflag == USE) ERRCODE(openhydfile(p));
|
|
100
|
+
|
|
101
|
+
// Write input summary to report file
|
|
102
|
+
if (!errcode)
|
|
103
|
+
{
|
|
104
|
+
if (p->report.Summaryflag) writesummary(p);
|
|
105
|
+
writetime(p, FMT104);
|
|
106
|
+
p->Openflag = TRUE;
|
|
107
|
+
}
|
|
108
|
+
else errmsg(p, errcode);
|
|
109
|
+
return errcode;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
int DLLEXPORT ENopenfrombuffer(const char *inpBuffer, const char *inpFile, const char *rptFile, const char *outFile)
|
|
113
|
+
{
|
|
114
|
+
int errcode = 0;
|
|
115
|
+
createtmpfiles();
|
|
116
|
+
errcode = EN_openfrombuffer(_defaultProject, inpBuffer, inpFile, rptFile, outFile);
|
|
117
|
+
return errcode;
|
|
118
|
+
}
|