epyt-flow 0.13.1__py3-none-any.whl → 0.14.1__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 (63) hide show
  1. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +40 -8
  2. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +3 -3
  3. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +24 -7
  4. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +726 -374
  5. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +128 -32
  6. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +7 -1
  7. epyt_flow/EPANET/EPANET/SRC_engines/flowbalance.c +186 -0
  8. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +40 -14
  9. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +177 -177
  10. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +28 -28
  11. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +192 -40
  12. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +101 -46
  13. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +85 -24
  14. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +29 -63
  15. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +70 -37
  16. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +408 -234
  17. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +87 -37
  18. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +153 -79
  19. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +59 -94
  20. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +73 -202
  21. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +446 -351
  22. epyt_flow/EPANET/EPANET/SRC_engines/leakage.c +527 -0
  23. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +8 -4
  24. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +23 -23
  25. epyt_flow/EPANET/EPANET/SRC_engines/output.c +5 -4
  26. epyt_flow/EPANET/EPANET/SRC_engines/project.c +407 -75
  27. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +12 -2
  28. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +70 -13
  29. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +7 -5
  30. epyt_flow/EPANET/EPANET/SRC_engines/report.c +88 -20
  31. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +144 -6
  32. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +19 -19
  33. epyt_flow/EPANET/EPANET/SRC_engines/text.h +16 -5
  34. epyt_flow/EPANET/EPANET/SRC_engines/types.h +73 -19
  35. epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.c +59 -0
  36. epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.h +38 -0
  37. epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.c +92 -0
  38. epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.h +39 -0
  39. epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.c +212 -0
  40. epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.h +81 -0
  41. epyt_flow/EPANET/EPANET/SRC_engines/validate.c +408 -0
  42. epyt_flow/EPANET/compile_linux.sh +1 -1
  43. epyt_flow/EPANET/compile_macos.sh +2 -2
  44. epyt_flow/VERSION +1 -1
  45. epyt_flow/__init__.py +1 -1
  46. epyt_flow/gym/scenario_control_env.py +26 -3
  47. epyt_flow/simulation/backend/my_epyt.py +58 -13
  48. epyt_flow/simulation/events/quality_events.py +6 -6
  49. epyt_flow/simulation/events/sensor_faults.py +24 -24
  50. epyt_flow/simulation/events/system_event.py +3 -3
  51. epyt_flow/simulation/scada/scada_data.py +10 -14
  52. epyt_flow/simulation/scenario_simulator.py +100 -20
  53. epyt_flow/topology.py +8 -1
  54. epyt_flow/uncertainty/model_uncertainty.py +292 -150
  55. epyt_flow/uncertainty/uncertainties.py +2 -2
  56. {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/METADATA +4 -4
  57. {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/RECORD +60 -54
  58. {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/WHEEL +1 -1
  59. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +0 -18
  60. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +0 -131
  61. epyt_flow/EPANET/EPANET/SRC_engines/main.c +0 -93
  62. {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/licenses/LICENSE +0 -0
  63. {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,13 @@
1
1
  /*
2
2
  ******************************************************************************
3
3
  Project: OWA EPANET
4
- Version: 2.2
4
+ Version: 2.3
5
5
  Module: inpfile.c
6
6
  Description: saves network data to an EPANET formatted text file
7
7
  Authors: see AUTHORS
8
8
  Copyright: see AUTHORS
9
9
  License: see LICENSE
10
- Last Updated: 10/29/2019
10
+ Last Updated: 04/19/2025
11
11
  ******************************************************************************
12
12
  */
13
13
 
@@ -33,17 +33,18 @@ extern char *MixTxt[];
33
33
  extern char *TstatTxt[];
34
34
  extern char *RptFlagTxt[];
35
35
  extern char *SectTxt[];
36
+ extern char *BackflowTxt[];
37
+ extern char *CurveTypeTxt[];
36
38
 
37
39
  void saveauxdata(Project *pr, FILE *f)
38
40
  /*
39
41
  ------------------------------------------------------------
40
- Writes auxilary data from original input file to new file.
42
+ Writes auxiliary data from original input file to new file.
41
43
  ------------------------------------------------------------
42
44
  */
43
45
  {
44
46
  int sect, newsect;
45
47
  char *tok;
46
- char write;
47
48
  char line[MAXLINE + 1];
48
49
  char s[MAXLINE + 1];
49
50
  FILE *InFile = pr->parser.InFile;
@@ -78,31 +79,23 @@ void saveauxdata(Project *pr, FILE *f)
78
79
  {
79
80
  case _LABELS:
80
81
  case _BACKDROP:
81
- case _TAGS:
82
82
  fprintf(f, "\n%s", line);
83
83
  }
84
84
  }
85
85
  }
86
86
 
87
- // Write line of auxilary data to file
87
+ // Write line of auxiliary data to file
88
88
  else
89
89
  {
90
- write = FALSE;
91
90
  switch (sect)
92
91
  {
93
- case _TAGS:
94
- if (*tok == ';' ||
95
- (match("NODE", tok) && findnode(&pr->network, strtok(NULL, SEPSTR))) ||
96
- (match("LINK", tok) && findlink(&pr->network, strtok(NULL, SEPSTR))))
97
- write = TRUE;
98
- break;
99
92
  case _LABELS:
100
93
  case _BACKDROP:
101
- write = TRUE; break;
94
+ fprintf(f, "%s", line);
95
+ break;
102
96
  default:
103
97
  break;
104
98
  }
105
- if (write) fprintf(f, "%s", line);
106
99
  }
107
100
  }
108
101
  fclose(InFile);
@@ -151,40 +144,46 @@ int saveinpfile(Project *pr, const char *fname)
151
144
  // (Leave demands for [DEMANDS] section)
152
145
  fprintf(f, "\n\n");
153
146
  fprintf(f, s_JUNCTIONS);
147
+ fprintf(f, "\n;;%-31s\t%-12s\t%-12s\t%-31s",
148
+ "ID", "Elev", "Demand", "Pattern");
154
149
  for (i = 1; i <= net->Njuncs; i++)
155
150
  {
156
151
  node = &net->Node[i];
157
- fprintf(f, "\n %-31s %12.4f", node->ID, node->El * pr->Ucf[ELEV]);
158
- if (node->Comment) fprintf(f, " ;%s", node->Comment);
152
+ fprintf(f, "\n %-31s\t%-12.4f", node->ID, node->El * pr->Ucf[ELEV]);
153
+ if (node->Comment) fprintf(f, "\t;%s", node->Comment);
159
154
  }
160
155
 
161
156
  // Write [RESERVOIRS] section
162
157
  fprintf(f, "\n\n");
163
158
  fprintf(f, s_RESERVOIRS);
159
+ fprintf(f, "\n;;%-31s\t%-12s\t%-31s",
160
+ "ID", "Head", "Pattern");
164
161
  for (i = 1; i <= net->Ntanks; i++)
165
162
  {
166
163
  tank = &net->Tank[i];
167
164
  if (tank->A == 0.0)
168
165
  {
169
166
  node = &net->Node[tank->Node];
170
- sprintf(s, " %-31s %12.4f", node->ID, node->El * pr->Ucf[ELEV]);
171
- if ((j = tank->Pat) > 0) sprintf(s1, " %s", net->Pattern[j].ID);
167
+ sprintf(s, " %-31s\t%-12.4f", node->ID, node->El * pr->Ucf[ELEV]);
168
+ if ((j = tank->Pat) > 0) sprintf(s1, "%s", net->Pattern[j].ID);
172
169
  else strcpy(s1, " ");
173
- fprintf(f, "\n%s %-31s", s, s1);
174
- if (node->Comment) fprintf(f, " ;%s", node->Comment);
170
+ fprintf(f, "\n%s\t%-31s", s, s1);
171
+ if (node->Comment) fprintf(f, "\t;%s", node->Comment);
175
172
  }
176
173
  }
177
174
 
178
175
  // Write [TANKS] section
179
176
  fprintf(f, "\n\n");
180
177
  fprintf(f, s_TANKS);
178
+ fprintf(f, "\n;;%-31s\t%-12s\t%-12s\t%-12s\t%-12s\t%-12s\t%-12s\t%-31s\t%-12s",
179
+ "ID", "Elevation", "InitLevel", "MinLevel", "MaxLevel", "Diameter", "MinVol", "VolCurve", "Overflow");
181
180
  for (i = 1; i <= net->Ntanks; i++)
182
181
  {
183
182
  tank = &net->Tank[i];
184
183
  if (tank->A > 0.0)
185
184
  {
186
185
  node = &net->Node[tank->Node];
187
- sprintf(s, " %-31s %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f",
186
+ sprintf(s, " %-31s\t%-12.4f\t%-12.4f\t%-12.4f\t%-12.4f\t%-12.4f\t%-12.4f",
188
187
  node->ID, node->El * pr->Ucf[ELEV],
189
188
  (tank->H0 - node->El) * pr->Ucf[ELEV],
190
189
  (tank->Hmin - node->El) * pr->Ucf[ELEV],
@@ -194,55 +193,59 @@ int saveinpfile(Project *pr, const char *fname)
194
193
  if ((j = tank->Vcurve) > 0) sprintf(s1, "%s", net->Curve[j].ID);
195
194
  else if (tank->CanOverflow) strcpy(s1, "*");
196
195
  else strcpy(s1, " ");
197
- fprintf(f, "\n%s %-31s", s, s1);
198
- if (tank->CanOverflow) fprintf(f, " YES ");
199
- if (node->Comment) fprintf(f, " ;%s", node->Comment);
196
+ fprintf(f, "\n%s\t%-31s", s, s1);
197
+ if (tank->CanOverflow) fprintf(f, "\t%-12s", "YES");
198
+ if (node->Comment) fprintf(f, "\t;%s", node->Comment);
200
199
  }
201
200
  }
202
201
 
203
202
  // Write [PIPES] section
204
203
  fprintf(f, "\n\n");
205
204
  fprintf(f, s_PIPES);
205
+ fprintf(f, "\n;;%-31s\t%-31s\t%-31s\t%-12s\t%-12s\t%-12s\t%-12s\t%-6s",
206
+ "ID", "Node1", "Node2", "Length", "Diameter", "Roughness", "MinorLoss", "Status");
206
207
  for (i = 1; i <= net->Nlinks; i++)
207
208
  {
208
209
  link = &net->Link[i];
209
210
  if (link->Type <= PIPE)
210
211
  {
211
212
  d = link->Diam;
212
- kc = link->Kc;
213
+ kc = link->InitSetting;
213
214
  if (hyd->Formflag == DW) kc = kc * pr->Ucf[ELEV] * 1000.0;
214
215
  km = link->Km * SQR(d) * SQR(d) / 0.02517;
215
216
 
216
- sprintf(s, " %-31s %-31s %-31s %12.4f %12.4f %12.4f %12.4f",
217
+ sprintf(s, " %-31s\t%-31s\t%-31s\t%-12.4f\t%-12.4f\t%-12.4f\t%-12.4f",
217
218
  link->ID, net->Node[link->N1].ID, net->Node[link->N2].ID,
218
219
  link->Len * pr->Ucf[LENGTH], d * pr->Ucf[DIAM], kc, km);
219
220
 
220
221
  if (link->Type == CVPIPE) sprintf(s2, "CV");
221
- else if (link->Status == CLOSED) sprintf(s2, "CLOSED");
222
+ else if (link->InitStatus == CLOSED) sprintf(s2, "CLOSED");
222
223
  else strcpy(s2, " ");
223
- fprintf(f, "\n%s %-6s", s, s2);
224
- if (link->Comment) fprintf(f, " ;%s", link->Comment);
224
+ fprintf(f, "\n%s\t%-6s", s, s2);
225
+ if (link->Comment) fprintf(f, "\t;%s", link->Comment);
225
226
  }
226
227
  }
227
228
 
228
229
  // Write [PUMPS] section
229
230
  fprintf(f, "\n\n");
230
231
  fprintf(f, s_PUMPS);
232
+ fprintf(f, "\n;;%-31s\t%-31s\t%-31s\t%-12s",
233
+ "ID", "Node1", "Node2", "Parameters");
231
234
  for (i = 1; i <= net->Npumps; i++)
232
235
  {
233
236
  n = net->Pump[i].Link;
234
237
  link = &net->Link[n];
235
238
  pump = &net->Pump[i];
236
- sprintf(s, " %-31s %-31s %-31s", link->ID, net->Node[link->N1].ID,
239
+ sprintf(s, " %-31s\t%-31s\t%-31s", link->ID, net->Node[link->N1].ID,
237
240
  net->Node[link->N2].ID);
238
241
 
239
242
  // Pump has constant power
240
- if (pump->Ptype == CONST_HP) sprintf(s1, " POWER %.4f", link->Km);
243
+ if (pump->Ptype == CONST_HP) sprintf(s1, "\tPOWER %.4f", link->Km);
241
244
 
242
245
  // Pump has a head curve
243
246
  else if ((j = pump->Hcurve) > 0)
244
247
  {
245
- sprintf(s1, " HEAD %s", net->Curve[j].ID);
248
+ sprintf(s1, "\tHEAD %s", net->Curve[j].ID);
246
249
  }
247
250
 
248
251
  // Old format used for pump curve
@@ -259,25 +262,26 @@ int saveinpfile(Project *pr, const char *fname)
259
262
  // Optional speed pattern
260
263
  if ((j = pump->Upat) > 0)
261
264
  {
262
- sprintf(s1, " PATTERN %s", net->Pattern[j].ID);
265
+ sprintf(s1, "\tPATTERN %s", net->Pattern[j].ID);
263
266
  strcat(s, s1);
264
267
  }
265
268
 
266
269
  // Optional speed setting
267
- if (link->Kc != 1.0)
270
+ if (link->InitSetting != 1.0)
268
271
  {
269
- sprintf(s1, " SPEED %.4f", link->Kc);
272
+ sprintf(s1, "\tSPEED %.4f", link->InitSetting);
270
273
  strcat(s, s1);
271
274
  }
272
275
 
273
276
  fprintf(f, "\n%s", s);
274
- if (link->Comment) fprintf(f, " ;%s", link->Comment);
275
-
277
+ if (link->Comment) fprintf(f, "\t;%s", link->Comment);
276
278
  }
277
279
 
278
280
  // Write [VALVES] section
279
281
  fprintf(f, "\n\n");
280
282
  fprintf(f, s_VALVES);
283
+ fprintf(f, "\n;;%-31s\t%-31s\t%-31s\t%-12s\t%-6s\t%-12s\t%-12s",
284
+ "ID", "Node1", "Node2", "Diameter", "Type", "Setting", "MinorLoss");
281
285
  for (i = 1; i <= net->Nvalves; i++)
282
286
  {
283
287
  n = net->Valve[i].Link;
@@ -285,8 +289,7 @@ int saveinpfile(Project *pr, const char *fname)
285
289
  d = link->Diam;
286
290
 
287
291
  // Valve setting
288
- kc = link->Kc;
289
- if (kc == MISSING) kc = 0.0;
292
+ kc = link->InitSetting;
290
293
  switch (link->Type)
291
294
  {
292
295
  case FCV:
@@ -302,36 +305,44 @@ int saveinpfile(Project *pr, const char *fname)
302
305
  }
303
306
  km = link->Km * SQR(d) * SQR(d) / 0.02517;
304
307
 
305
- sprintf(s, " %-31s %-31s %-31s %12.4f %5s",
308
+ sprintf(s, " %-31s\t%-31s\t%-31s\t%-12.4f\t%-6s",
306
309
  link->ID, net->Node[link->N1].ID,
307
310
  net->Node[link->N2].ID, d * pr->Ucf[DIAM],
308
311
  LinkTxt[link->Type]);
309
312
 
310
313
  // For GPV, setting = head curve index
311
- if (link->Type == GPV && (j = ROUND(link->Kc)) > 0)
314
+ if (link->Type == GPV && (j = ROUND(kc)) > 0)
315
+ {
316
+ sprintf(s1, "%-31s\t%-12.4f", net->Curve[j].ID, km);
317
+ }
318
+ // For PCV add loss curve if present
319
+ else if (link->Type == PCV && (j = net->Valve[i].Curve) > 0)
312
320
  {
313
- sprintf(s1, "%-31s %12.4f", net->Curve[j].ID, km);
321
+ sprintf(s1, "%-12.4f\t%-12.4f\t%-31s", kc, km, net->Curve[j].ID);
314
322
  }
315
- else sprintf(s1, "%12.4f %12.4f", kc, km);
316
- fprintf(f, "\n%s %s", s, s1);
317
- if (link->Comment) fprintf(f, " ;%s", link->Comment);
323
+ else sprintf(s1, "%-12.4f\t%-12.4f", kc, km);
324
+ fprintf(f, "\n%s\t%s", s, s1);
325
+ if (link->Comment) fprintf(f, "\t;%s", link->Comment);
318
326
  }
319
327
 
320
328
 
321
329
  // Write [DEMANDS] section
322
330
  fprintf(f, "\n\n");
323
331
  fprintf(f, s_DEMANDS);
332
+ fprintf(f, "\n;;%-31s\t%-14s\t%-31s\t%-31s",
333
+ "Junction", "Demand", "Pattern", "Category");
324
334
  ucf = pr->Ucf[DEMAND];
325
335
  for (i = 1; i <= net->Njuncs; i++)
326
336
  {
327
337
  node = &net->Node[i];
328
338
  for (demand = node->D; demand != NULL; demand = demand->next)
329
339
  {
330
- sprintf(s, " %-31s %14.6f", node->ID, ucf * demand->Base);
331
- if ((j = demand->Pat) > 0) sprintf(s1, " %-31s", net->Pattern[j].ID);
340
+ if (demand->Base == 0.0) continue;
341
+ sprintf(s, " %-31s\t%-14.6f", node->ID, ucf * demand->Base);
342
+ if ((j = demand->Pat) > 0) sprintf(s1, "%-31s", net->Pattern[j].ID);
332
343
  else strcpy(s1, " ");
333
- fprintf(f, "\n%s %-31s", s, s1);
334
- if (demand->Name) fprintf(f, " ;%s", demand->Name);
344
+ fprintf(f, "\n%s\t%-31s", s, s1);
345
+ if (demand->Name) fprintf(f, "\t;%s", demand->Name);
335
346
  }
336
347
  }
337
348
 
@@ -339,25 +350,42 @@ int saveinpfile(Project *pr, const char *fname)
339
350
  // Write [EMITTERS] section
340
351
  fprintf(f, "\n\n");
341
352
  fprintf(f, s_EMITTERS);
353
+ fprintf(f, "\n;;%-31s\t%-14s",
354
+ "Junction", "Coefficient");
342
355
  for (i = 1; i <= net->Njuncs; i++)
343
356
  {
344
357
  node = &net->Node[i];
345
358
  if (node->Ke == 0.0) continue;
346
359
  ke = pr->Ucf[FLOW] / pow(pr->Ucf[PRESSURE] * node->Ke, (1.0 / hyd->Qexp));
347
- fprintf(f, "\n %-31s %14.6f", node->ID, ke);
360
+ fprintf(f, "\n %-31s\t%-14.6f", node->ID, ke);
361
+ }
362
+
363
+ // Write [LEAKAGE] section
364
+ fprintf(f, "\n\n");
365
+ fprintf(f, s_LEAKAGE);
366
+ fprintf(f, "\n;;%-31s\t%-14s\t%-14s",
367
+ "Pipe", "Leak Area", "Leak Expansion");
368
+ for (i = 1; i <= net->Nlinks; i++)
369
+ {
370
+ link = &net->Link[i];
371
+ if (link->LeakArea == 0.0 && link->LeakExpan == 0.0) continue;
372
+ fprintf(f, "\n %-31s %14.6f %14.6f", link->ID,
373
+ link->LeakArea * pr->Ucf[LENGTH], link->LeakExpan * pr->Ucf[LENGTH]);
348
374
  }
349
375
 
350
376
  // Write [STATUS] section
351
377
  fprintf(f, "\n\n");
352
378
  fprintf(f, s_STATUS);
379
+ fprintf(f, "\n;;%-31s\t%-12s",
380
+ "ID", "Status/Setting");
353
381
  for (i = 1; i <= net->Nlinks; i++)
354
382
  {
355
383
  link = &net->Link[i];
356
384
  if (link->Type <= PUMP)
357
385
  {
358
- if (link->Status == CLOSED)
386
+ if (link->InitStatus == CLOSED)
359
387
  {
360
- fprintf(f, "\n %-31s %s", link->ID, StatTxt[CLOSED]);
388
+ fprintf(f, "\n %-31s\t%s", link->ID, StatTxt[CLOSED]);
361
389
  }
362
390
 
363
391
  // Write pump speed here for pumps with old-style pump curve input
@@ -366,23 +394,23 @@ int saveinpfile(Project *pr, const char *fname)
366
394
  n = findpump(net, i);
367
395
  pump = &net->Pump[n];
368
396
  if (pump->Hcurve == 0 && pump->Ptype != CONST_HP &&
369
- link->Kc != 1.0)
397
+ link->InitSetting != 1.0)
370
398
  {
371
- fprintf(f, "\n %-31s %-.4f", link->ID, link->Kc);
399
+ fprintf(f, "\n %-31s\t%-.4f", link->ID, link->InitSetting);
372
400
  }
373
401
  }
374
402
  }
375
403
 
376
- // Write fixed-status PRVs & PSVs (setting = MISSING)
377
- else if (link->Kc == MISSING)
404
+ // Write fixed-status valves
405
+ else
378
406
  {
379
- if (link->Status == OPEN)
407
+ if (link->InitStatus == OPEN)
380
408
  {
381
- fprintf(f, "\n %-31s %s", link->ID, StatTxt[OPEN]);
409
+ fprintf(f, "\n %-31s\t%s", link->ID, StatTxt[OPEN]);
382
410
  }
383
- if (link->Status == CLOSED)
411
+ if (link->InitStatus == CLOSED)
384
412
  {
385
- fprintf(f, "\n%-31s %s", link->ID, StatTxt[CLOSED]);
413
+ fprintf(f, "\n%-31s\t%s", link->ID, StatTxt[CLOSED]);
386
414
  }
387
415
  }
388
416
  }
@@ -391,26 +419,35 @@ int saveinpfile(Project *pr, const char *fname)
391
419
  // (Use 6 pattern factors per line)
392
420
  fprintf(f, "\n\n");
393
421
  fprintf(f, s_PATTERNS);
422
+ fprintf(f, "\n;;%-31s\t%-12s",
423
+ "ID", "Multipliers");
394
424
  for (i = 1; i <= net->Npats; i++)
395
425
  {
396
426
  if (net->Pattern[i].Comment) fprintf(f, "\n;%s", net->Pattern[i].Comment);
397
427
  for (j = 0; j < net->Pattern[i].Length; j++)
398
428
  {
399
429
  if (j % 6 == 0) fprintf(f, "\n %-31s", net->Pattern[i].ID);
400
- fprintf(f, " %12.4f", net->Pattern[i].F[j]);
430
+ fprintf(f, "\t%-12.4f", net->Pattern[i].F[j]);
401
431
  }
402
432
  }
403
433
 
404
434
  // Write [CURVES] section
405
435
  fprintf(f, "\n\n");
406
436
  fprintf(f, s_CURVES);
437
+ fprintf(f, "\n;;%-31s\t%-12s\t%-12s", "ID", "X-Value", "Y-Value");
407
438
  for (i = 1; i <= net->Ncurves; i++)
408
439
  {
409
- if (net->Curve[i].Comment) fprintf(f, "\n;%s", net->Curve[i].Comment);
410
- for (j = 0; j < net->Curve[i].Npts; j++)
440
+ curve = &net->Curve[i];
441
+ if (curve->Comment) fprintf(f, "\n;%s", curve->Comment);
442
+ if (curve->Npts > 0)
411
443
  {
412
- curve = &net->Curve[i];
413
- fprintf(f, "\n %-31s %12.4f %12.4f", curve->ID, curve->X[j], curve->Y[j]);
444
+ fprintf(f, "\n %-31s\t%-12.4f\t%-12.4f\t%s", curve->ID,
445
+ curve->X[0], curve->Y[0], CurveTypeTxt[curve->Type]);
446
+ for (j = 1; j < curve->Npts; j++)
447
+ {
448
+ fprintf(f, "\n %-31s\t%-12.4f\t%-12.4f", curve->ID,
449
+ curve->X[j], curve->Y[j]);
450
+ }
414
451
  }
415
452
  }
416
453
 
@@ -425,7 +462,12 @@ int saveinpfile(Project *pr, const char *fname)
425
462
  link = &net->Link[j];
426
463
 
427
464
  // Get text of control's link status/setting
428
- if (control->Setting == MISSING)
465
+ if (control->Setting == MISSING || link->Type == GPV || link->Type == PIPE)
466
+ {
467
+ sprintf(s, " LINK %s %s ", link->ID, StatTxt[control->Status]);
468
+ }
469
+ else if (link->Type == PUMP &&
470
+ (control->Setting == 0.0 || control->Setting == 1.0))
429
471
  {
430
472
  sprintf(s, " LINK %s %s ", link->ID, StatTxt[control->Status]);
431
473
  }
@@ -473,7 +515,10 @@ int saveinpfile(Project *pr, const char *fname)
473
515
  fprintf(f, "\n%s AT %s %s", s, ControlTxt[TIMEOFDAY],
474
516
  clocktime(rpt->Atime, control->Time));
475
517
  break;
518
+
519
+ default: continue;
476
520
  }
521
+ if (control->isEnabled == FALSE) fprintf(f, " DISABLED");
477
522
  }
478
523
 
479
524
  // Write [RULES] section
@@ -483,6 +528,7 @@ int saveinpfile(Project *pr, const char *fname)
483
528
  {
484
529
  fprintf(f, "\nRULE %s", pr->network.Rule[i].label);
485
530
  writerule(pr, f, i); // see RULES.C
531
+ if (pr->network.Rule[i].isEnabled == FALSE) fprintf(f, "\nDISABLED");
486
532
  fprintf(f, "\n");
487
533
  }
488
534
 
@@ -490,40 +536,43 @@ int saveinpfile(Project *pr, const char *fname)
490
536
  // (Skip nodes with default quality of 0)
491
537
  fprintf(f, "\n\n");
492
538
  fprintf(f, s_QUALITY);
539
+ fprintf(f, "\n;;%-31s\t%-14s", "ID", "InitQual");
493
540
  for (i = 1; i <= net->Nnodes; i++)
494
541
  {
495
542
  node = &net->Node[i];
496
543
  if (node->C0 == 0.0) continue;
497
- fprintf(f, "\n %-31s %14.6f", node->ID, node->C0 * pr->Ucf[QUALITY]);
544
+ fprintf(f, "\n %-31s\t%-14.6f", node->ID, node->C0 * pr->Ucf[QUALITY]);
498
545
  }
499
546
 
500
547
  // Write [SOURCES] section
501
548
  fprintf(f, "\n\n");
502
549
  fprintf(f, s_SOURCES);
550
+ fprintf(f, "\n;;%-31s\t%-9s\t%-14s\t%-31s", "ID", "Type", "Quality", "Pattern");
503
551
  for (i = 1; i <= net->Nnodes; i++)
504
552
  {
505
553
  node = &net->Node[i];
506
554
  source = node->S;
507
555
  if (source == NULL) continue;
508
- sprintf(s, " %-31s %-8s %14.6f", node->ID, SourceTxt[source->Type],
556
+ sprintf(s, " %-31s\t%-9s\t%-14.6f", node->ID, SourceTxt[source->Type],
509
557
  source->C0);
510
558
  if ((j = source->Pat) > 0)
511
559
  {
512
560
  sprintf(s1, "%s", net->Pattern[j].ID);
513
561
  }
514
562
  else strcpy(s1, "");
515
- fprintf(f, "\n%s %s", s, s1);
563
+ fprintf(f, "\n%s\t%s", s, s1);
516
564
  }
517
565
 
518
566
  // Write [MIXING] section
519
567
  fprintf(f, "\n\n");
520
568
  fprintf(f, s_MIXING);
569
+ fprintf(f, "\n;;%-31s\t%-8s", "ID", "Model");
521
570
  for (i = 1; i <= net->Ntanks; i++)
522
571
  {
523
572
  tank = &net->Tank[i];
524
573
  if (tank->A == 0.0) continue;
525
- fprintf(f, "\n %-31s %-8s %12.4f", net->Node[tank->Node].ID,
526
- MixTxt[tank->MixModel], (tank->V1max / tank->Vmax));
574
+ fprintf(f, "\n %-31s\t%-8s\t%12.4f", net->Node[tank->Node].ID,
575
+ MixTxt[tank->MixModel], tank->V1frac);
527
576
  }
528
577
 
529
578
  // Write [REACTIONS] section
@@ -546,6 +595,10 @@ int saveinpfile(Project *pr, const char *fname)
546
595
  fprintf(f, "\n ROUGHNESS CORRELATION %-.6f", qual->Rfactor);
547
596
  }
548
597
 
598
+ fprintf(f, "\n\n");
599
+ fprintf(f, s_REACTIONS);
600
+ fprintf(f, "\n;%-9s\t%-31s\t%-12s", "Type", "Pipe/Tank", "Coefficient");
601
+
549
602
  // Pipe-specific parameters
550
603
  for (i = 1; i <= net->Nlinks; i++)
551
604
  {
@@ -553,11 +606,11 @@ int saveinpfile(Project *pr, const char *fname)
553
606
  if (link->Type > PIPE) continue;
554
607
  if (link->Kb != qual->Kbulk)
555
608
  {
556
- fprintf(f, "\n BULK %-31s %-.6f", link->ID, link->Kb * SECperDAY);
609
+ fprintf(f, "\n %-9s\t%-31s\t%-.6f", "BULK", link->ID, link->Kb * SECperDAY);
557
610
  }
558
611
  if (link->Kw != qual->Kwall)
559
612
  {
560
- fprintf(f, "\n WALL %-31s %-.6f", link->ID, link->Kw * SECperDAY);
613
+ fprintf(f, "\n %-9s\t%-31s\t%-.6f", "WALL", link->ID, link->Kw * SECperDAY);
561
614
  }
562
615
  }
563
616
 
@@ -568,7 +621,7 @@ int saveinpfile(Project *pr, const char *fname)
568
621
  if (tank->A == 0.0) continue;
569
622
  if (tank->Kb != qual->Kbulk)
570
623
  {
571
- fprintf(f, "\n TANK %-31s %-.6f", net->Node[tank->Node].ID,
624
+ fprintf(f, "\n %-9s\t%-31s\t%-.6f", "TANK", net->Node[tank->Node].ID,
572
625
  tank->Kb * SECperDAY);
573
626
  }
574
627
  }
@@ -666,8 +719,11 @@ int saveinpfile(Project *pr, const char *fname)
666
719
  break;
667
720
  }
668
721
 
722
+ if (hyd->DefPat > 0)
723
+ fprintf(f, "\n PATTERN %s", net->Pattern[hyd->DefPat].ID);
669
724
  fprintf(f, "\n DEMAND MULTIPLIER %-.4f", hyd->Dmult);
670
725
  fprintf(f, "\n EMITTER EXPONENT %-.4f", 1.0 / hyd->Qexp);
726
+ fprintf(f, "\n BACKFLOW ALLOWED %s", BackflowTxt[hyd->EmitBackFlag]);
671
727
  fprintf(f, "\n VISCOSITY %-.6f", hyd->Viscos / VISCOS);
672
728
  fprintf(f, "\n DIFFUSIVITY %-.6f", qual->Diffus / DIFFUS);
673
729
  fprintf(f, "\n SPECIFIC GRAVITY %-.6f", hyd->SpGrav);
@@ -774,32 +830,50 @@ int saveinpfile(Project *pr, const char *fname)
774
830
  }
775
831
  else fprintf(f, "\n %-20sNO",field->Name);
776
832
  }
777
-
833
+
834
+ // Write [TAGS] section
835
+ fprintf(f, "\n\n");
836
+ fprintf(f, s_TAGS);
837
+ fprintf(f, "\n;;%-8s\t%-31s\t%s", "Object", "ID", "Tag");
838
+ for (i = 1; i <= net->Nnodes; i++)
839
+ {
840
+ node = &net->Node[i];
841
+ if (node->Tag == NULL || strlen(node->Tag) == 0) continue;
842
+ fprintf(f, "\n %-8s\t%-31s\t%s", "NODE", node->ID, node->Tag);
843
+ }
844
+ for (i = 1; i <= net->Nlinks; i++)
845
+ {
846
+ link = &net->Link[i];
847
+ if (link->Tag == NULL || strlen(link->Tag) == 0) continue;
848
+ fprintf(f, "\n %-8s\t%-31s\t%s", "LINK", link->ID, link->Tag);
849
+ }
778
850
  // Write [COORDINATES] section
779
851
  fprintf(f, "\n\n");
780
852
  fprintf(f, s_COORDS);
853
+ fprintf(f, "\n;;%-31s\t%-14s\t%-14s", "ID", "X-Coord", "Y-Coord");
781
854
  for (i = 1; i <= net->Nnodes; i++)
782
855
  {
783
856
  node = &net->Node[i];
784
857
  if (node->X == MISSING || node->Y == MISSING) continue;
785
- fprintf(f, "\n %-31s %14.6f %14.6f", node->ID, node->X, node->Y);
858
+ fprintf(f, "\n %-31s\t%-14.6f\t%-14.6f", node->ID, node->X, node->Y);
786
859
  }
787
860
 
788
861
  // Write [VERTICES] section
789
862
  fprintf(f, "\n\n");
790
863
  fprintf(f, s_VERTICES);
864
+ fprintf(f, "\n;;%-31s\t%-14s\t%-14s", "ID", "X-Coord", "Y-Coord");
791
865
  for (i = 1; i <= net->Nlinks; i++)
792
866
  {
793
867
  link = &net->Link[i];
794
868
  if (link->Vertices != NULL)
795
869
  {
796
870
  for (j = 0; j < link->Vertices->Npts; j++)
797
- fprintf(f, "\n %-31s %14.6f %14.6f",
871
+ fprintf(f, "\n %-31s\t%-14.6f\t%-14.6f",
798
872
  link->ID, link->Vertices->X[j], link->Vertices->Y[j]);
799
873
  }
800
874
  }
801
875
 
802
- // Save auxilary data to new input file
876
+ // Save auxiliary data to new input file
803
877
  fprintf(f, "\n");
804
878
  saveauxdata(pr, f);
805
879