Adding Pipe Leakage Modeling
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/14/2022
|
||||
Last Updated: 06/15/2024
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -47,6 +47,7 @@ static double newflows(Project *, Hydbalance *);
|
||||
static void newlinkflows(Project *, Hydbalance *, double *, double *);
|
||||
static void newemitterflows(Project *, Hydbalance *, double *, double *);
|
||||
static void newdemandflows(Project *, Hydbalance *, double *, double *);
|
||||
static void newleakageflows(Project *, Hydbalance *, double *, double *);
|
||||
|
||||
static void checkhydbalance(Project *, Hydbalance *);
|
||||
static int hasconverged(Project *, double *, Hydbalance *);
|
||||
@@ -93,7 +94,6 @@ int hydsolve(Project *pr, int *iter, double *relerr)
|
||||
int valveChange; // Valve status change flag
|
||||
int statChange; // Non-valve status change flag
|
||||
Hydbalance hydbal; // Hydraulic balance errors
|
||||
double fullDemand; // Full demand for a node (cfs)
|
||||
|
||||
// Initialize status checking & relaxation factor
|
||||
nextcheck = hyd->CheckFreq;
|
||||
@@ -195,12 +195,12 @@ int hydsolve(Project *pr, int *iter, double *relerr)
|
||||
errcode = 110;
|
||||
}
|
||||
|
||||
// Store actual junction outflow in NodeDemand & full demand in DemandFlow
|
||||
// Save total outflow (NodeDemand) at each junction
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
fullDemand = hyd->NodeDemand[i];
|
||||
hyd->NodeDemand[i] = hyd->DemandFlow[i] + hyd->EmitterFlow[i];
|
||||
hyd->DemandFlow[i] = fullDemand;
|
||||
hyd->NodeDemand[i] = hyd->DemandFlow[i] +
|
||||
hyd->EmitterFlow[i] +
|
||||
hyd->LeakageFlow[i];
|
||||
}
|
||||
|
||||
// Save convergence info
|
||||
@@ -381,6 +381,7 @@ double newflows(Project *pr, Hydbalance *hbal)
|
||||
newlinkflows(pr, hbal, &qsum, &dqsum);
|
||||
newemitterflows(pr, hbal, &qsum, &dqsum);
|
||||
newdemandflows(pr, hbal, &qsum, &dqsum);
|
||||
if (hyd->HasLeakage) newleakageflows(pr, hbal, &qsum, &dqsum);
|
||||
|
||||
// Return ratio of total flow corrections to total flow
|
||||
if (qsum > hyd->Hacc) return (dqsum / qsum);
|
||||
@@ -514,6 +515,45 @@ void newemitterflows(Project *pr, Hydbalance *hbal, double *qsum,
|
||||
}
|
||||
|
||||
|
||||
void newleakageflows(Project *pr, Hydbalance *hbal, double *qsum,
|
||||
double *dqsum)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: hbal = ptr. to hydraulic balance information
|
||||
** qsum = sum of current system flows
|
||||
** dqsum = sum of system flow changes
|
||||
** Output: updates hbal, qsum and dqsum
|
||||
** Purpose: updates nodal leakage flows after new nodal heads computed
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
int i;
|
||||
double dq;
|
||||
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
// Update leakage flow at node i
|
||||
dq = leakageflowchange(pr, i);
|
||||
if (dq == 0.0) continue;
|
||||
|
||||
// Update system flow summation
|
||||
*qsum += ABS(hyd->LeakageFlow[i]);
|
||||
*dqsum += ABS(dq);
|
||||
|
||||
// Update identity of element with max. flow change
|
||||
if (ABS(dq) > hbal->maxflowchange)
|
||||
{
|
||||
hbal->maxflowchange = ABS(dq);
|
||||
hbal->maxflownode = i;
|
||||
hbal->maxflowlink = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void newdemandflows(Project *pr, Hydbalance *hbal, double *qsum, double *dqsum)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
@@ -546,7 +586,7 @@ void newdemandflows(Project *pr, Hydbalance *hbal, double *qsum, double *dqsum)
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
// Skip junctions with no positive demand
|
||||
if (hyd->NodeDemand[i] <= 0.0) continue;
|
||||
if (hyd->FullDemand[i] <= 0.0) continue;
|
||||
|
||||
// Find change in demand flow (see hydcoeffs.c)
|
||||
demandheadloss(pr, i, dp, n, &hloss, &hgrad);
|
||||
@@ -555,8 +595,8 @@ void newdemandflows(Project *pr, Hydbalance *hbal, double *qsum, double *dqsum)
|
||||
dq *= hyd->RelaxFactor;
|
||||
|
||||
// Prevent a flow change greater than full demand
|
||||
if (fabs(dq) > 0.4 * hyd->NodeDemand[i])
|
||||
dq = 0.4 * SGN(dq) * hyd->NodeDemand[i];
|
||||
if (fabs(dq) > 0.4 * hyd->FullDemand[i])
|
||||
dq = 0.4 * SGN(dq) * hyd->FullDemand[i];
|
||||
hyd->DemandFlow[i] -= dq;
|
||||
|
||||
// Update system flow summation
|
||||
@@ -641,11 +681,15 @@ int hasconverged(Project *pr, double *relerr, Hydbalance *hbal)
|
||||
if (hyd->FlowChangeLimit > 0.0 &&
|
||||
hbal->maxflowchange > hyd->FlowChangeLimit) return 0;
|
||||
|
||||
// Check for node leakage convergence
|
||||
if (hyd->HasLeakage && !leakagehasconverged(pr)) return 0;
|
||||
|
||||
// Check for pressure driven analysis convergence
|
||||
if (hyd->DemandModel == PDA) return pdaconverged(pr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int pdaconverged(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
@@ -659,47 +703,32 @@ int pdaconverged(Project *pr)
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
const double QTOL = 0.0001; // 0.0001 cfs ~= 0.005 gpm ~= 0.2 lpm)
|
||||
int i, converged = 1;
|
||||
double totalDemand = 0.0, totalReduction = 0.0;
|
||||
int i;
|
||||
double dp = hyd->Preq - hyd->Pmin;
|
||||
double p, q, r;
|
||||
|
||||
hyd->DeficientNodes = 0;
|
||||
hyd->DemandReduction = 0.0;
|
||||
|
||||
// Add up number of junctions with demand deficits
|
||||
// Examine each network junction
|
||||
for (i = 1; i <= pr->network.Njuncs; i++)
|
||||
{
|
||||
// Skip nodes whose required demand is non-positive
|
||||
if (hyd->NodeDemand[i] <= 0.0) continue;
|
||||
if (hyd->FullDemand[i] <= 0.0) continue;
|
||||
|
||||
// Evaluate demand equation at current pressure solution
|
||||
p = hyd->NodeHead[i] - pr->network.Node[i].El;
|
||||
if (p <= hyd->Pmin)
|
||||
q = 0.0;
|
||||
else if (p >= hyd->Preq)
|
||||
q = hyd->NodeDemand[i];
|
||||
q = hyd->FullDemand[i];
|
||||
else
|
||||
{
|
||||
r = (p - hyd->Pmin) / dp;
|
||||
q = hyd->NodeDemand[i] * pow(r, hyd->Pexp);
|
||||
q = hyd->FullDemand[i] * pow(r, hyd->Pexp);
|
||||
}
|
||||
|
||||
// Check if demand has not converged
|
||||
if (fabs(q - hyd->DemandFlow[i]) > QTOL)
|
||||
converged = 0;
|
||||
|
||||
// Accumulate total required demand and demand deficit
|
||||
if (hyd->DemandFlow[i] + QTOL < hyd->NodeDemand[i])
|
||||
{
|
||||
hyd->DeficientNodes++;
|
||||
totalDemand += hyd->NodeDemand[i];
|
||||
totalReduction += hyd->NodeDemand[i] - hyd->DemandFlow[i];
|
||||
}
|
||||
}
|
||||
if (totalDemand > 0.0)
|
||||
hyd->DemandReduction = totalReduction / totalDemand * 100.0;
|
||||
return converged;
|
||||
if (fabs(q - hyd->DemandFlow[i]) > QTOL) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user