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,707 +0,0 @@
1
- /*
2
- ******************************************************************************
3
- Project: OWA EPANET
4
- Version: 2.2
5
- Module: input1.c
6
- Description: retrieves network data from an EPANET input file
7
- Authors: see AUTHORS
8
- Copyright: see AUTHORS
9
- License: see LICENSE
10
- Last Updated: 07/08/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
- // Default values
25
- #define MAXITER 200 // Default max. # hydraulic iterations
26
- #define HACC 0.001 // Default hydraulics convergence ratio
27
- #define HTOL 0.0005 // Default hydraulic head tolerance (ft)
28
- #define QTOL 0.0001 // Default flow rate tolerance (cfs)
29
- #define AGETOL 0.01 // Default water age tolerance (hrs)
30
- #define CHEMTOL 0.01 // Default concentration tolerance
31
- #define PAGESIZE 0 // Default uses no page breaks
32
- #define SPGRAV 1.0 // Default specific gravity
33
- #define EPUMP 75 // Default pump efficiency
34
- #define DEFPATID "1" // Default demand pattern ID
35
- #define RQTOL 1E-7 // Default low flow resistance tolerance
36
- #define CHECKFREQ 2 // Default status check frequency
37
- #define MAXCHECK 10 // Default # iterations for status checks
38
- #define DAMPLIMIT 0 // Default damping threshold
39
-
40
- // Defined in ENUMSTXT.H
41
- extern char *Fldname[];
42
- extern char *RptFlowUnitsTxt[];
43
-
44
- int getdata(Project *pr)
45
- /*
46
- **----------------------------------------------------------------
47
- ** Input: none
48
- ** Output: returns error code
49
- ** Purpose: reads in network data from disk file
50
- **----------------------------------------------------------------
51
- */
52
- {
53
- int errcode = 0;
54
-
55
- // Assign default data values & reporting options
56
- setdefaults(pr);
57
- initreport(&pr->report);
58
-
59
- // Read in network data
60
- rewind(pr->parser.InFile);
61
- ERRCODE(readdata(pr));
62
-
63
- // Adjust data and convert it to internal units
64
- if (!errcode) adjustdata(pr);
65
- if (!errcode) initunits(pr);
66
- ERRCODE(inittanks(pr));
67
- if (!errcode) convertunits(pr);
68
- return errcode;
69
- }
70
-
71
- void setdefaults(Project *pr)
72
- /*
73
- **----------------------------------------------------------------
74
- ** Input: none
75
- ** Output: none
76
- ** Purpose: assigns default values to a project's variables
77
- **----------------------------------------------------------------
78
- */
79
- {
80
- Parser *parser = &pr->parser;
81
- Report *rpt = &pr->report;
82
- Hydraul *hyd = &pr->hydraul;
83
- Quality *qual = &pr->quality;
84
- Times *time = &pr->times;
85
- Outfile *out = &pr->outfile;
86
-
87
- strncpy(pr->Title[0], "", TITLELEN);
88
- strncpy(pr->Title[1], "", TITLELEN);
89
- strncpy(pr->Title[2], "", TITLELEN);
90
- strncpy(out->HydFname, "", MAXFNAME);
91
- strncpy(pr->MapFname, "", MAXFNAME);
92
- strncpy(qual->ChemName, t_CHEMICAL, MAXID);
93
- strncpy(qual->ChemUnits, u_MGperL, MAXID);
94
- strncpy(parser->DefPatID, DEFPATID, MAXID);
95
-
96
- pr->Warnflag = FALSE; // Warning flag is off
97
- parser->Unitsflag = US; // US unit system
98
- parser->Flowflag = GPM; // Flow units are gpm
99
- parser->Pressflag = PSI; // Pressure units are psi
100
- parser->DefPat = 0; // Default demand pattern index
101
- out->Hydflag = SCRATCH; // No external hydraulics file
102
- rpt->Tstatflag = SERIES; // Generate time series output
103
-
104
- hyd->Formflag = HW; // Use Hazen-Williams formula
105
- hyd->Htol = HTOL; // Default head tolerance
106
- hyd->Qtol = QTOL; // Default flow tolerance
107
- hyd->Hacc = HACC; // Default hydraulic accuracy
108
- hyd->FlowChangeLimit = 0.0; // Default flow change limit
109
- hyd->HeadErrorLimit = 0.0; // Default head error limit
110
- hyd->DemandModel = DDA; // Demand driven analysis
111
- hyd->Pmin = 0.0; // Minimum demand pressure (ft)
112
- hyd->Preq = MINPDIFF; // Required demand pressure (ft)
113
- hyd->Pexp = 0.5; // Pressure function exponent
114
- hyd->MaxIter = MAXITER; // Default max. hydraulic trials
115
- hyd->ExtraIter = -1; // Stop if network unbalanced
116
- hyd->Viscos = MISSING; // Temporary viscosity
117
- hyd->SpGrav = SPGRAV; // Default specific gravity
118
- hyd->Epat = 0; // No energy price pattern
119
- hyd->Ecost = 0.0; // Zero unit energy cost
120
- hyd->Dcost = 0.0; // Zero energy demand charge
121
- hyd->Epump = EPUMP; // Default pump efficiency
122
- hyd->Emax = 0.0; // Zero peak energy usage
123
- hyd->Qexp = 2.0; // Flow exponent for emitters
124
- hyd->Dmult = 1.0; // Demand multiplier
125
- hyd->RQtol = RQTOL; // Default hydraulics parameters
126
- hyd->CheckFreq = CHECKFREQ;
127
- hyd->MaxCheck = MAXCHECK;
128
- hyd->DampLimit = DAMPLIMIT;
129
-
130
- qual->Qualflag = NONE; // No quality simulation
131
- qual->Ctol = MISSING; // No pre-set quality tolerance
132
- qual->TraceNode = 0; // No source tracing
133
- qual->BulkOrder = 1.0; // 1st-order bulk reaction rate
134
- qual->WallOrder = 1.0; // 1st-order wall reaction rate
135
- qual->TankOrder = 1.0; // 1st-order tank reaction rate
136
- qual->Kbulk = 0.0; // No global bulk reaction
137
- qual->Kwall = 0.0; // No global wall reaction
138
- qual->Climit = 0.0; // No limiting potential quality
139
- qual->Diffus = MISSING; // Temporary diffusivity
140
- qual->Rfactor = 0.0; // No roughness-reaction factor
141
- qual->MassBalance.ratio = 0.0;
142
-
143
- time->Dur = 0; // 0 sec duration (steady state)
144
- time->Tstart = 0; // Starting time of day
145
- time->Pstart = 0; // Starting pattern period
146
- time->Hstep = 3600; // 1 hr hydraulic time step
147
- time->Qstep = 0; // No pre-set quality time step
148
- time->Pstep = 3600; // 1 hr time pattern period
149
- time->Rstep = 3600; // 1 hr reporting period
150
- time->Rulestep = 0; // No pre-set rule time step
151
- time->Rstart = 0; // Start reporting at time 0
152
- }
153
-
154
- void initreport(Report *rpt)
155
- /*
156
- **----------------------------------------------------------------------
157
- ** Input: none
158
- ** Output: none
159
- ** Purpose: initializes reporting options
160
- **----------------------------------------------------------------------
161
- */
162
- {
163
- int i;
164
- strncpy(rpt->Rpt2Fname, "", MAXFNAME);
165
-
166
- // Initialize general reporting options
167
- rpt->PageSize = PAGESIZE; // Default page size for report
168
- rpt->Summaryflag = TRUE; // Write summary report
169
- rpt->Messageflag = TRUE; // Report error/warning messages
170
- rpt->Statflag = FALSE; // No hydraulic status reports
171
- rpt->Energyflag = FALSE; // No energy usage report
172
- rpt->Nodeflag = 0; // No reporting on nodes
173
- rpt->Linkflag = 0; // No reporting on links
174
-
175
- // Initialize options for each reported variable field
176
- for (i = 0; i < MAXVAR; i++)
177
- {
178
- strncpy(rpt->Field[i].Name, Fldname[i], MAXID);
179
- rpt->Field[i].Enabled = FALSE; // Not included in report
180
- rpt->Field[i].Precision = 2; // 2 decimal precision
181
- rpt->Field[i].RptLim[LOW] = SQR(BIG); // No reporting limits
182
- rpt->Field[i].RptLim[HI] = -SQR(BIG);
183
- }
184
- rpt->Field[FRICTION].Precision = 3;
185
-
186
- // Set default set of variables reported on
187
- for (i = DEMAND; i <= QUALITY; i++)
188
- {
189
- rpt->Field[i].Enabled = TRUE;
190
- }
191
- for (i = FLOW; i <= HEADLOSS; i++)
192
- {
193
- rpt->Field[i].Enabled = TRUE;
194
- }
195
- }
196
-
197
- void adjustdata(Project *pr)
198
- /*
199
- **----------------------------------------------------------------------
200
- ** Input: none
201
- ** Output: none
202
- ** Purpose: adjusts project data after input file has been processed
203
- **----------------------------------------------------------------------
204
- */
205
- {
206
- Network *net = &pr->network;
207
- Hydraul *hyd = &pr->hydraul;
208
- Quality *qual = &pr->quality;
209
- Times *time = &pr->times;
210
- Parser *parser = &pr->parser;
211
- Report *rpt = &pr->report;
212
-
213
- int i;
214
- double ucf; // Unit conversion factor
215
- Pdemand demand; // Pointer to demand record
216
- Slink *link;
217
- Snode *node;
218
- Stank *tank;
219
-
220
- // Use 1 hr pattern & report time step if none specified
221
- if (time->Pstep <= 0) time->Pstep = 3600;
222
- if (time->Rstep == 0) time->Rstep = time->Pstep;
223
-
224
- // Hydraulic time step cannot be greater than pattern or report time step
225
- if (time->Hstep <= 0) time->Hstep = 3600;
226
- if (time->Hstep > time->Pstep) time->Hstep = time->Pstep;
227
- if (time->Hstep > time->Rstep) time->Hstep = time->Rstep;
228
-
229
- // Report start time cannot be greater than simulation duration
230
- if (time->Rstart > time->Dur) time->Rstart = 0;
231
-
232
- // No water quality analysis for single period run
233
- if (time->Dur == 0) qual->Qualflag = NONE;
234
-
235
- // If no quality timestep, then make it 1/10 of hydraulic timestep
236
- if (time->Qstep == 0) time->Qstep = time->Hstep / 10;
237
-
238
- // If no rule time step then make it 1/10 of hydraulic time step
239
- // but not greater than hydraulic time step
240
- if (time->Rulestep == 0) time->Rulestep = time->Hstep / 10;
241
- time->Rulestep = MIN(time->Rulestep, time->Hstep);
242
-
243
- // Quality timestep cannot exceed hydraulic timestep
244
- time->Qstep = MIN(time->Qstep, time->Hstep);
245
-
246
- // If no quality tolerance, then use default values
247
- if (qual->Ctol == MISSING)
248
- {
249
- if (qual->Qualflag == AGE) qual->Ctol = AGETOL;
250
- else qual->Ctol = CHEMTOL;
251
- }
252
-
253
- // Determine units system based on flow units
254
- switch (parser->Flowflag)
255
- {
256
- case LPS: // Liters/sec
257
- case LPM: // Liters/min
258
- case MLD: // megaliters/day
259
- case CMH: // cubic meters/hr
260
- case CMD: // cubic meters/day
261
- parser->Unitsflag = SI;
262
- break;
263
- default:
264
- parser->Unitsflag = US;
265
- }
266
-
267
- // Revise pressure units depending on flow units
268
- if (parser->Unitsflag != SI) parser->Pressflag = PSI;
269
- else if (parser->Pressflag == PSI) parser->Pressflag = METERS;
270
-
271
- // Store value of viscosity & diffusivity
272
- ucf = 1.0;
273
- if (parser->Unitsflag == SI) ucf = SQR(MperFT);
274
- if (hyd->Viscos == MISSING)
275
- {
276
- hyd->Viscos = VISCOS; // No viscosity supplied
277
- }
278
- else if (hyd->Viscos > 1.e-3)
279
- {
280
- hyd->Viscos = hyd->Viscos * VISCOS; // Multiplier supplied
281
- }
282
- else hyd->Viscos = hyd->Viscos / ucf; // Actual value supplied
283
- if (qual->Diffus == MISSING)
284
- {
285
- qual->Diffus = DIFFUS; // No viscosity supplied
286
- }
287
- else if (qual->Diffus > 1.e-4)
288
- {
289
- qual->Diffus = qual->Diffus * DIFFUS; // Multiplier supplied
290
- }
291
- else qual->Diffus = qual->Diffus / ucf; // Actual value supplied
292
-
293
- // Set exponent in head loss equation and adjust flow-resistance tolerance.
294
- if (hyd->Formflag == HW) hyd->Hexp = 1.852;
295
- else hyd->Hexp = 2.0;
296
-
297
- // See if default reaction coeffs. apply
298
- for (i = 1; i <= net->Nlinks; i++)
299
- {
300
- link = &net->Link[i];
301
- if (link->Type > PIPE) continue;
302
- if (link->Kb == MISSING) link->Kb = qual->Kbulk; // Bulk coeff.
303
- if (link->Kw == MISSING) // Wall coeff.
304
- {
305
- // Rfactor is the pipe roughness correlation factor
306
- if (qual->Rfactor == 0.0) link->Kw = qual->Kwall;
307
- else if ((link->Kc > 0.0) && (link->Diam > 0.0))
308
- {
309
- if (hyd->Formflag == HW) link->Kw = qual->Rfactor / link->Kc;
310
- if (hyd->Formflag == DW)
311
- {
312
- link->Kw = qual->Rfactor / ABS(log(link->Kc / link->Diam));
313
- }
314
- if (hyd->Formflag == CM) link->Kw = qual->Rfactor * link->Kc;
315
- }
316
- else link->Kw = 0.0;
317
- }
318
- }
319
- for (i = 1; i <= net->Ntanks; i++)
320
- {
321
- tank = &net->Tank[i];
322
- if (tank->Kb == MISSING) tank->Kb = qual->Kbulk;
323
- }
324
-
325
- // Use default pattern if none assigned to a demand
326
- parser->DefPat = findpattern(net, parser->DefPatID);
327
- if (parser->DefPat > 0) for (i = 1; i <= net->Nnodes; i++)
328
- {
329
- node = &net->Node[i];
330
- for (demand = node->D; demand != NULL; demand = demand->next)
331
- {
332
- if (demand->Pat == 0) demand->Pat = parser->DefPat;
333
- }
334
- }
335
-
336
- // Remove QUALITY as a reporting variable if no WQ analysis
337
- if (qual->Qualflag == NONE) rpt->Field[QUALITY].Enabled = FALSE;
338
- }
339
-
340
- int inittanks(Project *pr)
341
- /*
342
- **---------------------------------------------------------------
343
- ** Input: none
344
- ** Output: returns error code
345
- ** Purpose: initializes volumes in non-cylindrical tanks
346
- **---------------------------------------------------------------
347
- */
348
- {
349
- Network *net = &pr->network;
350
-
351
- int i, j, n = 0;
352
- double a;
353
- int errcode = 0, levelerr;
354
- char errmsg[MAXMSG+1] = "";
355
- Stank *tank;
356
- Scurve *curve;
357
-
358
- for (j = 1; j <= net->Ntanks; j++)
359
- {
360
- tank = &net->Tank[j];
361
- if (tank->A == 0.0) continue; // Skip reservoirs
362
-
363
- // Check for valid lower/upper tank levels
364
- levelerr = 0;
365
- if (tank->H0 > tank->Hmax ||
366
- tank->Hmin > tank->Hmax ||
367
- tank->H0 < tank->Hmin
368
- ) levelerr = 1;
369
-
370
- // Check that tank heights are within volume curve
371
- i = tank->Vcurve;
372
- if (i > 0)
373
- {
374
- curve = &net->Curve[i];
375
- n = curve->Npts - 1;
376
- if (tank->Hmin < curve->X[0] || tank->Hmax > curve->X[n])
377
- {
378
- levelerr = 1;
379
- }
380
-
381
- else
382
- {
383
- // Find min., max., and initial volumes from curve
384
- tank->Vmin = interp(curve->Npts, curve->X, curve->Y, tank->Hmin);
385
- tank->Vmax = interp(curve->Npts, curve->X, curve->Y, tank->Hmax);
386
- tank->V0 = interp(curve->Npts, curve->X, curve->Y, tank->H0);
387
-
388
- // Find a "nominal" diameter for tank
389
- a = (curve->Y[n] - curve->Y[0]) / (curve->X[n] - curve->X[0]);
390
- tank->A = sqrt(4.0 * a / PI);
391
- }
392
- }
393
-
394
- // Report error in levels if found
395
- if (levelerr)
396
- {
397
- sprintf(pr->Msg, "Error 225: %s node %s", geterrmsg(225, errmsg),
398
- net->Node[tank->Node].ID);
399
- writeline(pr, pr->Msg);
400
- errcode = 200;
401
- }
402
- }
403
- return errcode;
404
- }
405
-
406
- void initunits(Project *pr)
407
- /*
408
- **--------------------------------------------------------------
409
- ** Input: none
410
- ** Output: none
411
- ** Purpose: determines unit conversion factors
412
- **--------------------------------------------------------------
413
- */
414
- {
415
- Parser *parser = &pr->parser;
416
- Report *rpt = &pr->report;
417
- Hydraul *hyd = &pr->hydraul;
418
- Quality *qual = &pr->quality;
419
- Times *time = &pr->times;
420
-
421
- double dcf, // distance conversion factor
422
- ccf, // concentration conversion factor
423
- qcf, // flow conversion factor
424
- hcf, // head conversion factor
425
- pcf, // pressure conversion factor
426
- wcf; // energy conversion factor
427
-
428
- if (parser->Unitsflag == SI) // SI units
429
- {
430
- strcpy(rpt->Field[DEMAND].Units, RptFlowUnitsTxt[parser->Flowflag]);
431
- strcpy(rpt->Field[ELEV].Units, u_METERS);
432
- strcpy(rpt->Field[HEAD].Units, u_METERS);
433
- if (parser->Pressflag == METERS) strcpy(rpt->Field[PRESSURE].Units, u_METERS);
434
- else strcpy(rpt->Field[PRESSURE].Units, u_KPA);
435
- strcpy(rpt->Field[LENGTH].Units, u_METERS);
436
- strcpy(rpt->Field[DIAM].Units, u_MMETERS);
437
- strcpy(rpt->Field[FLOW].Units, RptFlowUnitsTxt[parser->Flowflag]);
438
- strcpy(rpt->Field[VELOCITY].Units, u_MperSEC);
439
- strcpy(rpt->Field[HEADLOSS].Units, u_per1000M);
440
- strcpy(rpt->Field[FRICTION].Units, "");
441
- strcpy(rpt->Field[POWER].Units, u_KW);
442
-
443
- dcf = 1000.0 * MperFT;
444
- qcf = LPSperCFS;
445
- if (parser->Flowflag == LPM) qcf = LPMperCFS;
446
- if (parser->Flowflag == MLD) qcf = MLDperCFS;
447
- if (parser->Flowflag == CMH) qcf = CMHperCFS;
448
- if (parser->Flowflag == CMD) qcf = CMDperCFS;
449
-
450
- hcf = MperFT;
451
- if (parser->Pressflag == METERS) pcf = MperFT * hyd->SpGrav;
452
- else pcf = KPAperPSI * PSIperFT * hyd->SpGrav;
453
- wcf = KWperHP;
454
- }
455
- else // US units
456
- {
457
- strcpy(rpt->Field[DEMAND].Units, RptFlowUnitsTxt[parser->Flowflag]);
458
- strcpy(rpt->Field[ELEV].Units, u_FEET);
459
- strcpy(rpt->Field[HEAD].Units, u_FEET);
460
- strcpy(rpt->Field[PRESSURE].Units, u_PSI);
461
- strcpy(rpt->Field[LENGTH].Units, u_FEET);
462
- strcpy(rpt->Field[DIAM].Units, u_INCHES);
463
- strcpy(rpt->Field[FLOW].Units, RptFlowUnitsTxt[parser->Flowflag]);
464
- strcpy(rpt->Field[VELOCITY].Units, u_FTperSEC);
465
- strcpy(rpt->Field[HEADLOSS].Units, u_per1000FT);
466
- strcpy(rpt->Field[FRICTION].Units, "");
467
- strcpy(rpt->Field[POWER].Units, u_HP);
468
-
469
- dcf = 12.0;
470
- qcf = 1.0;
471
- if (parser->Flowflag == GPM) qcf = GPMperCFS;
472
- if (parser->Flowflag == MGD) qcf = MGDperCFS;
473
- if (parser->Flowflag == IMGD) qcf = IMGDperCFS;
474
- if (parser->Flowflag == AFD) qcf = AFDperCFS;
475
- hcf = 1.0;
476
- pcf = PSIperFT * hyd->SpGrav;
477
- wcf = 1.0;
478
- }
479
-
480
- strcpy(rpt->Field[QUALITY].Units, "");
481
- ccf = 1.0;
482
- if (qual->Qualflag == CHEM)
483
- {
484
- ccf = 1.0 / LperFT3;
485
- strncpy(rpt->Field[QUALITY].Units, qual->ChemUnits, MAXID);
486
- strncpy(rpt->Field[REACTRATE].Units, qual->ChemUnits, MAXID);
487
- strcat(rpt->Field[REACTRATE].Units, t_PERDAY);
488
- }
489
- else if (qual->Qualflag == AGE) strcpy(rpt->Field[QUALITY].Units, u_HOURS);
490
- else if (qual->Qualflag == TRACE) strcpy(rpt->Field[QUALITY].Units, u_PERCENT);
491
-
492
- pr->Ucf[DEMAND] = qcf;
493
- pr->Ucf[ELEV] = hcf;
494
- pr->Ucf[HEAD] = hcf;
495
- pr->Ucf[PRESSURE] = pcf;
496
- pr->Ucf[QUALITY] = ccf;
497
- pr->Ucf[LENGTH] = hcf;
498
- pr->Ucf[DIAM] = dcf;
499
- pr->Ucf[FLOW] = qcf;
500
- pr->Ucf[VELOCITY] = hcf;
501
- pr->Ucf[HEADLOSS] = hcf;
502
- pr->Ucf[LINKQUAL] = ccf;
503
- pr->Ucf[REACTRATE] = ccf;
504
- pr->Ucf[FRICTION] = 1.0;
505
- pr->Ucf[POWER] = wcf;
506
- pr->Ucf[VOLUME] = hcf * hcf * hcf;
507
-
508
- // Report time in minutes if hyd. time step < 1/2 hr.
509
- if (time->Hstep < 1800)
510
- {
511
- pr->Ucf[TIME] = 1.0 / 60.0;
512
- strcpy(rpt->Field[TIME].Units, u_MINUTES);
513
- }
514
- else
515
- {
516
- pr->Ucf[TIME] = 1.0 / 3600.0;
517
- strcpy(rpt->Field[TIME].Units, u_HOURS);
518
- }
519
- }
520
-
521
- void convertunits(Project *pr)
522
- /*
523
- **--------------------------------------------------------------
524
- ** Input: none
525
- ** Output: none
526
- ** Purpose: converts units of input data
527
- **--------------------------------------------------------------
528
- */
529
- {
530
- Network *net = &pr->network;
531
- Hydraul *hyd = &pr->hydraul;
532
- Quality *qual = &pr->quality;
533
- Parser *parser = &pr->parser;
534
-
535
- int i, j, k;
536
- double ucf; // Unit conversion factor
537
- Pdemand demand; // Pointer to demand record
538
- Snode *node;
539
- Stank *tank;
540
- Slink *link;
541
- Spump *pump;
542
- Scontrol *control;
543
-
544
- // Convert nodal elevations & initial WQ
545
- // (WQ source units are converted in QUALITY.C
546
- for (i = 1; i <= net->Nnodes; i++)
547
- {
548
- node = &net->Node[i];
549
- node->El /= pr->Ucf[ELEV];
550
- node->C0 /= pr->Ucf[QUALITY];
551
- }
552
-
553
- // Convert demands
554
- for (i = 1; i <= net->Njuncs; i++)
555
- {
556
- node = &net->Node[i];
557
- for (demand = node->D; demand != NULL; demand = demand->next)
558
- {
559
- demand->Base /= pr->Ucf[DEMAND];
560
- }
561
- }
562
-
563
- // Convert PDA pressure limits
564
- hyd->Pmin /= pr->Ucf[PRESSURE];
565
- hyd->Preq /= pr->Ucf[PRESSURE];
566
-
567
- // Convert emitter discharge coeffs. to head loss coeff.
568
- ucf = pow(pr->Ucf[FLOW], hyd->Qexp) / pr->Ucf[PRESSURE];
569
- for (i = 1; i <= net->Njuncs; i++)
570
- {
571
- node = &net->Node[i];
572
- if (node->Ke > 0.0) node->Ke = ucf / pow(node->Ke, hyd->Qexp);
573
- }
574
-
575
- // Initialize tank variables (convert tank levels to elevations)
576
- for (j = 1; j <= net->Ntanks; j++)
577
- {
578
- tank = &net->Tank[j];
579
- i = tank->Node;
580
- node = &net->Node[i];
581
- tank->H0 = node->El + tank->H0 / pr->Ucf[ELEV];
582
- tank->Hmin = node->El + tank->Hmin / pr->Ucf[ELEV];
583
- tank->Hmax = node->El + tank->Hmax / pr->Ucf[ELEV];
584
- tank->A = PI * SQR(tank->A / pr->Ucf[ELEV]) / 4.0;
585
- tank->V0 /= pr->Ucf[VOLUME];
586
- tank->Vmin /= pr->Ucf[VOLUME];
587
- tank->Vmax /= pr->Ucf[VOLUME];
588
- tank->Kb /= SECperDAY;
589
- tank->V = tank->V0;
590
- tank->C = node->C0;
591
- tank->V1max *= tank->Vmax;
592
- }
593
-
594
- // Convert hydraulic convergence criteria
595
- hyd->FlowChangeLimit /= pr->Ucf[FLOW];
596
- hyd->HeadErrorLimit /= pr->Ucf[HEAD];
597
-
598
- // Convert water quality concentration options
599
- qual->Climit /= pr->Ucf[QUALITY];
600
- qual->Ctol /= pr->Ucf[QUALITY];
601
-
602
- // Convert global reaction coeffs.
603
- qual->Kbulk /= SECperDAY;
604
- qual->Kwall /= SECperDAY;
605
-
606
- // Convert units of link parameters
607
- for (k = 1; k <= net->Nlinks; k++)
608
- {
609
- link = &net->Link[k];
610
- if (link->Type <= PIPE)
611
- {
612
- // Convert D-W roughness from millifeet (or mm) to ft
613
- if (hyd->Formflag == DW) link->Kc /= (1000.0 * pr->Ucf[ELEV]);
614
- link->Diam /= pr->Ucf[DIAM];
615
- link->Len /= pr->Ucf[LENGTH];
616
-
617
- // Convert minor loss coeff. from V^2/2g basis to Q^2 basis
618
- link->Km = 0.02517 * link->Km / SQR(link->Diam) / SQR(link->Diam);
619
-
620
- // Convert units on reaction coeffs.
621
- link->Kb /= SECperDAY;
622
- link->Kw /= SECperDAY;
623
- }
624
-
625
- else if (link->Type == PUMP)
626
- {
627
- // Convert units for pump curve parameters
628
- i = findpump(net, k);
629
- pump = &net->Pump[i];
630
- if (pump->Ptype == CONST_HP)
631
- {
632
- // For constant hp pump, convert kw to hp
633
- if (parser->Unitsflag == SI) pump->R /= pr->Ucf[POWER];
634
- }
635
- else
636
- {
637
- // For power curve pumps, convert shutoff head and flow coeff.
638
- if (pump->Ptype == POWER_FUNC)
639
- {
640
- pump->H0 /= pr->Ucf[HEAD];
641
- pump->R *= (pow(pr->Ucf[FLOW], pump->N) / pr->Ucf[HEAD]);
642
- }
643
-
644
- // Convert flow range & max. head units
645
- pump->Q0 /= pr->Ucf[FLOW];
646
- pump->Qmax /= pr->Ucf[FLOW];
647
- pump->Hmax /= pr->Ucf[HEAD];
648
- }
649
- }
650
- else
651
- {
652
- // For flow control valves, convert flow setting
653
- // while for other valves convert pressure setting
654
- link->Diam /= pr->Ucf[DIAM];
655
- link->Km = 0.02517 * link->Km / SQR(link->Diam) / SQR(link->Diam);
656
- if (link->Kc != MISSING) switch (link->Type)
657
- {
658
- case FCV:
659
- link->Kc /= pr->Ucf[FLOW];
660
- break;
661
- case PRV:
662
- case PSV:
663
- case PBV:
664
- link->Kc /= pr->Ucf[PRESSURE];
665
- break;
666
- default:
667
- break;
668
- }
669
- }
670
- }
671
-
672
- // Convert units on control settings
673
- for (i = 1; i <= net->Ncontrols; i++)
674
- {
675
- control = &net->Control[i];
676
- if ((k = control->Link) == 0) continue;
677
- link = &net->Link[k];
678
- if ((j = control->Node) > 0)
679
- {
680
- node = &net->Node[j];
681
- // control is based on tank level
682
- if (j > net->Njuncs)
683
- {
684
- control->Grade = node->El + control->Grade / pr->Ucf[ELEV];
685
- }
686
- // control is based on nodal pressure
687
- else control->Grade = node->El + control->Grade / pr->Ucf[PRESSURE];
688
- }
689
-
690
- // Convert units on valve settings
691
- if (control->Setting != MISSING)
692
- {
693
- switch (link->Type)
694
- {
695
- case PRV:
696
- case PSV:
697
- case PBV:
698
- control->Setting /= pr->Ucf[PRESSURE];
699
- break;
700
- case FCV:
701
- control->Setting /= pr->Ucf[FLOW];
702
- default:
703
- break;
704
- }
705
- }
706
- }
707
- }