diff --git a/ReleaseNotes2_2.md b/ReleaseNotes2_2.md index 9494f74..c560bbb 100644 --- a/ReleaseNotes2_2.md +++ b/ReleaseNotes2_2.md @@ -38,22 +38,35 @@ Prototypes of the thread-safe functions appear in the `epanet2_2.h` header file API users now have the ability to build a complete EPANET network model using just function calls, without the need to open an EPANET-formatted input file. All types of network objects can be created and have their properties set using these calls, including both simple and rule-based controls. Here is an example of building a simple 2-node, 1-pipe network just through code: ``` #include "epanet2_2.h" -int buildandrunEpanet(char *frpt) +int buildandrunEpanet(char *rptfile) { + // Create and initialize a project using gpm for flow + // units and the Hazen-Williams formula for head loss EN_Project ph = 0; - int err; + int err, index; err = EN_createproject(&ph); if (err) return err; - EN_init(ph, frpt, "", EN_GPM, EN_HW); - EN_addnode(ph, "J1, EN_JUNCTION); - EN_setjuncdata(ph, 1, 710, 500, ""); //elev, demand - EN_addnode(ph, "R1", EN_RESERVOIR); - EN_setnodevalue(ph, 2, EN_ELEVATION, 800); - EN_addlink(ph, "P1", EN_PIPE, "R1", "J1"); - EN_setpipedata(ph, 1, 5280, 14, 100, 0); // length, diam, C-factor + EN_init(ph, rptfile, "", EN_GPM, EN_HW); + + //Add a junction node with 710 ft elevation and 500 gpm demand + EN_addnode(ph, "J1", EN_JUNCTION, &index); + EN_setjuncdata(ph, index, 710, 500, ""); + + // Add a reservoir node at 800 ft elevation + EN_addnode(ph, "R1", EN_RESERVOIR, &index); + EN_setnodevalue(ph, index, EN_ELEVATION, 800); + + // Add a 5280 ft long, 14-inch pipe with C-factor of 100 + // from the reservoir to the demand node + EN_addlink(ph, "P1", EN_PIPE, "R1", "J1", &index); + EN_setpipedata(ph, index, 5280, 14, 100, 0); + + // Solve for hydraulics and report nodal results EN_setreport(ph, "NODES ALL"); err = EN_solveH(ph); if (!err) err = EN_report(ph); + + // Close and delete the project EN_close(ph); EN_deleteproject(&ph); return err; @@ -81,26 +94,26 @@ EPANET's original node re-ordering scheme has been replaced by the more powerful EPANET's hydraulic solver can generate an ill-conditioned solution matrix when pipe flows approach zero unless some adjustment is made (i.e., as a pipe's flow approaches 0 its head loss gradient also approaches 0 causing its reciprocal, which is used to form the solution matrix's coefficients, to approach infinity). EPANET 2.0 used an arbitrary cutoff on head loss gradient to prevent it from becoming 0. This approach doesn't allow a pipe to follow any head loss v. flow relation in the region below the cutoff and can produce incorrect solutions for some networks (see [Estrada et al., 2009](https://ascelibrary.org/doi/full/10.1061/%28ASCE%29IR.1943-4774.0000100)). -The hydraulic solver has been modified to use a linear head loss v. flow relation for flows approaching zero. For the Darcy-Weisbach equation, the linear Hagen-Poiseuille formula is used for laminar flow where the Reynolds Number is <= 2000. For the Hazen-Williams and Chezy-Manning equations, a flow limit `Qa` is established for each pipe, equal to the flow that produces the EPANET 2 gradient cutoff. For flows below this a linear head loss relation is used between 0 and the head loss at `Qa` and the gradient always equals the cutoff. EPANET 2.2 is now able to correctly solve the examples presented in Estrada et al. (2009) as well as those in [Gorev et al., (2013)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000694) and [Elhay and Simpson (2011)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000411). +The hydraulic solver has been modified to use a linear head loss v. flow relation for flows approaching zero. For the Darcy-Weisbach equation, the linear Hagen-Poiseuille formula is used for laminar flow where the Reynolds Number is <= 2000. For the Hazen-Williams and Chezy-Manning equations, a flow limit is established for each pipe, equal to the flow that produces the EPANET 2 gradient cutoff. For flows below this a linear head loss relation is used whose gradient always equals the cutoff. EPANET 2.2 is now able to correctly solve the examples presented in Estrada et al. (2009) as well as those in [Gorev et al., (2013)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000694) and [Elhay and Simpson (2011)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000411). ## Pressure Dependent Demands EPANET has always employed a Demand Driven Analysis (**DDA**) when modeling network hydraulics. Under this approach nodal demands at a given point in time are fixed values that must be delivered no matter what nodal heads and link flows are produced by a hydraulic solution. This can result in situations where required demands are satisfied at nodes that have negative pressures - a physical impossibility. -To address this issue EPANET has been extended to use a Pressure Driven Analysis (**PDA**) if so desired. Under **PDA**, the demand *D* delivered at a node depends on the node's available pressure *P* according to: +To address this issue EPANET has been extended to use a Pressure Driven Analysis (**PDA**) if so desired. Under **PDA**, the demand D delivered at a node depends on the node's available pressure P according to: -*D = Df [ (P - Pmin) / (Preq - Pmin) ]Pexp* +D = Dfull * [ (P - Pmin) / (Preq - Pmin) ]^Pexp -where *Df* is the full demand required, *Pmin* is the pressure below which demand is zero, *Preq* is the pressure required to deliver the full required demand and *Pexp* is an exponent. When *P < Pmin* demand is 0 and when *P > Preq* demand equals *Df*. +where Dfull is the full demand required, Pmin is the pressure below which demand is zero, Preq is the pressure required to deliver the full required demand and Pexp is an exponent. When P < Pmin demand is 0 and when P > Preq demand equals Dfull. To implement pressure driven analysis four new parameters have been added to the [OPTIONS] section of the EPANET input file: | Parameter | Description | Default | -|--|--|--| +|-----------|--------------|---------| | DEMAND MODEL | either DDA or PDA | DDA | -| MINIMUM PRESSURE | value for *Pmin* | 0 -| REQUIRED PRESSURE | value for *Preq* | 0 -| PRESSURE EXPONENT | value for *Pexp* | 0.5 | +| MINIMUM PRESSURE | value for Pmin | 0 +| REQUIRED PRESSURE | value for Preq | 0 +| PRESSURE EXPONENT | value for Pexp | 0.5 | These parameters can also be set and retrieved in code using the following API functions ``` @@ -116,30 +129,19 @@ for the thread-safe API. Some additional points regarding the new **PDA** option - If no DEMAND MODEL and its parameters are specified then the analysis defaults to being demand driven (**DDA**). - This implementation of **PDA** assumes that the same parameters apply to all nodes in the network. Extending the framework to allow different parameters for specific nodes is left as a future feature to implement. - - *Pmin* is allowed to equal to *Preq*. This condition can be used to find a solution that results in the smallest amount of demand reductions needed to insure that no node delivers positive demand at a pressure below *Pmin*. + - Pmin is allowed to equal to Preq. This condition can be used to find a solution that results in the smallest amount of demand reductions needed to insure that no node delivers positive demand at a pressure below Pmin. ## Improved Water Quality Mass Balance As described by [Davis et al. (2018)](https://www.drink-water-eng-sci.net/11/25/2018/dwes-11-25-2018.pdf) EPANET's water quality simulations can result in some significant mass balance errors when modeling short term mass injections (errors are much smaller for continuous source flows). The entire water quality engine has been re-written to eliminate these errors. It still uses the Lagrangian Time Driven transport method but now analyzes each network node in topologically sorted order rather than in arbitrary order. -A Mass Balance Report now appears the end of a simulation's Status Report that lists the various components (inflow, outflow, reaction) that comprise the network's overall mass balance. In addition `EN_MASSBALANCE` can be used as a parameter in the `ENgetstatistic` (or `EN_getstatistic`) function to retrieve the Mass Balance Ratio (Total Outflow Mass / Total Inflow Mass) at any point during a water quality simulation. +A Mass Balance Report now appears the end of a simulation's Status Report that lists the various components (inflow, outflow, reaction) that comprise the network's overall mass balance. In addition `EN_MASSBALANCE` can be used as a parameter in the `EN_getstatistic` (or `ENgetstatistic`) function to retrieve the Mass Balance Ratio (Total Outflow Mass / Total Inflow Mass) at any point during a water quality simulation. -Mass balance ratio (MBR) results for two of the networks analyzed by Davis et al. (2018) are shown in the following table. MBR-2.0 is for EPANET 2.0.012 as reported by Davis et al. while MBR-2.2 is for the re-written quality engine. - -| Network | Time Step (s) | MBR-2.0 | MBR-2.2 | -|--|--|--|--| -| N2 | 900 | 16.63 | 1.00 | -| | 300 | 23.45 | 1.00 | -| | 60 | 6.49 | 1.00 | -| N4 | 900 | 0.09 | 1.00 | -| | 300 | 0.70 | 1.00 | -| | 60 | 0.98 | 1.00 | - -Both network files are available [here](https://doi.org/10.23719/1375314). +With this change EPANET 2.2 now produces perfect mass balances when tested against the networks used in Davis et al. (2018). ## New API functions |Function|Description| -|--|--| +|--------|-----------| |`EN_createproject` | Creates a new EPANET project | |`EN_deleteproject` | Deletes an EPANET project | |`EN_init`|Initializes an EPANET project| @@ -163,6 +165,9 @@ Both network files are available [here](https://doi.org/10.23719/1375314). |`EN_setpipedata`|Sets values for a pipe's parameters| |`EN_getdemandmodel`|Retrieves the type of demand model in use | |`EN_setdemandmodel`|Sets the type of demand model to use| +|`EN_adddemand`|Adds a new demand category to a node| +|`EN_deletedemand`|Deletes a demand category from a node| +|`EN_getdemandindex`|Finds a demand category's index given its name| |`EN_getdemandname`|Gets the name of a node's demand category| |`EN_setdemandname`|Sets the name of a node's demand category| |`EN_setdemandpattern`|Assigns a time pattern to a node's demand category | @@ -170,7 +175,7 @@ Both network files are available [here](https://doi.org/10.23719/1375314). |`EN_setcurveid`|Changes the ID name of a data curve| |`EN_getcurvetype`|Gets a curve's type| |`EN_setheadcurveindex`|Sets the index of a head curve used by a pump | -|`EN_getrule`|Gets the number of elements in a rule-based control | +|`EN_getruleinfo`|Gets the number of elements in a rule-based control | |`EN_getruleid` | Gets the name assigned to a rule-based control | |`EN_getpremise`|Gets the contents of a premise in a rule-based control| |`EN_setpremise`|Sets the contents of a premise in a rule-based control| @@ -184,6 +189,8 @@ Both network files are available [here](https://doi.org/10.23719/1375314). |`EN_setrulepriority`|Sets the priority of a rule-based control| |`EN_gettitle` |Gets a project's title | |`EN_settitle` |Sets a project's title | +|`EN_getcomment` |Gets the descriptive comment assigned to an object| +|`EN_setcomment` |Assigns a descriptive comment to an object| |`EN_clearreport` |Clears the contents of a project's report file | |`EN_copyreport` | Copies the contents of a project's report file | In addition to these new functions, a tank's volume curve `EN_VOLCURVE` can be set using `EN_setnodevalue` and `EN_setlinkvalue` can now be used to set the following pump properties: @@ -222,13 +229,25 @@ Access to the following global energy options have been added to `EN_getoption` ### Hydraulic option types: - `EN_HEADERROR` - `EN_FLOWCHANGE` - - `EN_DEFDEMANDPAT` - `EN_HEADLOSSFORM` - `EN_GLOBALEFFIC` - `EN_GLOBALPRICE` - `EN_GLOBALPATTERN` - `EN_DEMANDCHARGE` + - `EN_SP_GRAVITY` + - `EN_SP_VISCOS` + - `EN_EXTRA_ITER` + - `EN_CHECKFREQ` + - `EN_MAXCHECK` + - `EN_DAMPLIMIT` +### Quality option types: +- `EN_SP_DIFFUS` + - `EN_BULKORDER` + - `EN_WALLORDER` + - `EN_TANKORDER` + - `EN_CONCENLIMIT` + ### Simulation statistic types: - `EN_MAXHEADERROR` - `EN_MAXFLOWCHANGE` @@ -248,6 +267,9 @@ Access to the following global energy options have been added to `EN_getoption` ### Demand model types: - `EN_DDA` - `EN_PDA` - + +## Documentation +Doxygen files have been created to generate a complete Users Guide for version 2.2's API. The guide's format is similar to the original EPANET Programmer's Toolkit help file and can be produced as a set of HTML pages, a Windows help file or a PDF document. + ## Authors contributing to this release: - List item diff --git a/doc/modules.dox b/doc/modules.dox index 6a990be..f5912ab 100644 --- a/doc/modules.dox +++ b/doc/modules.dox @@ -162,6 +162,9 @@ These are symbolic constants used as function arguments. @{ @fn int EN_getdemandmodel(EN_Project ph, int *type, double *pmin, double *preq, double *pexp) @fn int EN_setdemandmodel(EN_Project ph, int type, double pmin, double preq, double pexp) +@fn int EN_adddemand(EN_Project ph, int nodeIndex, double baseDemand, char *demandPattern, char *demandName) +@fn int EN_deletedemand(EN_Project ph, int nodeIndex, int demandIndex) +@fn int EN_getdemandindex(EN_Project p, int nodeIndex, char *demandName, int *demandIndex) @fn int EN_getnumdemands(EN_Project ph, int nodeIndex, int *numDemands) @fn int EN_getbasedemand(EN_Project ph, int nodeIndex, int demandIndex, double *baseDemand) @fn int EN_setbasedemand(EN_Project ph, int nodeIndex, int demandIndex, double baseDemand)