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.
- epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +40 -8
- epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +3 -3
- epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +24 -7
- epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +726 -374
- epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +128 -32
- epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +7 -1
- epyt_flow/EPANET/EPANET/SRC_engines/flowbalance.c +186 -0
- epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +40 -14
- 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 +192 -40
- epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +101 -46
- epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +85 -24
- epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +29 -63
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +70 -37
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +408 -234
- epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +87 -37
- epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +153 -79
- epyt_flow/EPANET/EPANET/SRC_engines/input1.c +59 -94
- epyt_flow/EPANET/EPANET/SRC_engines/input2.c +73 -202
- epyt_flow/EPANET/EPANET/SRC_engines/input3.c +446 -351
- epyt_flow/EPANET/EPANET/SRC_engines/leakage.c +527 -0
- epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +8 -4
- epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +23 -23
- epyt_flow/EPANET/EPANET/SRC_engines/output.c +5 -4
- epyt_flow/EPANET/EPANET/SRC_engines/project.c +407 -75
- epyt_flow/EPANET/EPANET/SRC_engines/quality.c +12 -2
- epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +70 -13
- epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +7 -5
- epyt_flow/EPANET/EPANET/SRC_engines/report.c +88 -20
- epyt_flow/EPANET/EPANET/SRC_engines/rules.c +144 -6
- epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +19 -19
- epyt_flow/EPANET/EPANET/SRC_engines/text.h +16 -5
- epyt_flow/EPANET/EPANET/SRC_engines/types.h +73 -19
- epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.c +59 -0
- epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.h +38 -0
- epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.c +92 -0
- epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.h +39 -0
- epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.c +212 -0
- epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.h +81 -0
- epyt_flow/EPANET/EPANET/SRC_engines/validate.c +408 -0
- epyt_flow/EPANET/compile_linux.sh +1 -1
- epyt_flow/EPANET/compile_macos.sh +2 -2
- epyt_flow/VERSION +1 -1
- epyt_flow/__init__.py +1 -1
- epyt_flow/gym/scenario_control_env.py +26 -3
- epyt_flow/simulation/backend/my_epyt.py +58 -13
- epyt_flow/simulation/events/quality_events.py +6 -6
- epyt_flow/simulation/events/sensor_faults.py +24 -24
- epyt_flow/simulation/events/system_event.py +3 -3
- epyt_flow/simulation/scada/scada_data.py +10 -14
- epyt_flow/simulation/scenario_simulator.py +100 -20
- epyt_flow/topology.py +8 -1
- epyt_flow/uncertainty/model_uncertainty.py +292 -150
- epyt_flow/uncertainty/uncertainties.py +2 -2
- {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/METADATA +4 -4
- {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/RECORD +60 -54
- {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/WHEEL +1 -1
- epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +0 -18
- epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +0 -131
- epyt_flow/EPANET/EPANET/SRC_engines/main.c +0 -93
- {epyt_flow-0.13.1.dist-info → epyt_flow-0.14.1.dist-info}/licenses/LICENSE +0 -0
- {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.
|
|
4
|
+
Version: 2.3
|
|
5
5
|
Module: hydcoeffs.c
|
|
6
6
|
Description: computes coefficients for a hydraulic solution matrix
|
|
7
7
|
Authors: see AUTHORS
|
|
8
8
|
Copyright: see AUTHORS
|
|
9
9
|
License: see LICENSE
|
|
10
|
-
Last Updated:
|
|
10
|
+
Last Updated: 06/15/2024
|
|
11
11
|
******************************************************************************
|
|
12
12
|
*/
|
|
13
13
|
|
|
@@ -36,6 +36,7 @@ const double CBIG = 1.e8;
|
|
|
36
36
|
|
|
37
37
|
// Exported functions
|
|
38
38
|
//void resistcoeff(Project *, int );
|
|
39
|
+
//double pcvlosscoeff(Project *, int, double);
|
|
39
40
|
//void headlosscoeffs(Project *);
|
|
40
41
|
//void matrixcoeffs(Project *);
|
|
41
42
|
//void emitterheadloss(Project *, int, double *, double *);
|
|
@@ -59,11 +60,47 @@ static void valvecoeff(Project *pr, int k);
|
|
|
59
60
|
static void gpvcoeff(Project *pr, int k);
|
|
60
61
|
static void pbvcoeff(Project *pr, int k);
|
|
61
62
|
static void tcvcoeff(Project *pr, int k);
|
|
63
|
+
static void pcvcoeff(Project *pr, int k);
|
|
62
64
|
static void prvcoeff(Project *pr, int k, int n1, int n2);
|
|
63
65
|
static void psvcoeff(Project *pr, int k, int n1, int n2);
|
|
64
66
|
static void fcvcoeff(Project *pr, int k, int n1, int n2);
|
|
65
67
|
|
|
66
68
|
|
|
69
|
+
void addlowerbarrier(double dq, double* hloss, double* hgrad)
|
|
70
|
+
/*
|
|
71
|
+
**--------------------------------------------------------------------
|
|
72
|
+
** Input: dq = difference between current flow and lower flow limit
|
|
73
|
+
** Output: hloss = updated head loss value
|
|
74
|
+
** hgrad = updated head loss gradient value
|
|
75
|
+
** Purpose: adds a head loss barrier to prevent flow from falling
|
|
76
|
+
** below a given lower limit.
|
|
77
|
+
**--------------------------------------------------------------------
|
|
78
|
+
*/
|
|
79
|
+
{
|
|
80
|
+
double a = 1.e9 * dq;
|
|
81
|
+
double b = sqrt(a*a + 1.e-6);
|
|
82
|
+
*hloss += (a - b) / 2.;
|
|
83
|
+
*hgrad += (1.e9 / 2.) * ( 1.0 - a / b);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
void addupperbarrier(double dq, double* hloss, double* hgrad)
|
|
87
|
+
/*
|
|
88
|
+
**--------------------------------------------------------------------
|
|
89
|
+
** Input: dq = difference between current flow and upper flow limit
|
|
90
|
+
** Output: hloss = updated head loss value
|
|
91
|
+
** hgrad = updated head loss gradient value
|
|
92
|
+
** Purpose: adds a head loss barrier to prevent flow from exceeding
|
|
93
|
+
** a given upper limit.
|
|
94
|
+
**--------------------------------------------------------------------
|
|
95
|
+
*/
|
|
96
|
+
{
|
|
97
|
+
double a = 1.e9 * dq;
|
|
98
|
+
double b = sqrt(a*a + 1.e-6);
|
|
99
|
+
*hloss += (a + b) / 2.;
|
|
100
|
+
*hgrad += (1.e9 / 2.) * ( 1.0 + a / b);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
67
104
|
void resistcoeff(Project *pr, int k)
|
|
68
105
|
/*
|
|
69
106
|
**--------------------------------------------------------------------
|
|
@@ -107,6 +144,10 @@ void resistcoeff(Project *pr, int k)
|
|
|
107
144
|
case PUMP:
|
|
108
145
|
link->R = CBIG;
|
|
109
146
|
break;
|
|
147
|
+
|
|
148
|
+
case PCV:
|
|
149
|
+
link->R = pcvlosscoeff(pr, k, link->Kc);
|
|
150
|
+
break;
|
|
110
151
|
|
|
111
152
|
// ... For all other links (e.g. valves) use a small resistance
|
|
112
153
|
default:
|
|
@@ -116,6 +157,87 @@ void resistcoeff(Project *pr, int k)
|
|
|
116
157
|
}
|
|
117
158
|
|
|
118
159
|
|
|
160
|
+
double pcvlosscoeff(Project* pr, int k, double s)
|
|
161
|
+
/*
|
|
162
|
+
**--------------------------------------------------------------
|
|
163
|
+
** Input: k = link index
|
|
164
|
+
** s = valve percent open setting
|
|
165
|
+
** Output: returns a valve loss coefficient
|
|
166
|
+
** Purpose: finds a Positional Control Valve's loss
|
|
167
|
+
** coefficient from its percent open setting.
|
|
168
|
+
**--------------------------------------------------------------
|
|
169
|
+
*/
|
|
170
|
+
{
|
|
171
|
+
Network* net = &pr->network;
|
|
172
|
+
|
|
173
|
+
int v = findvalve(net, k); // valve index
|
|
174
|
+
int c = net->Valve[v].Curve; // Kv curve index
|
|
175
|
+
double d; // valve diameter
|
|
176
|
+
double kmo; // fully open loss coeff.
|
|
177
|
+
double km; // partly open loss coeff.
|
|
178
|
+
double kvr; // Kv / Kvo (Kvo = Kv at fully open)
|
|
179
|
+
double *x, *y; // points on kvr v. percent open curve
|
|
180
|
+
int k1, k2, npts;
|
|
181
|
+
Scurve *curve;
|
|
182
|
+
|
|
183
|
+
// Valve has no setting so return 0
|
|
184
|
+
if (s == MISSING) return 0.0;
|
|
185
|
+
|
|
186
|
+
// Valve is completely open so return its Km value
|
|
187
|
+
d = net->Link[k].Diam;
|
|
188
|
+
kmo = net->Link[k].Km;
|
|
189
|
+
if (s >= 100.0) return kmo;
|
|
190
|
+
|
|
191
|
+
// Valve is completely closed so return a large coeff.
|
|
192
|
+
if (s <= 0.0) return CBIG;
|
|
193
|
+
|
|
194
|
+
// Valve has no assigned curve so assume a linear one
|
|
195
|
+
if (c == 0) kvr = s;
|
|
196
|
+
|
|
197
|
+
else
|
|
198
|
+
{
|
|
199
|
+
// Valve curve data
|
|
200
|
+
curve = &net->Curve[c];
|
|
201
|
+
npts = curve->Npts;
|
|
202
|
+
x = curve->X; // x = % open
|
|
203
|
+
y = curve->Y; // y = Kv / Kvo as a %
|
|
204
|
+
|
|
205
|
+
// s lies below first point of curve
|
|
206
|
+
if (s < x[0])
|
|
207
|
+
kvr = s / x[0] * y[0];
|
|
208
|
+
|
|
209
|
+
// s lies above last point of curve
|
|
210
|
+
else if (s > x[npts-1])
|
|
211
|
+
{
|
|
212
|
+
k2 = npts - 1;
|
|
213
|
+
kvr = (s - x[k2]) / (1. - x[k2]) * (1. - y[k2]) + y[k2];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Otherwise interpolate over curve segment that brackets s
|
|
217
|
+
else
|
|
218
|
+
{
|
|
219
|
+
k2 = 0;
|
|
220
|
+
while (k2 < npts && x[k2] < s) k2++;
|
|
221
|
+
if (k2 == 0) k2++;
|
|
222
|
+
else if (k2 == npts) k2--;
|
|
223
|
+
k1 = k2 - 1;
|
|
224
|
+
kvr = (y[k2] - y[k1]) / (x[k2] - x[k1]);
|
|
225
|
+
kvr = y[k1] + kvr * (s - x[k1]);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Convert kvr from % to fraction
|
|
230
|
+
kvr /= 100.;
|
|
231
|
+
kvr = MIN(kvr, 1.0);
|
|
232
|
+
kvr = MAX(kvr, CSMALL);
|
|
233
|
+
|
|
234
|
+
// Convert from Kv ratio to minor loss coeff.
|
|
235
|
+
km = kmo / (kvr * kvr);
|
|
236
|
+
km = MIN(km, CBIG);
|
|
237
|
+
return km;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
119
241
|
void headlosscoeffs(Project *pr)
|
|
120
242
|
/*
|
|
121
243
|
**--------------------------------------------------------------
|
|
@@ -148,6 +270,9 @@ void headlosscoeffs(Project *pr)
|
|
|
148
270
|
case TCV:
|
|
149
271
|
tcvcoeff(pr, k);
|
|
150
272
|
break;
|
|
273
|
+
case PCV:
|
|
274
|
+
pcvcoeff(pr, k);
|
|
275
|
+
break;
|
|
151
276
|
case GPV:
|
|
152
277
|
gpvcoeff(pr, k);
|
|
153
278
|
break;
|
|
@@ -185,6 +310,7 @@ void matrixcoeffs(Project *pr)
|
|
|
185
310
|
linkcoeffs(pr);
|
|
186
311
|
emittercoeffs(pr);
|
|
187
312
|
demandcoeffs(pr);
|
|
313
|
+
if (hyd->HasLeakage) leakagecoeffs(pr);
|
|
188
314
|
|
|
189
315
|
// Update nodal flow balances with demands and add onto r.h.s. coeffs.
|
|
190
316
|
nodecoeffs(pr);
|
|
@@ -381,7 +507,7 @@ void emitterheadloss(Project *pr, int i, double *hloss, double *hgrad)
|
|
|
381
507
|
** Input: i = node index
|
|
382
508
|
** Output: hloss = head loss across node's emitter
|
|
383
509
|
** hgrad = head loss gradient
|
|
384
|
-
** Purpose: computes an
|
|
510
|
+
** Purpose: computes an emitter's head loss and gradient.
|
|
385
511
|
**-------------------------------------------------------------
|
|
386
512
|
*/
|
|
387
513
|
{
|
|
@@ -400,12 +526,18 @@ void emitterheadloss(Project *pr, int i, double *hloss, double *hgrad)
|
|
|
400
526
|
// Use linear head loss function for small gradient
|
|
401
527
|
if (*hgrad < hyd->RQtol)
|
|
402
528
|
{
|
|
403
|
-
*hgrad = hyd->RQtol;
|
|
529
|
+
*hgrad = hyd->RQtol / hyd->Qexp;
|
|
404
530
|
*hloss = (*hgrad) * q;
|
|
405
531
|
}
|
|
406
532
|
|
|
407
533
|
// Otherwise use normal emitter head loss function
|
|
408
534
|
else *hloss = (*hgrad) * q / hyd->Qexp;
|
|
535
|
+
|
|
536
|
+
// Prevent negative flow if backflow not allowed
|
|
537
|
+
if (hyd->EmitBackFlag == 0)
|
|
538
|
+
{
|
|
539
|
+
addlowerbarrier(q, hloss, hgrad);
|
|
540
|
+
}
|
|
409
541
|
}
|
|
410
542
|
|
|
411
543
|
|
|
@@ -443,7 +575,7 @@ void demandcoeffs(Project *pr)
|
|
|
443
575
|
for (i = 1; i <= net->Njuncs; i++)
|
|
444
576
|
{
|
|
445
577
|
// Skip junctions with non-positive demands
|
|
446
|
-
if (hyd->
|
|
578
|
+
if (hyd->FullDemand[i] <= 0.0) continue;
|
|
447
579
|
|
|
448
580
|
// Find head loss for demand outflow at node's elevation
|
|
449
581
|
demandheadloss(pr, i, dp, n, &hloss, &hgrad);
|
|
@@ -475,35 +607,17 @@ void demandheadloss(Project *pr, int i, double dp, double n,
|
|
|
475
607
|
Hydraul *hyd = &pr->hydraul;
|
|
476
608
|
|
|
477
609
|
double d = hyd->DemandFlow[i];
|
|
478
|
-
double dfull = hyd->
|
|
610
|
+
double dfull = hyd->FullDemand[i];
|
|
479
611
|
double r = d / dfull;
|
|
480
612
|
|
|
481
|
-
//
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
*hloss = CBIG * d;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// Use power head loss function for demand less than full
|
|
489
|
-
else if (r < 1.0)
|
|
490
|
-
{
|
|
491
|
-
*hgrad = n * dp * pow(r, n - 1.0) / dfull;
|
|
492
|
-
// ... use linear function for very small gradient
|
|
493
|
-
if (*hgrad < hyd->RQtol)
|
|
494
|
-
{
|
|
495
|
-
*hgrad = hyd->RQtol;
|
|
496
|
-
*hloss = (*hgrad) * d;
|
|
497
|
-
}
|
|
498
|
-
else *hloss = (*hgrad) * d / n;
|
|
499
|
-
}
|
|
613
|
+
// Evaluate inverted demand function
|
|
614
|
+
r = fabs(d) / dfull;
|
|
615
|
+
*hgrad = n * dp * pow(r, n - 1.0) / dfull;
|
|
616
|
+
*hloss = (*hgrad) * d / n;
|
|
500
617
|
|
|
501
|
-
//
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
*hgrad = CBIG;
|
|
505
|
-
*hloss = dp + CBIG * (d - dfull);
|
|
506
|
-
}
|
|
618
|
+
// Add barrier functions
|
|
619
|
+
addlowerbarrier(d, hloss, hgrad);
|
|
620
|
+
addupperbarrier(d-dfull, hloss, hgrad);
|
|
507
621
|
}
|
|
508
622
|
|
|
509
623
|
|
|
@@ -553,7 +667,7 @@ void pipecoeff(Project *pr, int k)
|
|
|
553
667
|
// ... use linear function for very small gradient
|
|
554
668
|
if (hgrad < hyd->RQtol)
|
|
555
669
|
{
|
|
556
|
-
hgrad = hyd->RQtol;
|
|
670
|
+
hgrad = hyd->RQtol / hyd->Hexp;
|
|
557
671
|
hloss = hgrad * q;
|
|
558
672
|
}
|
|
559
673
|
// ... otherwise use original formula
|
|
@@ -744,17 +858,23 @@ void pumpcoeff(Project *pr, int k)
|
|
|
744
858
|
{
|
|
745
859
|
// ... compute pump curve's gradient
|
|
746
860
|
hgrad = -r / q / q;
|
|
747
|
-
|
|
861
|
+
|
|
862
|
+
// ... treat as closed link if gradient too large
|
|
748
863
|
if (hgrad > CBIG)
|
|
749
864
|
{
|
|
750
|
-
|
|
751
|
-
|
|
865
|
+
hyd->P[k] = 1.0 / CBIG;
|
|
866
|
+
hyd->Y[k] = hyd->LinkFlow[k];
|
|
867
|
+
return;
|
|
752
868
|
}
|
|
753
|
-
|
|
869
|
+
|
|
870
|
+
// ... treat as open valve if gradient too small
|
|
871
|
+
else if (hgrad < CSMALL)
|
|
754
872
|
{
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
873
|
+
hyd->P[k] = 1.0 / CSMALL;
|
|
874
|
+
hyd->Y[k] = hyd->LinkFlow[k];
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
|
|
758
878
|
// ... otherwise compute head loss from pump curve
|
|
759
879
|
else
|
|
760
880
|
{
|
|
@@ -939,6 +1059,36 @@ void tcvcoeff(Project *pr, int k)
|
|
|
939
1059
|
}
|
|
940
1060
|
|
|
941
1061
|
|
|
1062
|
+
void pcvcoeff(Project *pr, int k)
|
|
1063
|
+
/*
|
|
1064
|
+
**--------------------------------------------------------------
|
|
1065
|
+
** Input: k = link index
|
|
1066
|
+
** Output: none
|
|
1067
|
+
** Purpose: computes P & Y coeffs. for positional control valve
|
|
1068
|
+
**--------------------------------------------------------------
|
|
1069
|
+
*/
|
|
1070
|
+
{
|
|
1071
|
+
double km;
|
|
1072
|
+
Hydraul *hyd = &pr->hydraul;
|
|
1073
|
+
Slink *link = &pr->network.Link[k];
|
|
1074
|
+
|
|
1075
|
+
// Save original loss coeff. for open valve
|
|
1076
|
+
km = link->Km;
|
|
1077
|
+
|
|
1078
|
+
// If valve not fixed OPEN or CLOSED, compute its loss coeff.
|
|
1079
|
+
if (hyd->LinkSetting[k] != MISSING)
|
|
1080
|
+
{
|
|
1081
|
+
link->Km = link->R;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
// Then apply usual valve formula
|
|
1085
|
+
valvecoeff(pr, k);
|
|
1086
|
+
|
|
1087
|
+
// Restore original loss coeff.
|
|
1088
|
+
link->Km = km;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
|
|
942
1092
|
void prvcoeff(Project *pr, int k, int n1, int n2)
|
|
943
1093
|
/*
|
|
944
1094
|
**--------------------------------------------------------------
|
|
@@ -1029,6 +1179,8 @@ void psvcoeff(Project *pr, int k, int n1, int n2)
|
|
|
1029
1179
|
{
|
|
1030
1180
|
sm->F[j] += hyd->Xflow[n1];
|
|
1031
1181
|
}
|
|
1182
|
+
sm->Aij[sm->Ndx[k]] -= 1.0 / CBIG; // Preserve connectivity
|
|
1183
|
+
sm->Aii[j] += 1.0 / CBIG;
|
|
1032
1184
|
return;
|
|
1033
1185
|
}
|
|
1034
1186
|
|
|
@@ -1131,7 +1283,7 @@ void valvecoeff(Project *pr, int k)
|
|
|
1131
1283
|
// Guard against too small a head loss gradient
|
|
1132
1284
|
if (hgrad < hyd->RQtol)
|
|
1133
1285
|
{
|
|
1134
|
-
hgrad = hyd->RQtol;
|
|
1286
|
+
hgrad = hyd->RQtol / 2.0;
|
|
1135
1287
|
hloss = flow * hgrad;
|
|
1136
1288
|
}
|
|
1137
1289
|
else hloss = flow * hgrad / 2.0;
|