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,1489 +0,0 @@
1
- /*
2
- ******************************************************************************
3
- Project: OWA EPANET
4
- Version: 2.2
5
- Module: report.c
6
- Description: procedures for writing formatted text to a report file
7
- Authors: see AUTHORS
8
- Copyright: see AUTHORS
9
- License: see LICENSE
10
- Last Updated: 07/22/2019
11
- ******************************************************************************
12
- */
13
-
14
- #include <stdlib.h>
15
- #include <stdio.h>
16
- #include <string.h>
17
-
18
- #ifdef _WIN32
19
- #define snprintf _snprintf
20
- #endif
21
-
22
- #include <math.h>
23
- #include <time.h>
24
-
25
- #include "types.h"
26
- #include "funcs.h"
27
- #include "hash.h"
28
- #include "text.h"
29
-
30
- #define MAXCOUNT 10 // Max. # of disconnected nodes listed
31
-
32
- // Defined in ENUMSTXT.H
33
- extern char *NodeTxt[];
34
- extern char *LinkTxt[];
35
- extern char *StatTxt[];
36
- extern char *TstatTxt[];
37
- extern char *RptFormTxt[];
38
- extern char *DemandModelTxt[];
39
-
40
- // Local functions
41
- typedef REAL4 *Pfloat;
42
- static void writenodetable(Project *, Pfloat *);
43
- static void writelinktable(Project *, Pfloat *);
44
- static void writeenergy(Project *);
45
- static int writeresults(Project *);
46
- static int disconnected(Project *);
47
- static void marknodes(Project *, int, int *, char *);
48
- static void getclosedlink(Project *, int, char *);
49
- static void writelimits(Project *, int, int);
50
- static int checklimits(Report *, double *, int, int);
51
- static char *fillstr(char *, char, int);
52
- static int getnodetype(Network *, int);
53
-
54
- int clearreport(Project *pr)
55
- /*
56
- **------------------------------------------------------
57
- ** Input: none
58
- ** Output: returns error code
59
- ** Purpose: clears contents of a project's report file
60
- **------------------------------------------------------
61
- */
62
- {
63
- Report *rpt = &pr->report;
64
- if (rpt->RptFile == NULL) return 0;
65
- if (freopen(rpt->Rpt1Fname, "w", rpt->RptFile) == NULL) return 303;
66
- writelogo(pr);
67
- return 0;
68
- }
69
-
70
- int copyreport(Project* pr, char *filename)
71
- /*
72
- **------------------------------------------------------
73
- ** Input: filename = name of file to copy to
74
- ** Output: returns error code
75
- ** Purpose: copies contents of a project's report file
76
- **------------------------------------------------------
77
- */
78
- {
79
- FILE *tfile;
80
- int c;
81
- Report *rpt = &pr->report;
82
-
83
- // Check that project's report file exists
84
- if (rpt->RptFile == NULL) return 0;
85
-
86
- // Open the new destination file
87
- tfile = fopen(filename, "w");
88
- if (tfile == NULL) return 303;
89
-
90
- // Re-open project's report file in read mode
91
- fclose(rpt->RptFile);
92
- rpt->RptFile = fopen(rpt->Rpt1Fname, "r");
93
-
94
- // Copy contents of project's report file
95
- if (rpt->RptFile)
96
- {
97
- while ((c = fgetc(rpt->RptFile)) != EOF) fputc(c, tfile);
98
- fclose(rpt->RptFile);
99
- }
100
-
101
- // Close destination file
102
- fclose(tfile);
103
-
104
- // Re-open project's report file in append mode
105
- rpt->RptFile = fopen(rpt->Rpt1Fname, "a");
106
- if (rpt->RptFile == NULL) return 303;
107
- return 0;
108
- }
109
-
110
- int writereport(Project *pr)
111
- /*
112
- **------------------------------------------------------
113
- ** Input: none
114
- ** Output: returns error code
115
- ** Purpose: writes formatted output report to file
116
- **------------------------------------------------------
117
- */
118
- {
119
- Report *rpt = &pr->report;
120
- Parser *parser = &pr->parser;
121
-
122
- int tflag;
123
- FILE *tfile;
124
- int errcode = 0;
125
-
126
- // If no secondary report file specified then
127
- // write formatted output to primary report file
128
- rpt->Fprinterr = FALSE;
129
- if (rpt->Rptflag && strlen(rpt->Rpt2Fname) == 0 && rpt->RptFile != NULL)
130
- {
131
- if (rpt->Energyflag) writeenergy(pr);
132
- errcode = writeresults(pr);
133
- }
134
-
135
- // A secondary report file was specified
136
- else if (strlen(rpt->Rpt2Fname) > 0)
137
- {
138
- // If secondary report file has same name as either input
139
- // or primary report file then use primary report file.
140
- if (strcomp(rpt->Rpt2Fname, parser->InpFname) ||
141
- strcomp(rpt->Rpt2Fname, rpt->Rpt1Fname))
142
- {
143
- if (rpt->Energyflag) writeenergy(pr);
144
- errcode = writeresults(pr);
145
- }
146
-
147
- // Otherwise write report to secondary report file
148
- else
149
- {
150
- // Try to open file
151
- tfile = rpt->RptFile;
152
- tflag = rpt->Rptflag;
153
- if ((rpt->RptFile = fopen(rpt->Rpt2Fname, "wt")) == NULL)
154
- {
155
- rpt->RptFile = tfile;
156
- rpt->Rptflag = tflag;
157
- errcode = 303;
158
- }
159
-
160
- // Write full formatted report to file
161
- else
162
- {
163
- rpt->Rptflag = 1;
164
- writelogo(pr);
165
- if (rpt->Summaryflag) writesummary(pr);
166
- if (rpt->Energyflag) writeenergy(pr);
167
- errcode = writeresults(pr);
168
- fclose(rpt->RptFile);
169
- rpt->RptFile = tfile;
170
- rpt->Rptflag = tflag;
171
- }
172
- }
173
- }
174
-
175
- // Special error handler for write-to-file error
176
- if (rpt->Fprinterr) errmsg(pr, 309);
177
- return errcode;
178
- }
179
-
180
- void writelogo(Project *pr)
181
- /*
182
- **--------------------------------------------------------------
183
- ** Input: none
184
- ** Output: none
185
- ** Purpose: writes program logo to report file.
186
- **--------------------------------------------------------------
187
- */
188
- {
189
- Report *rpt = &pr->report;
190
-
191
- int version;
192
- int major;
193
- int minor;
194
- char s[80];
195
- time_t timer; // time_t structure & functions time() &
196
- // ctime() are defined in time.h
197
-
198
- version = CODEVERSION;
199
- major = version / 10000;
200
- minor = (version % 10000) / 100;
201
-
202
- time(&timer);
203
- strcpy(rpt->DateStamp, ctime(&timer));
204
- rpt->PageNum = 1;
205
- rpt->LineNum = 2;
206
- fprintf(rpt->RptFile, FMT18);
207
- fprintf(rpt->RptFile, "%s", rpt->DateStamp);
208
- writeline(pr, LOGO1);
209
- writeline(pr, LOGO2);
210
- writeline(pr, LOGO3);
211
- writeline(pr, LOGO4);
212
- sprintf(s, LOGO5, major, minor);
213
- writeline(pr, s);
214
- writeline(pr, LOGO6);
215
- writeline(pr, "");
216
- }
217
-
218
- void writesummary(Project *pr)
219
- /*
220
- **--------------------------------------------------------------
221
- ** Input: none
222
- ** Output: none
223
- ** Purpose: writes summary system information to report file
224
- **--------------------------------------------------------------
225
- */
226
- {
227
- Network *net = &pr->network;
228
- Hydraul *hyd = &pr->hydraul;
229
- Quality *qual = &pr->quality;
230
- Report *rpt = &pr->report;
231
- Parser *parser = &pr->parser;
232
- Times *time = &pr->times;
233
-
234
- char s[MAXLINE + 1];
235
- int i;
236
- int nres = 0;
237
-
238
- for (i = 0; i < 3; i++)
239
- {
240
- if (strlen(pr->Title[i]) > 0)
241
- {
242
- sprintf(s, "%-.70s", pr->Title[i]);
243
- writeline(pr, s);
244
- }
245
- }
246
- writeline(pr, " ");
247
- sprintf(s, FMT19, parser->InpFname);
248
- writeline(pr, s);
249
- sprintf(s, FMT20, net->Njuncs);
250
- writeline(pr, s);
251
- for (i = 1; i <= net->Ntanks; i++) if (net->Tank[i].A == 0.0) nres++;
252
- sprintf(s, FMT21a, nres);
253
- writeline(pr, s);
254
- sprintf(s, FMT21b, net->Ntanks - nres);
255
- writeline(pr, s);
256
- sprintf(s, FMT22, net->Npipes);
257
- writeline(pr, s);
258
- sprintf(s, FMT23, net->Npumps);
259
- writeline(pr, s);
260
- sprintf(s, FMT24, net->Nvalves);
261
- writeline(pr, s);
262
- sprintf(s, FMT25, RptFormTxt[hyd->Formflag]);
263
- writeline(pr, s);
264
- sprintf(s, FMT25a, DemandModelTxt[hyd->DemandModel]);
265
- writeline(pr, s);
266
- sprintf(s, FMT26, time->Hstep * pr->Ucf[TIME], rpt->Field[TIME].Units);
267
- writeline(pr, s);
268
- sprintf(s, FMT27, hyd->Hacc);
269
- writeline(pr, s);
270
-
271
- if (hyd->HeadErrorLimit > 0.0)
272
- {
273
- sprintf(s, FMT27d, hyd->HeadErrorLimit*pr->Ucf[HEAD], rpt->Field[HEAD].Units);
274
- writeline(pr, s);
275
- }
276
- if (hyd->FlowChangeLimit > 0.0)
277
- {
278
- sprintf(s, FMT27e, hyd->FlowChangeLimit*pr->Ucf[FLOW], rpt->Field[FLOW].Units);
279
- writeline(pr, s);
280
- }
281
-
282
- sprintf(s, FMT27a, hyd->CheckFreq);
283
- writeline(pr, s);
284
- sprintf(s, FMT27b, hyd->MaxCheck);
285
- writeline(pr, s);
286
- sprintf(s, FMT27c, hyd->DampLimit);
287
- writeline(pr, s);
288
- sprintf(s, FMT28, hyd->MaxIter);
289
- writeline(pr, s);
290
-
291
- if (qual->Qualflag == NONE || time->Dur == 0.0) sprintf(s, FMT29);
292
- else if (qual->Qualflag == CHEM) sprintf(s, FMT30, qual->ChemName);
293
- else if (qual->Qualflag == TRACE) sprintf(s, FMT31, net->Node[qual->TraceNode].ID);
294
- else if (qual->Qualflag == AGE) printf(s, FMT32);
295
- writeline(pr, s);
296
- if (qual->Qualflag != NONE && time->Dur > 0)
297
- {
298
- sprintf(s, FMT33, (float)time->Qstep / 60.0);
299
- writeline(pr, s);
300
- sprintf(s, FMT34, qual->Ctol * pr->Ucf[QUALITY], rpt->Field[QUALITY].Units);
301
- writeline(pr, s);
302
- }
303
-
304
- sprintf(s, FMT36, hyd->SpGrav);
305
- writeline(pr, s);
306
- sprintf(s, FMT37a, hyd->Viscos / VISCOS);
307
- writeline(pr, s);
308
- sprintf(s, FMT37b, qual->Diffus / DIFFUS);
309
- writeline(pr, s);
310
- sprintf(s, FMT38, hyd->Dmult);
311
- writeline(pr, s);
312
- sprintf(s, FMT39, time->Dur * pr->Ucf[TIME], rpt->Field[TIME].Units);
313
- writeline(pr, s);
314
-
315
- if (rpt->Rptflag)
316
- {
317
- sprintf(s, FMT40);
318
- writeline(pr, s);
319
- if (rpt->Nodeflag == 0) writeline(pr, FMT41);
320
- if (rpt->Nodeflag == 1) writeline(pr, FMT42);
321
- if (rpt->Nodeflag == 2) writeline(pr, FMT43);
322
- writelimits(pr, DEMAND, QUALITY);
323
- if (rpt->Linkflag == 0) writeline(pr, FMT44);
324
- if (rpt->Linkflag == 1) writeline(pr, FMT45);
325
- if (rpt->Linkflag == 2) writeline(pr, FMT46);
326
- writelimits(pr, DIAM, HEADLOSS);
327
- }
328
- writeline(pr, " ");
329
- }
330
-
331
- void writehydstat(Project *pr, int iter, double relerr)
332
- /*
333
- **--------------------------------------------------------------
334
- ** Input: iter = # iterations to find hydraulic solution
335
- ** relerr = convergence error in hydraulic solution
336
- ** Output: none
337
- ** Purpose: writes hydraulic status report for solution found
338
- ** at current time period to report file
339
- **--------------------------------------------------------------
340
- */
341
- {
342
- Network *net = &pr->network;
343
- Hydraul *hyd = &pr->hydraul;
344
- Report *rpt = &pr->report;
345
- Times *time = &pr->times;
346
-
347
- int i, n;
348
- double *NodeDemand;
349
- char s1[MAXLINE + 1];
350
- char atime[13];
351
- StatusType newstat;
352
- Stank *Tank = net->Tank;
353
- Slink *Link = net->Link;
354
-
355
- // Display system status
356
- strcpy(atime, clocktime(rpt->Atime, time->Htime));
357
- if (iter > 0)
358
- {
359
- if (relerr <= hyd->Hacc) sprintf(s1, FMT58, atime, iter);
360
- else sprintf(s1, FMT59, atime, iter, relerr);
361
- writeline(pr, s1);
362
- if (hyd->DemandModel == PDA && hyd->DeficientNodes > 0)
363
- {
364
- if (hyd->DeficientNodes == 1)
365
- sprintf(s1, FMT69a, hyd->DemandReduction);
366
- else
367
- sprintf(s1, FMT69b, hyd->DeficientNodes, hyd->DemandReduction);
368
- writeline(pr, s1);
369
- }
370
- }
371
-
372
- // Display status changes for tanks:
373
- // D[n] is net inflow to tank at node n;
374
- // old tank status is stored in OldStatus[]
375
- // at indexes Nlinks+1 to Nlinks+Ntanks.
376
- for (i = 1; i <= net->Ntanks; i++)
377
- {
378
- n = net->Tank[i].Node;
379
- NodeDemand = hyd->NodeDemand;
380
- if (ABS(NodeDemand[n]) < 0.001) newstat = CLOSED;
381
- else if (NodeDemand[n] < 0.0) newstat = EMPTYING;
382
- else if (NodeDemand[n] > 0.0)
383
- {
384
- if (Tank[i].A > 0.0 && ABS(hyd->NodeHead[n] - Tank[i].Hmax) < 0.001)
385
- newstat = OVERFLOWING;
386
- else newstat = FILLING;
387
- }
388
- else newstat = hyd->OldStatus[net->Nlinks + i];
389
- if (newstat != hyd->OldStatus[net->Nlinks + i])
390
- {
391
- if (Tank[i].A > 0.0)
392
- {
393
- snprintf(s1, MAXLINE, FMT50, atime, net->Node[n].ID, StatTxt[newstat],
394
- (hyd->NodeHead[n] - net->Node[n].El) * pr->Ucf[HEAD],
395
- rpt->Field[HEAD].Units);
396
- }
397
- else
398
- {
399
- snprintf(s1, MAXLINE, FMT51, atime, net->Node[n].ID, StatTxt[newstat]);
400
- }
401
- writeline(pr, s1);
402
- hyd->OldStatus[net->Nlinks + i] = newstat;
403
- }
404
- }
405
-
406
- // Display status changes for links
407
- for (i = 1; i <= net->Nlinks; i++)
408
- {
409
- if (hyd->LinkStatus[i] != hyd->OldStatus[i])
410
- {
411
- if (time->Htime == 0)
412
- {
413
- sprintf(s1, FMT52, atime, LinkTxt[(int)net->Link[i].Type],
414
- net->Link[i].ID, StatTxt[(int)hyd->LinkStatus[i]]);
415
- }
416
- else sprintf(s1, FMT53, atime, LinkTxt[Link[i].Type], net->Link[i].ID,
417
- StatTxt[hyd->OldStatus[i]], StatTxt[hyd->LinkStatus[i]]);
418
- writeline(pr, s1);
419
- hyd->OldStatus[i] = hyd->LinkStatus[i];
420
- }
421
- }
422
- writeline(pr, " ");
423
- }
424
-
425
- void writemassbalance(Project *pr)
426
- /*
427
- **-------------------------------------------------------------
428
- ** Input: none
429
- ** Output: none
430
- ** Purpose: writes water quality mass balance ratio
431
- ** (Outflow + Final Storage) / Inflow + Initial Storage)
432
- ** to report file.
433
- **-------------------------------------------------------------
434
- */
435
- {
436
- Quality *qual = &pr->quality;
437
-
438
- char s1[MAXMSG+1];
439
- char *units[] = {"", " (mg)", " (ug)", " (hrs)"};
440
- int kunits = 0;
441
-
442
- if (qual->Qualflag == TRACE) kunits = 1;
443
- else if (qual->Qualflag == AGE) kunits = 3;
444
- else
445
- {
446
- if (match(qual->ChemUnits, "mg")) kunits = 1;
447
- else if (match(qual->ChemUnits, "ug")) kunits = 2;
448
- }
449
-
450
- snprintf(s1, MAXMSG, "Water Quality Mass Balance%s", units[kunits]);
451
- writeline(pr, s1);
452
- snprintf(s1, MAXMSG, "================================");
453
- writeline(pr, s1);
454
- snprintf(s1, MAXMSG, "Initial Mass: %12.5e", qual->MassBalance.initial);
455
- writeline(pr, s1);
456
- snprintf(s1, MAXMSG, "Mass Inflow: %12.5e", qual->MassBalance.inflow);
457
- writeline(pr, s1);
458
- snprintf(s1, MAXMSG, "Mass Outflow: %12.5e", qual->MassBalance.outflow);
459
- writeline(pr, s1);
460
- snprintf(s1, MAXMSG, "Mass Reacted: %12.5e", qual->MassBalance.reacted);
461
- writeline(pr, s1);
462
- snprintf(s1, MAXMSG, "Final Mass: %12.5e", qual->MassBalance.final);
463
- writeline(pr, s1);
464
- snprintf(s1, MAXMSG, "Mass Ratio: %-.5f", qual->MassBalance.ratio);
465
- writeline(pr, s1);
466
- snprintf(s1, MAXMSG, "================================\n");
467
- writeline(pr, s1);
468
- }
469
-
470
- void writeenergy(Project *pr)
471
- /*
472
- **-------------------------------------------------------------
473
- ** Input: none
474
- ** Output: none
475
- ** Purpose: writes energy usage report to report file
476
- **-------------------------------------------------------------
477
- */
478
- {
479
- Network *net = &pr->network;
480
- Hydraul *hyd = &pr->hydraul;
481
- Report *rpt = &pr->report;
482
-
483
- int j;
484
- double csum;
485
- char s[MAXLINE + 1];
486
- Spump *pump;
487
-
488
- if (net->Npumps == 0) return;
489
- writeline(pr, " ");
490
- writeheader(pr,ENERHDR, 0);
491
-
492
- csum = 0.0;
493
- for (j = 1; j <= net->Npumps; j++)
494
- {
495
- pump = &net->Pump[j];
496
- csum += pump->Energy.TotalCost;
497
- if (rpt->LineNum == (long)rpt->PageSize) writeheader(pr, ENERHDR, 1);
498
-
499
- sprintf(s, "%-8s %6.2f %6.2f %9.2f %9.2f %9.2f %9.2f",
500
- net->Link[pump->Link].ID, pump->Energy.TimeOnLine,
501
- pump->Energy.Efficiency, pump->Energy.KwHrsPerFlow,
502
- pump->Energy.KwHrs, pump->Energy.MaxKwatts,
503
- pump->Energy.TotalCost);
504
- writeline(pr, s);
505
- }
506
-
507
- fillstr(s, '-', 63);
508
- writeline(pr, s);
509
- sprintf(s, FMT74, "", hyd->Emax * hyd->Dcost);
510
- writeline(pr, s);
511
- sprintf(s, FMT75, "", csum + hyd->Emax * hyd->Dcost);
512
- writeline(pr, s);
513
- writeline(pr, " ");
514
- }
515
-
516
- int writeresults(Project *pr)
517
- /*
518
- **--------------------------------------------------------------
519
- ** Input: none
520
- ** Output: returns error code
521
- ** Purpose: writes simulation results to report file
522
- **--------------------------------------------------------------
523
- */
524
- {
525
- Network *net = &pr->network;
526
- Outfile *out = &pr->outfile;
527
- Report *rpt = &pr->report;
528
- Times *time = &pr->times;
529
-
530
- int j, m, n,
531
- np, // Reporting period counter
532
- nnv, // # node variables reported on
533
- nlv; // # link variables reported on
534
- int errcode = 0;
535
- Pfloat *x; // Array of pointers to floats (i.e., a 2-D array)
536
- FILE *outFile = out->OutFile;
537
-
538
- //-----------------------------------------------------------
539
- // NOTE: The OutFile contains results for 4 node variables
540
- // (demand, head, pressure, & quality) and 8 link
541
- // variables (flow, velocity, headloss, quality,
542
- // status, setting, reaction rate & friction factor)
543
- // at each reporting time.
544
- //-----------------------------------------------------------
545
-
546
- // Return if no nodes or links selected for reporting
547
- // or if no node or link report variables enabled
548
- if (!rpt->Nodeflag && !rpt->Linkflag) return errcode;
549
-
550
- nnv = 0;
551
- for (j = ELEV; j <= QUALITY; j++) nnv += rpt->Field[j].Enabled;
552
- nlv = 0;
553
- for (j = LENGTH; j <= FRICTION; j++) nlv += rpt->Field[j].Enabled;
554
- if (nnv == 0 && nlv == 0) return errcode;
555
-
556
- // Return if no output file
557
- if (outFile == NULL) outFile = fopen(pr->outfile.OutFname, "rb");
558
- if (outFile == NULL) return 106;
559
-
560
- // Allocate memory for output variables:
561
- // m = larger of # node variables & # link variables
562
- // n = larger of # nodes & # links
563
- m = MAX((QUALITY - DEMAND + 1), (FRICTION - FLOW + 1));
564
- n = MAX((net->Nnodes + 1), (net->Nlinks + 1));
565
- x = (Pfloat *)calloc(m, sizeof(Pfloat));
566
- ERRCODE(MEMCHECK(x));
567
- if (errcode) return errcode;
568
- for (j = 0; j < m; j++)
569
- {
570
- x[j] = (REAL4 *)calloc(n, sizeof(REAL4));
571
- if (x[j] == NULL) errcode = 101;
572
- }
573
- if (!errcode)
574
- {
575
- // Re-position output file & initialize report time
576
- fseek(outFile, out->OutOffset2, SEEK_SET);
577
- time->Htime = time->Rstart;
578
-
579
- // For each reporting time:
580
- for (np = 1; np <= rpt->Nperiods; np++)
581
- {
582
- // Read in node results & write node table
583
- // (Remember to offset x[j] by 1 because array is zero-based)
584
- for (j = DEMAND; j <= QUALITY; j++)
585
- {
586
- fread((x[j - DEMAND]) + 1, sizeof(REAL4), net->Nnodes, outFile);
587
- }
588
- if (nnv > 0 && rpt->Nodeflag > 0) writenodetable(pr, x);
589
-
590
- // Read in link results & write link table
591
- for (j = FLOW; j <= FRICTION; j++)
592
- {
593
- fread((x[j - FLOW]) + 1, sizeof(REAL4), net->Nlinks, outFile);
594
- }
595
- if (nlv > 0 && rpt->Linkflag > 0) writelinktable(pr, x);
596
- time->Htime += time->Rstep;
597
- }
598
- }
599
-
600
- // Free output file
601
- if (outFile != NULL)
602
- {
603
- fclose(outFile);
604
- outFile = NULL;
605
- }
606
-
607
- // Free allocated memory
608
- for (j = 0; j < m; j++) free(x[j]);
609
- free(x);
610
- return errcode;
611
- }
612
-
613
- void writenodetable(Project *pr, Pfloat *x)
614
- /*
615
- **---------------------------------------------------------------
616
- ** Input: x = pointer to node results for current time
617
- ** Output: none
618
- ** Purpose: writes node results for current time to report file
619
- **---------------------------------------------------------------
620
- */
621
- {
622
- Network *net = &pr->network;
623
- Report *rpt = &pr->report;
624
-
625
- int i, j;
626
- char s[MAXLINE + 1], s1[16];
627
- double y[MAXVAR];
628
- Snode *node;
629
-
630
- // Write table header
631
- writeheader(pr, NODEHDR, 0);
632
-
633
- // For each node:
634
- for (i = 1; i <= net->Nnodes; i++)
635
- {
636
- // Place node's results for each variable in y
637
- node = &net->Node[i];
638
- y[ELEV] = node->El * pr->Ucf[ELEV];
639
- for (j = DEMAND; j <= QUALITY; j++) y[j] = *((x[j - DEMAND]) + i);
640
-
641
- // Check if node gets reported on
642
- if ((rpt->Nodeflag == 1 || node->Rpt) &&
643
- checklimits(rpt, y, ELEV, QUALITY))
644
- {
645
- // Check if new page needed
646
- if (rpt->LineNum == (long)rpt->PageSize) writeheader(pr, NODEHDR, 1);
647
-
648
- // Add node ID and each reported field to string s
649
- sprintf(s, "%-15s", node->ID);
650
- for (j = ELEV; j <= QUALITY; j++)
651
- {
652
- if (rpt->Field[j].Enabled == TRUE)
653
- {
654
- if (fabs(y[j]) > 1.e6) sprintf(s1, "%10.2e", y[j]);
655
- else sprintf(s1, "%10.*f", rpt->Field[j].Precision, y[j]);
656
- strcat(s, s1);
657
- }
658
- }
659
-
660
- // Note if node is a reservoir/tank
661
- if (i > net->Njuncs)
662
- {
663
- strcat(s, " ");
664
- strcat(s, NodeTxt[getnodetype(net, i)]);
665
- }
666
-
667
- // Write results for node to report file
668
- writeline(pr, s);
669
- }
670
- }
671
- writeline(pr, " ");
672
- }
673
-
674
- void writelinktable(Project *pr, Pfloat *x)
675
- /*
676
- **---------------------------------------------------------------
677
- ** Input: x = pointer to link results for current time
678
- ** Output: none
679
- ** Purpose: writes link results for current time to report file
680
- **---------------------------------------------------------------
681
- */
682
- {
683
- Network *net = &pr->network;
684
- Report *rpt = &pr->report;
685
-
686
- int i, j, k;
687
- char s[MAXLINE + 1], s1[16];
688
- double y[MAXVAR];
689
- double *Ucf = pr->Ucf;
690
- Slink *Link = net->Link;
691
-
692
- // Write table header
693
- writeheader(pr, LINKHDR, 0);
694
-
695
- // For each link:
696
- for (i = 1; i <= net->Nlinks; i++)
697
- {
698
- // Place results for each link variable in y
699
- y[LENGTH] = Link[i].Len * Ucf[LENGTH];
700
- y[DIAM] = Link[i].Diam * Ucf[DIAM];
701
- for (j = FLOW; j <= FRICTION; j++) y[j] = *((x[j - FLOW]) + i);
702
-
703
- // Check if link gets reported on
704
- if ((rpt->Linkflag == 1 || Link[i].Rpt) && checklimits(rpt, y, DIAM, FRICTION))
705
- {
706
- // Check if new page needed
707
- if (rpt->LineNum == (long)rpt->PageSize) writeheader(pr, LINKHDR, 1);
708
-
709
- // Add link ID and each reported field to string s
710
- sprintf(s, "%-15s", Link[i].ID);
711
- for (j = LENGTH; j <= FRICTION; j++)
712
- {
713
- if (rpt->Field[j].Enabled == TRUE)
714
- {
715
- if (j == STATUS)
716
- {
717
- if (y[j] <= CLOSED) k = CLOSED;
718
- else if (y[j] == ACTIVE) k = ACTIVE;
719
- else k = OPEN;
720
- sprintf(s1, "%10s", StatTxt[k]);
721
- }
722
- else
723
- {
724
- if (fabs(y[j]) > 1.e6) sprintf(s1, "%10.2e", y[j]);
725
- else sprintf(s1, "%10.*f", rpt->Field[j].Precision, y[j]);
726
- }
727
- strcat(s, s1);
728
- }
729
- }
730
-
731
- // Note if link is a pump or valve
732
- if ((j = Link[i].Type) > PIPE)
733
- {
734
- strcat(s, " ");
735
- strcat(s, LinkTxt[j]);
736
- }
737
-
738
- // Write results for link
739
- writeline(pr, s);
740
- }
741
- }
742
- writeline(pr, " ");
743
- }
744
-
745
- void writeheader(Project *pr, int type, int contin)
746
- /*
747
- **--------------------------------------------------------------
748
- ** Input: type = table type
749
- ** contin = table continuation flag
750
- ** Output: none
751
- ** Purpose: writes column headings for output report tables
752
- **--------------------------------------------------------------
753
- */
754
- {
755
- Report *rpt = &pr->report;
756
- Quality *qual = &pr->quality;
757
- Parser *parser = &pr->parser;
758
- Times *time = &pr->times;
759
-
760
- char s[MAXLINE + 1], s1[MAXLINE + 1], s2[MAXLINE + 1], s3[MAXLINE + 1];
761
- int i, n;
762
-
763
- // Move to next page if < 11 lines remain on current page
764
- if (rpt->Rptflag && rpt->LineNum + 11 > (long)rpt->PageSize)
765
- {
766
- while (rpt->LineNum < (long)rpt->PageSize) writeline(pr, " ");
767
- }
768
- writeline(pr, " ");
769
-
770
- // Hydraulic Status Table
771
- if (type == STATHDR)
772
- {
773
- sprintf(s, FMT49);
774
- if (contin) strcat(s, t_CONTINUED);
775
- writeline(pr, s);
776
- fillstr(s, '-', 70);
777
- writeline(pr, s);
778
- }
779
-
780
- // Energy Usage Table
781
- if (type == ENERHDR)
782
- {
783
- if (parser->Unitsflag == SI) strcpy(s1, t_perM3);
784
- else strcpy(s1, t_perMGAL);
785
- sprintf(s, FMT71);
786
- if (contin) strcat(s, t_CONTINUED);
787
- writeline(pr, s);
788
- fillstr(s, '-', 63);
789
- writeline(pr, s);
790
- sprintf(s, FMT72);
791
- writeline(pr, s);
792
- sprintf(s, FMT73, s1);
793
- writeline(pr, s);
794
- fillstr(s, '-', 63);
795
- writeline(pr, s);
796
- }
797
-
798
- // Node Results Table
799
- if (type == NODEHDR)
800
- {
801
- if (rpt->Tstatflag == RANGE) sprintf(s, FMT76, t_DIFFER);
802
- else if (rpt->Tstatflag != SERIES)
803
- {
804
- sprintf(s, FMT76, TstatTxt[rpt->Tstatflag]);
805
- }
806
- else if (time->Dur == 0) sprintf(s, FMT77);
807
- else sprintf(s, FMT78, clocktime(rpt->Atime, time->Htime));
808
- if (contin) strcat(s, t_CONTINUED);
809
- writeline(pr, s);
810
-
811
- n = 15;
812
- sprintf(s2, "%15s", "");
813
- strcpy(s, t_NODEID);
814
- sprintf(s3, "%-15s", s);
815
-
816
- for (i = ELEV; i < QUALITY; i++)
817
- {
818
- if (rpt->Field[i].Enabled == TRUE)
819
- {
820
- n += 10;
821
- sprintf(s, "%10s", rpt->Field[i].Name);
822
- strcat(s2, s);
823
- sprintf(s, "%10s", rpt->Field[i].Units);
824
- strcat(s3, s);
825
- }
826
- }
827
-
828
- if (rpt->Field[QUALITY].Enabled == TRUE)
829
- {
830
- n += 10;
831
- sprintf(s, "%10s", qual->ChemName);
832
- strcat(s2, s);
833
- sprintf(s, "%10s", qual->ChemUnits);
834
- strcat(s3, s);
835
- }
836
- fillstr(s1, '-', n);
837
- writeline(pr, s1);
838
- writeline(pr, s2);
839
- writeline(pr, s3);
840
- writeline(pr, s1);
841
- }
842
-
843
- // Link Results Table
844
- if (type == LINKHDR)
845
- {
846
- if (rpt->Tstatflag == RANGE) sprintf(s, FMT79, t_DIFFER);
847
- else if (rpt->Tstatflag != SERIES)
848
- {
849
- sprintf(s, FMT79, TstatTxt[rpt->Tstatflag]);
850
- }
851
- else if (time->Dur == 0) sprintf(s, FMT80);
852
- else sprintf(s, FMT81, clocktime(rpt->Atime, time->Htime));
853
- if (contin) strcat(s, t_CONTINUED);
854
- writeline(pr, s);
855
-
856
- n = 15;
857
- sprintf(s2, "%15s", "");
858
- strcpy(s, t_LINKID);
859
- sprintf(s3, "%-15s", s);
860
- for (i = LENGTH; i <= FRICTION; i++)
861
- {
862
- if (rpt->Field[i].Enabled == TRUE)
863
- {
864
- n += 10;
865
- sprintf(s, "%10s", rpt->Field[i].Name);
866
- strcat(s2, s);
867
- sprintf(s, "%10s", rpt->Field[i].Units);
868
- strcat(s3, s);
869
- }
870
- }
871
- fillstr(s1, '-', n);
872
- writeline(pr, s1);
873
- writeline(pr, s2);
874
- writeline(pr, s3);
875
- writeline(pr, s1);
876
- }
877
- }
878
-
879
- void writeline(Project *pr, char *s)
880
- /*
881
- **--------------------------------------------------------------
882
- ** Input: *s = text string
883
- ** Output: none
884
- ** Purpose: writes a line of output to report file
885
- **--------------------------------------------------------------
886
- */
887
- {
888
- Report *rpt = &pr->report;
889
-
890
- if (rpt->RptFile == NULL) return;
891
- if (rpt->Rptflag)
892
- {
893
- if (rpt->LineNum == (long)rpt->PageSize)
894
- {
895
- rpt->PageNum++;
896
- if (fprintf(rpt->RptFile, FMT82, (int)rpt->PageNum, pr->Title[0]) < 0)
897
- {
898
- rpt->Fprinterr = TRUE;
899
- }
900
- rpt->LineNum = 3;
901
- }
902
- }
903
- if (fprintf(rpt->RptFile, "\n %s", s) < 0) rpt->Fprinterr = TRUE;
904
- rpt->LineNum++;
905
- }
906
-
907
- void writerelerr(Project *pr, int iter, double relerr)
908
- /*
909
- **-----------------------------------------------------------------
910
- ** Input: iter = current iteration of hydraulic solution
911
- ** relerr = current convergence error
912
- ** Output: none
913
- ** Purpose: writes out convergence status of hydraulic solution
914
- **-----------------------------------------------------------------
915
- */
916
- {
917
- Report *rpt = &pr->report;
918
- Times *time = &pr->times;
919
-
920
- if (iter == 0)
921
- {
922
- sprintf(pr->Msg, FMT64, clocktime(rpt->Atime, time->Htime));
923
- writeline(pr, pr->Msg);
924
- }
925
- else
926
- {
927
- sprintf(pr->Msg, FMT65, iter, relerr);
928
- writeline(pr, pr->Msg);
929
- }
930
- }
931
-
932
- void writestatchange(Project *pr, int k, char s1, char s2)
933
- /*
934
- **--------------------------------------------------------------
935
- ** Input: k = link index
936
- ** s1 = old link status
937
- ** s2 = new link status
938
- ** Output: none
939
- ** Purpose: writes change in link status to output report
940
- **--------------------------------------------------------------
941
- */
942
- {
943
- Network *net = &pr->network;
944
- Hydraul *hyd = &pr->hydraul;
945
-
946
- int j1, j2;
947
- double setting;
948
- double *Ucf = pr->Ucf;
949
- double *LinkSetting = hyd->LinkSetting;
950
- Slink *Link = net->Link;
951
-
952
- // We have a pump/valve setting change instead of a status change
953
- if (s1 == s2)
954
- {
955
- setting = LinkSetting[k];
956
- switch (Link[k].Type)
957
- {
958
- case PRV:
959
- case PSV:
960
- case PBV:
961
- setting *= Ucf[PRESSURE];
962
- break;
963
- case FCV:
964
- setting *= Ucf[FLOW];
965
- break;
966
- default:
967
- break;
968
- }
969
- sprintf(pr->Msg, FMT56, LinkTxt[Link[k].Type], Link[k].ID, setting);
970
- writeline(pr, pr->Msg);
971
- return;
972
- }
973
-
974
- // We have a status change - write the old & new status types
975
- if (s1 == ACTIVE) j1 = ACTIVE;
976
- else if (s1 <= CLOSED) j1 = CLOSED;
977
- else j1 = OPEN;
978
- if (s2 == ACTIVE) j2 = ACTIVE;
979
- else if (s2 <= CLOSED) j2 = CLOSED;
980
- else j2 = OPEN;
981
- if (j1 != j2)
982
- {
983
- sprintf(pr->Msg, FMT57, LinkTxt[Link[k].Type], Link[k].ID, StatTxt[j1],
984
- StatTxt[j2]);
985
- writeline(pr, pr->Msg);
986
- }
987
- }
988
-
989
- void writecontrolaction(Project *pr, int k, int i)
990
- /*
991
- ----------------------------------------------------------------
992
- ** Input: k = link index
993
- ** i = control index
994
- ** Output: none
995
- ** Purpose: writes control action taken to status report
996
- **--------------------------------------------------------------
997
- */
998
- {
999
- Network *net = &pr->network;
1000
- Report *rpt = &pr->report;
1001
- Times *time = &pr->times;
1002
-
1003
- int n;
1004
- Snode *Node = net->Node;
1005
- Slink *Link = net->Link;
1006
- Scontrol *Control = net->Control;
1007
-
1008
- switch (Control[i].Type)
1009
- {
1010
- case LOWLEVEL:
1011
- case HILEVEL:
1012
- n = Control[i].Node;
1013
- sprintf(pr->Msg, FMT54, clocktime(rpt->Atime, time->Htime),
1014
- LinkTxt[Link[k].Type], Link[k].ID,
1015
- NodeTxt[getnodetype(net, n)], Node[n].ID);
1016
- break;
1017
-
1018
- case TIMER:
1019
- case TIMEOFDAY:
1020
- sprintf(pr->Msg, FMT55, clocktime(rpt->Atime, time->Htime),
1021
- LinkTxt[Link[k].Type], Link[k].ID);
1022
- break;
1023
- default:
1024
- return;
1025
- }
1026
- writeline(pr, pr->Msg);
1027
- }
1028
-
1029
- void writeruleaction(Project *pr, int k, char *ruleID)
1030
- /*
1031
- **--------------------------------------------------------------
1032
- ** Input: k = link index
1033
- ** *ruleID = rule ID
1034
- ** Output: none
1035
- ** Purpose: writes rule action taken to status report
1036
- **--------------------------------------------------------------
1037
- */
1038
- {
1039
- Network *net = &pr->network;
1040
- Report *rpt = &pr->report;
1041
- Times *time = &pr->times;
1042
-
1043
- Slink *Link = net->Link;
1044
-
1045
- sprintf(pr->Msg, FMT63, clocktime(rpt->Atime, time->Htime),
1046
- LinkTxt[Link[k].Type], Link[k].ID, ruleID);
1047
- writeline(pr, pr->Msg);
1048
- }
1049
-
1050
- int writehydwarn(Project *pr, int iter, double relerr)
1051
- /*
1052
- **--------------------------------------------------------------
1053
- ** Input: iter = # iterations to find hydraulic solution
1054
- ** Output: warning flag code
1055
- ** Purpose: writes hydraulic warning message to report file
1056
- **
1057
- ** Note: Warning conditions checked in following order:
1058
- ** 1. System balanced but unstable
1059
- ** 2. Negative pressures
1060
- ** 3. FCV cannot supply flow or PRV/PSV cannot maintain pressure
1061
- ** 4. Pump out of range
1062
- ** 5. Network disconnected
1063
- ** 6. System unbalanced
1064
- **--------------------------------------------------------------
1065
- */
1066
- {
1067
- Network *net = &pr->network;
1068
- Hydraul *hyd = &pr->hydraul;
1069
- Report *rpt = &pr->report;
1070
- Times *time = &pr->times;
1071
-
1072
- int i, j;
1073
- char flag = 0;
1074
- int s;
1075
- Snode *node;
1076
- Slink *link;
1077
- Spump *pump;
1078
-
1079
- // Check if system unstable
1080
- if (iter > hyd->MaxIter && relerr <= hyd->Hacc)
1081
- {
1082
- sprintf(pr->Msg, WARN02, clocktime(rpt->Atime, time->Htime));
1083
- if (rpt->Messageflag) writeline(pr, pr->Msg);
1084
- flag = 2;
1085
- }
1086
-
1087
- // Check for pressure deficient nodes
1088
- if (hyd->DemandModel == DDA)
1089
- {
1090
- hyd->DeficientNodes = 0;
1091
- for (i = 1; i <= net->Njuncs; i++)
1092
- {
1093
- node = &net->Node[i];
1094
- if (hyd->NodeHead[i] < node->El && hyd->NodeDemand[i] > 0.0)
1095
- hyd->DeficientNodes++;
1096
- }
1097
- if (hyd->DeficientNodes > 0)
1098
- {
1099
- if (rpt->Messageflag)
1100
- {
1101
- sprintf(pr->Msg, WARN06, clocktime(rpt->Atime, time->Htime));
1102
- writeline(pr, pr->Msg);
1103
- }
1104
- flag = 6;
1105
- }
1106
- }
1107
-
1108
- // Check for abnormal valve condition
1109
- for (i = 1; i <= net->Nvalves; i++)
1110
- {
1111
- j = net->Valve[i].Link;
1112
- link = &net->Link[j];
1113
- if (hyd->LinkStatus[j] >= XFCV)
1114
- {
1115
- if (rpt->Messageflag)
1116
- {
1117
- sprintf(pr->Msg, WARN05, LinkTxt[link->Type], link->ID,
1118
- StatTxt[hyd->LinkStatus[j]],
1119
- clocktime(rpt->Atime, time->Htime));
1120
- writeline(pr, pr->Msg);
1121
- }
1122
- flag = 5;
1123
- }
1124
- }
1125
-
1126
- // Check for abnormal pump condition
1127
- for (i = 1; i <= net->Npumps; i++)
1128
- {
1129
- pump = &net->Pump[i];
1130
- j = pump->Link;
1131
- s = hyd->LinkStatus[j];
1132
- if (hyd->LinkStatus[j] >= OPEN)
1133
- {
1134
- if (hyd->LinkFlow[j] > hyd->LinkSetting[j] * pump->Qmax) s = XFLOW;
1135
- if (hyd->LinkFlow[j] < 0.0) s = XHEAD;
1136
- }
1137
- if (s == XHEAD || s == XFLOW)
1138
- {
1139
- if (rpt->Messageflag)
1140
- {
1141
- sprintf(pr->Msg, WARN04, net->Link[j].ID, StatTxt[s],
1142
- clocktime(rpt->Atime, time->Htime));
1143
- writeline(pr, pr->Msg);
1144
- }
1145
- flag = 4;
1146
- }
1147
- }
1148
-
1149
- // Check if system is unbalanced
1150
- if (iter > hyd->MaxIter && relerr > hyd->Hacc)
1151
- {
1152
- if (rpt->Messageflag)
1153
- {
1154
- sprintf(pr->Msg, WARN01, clocktime(rpt->Atime, time->Htime));
1155
- if (hyd->ExtraIter == -1) strcat(pr->Msg, t_HALTED);
1156
- writeline(pr, pr->Msg);
1157
- }
1158
- flag = 1;
1159
- }
1160
-
1161
- // Check for disconnected network & update project's warning flag
1162
- if (flag > 0)
1163
- {
1164
- disconnected(pr);
1165
- pr->Warnflag = flag;
1166
- if (rpt->Messageflag) writeline(pr, " ");
1167
- }
1168
- return flag;
1169
- }
1170
-
1171
- void writehyderr(Project *pr, int errnode)
1172
- /*
1173
- **-----------------------------------------------------------
1174
- ** Input: none
1175
- ** Output: none
1176
- ** Purpose: outputs status & checks connectivity when
1177
- ** network hydraulic equations cannot be solved.
1178
- **-----------------------------------------------------------
1179
- */
1180
- {
1181
- Network *net = &pr->network;
1182
- Report *rpt = &pr->report;
1183
- Times *time = &pr->times;
1184
-
1185
- Snode *Node = net->Node;
1186
-
1187
- if (rpt->Messageflag)
1188
- {
1189
- sprintf(pr->Msg, FMT62, clocktime(rpt->Atime, time->Htime),
1190
- Node[errnode].ID);
1191
- writeline(pr, pr->Msg);
1192
- }
1193
- writehydstat(pr, 0, 0);
1194
- disconnected(pr);
1195
- }
1196
-
1197
- int disconnected(Project *pr)
1198
- /*
1199
- **-------------------------------------------------------------------
1200
- ** Input: None
1201
- ** Output: Returns number of disconnected nodes
1202
- ** Purpose: Tests current hydraulic solution to see if any closed
1203
- ** links have caused the network to become disconnected.
1204
- **-------------------------------------------------------------------
1205
- */
1206
- {
1207
- Network *net = &pr->network;
1208
- Hydraul *hyd = &pr->hydraul;
1209
- Report *rpt = &pr->report;
1210
- Times *time = &pr->times;
1211
-
1212
- int i, j;
1213
- int count, mcount;
1214
- int errcode = 0;
1215
- int *nodelist;
1216
- char *marked;
1217
- Snode *node;
1218
-
1219
- // Allocate memory for node list & marked list
1220
- nodelist = (int *)calloc(net->Nnodes + 1, sizeof(int));
1221
- marked = (char *)calloc(net->Nnodes + 1, sizeof(char));
1222
- ERRCODE(MEMCHECK(nodelist));
1223
- ERRCODE(MEMCHECK(marked));
1224
-
1225
- // If allocation fails return with 0 nodes disconnected
1226
- if (errcode)
1227
- {
1228
- free(nodelist);
1229
- free(marked);
1230
- return (0);
1231
- }
1232
-
1233
- // Place tanks on node list and marked list
1234
- for (i = 1; i <= net->Ntanks; i++)
1235
- {
1236
- j = net->Njuncs + i;
1237
- nodelist[i] = j;
1238
- marked[j] = 1;
1239
- }
1240
-
1241
- // Place junctions with negative demands on the lists
1242
- mcount = net->Ntanks;
1243
- for (i = 1; i <= net->Njuncs; i++)
1244
- {
1245
- if (hyd->NodeDemand[i] < 0.0)
1246
- {
1247
- mcount++;
1248
- nodelist[mcount] = i;
1249
- marked[i] = 1;
1250
- }
1251
- }
1252
-
1253
- // Mark all nodes that can be connected to tanks
1254
- // and count number of nodes remaining unmarked
1255
- marknodes(pr, mcount, nodelist, marked);
1256
- j = 0;
1257
- count = 0;
1258
- for (i = 1; i <= net->Njuncs; i++)
1259
- {
1260
- node = &net->Node[i];
1261
- if (!marked[i] && hyd->NodeDemand[i] != 0.0)
1262
- {
1263
- count++;
1264
- if (count <= MAXCOUNT && rpt->Messageflag)
1265
- {
1266
- sprintf(pr->Msg, WARN03a, node->ID,
1267
- clocktime(rpt->Atime, time->Htime));
1268
- writeline(pr, pr->Msg);
1269
- }
1270
- j = i; // Last unmarked node
1271
- }
1272
- }
1273
-
1274
- // Report number of unmarked nodes and find closed link
1275
- // on path from node j back to a tank
1276
- if (count > 0 && rpt->Messageflag)
1277
- {
1278
- if (count > MAXCOUNT)
1279
- {
1280
- sprintf(pr->Msg, WARN03b, count - MAXCOUNT,
1281
- clocktime(rpt->Atime, time->Htime));
1282
- writeline(pr, pr->Msg);
1283
- }
1284
- getclosedlink(pr, j, marked);
1285
- }
1286
-
1287
- // Free allocated memory
1288
- free(nodelist);
1289
- free(marked);
1290
- return count;
1291
- }
1292
-
1293
- void marknodes(Project *pr, int m, int *nodelist, char *marked)
1294
- /*
1295
- **----------------------------------------------------------------
1296
- ** Input: m = number of source nodes
1297
- ** nodelist[] = list of nodes to be traced from
1298
- ** marked[] = TRUE if node connected to source
1299
- ** Output: None.
1300
- ** Purpose: Marks all junction nodes connected to tanks.
1301
- **----------------------------------------------------------------
1302
- */
1303
- {
1304
- Network *net = &pr->network;
1305
- Hydraul *hyd = &pr->hydraul;
1306
-
1307
- int i, j, k, n;
1308
- Padjlist alink;
1309
-
1310
- // Scan each successive entry of node list
1311
- n = 1;
1312
- while (n <= m)
1313
- {
1314
- // Scan all nodes connected to current node
1315
- i = nodelist[n];
1316
- for (alink = net->Adjlist[i]; alink != NULL; alink = alink->next)
1317
- {
1318
- // Get indexes of connecting link and node
1319
- k = alink->link;
1320
- j = alink->node;
1321
- if (marked[j]) continue;
1322
-
1323
- // Check if valve connection is in correct direction
1324
- switch (net->Link[k].Type)
1325
- {
1326
- case CVPIPE:
1327
- case PRV:
1328
- case PSV:
1329
- if (j == net->Link[k].N1) continue;
1330
- break;
1331
- default:
1332
- break;
1333
- }
1334
-
1335
- // Mark connection node if link not closed
1336
- if (hyd->LinkStatus[k] > CLOSED)
1337
- {
1338
- marked[j] = 1;
1339
- m++;
1340
- nodelist[m] = j;
1341
- }
1342
- }
1343
- n++;
1344
- }
1345
- }
1346
-
1347
- void getclosedlink(Project *pr, int i, char *marked)
1348
- /*
1349
- **----------------------------------------------------------------
1350
- ** Input: i = junction index
1351
- ** marked[] = marks nodes already examined
1352
- ** Output: None.
1353
- ** Purpose: Determines if a closed link connects to junction i.
1354
- **----------------------------------------------------------------
1355
- */
1356
- {
1357
- Network *net = &pr->network;
1358
-
1359
- int j, k;
1360
- Padjlist alink;
1361
-
1362
- marked[i] = 2;
1363
- for (alink = net->Adjlist[i]; alink != NULL; alink = alink->next)
1364
- {
1365
- k = alink->link;
1366
- j = alink->node;
1367
- if (marked[j] == 2) continue;
1368
- if (marked[j] == 1)
1369
- {
1370
- sprintf(pr->Msg, WARN03c, net->Link[k].ID);
1371
- writeline(pr, pr->Msg);
1372
- return;
1373
- }
1374
- else getclosedlink(pr, j, marked);
1375
- }
1376
- }
1377
-
1378
- void writelimits(Project *pr, int j1, int j2)
1379
- /*
1380
- **--------------------------------------------------------------
1381
- ** Input: j1 = index of first output variable
1382
- ** j2 = index of last output variable
1383
- ** Output: none
1384
- ** Purpose: writes reporting criteria to output report
1385
- **--------------------------------------------------------------
1386
- */
1387
- {
1388
- Report *rpt = &pr->report;
1389
- int j;
1390
-
1391
- for (j = j1; j <= j2; j++)
1392
- {
1393
- if (rpt->Field[j].RptLim[LOW] < BIG)
1394
- {
1395
- sprintf(pr->Msg, FMT47, rpt->Field[j].Name,
1396
- rpt->Field[j].RptLim[LOW],
1397
- rpt->Field[j].Units);
1398
- writeline(pr, pr->Msg);
1399
- }
1400
- if (rpt->Field[j].RptLim[HI] > -BIG)
1401
- {
1402
- sprintf(pr->Msg, FMT48, rpt->Field[j].Name,
1403
- rpt->Field[j].RptLim[HI],
1404
- rpt->Field[j].Units);
1405
- writeline(pr, pr->Msg);
1406
- }
1407
- }
1408
- }
1409
-
1410
- int checklimits(Report *rpt, double *y, int j1, int j2)
1411
- /*
1412
- **--------------------------------------------------------------
1413
- ** Input: *y = array of output results
1414
- ** j1 = index of first output variable
1415
- ** j2 = index of last output variable
1416
- ** Output: returns 1 if criteria met, 0 otherwise
1417
- ** Purpose: checks if output reporting criteria is met
1418
- **--------------------------------------------------------------
1419
- */
1420
- {
1421
- int j;
1422
- for (j = j1; j <= j2; j++)
1423
- {
1424
- if (y[j] > rpt->Field[j].RptLim[LOW] ||
1425
- y[j] < rpt->Field[j].RptLim[HI]
1426
- ) return 0;
1427
- }
1428
- return 1;
1429
- }
1430
-
1431
- void writetime(Project *pr, char *fmt)
1432
- /*
1433
- **----------------------------------------------------------------
1434
- ** Input: fmt = format string
1435
- ** Output: none
1436
- ** Purpose: writes starting/ending time of a run to report file
1437
- **----------------------------------------------------------------
1438
- */
1439
- {
1440
- time_t timer;
1441
- time(&timer);
1442
- sprintf(pr->Msg, fmt, ctime(&timer));
1443
- writeline(pr, pr->Msg);
1444
- }
1445
-
1446
- char *clocktime(char *atime, long seconds)
1447
- /*
1448
- **--------------------------------------------------------------
1449
- ** Input: seconds = time in seconds
1450
- ** Output: atime = time in hrs:min
1451
- ** (returns pointer to atime)
1452
- ** Purpose: converts time in seconds to hours:minutes format
1453
- **--------------------------------------------------------------
1454
- */
1455
- {
1456
- long h, m, s;
1457
- h = seconds / 3600;
1458
- m = seconds % 3600 / 60;
1459
- s = seconds - 3600 * h - 60 * m;
1460
- sprintf(atime, "%01d:%02d:%02d", (int)h, (int)m, (int)s);
1461
- return atime;
1462
- }
1463
-
1464
- char *fillstr(char *s, char ch, int n)
1465
- /*
1466
- **---------------------------------------------------------
1467
- ** Fills n bytes of s to character ch.
1468
- ** NOTE: does not check for overwriting s.
1469
- **---------------------------------------------------------
1470
- */
1471
- {
1472
- int i;
1473
- for (i = 0; i <= n; i++) s[i] = ch;
1474
- s[n + 1] = '\0';
1475
- return (s);
1476
- }
1477
-
1478
- int getnodetype(Network *net, int i)
1479
- /*
1480
- **---------------------------------------------------------
1481
- ** Determines type of node with index i
1482
- ** (junction = 0, reservoir = 1, tank = 2).
1483
- **---------------------------------------------------------
1484
- */
1485
- {
1486
- if (i <= net->Njuncs) return 0;
1487
- if (net->Tank[i - net->Njuncs].A == 0.0) return 1;
1488
- return 2;
1489
- }