Fixed water quality mass balance issue (#160)
This commit is contained in:
@@ -6,30 +6,30 @@ This document describes the changes and updates that have been made to version 2
|
||||
|
||||
## Thread-Safe API Functions
|
||||
|
||||
A duplicate set of the version 2.1 API functions has been provided that allow multiple EPANET projects to be analyzed concurrently in a thread-safe manner. These functions maintain the same name as the original but use a `EN_` prefix instead of `EN`. In addition, the first argument to each of these functions is a pointer to an `EN_Project` structure that encapsulates the network data for the particular project being analyzed. For example, instead of writing:
|
||||
A duplicate set of the version 2.1 API functions has been provided that allow multiple EPANET projects to be analyzed concurrently in a thread-safe manner. These functions maintain the same name as the original but use a `EN_` prefix instead of `EN`. In addition, the first argument to each of these functions is a handle that identifies the network data for the particular project being analyzed. For example, instead of writing:
|
||||
|
||||
`ENgetnodevalue(nodeIndex, EN_ELEVATION, &elev)`
|
||||
|
||||
one would use:
|
||||
|
||||
`EN_getnodevalue(pr, nodeIndex, EN_ELEVATION, &elev)`
|
||||
`EN_getnodevalue(ph, nodeIndex, EN_ELEVATION, &elev)`
|
||||
|
||||
where `pr` is the pointer to an `EN_Project`.
|
||||
where `ph` is the handle assigned to the project.
|
||||
|
||||
Two new functions have been added to the API to manage the creation and deletion of project pointers. `EN_createproject` creates a new project along with a pointer to it, while `EN_deleteproject` deletes a project. An example of using the thread-safe version of the API is shown below:
|
||||
Two new functions have been added to the API to manage the creation and deletion of project handles. `EN_createproject` creates a new project along with its handle, while `EN_deleteproject` deletes a project. An example of using the thread-safe version of the API is shown below:
|
||||
```
|
||||
#include "epanet2.h"
|
||||
int runEpanet(char *finp, char *frpt)
|
||||
{
|
||||
EN_Project *pr = NULL;
|
||||
EN_ProjectHandle ph = 0;
|
||||
int err;
|
||||
err = EN_createproject(&pr);
|
||||
err = EN_createproject(&ph);
|
||||
if (err) return err;
|
||||
err = EN_open(pr, finp, frpt, "");
|
||||
if (!err) err = EN_solveH(pr);
|
||||
if (!err) err = EN_report(pr);
|
||||
EN_close(pr);
|
||||
EN_deleteproject(pr);
|
||||
err = EN_open(ph, finp, frpt, "");
|
||||
if (!err) err = EN_solveH(ph);
|
||||
if (!err) err = EN_report(ph);
|
||||
EN_close(ph);
|
||||
EN_deleteproject(ph);
|
||||
return err;
|
||||
}
|
||||
```
|
||||
@@ -49,6 +49,11 @@ EPANET's hydraulic solver requires solving a system of linear equations over a s
|
||||
|
||||
EPANET's original node re-ordering scheme has been replaced by the more powerful **Multiple Minimum Degree (MMD)** algorithm. On a series of eight networks ranging in size from 7,700 to 100,000 nodes **MMD** reduced the solution time for a single period (steady state) hydraulic analysis by an average of 58%.
|
||||
|
||||
## Improved Handling of Near-Zero Flows
|
||||
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).
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -81,9 +86,26 @@ int EN_getdemandmodel(EN_Project *pr, int *modelType, double *pMin, double *pReq
|
||||
for the thread-safe API. Some additional points regarding the new **PDA** option are:
|
||||
|
||||
- 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 straightforward to do but is left as a future feature to implement.
|
||||
- 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.
|
||||
- *P<sub>min</sub>* is allowed to equal to *P<sub>req</sub>*. 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 *P<sub>min</min>*.
|
||||
|
||||
## 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.
|
||||
|
||||
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).
|
||||
|
||||
## Code Changes
|
||||
|
||||
@@ -96,6 +118,10 @@ for the thread-safe API. Some additional points regarding the new **PDA** option
|
||||
- `hydcoeffs.c` computes values of the matrix coefficients (derived from link head losses and their gradients) used by the hydraulic solver.
|
||||
- `hydstatus.c` checks for status changes in valves and pumps as requested by the hydraulic solver.
|
||||
- The Multiple Minimum Degree re-ordering algorithm appears in a new file named `genmmd.c`. This is 1990's legacy code that is readily available on the web and can be found in several linear equation solver libraries.
|
||||
- The original `quality.c` file has also been split into three separate files:
|
||||
- `quality.c` initializes the quality solver and supervises the quality calculations over each simulation time step.
|
||||
- `qualreact.c` reacts the quality constituent within each pipe and tank over a single time step and also implements the various tank mixing models.
|
||||
- `qualroute.c` topologically sorts the network's nodes when flow directions change and implements the Lagrangian Time Driven transport algorithm over a single time step.
|
||||
|
||||
## General changes
|
||||
- Read and write demand categories names
|
||||
@@ -152,6 +178,7 @@ for the thread-safe API. Some additional points regarding the new **PDA** option
|
||||
- `EN_HEADERROR`
|
||||
- `EN_FLOWCHANGE`
|
||||
- `EN_DEMANDDEFPAT`
|
||||
- `EN_MASSBALANCE`
|
||||
### Curve types:
|
||||
- `EN_V_CURVE`
|
||||
- `EN_P_CURVE`
|
||||
|
||||
Reference in New Issue
Block a user