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,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
- }