epyt-flow 0.14.1__py3-none-any.whl → 0.14.2__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 (55) hide show
  1. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +8 -40
  2. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +3 -3
  3. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +18 -0
  4. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +7 -24
  5. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +374 -726
  6. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +32 -128
  7. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +131 -0
  8. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +1 -7
  9. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +14 -40
  10. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +177 -177
  11. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +28 -28
  12. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +40 -192
  13. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +46 -101
  14. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +24 -85
  15. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +63 -29
  16. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +37 -70
  17. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +234 -408
  18. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +37 -87
  19. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +79 -153
  20. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +94 -59
  21. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +202 -73
  22. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +351 -446
  23. epyt_flow/EPANET/EPANET/SRC_engines/main.c +93 -0
  24. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +4 -8
  25. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +23 -23
  26. epyt_flow/EPANET/EPANET/SRC_engines/output.c +4 -5
  27. epyt_flow/EPANET/EPANET/SRC_engines/project.c +75 -407
  28. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +2 -12
  29. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +13 -70
  30. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +5 -7
  31. epyt_flow/EPANET/EPANET/SRC_engines/report.c +20 -88
  32. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +6 -144
  33. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +19 -19
  34. epyt_flow/EPANET/EPANET/SRC_engines/text.h +5 -16
  35. epyt_flow/EPANET/EPANET/SRC_engines/types.h +19 -73
  36. epyt_flow/EPANET/compile_linux.sh +1 -1
  37. epyt_flow/EPANET/compile_macos.sh +1 -1
  38. epyt_flow/VERSION +1 -1
  39. epyt_flow/simulation/scada/scada_data.py +1 -1
  40. epyt_flow/utils.py +66 -0
  41. epyt_flow/visualization/visualization_utils.py +4 -2
  42. {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/METADATA +1 -1
  43. {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/RECORD +46 -52
  44. epyt_flow/EPANET/EPANET/SRC_engines/flowbalance.c +0 -186
  45. epyt_flow/EPANET/EPANET/SRC_engines/leakage.c +0 -527
  46. epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.c +0 -59
  47. epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.h +0 -38
  48. epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.c +0 -92
  49. epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.h +0 -39
  50. epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.c +0 -212
  51. epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.h +0 -81
  52. epyt_flow/EPANET/EPANET/SRC_engines/validate.c +0 -408
  53. {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/WHEEL +0 -0
  54. {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/licenses/LICENSE +0 -0
  55. {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,13 @@
1
1
  /*
2
2
  ******************************************************************************
3
3
  Project: OWA EPANET
4
- Version: 2.3
4
+ Version: 2.2
5
5
  Module: hydraul.c
6
6
  Description: implements EPANET's hydraulic engine
7
7
  Authors: see AUTHORS
8
8
  Copyright: see AUTHORS
9
9
  License: see LICENSE
10
- Last Updated: 04/19/2025
10
+ Last Updated: 12/05/2019
11
11
  ******************************************************************************
12
12
  */
13
13
 
@@ -23,7 +23,6 @@
23
23
  const double QZERO = 1.e-6; // Equivalent to zero flow in cfs
24
24
 
25
25
  // Imported functions
26
- extern int validateproject(Project *);
27
26
  extern int createsparse(Project *);
28
27
  extern void freesparse(Project *);
29
28
  extern int hydsolve(Project *, int *, double *);
@@ -35,11 +34,11 @@ void initlinkflow(Project *, int, char, double);
35
34
  void demands(Project *);
36
35
  int controls(Project *);
37
36
  long timestep(Project *);
37
+ void controltimestep(Project *, long *);
38
38
  void ruletimestep(Project *, long *);
39
39
  void addenergy(Project *, long);
40
40
  void tanklevels(Project *, long);
41
41
  void resetpumpflow(Project *, int);
42
- void getallpumpsenergy(Project *);
43
42
 
44
43
  int openhyd(Project *pr)
45
44
  /*
@@ -53,27 +52,33 @@ int openhyd(Project *pr)
53
52
  int i;
54
53
  int errcode = 0;
55
54
  Slink *link;
56
-
57
- // Check for valid project data (see VALIDATE.C)
58
- errcode = validateproject(pr);
59
- if (errcode > 0) return errcode;
55
+
56
+ // Check for too few nodes & no fixed grade nodes
57
+ if (pr->network.Nnodes < 2) errcode = 223;
58
+ else if (pr->network.Ntanks == 0) errcode = 224;
60
59
 
61
60
  // Allocate memory for sparse matrix structures (see SMATRIX.C)
62
61
  ERRCODE(createsparse(pr));
63
62
 
64
63
  // Allocate memory for hydraulic variables
65
64
  ERRCODE(allocmatrix(pr));
66
-
65
+
67
66
  // Check for unconnected nodes
68
- ERRCODE(unlinked(pr));
67
+ if (!errcode) for (i = 1; i <= pr->network.Njuncs; i++)
68
+ {
69
+ if (pr->network.Adjlist[i] == NULL)
70
+ {
71
+ errcode = 233;
72
+ break;
73
+ }
74
+ }
69
75
 
70
76
  // Initialize link flows
71
77
  if (!errcode) for (i = 1; i <= pr->network.Nlinks; i++)
72
78
  {
73
79
  link = &pr->network.Link[i];
74
- initlinkflow(pr, i, link->InitStatus, link->Kc);
80
+ initlinkflow(pr, i, link->Status, link->Kc);
75
81
  }
76
- else closehyd(pr);
77
82
  return errcode;
78
83
  }
79
84
 
@@ -107,10 +112,8 @@ void inithyd(Project *pr, int initflag)
107
112
  hyd->OldStatus[net->Nlinks+i] = TEMPCLOSED;
108
113
  }
109
114
 
110
- // Initialize node outflows
111
- memset(hyd->DemandFlow,0,(net->Nnodes+1)*sizeof(double));
115
+ // Initialize emitter flows
112
116
  memset(hyd->EmitterFlow,0,(net->Nnodes+1)*sizeof(double));
113
- memset(hyd->LeakageFlow,0,(net->Nnodes+1)*sizeof(double));
114
117
  for (i = 1; i <= net->Nnodes; i++)
115
118
  {
116
119
  net->Node[i].ResultIndex = i;
@@ -124,22 +127,9 @@ void inithyd(Project *pr, int initflag)
124
127
  link->ResultIndex = i;
125
128
 
126
129
  // Initialize status and setting
127
- hyd->LinkStatus[i] = link->InitStatus;
128
- hyd->LinkSetting[i] = link->InitSetting;
129
-
130
- // Setting of non-ACTIVE FCV, PRV, PSV valves is "MISSING"
131
- switch (link->Type)
132
- {
133
- case FCV:
134
- case PRV:
135
- case PSV:
136
- if (link->InitStatus != ACTIVE)
137
- {
138
- link->Kc = MISSING;
139
- hyd->LinkSetting[i] = MISSING;
140
- }
141
- }
142
-
130
+ hyd->LinkStatus[i] = link->Status;
131
+ hyd->LinkSetting[i] = link->Kc;
132
+
143
133
  // Compute flow resistance
144
134
  resistcoeff(pr, i);
145
135
 
@@ -173,12 +163,7 @@ void inithyd(Project *pr, int initflag)
173
163
  pump->Energy.KwHrsPerFlow = 0.0;
174
164
  pump->Energy.MaxKwatts = 0.0;
175
165
  pump->Energy.TotalCost = 0.0;
176
- pump->Energy.CurrentPower = 0.0;
177
- pump->Energy.CurrentEffic = 0.0;
178
166
  }
179
-
180
- // Initialize flow balance
181
- startflowbalance(pr);
182
167
 
183
168
  // Re-position hydraulics file
184
169
  if (pr->outfile.Saveflag)
@@ -211,7 +196,7 @@ int runhyd(Project *pr, long *t)
211
196
  int iter; // Iteration count
212
197
  int errcode; // Error code
213
198
  double relerr; // Solution accuracy
214
-
199
+
215
200
  // Find new demands & control actions
216
201
  *t = time->Htime;
217
202
  demands(pr);
@@ -254,9 +239,6 @@ int nexthyd(Project *pr, long *tstep)
254
239
  long hydstep; // Actual time step
255
240
  int errcode = 0; // Error code
256
241
 
257
- // Compute current power and efficiency of all pumps
258
- getallpumpsenergy(pr);
259
-
260
242
  // Save current results to hydraulics file and
261
243
  // force end of simulation if Haltflag is active
262
244
  if (pr->outfile.Saveflag) errcode = savehyd(pr, &time->Htime);
@@ -268,12 +250,9 @@ int nexthyd(Project *pr, long *tstep)
268
250
  if (time->Htime < time->Dur) hydstep = timestep(pr);
269
251
  if (pr->outfile.Saveflag) errcode = savehydstep(pr,&hydstep);
270
252
 
271
- // Accumulate pumping energy
253
+ // Compute pumping energy
272
254
  if (time->Dur == 0) addenergy(pr,0);
273
255
  else if (time->Htime < time->Dur) addenergy(pr,hydstep);
274
-
275
- // Update flow balance
276
- updateflowbalance(pr, hydstep);
277
256
 
278
257
  // More time remains - update current time
279
258
  if (time->Htime < time->Dur)
@@ -288,8 +267,6 @@ int nexthyd(Project *pr, long *tstep)
288
267
  // No more time remains - force completion of analysis
289
268
  else
290
269
  {
291
- endflowbalance(pr);
292
- if (pr->report.Statflag) writeflowbalance(pr);
293
270
  time->Htime++;
294
271
  if (pr->quality.OpenQflag) time->Qtime++;
295
272
  }
@@ -309,7 +286,6 @@ void closehyd(Project *pr)
309
286
  {
310
287
  freesparse(pr);
311
288
  freematrix(pr);
312
- freeadjlists(&pr->network);
313
289
  }
314
290
 
315
291
 
@@ -329,12 +305,16 @@ int allocmatrix(Project *pr)
329
305
 
330
306
  hyd->P = (double *) calloc(net->Nlinks+1,sizeof(double));
331
307
  hyd->Y = (double *) calloc(net->Nlinks+1,sizeof(double));
308
+ hyd->DemandFlow = (double *) calloc(net->Nnodes + 1, sizeof(double));
309
+ hyd->EmitterFlow = (double *) calloc(net->Nnodes+1, sizeof(double));
332
310
  hyd->Xflow = (double *) calloc(MAX((net->Nnodes+1), (net->Nlinks+1)),
333
311
  sizeof(double));
334
312
  hyd->OldStatus = (StatusType *) calloc(net->Nlinks+net->Ntanks+1,
335
313
  sizeof(StatusType));
336
314
  ERRCODE(MEMCHECK(hyd->P));
337
315
  ERRCODE(MEMCHECK(hyd->Y));
316
+ ERRCODE(MEMCHECK(hyd->DemandFlow));
317
+ ERRCODE(MEMCHECK(hyd->EmitterFlow));
338
318
  ERRCODE(MEMCHECK(hyd->Xflow));
339
319
  ERRCODE(MEMCHECK(hyd->OldStatus));
340
320
  return errcode;
@@ -354,6 +334,8 @@ void freematrix(Project *pr)
354
334
 
355
335
  free(hyd->P);
356
336
  free(hyd->Y);
337
+ free(hyd->DemandFlow);
338
+ free(hyd->EmitterFlow);
357
339
  free(hyd->Xflow);
358
340
  free(hyd->OldStatus);
359
341
  }
@@ -415,7 +397,7 @@ void setlinkstatus(Project *pr, int index, char value, StatusType *s, double *k
415
397
  if (t == PUMP)
416
398
  {
417
399
  *k = 1.0;
418
- // Check if a re-opened pump needs its flow reset
400
+ // Check if a re-opened pump needs its flow reset
419
401
  if (*s == CLOSED) resetpumpflow(pr, index);
420
402
  }
421
403
  if (t > PUMP && t != GPV) *k = MISSING;
@@ -475,7 +457,6 @@ void setlinksetting(Project *pr, int index, double value, StatusType *s,
475
457
  else
476
458
  {
477
459
  if (*k == MISSING && *s <= CLOSED) *s = OPEN;
478
- if (t == PCV) link->R = pcvlosscoeff(pr, index, link->Kc);
479
460
  *k = value;
480
461
  }
481
462
  }
@@ -511,14 +492,12 @@ void demands(Project *pr)
511
492
  {
512
493
  // pattern period (k) = (elapsed periods) modulus (periods per pattern)
513
494
  j = demand->Pat;
514
- if (j == 0)
515
- j = hyd->DefPat;
516
495
  k = p % (long)net->Pattern[j].Length;
517
496
  djunc = (demand->Base) * net->Pattern[j].F[k] * hyd->Dmult;
518
497
  if (djunc > 0.0) hyd->Dsystem += djunc;
519
498
  sum += djunc;
520
499
  }
521
- hyd->FullDemand[i] = sum;
500
+ hyd->NodeDemand[i] = sum;
522
501
 
523
502
  // Initialize pressure dependent demand
524
503
  hyd->DemandFlow[i] = sum;
@@ -583,10 +562,6 @@ int controls(Project *pr)
583
562
  {
584
563
  // Make sure that link is defined
585
564
  control = &net->Control[i];
586
- if (!control->isEnabled)
587
- {
588
- continue;
589
- }
590
565
  reset = 0;
591
566
  if ( (k = control->Link) <= 0) continue;
592
567
  link = &net->Link[k];
@@ -626,16 +601,15 @@ int controls(Project *pr)
626
601
  k1 = hyd->LinkSetting[k];
627
602
  k2 = k1;
628
603
  if (link->Type > PIPE) k2 = control->Setting;
629
-
604
+
630
605
  // Check if a re-opened pump needs its flow reset
631
606
  if (link->Type == PUMP && s1 == CLOSED && s2 == OPEN)
632
607
  resetpumpflow(pr, k);
633
-
608
+
634
609
  if (s1 != s2 || k1 != k2)
635
610
  {
636
611
  hyd->LinkStatus[k] = s2;
637
612
  hyd->LinkSetting[k] = k2;
638
- if (link->Type == PCV) link->R = pcvlosscoeff(pr, k, k2);
639
613
  if (pr->report.Statflag) writecontrolaction(pr,k,i);
640
614
  setsum++;
641
615
  }
@@ -699,7 +673,7 @@ int tanktimestep(Project *pr, long *tstep)
699
673
  Hydraul *hyd = &pr->hydraul;
700
674
 
701
675
  int i, n, tankIdx = 0;
702
- double h, q, v, xt;
676
+ double h, q, v;
703
677
  long t;
704
678
  Stank *tank;
705
679
 
@@ -722,9 +696,7 @@ int tanktimestep(Project *pr, long *tstep)
722
696
  else continue;
723
697
 
724
698
  // Find time to fill/drain tank
725
- xt = v / q;
726
- if (ABS(xt) > *tstep + 1) continue;
727
- t = (long)ROUND(xt);
699
+ t = (long)ROUND(v / q);
728
700
  if (t > 0 && t < *tstep)
729
701
  {
730
702
  *tstep = t;
@@ -735,7 +707,7 @@ int tanktimestep(Project *pr, long *tstep)
735
707
  }
736
708
 
737
709
 
738
- int controltimestep(Project *pr, long *tstep)
710
+ void controltimestep(Project *pr, long *tstep)
739
711
  /*
740
712
  **------------------------------------------------------------------
741
713
  ** Input: *tstep = current time step
@@ -748,7 +720,7 @@ int controltimestep(Project *pr, long *tstep)
748
720
  Network *net = &pr->network;
749
721
  Hydraul *hyd = &pr->hydraul;
750
722
 
751
- int i, j, k, n, controlIndex = 0;
723
+ int i, j, k, n;
752
724
  double h, q, v;
753
725
  long t, t1, t2;
754
726
  Slink *link;
@@ -759,10 +731,7 @@ int controltimestep(Project *pr, long *tstep)
759
731
  {
760
732
  t = 0;
761
733
  control = &net->Control[i];
762
- if (!control->isEnabled)
763
- {
764
- continue;
765
- }
734
+
766
735
  // Control depends on a tank level
767
736
  if ( (n = control->Node) > 0)
768
737
  {
@@ -808,14 +777,9 @@ int controltimestep(Project *pr, long *tstep)
808
777
  k = control->Link;
809
778
  link = &net->Link[k];
810
779
  if ( (link->Type > PIPE && hyd->LinkSetting[k] != control->Setting)
811
- || (hyd->LinkStatus[k] != control->Status) )
812
- {
813
- *tstep = t;
814
- controlIndex = i;
815
- }
780
+ || (hyd->LinkStatus[k] != control->Status) ) *tstep = t;
816
781
  }
817
782
  }
818
- return controlIndex;
819
783
  }
820
784
 
821
785
 
@@ -938,7 +902,7 @@ void addenergy(Project *pr, long hstep)
938
902
  // Skip closed pumps
939
903
  pump = &net->Pump[j];
940
904
  k = pump->Link;
941
- if (pump->Energy.CurrentEffic == 0.0) continue;
905
+ if (hyd->LinkStatus[k] <= CLOSED) continue;
942
906
  q = MAX(QZERO, ABS(hyd->LinkFlow[k]));
943
907
 
944
908
  // Find pump-specific energy cost
@@ -951,10 +915,11 @@ void addenergy(Project *pr, long hstep)
951
915
  }
952
916
  else c *= f0;
953
917
 
954
- // Update pump's cumulative statistics
955
- p = pump->Energy.CurrentPower;
956
- e = pump->Energy.CurrentEffic;
918
+ // Find pump energy & efficiency
919
+ getenergy(pr, k, &p, &e);
957
920
  psum += p;
921
+
922
+ // Update pump's cumulative statistics
958
923
  pump->Energy.TimeOnLine += dt;
959
924
  pump->Energy.Efficiency += e * dt;
960
925
  pump->Energy.KwHrsPerFlow += p / q * dt;
@@ -1030,27 +995,6 @@ void getenergy(Project *pr, int k, double *kw, double *eff)
1030
995
  }
1031
996
 
1032
997
 
1033
- void getallpumpsenergy(Project *pr)
1034
- /*
1035
- **-------------------------------------------------------------
1036
- ** Input: none
1037
- ** Output: none
1038
- ** Purpose: finds the current power and efficiency for each pump.
1039
- **-------------------------------------------------------------
1040
- */
1041
- {
1042
- int j;
1043
- Spump *pump;
1044
-
1045
- for (j = 1; j <= pr->network.Npumps; j++)
1046
- {
1047
- pump = &(pr->network.Pump[j]);
1048
- getenergy(pr, pump->Link, &(pump->Energy.CurrentPower),
1049
- &(pump->Energy.CurrentEffic));
1050
- }
1051
- }
1052
-
1053
-
1054
998
  void tanklevels(Project *pr, long tstep)
1055
999
  /*
1056
1000
  **----------------------------------------------------------------
@@ -1168,5 +1112,6 @@ void resetpumpflow(Project *pr, int i)
1168
1112
  Network *net = &pr->network;
1169
1113
  Spump *pump = &net->Pump[findpump(net, i)];
1170
1114
  if (pump->Ptype == CONST_HP)
1171
- pr->hydraul.LinkFlow[i] = pump->Q0;
1115
+ pr->hydraul.LinkFlow[i] = pump->Q0;
1172
1116
  }
1117
+
@@ -1,14 +1,14 @@
1
1
  /*
2
2
  ******************************************************************************
3
3
  Project: OWA EPANET
4
- Version: 2.3
4
+ Version: 2.2
5
5
  Module: hydsolver.c
6
6
  Description: computes flows and pressures throughout a pipe network using
7
7
  Todini's Global Gradient Algorithm
8
8
  Authors: see AUTHORS
9
9
  Copyright: see AUTHORS
10
10
  License: see LICENSE
11
- Last Updated: 06/26/2024
11
+ Last Updated: 07/15/2019
12
12
  ******************************************************************************
13
13
  */
14
14
 
@@ -47,7 +47,6 @@ static double newflows(Project *, Hydbalance *);
47
47
  static void newlinkflows(Project *, Hydbalance *, double *, double *);
48
48
  static void newemitterflows(Project *, Hydbalance *, double *, double *);
49
49
  static void newdemandflows(Project *, Hydbalance *, double *, double *);
50
- static void newleakageflows(Project *, Hydbalance *, double *, double *);
51
50
 
52
51
  static void checkhydbalance(Project *, Hydbalance *);
53
52
  static int hasconverged(Project *, double *, Hydbalance *);
@@ -94,6 +93,7 @@ int hydsolve(Project *pr, int *iter, double *relerr)
94
93
  int valveChange; // Valve status change flag
95
94
  int statChange; // Non-valve status change flag
96
95
  Hydbalance hydbal; // Hydraulic balance errors
96
+ double fullDemand; // Full demand for a node (cfs)
97
97
 
98
98
  // Initialize status checking & relaxation factor
99
99
  nextcheck = hyd->CheckFreq;
@@ -178,7 +178,7 @@ int hydsolve(Project *pr, int *iter, double *relerr)
178
178
  nextcheck = *iter + hyd->CheckFreq;
179
179
  }
180
180
 
181
- // No convergence yet - see if it's time for a periodic status
181
+ // No convergence yet - see if its time for a periodic status
182
182
  // check on pumps, CV's, and pipes connected to tank
183
183
  else if (*iter <= hyd->MaxCheck && *iter == nextcheck)
184
184
  {
@@ -195,12 +195,12 @@ int hydsolve(Project *pr, int *iter, double *relerr)
195
195
  errcode = 110;
196
196
  }
197
197
 
198
- // Save total outflow (NodeDemand) at each junction
198
+ // Store actual junction outflow in NodeDemand & full demand in DemandFlow
199
199
  for (i = 1; i <= net->Njuncs; i++)
200
200
  {
201
- hyd->NodeDemand[i] = hyd->DemandFlow[i] +
202
- hyd->EmitterFlow[i] +
203
- hyd->LeakageFlow[i];
201
+ fullDemand = hyd->NodeDemand[i];
202
+ hyd->NodeDemand[i] = hyd->DemandFlow[i] + hyd->EmitterFlow[i];
203
+ hyd->DemandFlow[i] = fullDemand;
204
204
  }
205
205
 
206
206
  // Save convergence info
@@ -381,7 +381,6 @@ double newflows(Project *pr, Hydbalance *hbal)
381
381
  newlinkflows(pr, hbal, &qsum, &dqsum);
382
382
  newemitterflows(pr, hbal, &qsum, &dqsum);
383
383
  newdemandflows(pr, hbal, &qsum, &dqsum);
384
- if (hyd->HasLeakage) newleakageflows(pr, hbal, &qsum, &dqsum);
385
384
 
386
385
  // Return ratio of total flow corrections to total flow
387
386
  if (qsum > hyd->Hacc) return (dqsum / qsum);
@@ -515,45 +514,6 @@ void newemitterflows(Project *pr, Hydbalance *hbal, double *qsum,
515
514
  }
516
515
 
517
516
 
518
- void newleakageflows(Project *pr, Hydbalance *hbal, double *qsum,
519
- double *dqsum)
520
- /*
521
- **----------------------------------------------------------------
522
- ** Input: hbal = ptr. to hydraulic balance information
523
- ** qsum = sum of current system flows
524
- ** dqsum = sum of system flow changes
525
- ** Output: updates hbal, qsum and dqsum
526
- ** Purpose: updates nodal leakage flows after new nodal heads computed
527
- **----------------------------------------------------------------
528
- */
529
- {
530
- Network *net = &pr->network;
531
- Hydraul *hyd = &pr->hydraul;
532
-
533
- int i;
534
- double dq;
535
-
536
- for (i = 1; i <= net->Njuncs; i++)
537
- {
538
- // Update leakage flow at node i
539
- dq = leakageflowchange(pr, i);
540
- if (dq == 0.0) continue;
541
-
542
- // Update system flow summation
543
- *qsum += ABS(hyd->LeakageFlow[i]);
544
- *dqsum += ABS(dq);
545
-
546
- // Update identity of element with max. flow change
547
- if (ABS(dq) > hbal->maxflowchange)
548
- {
549
- hbal->maxflowchange = ABS(dq);
550
- hbal->maxflownode = i;
551
- hbal->maxflowlink = -1;
552
- }
553
- }
554
- }
555
-
556
-
557
517
  void newdemandflows(Project *pr, Hydbalance *hbal, double *qsum, double *dqsum)
558
518
  /*
559
519
  **----------------------------------------------------------------
@@ -586,17 +546,13 @@ void newdemandflows(Project *pr, Hydbalance *hbal, double *qsum, double *dqsum)
586
546
  for (i = 1; i <= net->Njuncs; i++)
587
547
  {
588
548
  // Skip junctions with no positive demand
589
- if (hyd->FullDemand[i] <= 0.0) continue;
549
+ if (hyd->NodeDemand[i] <= 0.0) continue;
590
550
 
591
551
  // Find change in demand flow (see hydcoeffs.c)
592
552
  demandheadloss(pr, i, dp, n, &hloss, &hgrad);
593
553
  dh = hyd->NodeHead[i] - net->Node[i].El - hyd->Pmin;
594
554
  dq = (hloss - dh) / hgrad;
595
555
  dq *= hyd->RelaxFactor;
596
-
597
- // Prevent a flow change greater than full demand
598
- if (fabs(dq) > 0.4 * hyd->FullDemand[i])
599
- dq = 0.4 * SGN(dq) * hyd->FullDemand[i];
600
556
  hyd->DemandFlow[i] -= dq;
601
557
 
602
558
  // Update system flow summation
@@ -681,15 +637,11 @@ int hasconverged(Project *pr, double *relerr, Hydbalance *hbal)
681
637
  if (hyd->FlowChangeLimit > 0.0 &&
682
638
  hbal->maxflowchange > hyd->FlowChangeLimit) return 0;
683
639
 
684
- // Check for node leakage convergence
685
- if (hyd->HasLeakage && !leakagehasconverged(pr)) return 0;
686
-
687
640
  // Check for pressure driven analysis convergence
688
641
  if (hyd->DemandModel == PDA) return pdaconverged(pr);
689
642
  return 1;
690
643
  }
691
644
 
692
-
693
645
  int pdaconverged(Project *pr)
694
646
  /*
695
647
  **--------------------------------------------------------------
@@ -702,46 +654,33 @@ int pdaconverged(Project *pr)
702
654
  {
703
655
  Hydraul *hyd = &pr->hydraul;
704
656
 
705
- const double QTOL = 0.0001; // 0.0001 cfs ~= 0.05 gpm ~= 0.2 lpm)
657
+ const double TOL = 0.001;
706
658
  int i, converged = 1;
707
-
708
659
  double totalDemand = 0.0, totalReduction = 0.0;
709
- double dp = hyd->Preq - hyd->Pmin;
710
- double p, q, r;
711
-
660
+
712
661
  hyd->DeficientNodes = 0;
713
662
  hyd->DemandReduction = 0.0;
714
-
715
- // Examine each network junction
663
+
664
+ // Add up number of junctions with demand deficits
716
665
  for (i = 1; i <= pr->network.Njuncs; i++)
717
666
  {
718
667
  // Skip nodes whose required demand is non-positive
719
- if (hyd->FullDemand[i] <= 0.0) continue;
720
-
721
- // Evaluate demand equation at current pressure solution
722
- p = hyd->NodeHead[i] - pr->network.Node[i].El;
723
- if (p <= hyd->Pmin)
724
- q = 0.0;
725
- else if (p >= hyd->Preq)
726
- q = hyd->FullDemand[i];
727
- else
728
- {
729
- r = (p - hyd->Pmin) / dp;
730
- q = hyd->FullDemand[i] * pow(r, hyd->Pexp);
731
- }
668
+ if (hyd->NodeDemand[i] <= 0.0) continue;
732
669
 
733
- // Check if demand has not converged
734
- if (fabs(q - hyd->DemandFlow[i]) > QTOL)
670
+ // Check for negative demand flow or positive demand flow at negative pressure
671
+ if (hyd->DemandFlow[i] < -TOL) converged = 0;
672
+ if (hyd->DemandFlow[i] > TOL &&
673
+ hyd->NodeHead[i] - pr->network.Node[i].El - hyd->Pmin < -TOL)
735
674
  converged = 0;
736
-
737
- // Accumulate demand deficient node count and demand deficit
738
- if (hyd->DemandFlow[i] + QTOL < hyd->FullDemand[i])
675
+
676
+ // Accumulate total required demand and demand deficit
677
+ if (hyd->DemandFlow[i] + 0.0001 < hyd->NodeDemand[i])
739
678
  {
740
679
  hyd->DeficientNodes++;
741
- totalDemand += hyd->FullDemand[i];
742
- totalReduction += hyd->FullDemand[i] - hyd->DemandFlow[i];
680
+ totalDemand += hyd->NodeDemand[i];
681
+ totalReduction += hyd->NodeDemand[i] - hyd->DemandFlow[i];
743
682
  }
744
- }
683
+ }
745
684
  if (totalDemand > 0.0)
746
685
  hyd->DemandReduction = totalReduction / totalDemand * 100.0;
747
686
  return converged;