epyt-flow 0.14.2__py3-none-any.whl → 0.15.0__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 (100) 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 +368 -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-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/METADATA +14 -19
  19. epyt_flow-0.15.0.dist-info/RECORD +65 -0
  20. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +0 -28
  21. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +0 -21
  22. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +0 -18
  23. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +0 -134
  24. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +0 -5578
  25. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +0 -865
  26. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +0 -131
  27. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +0 -73
  28. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +0 -193
  29. epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +0 -1000
  30. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +0 -177
  31. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +0 -28
  32. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +0 -1151
  33. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +0 -1117
  34. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +0 -720
  35. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +0 -476
  36. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +0 -431
  37. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +0 -1786
  38. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +0 -468
  39. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +0 -810
  40. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +0 -707
  41. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +0 -864
  42. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +0 -2170
  43. epyt_flow/EPANET/EPANET/SRC_engines/main.c +0 -93
  44. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +0 -142
  45. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +0 -24
  46. epyt_flow/EPANET/EPANET/SRC_engines/output.c +0 -852
  47. epyt_flow/EPANET/EPANET/SRC_engines/project.c +0 -1359
  48. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +0 -685
  49. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +0 -743
  50. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +0 -694
  51. epyt_flow/EPANET/EPANET/SRC_engines/report.c +0 -1489
  52. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +0 -1362
  53. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +0 -871
  54. epyt_flow/EPANET/EPANET/SRC_engines/text.h +0 -497
  55. epyt_flow/EPANET/EPANET/SRC_engines/types.h +0 -874
  56. epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +0 -53
  57. epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +0 -27
  58. epyt_flow/EPANET/EPANET-MSX/Src/hash.c +0 -107
  59. epyt_flow/EPANET/EPANET-MSX/Src/hash.h +0 -28
  60. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +0 -102
  61. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +0 -42
  62. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +0 -937
  63. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +0 -39
  64. epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +0 -204
  65. epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +0 -24
  66. epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +0 -1285
  67. epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +0 -368
  68. epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +0 -42
  69. epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +0 -586
  70. epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +0 -116
  71. epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +0 -260
  72. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +0 -175
  73. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +0 -35
  74. epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +0 -1504
  75. epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +0 -401
  76. epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +0 -791
  77. epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +0 -2010
  78. epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +0 -400
  79. epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +0 -422
  80. epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +0 -1164
  81. epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +0 -551
  82. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +0 -524
  83. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +0 -56
  84. epyt_flow/EPANET/EPANET-MSX/Src/newton.c +0 -158
  85. epyt_flow/EPANET/EPANET-MSX/Src/newton.h +0 -34
  86. epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +0 -287
  87. epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +0 -39
  88. epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +0 -293
  89. epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +0 -35
  90. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +0 -816
  91. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +0 -29
  92. epyt_flow/EPANET/EPANET-MSX/readme.txt +0 -14
  93. epyt_flow/EPANET/compile_linux.sh +0 -4
  94. epyt_flow/EPANET/compile_macos.sh +0 -4
  95. epyt_flow/simulation/backend/__init__.py +0 -1
  96. epyt_flow/simulation/backend/my_epyt.py +0 -1101
  97. epyt_flow-0.14.2.dist-info/RECORD +0 -142
  98. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/WHEEL +0 -0
  99. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/licenses/LICENSE +0 -0
  100. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0.dist-info}/top_level.txt +0 -0
@@ -1,864 +0,0 @@
1
- /*
2
- ******************************************************************************
3
- Project: OWA EPANET
4
- Version: 2.2
5
- Module: input2.c
6
- Description: reads and interprets network data from an EPANET input file
7
- Authors: see AUTHORS
8
- Copyright: see AUTHORS
9
- License: see LICENSE
10
- Last Updated: 10/29/2019
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 "hash.h"
22
- #include "text.h"
23
-
24
- #define MAXERRS 10 // Max. input errors reported
25
-
26
- extern char *SectTxt[]; // Input section keywords (see ENUMSTXT.H)
27
-
28
- // Exported functions
29
- int addnodeID(Network *n, int, char *);
30
- int addlinkID(Network *n, int, char *);
31
-
32
- // Imported functions
33
- extern int powercurve(double, double, double, double, double, double *,
34
- double *, double *);
35
-
36
- // Local functions
37
- static int newline(Project *, int, char *);
38
- static int addpattern(Network *, char *);
39
- static int addcurve(Network *, char *);
40
- static int unlinked(Project *);
41
- static int getpumpparams(Project *);
42
- static void inperrmsg(Project *, int, int, char *);
43
-
44
-
45
- int netsize(Project *pr)
46
- /*
47
- **--------------------------------------------------------------
48
- ** Input: none
49
- ** Output: returns error code
50
- ** Purpose: determines number of network objects
51
- **--------------------------------------------------------------
52
- */
53
- {
54
- Parser *parser = &pr->parser;
55
-
56
- char line[MAXLINE + 1]; // Line from input data file
57
- char *tok; // First token of line
58
- int sect, newsect; // Input data sections
59
- int errcode = 0; // Error code
60
- Spattern *pattern;
61
-
62
- // Initialize object counts
63
- parser->MaxJuncs = 0;
64
- parser->MaxTanks = 0;
65
- parser->MaxPipes = 0;
66
- parser->MaxPumps = 0;
67
- parser->MaxValves = 0;
68
- parser->MaxControls = 0;
69
- parser->MaxRules = 0;
70
- parser->MaxCurves = 0;
71
- sect = -1;
72
-
73
-
74
- // Add a "dummy" time pattern with index of 0 and a single multiplier
75
- // of 1.0 to be used by all demands not assigned a pattern
76
- pr->network.Npats = -1;
77
- errcode = addpattern(&pr->network, "");
78
- if (errcode) return errcode;
79
- pattern = &pr->network.Pattern[0];
80
- pattern->Length = 1;
81
- pattern[0].F = (double *)calloc(1, sizeof(double));
82
- pattern[0].F[0] = 1.0;
83
- parser->MaxPats = pr->network.Npats;
84
-
85
- // Make a pass through input file counting number of each object
86
- if (parser->InFile == NULL) return 0;
87
- while (fgets(line, MAXLINE, parser->InFile) != NULL)
88
- {
89
- // Skip blank lines & those beginning with a comment
90
- tok = strtok(line, SEPSTR);
91
- if (tok == NULL) continue;
92
- if (*tok == ';') continue;
93
-
94
- // Check if line begins with a new section heading
95
- if (tok[0] == '[')
96
- {
97
- newsect = findmatch(tok, SectTxt);
98
- if (newsect >= 0)
99
- {
100
- sect = newsect;
101
- if (sect == _END) break;
102
- continue;
103
- }
104
- else continue;
105
- }
106
-
107
- // Add to count of current object
108
- switch (sect)
109
- {
110
- case _JUNCTIONS: parser->MaxJuncs++; break;
111
- case _RESERVOIRS:
112
- case _TANKS: parser->MaxTanks++; break;
113
- case _PIPES: parser->MaxPipes++; break;
114
- case _PUMPS: parser->MaxPumps++; break;
115
- case _VALVES: parser->MaxValves++; break;
116
- case _CONTROLS: parser->MaxControls++; break;
117
- case _RULES: addrule(parser,tok); break;
118
- case _PATTERNS:
119
- errcode = addpattern(&pr->network, tok);
120
- parser->MaxPats = pr->network.Npats;
121
- break;
122
- case _CURVES:
123
- errcode = addcurve(&pr->network, tok);
124
- parser->MaxCurves = pr->network.Ncurves;
125
- break;
126
- }
127
- if (errcode) break;
128
- }
129
-
130
- parser->MaxNodes = parser->MaxJuncs + parser->MaxTanks;
131
- parser->MaxLinks = parser->MaxPipes + parser->MaxPumps + parser->MaxValves;
132
- if (parser->MaxPats < 1) parser->MaxPats = 1;
133
- if (!errcode)
134
- {
135
- if (parser->MaxJuncs < 1) errcode = 223; // Not enough nodes
136
- else if (parser->MaxTanks == 0) errcode = 224; // No tanks
137
- }
138
- return errcode;
139
- }
140
-
141
- int readdata(Project *pr)
142
- /*
143
- **--------------------------------------------------------------
144
- ** Input: none
145
- ** Output: returns error code
146
- ** Purpose: reads contents of input data file
147
- **--------------------------------------------------------------
148
- */
149
- {
150
- Network *net = &pr->network;
151
- Parser *parser = &pr->parser;
152
-
153
- char line[MAXLINE + 1], // Line from input data file
154
- wline[MAXLINE + 1]; // Working copy of input line
155
- int sect, newsect, // Data sections
156
- errcode = 0, // Error code
157
- inperr, errsum; // Error code & total error count
158
-
159
- // Allocate input buffer
160
- parser->X = (double *)calloc(MAXTOKS, sizeof(double));
161
- ERRCODE(MEMCHECK(parser->X));
162
- if (errcode) return errcode;
163
-
164
- // Initialize actual number of network components
165
- parser->Ntitle = 0;
166
- net->Nnodes = 0;
167
- net->Njuncs = 0;
168
- net->Ntanks = 0;
169
- net->Nlinks = 0;
170
- net->Npipes = 0;
171
- net->Npumps = 0;
172
- net->Nvalves = 0;
173
- net->Ncontrols = 0;
174
- net->Nrules = 0;
175
-
176
- // Patterns & Curves were created previously in netsize()
177
- parser->MaxPats = net->Npats;
178
- parser->MaxCurves = net->Ncurves;
179
- parser->PrevPat = NULL;
180
- parser->PrevCurve = NULL;
181
-
182
- // Initialize full line comment, input data section and error count
183
- parser->LineComment[0] = '\0';
184
- sect = -1;
185
- errsum = 0;
186
-
187
- // Read each line from input file
188
- while (fgets(line, MAXLINE, parser->InFile) != NULL)
189
- {
190
- // Make copy of line and scan for tokens
191
- strcpy(wline, line);
192
- parser->Ntokens = gettokens(wline, parser->Tok, MAXTOKS, parser->Comment);
193
-
194
- // Skip blank lines and those filled with a comment
195
- parser->ErrTok = -1;
196
- if (parser->Ntokens == 0)
197
- {
198
- // Store full line comment for Patterns and Curves
199
- if (sect == _PATTERNS || sect == _CURVES)
200
- {
201
- strncpy(parser->LineComment, parser->Comment, MAXMSG);
202
- }
203
- continue;
204
- }
205
-
206
- // Apply full line comment for Patterns and Curves
207
- if (sect == _PATTERNS || sect == _CURVES)
208
- {
209
- strcpy(parser->Comment, parser->LineComment);
210
- }
211
- parser->LineComment[0] = '\0';
212
-
213
- // Check if max. line length exceeded
214
- if (strlen(line) >= MAXLINE)
215
- {
216
- sprintf(pr->Msg, "%s section: %s", geterrmsg(214, pr->Msg), SectTxt[sect]);
217
- writeline(pr, pr->Msg);
218
- writeline(pr, line);
219
- errsum++;
220
- }
221
-
222
- // Check if at start of a new input section
223
- if (parser->Tok[0][0] == '[')
224
- {
225
- newsect = findmatch(parser->Tok[0], SectTxt);
226
- if (newsect >= 0)
227
- {
228
- sect = newsect;
229
- if (sect == _END) break;
230
- continue;
231
- }
232
- else
233
- {
234
- inperrmsg(pr, 201, sect, line);
235
- errsum++;
236
- break;
237
- }
238
- }
239
-
240
- // Otherwise process next line of input in current section
241
- else
242
- {
243
- if (sect >= 0)
244
- {
245
- inperr = newline(pr, sect, line);
246
- if (inperr > 0)
247
- {
248
- inperrmsg(pr, inperr, sect, line);
249
- errsum++;
250
- }
251
- }
252
- else
253
- {
254
- errcode = 200;
255
- break;
256
- }
257
- }
258
-
259
- // Stop if reach end of file or max. error count
260
- if (errsum == MAXERRS) break;
261
- }
262
-
263
- // Check for errors
264
- if (errsum > 0) errcode = 200;
265
-
266
- // Check for unlinked nodes
267
- if (!errcode) errcode = unlinked(pr);
268
-
269
- // Determine pump curve parameters
270
- if (!errcode) errcode = getpumpparams(pr);
271
-
272
- // Free input buffer
273
- free(parser->X);
274
- return errcode;
275
- }
276
-
277
- int newline(Project *pr, int sect, char *line)
278
- /*
279
- **--------------------------------------------------------------
280
- ** Input: sect = current section of input file
281
- ** *line = line read from input file
282
- ** Output: returns error code or 0 if no error found
283
- ** Purpose: processes a new line of data from input file
284
- **
285
- ** Note: The xxxdata() functions appear in INPUT3.c.
286
- **--------------------------------------------------------------
287
- */
288
- {
289
- Parser *parser = &pr->parser;
290
- int n;
291
-
292
- switch (sect)
293
- {
294
- case _TITLE:
295
- if (parser->Ntitle < 3)
296
- {
297
- n = (int)strlen(line);
298
- if (line[n - 1] == 10)
299
- line[n - 1] = '\0';
300
- strncpy(pr->Title[parser->Ntitle], line, TITLELEN);
301
- parser->Ntitle++;
302
- }
303
- return 0;
304
- case _JUNCTIONS: return (juncdata(pr));
305
- case _RESERVOIRS:
306
- case _TANKS: return (tankdata(pr));
307
- case _PIPES: return (pipedata(pr));
308
- case _PUMPS: return (pumpdata(pr));
309
- case _VALVES: return (valvedata(pr));
310
- case _PATTERNS: return (patterndata(pr));
311
- case _CURVES: return (curvedata(pr));
312
- case _DEMANDS: return (demanddata(pr));
313
- case _CONTROLS: return (controldata(pr));
314
- case _RULES:
315
- if (ruledata(pr) > 0)
316
- {
317
- ruleerrmsg(pr);
318
- return 200;
319
- }
320
- else return 0;
321
- case _SOURCES: return (sourcedata(pr));
322
- case _EMITTERS: return (emitterdata(pr));
323
- case _QUALITY: return (qualdata(pr));
324
- case _STATUS: return (statusdata(pr));
325
- case _ROUGHNESS: return (0);
326
- case _ENERGY: return (energydata(pr));
327
- case _REACTIONS: return (reactdata(pr));
328
- case _MIXING: return (mixingdata(pr));
329
- case _REPORT: return (reportdata(pr));
330
- case _TIMES: return (timedata(pr));
331
- case _OPTIONS: return (optiondata(pr));
332
- case _COORDS: return (coordata(pr));
333
- case _VERTICES: return (vertexdata(pr));
334
-
335
- // Data in these sections are not used for any computations
336
- case _LABELS:
337
- case _TAGS:
338
- case _BACKDROP:
339
- return (0);
340
- }
341
- return 201;
342
- }
343
-
344
- int getpumpparams(Project *pr)
345
- /*
346
- **-------------------------------------------------------------
347
- ** Input: none
348
- ** Output: returns error code
349
- ** Purpose: computes pump curve coefficients for all pumps
350
- **--------------------------------------------------------------
351
- */
352
- {
353
- Network *net = &pr->network;
354
- int i, k, errcode = 0;
355
- char errmsg[MAXMSG+1];
356
-
357
- for (i = 1; i <= net->Npumps; i++)
358
- {
359
- errcode = updatepumpparams(pr, i);
360
- if (errcode)
361
- {
362
- k = net->Pump[i].Link;
363
- sprintf(pr->Msg, "Error %d: %s %s",
364
- errcode, geterrmsg(errcode, errmsg), net->Link[k].ID);
365
- writeline(pr, pr->Msg);
366
- return 200;
367
- }
368
- }
369
- return 0;
370
- }
371
-
372
- int updatepumpparams(Project *pr, int pumpindex)
373
- /*
374
- **-------------------------------------------------------------
375
- ** Input: pumpindex = index of a pump
376
- ** Output: returns error code
377
- ** Purpose: computes & checks a pump's head curve coefficients
378
- **--------------------------------------------------------------
379
- */
380
- {
381
- Network *net = &pr->network;
382
- Spump *pump;
383
- Scurve *curve;
384
-
385
- int m;
386
- int curveindex;
387
- int npts = 0;
388
- int errcode = 0;
389
- double a, b, c, h0 = 0.0, h1 = 0.0, h2 = 0.0, q1 = 0.0, q2 = 0.0;
390
-
391
- pump = &net->Pump[pumpindex];
392
- if (pump->Ptype == CONST_HP) // Constant Hp pump
393
- {
394
- pump->H0 = 0.0;
395
- pump->R = -8.814 * net->Link[pump->Link].Km;
396
- pump->N = -1.0;
397
- pump->Hmax = BIG; // No head limit
398
- pump->Qmax = BIG; // No flow limit
399
- pump->Q0 = 1.0; // Init. flow = 1 cfs
400
- return errcode;
401
- }
402
-
403
- else if (pump->Ptype == NOCURVE) // Pump curve specified
404
- {
405
- curveindex = pump->Hcurve;
406
- if (curveindex == 0) return 226;
407
- curve = &net->Curve[curveindex];
408
- curve->Type = PUMP_CURVE;
409
- npts = curve->Npts;
410
-
411
- // Generic power function curve
412
- if (npts == 1)
413
- {
414
- pump->Ptype = POWER_FUNC;
415
- q1 = curve->X[0];
416
- h1 = curve->Y[0];
417
- h0 = 1.33334 * h1;
418
- q2 = 2.0 * q1;
419
- h2 = 0.0;
420
- }
421
-
422
- // 3 point curve with shutoff head
423
- else if (npts == 3 && curve->X[0] == 0.0)
424
- {
425
- pump->Ptype = POWER_FUNC;
426
- h0 = curve->Y[0];
427
- q1 = curve->X[1];
428
- h1 = curve->Y[1];
429
- q2 = curve->X[2];
430
- h2 = curve->Y[2];
431
- }
432
-
433
- // Custom pump curve
434
- else
435
- {
436
- pump->Ptype = CUSTOM;
437
- for (m = 1; m < npts; m++)
438
- {
439
- if (curve->Y[m] >= curve->Y[m - 1]) return 227;
440
- }
441
- pump->Qmax = curve->X[npts - 1];
442
- pump->Q0 = (curve->X[0] + pump->Qmax) / 2.0;
443
- pump->Hmax = curve->Y[0];
444
- }
445
-
446
- // Compute shape factors & limits of power function curves
447
- if (pump->Ptype == POWER_FUNC)
448
- {
449
- if (!powercurve(h0, h1, h2, q1, q2, &a, &b, &c)) return 227;
450
- else
451
- {
452
- pump->H0 = -a;
453
- pump->R = -b;
454
- pump->N = c;
455
- pump->Q0 = q1;
456
- pump->Qmax = pow((-a / b), (1.0 / c));
457
- pump->Hmax = h0;
458
- }
459
- }
460
- }
461
- return 0;
462
- }
463
-
464
-
465
- int addnodeID(Network *net, int n, char *id)
466
- /*
467
- **-------------------------------------------------------------
468
- ** Input: n = node index
469
- ** id = ID label
470
- ** Output: returns 0 if ID already in use, 1 if not
471
- ** Purpose: adds a node ID to the Node Hash Table
472
- **--------------------------------------------------------------
473
- */
474
- {
475
- if (findnode(net,id))
476
- return 215; // duplicate id
477
- if (strlen(id) > MAXID)
478
- return 252; // invalid format (too long)
479
- strncpy(net->Node[n].ID, id, MAXID);
480
- hashtable_insert(net->NodeHashTable, net->Node[n].ID, n);
481
- return 0;
482
- }
483
-
484
- int addlinkID(Network *net, int n, char *id)
485
- /*
486
- **-------------------------------------------------------------
487
- ** Input: n = link index
488
- ** id = ID label
489
- ** Output: returns 0 if ID already in use, 1 if not
490
- ** Purpose: adds a link ID to the Link Hash Table
491
- **--------------------------------------------------------------
492
- */
493
- {
494
- if (findlink(net,id))
495
- return 215; // duplicate id
496
- if (strlen(id) > MAXID)
497
- return 252; // invalid formt (too long);
498
- strncpy(net->Link[n].ID, id, MAXID);
499
- hashtable_insert(net->LinkHashTable, net->Link[n].ID, n);
500
- return 0;
501
- }
502
-
503
- int addpattern(Network *network, char *id)
504
- /*
505
- **-------------------------------------------------------------
506
- ** Input: id = pattern ID label
507
- ** Output: returns error code
508
- ** Purpose: adds a new pattern to the database
509
- **--------------------------------------------------------------
510
- */
511
- {
512
- int n = network->Npats;
513
- Spattern *pattern;
514
-
515
- // Check if pattern was already created
516
- if (n > 0)
517
- {
518
- if (strcmp(id, network->Pattern[n].ID) == 0) return 0;
519
- if (findpattern(network, id) > 0) return 0;
520
- }
521
- if (strlen(id) > MAXID) return 252;
522
-
523
- // Update pattern count & add a new pattern to the database
524
- n = n + 2;
525
- network->Pattern = (Spattern *)realloc(network->Pattern, n * sizeof(Spattern));
526
- if (network->Pattern == NULL) return 101;
527
- (network->Npats)++;
528
-
529
- // Initialize the pattern
530
- pattern = &network->Pattern[network->Npats];
531
- strncpy(pattern->ID, id, MAXID);
532
- pattern->Comment = NULL;
533
- pattern->Length = 0;
534
- pattern->F = NULL;
535
- return 0;
536
- }
537
-
538
- int addcurve(Network *network, char *id)
539
- /*
540
- **-------------------------------------------------------------
541
- ** Input: id = curve ID label
542
- ** Output: returns error code
543
- ** Purpose: adds a new curve to the database
544
- **--------------------------------------------------------------
545
- */
546
- {
547
- int n = network->Ncurves;
548
- Scurve *curve;
549
-
550
- // Check if was already created
551
- if (n > 0)
552
- {
553
- if (strcmp(id, network->Curve[n].ID) == 0) return 0;
554
- if (findcurve(network, id) > 0) return 0;
555
- }
556
- if (strlen(id) > MAXID) return 252;
557
-
558
- n = n + 2;
559
- network->Curve = (Scurve *)realloc(network->Curve, n * sizeof(Scurve));
560
- if (network->Curve == NULL) return 101;
561
- (network->Ncurves)++;
562
-
563
- // Initialize the curve
564
- curve = &network->Curve[network->Ncurves];
565
- strncpy(curve->ID, id, MAXID);
566
- curve->Type = GENERIC_CURVE;
567
- curve->Comment = NULL;
568
- curve->Capacity = 0;
569
- curve->Npts = 0;
570
- curve->X = NULL;
571
- curve->Y = NULL;
572
- return 0;
573
- }
574
-
575
- int unlinked(Project *pr)
576
- /*
577
- **--------------------------------------------------------------
578
- ** Input: none
579
- ** Output: returns error code if any unlinked junctions found
580
- ** Purpose: checks for unlinked junctions in network
581
- **
582
- ** NOTE: unlinked tanks have no effect on computations.
583
- **--------------------------------------------------------------
584
- */
585
- {
586
- Network *net = &pr->network;
587
- int *marked;
588
- int i, err, errcode;
589
-
590
- errcode = 0;
591
- err = 0;
592
-
593
- // Create an array to record number of links incident on each node
594
- marked = (int *)calloc(net->Nnodes + 1, sizeof(int));
595
- ERRCODE(MEMCHECK(marked));
596
- if (errcode) return errcode;
597
- memset(marked, 0, (net->Nnodes + 1) * sizeof(int));
598
-
599
- // Mark end nodes of each link
600
- for (i = 1; i <= net->Nlinks; i++)
601
- {
602
- marked[net->Link[i].N1]++;
603
- marked[net->Link[i].N2]++;
604
- }
605
-
606
- // Check each junction
607
- for (i = 1; i <= net->Njuncs; i++)
608
- {
609
- // If not marked then error
610
- if (marked[i] == 0)
611
- {
612
- err++;
613
- sprintf(pr->Msg, "Error 233: %s %s", geterrmsg(233, pr->Msg), net->Node[i].ID);
614
- writeline(pr, pr->Msg);
615
- }
616
- if (err >= MAXERRS) break;
617
- }
618
- if (err > 0) errcode = 200;
619
- free(marked);
620
- return errcode;
621
- }
622
-
623
- int findmatch(char *line, char *keyword[])
624
- /*
625
- **--------------------------------------------------------------
626
- ** Input: *line = line from input file
627
- ** *keyword[] = list of NULL terminated keywords
628
- ** Output: returns index of matching keyword or
629
- ** -1 if no match found
630
- ** Purpose: determines which keyword appears on input line
631
- **--------------------------------------------------------------
632
- */
633
- {
634
- int i = 0;
635
- while (keyword[i] != NULL)
636
- {
637
- if (match(line, keyword[i])) return i;
638
- i++;
639
- }
640
- return -1;
641
- }
642
-
643
- int match(const char *str, const char *substr)
644
- /*
645
- **--------------------------------------------------------------
646
- ** Input: *str = string being searched
647
- ** *substr = substring being searched for
648
- ** Output: returns 1 if substr found in str, 0 if not
649
- ** Purpose: sees if substr matches any part of str
650
- **
651
- ** (Not case sensitive)
652
- **--------------------------------------------------------------
653
- */
654
- {
655
- int i, j;
656
-
657
- // Fail if substring is empty
658
- if (!substr[0]) return 0;
659
-
660
- // Skip leading blanks of str
661
- for (i = 0; str[i]; i++)
662
- {
663
- if (str[i] != ' ') break;
664
- }
665
-
666
- // Check if substr matches remainder of str
667
- for (j = 0; substr[j]; i++, j++)
668
- {
669
- if (!str[i] || UCHAR(str[i]) != UCHAR(substr[j])) return 0;
670
- }
671
- return 1;
672
- }
673
-
674
- int gettokens(char *s, char** Tok, int maxToks, char *comment)
675
- /*
676
- **--------------------------------------------------------------
677
- ** Input: *s = string to be tokenized
678
- ** Output: returns number of tokens in s
679
- ** Purpose: scans string for tokens, saving pointers to them
680
- ** in module global variable Tok[]
681
- **
682
- ** Tokens can be separated by the characters listed in SEPSTR
683
- ** (spaces, tabs, newline, carriage return) which is defined
684
- ** in TYPES.H. Text between quotes is treated as a single token.
685
- **--------------------------------------------------------------
686
- */
687
- {
688
- int n;
689
- size_t len, m;
690
- char *c, *c2;
691
-
692
- // clear comment
693
- comment[0] = '\0';
694
-
695
- // Begin with no tokens
696
- for (n=0; n<maxToks; n++) Tok[n] = NULL;
697
- n = 0;
698
-
699
- // Truncate s at start of comment
700
- c = strchr(s,';');
701
- if (c)
702
- {
703
- c2 = c+1;
704
- if (c2)
705
- {
706
- // there is a comment here, after the semi-colon.
707
- len = strlen(c2);
708
- if (len > 0)
709
- {
710
- len = strcspn(c2, "\n\r");
711
- len = MIN(len, MAXMSG);
712
- strncpy(comment, c2, len);
713
- comment[MIN(len,MAXMSG)] = '\0';
714
- }
715
- }
716
- *c = '\0';
717
- }
718
- len = (int)strlen(s);
719
-
720
- // Scan s for tokens until nothing left
721
- while (len > 0 && n < MAXTOKS)
722
- {
723
- m = (int)strcspn(s,SEPSTR); // Find token length
724
- if (m == len) // s is last token
725
- {
726
- Tok[n] = s;
727
- n++;
728
- break;
729
- }
730
- len -= m+1; // Update length of s
731
- if (m == 0) s++; // No token found
732
- else
733
- {
734
- if (*s == '"') // Token begins with quote
735
- {
736
- s++; // Start token after quote
737
- m = (int)strcspn(s,"\"\n\r"); // Find end quote (or EOL)
738
- }
739
- s[m] = '\0'; // Null-terminate the token
740
- Tok[n] = s; // Save pointer to token
741
- n++; // Update token count
742
- s += m+1; // Begin next token
743
- }
744
- }
745
- return n;
746
- }
747
-
748
- double hour(char *time, char *units)
749
- /*
750
- **---------------------------------------------------------
751
- ** Input: *time = string containing a time value
752
- ** *units = string containing time units
753
- ** Output: returns numerical value of time in hours,
754
- ** or -1 if an error occurs
755
- ** Purpose: converts time from units to hours
756
- **---------------------------------------------------------
757
- */
758
- {
759
- int n;
760
- double y[3];
761
- char *s;
762
-
763
- // Separate clock time into hrs, min, sec
764
- for (n = 0; n < 3; n++) y[n] = 0.0;
765
- n = 0;
766
- s = strtok(time, ":");
767
- while (s != NULL && n <= 3)
768
- {
769
- if (!getfloat(s, &y[n])) return -1.0;
770
- s = strtok(NULL, ":");
771
- n++;
772
- }
773
-
774
- // If decimal time with units attached then convert to hours
775
- if (n == 1)
776
- {
777
- if (strlen(units) == 0) return (y[0]);
778
- if (match(units, w_SECONDS)) return (y[0] / 3600.0);
779
- if (match(units, w_MINUTES)) return (y[0] / 60.0);
780
- if (match(units, w_HOURS)) return (y[0]);
781
- if (match(units, w_DAYS)) return (y[0] * 24.0);
782
- }
783
-
784
- // Convert hh:mm:ss format to decimal hours
785
- if (n > 1) y[0] = y[0] + y[1] / 60.0 + y[2] / 3600.0;
786
-
787
- // If am/pm attached then adjust hour accordingly
788
- // (12 am is midnight, 12 pm is noon)
789
- if (units[0] == '\0') return y[0];
790
- if (match(units, w_AM))
791
- {
792
- if (y[0] >= 13.0) return -1.0;
793
- if (y[0] >= 12.0) return (y[0] - 12.0);
794
- else return (y[0]);
795
- }
796
- if (match(units, w_PM))
797
- {
798
- if (y[0] >= 13.0) return -1.0;
799
- if (y[0] >= 12.0) return y[0];
800
- else return (y[0] + 12.0);
801
- }
802
- return -1.0;
803
- }
804
-
805
- int getfloat(char *s, double *y)
806
- /*
807
- **-----------------------------------------------------------
808
- ** Input: *s = character string
809
- ** Output: *y = floating point number
810
- ** returns 1 if conversion successful, 0 if not
811
- ** Purpose: converts string to floating point number
812
- **-----------------------------------------------------------
813
- */
814
- {
815
- char *endptr;
816
- *y = (double)strtod(s, &endptr);
817
- if (*endptr > 0) return 0;
818
- return 1;
819
- }
820
-
821
- int setreport(Project *pr, char *s)
822
- /*
823
- **-----------------------------------------------------------
824
- ** Input: *s = report format command
825
- ** Output: none
826
- ** Returns: error code
827
- ** Purpose: processes a report formatting command
828
- ** issued by the ENsetreport function
829
- **-----------------------------------------------------------
830
- */
831
- {
832
- Parser *parser = &pr->parser;
833
- parser->Ntokens = gettokens(s, parser->Tok, MAXTOKS, parser->Comment);
834
- return reportdata(pr);
835
- }
836
-
837
- void inperrmsg(Project *pr, int err, int sect, char *line)
838
- /*
839
- **-------------------------------------------------------------
840
- ** Input: err = error code
841
- ** sect = input data section
842
- ** *line = line from input file
843
- ** Output: none
844
- ** Purpose: displays input reader error message
845
- **-------------------------------------------------------------
846
- */
847
- {
848
- Parser *parser = &pr->parser;
849
-
850
- char errStr[MAXMSG + 1] = "";
851
- char tok[MAXMSG + 1];
852
-
853
- // Get token associated with input error
854
- if (parser->ErrTok >= 0) strcpy(tok, parser->Tok[parser->ErrTok]);
855
- else strcpy(tok, "");
856
-
857
- // write error message to report file
858
- sprintf(pr->Msg, "Error %d: %s %s in %s section:",
859
- err, geterrmsg(err, errStr), tok, SectTxt[sect]);
860
- writeline(pr, pr->Msg);
861
-
862
- // Echo input line
863
- writeline(pr, line);
864
- }