Merge pull request #706 from OpenWaterAnalytics/dev-emitter-backflow
Add emitter backflow option
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
>
|
||||
>
|
||||
## Release Notes for EPANET 2.3
|
||||
|
||||
This document describes the changes and updates that have been made in version 2.3 of EPANET.
|
||||
@@ -17,7 +17,7 @@ This document describes the changes and updates that have been made in version 2
|
||||
- A failure to raise an error condition for a pipe roughness <= 0 in the input file has been fixed.
|
||||
- The calculation of head loss gradient for low flow conditions was corrected.
|
||||
- Improved updating and convergence tests were added to pressure dependent demand analysis.
|
||||
- Improved checks to prevent outflow from empty tanks or inflow to full (non-overflow) tanks. *(Still needs more work).*
|
||||
- Improved checks to prevent outflow from empty tanks or inflow to full (non-overflow) tanks, including the case where a link is connected to a pair of tanks.
|
||||
- The CI regression test protocol was modified by:
|
||||
- changing the absolute tolerance used to compare the closeness of test results to benchmark values from 0 to 0.0001
|
||||
- dropping the "correct decimal digits" test
|
||||
@@ -27,5 +27,6 @@ This document describes the changes and updates that have been made in version 2
|
||||
- A new type of valve, a Positional Control Valve (PCV), was added that uses a valve characteristic curve to relate its loss coefficient to its fraction open setting.
|
||||
- A new set of functions have been added to get information about upcoming time step events. Users will now see what type of event is going to cause the end of a time step to occur. See ENtimetonextevent and EN_timetonextevent.
|
||||
- A new set of functions have been added to allow users to set a reporting callback function. The user-supplied function will recieve all output normally directed to the report file.
|
||||
- A `EN_EMITBACKFLOW` option was added that either allows emitters to have reverse flow through them (the default) or not.
|
||||
|
||||
|
||||
|
||||
@@ -298,6 +298,7 @@ __Formats:__
|
||||
<tr><td><B>PATTERN</B></td><td><I>id</I></td></tr>
|
||||
<tr><td><B>DEMAND MULTIPLIER</B></td><td><I>value</I></td></tr>
|
||||
<tr><td><B>EMITTER EXPONENT</B></td><td><I>value</I></td></tr>
|
||||
<tr><td><B>EMITTER BACKFLOW</B></td><td><B>YES / NO</B></td></tr>
|
||||
<tr><td><B>QUALITY</B></td><td><B>NONE / CHEMICAL / AGE / TRACE </B><I>nodeID</I></td></tr>
|
||||
<tr><td><B>DIFFUSIVITY</B></td><td><I>value</I></td></tr>
|
||||
<tr><td><B>TOLERANCE</B></td><td><I>value</I></td></tr>
|
||||
@@ -357,6 +358,8 @@ The <b>DEMAND MULTIPLIER</b> is used to adjust the values of baseline demands fo
|
||||
|
||||
<b>EMITTER EXPONENT</b> specifies the power to which the pressure at a junction is raised when computing the flow issuing from an emitter. The default is 0.5.
|
||||
|
||||
<b>EMITTER BACKFLOW</b> specifies if back flow through an emitter (i.e., flow into the network) is allowed. The default is <b>YES</b>.
|
||||
|
||||
\b QUALITY selects the type of water quality analysis to perform. The choices are <b>NONE, CHEMICAL, AGE</b>, and \b TRACE. In place of \b CHEMICAL the actual name of the chemical can be used followed by its concentration units (e.g., <b>CHLORINE mg/L</b>). If \b TRACE is selected it must be followed by the ID label of the node being traced. The default selection is \b NONE (no water quality analysis).
|
||||
|
||||
\b DIFFUSIVITY is the molecular diffusivity of the chemical being analyzed relative to that of chlorine in water. The default value is 1.0. Diffusivity is only used when mass transfer limitations are considered in pipe wall reactions. A value of 0 will cause EPANET to ignore mass transfer limitations.
|
||||
|
||||
@@ -182,6 +182,8 @@ namespace EpanetCSharpLibrary
|
||||
public const int EN_WALLORDER = 20;
|
||||
public const int EN_TANKORDER = 21;
|
||||
public const int EN_CONCENLIMIT = 22;
|
||||
public const int EN_DEMANDPATTERN = 23;
|
||||
public const int EN_EMITBACKFLOW = 24;
|
||||
|
||||
public const int EN_LOWLEVEL = 0; //Control types
|
||||
public const int EN_HILEVEL = 1;
|
||||
|
||||
@@ -179,6 +179,8 @@ Public Const EN_BULKORDER = 19
|
||||
Public Const EN_WALLORDER = 20
|
||||
Public Const EN_TANKORDER = 21
|
||||
Public Const EN_CONCENLIMIT = 22
|
||||
Public Const EN_DEMANDPATTERN = 23
|
||||
Public Const EN_EMITBACKFLOW = 24
|
||||
|
||||
Public Const EN_LOWLEVEL = 0 ' Control types
|
||||
Public Const EN_HILEVEL = 1
|
||||
|
||||
@@ -185,6 +185,8 @@ const
|
||||
EN_WALLORDER = 20;
|
||||
EN_TANKORDER = 21;
|
||||
EN_CONCENLIMIT = 22;
|
||||
EN_DEMANDPATTERN = 23;
|
||||
EN_EMITBACKFLOW = 24;
|
||||
|
||||
EN_LOWLEVEL = 0; { Control types }
|
||||
EN_HILEVEL = 1;
|
||||
|
||||
@@ -174,6 +174,8 @@ Public Const EN_BULKORDER = 19
|
||||
Public Const EN_WALLORDER = 20
|
||||
Public Const EN_TANKORDER = 21
|
||||
Public Const EN_CONCENLIMIT = 22
|
||||
Public Const EN_DEMANDPATTERN = 23
|
||||
Public Const EN_EMITBACKFLOW = 24
|
||||
|
||||
Public Const EN_LOWLEVEL = 0 ' Control types
|
||||
Public Const EN_HILEVEL = 1
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -335,7 +335,8 @@ typedef enum {
|
||||
EN_WALLORDER = 20, //!< Wall reaction order for pipes (either 0 or 1)
|
||||
EN_TANKORDER = 21, //!< Bulk water reaction order for tanks
|
||||
EN_CONCENLIMIT = 22, //!< Limiting concentration for growth reactions
|
||||
EN_DEMANDPATTERN = 23 //!< Name of default demand pattern
|
||||
EN_DEMANDPATTERN = 23, //!< Name of default demand pattern
|
||||
EN_EMITBACKFLOW = 24 //!< 1 if emitters can backflow, 0 if not
|
||||
} EN_Option;
|
||||
|
||||
/// Simple control types
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -112,6 +112,10 @@ char *RptFlagTxt[] = {w_NO,
|
||||
w_YES,
|
||||
w_FULL};
|
||||
|
||||
char *BackflowTxt[] = {w_NO,
|
||||
w_YES,
|
||||
NULL};
|
||||
|
||||
char *SectTxt[] = {s_TITLE, s_JUNCTIONS, s_RESERVOIRS,
|
||||
s_TANKS, s_PIPES, s_PUMPS,
|
||||
s_VALVES, s_CONTROLS, s_RULES,
|
||||
|
||||
10
src/epanet.c
10
src/epanet.c
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -1205,6 +1205,9 @@ int DLLEXPORT EN_getoption(EN_Project p, int option, double *value)
|
||||
case EN_DEMANDPATTERN:
|
||||
v = hyd->DefPat;
|
||||
break;
|
||||
case EN_EMITBACKFLOW:
|
||||
v = hyd->EmitBackFlag;
|
||||
break;
|
||||
default:
|
||||
return 251;
|
||||
}
|
||||
@@ -1367,6 +1370,11 @@ int DLLEXPORT EN_setoption(EN_Project p, int option, double value)
|
||||
hyd->DefPat = pat;
|
||||
break;
|
||||
|
||||
case EN_EMITBACKFLOW:
|
||||
if (value == 0.0 || value == 1.0) hyd->EmitBackFlag = (int)value;
|
||||
else return 213;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 251;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -495,6 +495,13 @@ void emitterheadloss(Project *pr, int i, double *hloss, double *hgrad)
|
||||
|
||||
// Otherwise use normal emitter head loss function
|
||||
else *hloss = (*hgrad) * q / hyd->Qexp;
|
||||
|
||||
// Prevent negative flow if backflow not allowed
|
||||
if (hyd->EmitBackFlag == 0 && q <= 0.0)
|
||||
{
|
||||
*hgrad += CBIG;
|
||||
*hloss += CBIG * q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: saves network data to an EPANET formatted text file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,7 @@ extern char *MixTxt[];
|
||||
extern char *TstatTxt[];
|
||||
extern char *RptFlagTxt[];
|
||||
extern char *SectTxt[];
|
||||
extern char *BackflowTxt[];
|
||||
|
||||
void saveauxdata(Project *pr, FILE *f)
|
||||
/*
|
||||
@@ -676,6 +677,7 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
fprintf(f, "\n PATTERN %s", net->Pattern[hyd->DefPat].ID);
|
||||
fprintf(f, "\n DEMAND MULTIPLIER %-.4f", hyd->Dmult);
|
||||
fprintf(f, "\n EMITTER EXPONENT %-.4f", 1.0 / hyd->Qexp);
|
||||
fprintf(f, "\n EMITTER BACKFLOW %s", BackflowTxt[hyd->EmitBackFlag]);
|
||||
fprintf(f, "\n VISCOSITY %-.6f", hyd->Viscos / VISCOS);
|
||||
fprintf(f, "\n DIFFUSIVITY %-.6f", qual->Diffus / DIFFUS);
|
||||
fprintf(f, "\n SPECIFIC GRAVITY %-.6f", hyd->SpGrav);
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: retrieves network data from an EPANET input file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 07/08/2019
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -120,6 +120,7 @@ void setdefaults(Project *pr)
|
||||
hyd->Epump = EPUMP; // Default pump efficiency
|
||||
hyd->Emax = 0.0; // Zero peak energy usage
|
||||
hyd->Qexp = 2.0; // Flow exponent for emitters
|
||||
hyd->EmitBackFlag = 1; // Allow emitter backflow
|
||||
hyd->DefPat = 0; // Default demand pattern index
|
||||
hyd->Dmult = 1.0; // Demand multiplier
|
||||
hyd->RQtol = RQTOL; // Default hydraulics parameters
|
||||
|
||||
14
src/input3.c
14
src/input3.c
@@ -7,7 +7,7 @@ Description: parses network data from a line of an EPANET input file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@ Last Updated: 08/13/2022
|
||||
extern char *MixTxt[];
|
||||
extern char *Fldname[];
|
||||
extern char *DemandModelTxt[];
|
||||
extern char *BackflowTxt[];
|
||||
|
||||
// Exported functions
|
||||
int powercurve(double, double, double, double, double, double *, double *,
|
||||
@@ -1759,6 +1760,7 @@ int optionchoice(Project *pr, int n)
|
||||
** UNBALANCED STOP/CONTINUE {Niter}
|
||||
** PATTERN id
|
||||
** DEMAND MODEL DDA/PDA
|
||||
** EMITTER BACKFLOW YES/NO
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
@@ -1897,6 +1899,16 @@ int optionchoice(Project *pr, int n)
|
||||
hyd->DemandModel = choice;
|
||||
}
|
||||
|
||||
// EMITTER BACKFLOW
|
||||
else if (match(parser->Tok[0], w_EMITTER))
|
||||
{
|
||||
if (n < 2) return 0;
|
||||
if (!match(parser->Tok[1], w_BACKFLOW)) return -1;
|
||||
choice = findmatch(parser->Tok[2], BackflowTxt);
|
||||
if (choice < 0) return setError(parser, 2, 213);
|
||||
hyd->EmitBackFlag = choice;
|
||||
}
|
||||
|
||||
// Return -1 if keyword did not match any option
|
||||
else return -1;
|
||||
return 0;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
#define w_SEGMENTS "SEGM"
|
||||
#define w_TOLERANCE "TOLER"
|
||||
#define w_EMITTER "EMIT"
|
||||
#define w_BACKFLOW "BACK"
|
||||
|
||||
#define w_PRICE "PRICE"
|
||||
#define w_DMNDCHARGE "DEMAN"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 08/13/2022
|
||||
Last Updated: 02/05/2023
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -744,6 +744,7 @@ typedef struct {
|
||||
Epat, // Energy cost time pattern
|
||||
DemandModel, // Fixed or pressure dependent
|
||||
Formflag, // Head loss formula flag
|
||||
EmitBackFlag, // Emitter backflow flag
|
||||
Iterations, // Number of hydraulic trials taken
|
||||
MaxIter, // Max. hydraulic trials allowed
|
||||
ExtraIter, // Extra hydraulic trials
|
||||
|
||||
Reference in New Issue
Block a user