epyt-flow 0.14.2__py3-none-any.whl → 0.15.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. epyt_flow/VERSION +1 -1
  2. epyt_flow/__init__.py +0 -37
  3. epyt_flow/data/benchmarks/battledim.py +2 -2
  4. epyt_flow/data/benchmarks/leakdb.py +12 -9
  5. epyt_flow/gym/scenario_control_env.py +32 -33
  6. epyt_flow/simulation/events/actuator_events.py +24 -18
  7. epyt_flow/simulation/events/leakages.py +59 -57
  8. epyt_flow/simulation/events/quality_events.py +21 -30
  9. epyt_flow/simulation/events/system_event.py +3 -3
  10. epyt_flow/simulation/scada/complex_control.py +14 -12
  11. epyt_flow/simulation/scada/custom_control.py +22 -21
  12. epyt_flow/simulation/scada/scada_data.py +107 -104
  13. epyt_flow/simulation/scada/simple_control.py +38 -31
  14. epyt_flow/simulation/scenario_simulator.py +367 -395
  15. epyt_flow/simulation/sensor_config.py +31 -32
  16. epyt_flow/topology.py +11 -10
  17. epyt_flow/uncertainty/model_uncertainty.py +146 -122
  18. epyt_flow/utils.py +0 -66
  19. epyt_flow/visualization/visualization_utils.py +2 -4
  20. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/METADATA +12 -18
  21. epyt_flow-0.15.0b1.dist-info/RECORD +65 -0
  22. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +0 -28
  23. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +0 -21
  24. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +0 -18
  25. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +0 -134
  26. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +0 -5578
  27. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +0 -865
  28. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +0 -131
  29. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +0 -73
  30. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +0 -193
  31. epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +0 -1000
  32. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +0 -177
  33. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +0 -28
  34. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +0 -1151
  35. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +0 -1117
  36. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +0 -720
  37. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +0 -476
  38. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +0 -431
  39. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +0 -1786
  40. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +0 -468
  41. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +0 -810
  42. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +0 -707
  43. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +0 -864
  44. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +0 -2170
  45. epyt_flow/EPANET/EPANET/SRC_engines/main.c +0 -93
  46. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +0 -142
  47. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +0 -24
  48. epyt_flow/EPANET/EPANET/SRC_engines/output.c +0 -852
  49. epyt_flow/EPANET/EPANET/SRC_engines/project.c +0 -1359
  50. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +0 -685
  51. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +0 -743
  52. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +0 -694
  53. epyt_flow/EPANET/EPANET/SRC_engines/report.c +0 -1489
  54. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +0 -1362
  55. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +0 -871
  56. epyt_flow/EPANET/EPANET/SRC_engines/text.h +0 -497
  57. epyt_flow/EPANET/EPANET/SRC_engines/types.h +0 -874
  58. epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +0 -53
  59. epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +0 -27
  60. epyt_flow/EPANET/EPANET-MSX/Src/hash.c +0 -107
  61. epyt_flow/EPANET/EPANET-MSX/Src/hash.h +0 -28
  62. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +0 -102
  63. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +0 -42
  64. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +0 -937
  65. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +0 -39
  66. epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +0 -204
  67. epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +0 -24
  68. epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +0 -1285
  69. epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +0 -368
  70. epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +0 -42
  71. epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +0 -586
  72. epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +0 -116
  73. epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +0 -260
  74. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +0 -175
  75. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +0 -35
  76. epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +0 -1504
  77. epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +0 -401
  78. epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +0 -791
  79. epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +0 -2010
  80. epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +0 -400
  81. epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +0 -422
  82. epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +0 -1164
  83. epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +0 -551
  84. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +0 -524
  85. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +0 -56
  86. epyt_flow/EPANET/EPANET-MSX/Src/newton.c +0 -158
  87. epyt_flow/EPANET/EPANET-MSX/Src/newton.h +0 -34
  88. epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +0 -287
  89. epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +0 -39
  90. epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +0 -293
  91. epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +0 -35
  92. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +0 -816
  93. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +0 -29
  94. epyt_flow/EPANET/EPANET-MSX/readme.txt +0 -14
  95. epyt_flow/EPANET/compile_linux.sh +0 -4
  96. epyt_flow/EPANET/compile_macos.sh +0 -4
  97. epyt_flow/simulation/backend/__init__.py +0 -1
  98. epyt_flow/simulation/backend/my_epyt.py +0 -1101
  99. epyt_flow-0.14.2.dist-info/RECORD +0 -142
  100. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/WHEEL +0 -0
  101. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/licenses/LICENSE +0 -0
  102. {epyt_flow-0.14.2.dist-info → epyt_flow-0.15.0b1.dist-info}/top_level.txt +0 -0
@@ -1,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
- }