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.
- epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +8 -40
- epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +3 -3
- epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +18 -0
- epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +7 -24
- epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +374 -726
- epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +32 -128
- epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +131 -0
- epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +1 -7
- epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +14 -40
- epyt_flow/EPANET/EPANET/SRC_engines/hash.c +177 -177
- epyt_flow/EPANET/EPANET/SRC_engines/hash.h +28 -28
- epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +40 -192
- epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +46 -101
- epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +24 -85
- epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +63 -29
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +37 -70
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +234 -408
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +37 -87
- epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +79 -153
- epyt_flow/EPANET/EPANET/SRC_engines/input1.c +94 -59
- epyt_flow/EPANET/EPANET/SRC_engines/input2.c +202 -73
- epyt_flow/EPANET/EPANET/SRC_engines/input3.c +351 -446
- epyt_flow/EPANET/EPANET/SRC_engines/main.c +93 -0
- epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +4 -8
- epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +23 -23
- epyt_flow/EPANET/EPANET/SRC_engines/output.c +4 -5
- epyt_flow/EPANET/EPANET/SRC_engines/project.c +75 -407
- epyt_flow/EPANET/EPANET/SRC_engines/quality.c +2 -12
- epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +13 -70
- epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +5 -7
- epyt_flow/EPANET/EPANET/SRC_engines/report.c +20 -88
- epyt_flow/EPANET/EPANET/SRC_engines/rules.c +6 -144
- epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +19 -19
- epyt_flow/EPANET/EPANET/SRC_engines/text.h +5 -16
- epyt_flow/EPANET/EPANET/SRC_engines/types.h +19 -73
- epyt_flow/EPANET/compile_linux.sh +1 -1
- epyt_flow/EPANET/compile_macos.sh +1 -1
- epyt_flow/VERSION +1 -1
- epyt_flow/simulation/scada/scada_data.py +1 -1
- epyt_flow/utils.py +66 -0
- epyt_flow/visualization/visualization_utils.py +4 -2
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/METADATA +1 -1
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/RECORD +46 -52
- epyt_flow/EPANET/EPANET/SRC_engines/flowbalance.c +0 -186
- epyt_flow/EPANET/EPANET/SRC_engines/leakage.c +0 -527
- epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.c +0 -59
- epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.h +0 -38
- epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.c +0 -92
- epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.h +0 -39
- epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.c +0 -212
- epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.h +0 -81
- epyt_flow/EPANET/EPANET/SRC_engines/validate.c +0 -408
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/WHEEL +0 -0
- {epyt_flow-0.14.1.dist-info → epyt_flow-0.14.2.dist-info}/licenses/LICENSE +0 -0
- {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.
|
|
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:
|
|
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
|
|
58
|
-
errcode =
|
|
59
|
-
if (
|
|
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
|
-
|
|
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->
|
|
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
|
|
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->
|
|
128
|
-
hyd->LinkSetting[i] = link->
|
|
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
|
-
//
|
|
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->
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
//
|
|
955
|
-
p
|
|
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.
|
|
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:
|
|
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
|
|
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
|
-
//
|
|
198
|
+
// Store actual junction outflow in NodeDemand & full demand in DemandFlow
|
|
199
199
|
for (i = 1; i <= net->Njuncs; i++)
|
|
200
200
|
{
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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->
|
|
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
|
|
657
|
+
const double TOL = 0.001;
|
|
706
658
|
int i, converged = 1;
|
|
707
|
-
|
|
708
659
|
double totalDemand = 0.0, totalReduction = 0.0;
|
|
709
|
-
|
|
710
|
-
double p, q, r;
|
|
711
|
-
|
|
660
|
+
|
|
712
661
|
hyd->DeficientNodes = 0;
|
|
713
662
|
hyd->DemandReduction = 0.0;
|
|
714
|
-
|
|
715
|
-
//
|
|
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->
|
|
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
|
|
734
|
-
if (
|
|
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
|
|
738
|
-
if (hyd->DemandFlow[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->
|
|
742
|
-
totalReduction += hyd->
|
|
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;
|