epyt-flow 0.14.1__py3-none-any.whl → 0.14.2__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.
- epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +8 -40
- epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +3 -3
- epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +18 -0
- epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +7 -24
- epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +374 -726
- epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +32 -128
- epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +131 -0
- epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +1 -7
- epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +14 -40
- epyt_flow/EPANET/EPANET/SRC_engines/hash.c +177 -177
- epyt_flow/EPANET/EPANET/SRC_engines/hash.h +28 -28
- epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +40 -192
- epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +46 -101
- epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +24 -85
- epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +63 -29
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +37 -70
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +234 -408
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +37 -87
- epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +79 -153
- epyt_flow/EPANET/EPANET/SRC_engines/input1.c +94 -59
- epyt_flow/EPANET/EPANET/SRC_engines/input2.c +202 -73
- epyt_flow/EPANET/EPANET/SRC_engines/input3.c +351 -446
- epyt_flow/EPANET/EPANET/SRC_engines/main.c +93 -0
- epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +4 -8
- epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +23 -23
- epyt_flow/EPANET/EPANET/SRC_engines/output.c +4 -5
- epyt_flow/EPANET/EPANET/SRC_engines/project.c +75 -407
- epyt_flow/EPANET/EPANET/SRC_engines/quality.c +2 -12
- epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +13 -70
- epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +5 -7
- epyt_flow/EPANET/EPANET/SRC_engines/report.c +20 -88
- epyt_flow/EPANET/EPANET/SRC_engines/rules.c +6 -144
- epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +19 -19
- epyt_flow/EPANET/EPANET/SRC_engines/text.h +5 -16
- epyt_flow/EPANET/EPANET/SRC_engines/types.h +19 -73
- epyt_flow/EPANET/compile_linux.sh +1 -1
- epyt_flow/EPANET/compile_macos.sh +1 -1
- epyt_flow/VERSION +1 -1
- epyt_flow/simulation/scada/scada_data.py +1 -1
- epyt_flow/utils.py +66 -0
- epyt_flow/visualization/visualization_utils.py +4 -2
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/METADATA +1 -1
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/RECORD +46 -52
- epyt_flow/EPANET/EPANET/SRC_engines/flowbalance.c +0 -186
- epyt_flow/EPANET/EPANET/SRC_engines/leakage.c +0 -527
- epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.c +0 -59
- epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.h +0 -38
- epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.c +0 -92
- epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.h +0 -39
- epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.c +0 -212
- epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.h +0 -81
- epyt_flow/EPANET/EPANET/SRC_engines/validate.c +0 -408
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/WHEEL +0 -0
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/licenses/LICENSE +0 -0
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/top_level.txt +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
2
|
******************************************************************************
|
|
3
3
|
Project: OWA EPANET
|
|
4
|
-
Version: 2.
|
|
4
|
+
Version: 2.2
|
|
5
5
|
Module: input3.c
|
|
6
6
|
Description: parses network data from a line of an EPANET input file
|
|
7
7
|
Authors: see AUTHORS
|
|
8
8
|
Copyright: see AUTHORS
|
|
9
9
|
License: see LICENSE
|
|
10
|
-
Last Updated:
|
|
10
|
+
Last Updated: 11/29/2019
|
|
11
11
|
******************************************************************************
|
|
12
12
|
*/
|
|
13
13
|
|
|
@@ -25,18 +25,16 @@ Last Updated: 04/19/2025
|
|
|
25
25
|
extern char *MixTxt[];
|
|
26
26
|
extern char *Fldname[];
|
|
27
27
|
extern char *DemandModelTxt[];
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
|
|
29
|
+
// Exported functions
|
|
30
|
+
int powercurve(double, double, double, double, double, double *, double *,
|
|
31
|
+
double *);
|
|
30
32
|
|
|
31
33
|
// Imported Functions
|
|
32
34
|
extern int addnodeID(Network *, int, char *);
|
|
33
35
|
extern int addlinkID(Network *, int, char *);
|
|
34
|
-
extern int getunitsoption(Project *, char *);
|
|
35
|
-
extern int getheadlossoption(Project *, char *);
|
|
36
36
|
|
|
37
37
|
// Local functions
|
|
38
|
-
static double gettokvalue(Project *, double, int, int *, int *);
|
|
39
|
-
static int getlinknodes(Project *, int *, int *);
|
|
40
38
|
static int optionchoice(Project *, int);
|
|
41
39
|
static int optionvalue(Project *, int);
|
|
42
40
|
static int getpumpcurve(Project *, int);
|
|
@@ -78,52 +76,31 @@ int juncdata(Project *pr)
|
|
|
78
76
|
int p = 0; // time pattern index
|
|
79
77
|
int n; // number of tokens
|
|
80
78
|
int njuncs; // number of network junction nodes
|
|
81
|
-
double el
|
|
82
|
-
|
|
83
|
-
x;
|
|
79
|
+
double el, // elevation
|
|
80
|
+
y = 0.0; // base demand
|
|
84
81
|
Snode *node;
|
|
85
|
-
int
|
|
86
|
-
int errtok = -1;
|
|
82
|
+
int err = 0;
|
|
87
83
|
|
|
88
84
|
// Add new junction to data base
|
|
85
|
+
n = parser->Ntokens;
|
|
89
86
|
if (net->Nnodes == parser->MaxNodes) return 200;
|
|
90
|
-
errcode = addnodeID(net, net->Njuncs + 1, parser->Tok[0]);
|
|
91
|
-
if (errcode > 0) return setError(parser, 0, errcode);
|
|
92
87
|
net->Njuncs++;
|
|
93
88
|
net->Nnodes++;
|
|
89
|
+
njuncs = net->Njuncs;
|
|
90
|
+
err = addnodeID(net, net->Njuncs, parser->Tok[0]);
|
|
91
|
+
if (err) return setError(parser, 0, err);
|
|
94
92
|
|
|
95
93
|
// Check for valid data
|
|
96
|
-
n
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
{
|
|
101
|
-
errcode = 202;
|
|
102
|
-
errtok = 1;
|
|
103
|
-
}
|
|
104
|
-
else el = x;
|
|
105
|
-
}
|
|
106
|
-
if (!errcode && n > 2)
|
|
107
|
-
{
|
|
108
|
-
if (!getfloat(parser->Tok[2], &x))
|
|
109
|
-
{
|
|
110
|
-
errcode = 202;
|
|
111
|
-
errtok = 2;
|
|
112
|
-
}
|
|
113
|
-
else d = x;
|
|
114
|
-
}
|
|
115
|
-
if (!errcode && n > 3)
|
|
94
|
+
if (n < 2) return 201;
|
|
95
|
+
if (!getfloat(parser->Tok[1], &el)) return setError(parser, 1, 202);
|
|
96
|
+
if (n >= 3 && !getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
|
|
97
|
+
if (n >= 4)
|
|
116
98
|
{
|
|
117
99
|
p = findpattern(net, parser->Tok[3]);
|
|
118
|
-
if (p < 0)
|
|
119
|
-
{
|
|
120
|
-
errcode = 205;
|
|
121
|
-
errtok = 3;
|
|
122
|
-
}
|
|
100
|
+
if (p < 0) return setError(parser, 3, 205);
|
|
123
101
|
}
|
|
124
102
|
|
|
125
103
|
// Save junction data
|
|
126
|
-
njuncs = net->Njuncs;
|
|
127
104
|
node = &net->Node[njuncs];
|
|
128
105
|
node->X = MISSING;
|
|
129
106
|
node->Y = MISSING;
|
|
@@ -138,14 +115,11 @@ int juncdata(Project *pr)
|
|
|
138
115
|
|
|
139
116
|
// Create a demand for the junction and use NodeDemand as an indicator
|
|
140
117
|
// to be used when processing demands from the [DEMANDS] section
|
|
141
|
-
if (!adddemand(node,
|
|
142
|
-
hyd->NodeDemand[njuncs] =
|
|
143
|
-
|
|
144
|
-
// Return error code
|
|
145
|
-
if (errcode > 0) return setError(parser, errtok, errcode);
|
|
118
|
+
if (!adddemand(node, y, p, NULL)) return 101;
|
|
119
|
+
hyd->NodeDemand[njuncs] = y;
|
|
146
120
|
return 0;
|
|
147
121
|
}
|
|
148
|
-
|
|
122
|
+
|
|
149
123
|
int tankdata(Project *pr)
|
|
150
124
|
/*
|
|
151
125
|
**--------------------------------------------------------------
|
|
@@ -156,6 +130,7 @@ int tankdata(Project *pr)
|
|
|
156
130
|
** [RESERVOIRS]
|
|
157
131
|
** id elev (pattern)
|
|
158
132
|
** [TANKS]
|
|
133
|
+
** id elev (pattern)
|
|
159
134
|
** id elev initlevel minlevel maxlevel diam (minvol vcurve)
|
|
160
135
|
**--------------------------------------------------------------
|
|
161
136
|
*/
|
|
@@ -179,84 +154,68 @@ int tankdata(Project *pr)
|
|
|
179
154
|
Snode *node;
|
|
180
155
|
Stank *tank;
|
|
181
156
|
|
|
182
|
-
int
|
|
183
|
-
int errtok = -1;
|
|
184
|
-
double x;
|
|
157
|
+
int err = 0;
|
|
185
158
|
|
|
186
159
|
// Add new tank to data base
|
|
160
|
+
n = parser->Ntokens;
|
|
187
161
|
if (net->Ntanks == parser->MaxTanks ||
|
|
188
162
|
net->Nnodes == parser->MaxNodes) return 200;
|
|
189
|
-
i = parser->MaxJuncs + net->Ntanks + 1;
|
|
190
|
-
errcode = addnodeID(net, i, parser->Tok[0]);
|
|
191
|
-
if (errcode) return setError(parser, 0, errcode);
|
|
192
163
|
net->Ntanks++;
|
|
193
164
|
net->Nnodes++;
|
|
194
165
|
|
|
166
|
+
i = parser->MaxJuncs + net->Ntanks;
|
|
167
|
+
err = addnodeID(net, i, parser->Tok[0]);
|
|
168
|
+
if (err) return setError(parser, 0, err);
|
|
169
|
+
|
|
195
170
|
// Check for valid data
|
|
196
|
-
n
|
|
197
|
-
if (
|
|
198
|
-
if (!errcode && !getfloat(parser->Tok[1], &x))
|
|
199
|
-
{
|
|
200
|
-
errcode = 202;
|
|
201
|
-
errtok = 1;
|
|
202
|
-
}
|
|
203
|
-
else el = x;
|
|
171
|
+
if (n < 2) return 201;
|
|
172
|
+
if (!getfloat(parser->Tok[1], &el)) return setError(parser, 1, 202);
|
|
204
173
|
|
|
205
|
-
//
|
|
174
|
+
// Tank is reservoir
|
|
206
175
|
if (n <= 3)
|
|
207
176
|
{
|
|
208
177
|
// Head pattern supplied
|
|
209
|
-
if (n == 3
|
|
178
|
+
if (n == 3)
|
|
210
179
|
{
|
|
211
180
|
pattern = findpattern(net, parser->Tok[2]);
|
|
212
|
-
if (pattern < 0)
|
|
213
|
-
{
|
|
214
|
-
errcode = 205;
|
|
215
|
-
errtok = 2;
|
|
216
|
-
}
|
|
181
|
+
if (pattern < 0) return setError(parser, 2, 205);
|
|
217
182
|
}
|
|
218
183
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
184
|
+
else if (n < 6) return 201;
|
|
185
|
+
|
|
186
|
+
// Tank is a storage tank
|
|
187
|
+
else
|
|
222
188
|
{
|
|
223
|
-
if (
|
|
224
|
-
|
|
189
|
+
if (!getfloat(parser->Tok[2], &initlevel)) return setError(parser, 2, 202);
|
|
190
|
+
if (!getfloat(parser->Tok[3], &minlevel)) return setError(parser, 3, 202);
|
|
191
|
+
if (!getfloat(parser->Tok[4], &maxlevel)) return setError(parser, 4, 202);
|
|
192
|
+
if (!getfloat(parser->Tok[5], &diam)) return setError(parser, 5, 202);
|
|
193
|
+
if (n >= 7 && !getfloat(parser->Tok[6], &minvol)) return setError(parser, 6, 202);
|
|
194
|
+
|
|
195
|
+
// If volume curve supplied check it exists
|
|
196
|
+
if (n >= 8)
|
|
225
197
|
{
|
|
226
|
-
|
|
227
|
-
initlevel = gettokvalue(pr, initlevel, 2, &errcode, &errtok);
|
|
228
|
-
minlevel = gettokvalue(pr, minlevel, 3, &errcode, &errtok);
|
|
229
|
-
maxlevel = gettokvalue(pr, maxlevel, 4, &errcode, &errtok);
|
|
230
|
-
diam = gettokvalue(pr, diam, 5, &errcode, &errtok);
|
|
231
|
-
if (n >= 7) minvol = gettokvalue(pr, minvol, 6, &errcode, &errtok);
|
|
232
|
-
|
|
233
|
-
// If volume curve supplied check it exists
|
|
234
|
-
if (!errcode && n >= 8)
|
|
198
|
+
if (strlen(parser->Tok[7]) > 0 && *(parser->Tok[7]) != '*')
|
|
235
199
|
{
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (curve == 0)
|
|
240
|
-
{
|
|
241
|
-
errcode = 206;
|
|
242
|
-
errtok = 7;
|
|
243
|
-
}
|
|
244
|
-
else net->Curve[curve].Type = VOLUME_CURVE;
|
|
245
|
-
}
|
|
200
|
+
curve = findcurve(net, parser->Tok[7]);
|
|
201
|
+
if (curve == 0) return setError(parser, 7, 206);
|
|
202
|
+
net->Curve[curve].Type = VOLUME_CURVE;
|
|
246
203
|
}
|
|
204
|
+
}
|
|
247
205
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
{
|
|
255
|
-
errcode = 213;
|
|
256
|
-
errtok = 8;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
206
|
+
// Parse overflow indicator if present
|
|
207
|
+
if (n >= 9)
|
|
208
|
+
{
|
|
209
|
+
if (match(parser->Tok[8], w_YES)) overflow = TRUE;
|
|
210
|
+
else if (match(parser->Tok[8], w_NO)) overflow = FALSE;
|
|
211
|
+
else return setError(parser, 8, 213);
|
|
259
212
|
}
|
|
213
|
+
|
|
214
|
+
if (initlevel < 0.0) return setError(parser, 2, 209);
|
|
215
|
+
if (minlevel < 0.0) return setError(parser, 3, 209);
|
|
216
|
+
if (maxlevel < 0.0) return setError(parser, 4, 209);
|
|
217
|
+
if (diam < 0.0) return setError(parser, 5, 209);
|
|
218
|
+
if (minvol < 0.0) return setError(parser, 6, 209);
|
|
260
219
|
}
|
|
261
220
|
node = &net->Node[i];
|
|
262
221
|
tank = &net->Tank[net->Ntanks];
|
|
@@ -293,39 +252,10 @@ int tankdata(Project *pr)
|
|
|
293
252
|
|
|
294
253
|
tank->Vcurve = curve;
|
|
295
254
|
tank->MixModel = MIX1; // Completely mixed
|
|
296
|
-
tank->
|
|
297
|
-
|
|
298
|
-
// Return error code
|
|
299
|
-
if (errcode > 0) return setError(parser, errtok, errcode);
|
|
255
|
+
tank->V1max = 1.0; // Mixing compartment size fraction
|
|
300
256
|
return 0;
|
|
301
257
|
}
|
|
302
258
|
|
|
303
|
-
double gettokvalue(Project *pr, double x, int itok, int *errcode, int *errtok)
|
|
304
|
-
/*
|
|
305
|
-
**--------------------------------------------------------------
|
|
306
|
-
** Input: x = default numerical value
|
|
307
|
-
** itok = index into an array of string tokens
|
|
308
|
-
** Output: errcode = an error code or 0 if successful
|
|
309
|
-
** errtok = itok if an error occurs
|
|
310
|
-
** returns a numerical data value
|
|
311
|
-
** Purpose: converts a string token into a numerical value.
|
|
312
|
-
**--------------------------------------------------------------
|
|
313
|
-
*/
|
|
314
|
-
{
|
|
315
|
-
Parser *parser = &pr->parser;
|
|
316
|
-
double result;
|
|
317
|
-
|
|
318
|
-
if (*errcode) return x;
|
|
319
|
-
if (!getfloat(parser->Tok[itok], &result)) *errcode = 202;
|
|
320
|
-
else if (result < 0.0) *errcode = 209;
|
|
321
|
-
if (*errcode > 0)
|
|
322
|
-
{
|
|
323
|
-
result = x;
|
|
324
|
-
*errtok = itok;
|
|
325
|
-
}
|
|
326
|
-
return result;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
259
|
int pipedata(Project *pr)
|
|
330
260
|
/*
|
|
331
261
|
**--------------------------------------------------------------
|
|
@@ -344,104 +274,71 @@ int pipedata(Project *pr)
|
|
|
344
274
|
int j1, // Start-node index
|
|
345
275
|
j2, // End-node index
|
|
346
276
|
n; // # data items
|
|
347
|
-
double
|
|
277
|
+
double length, // Pipe length
|
|
278
|
+
diam, // Pipe diameter
|
|
279
|
+
rcoeff, // Roughness coeff.
|
|
280
|
+
lcoeff = 0.0; // Minor loss coeff
|
|
281
|
+
LinkType type = PIPE; // Link type
|
|
282
|
+
StatusType status = OPEN; // Link status
|
|
348
283
|
Slink *link;
|
|
349
|
-
int
|
|
350
|
-
|
|
351
|
-
//
|
|
352
|
-
if (net->Nlinks == parser->MaxLinks) return 200;
|
|
284
|
+
int err = 0;
|
|
285
|
+
|
|
286
|
+
// Add new pipe to data base
|
|
353
287
|
n = parser->Ntokens;
|
|
354
|
-
if (
|
|
288
|
+
if (net->Nlinks == parser->MaxLinks) return 200;
|
|
289
|
+
net->Npipes++;
|
|
290
|
+
net->Nlinks++;
|
|
291
|
+
err = addlinkID(net, net->Nlinks, parser->Tok[0]);
|
|
292
|
+
if (err) return setError(parser, 0, err);
|
|
293
|
+
|
|
294
|
+
// Check for valid data
|
|
295
|
+
if (n < 6) return 201;
|
|
355
296
|
if ((j1 = findnode(net, parser->Tok[1])) == 0) return setError(parser, 1, 203);
|
|
356
297
|
if ((j2 = findnode(net, parser->Tok[2])) == 0) return setError(parser, 2, 203);
|
|
357
298
|
if (j1 == j2) return setError(parser, 0, 222);
|
|
358
299
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
|
|
300
|
+
if (!getfloat(parser->Tok[3], &length)) return setError(parser, 3, 202);
|
|
301
|
+
if (length <= 0.0) return setError(parser, 3, 211);
|
|
302
|
+
if (!getfloat(parser->Tok[4], &diam)) return setError(parser, 4, 202);
|
|
303
|
+
if (diam <= 0.0) return setError(parser, 4, 211);
|
|
304
|
+
if (!getfloat(parser->Tok[5], &rcoeff)) return setError(parser, 5, 202);
|
|
305
|
+
if (rcoeff <= 0.0) setError(parser, 5, 211);
|
|
364
306
|
|
|
365
|
-
//
|
|
366
|
-
|
|
367
|
-
link->N1 = j1;
|
|
368
|
-
link->N2 = j2;
|
|
369
|
-
|
|
370
|
-
if (parser->Unitsflag == SI)
|
|
307
|
+
// Either a loss coeff. or a status is supplied
|
|
308
|
+
if (n == 7)
|
|
371
309
|
{
|
|
372
|
-
|
|
373
|
-
|
|
310
|
+
if (match(parser->Tok[6], w_CV)) type = CVPIPE;
|
|
311
|
+
else if (match(parser->Tok[6], w_CLOSED)) status = CLOSED;
|
|
312
|
+
else if (match(parser->Tok[6], w_OPEN)) status = OPEN;
|
|
313
|
+
else if (!getfloat(parser->Tok[6], &lcoeff)) return setError(parser, 6, 202);
|
|
374
314
|
}
|
|
375
|
-
|
|
315
|
+
|
|
316
|
+
// Both a loss coeff. and a status is supplied
|
|
317
|
+
if (n == 8)
|
|
376
318
|
{
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
case HW: link->Kc = 130; break;
|
|
383
|
-
case DW: link->Kc = 0.0005; break;
|
|
384
|
-
case CM: link->Kc = 0.01; break;
|
|
385
|
-
default: link->Kc = 1.0;
|
|
319
|
+
if (!getfloat(parser->Tok[6], &lcoeff)) return setError(parser, 6, 202);
|
|
320
|
+
if (match(parser->Tok[7], w_CV)) type = CVPIPE;
|
|
321
|
+
else if (match(parser->Tok[7], w_CLOSED)) status = CLOSED;
|
|
322
|
+
else if (match(parser->Tok[7], w_OPEN)) status = OPEN;
|
|
323
|
+
else return setError(parser, 7, 213);
|
|
386
324
|
}
|
|
387
|
-
|
|
388
|
-
|
|
325
|
+
if (lcoeff < 0.0) return setError(parser, 6, 211);
|
|
326
|
+
|
|
327
|
+
// Save pipe data
|
|
328
|
+
link = &net->Link[net->Nlinks];
|
|
329
|
+
link->N1 = j1;
|
|
330
|
+
link->N2 = j2;
|
|
331
|
+
link->Len = length;
|
|
332
|
+
link->Diam = diam;
|
|
333
|
+
link->Kc = rcoeff;
|
|
334
|
+
link->Km = lcoeff;
|
|
389
335
|
link->Kb = MISSING;
|
|
390
336
|
link->Kw = MISSING;
|
|
391
|
-
link->
|
|
392
|
-
link->
|
|
393
|
-
link->Type = PIPE;
|
|
394
|
-
link->InitStatus = OPEN;
|
|
395
|
-
link->InitSetting = link->Kc;
|
|
337
|
+
link->Type = type;
|
|
338
|
+
link->Status = status;
|
|
396
339
|
link->Rpt = 0;
|
|
397
340
|
link->ResultIndex = 0;
|
|
398
341
|
link->Comment = xstrcpy(&link->Comment, parser->Comment, MAXMSG);
|
|
399
|
-
|
|
400
|
-
// Parse data values from input tokens
|
|
401
|
-
if (n > 3)
|
|
402
|
-
{
|
|
403
|
-
if (!getfloat(parser->Tok[3], &x) || x <= 0.0)
|
|
404
|
-
return setError(parser, 3, 202);
|
|
405
|
-
link->Len = x;
|
|
406
|
-
}
|
|
407
|
-
if (n > 4)
|
|
408
|
-
{
|
|
409
|
-
if (!getfloat(parser->Tok[4], &x) || x <= 0.0)
|
|
410
|
-
return setError(parser, 4, 202);
|
|
411
|
-
link->Diam = x;
|
|
412
|
-
}
|
|
413
|
-
if (n > 5)
|
|
414
|
-
{
|
|
415
|
-
if (!getfloat(parser->Tok[5], &x) || x <= 0.0)
|
|
416
|
-
return setError(parser, 5, 202);
|
|
417
|
-
link->Kc = x;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
// Either a loss coeff. or a status is supplied
|
|
421
|
-
if (n > 6)
|
|
422
|
-
{
|
|
423
|
-
if (match(parser->Tok[6], w_CV)) link->Type = CVPIPE;
|
|
424
|
-
else if (match(parser->Tok[6], w_CLOSED)) link->InitStatus = CLOSED;
|
|
425
|
-
else if (match(parser->Tok[6], w_OPEN)) link->InitStatus = OPEN;
|
|
426
|
-
else
|
|
427
|
-
{
|
|
428
|
-
if (!getfloat(parser->Tok[6], &x) || x < 0.0)
|
|
429
|
-
return setError(parser, 6, 202);
|
|
430
|
-
link->Km = x;
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// Both a loss coeff. and a status is supplied
|
|
435
|
-
if (n > 7)
|
|
436
|
-
{
|
|
437
|
-
if (!getfloat(parser->Tok[6], &x) || x < 0.0)
|
|
438
|
-
return setError(parser, 6, 202);
|
|
439
|
-
link->Km = x;
|
|
440
|
-
if (match(parser->Tok[7], w_CV)) link->Type = CVPIPE;
|
|
441
|
-
else if (match(parser->Tok[7], w_CLOSED)) link->InitStatus = CLOSED;
|
|
442
|
-
else if (match(parser->Tok[7], w_OPEN)) link->InitStatus = OPEN;
|
|
443
|
-
else return setError(parser, 7, 213);
|
|
444
|
-
}
|
|
445
342
|
return 0;
|
|
446
343
|
}
|
|
447
344
|
|
|
@@ -453,6 +350,11 @@ int pumpdata(Project *pr)
|
|
|
453
350
|
** Purpose: processes pump data
|
|
454
351
|
** Formats:
|
|
455
352
|
** [PUMP]
|
|
353
|
+
** (Version 1.x Format):
|
|
354
|
+
** id node1 node2 power
|
|
355
|
+
** id node1 node2 h1 q1
|
|
356
|
+
** id node1 node2 h0 h1 q1 h2 q2
|
|
357
|
+
** (Version 2 Format):
|
|
456
358
|
** id node1 node2 KEYWORD value {KEYWORD value ...}
|
|
457
359
|
** where KEYWORD = [POWER,HEAD,PATTERN,SPEED]
|
|
458
360
|
**--------------------------------------------------------------
|
|
@@ -461,7 +363,7 @@ int pumpdata(Project *pr)
|
|
|
461
363
|
Network *net = &pr->network;
|
|
462
364
|
Parser *parser = &pr->parser;
|
|
463
365
|
|
|
464
|
-
int m,
|
|
366
|
+
int j, m, // Token array indexes
|
|
465
367
|
j1, // Start-node index
|
|
466
368
|
j2, // End-node index
|
|
467
369
|
n, // # data items
|
|
@@ -469,24 +371,24 @@ int pumpdata(Project *pr)
|
|
|
469
371
|
double y;
|
|
470
372
|
Slink *link;
|
|
471
373
|
Spump *pump;
|
|
472
|
-
int
|
|
473
|
-
|
|
474
|
-
|
|
374
|
+
int err = 0;
|
|
375
|
+
|
|
376
|
+
/* Add new pump to data base */
|
|
377
|
+
n = parser->Ntokens;
|
|
475
378
|
if (net->Nlinks == parser->MaxLinks ||
|
|
476
379
|
net->Npumps == parser->MaxPumps) return 200;
|
|
477
|
-
|
|
478
|
-
|
|
380
|
+
net->Nlinks++;
|
|
381
|
+
net->Npumps++;
|
|
382
|
+
err = addlinkID(net, net->Nlinks, parser->Tok[0]);
|
|
383
|
+
if (err) return setError(parser, 0, err);
|
|
384
|
+
|
|
385
|
+
// Check for valid data
|
|
386
|
+
if (n < 3) return 201;
|
|
479
387
|
if ((j1 = findnode(net, parser->Tok[1])) == 0) return setError(parser, 1, 203);
|
|
480
388
|
if ((j2 = findnode(net, parser->Tok[2])) == 0) return setError(parser, 2, 203);
|
|
481
389
|
if (j1 == j2) return setError(parser, 0, 222);
|
|
482
390
|
|
|
483
|
-
//
|
|
484
|
-
errcode = addlinkID(net, net->Nlinks+1, parser->Tok[0]);
|
|
485
|
-
if (errcode) return setError(parser, 0, errcode);
|
|
486
|
-
net->Nlinks++;
|
|
487
|
-
net->Npumps++;
|
|
488
|
-
|
|
489
|
-
// Assign default data to pump
|
|
391
|
+
// Save pump data
|
|
490
392
|
link = &net->Link[net->Nlinks];
|
|
491
393
|
pump = &net->Pump[net->Npumps];
|
|
492
394
|
|
|
@@ -498,11 +400,8 @@ int pumpdata(Project *pr)
|
|
|
498
400
|
link->Km = 0.0;
|
|
499
401
|
link->Kb = 0.0;
|
|
500
402
|
link->Kw = 0.0;
|
|
501
|
-
link->LeakArea = 0.0;
|
|
502
|
-
link->LeakExpan = 0.0;
|
|
503
403
|
link->Type = PUMP;
|
|
504
|
-
link->
|
|
505
|
-
link->InitSetting = 1.0;
|
|
404
|
+
link->Status = OPEN;
|
|
506
405
|
link->Rpt = 0;
|
|
507
406
|
link->ResultIndex = 0;
|
|
508
407
|
link->Comment = xstrcpy(&link->Comment, parser->Comment, MAXMSG);
|
|
@@ -515,14 +414,28 @@ int pumpdata(Project *pr)
|
|
|
515
414
|
pump->Epat = 0;
|
|
516
415
|
if (n < 4) return 0;
|
|
517
416
|
|
|
518
|
-
//
|
|
417
|
+
// If 4-th token is a number then input follows Version 1.x format
|
|
418
|
+
// so retrieve pump curve parameters
|
|
419
|
+
if (getfloat(parser->Tok[3], &parser->X[0]))
|
|
420
|
+
{
|
|
421
|
+
m = 1;
|
|
422
|
+
for (j = 4; j < n; j++)
|
|
423
|
+
{
|
|
424
|
+
if (!getfloat(parser->Tok[j], &parser->X[m])) return setError(parser, j, 202);
|
|
425
|
+
m++;
|
|
426
|
+
}
|
|
427
|
+
return (getpumpcurve(pr, m));
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Otherwise input follows Version 2 format
|
|
431
|
+
// so retrieve keyword/value pairs
|
|
519
432
|
m = 4;
|
|
520
433
|
while (m < n)
|
|
521
434
|
{
|
|
522
435
|
if (match(parser->Tok[m - 1], w_POWER)) // Const. HP curve
|
|
523
436
|
{
|
|
524
|
-
|
|
525
|
-
|
|
437
|
+
y = atof(parser->Tok[m]);
|
|
438
|
+
if (y <= 0.0) return setError(parser, m, 202);
|
|
526
439
|
pump->Ptype = CONST_HP;
|
|
527
440
|
link->Km = y;
|
|
528
441
|
}
|
|
@@ -530,7 +443,6 @@ int pumpdata(Project *pr)
|
|
|
530
443
|
{
|
|
531
444
|
c = findcurve(net, parser->Tok[m]);
|
|
532
445
|
if (c == 0) return setError(parser, m, 206);
|
|
533
|
-
pump->Ptype = CUSTOM;
|
|
534
446
|
pump->Hcurve = c;
|
|
535
447
|
}
|
|
536
448
|
else if (match(parser->Tok[m - 1], w_PATTERN)) // Speed/status pattern
|
|
@@ -541,14 +453,13 @@ int pumpdata(Project *pr)
|
|
|
541
453
|
}
|
|
542
454
|
else if (match(parser->Tok[m - 1], w_SPEED)) // Speed setting
|
|
543
455
|
{
|
|
544
|
-
if (!getfloat(parser->Tok[m], &y)
|
|
545
|
-
|
|
456
|
+
if (!getfloat(parser->Tok[m], &y)) return setError(parser, m, 202);
|
|
457
|
+
if (y < 0.0) return setError(parser, m, 211);
|
|
546
458
|
link->Kc = y;
|
|
547
459
|
}
|
|
548
|
-
else return
|
|
460
|
+
else return 201;
|
|
549
461
|
m = m + 2; // Move to next keyword token
|
|
550
462
|
}
|
|
551
|
-
link->InitSetting = link->Kc;
|
|
552
463
|
return 0;
|
|
553
464
|
}
|
|
554
465
|
|
|
@@ -560,7 +471,7 @@ int valvedata(Project *pr)
|
|
|
560
471
|
** Purpose: processes valve data
|
|
561
472
|
** Format:
|
|
562
473
|
** [VALVE]
|
|
563
|
-
** id node1 node2 diam type setting (lcoeff
|
|
474
|
+
** id node1 node2 diam type setting (lcoeff)
|
|
564
475
|
**--------------------------------------------------------------
|
|
565
476
|
*/
|
|
566
477
|
{
|
|
@@ -573,30 +484,61 @@ int valvedata(Project *pr)
|
|
|
573
484
|
n; // # data items
|
|
574
485
|
char status = ACTIVE, // Valve status
|
|
575
486
|
type; // Valve type
|
|
576
|
-
double
|
|
487
|
+
double diam = 0.0, // Valve diameter
|
|
488
|
+
setting, // Valve setting
|
|
489
|
+
lcoeff = 0.0; // Minor loss coeff.
|
|
577
490
|
Slink *link;
|
|
578
|
-
int
|
|
579
|
-
losscurve = 0; // Loss coeff. curve
|
|
491
|
+
int err = 0;
|
|
580
492
|
|
|
581
|
-
//
|
|
493
|
+
// Add new valve to data base
|
|
494
|
+
n = parser->Ntokens;
|
|
582
495
|
if (net->Nlinks == parser->MaxLinks ||
|
|
583
496
|
net->Nvalves == parser->MaxValves) return 200;
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
if (
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
497
|
+
net->Nvalves++;
|
|
498
|
+
net->Nlinks++;
|
|
499
|
+
err = addlinkID(net, net->Nlinks, parser->Tok[0]);
|
|
500
|
+
if (err) return setError(parser, 0, err);
|
|
501
|
+
|
|
502
|
+
// Check for valid data
|
|
503
|
+
if (n < 6)
|
|
504
|
+
return 201;
|
|
505
|
+
if ((j1 = findnode(net, parser->Tok[1])) == 0)
|
|
506
|
+
return setError(parser, 1, 203);
|
|
507
|
+
if ((j2 = findnode(net, parser->Tok[2])) == 0)
|
|
508
|
+
return setError(parser, 2, 203);
|
|
509
|
+
if (j1 == j2)
|
|
510
|
+
return setError(parser, 0, 222);
|
|
511
|
+
|
|
512
|
+
if (match(parser->Tok[4], w_PRV))
|
|
513
|
+
type = PRV;
|
|
514
|
+
else if (match(parser->Tok[4], w_PSV))
|
|
515
|
+
type = PSV;
|
|
516
|
+
else if (match(parser->Tok[4], w_PBV))
|
|
517
|
+
type = PBV;
|
|
518
|
+
else if (match(parser->Tok[4], w_FCV))
|
|
519
|
+
type = FCV;
|
|
520
|
+
else if (match(parser->Tok[4], w_TCV))
|
|
521
|
+
type = TCV;
|
|
522
|
+
else if (match(parser->Tok[4], w_GPV))
|
|
523
|
+
type = GPV;
|
|
524
|
+
else
|
|
525
|
+
return setError(parser, 4, 213);
|
|
526
|
+
|
|
527
|
+
if (!getfloat(parser->Tok[3], &diam)) return setError(parser, 3, 202);
|
|
528
|
+
if (diam <= 0.0) return setError(parser, 3, 211);
|
|
529
|
+
|
|
530
|
+
// Find headloss curve for GPV
|
|
531
|
+
if (type == GPV)
|
|
532
|
+
{
|
|
533
|
+
c = findcurve(net, parser->Tok[5]);
|
|
534
|
+
if (c == 0) return setError(parser, 5, 206);
|
|
535
|
+
setting = c;
|
|
536
|
+
net->Curve[c].Type = HLOSS_CURVE;
|
|
537
|
+
status = OPEN;
|
|
538
|
+
}
|
|
539
|
+
else if (!getfloat(parser->Tok[5], &setting)) return setError(parser, 5, 202);
|
|
540
|
+
if (n >= 7 && !getfloat(parser->Tok[6], &lcoeff)) return setError(parser, 6, 202);
|
|
541
|
+
|
|
600
542
|
// Check for illegal connections
|
|
601
543
|
if (valvecheck(pr, net->Nlinks, type, j1, j2))
|
|
602
544
|
{
|
|
@@ -605,71 +547,22 @@ int valvedata(Project *pr)
|
|
|
605
547
|
else return setError(parser, -1, 220);
|
|
606
548
|
}
|
|
607
549
|
|
|
608
|
-
//
|
|
609
|
-
errcode = addlinkID(net, net->Nlinks+1, parser->Tok[0]);
|
|
610
|
-
if (errcode) return setError(parser, 0, errcode);
|
|
611
|
-
net->Nvalves++;
|
|
612
|
-
net->Nlinks++;
|
|
613
|
-
|
|
614
|
-
// Assign default data to valve
|
|
550
|
+
// Save valve data
|
|
615
551
|
link = &net->Link[net->Nlinks];
|
|
616
552
|
link->N1 = j1;
|
|
617
553
|
link->N2 = j2;
|
|
618
|
-
|
|
619
|
-
else link->Diam = 10.0;
|
|
554
|
+
link->Diam = diam;
|
|
620
555
|
link->Len = 0.0;
|
|
621
|
-
link->Kc =
|
|
622
|
-
link->Km =
|
|
556
|
+
link->Kc = setting;
|
|
557
|
+
link->Km = lcoeff;
|
|
623
558
|
link->Kb = 0.0;
|
|
624
559
|
link->Kw = 0.0;
|
|
625
|
-
link->LeakArea = 0.0;
|
|
626
|
-
link->LeakExpan = 0.0;
|
|
627
560
|
link->Type = type;
|
|
628
|
-
link->
|
|
629
|
-
link->InitSetting = 0.0;
|
|
561
|
+
link->Status = status;
|
|
630
562
|
link->Rpt = 0;
|
|
631
563
|
link->ResultIndex = 0;
|
|
632
564
|
link->Comment = xstrcpy(&link->Comment, parser->Comment, MAXMSG);
|
|
633
565
|
net->Valve[net->Nvalves].Link = net->Nlinks;
|
|
634
|
-
net->Valve[net->Nvalves].Curve = 0;
|
|
635
|
-
|
|
636
|
-
// Parse data values
|
|
637
|
-
if (!getfloat(parser->Tok[3], &x) || x <= 0.0)
|
|
638
|
-
return setError(parser, 3, 202);
|
|
639
|
-
link->Diam = x;
|
|
640
|
-
if (n > 5)
|
|
641
|
-
{
|
|
642
|
-
// Find headloss curve for GPV
|
|
643
|
-
if (type == GPV)
|
|
644
|
-
{
|
|
645
|
-
c = findcurve(net, parser->Tok[5]);
|
|
646
|
-
if (c == 0) return setError(parser, 5, 206);
|
|
647
|
-
link->Kc = c;
|
|
648
|
-
net->Curve[c].Type = HLOSS_CURVE;
|
|
649
|
-
link->InitStatus = OPEN;
|
|
650
|
-
}
|
|
651
|
-
else
|
|
652
|
-
{
|
|
653
|
-
if (!getfloat(parser->Tok[5], &x)) return setError(parser, 5, 202);
|
|
654
|
-
link->Kc = x;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
if (n > 6)
|
|
658
|
-
{
|
|
659
|
-
if (!getfloat(parser->Tok[6], &x) || x < 0.0)
|
|
660
|
-
return setError(parser, 6, 202);
|
|
661
|
-
link->Km = x;
|
|
662
|
-
}
|
|
663
|
-
if (n > 7 && type == PCV)
|
|
664
|
-
{
|
|
665
|
-
// Find loss coeff. curve for PCV
|
|
666
|
-
c = findcurve(net, parser->Tok[7]);
|
|
667
|
-
if (c == 0) return setError(parser, 7, 206);
|
|
668
|
-
net->Valve[net->Nvalves].Curve = c;
|
|
669
|
-
net->Curve[c].Type = VALVE_CURVE;
|
|
670
|
-
if (link->Kc > 100.0) link->Kc = 100.0;
|
|
671
|
-
}
|
|
672
|
-
link->InitSetting = link->Kc;
|
|
673
566
|
return 0;
|
|
674
567
|
}
|
|
675
568
|
|
|
@@ -720,7 +613,6 @@ int patterndata(Project *pr)
|
|
|
720
613
|
pattern->F = realloc(pattern->F, pattern->Length * sizeof(double));
|
|
721
614
|
|
|
722
615
|
// Add parsed multipliers to the pattern
|
|
723
|
-
for (j = 1; j <= n; j++) pattern->F[n1 + j - 1] = 1.0;
|
|
724
616
|
for (j = 1; j <= n; j++)
|
|
725
617
|
{
|
|
726
618
|
if (!getfloat(parser->Tok[j], &x)) return setError(parser, j, 202);
|
|
@@ -747,7 +639,7 @@ int curvedata(Project *pr)
|
|
|
747
639
|
Network *net = &pr->network;
|
|
748
640
|
Parser *parser = &pr->parser;
|
|
749
641
|
|
|
750
|
-
int i
|
|
642
|
+
int i;
|
|
751
643
|
double x, y;
|
|
752
644
|
Scurve *curve;
|
|
753
645
|
|
|
@@ -755,11 +647,6 @@ int curvedata(Project *pr)
|
|
|
755
647
|
if (parser->Ntokens < 3) return 201;
|
|
756
648
|
if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
|
|
757
649
|
if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
|
|
758
|
-
ctype = -1;
|
|
759
|
-
if (parser->Ntokens > 3)
|
|
760
|
-
{
|
|
761
|
-
ctype = findmatch(parser->Tok[3], CurveTypeTxt);
|
|
762
|
-
}
|
|
763
650
|
|
|
764
651
|
// Check if previous input line was for the same curve
|
|
765
652
|
if (parser->PrevCurve && strcmp(parser->Tok[0], parser->PrevCurve->ID) == 0)
|
|
@@ -789,7 +676,6 @@ int curvedata(Project *pr)
|
|
|
789
676
|
curve->X[curve->Npts] = x;
|
|
790
677
|
curve->Y[curve->Npts] = y;
|
|
791
678
|
curve->Npts++;
|
|
792
|
-
if (ctype >= 0) curve->Type = (CurveType)ctype;
|
|
793
679
|
|
|
794
680
|
// Save a reference to this curve for processing additional curve data
|
|
795
681
|
parser->PrevCurve = curve;
|
|
@@ -800,14 +686,11 @@ int coordata(Project *pr)
|
|
|
800
686
|
/*
|
|
801
687
|
**--------------------------------------------------------------
|
|
802
688
|
** Input: none
|
|
803
|
-
** Output: returns
|
|
804
|
-
** Purpose: processes
|
|
689
|
+
** Output: returns error code
|
|
690
|
+
** Purpose: processes coordinate data
|
|
805
691
|
** Format:
|
|
806
692
|
** [COORD]
|
|
807
693
|
** id x y
|
|
808
|
-
**
|
|
809
|
-
** Note: since node coords. are not used in any computations,
|
|
810
|
-
** invalid data are simply ignored.
|
|
811
694
|
**--------------------------------------------------------------
|
|
812
695
|
*/
|
|
813
696
|
{
|
|
@@ -819,12 +702,12 @@ int coordata(Project *pr)
|
|
|
819
702
|
Snode *node;
|
|
820
703
|
|
|
821
704
|
// Check for valid node ID
|
|
822
|
-
if (parser->Ntokens < 3) return
|
|
823
|
-
if ((j = findnode(net, parser->Tok[0])) == 0) return 0;
|
|
705
|
+
if (parser->Ntokens < 3) return 201;
|
|
706
|
+
if ((j = findnode(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
|
|
824
707
|
|
|
825
708
|
// Check for valid data
|
|
826
|
-
if (!getfloat(parser->Tok[1], &x)) return
|
|
827
|
-
if (!getfloat(parser->Tok[2], &y)) return
|
|
709
|
+
if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
|
|
710
|
+
if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
|
|
828
711
|
|
|
829
712
|
// Save coord data
|
|
830
713
|
node = &net->Node[j];
|
|
@@ -837,14 +720,11 @@ int vertexdata(Project *pr)
|
|
|
837
720
|
/*
|
|
838
721
|
**--------------------------------------------------------------
|
|
839
722
|
** Input: none
|
|
840
|
-
** Output: returns
|
|
723
|
+
** Output: returns error code
|
|
841
724
|
** Purpose: processes link vertex data
|
|
842
725
|
** Format:
|
|
843
726
|
** [VERTICES]
|
|
844
727
|
** id x y
|
|
845
|
-
**
|
|
846
|
-
** Note: since vertex coords. are not used in any computations,
|
|
847
|
-
** invalid data are simply ignored.
|
|
848
728
|
**--------------------------------------------------------------
|
|
849
729
|
*/
|
|
850
730
|
{
|
|
@@ -855,12 +735,12 @@ int vertexdata(Project *pr)
|
|
|
855
735
|
double x, y;
|
|
856
736
|
|
|
857
737
|
// Check for valid link ID
|
|
858
|
-
if (parser->Ntokens < 3) return
|
|
859
|
-
if ((j = findlink(net, parser->Tok[0])) == 0) return 0;
|
|
738
|
+
if (parser->Ntokens < 3) return 201;
|
|
739
|
+
if ((j = findlink(net, parser->Tok[0])) == 0) return setError(parser, 0, 204);
|
|
860
740
|
|
|
861
741
|
// Check for valid coordinate data
|
|
862
|
-
if (!getfloat(parser->Tok[1], &x)) return
|
|
863
|
-
if (!getfloat(parser->Tok[2], &y)) return
|
|
742
|
+
if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
|
|
743
|
+
if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
|
|
864
744
|
|
|
865
745
|
// Add to link's list of vertex points
|
|
866
746
|
return addlinkvertex(&net->Link[j], x, y);
|
|
@@ -875,6 +755,7 @@ int demanddata(Project *pr)
|
|
|
875
755
|
** Purpose: processes node demand data
|
|
876
756
|
** Format:
|
|
877
757
|
** [DEMANDS]
|
|
758
|
+
** MULTIPLY factor
|
|
878
759
|
** node base_demand (pattern)
|
|
879
760
|
**
|
|
880
761
|
** NOTE: Demands entered in this section replace those
|
|
@@ -896,7 +777,15 @@ int demanddata(Project *pr)
|
|
|
896
777
|
if (n < 2) return 201;
|
|
897
778
|
if (!getfloat(parser->Tok[1], &y)) return setError(parser, 1, 202);
|
|
898
779
|
|
|
899
|
-
//
|
|
780
|
+
// If MULTIPLY command, save multiplier
|
|
781
|
+
if (match(parser->Tok[0], w_MULTIPLY))
|
|
782
|
+
{
|
|
783
|
+
if (y <= 0.0) return setError(parser, 1, 213);
|
|
784
|
+
else hyd->Dmult = y;
|
|
785
|
+
return 0;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// Otherwise find node (and pattern) being referenced
|
|
900
789
|
if ((j = findnode(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
|
|
901
790
|
if (j > net->Njuncs) return 0;
|
|
902
791
|
if (n >= 3)
|
|
@@ -933,10 +822,10 @@ int controldata(Project *pr)
|
|
|
933
822
|
** Purpose: processes simple controls
|
|
934
823
|
** Formats:
|
|
935
824
|
** [CONTROLS]
|
|
936
|
-
** LINK linkID setting IF NODE nodeID {BELOW/ABOVE} level
|
|
937
|
-
** LINK linkID setting AT TIME value (units)
|
|
938
|
-
** LINK linkID setting AT CLOCKTIME value (units)
|
|
939
|
-
** (0) (1) (2) (3) (4) (5) (6) (7)
|
|
825
|
+
** LINK linkID setting IF NODE nodeID {BELOW/ABOVE} level
|
|
826
|
+
** LINK linkID setting AT TIME value (units)
|
|
827
|
+
** LINK linkID setting AT CLOCKTIME value (units)
|
|
828
|
+
** (0) (1) (2) (3) (4) (5) (6) (7)
|
|
940
829
|
**--------------------------------------------------------------
|
|
941
830
|
*/
|
|
942
831
|
{
|
|
@@ -945,8 +834,7 @@ int controldata(Project *pr)
|
|
|
945
834
|
|
|
946
835
|
int i = 0, // Node index
|
|
947
836
|
k, // Link index
|
|
948
|
-
n
|
|
949
|
-
isEnabled = TRUE; // Control enabled
|
|
837
|
+
n; // # data items
|
|
950
838
|
double setting = MISSING, // Link setting
|
|
951
839
|
time = 0.0, // Simulation time
|
|
952
840
|
level = 0.0; // Pressure or tank level
|
|
@@ -958,13 +846,6 @@ int controldata(Project *pr)
|
|
|
958
846
|
// Check for sufficient number of input tokens
|
|
959
847
|
n = parser->Ntokens;
|
|
960
848
|
if (n < 6) return 201;
|
|
961
|
-
|
|
962
|
-
// Check if last token is "DISABLED"
|
|
963
|
-
if (match(parser->Tok[n-1], w_DISABLED))
|
|
964
|
-
{
|
|
965
|
-
isEnabled = FALSE;
|
|
966
|
-
n = n - 1;
|
|
967
|
-
}
|
|
968
849
|
|
|
969
850
|
// Check that controlled link exists
|
|
970
851
|
k = findlink(net, parser->Tok[1]);
|
|
@@ -1020,7 +901,7 @@ int controldata(Project *pr)
|
|
|
1020
901
|
case TIMER:
|
|
1021
902
|
case TIMEOFDAY:
|
|
1022
903
|
if (n == 6) time = hour(parser->Tok[5], "");
|
|
1023
|
-
if (n
|
|
904
|
+
if (n == 7) time = hour(parser->Tok[5], parser->Tok[6]);
|
|
1024
905
|
if (time < 0.0) return setError(parser, 5, 213);
|
|
1025
906
|
break;
|
|
1026
907
|
case LOWLEVEL:
|
|
@@ -1041,7 +922,6 @@ int controldata(Project *pr)
|
|
|
1041
922
|
control->Time = (long)(3600.0 * time);
|
|
1042
923
|
if (ctltype == TIMEOFDAY) control->Time %= SECperDAY;
|
|
1043
924
|
control->Grade = level;
|
|
1044
|
-
control->isEnabled = isEnabled;
|
|
1045
925
|
return 0;
|
|
1046
926
|
}
|
|
1047
927
|
|
|
@@ -1145,41 +1025,6 @@ int emitterdata(Project *pr)
|
|
|
1145
1025
|
return 0;
|
|
1146
1026
|
}
|
|
1147
1027
|
|
|
1148
|
-
int leakagedata(Project *pr)
|
|
1149
|
-
/*
|
|
1150
|
-
**--------------------------------------------------------------
|
|
1151
|
-
** Input: none
|
|
1152
|
-
** Output: returns error code
|
|
1153
|
-
** Purpose: processes link leakage data
|
|
1154
|
-
** Format:
|
|
1155
|
-
** [LEAKAGE]
|
|
1156
|
-
** link C1 C2
|
|
1157
|
-
**--------------------------------------------------------------
|
|
1158
|
-
*/
|
|
1159
|
-
{
|
|
1160
|
-
Network *net = &pr->network;
|
|
1161
|
-
Parser *parser = &pr->parser;
|
|
1162
|
-
|
|
1163
|
-
int j, // Link index
|
|
1164
|
-
n; // # data items
|
|
1165
|
-
double c1, c2; // Flow coeff.
|
|
1166
|
-
|
|
1167
|
-
// Check that link exists & is a pipe
|
|
1168
|
-
n = parser->Ntokens;
|
|
1169
|
-
if (n < 3) return 201;
|
|
1170
|
-
if ((j = findlink(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
|
|
1171
|
-
if (net->Link[j].Type > PIPE) return 0;
|
|
1172
|
-
|
|
1173
|
-
// Parse leakage coeffs.
|
|
1174
|
-
if (!getfloat(parser->Tok[1], &c1)) return setError(parser, 1, 202);
|
|
1175
|
-
if (c1 < 0.0) return setError(parser, 1, 209);
|
|
1176
|
-
if (!getfloat(parser->Tok[2], &c2)) return setError(parser, 2, 202);
|
|
1177
|
-
if (c2 < 0.0) return setError(parser, 1, 209);
|
|
1178
|
-
net->Link[j].LeakArea = c1;
|
|
1179
|
-
net->Link[j].LeakExpan = c2;
|
|
1180
|
-
return 0;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
1028
|
int qualdata(Project *pr)
|
|
1184
1029
|
/*
|
|
1185
1030
|
**--------------------------------------------------------------
|
|
@@ -1443,7 +1288,7 @@ int mixingdata(Project *pr)
|
|
|
1443
1288
|
i = j - net->Njuncs;
|
|
1444
1289
|
if (net->Tank[i].A == 0.0) return 0;
|
|
1445
1290
|
net->Tank[i].MixModel = (char)m;
|
|
1446
|
-
net->Tank[i].
|
|
1291
|
+
net->Tank[i].V1max = v;
|
|
1447
1292
|
return 0;
|
|
1448
1293
|
}
|
|
1449
1294
|
|
|
@@ -1884,8 +1729,8 @@ int optionchoice(Project *pr, int n)
|
|
|
1884
1729
|
** those listed below, or -1 otherwise
|
|
1885
1730
|
** Purpose: processes fixed choice [OPTIONS] data
|
|
1886
1731
|
** Formats:
|
|
1887
|
-
** UNITS CFS/GPM/MGD/IMGD/AFD/LPS/LPM/MLD/CMH/CMD/
|
|
1888
|
-
** PRESSURE PSI/KPA/
|
|
1732
|
+
** UNITS CFS/GPM/MGD/IMGD/AFD/LPS/LPM/MLD/CMH/CMD/SI
|
|
1733
|
+
** PRESSURE PSI/KPA/M
|
|
1889
1734
|
** HEADLOSS H-W/D-W/C-M
|
|
1890
1735
|
** HYDRAULICS USE/SAVE filename
|
|
1891
1736
|
** QUALITY NONE/AGE/TRACE/CHEMICAL (TraceNode)
|
|
@@ -1894,7 +1739,6 @@ int optionchoice(Project *pr, int n)
|
|
|
1894
1739
|
** UNBALANCED STOP/CONTINUE {Niter}
|
|
1895
1740
|
** PATTERN id
|
|
1896
1741
|
** DEMAND MODEL DDA/PDA
|
|
1897
|
-
** BACKFLOW ALLOWED YES/NO
|
|
1898
1742
|
**--------------------------------------------------------------
|
|
1899
1743
|
*/
|
|
1900
1744
|
{
|
|
@@ -1914,20 +1758,28 @@ int optionchoice(Project *pr, int n)
|
|
|
1914
1758
|
if (match(parser->Tok[0], w_UNITS))
|
|
1915
1759
|
{
|
|
1916
1760
|
if (n < 1) return 0;
|
|
1917
|
-
if (
|
|
1918
|
-
|
|
1761
|
+
else if (match(parser->Tok[1], w_CFS)) parser->Flowflag = CFS;
|
|
1762
|
+
else if (match(parser->Tok[1], w_GPM)) parser->Flowflag = GPM;
|
|
1763
|
+
else if (match(parser->Tok[1], w_AFD)) parser->Flowflag = AFD;
|
|
1764
|
+
else if (match(parser->Tok[1], w_MGD)) parser->Flowflag = MGD;
|
|
1765
|
+
else if (match(parser->Tok[1], w_IMGD)) parser->Flowflag = IMGD;
|
|
1766
|
+
else if (match(parser->Tok[1], w_LPS)) parser->Flowflag = LPS;
|
|
1767
|
+
else if (match(parser->Tok[1], w_LPM)) parser->Flowflag = LPM;
|
|
1768
|
+
else if (match(parser->Tok[1], w_CMH)) parser->Flowflag = CMH;
|
|
1769
|
+
else if (match(parser->Tok[1], w_CMD)) parser->Flowflag = CMD;
|
|
1770
|
+
else if (match(parser->Tok[1], w_MLD)) parser->Flowflag = MLD;
|
|
1771
|
+
else if (match(parser->Tok[1], w_SI)) parser->Flowflag = LPS;
|
|
1772
|
+
else return setError(parser, 1, 213);
|
|
1919
1773
|
}
|
|
1920
1774
|
|
|
1921
1775
|
// PRESSURE units
|
|
1922
1776
|
else if (match(parser->Tok[0], w_PRESSURE))
|
|
1923
1777
|
{
|
|
1924
|
-
if (n < 1) return 0;
|
|
1778
|
+
if (n < 1) return 0;
|
|
1925
1779
|
else if (match(parser->Tok[1], w_EXPONENT)) return -1;
|
|
1926
1780
|
else if (match(parser->Tok[1], w_PSI)) parser->Pressflag = PSI;
|
|
1927
1781
|
else if (match(parser->Tok[1], w_KPA)) parser->Pressflag = KPA;
|
|
1928
1782
|
else if (match(parser->Tok[1], w_METERS)) parser->Pressflag = METERS;
|
|
1929
|
-
else if (match(parser->Tok[1], w_BAR)) parser->Pressflag = BAR;
|
|
1930
|
-
else if (match(parser->Tok[1], w_FEET)) parser->Pressflag = FEET;
|
|
1931
1783
|
else return setError(parser, 1, 213);
|
|
1932
1784
|
}
|
|
1933
1785
|
|
|
@@ -1935,8 +1787,10 @@ int optionchoice(Project *pr, int n)
|
|
|
1935
1787
|
else if (match(parser->Tok[0], w_HEADLOSS))
|
|
1936
1788
|
{
|
|
1937
1789
|
if (n < 1) return 0;
|
|
1938
|
-
if (
|
|
1939
|
-
|
|
1790
|
+
else if (match(parser->Tok[1], w_HW)) hyd->Formflag = HW;
|
|
1791
|
+
else if (match(parser->Tok[1], w_DW)) hyd->Formflag = DW;
|
|
1792
|
+
else if (match(parser->Tok[1], w_CM)) hyd->Formflag = CM;
|
|
1793
|
+
else return setError(parser, 1, 213);
|
|
1940
1794
|
}
|
|
1941
1795
|
|
|
1942
1796
|
// HYDRUALICS USE/SAVE file option
|
|
@@ -1965,7 +1819,10 @@ int optionchoice(Project *pr, int n)
|
|
|
1965
1819
|
}
|
|
1966
1820
|
if (qual->Qualflag == TRACE)
|
|
1967
1821
|
{
|
|
1822
|
+
// Copy Trace Node ID to parser->Tok[0] for error reporting
|
|
1823
|
+
strcpy(parser->Tok[0], "");
|
|
1968
1824
|
if (n < 2) return 201;
|
|
1825
|
+
strcpy(parser->Tok[0], parser->Tok[2]);
|
|
1969
1826
|
qual->TraceNode = findnode(net, parser->Tok[2]);
|
|
1970
1827
|
if (qual->TraceNode == 0) return setError(parser, 2, 212);
|
|
1971
1828
|
strncpy(qual->ChemName, u_PERCENT, MAXID);
|
|
@@ -2019,16 +1876,6 @@ int optionchoice(Project *pr, int n)
|
|
|
2019
1876
|
if (choice < 0) return setError(parser, 2, 213);
|
|
2020
1877
|
hyd->DemandModel = choice;
|
|
2021
1878
|
}
|
|
2022
|
-
|
|
2023
|
-
// Emitter BACKFLOW ALLOWED
|
|
2024
|
-
else if (match(parser->Tok[0], w_BACKFLOW))
|
|
2025
|
-
{
|
|
2026
|
-
if (n < 2) return 0;
|
|
2027
|
-
if (!match(parser->Tok[1], w_ALLOWED)) return -1;
|
|
2028
|
-
choice = findmatch(parser->Tok[2], BackflowTxt);
|
|
2029
|
-
if (choice < 0) return setError(parser, 2, 213);
|
|
2030
|
-
hyd->EmitBackFlag = choice;
|
|
2031
|
-
}
|
|
2032
1879
|
|
|
2033
1880
|
// Return -1 if keyword did not match any option
|
|
2034
1881
|
else return -1;
|
|
@@ -2038,7 +1885,7 @@ int optionchoice(Project *pr, int n)
|
|
|
2038
1885
|
int optionvalue(Project *pr, int n)
|
|
2039
1886
|
/*
|
|
2040
1887
|
**-------------------------------------------------------------
|
|
2041
|
-
** Input:
|
|
1888
|
+
** Input: *line = line read from input file
|
|
2042
1889
|
** Output: returns error code
|
|
2043
1890
|
** Purpose: processes numerical value [OPTIONS] data
|
|
2044
1891
|
** Formats:
|
|
@@ -2185,43 +2032,102 @@ int optionvalue(Project *pr, int n)
|
|
|
2185
2032
|
return 0;
|
|
2186
2033
|
}
|
|
2187
2034
|
|
|
2188
|
-
int
|
|
2035
|
+
int getpumpcurve(Project *pr, int n)
|
|
2189
2036
|
/*
|
|
2190
|
-
|
|
2191
|
-
** Input:
|
|
2037
|
+
**--------------------------------------------------------
|
|
2038
|
+
** Input: n = number of parameters for pump curve
|
|
2192
2039
|
** Output: returns error code
|
|
2193
|
-
** Purpose: processes
|
|
2194
|
-
**
|
|
2195
|
-
**
|
|
2196
|
-
**
|
|
2197
|
-
|
|
2040
|
+
** Purpose: processes pump curve data for Version 1.1-
|
|
2041
|
+
** style input data
|
|
2042
|
+
** Notes:
|
|
2043
|
+
** 1. Called by pumpdata() in INPUT3.C
|
|
2044
|
+
** 2. Current link index & pump index of pump being
|
|
2045
|
+
** processed is found in network variables Nlinks
|
|
2046
|
+
** and Npumps, respectively
|
|
2047
|
+
** 3. Curve data read from input line is found in
|
|
2048
|
+
** parser's array X[0],...X[n-1]
|
|
2049
|
+
**---------------------------------------------------------
|
|
2198
2050
|
*/
|
|
2199
2051
|
{
|
|
2200
2052
|
Network *net = &pr->network;
|
|
2201
2053
|
Parser *parser = &pr->parser;
|
|
2202
2054
|
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
// Check for sufficient data
|
|
2206
|
-
n = parser->Ntokens;
|
|
2207
|
-
if (n < 3) return 201;
|
|
2055
|
+
double a, b, c, h0, h1, h2, q1, q2;
|
|
2056
|
+
Spump *pump = &net->Pump[net->Npumps];
|
|
2208
2057
|
|
|
2209
|
-
//
|
|
2210
|
-
if (
|
|
2058
|
+
// Constant HP curve
|
|
2059
|
+
if (n == 1)
|
|
2211
2060
|
{
|
|
2212
|
-
if (
|
|
2213
|
-
|
|
2061
|
+
if (parser->X[0] <= 0.0) return 202;
|
|
2062
|
+
pump->Ptype = CONST_HP;
|
|
2063
|
+
net->Link[net->Nlinks].Km = parser->X[0];
|
|
2214
2064
|
}
|
|
2215
2065
|
|
|
2216
|
-
//
|
|
2217
|
-
else
|
|
2066
|
+
// Power function curve
|
|
2067
|
+
else
|
|
2218
2068
|
{
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2069
|
+
// Single point power curve
|
|
2070
|
+
if (n == 2)
|
|
2071
|
+
{
|
|
2072
|
+
q1 = parser->X[1];
|
|
2073
|
+
h1 = parser->X[0];
|
|
2074
|
+
h0 = 1.33334 * h1;
|
|
2075
|
+
q2 = 2.0 * q1;
|
|
2076
|
+
h2 = 0.0;
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
// 3-point power curve
|
|
2080
|
+
else if (n >= 5)
|
|
2081
|
+
{
|
|
2082
|
+
h0 = parser->X[0];
|
|
2083
|
+
h1 = parser->X[1];
|
|
2084
|
+
q1 = parser->X[2];
|
|
2085
|
+
h2 = parser->X[3];
|
|
2086
|
+
q2 = parser->X[4];
|
|
2087
|
+
}
|
|
2088
|
+
else return 202;
|
|
2089
|
+
pump->Ptype = POWER_FUNC;
|
|
2090
|
+
if (!powercurve(h0, h1, h2, q1, q2, &a, &b, &c)) return 206;
|
|
2091
|
+
pump->H0 = -a;
|
|
2092
|
+
pump->R = -b;
|
|
2093
|
+
pump->N = c;
|
|
2094
|
+
pump->Q0 = q1;
|
|
2095
|
+
pump->Qmax = pow((-a / b), (1.0 / c));
|
|
2096
|
+
pump->Hmax = h0;
|
|
2097
|
+
}
|
|
2098
|
+
return 0;
|
|
2223
2099
|
}
|
|
2224
|
-
|
|
2100
|
+
|
|
2101
|
+
int powercurve(double h0, double h1, double h2, double q1, double q2,
|
|
2102
|
+
double *a, double *b, double *c)
|
|
2103
|
+
/*
|
|
2104
|
+
**---------------------------------------------------------
|
|
2105
|
+
** Input: h0 = shutoff head
|
|
2106
|
+
** h1 = design head
|
|
2107
|
+
** h2 = head at max. flow
|
|
2108
|
+
** q1 = design flow
|
|
2109
|
+
** q2 = max. flow
|
|
2110
|
+
** Output: *a, *b, *c = pump curve coeffs. (H = a-bQ^c),
|
|
2111
|
+
** Returns 1 if sucessful, 0 otherwise.
|
|
2112
|
+
** Purpose: computes coeffs. for pump curve
|
|
2113
|
+
**----------------------------------------------------------
|
|
2114
|
+
*/
|
|
2115
|
+
{
|
|
2116
|
+
double h4, h5;
|
|
2117
|
+
|
|
2118
|
+
if (h0 < TINY || h0 - h1 < TINY || h1 - h2 < TINY ||
|
|
2119
|
+
q1 < TINY || q2 - q1 < TINY
|
|
2120
|
+
) return 0;
|
|
2121
|
+
*a = h0;
|
|
2122
|
+
h4 = h0 - h1;
|
|
2123
|
+
h5 = h0 - h2;
|
|
2124
|
+
*c = log(h5 / h4) / log(q2 / q1);
|
|
2125
|
+
if (*c <= 0.0 || *c > 20.0) return 0;
|
|
2126
|
+
*b = -h4 / pow(q1, *c);
|
|
2127
|
+
if (*b >= 0.0) return 0;
|
|
2128
|
+
return 1;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2225
2131
|
void changestatus(Network *net, int j, StatusType status, double y)
|
|
2226
2132
|
/*
|
|
2227
2133
|
**--------------------------------------------------------------
|
|
@@ -2230,10 +2136,11 @@ void changestatus(Network *net, int j, StatusType status, double y)
|
|
|
2230
2136
|
** y = numerical setting (pump speed, valve
|
|
2231
2137
|
** setting)
|
|
2232
2138
|
** Output: none
|
|
2233
|
-
** Purpose: changes
|
|
2139
|
+
** Purpose: changes status or setting of a link
|
|
2234
2140
|
**
|
|
2235
2141
|
** NOTE: If status = ACTIVE, then a numerical setting (y) was
|
|
2236
|
-
** supplied.
|
|
2142
|
+
** supplied. If status = OPEN/CLOSED, then numerical
|
|
2143
|
+
** setting is 0.
|
|
2237
2144
|
**--------------------------------------------------------------
|
|
2238
2145
|
*/
|
|
2239
2146
|
{
|
|
@@ -2241,7 +2148,7 @@ void changestatus(Network *net, int j, StatusType status, double y)
|
|
|
2241
2148
|
|
|
2242
2149
|
if (link->Type == PIPE || link->Type == GPV)
|
|
2243
2150
|
{
|
|
2244
|
-
if (status != ACTIVE) link->
|
|
2151
|
+
if (status != ACTIVE) link->Status = status;
|
|
2245
2152
|
}
|
|
2246
2153
|
else if (link->Type == PUMP)
|
|
2247
2154
|
{
|
|
@@ -2252,14 +2159,12 @@ void changestatus(Network *net, int j, StatusType status, double y)
|
|
|
2252
2159
|
if (y == 0.0) status = CLOSED;
|
|
2253
2160
|
}
|
|
2254
2161
|
else if (status == OPEN) link->Kc = 1.0;
|
|
2255
|
-
|
|
2256
|
-
link->InitStatus = status;
|
|
2257
|
-
link->InitSetting = link->Kc;
|
|
2162
|
+
link->Status = status;
|
|
2258
2163
|
}
|
|
2259
2164
|
else if (link->Type >= PRV)
|
|
2260
2165
|
{
|
|
2261
|
-
|
|
2262
|
-
link->
|
|
2263
|
-
link->
|
|
2166
|
+
link->Kc = y;
|
|
2167
|
+
link->Status = status;
|
|
2168
|
+
if (status != ACTIVE) link->Kc = MISSING;
|
|
2264
2169
|
}
|
|
2265
2170
|
}
|