diff --git a/ReleaseNotes2_3.md b/ReleaseNotes2_3.md
index 2a51cd6..a706923 100644
--- a/ReleaseNotes2_3.md
+++ b/ReleaseNotes2_3.md
@@ -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.
diff --git a/doc/input-file.dox b/doc/input-file.dox
index f4d36ce..758b847 100644
--- a/doc/input-file.dox
+++ b/doc/input-file.dox
@@ -298,6 +298,7 @@ __Formats:__
| PATTERN | id |
| DEMAND MULTIPLIER | value |
| EMITTER EXPONENT | value |
+| EMITTER BACKFLOW | YES / NO |
| QUALITY | NONE / CHEMICAL / AGE / TRACE nodeID |
| DIFFUSIVITY | value |
| TOLERANCE | value |
@@ -357,6 +358,8 @@ The DEMAND MULTIPLIER is used to adjust the values of baseline demands fo
EMITTER EXPONENT 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.
+EMITTER BACKFLOW specifies if back flow through an emitter (i.e., flow into the network) is allowed. The default is YES.
+
\b QUALITY selects the type of water quality analysis to perform. The choices are NONE, CHEMICAL, AGE, and \b TRACE. In place of \b CHEMICAL the actual name of the chemical can be used followed by its concentration units (e.g., CHLORINE mg/L). 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.
diff --git a/include/epanet.cs b/include/epanet.cs
index 68489e6..c379b8c 100644
--- a/include/epanet.cs
+++ b/include/epanet.cs
@@ -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;
diff --git a/include/epanet2.bas b/include/epanet2.bas
index 2d41bb2..ae26f53 100644
--- a/include/epanet2.bas
+++ b/include/epanet2.bas
@@ -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
diff --git a/include/epanet2.pas b/include/epanet2.pas
index fba8147..480cb3d 100644
--- a/include/epanet2.pas
+++ b/include/epanet2.pas
@@ -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;
diff --git a/include/epanet2.vb b/include/epanet2.vb
index 7c283f0..32ca854 100644
--- a/include/epanet2.vb
+++ b/include/epanet2.vb
@@ -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
diff --git a/include/epanet2_enums.h b/include/epanet2_enums.h
index 8c4be41..5fe6422 100644
--- a/include/epanet2_enums.h
+++ b/include/epanet2_enums.h
@@ -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
diff --git a/src/enumstxt.h b/src/enumstxt.h
index ccc12e8..682ab43 100755
--- a/src/enumstxt.h
+++ b/src/enumstxt.h
@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
- Last Updated: 08/13/2022
+ Last Updated: 02/05/2023
******************************************************************************
*/
@@ -111,6 +111,10 @@ char *MixTxt[] = {w_MIXED,
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,
diff --git a/src/epanet.c b/src/epanet.c
index d9e0280..f7818b7 100644
--- a/src/epanet.c
+++ b/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;
}
diff --git a/src/hydcoeffs.c b/src/hydcoeffs.c
index b45f032..55286fe 100644
--- a/src/hydcoeffs.c
+++ b/src/hydcoeffs.c
@@ -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;
+ }
}
diff --git a/src/inpfile.c b/src/inpfile.c
index f8b2005..33365ed 100644
--- a/src/inpfile.c
+++ b/src/inpfile.c
@@ -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);
diff --git a/src/input1.c b/src/input1.c
index 540225d..0e847f8 100644
--- a/src/input1.c
+++ b/src/input1.c
@@ -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
diff --git a/src/input3.c b/src/input3.c
index 9c2c795..082655a 100644
--- a/src/input3.c
+++ b/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
**--------------------------------------------------------------
*/
{
@@ -1896,6 +1898,16 @@ int optionchoice(Project *pr, int n)
if (choice < 0) return setError(parser, 2, 213);
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;
diff --git a/src/text.h b/src/text.h
index 72fef68..7f26a70 100755
--- a/src/text.h
+++ b/src/text.h
@@ -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"
diff --git a/src/types.h b/src/types.h
index 02634e7..a8d7273 100755
--- a/src/types.h
+++ b/src/types.h
@@ -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