Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
Michael Tryby
2019-01-28 10:26:44 -05:00
55 changed files with 35008 additions and 2823 deletions

View File

@@ -1,11 +1,10 @@
Release Notes for EPANET 2.2 (Draft)
Release Notes for EPANET 2.2 (Draft)
============================
This document describes the changes and updates that have been made to version 2.2 of EPANET.
## 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 handle that identifies the network data for the particular project being analyzed. For example, instead of writing:
A duplicate set of 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 particular project being analyzed. For example, instead of writing:
`ENgetnodevalue(nodeIndex, EN_ELEVATION, &elev)`
@@ -13,14 +12,14 @@ one would use:
`EN_getnodevalue(ph, nodeIndex, EN_ELEVATION, &elev)`
where `ph` is the handle assigned to the 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 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"
#include "epanet2_2.h"
int runEpanet(char *finp, char *frpt)
{
EN_ProjectHandle ph = 0;
EN_Project ph = 0;
int err;
err = EN_createproject(&ph);
if (err) return err;
@@ -32,6 +31,35 @@ int runEpanet(char *finp, char *frpt)
return err;
}
```
Prototypes of the thread-safe functions appear in the `epanet2_2.h` header file while `epanet2.h` contains prototypes of the legacy-style API functions. The enumerated constants used with both types of functions have been moved to `epanet2_enums.h`.
## Network Building By Code
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)
{
EN_Project ph = 0;
int err;
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_setreport(ph, "NODES ALL");
err = EN_solveH(ph);
if (!err) err = EN_report(ph);
EN_close(ph);
EN_deleteproject(&ph);
return err;
}
```
Instead of using `EN_open` to load data from a file, `EN_init` is used to initialize a project with the names of its report and binary files, and its flow units and head loss formula. The legacy-style API has a complementary set of functions for building networks from code.
## Additional Convergence Parameters
@@ -44,16 +72,19 @@ Two new analysis options have been added to provide more rigorous convergence cr
These new parameters augment the current `EN_ACCURACY` option which always remains in effect. In addition, both `EN_HEADERROR` and `EN_FLOWCHANGE` can be used as parameters in the `ENgetstatistic` (or `EN_getstatistic`) function to retrieve their computed values (even when their option values are 0) after a hydraulic solution has been completed.
## Improved Linear Solver Routine
EPANET's hydraulic solver requires solving a system of linear equations over a series of iterations until a set of convergence criteria are met. The coefficient matrix of this linear system is square and symmetric. It has a row for each network node and a non-zero off-diagonal coefficient for each link. The numerical effort needed to solve the linear system can be reduced if the nodes are re-ordered so that the non-zero coefficients cluster more tightly around the diagonal.
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.
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:
@@ -64,7 +95,6 @@ where *D<sub>f</sub>* is the full demand required, *P<sub>min</sub>* is the pres
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 |
@@ -89,6 +119,7 @@ for the thread-safe API. Some additional points regarding the new **PDA** option
- *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.
@@ -106,98 +137,109 @@ Mass balance ratio (MBR) results for two of the networks analyzed by Davis et al
Both network files are available [here](https://doi.org/10.23719/1375314).
## Code Changes
- The header file `vars.h` containing global variables has been eliminated. Instead a number of new structures incorporating these variables has been added to `types.h`. These structures have been incorporated into the new `EN_Project` structure, also defined in `types.h`, which gets passed into each of the thread-safe API functions as a pointer.
- Each of the legacy API functions now simply calls its thread-safe counterpart passing in a pointer to a default global`EN_Project` variable that is declared in `types.h`.
- Throughout all code modules, global variables that were previously accessed through `vars.h` are now accessed using the `EN_Project` pointer that is passed into the functions where the variables appear.
- The exceedingly long `hydraul.c` file has been split into four separate files:
- `hydraul.c` now contains just the code needed to initialize a hydraulic analysis, set demands and control actions at each time step, and determine the length of the next time step to take.
- `hydsolver.c` implements EPANET's hydraulic solver at a single point in time.
- `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
## New API functions
|Function|Description|
|--|--|
|`ENinit`|Initializes an EPANET session|
|`ENsetflowunits`|Sets the flow units|
|`ENgetdemandmodel`|Retrieves the type of demand model in use and its parameters|
|`ENsetdemandmodel`|Sets the type of demand model to use and its parameters|
|`ENgetdemandname`|Sets the node's demand name for a category|
|`ENsetdemandname`|Sets the node's demand name for a category|
|`ENsetdemandpattern`|Sets the index of the demand pattern assigned to a node for a category index|
|`ENsetheadcurveindex`|Sets the curve id for a specified pump index|
|`ENgetrule`|Gets the number of premises, true actions, and false actions and the priority of an existing rule-based control|
|`ENsetrulepriority`|Sets the priority of the existing rule-based control|
|`ENgetpremise`|Gets the components of a premise/condition in an existing rule-based control|
|`ENsetpremise`|Sets the components of a premise/condition in an existing rule-based control|
|`ENsetpremiseindex`|Sets the index of an object in a premise of an existing rule-based control|
|`ENsetpremisestatus`|Sets the status in a premise of an existing rule-based control|
|`ENsetpremisevalue`|Sets the value in a premise of an existing rule-based control|
|`ENgetthenaction`|Get the components of a THEN action in a rule-based control|
|`ENsetthenaction`|Set the components of a THEN action in a rule-based control|
|`ENgetelseaction`|Get the components of an ELSE action in a rule-based control|
|`ENsetelseaction`|Set the components of an ELSE action in a rule-based control|
|`ENgetruleID`|Returns the ID of a rule|
|`ENgetcurvetype`|Get the type of a curve|
|`ENsetlinknodes`|Set the indexes of a link's start- and end-nodes|
|`ENsetlinktype`|Set the link type code for a specified link|
|`ENaddnode`|Adds a new node|
|`ENaddlink`|Adds a new link|
|`ENaddcontrol`|Specify parameters to add a new simple control|
|`ENaddrule`|Add a new control rule to the project|
|`ENdeletenode`|Deletes a node|
|`ENdeletelink`|Deletes a link|
|`ENdeletecontrol`|Delete an existing simple control|
|`ENdeleterule`|Delete a rule-based control|
|`ENsetnodeid`|Change the ID name for a node|
|`ENsetlinkid`|Change the ID name for a link|
|`EN_createproject` | creates a new EPANET project |
|`EN_deleteproject` | deletes an EPANET project |
|`EN_init`|Initializes an EPANET project|
|`EN_setflowunits`|Sets the project's flow units|
|`EN_addnode`|Adds a new node to a project|
|`EN_addlink`|Adds a new link to a project|
|`EN_addcontrol`|Adds a new simple control to a project|
|`EN_addrule`|Adds a new control rule to a project|
|`EN_deletenode`|Deletes a node from the project|
|`EN_deletelink`|Deletes a link from the project|
|`EN_deletecontrol`|Deletes a simple control from the project|
|`EN_deleterule`|Deletes a rule-based control from the project|
|`EN_setnodeid`|Changes the ID name for a node|
|`EN_setjuncdata` |Sets values for a junction's parameters |
|`EN_settankdata` |Sets values for a tank's parameters|
|`EN_setlinkid`|Changes the ID name for a link|
|`EN_setlinknodes`|Sets a link's start- and end-nodes|
|`EN_setlinktype`|Changes the type of a specific link|
|`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_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 |
|`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_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|
|`EN_setpremiseindex`|Sets the index of an object in a premise of a rule-based control|
|`EN_setpremisestatus`|Sets the status of an object in a premise of a rule-based control|
|`EN_setpremisevalue`|Sets the value of a property in a premise of a rule-based control|
|`EN_getthenaction`|Gets the contents of a THEN action in a rule-based control|
|`EN_setthenaction`|Sets the contents of a THEN action in a rule-based control|
|`EN_getelseaction`|Gets the contents of an ELSE action in a rule-based control|
|`EN_setelseaction`|Set the contents of an ELSE action in a rule-based control|
|`EN_setrulepriority`|Sets the priority of a rule-based control|
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:
- `EN_PUMP_POWER` (constant power rating)
- `EN_PUMP_HCURVE` (head characteristic curve)
- `EN_PUMP_ECURVE` (efficiency curve)
- `EN_PUMP_ECOST` (average energy price)
- `EN_PUMP_EPAT` (energy pricing pattern)
- `EN_LINKPATTERN` (speed setting pattern)
Access to the following global energy options have been added to `EN_getoption` and `EN_setoption`:
- `EN_GLOBALEFFIC` (global pump efficiency)
- `EN_GLOBALPRICE` (global average energy price per kW-Hour)
- `EN_GLOBALPATTERN` (global energy price pattern)
- `EN_DEMANDCHARGE` (price per maximum kW of energy consumption)
## New API Constants
## API Extensions (additional definitions)
### Link value types:
- `EN_EFFICIENCY`
- `EN_HEADCURVE`
- `EN_EFFICIENCYCURVE`
- `EN_PRICEPATTERN`
- `EN_STATE`
- `EN_CONST_POWER`
- `EN_SPEED`
- `EN_PUMP_STATE`
- `EN_PUMP_EFFIC`
- `EN_PUMP_POWER`
- `EN_PUMP_HCURVE`
- `EN_PUMP_ECURVE`
- `EN_PUMP_ECOST`
- `EN_PUMP_EPAT`
### Count types:
- `EN_RULECOUNT`
### Head loss formula:
- `EN_HW`
- `EN_DW`
- `EN_CM`
### Option types:
### Hydraulic option types:
- `EN_HEADERROR`
- `EN_FLOWCHANGE`
- `EN_DEMANDDEFPAT`
- `EN_DEFDEMANDPAT`
- `EN_HEADLOSSFORM`
### Time statistic types:
- `EN_GLOBALEFFIC`
- `EN_GLOBALPRICE`
- `EN_GLOBALPATTERN`
- `EN_DEMANDCHARGE`
### Simulation statistic types:
- `EN_MAXHEADERROR`
- `EN_MAXFLOWCHANGE`
- `EN_MASSBALANCE`
### Action code types:
### Action code types:
- `EN_UNCONDITIONAL`
- `EN_CONDITIONAL`
### Curve types:
- `EN_V_CURVE`
- `EN_P_CURVE`
- `EN_E_CURVE`
- `EN_H_CURVE`
- `EN_G_CURVE`
- `EN_VOLUME_CURVE`
- `EN_PUMP_CURVE`
- `EN_EFFIC_CURVE`
- `EN_HLOSS_CURVE`
- `EN_GENERIC_CURVE`
### Demand model types:
- `EN_DDA`
- `EN_PDA`
## Authors contributing to this release:
- List item
- List item

15958
doc/DataFlow.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/DataFlow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

195
doc/DoxygenLayout.xml Normal file
View File

@@ -0,0 +1,195 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.10 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="Reference"
intro="These topics describe the Toolkit's functions, symbolic constants, and other details related to its usage."/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="no" title="">
<tab type="filelist" visible="no" title="" intro=""/>
<tab type="globals" visible="no" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title="File Sections"/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title="Overview"/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

5118
doc/Example2.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/Example2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,43 +0,0 @@
/**
@page how-to-use How to Use the Toolkit
The following topics briefly describe how to accomplish some basic tasks for which the Toolkit would be used. See the Example Applications topic for code listings of complete applications of the Toolkit.
@section open-close Opening and Closing the Toolkit
The Toolkit must open an EPANET [Input File](Input-File) to obtain a description of the pipe network to be analyzed before any of its other functions can be called. (The exception to this is the @ref ENepanet function, which performs a complete hydraulic/water quality simulation similar to a command line execution of EPANET). Once all analysis is completed, it must close itself down to free all allocated memory. The functions for doing this are @ref ENopen and @ref ENclose, respectively. An example of using these functions is shown below.
~~~~~~~~~~~~~~~{.c}
char *f1, // Name of input file
*f2, // name of report file
*f3; // name of output file (can be blank)
int errcode;
errcode = ENopen(f1, f2, f3);
if (errcode > 0) {
ENclose();
return;
}
{ Call functions that perform desired analysis }
ENclose();
~~~~~~~~~~~~~~~
@section parameters Retrieving and Setting Network Parameters
The Toolkit has various functions available for retrieving and setting the parameters that define the design and operation of the pipe network being analyzed. The names of retrieval functions all begin with `ENget` (e.g., [ENgetnodevalue](ENgetnodevalue), [ENgetoption](ENgetoption), etc.) while the functions used for setting parameter values begin with `ENset` (e.g., [ENsetnodevalue](ENsetnodevalue), [ENsetoption](ENsetoption), etc.).
Most of these functions use an index number to reference a specific network component (such as a node, link, or time pattern). This number is simply the position of the component in the list of all components of similar type (e.g., node 10 is the tenth node, starting from 1, in the network) and is not the same as the ID label assigned to the component in the Input File being processed. A series of functions exist to determine a component's index number given its ID label (see [ENgetlinkindex](ENgetlinkindex), [ENgetnodeindex](ENgetnodeindex), and [ENgetpatternindex](ENgetpatternindex)). Likewise, functions exist to retrieve a component's ID label given its index number (see [ENgetlinkid](ENgetlinkid), [ENgetnodeid](ENgetnodeid), and [ENgetpatternid](ENgetpatternid)). The [ENgetcount](ENgetcount) function can be used to determine the number of different components in the network.
The code below is an example of using the parameter retrieval and setting functions. It changes all pipes with diameter of 10 inches to 12 inches.
~~~~~~~~~~~~~~~{.c}
int i, Nlinks;
float D;
ENgetcount(EN_LINKCOUNT, &Nlinks);
for (i = 1; i <= Nlinks; i++) {
ENgetlinkvalue(i, EN_DIAMETER, &D);
if (D == 10) ENsetlinkvalue(i, EN_DIAMETER, 12);
}
~~~~~~~~~~~~~~~
*/

8420
doc/Network.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/Network.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,23 +0,0 @@
/**
@page toolkit-overview Toolkit Overview
The Programmer's Toolkit is an extension of the EPANET simulation package. EPANET performs extended period simulation of hydraulic and water quality behavior within pressurized pipe networks. A network can consist of pipes, nodes (pipe junctions), pumps, valves and storage tanks or reservoirs. EPANET tracks the flow of water in each pipe, the pressure at each node, the height of water in each tank, and the concentration of a chemical species throughout the network during a multi-time period simulation. In addition to chemical species, water age and source tracing can also be simulated.
The Toolkit provides a series of functions that allow programmers to customize the use of EPANET's hydraulic and water quality solution engine to their own applications. Before using the Toolkit one should become familiar with the way that EPANET represents a pipe network and the design and operating information it requires to perform a simulation. This information can be obtained from reading EPANET's on-line Help file or from the EPANET Users Manual.
A typical usage of the Toolkit functions to analyze a distribution system might look as follows:
1. Use the @ref ENopen function to open the Toolkit system, along with an EPANET [Input file](Input-File).
2. Use the `ENsetxxx` series of functions to change selected system characteristics.
3. Run a full hydraulic simulation using the @ref ENsolveH function (which automatically saves results to a [Hydraulics file](Hydraulics-File)) or use the @ref ENopenH - @ref ENinitH - @ref ENrunH - @ref ENnextH - @ref ENcloseH series of functions to step through a hydraulic simulation, accessing results along the way with the `ENgetxxx` series of functions.
4. Run a full water quality simulation using @ref ENsolveQ (which automatically saves hydraulic and water quality results to an [Output file](Output-File)) or use the @ref ENopenQ - @ref ENinitQ - @ref ENrunQ - @ref ENnextQ (or @ref ENstepQ) - @ref ENcloseQ series of functions to step through a water quality simulation, accessing results along the way with the `ENgetxxx` series of functions.
5. Return to Step 2 to run additional analyses or use the @ref ENreport function to write a formatted report to the [Report file](Report-File).
6. Call the @ref ENclose function to close all files and release system memory.
More specific examples of using the functions can be found in the [Example Applications](Example-Applications) topic.
- @subpage how-to-use
*/

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.8.11
# Doxyfile 1.8.10
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -32,13 +32,13 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = EPANET
PROJECT_NAME = "OWA-EPANET Toolkit"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 2.1
PROJECT_NUMBER = 2.2
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = ../epanet-owa-dox
OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -226,7 +226,7 @@ SEPARATE_MEMBER_PAGES = NO
# uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4.
TAB_SIZE = 2
TAB_SIZE = 4
# This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form:
@@ -694,7 +694,7 @@ FILE_VERSION_FILTER =
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
LAYOUT_FILE =
LAYOUT_FILE = DoxygenLayout.xml
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
@@ -749,12 +749,6 @@ WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# The default value is: NO.
WARN_AS_ERROR = NO
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated
@@ -781,10 +775,13 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = ../include \
../src \
../doc \
../
INPUT = main.dox \
toolkit-usage.dox \
toolkit-examples.dox \
modules.dox \
../include/epanet2_2.h \
../include/epanet2_enums.h \
output-format.dox
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -806,8 +803,8 @@ INPUT_ENCODING = UTF-8
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
# *.vhdl, *.ucf, *.qsf, *.as and *.js.
FILE_PATTERNS = *.c \
*.cc \
@@ -856,7 +853,7 @@ FILE_PATTERNS = *.c \
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = NO
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
@@ -918,7 +915,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH = .
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -934,10 +931,6 @@ IMAGE_PATH =
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
INPUT_FILTER =
@@ -947,10 +940,6 @@ INPUT_FILTER =
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
FILTER_PATTERNS =
@@ -1068,7 +1057,7 @@ VERBATIM_HEADERS = YES
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse-libclang=ON option for CMake.
# compiled with the --with-libclang option.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
@@ -1122,7 +1111,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = ../../epanet-owa-dox
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
@@ -1149,7 +1138,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER =
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1159,7 +1148,7 @@ HTML_HEADER =
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER =
HTML_FOOTER = newfooter.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1184,7 +1173,7 @@ HTML_STYLESHEET =
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_STYLESHEET = extrastylesheet.css
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
@@ -1323,7 +1312,7 @@ GENERATE_HTMLHELP = NO
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_FILE =
CHM_FILE = owa_epanet.chm
# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
@@ -1331,7 +1320,7 @@ CHM_FILE =
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
HHC_LOCATION = "c:\Program Files (x86)\HTML Help Workshop\hhc.exe"
# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the master .chm file (NO).
@@ -1453,7 +1442,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
DISABLE_INDEX = NO
DISABLE_INDEX = YES
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
@@ -1480,7 +1469,7 @@ GENERATE_TREEVIEW = YES
# Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES.
ENUM_VALUES_PER_LINE = 4
ENUM_VALUES_PER_LINE = 0
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
# to set the initial width (in pixels) of the frame in which the tree is shown.
@@ -1658,7 +1647,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = NO
GENERATE_LATEX = yes
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -1729,7 +1718,7 @@ EXTRA_PACKAGES =
# to HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
LATEX_HEADER = header.tex
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
@@ -1740,7 +1729,7 @@ LATEX_HEADER =
# Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
LATEX_FOOTER =
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# LaTeX style sheets that are included after the standard style sheets created
@@ -1751,7 +1740,7 @@ LATEX_FOOTER =
# list).
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_STYLESHEET =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output
@@ -1792,7 +1781,7 @@ LATEX_BATCHMODE = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HIDE_INDICES = NO
LATEX_HIDE_INDICES = YES
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
@@ -1812,14 +1801,6 @@ LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -2059,7 +2040,7 @@ MACRO_EXPANSION = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = YES
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
@@ -2175,7 +2156,7 @@ PERL_PATH = /usr/bin/perl
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
CLASS_DIAGRAMS = NO
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:

2
doc/extrastylesheet.css Normal file
View File

@@ -0,0 +1,2 @@
h1 { font-size:1.5em; }

12
doc/footer.tex Normal file
View File

@@ -0,0 +1,12 @@
% Latex footer for doxygen 1.8.10
%--- End generated contents ---
% Index
\backmatter
\newpage
\phantomsection
\clearemptydoublepage
\addcontentsline{toc}{chapter}{Index}
\printindex
\end{document}

141
doc/header.tex Normal file
View File

@@ -0,0 +1,141 @@
% Latex header for doxygen 1.8.10
\documentclass[twoside]{book}
% Packages required by doxygen
\usepackage{fixltx2e}
\usepackage{calc}
\usepackage{doxygen}
\usepackage[export]{adjustbox} % also loads graphicx
\usepackage{graphicx}
\usepackage[utf8]{inputenc}
\usepackage{makeidx}
\usepackage{multicol}
\usepackage{multirow}
\PassOptionsToPackage{warn}{textcomp}
\usepackage{textcomp}
\usepackage[nointegrals]{wasysym}
\usepackage[table]{xcolor}
% Font selection
\usepackage[T1]{fontenc}
\usepackage[scaled=.90]{helvet}
\usepackage{courier}
\usepackage{amssymb}
\usepackage{sectsty}
\renewcommand{\familydefault}{\sfdefault}
\allsectionsfont{%
\fontseries{bc}\selectfont%
\color{darkgray}%
}
\renewcommand{\DoxyLabelFont}{%
\fontseries{bc}\selectfont%
\color{darkgray}%
}
\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}}
% Page & text layout
\usepackage{geometry}
\geometry{%
a4paper,%
top=2.5cm,%
bottom=2.5cm,%
left=2.5cm,%
right=2.5cm%
}
\tolerance=750
\hfuzz=15pt
\hbadness=750
\setlength{\emergencystretch}{15pt}
\setlength{\parindent}{0cm}
\setlength{\parskip}{0.2cm}
\makeatletter
\renewcommand{\paragraph}{%
\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%
\normalfont\normalsize\bfseries\SS@parafont%
}%
}
\renewcommand{\subparagraph}{%
\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%
\normalfont\normalsize\bfseries\SS@subparafont%
}%
}
\makeatother
% Headers & footers
\usepackage{fancyhdr}
\pagestyle{fancyplain}
\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}}
\fancyhead[CE]{\fancyplain{}{}}
\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}}
\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}}
\fancyhead[CO]{\fancyplain{}{}}
\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}}
\fancyfoot[LE]{\fancyplain{}{}}
\fancyfoot[CE]{\fancyplain{}{}}
\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize OWA-EPANET 2.2 \textcopyright 2019}}
\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize OWA-EPANET 2.2 \textcopyright 2019}}
\fancyfoot[CO]{\fancyplain{}{}}
\fancyfoot[RO]{\fancyplain{}{}}
\renewcommand{\footrulewidth}{0.4pt}
\renewcommand{\chaptermark}[1]{%
\markboth{#1}{}%
}
\renewcommand{\sectionmark}[1]{%
\markright{\thesection\ #1}%
}
% Indices & bibliography
\usepackage{natbib}
\usepackage[titles]{tocloft}
\setcounter{tocdepth}{1}
\setcounter{secnumdepth}{5}
\makeindex
% Hyperlinks (required, but should be loaded last)
\usepackage{ifpdf}
\ifpdf
\usepackage[pdftex,pagebackref=true]{hyperref}
\else
\usepackage[ps2pdf,pagebackref=true]{hyperref}
\fi
\hypersetup{%
colorlinks=true,%
linkcolor=blue,%
citecolor=blue,%
unicode%
}
% Custom commands
\newcommand{\clearemptydoublepage}{%
\newpage{\pagestyle{empty}\cleardoublepage}%
}
%===== C O N T E N T S =====
\begin{document}
% Titlepage & ToC
\hypersetup{pageanchor=false,
bookmarks=true,
bookmarksnumbered=true,
pdfencoding=unicode
}
\pagenumbering{roman}
\begin{titlepage}
\vspace*{7cm}
\begin{center}%
{\Large OWA-EPANET Toolkit\linebreak\linebreak 2.2}\\
\vspace*{1cm}
{\large January 2019}\\
%\vspace*{0.5cm}
%{\small Wed Jan 23 2019 17:57:36}\\
\end{center}
\end{titlepage}
\clearemptydoublepage
\tableofcontents
\clearemptydoublepage
\pagenumbering{arabic}
\hypersetup{pageanchor=true}
%--- Begin generated contents ---

View File

@@ -1,12 +1,98 @@
/**
@mainpage EPANET Open Source
@mainpage Overview
The EPANET Open-Source Library is a pressurized pipe network hydraulic and water quality analysis toolkit, originally developed by USEPA, written in C.
EPANET is a program that performs extended period simulation of hydraulic and water quality behavior within pressurized pipe networks. A network can consist of pipes, nodes (pipe junctions), pumps, valves and storage tanks or reservoirs. EPANET tracks the flow of water in each pipe, the pressure at each node, the height of water in each tank, and the concentration of a chemical species throughout the network during a multi-time period simulation. In addition to chemical species, water age and source tracing can also be simulated. The EPANET Programmer's Toolkit is a library of functions (or API) that allow programmers to customize the use of EPANET's hydraulic and water quality solution engine to their own applications. Both EPANET and its toolkit were originally developed and are currently maintained by the U.S. Environmental Protection Agency (USEPA).
__Note:__ This repository is not affiliated with, or endorsed by, the USEPA. For the "official" release of EPANET (2.00.12 UI and Toolkit) please go to the [EPA's GitHub repo](https://github.com/USEPA/Water-Distribution-Network-Model) or [the USEPA website](http://www2.epa.gov/water-research/epanet). It is also not the graphical user interface version. This is the hydraulic and water quality solver engine.
The OWA-EPANET Toolkit is an open-source version of the original EPANET Toolkit that extends its capabilities by:
- providing a full set of functions to set and retrieve values for all parameters contained in a network model
- allowing networks to be built completely from function calls instead of from an input file
- allowing multiple projects to be analyzed in parallel in a thread-safe manner
- adding the ability to use pressure dependent demands in hydraulic analyses
- producing more robust results with regard to hydraulic convergence, low/zero flow conditions, and water quality mass balance
- achieving faster run times for hydraulic analyses.
However, if you are interested in extending EPANET for academic, personal, or commercial use, then you've come to the right place. For community discussion, FAQ, and roadmapping of the project, go to the [Community Forum](http://community.wateranalytics.org/category/epanet).
Before using the OWA-EPANET Toolkit one should be familiar with the way that EPANET represents a pipe network, the design and operating information it requires, and the steps it uses to simulate a network's behavior. The following topics provide some introductory material on these subjects:
- @subpage DataModel "Network Data Model"
- @subpage DataFlow "Data Flow Diagram"
- @subpage ToolkitVersions "Toolkit Versions"
- @subpage toolkit-overview "Toolkit Overview"
More detailed information can be obtained from reading the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>.
*/
__Note:__ OWA (Open Water Analytics) exists on GitHub as an open community for the exchange of information and ideas related to computing in the water & wastewater industries. It's activities and code projects are neither affiliated with nor endorsed by the USEPA.
*/
/**
@page DataModel Network Data Model
EPANET models a pipe network as a collection of links connected to nodes. The links represent pipes, pumps, and control valves. The nodes represent junctions, tanks, and reservoirs. The figure below illustrates how these objects can be connected to one another to form a network.
@image html Network.png
@image latex Network.eps
Junctions have a user-supplied water withdrawal rate (i.e., consumer demand) associated with them. Tanks are storage units whose water level changes over time. Reservoirs are boundary points where a fixed hydraulic head applies.
Pipes have a length, diameter and roughness coefficient that determines their head loss as a function of flow rate. Pumps have either a constant power rating or a head curve that determines the head they add as a function of flow rate. Valves are used to regulate either flow or pressure. Controls can be applied to completely open or close a link or to adjust its setting (pump speed or valve setting).
In addition to these physical objects an EPANET model can also contain the following data objects:
- time patterns that allow demands, quality source inflows and pump speed settings to vary at fixed
intervals of time
- data curves that describe relationships between two quantities, such as head versus flow for pumps and
volume versus water level for tanks
- simple controls that adjust a link's setting (such as a pump's status) based on node pressure, tank
level, elapsed time, ot time of day
- rule-based controls that consist of one or more premises that if true result in one set of actions
being taken and if false result in a different set of actions being taken.
An EPANET model also contains a number of analysis options that specify:
- the project's flow units which in turn determines its unit system (US or SI)
- the formula used to compute head loss
- whether to use a demand driven or a pressure driven analysis
- hydraulic convergence criteria
- the type of water quality analysis to perform
- time steps used for hydraulic, water quality and reporting
- global values for reaction coefficients that can be overridden for individual pipes
- global values for energy usage parameters that can be overridden for individual pumps.
Please refer to the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>
for more information on EPANET's data model.
*/
/**
@page DataFlow Data Flow Diagram
The EPANET Toolkit contains separate code modules for network building, hydraulic analysis, water quality analysis, and report generation. The data flow diagram for analyzing a pipe network is shown below. The processing steps depicted in this diagram can be summarized as follows:
@image html DataFlow.png
@image latex DataFlow.eps
- The network builder receives a description of the network being simulated either from an external input file (.inp) or from a series of function calls that create network objects and assign their properties via code. These data are stored in a Project data structure.
- The hydraulics solver carries out an extended period hydraulic simulation. The results obtained at every time step can be written to an external, unformatted (binary) hydraulics file (.hyd). Some of these time steps might represent intermediate points in time where system conditions change because of tanks becoming full or empty or pumps turning on or off due to level controls or timed operation.
- If a water quality simulation is requested, the water quality solver accesses the flow data from the hydraulics file as it computes substance transport and reaction throughout the network over each hydraulic time step. During this process it can write both the formerly computed hydraulic results as well as its water quality results for each preset reporting interval to an unformatted (binary) output file (.out). If no water quality analysis was called for, then the hydraulic results stored in the .hyd file can simply be written out to the binary output file at uniform reporting intervals.
- If requested, a report writer reads back the computed simulation results from the binary output file (.out) for each reporting period and writes out selected values to a formatted report file (.rpt). Any error or warning messages generated during the run are also written to this file.
Toolkit functions exist to carry out all of these steps under the programmer's control, including the ability to read and modify the contents of the Project data structure.
*/
/**
@page ToolkitVersions Toolkit Versions
The toolkit comes with two sets of identical functions that programmers can utilize:
- the single-threaded version of the toolkit is compatible with previous releases and only works
with single threaded applications.
- the multi-threaded version allows users to create multiple EPANET data sets (called projects) that can be
analyzed concurrently.
Both toolkit versions utilize identical function names and argument lists with the following exceptions:
- Function names in the single-threaded library begin with `EN` while those in the multi-threaded
library begin with `EN_`.
- The multi-threaded functions contain an additional argument that references a particular network project
that the function is applied to.
- The multi-threaded library contains two additional functions that allow users to create and delete
EPANET projects.
- The single-threaded library uses single precision for its floating point arguments while the
multi-threaded library uses double precision.
To avoid unnecessary duplication this document only discusses the multi-threaded version of the
toolkit.
*/

438
doc/modules.dox Normal file
View File

@@ -0,0 +1,438 @@
/**
@defgroup Project Project Functions
These functions are used to manage a project.
*/
/**
@defgroup Hydraulics Hydraulic Analysis Functions
These functions are used to perform a hydraulic analysis.
*/
/**
@defgroup Quality Water Quality Analysis Functions
These functions are used to perform a water quality analysis.
*/
/**
@defgroup Reporting Reporting Functions
These functions are used to report simulation results.
*/
/**
@defgroup Options Analysis Options Functions
These functions are used to get and set analysis options.
*/
/**
@defgroup Nodes Network Node Functions
These functions are used for working with network nodes.
*/
/**
@defgroup Demands Nodal Demand Functions
These functions are used for managing nodal demands.
*/
/**
@defgroup Links Network Link Functions
These functions are used for working with network links.
*/
/**
@defgroup Patterns Time Pattern Functions
These functions are used for working with time patterns.
*/
/**
@defgroup Curves Data Curve Functions
These functions are used for working with data curves.
*/
/**
@defgroup Controls Simple Control Functions
These functions are used for working with simple conditional controls.
*/
/**
@defgroup Rules Rule-Based Control Functions
These functions are used for working with rule-based controls.
*/
/**
@defgroup Constants Symbolic Constants
These are symbolic constants used as function arguments.
*/
/**
@addtogroup Project
@{
@fn int EN_createproject(EN_Project *ph)
@fn int EN_deleteproject(EN_Project *ph)
@fn int EN_runproject(EN_Project ph, const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *))
@fn int EN_init(EN_Project ph, const char *rptFile, const char *outFile, int unitsType, int headLossType)
@fn int EN_open(EN_Project ph, const char *inpFile, const char *rptFile, const char *binOutFile)
@fn int EN_saveinpfile(EN_Project ph, const char *filename)
@fn int EN_close(EN_Project ph)
@}
*/
/**
@addtogroup Hydraulics
@{
@fn int EN_solveH(EN_Project ph)
@fn int EN_usehydfile(EN_Project ph, char *filename)
@fn int EN_openH(EN_Project ph)
@fn int EN_initH(EN_Project ph, int initFlag)
@fn int EN_runH(EN_Project ph, long *currentTime)
@fn int EN_nextH(EN_Project ph, long *tStep)
@fn int EN_saveH(EN_Project ph)
@fn int EN_savehydfile(EN_Project ph, char *filename)
@fn int EN_closeH(EN_Project ph)
@}
*/
/**
@addtogroup Quality
@{
@fn int EN_solveQ(EN_Project ph)
@fn int EN_openQ(EN_Project ph)
@fn int EN_initQ(EN_Project ph, int saveFlag)
@fn int EN_runQ(EN_Project ph, long *currentTime)
@fn int EN_nextQ(EN_Project ph, long *tStep)
@fn int EN_stepQ(EN_Project ph, long *timeLeft)
@fn int EN_closeQ(EN_Project ph)
@}
*/
/**
@addtogroup Reporting
@{
@fn int EN_writeline(EN_Project ph, char *line)
@fn int EN_report(EN_Project ph)
@fn int EN_resetreport(EN_Project ph)
@fn int EN_setreport(EN_Project ph, char *reportFormat)
@fn int EN_setstatusreport(EN_Project ph, int code)
@fn int EN_getversion(int *version)
@fn int EN_getcount(EN_Project ph, int code, int *count)
@fn int EN_geterror(int errcode, char *errmsg, int maxLen)
@fn int EN_getstatistic(EN_Project ph, int type, double* value)
@}
*/
/**
@addtogroup Options
@{
@fn int EN_getoption(EN_Project ph, int option, double *value)
@fn int EN_setoption(EN_Project ph, int option, double value)
@fn int EN_getflowunits(EN_Project ph, int *units)
@fn int EN_setflowunits(EN_Project ph, int units)
@fn int EN_gettimeparam(EN_Project ph, int param, long *value)
@fn int EN_settimeparam(EN_Project ph, int param, long value)
@fn int EN_getqualinfo(EN_Project ph, int *qualType, char *chemName, char *chemUnits, int *traceNode)
@fn int EN_getqualtype(EN_Project ph, int *qualType, int *traceNode)
@fn int EN_setqualtype(EN_Project ph, int qualType, char *chemName, char *chemUnits, char *traceNode)
@}
*/
/**
@addtogroup Nodes
@{
@fn int EN_addnode(EN_Project ph, char *id, int nodeType)
@fn int EN_deletenode(EN_Project ph, int index, int actionCode)
@fn int EN_getnodeindex(EN_Project ph, char *id, int *index)
@fn int EN_getnodeid(EN_Project ph, int index, char *id)
@fn int EN_setnodeid(EN_Project ph, int index, char *newid)
@fn int EN_getnodetype(EN_Project ph, int index, int *code)
@fn int EN_getnodevalue(EN_Project ph, int index, int code, double *value)
@fn int EN_setnodevalue(EN_Project ph, int index, int code, double v)
@fn int EN_setjuncdata(EN_Project ph, int index, double elev, double dmnd, char *dmndpat)
@fn int EN_settankdata(EN_Project ph, int index, double elev, double initlvl,
double minlvl, double maxlvl, double diam, double minvol, char *volcurve)
@fn int EN_getcoord(EN_Project ph, int index, double *x, double *y)
@fn int EN_setcoord(EN_Project ph, int index, double x, double y)
@}
*/
/**
@addtogroup Demands
@{
@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_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)
@fn int EN_getdemandpattern(EN_Project ph, int nodeIndex, int demandIndex, int *pattIndex)
@fn int EN_setdemandpattern(EN_Project ph, int nodeIndex, int demandIndex, int patIndex)
@fn int EN_getdemandname(EN_Project ph, int nodeIndex, int demandIdx, char *demandName)
@fn int EN_setdemandname(EN_Project ph, int nodeIndex, int demandIdx, char *demandName)
@}
*/
/**
@addtogroup Links
@{
@fn int EN_addlink(EN_Project ph, char *id, int linkType, char *fromNode, char *toNode)
@fn int EN_deletelink(EN_Project ph, int index, int actionCode)
@fn int EN_getlinkindex(EN_Project ph, char *id, int *index)
@fn int EN_getlinkid(EN_Project ph, int index, char *id)
@fn int EN_setlinkid(EN_Project ph, int index, char *newid)
@fn int EN_getlinktype(EN_Project ph, int index, int *linkType)
@fn int EN_setlinktype(EN_Project ph, int *index, int linkType, int actionCode)
@fn int EN_getlinknodes(EN_Project ph, int index, int *node1, int *node2)
@fn int EN_setlinknodes(EN_Project ph, int index, int node1, int node2)
@fn int EN_getlinkvalue(EN_Project ph, int index, int property, double *value)
@fn int EN_setlinkvalue(EN_Project ph, int index, int property, double value)
@fn int EN_setpipedata(EN_Project ph, int index, double length, double diam, double rough, double mloss)
@fn int EN_getpumptype(EN_Project ph, int linkIndex, int *pumpType)
@fn int EN_getheadcurveindex(EN_Project ph, int pumpIndex, int *curveIndex)
@fn int EN_setheadcurveindex(EN_Project ph, int pumpIndex, int curveIndex)
@}
*/
/**
@addtogroup Patterns
@{
@fn int EN_addpattern(EN_Project ph, char *id)
@fn int EN_getpatternindex(EN_Project ph, char *id, int *index)
@fn int EN_getpatternid(EN_Project ph, int index, char *id)
@fn int EN_getpatternlen(EN_Project ph, int index, int *len)
@fn int EN_getpatternvalue(EN_Project ph, int index, int period, double *value)
@fn int EN_setpatternvalue(EN_Project ph, int index, int period, double value)
@fn int EN_getaveragepatternvalue(EN_Project ph, int index, double *value)
@fn int EN_setpattern(EN_Project ph, int index, double *f, int len)
@}
*/
/**
@addtogroup Curves
@{
@fn int EN_addcurve(EN_Project ph, char *id)
@fn int EN_getcurveindex(EN_Project ph, char *id, int *index)
@fn int EN_getcurveid(EN_Project ph, int index, char *id)
@fn int EN_getcurvelen(EN_Project ph, int index, int *len)
@fn int EN_getcurvetype(EN_Project ph, int index, int *type)
@fn int EN_getcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double *x, double *y)
@fn int EN_setcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double x, double y)
@fn int EN_getcurve(EN_Project ph, int curveIndex, char* id, int *nPoints, double **xValues, double **yValues)
@fn int EN_setcurve(EN_Project ph, int index, double *xValues, double *yValues, int nPoints)
@}
*/
/**
@addtogroup Controls
@{
@fn int EN_addcontrol(EN_Project ph, int type, int linkIndex, double setting, int nodeIndex, double level, int *index)
@fn int EN_deletecontrol(EN_Project ph, int index)
@fn int EN_getcontrol(EN_Project ph, int index, int *type, int *linkIndex, double *setting, int *nodeIndex, double *level)
@fn int EN_setcontrol(EN_Project ph, int index, int type, int linkIndex, double setting, int nodeIndex, double level)
@}
*/
/**
@addtogroup Rules
@{
@fn int EN_addrule(EN_Project ph, char *rule)
@fn int EN_deleterule(EN_Project ph, int index)
@fn int EN_getrule(EN_Project ph, int index, int *nPremises, int *nThenActions, int *nElseActions, double *priority)
@fn int EN_getruleID(EN_Project ph, int index, char* id);
@fn int EN_getpremise(EN_Project ph, int ruleIndex, int premiseIndex, int *logop, int *object, int *objIndex,
int *variable, int *relop, int *status, double *value)
@fn int EN_setpremise(EN_Project ph, int ruleIndex, int premiseIndex,
int logop, int object, int objIndex, int variable, int relop, int status, double value)
@fn int EN_setpremiseindex(EN_Project ph, int ruleIndex, int premiseIndex, int objIndex)
@fn int EN_setpremisestatus(EN_Project ph, int ruleIndex, int premiseIndex, int status)
@fn int EN_setpremisevalue(EN_Project ph, int ruleIndex, int premiseIndex, double value)
@fn int EN_getthenaction(EN_Project ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
@fn int EN_setthenaction(EN_Project ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
@fn int EN_getelseaction(EN_Project ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
@fn int EN_setelseaction(EN_Project ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
@fn int EN_setrulepriority(EN_Project ph, int index, double priority)
@}
*/
/**
@addtogroup Constants
@{
@file epanet2_enums.h
\enum EN_CountType
\enum EN_NodeType
\enum EN_LinkType
\enum EN_PumpType
\enum EN_CurveType
\enum EN_QualityType
\enum EN_SourceType
\enum EN_ControlType
\enum EN_HeadLossType
\enum EN_NodeProperty
\enum EN_LinkProperty
\enum EN_TimeParameter
\enum EN_Option
\enum EN_FlowUnits
\enum EN_DemandModel
\enum EN_MixingModel
\enum EN_StatusReport
\enum EN_StatisticType
\enum EN_InitHydOption
\enum EN_ActionCodeType
\enum EN_AnalysisStatistic
\enum EN_RuleObject
\enum EN_RuleVariable
\enum EN_RuleOperator
\enum EN_RuleStatus
@}
*/
/**
@defgroup Files File Descriptions
These are the various files used by the Toolkit.
@section InputFile Input File
The Input file is a standard EPANET input data file that describes the system being analyzed. It can either be created external to the application being developed with the Toolkit or by the application itself. It is the first file name supplied to the @ref EN_open function. The format of the file is described in Appendix C of the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>. A project's data associated with its Input file remains accessible until the project is closed down with the @ref EN_close or deleted with @ref EN_deleteproject.
@section ReportFile Report File
The Report file is the second file name supplied to the @ref EN_open function (or the first file name to @ref EN_init). It is used to log any error messages that occur when the Input file is being processed and to record all status messages that are generated during a hydraulic simulation. In addition, if the @ref EN_report function is called the resulting report can also be written to this file as can user-generated lines of text using the @ref EN_writeline function. The format of the report is controlled by statements placed in the [REPORT] section of the Input file and by similar statements included in calls to the @ref EN_setreport function. Only results at a specified uniform reporting time interval are written to this file.
To suppress the writing of all error and warning messages to the Report file either include the command `MESSAGES NO` in the [REPORT] section of the Input file or call the Toolkit function `EN_setreport("MESSAGES NO")`.
To route a formatted report to a different file than the Report file either include the command `FILE filename` in the [REPORT] section of the Input file or call the Toolkit function `EN_setreport("FILE filename")`, where `filename` is the name of the file to use.
@section OutputFile Output File
The Output file is an unformatted binary file used to store both hydraulic and water quality results at uniform reporting intervals (see @ref OutFileFormat). It is the third file name supplied to the @ref EN_open function (or second name to @ref EN_init). If an empty string ("") is used as its name then a scratch temporary file will be used. Otherwise the Output file will be saved after the @ref EN_close function is called. Saving this file is useful if further post-processing of the output results are needed. The function @ref EN_saveH will transfer hydraulic results to the Output file if no water quality analysis will be made. Using @ref EN_solveQ to run a water quality analysis automatically saves both hydraulic and water quality results to this file. If the @ref EN_initQ - @ref EN_runQ - @ref EN_nextQ set of functions is used to perform a water quality analysis, then results will be saved only if the `saveflag` argument of @ref EN_initQ is set to @ref EN_SAVE. Again, the need to save results to the Output file is application-dependent. If a formatted output report is to be generated using @ref EN_report, then results must first be saved to the Output file.
@section HydraulicsFile Hydraulics File
The Hydraulics file is an unformatted binary file used to store the results of a hydraulic analysis. Results for all time periods are stored, including those at intermediate times when special hydraulic events occur (e.g., pumps and tanks opening or closing because control conditions have been satisfied).
Normally it is a temporary file that is deleted after the @ref EN_deleteproject function is called. However, it will be saved if the @ref EN_savehydfile function is called before that.
Likewise, a previously saved Hydraulics file can be used if the command `HYDRAULICS USE` filename appears in the [OPTIONS] section of the input file, or if the @ref EN_usehydfile function is called.
When the Toolkit function @ref EN_solveH is used to make a hydraulic analysis, results are automatically saved to the Hydraulics file. When the @ref EN_initH - @ref EN_runH - @ref EN_nextH set of functions is used, the `initFlag` argument to @ref EN_initH determines whether results are saved or not. The need to save hydraulic results is application-dependent. They must always be saved to the Hydraulics file if a water quality analysis will follow.
*/
/**
@defgroup ErrorCodes Error Codes
| Code | Meaning |
|------|--------- |
| 0 | No error |
| 101 | Insufficient memory available |
| 102 | No network data available |
| 103 | Hydraulic solver not opened |
| 104 | No hydraulics for water quality analysis |
| 105 | Water quality solver not opened |
| 106 | No results saved to report on |
| 107 | Hydraulics supplied from external file |
| 108 | Cannot use external file while hydraulics solver is open |
| 110 | Cannot solve network hydraulic equations |
| 120 | Cannot solve water quality transport equations |
| ||
| 200 | One or more errors in an input file |
| 201 | Syntax error |
| 202 | Function call contains an illegal numeric value |
| 203 | Function call refers to an undefined node |
| 204 | Function call refers to an undefined link |
| 205 | Function call refers to an undefined time pattern |
| 206 | Function call refers to an undefined curve |
| 207 | Function call attempts to control a check valve pipe or a GPV valve |
| 209 | Function call contains an illegal node property value |
| 211 | Function call contains an illegal link property value |
| 212 | Function call refers to an undefined Trace Node |
| 213 | Function call contains an invalid option value |
| 214 | Too many characters in a line of an input file |
| 215 | Function call contains a duplicate ID label |
| 216 | Function call refers to an undefined pump |
| 217 | Invalid pump energy data |
| 219 | Illegal valve connection to tank node |
| 220 | Illegal valve connection to another valve |
| 221 | Mis-placed clause in rule-based control |
| 222 | Link assigned same start and end nodes |
| 223 | Not enough nodes in network |
| 224 | No tanks or reservoirs in network |
| 225 | Invalid lower/upper levels for tank |
| 226 | No head curve or power rating for pump |
| 227 | Invalid head curve for pump |
| 230 | Nonincreasing x-values for curve |
| 233 | Network has unconnected node |
| 240 | Function call refers to nonexistent water quality source |
| 241 | Function call refers to nonexistent control |
| 250 | Function call contains invalid format (e.g. too long an ID name) |
| 251 | Function call contains invalid parameter code |
| 253 | Function call refers to nonexistent demand category |
| 254 | Function call refers to node with no coordinates |
| 257 | Function call refers to nonexistent rule |
| 258 | Function call refers to nonexistent rule clause |
| 260 | Function call attempts to delete node assigned as a Trace Node |
| 261 | Function call attempts to delete a node or link contained in a control |
| 262 | Function call attempts to modify network structure while a solver is open |
| ||
| 301 | Identical file names used for different types of files |
| 302 | Cannot open input file |
| 303 | Cannot open report file |
| 304 | Cannot open output file |
| 305 | Cannot open hydraulics file |
| 306 | Hydraulics file does not match network data |
| 307 | Cannot read hydraulics file |
| 308 | Cannot save results to binary file |
| 309 | Cannot save results to report file |
*/
/**
@defgroup WarningCodes Warning Codes
| Code | Description |
|------|--------- |
|1 | System hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials |
|2 | System may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed |
|3 | System disconnected - one or more nodes with positive demands were disconnected from all supply sources |
|4 | Pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow |
|5 | Valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open |
|6 | System has negative pressures - negative pressures occurred at one or more junctions with positive demand |
*/
/**
@defgroup Units Parameter Units
| Parameter | US Customary | SI Metric |
|----------------|-------------------------|---------------------------|
|Concentration | mg/L or ug/L | mg/L or ug/L |
|Demand | (see Flow units) | (see Flow units) |
|Diameter (Pipes)| inches | millimeters |
|Diameter (Tanks)| feet | meters |
|Efficiency | percent | percent |
|Elevation | feet | meters |
|Emitter Coeff. | flow units @ 1 psi drop | flow units @ 1 meter drop |
|Energy | kwatt - hours | kwatt - hours |
|Flow | CFS (cubic feet / sec) | LPS (liters / sec) |
| | GPM (gallons / min) | LPM (liters / min) |
| | MGD (million gal / day) | MLD (megaliters / day) |
| | IMGD (Imperial MGD) | CMH (cubic meters / hr) |
| | AFD (acre-feet / day) | CMD (cubic meters / day) |
|Friction Factor | unitless | unitless |
|Head | feet | meters |
|Length | feet | meters |
|Minor Loss Coeff. | unitless | unitless |
|Power | horsepower | kwatts |
|Pressure | psi | meters |
|Reaction Coeff. (Bulk) | 1/day (1st-order)| 1/day (1st-order) |
|Reaction Coeff. (Wall) | mass/sq-ft/day (0-order) | mass/sq-m/day (0-order) |
| | ft/day (1st-order) | meters/day (1st-order) |
|Roughness Coeff. | millifeet (Darcy-Weisbach) unitless otherwise| mm (Darcy-Weisbach) unitless otherwise |
|Source Mass Injection | mass/minute | mass/minute |
|Velocity | ft/sec | meters/sec |
|Volume | cubic feet | cubic meters |
|Water Age | hours | hours |
*/
/**
@defgroup OutFileFormat Output File Format
*/

View File

@@ -1,12 +0,0 @@
/**
@defgroup Controls Managing Controls
@addtogroup Controls
@{
@enum EN_ControlType
@fn int ENgetcontrol(int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level)
@fn int ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level)
@}
*/

View File

@@ -1,20 +0,0 @@
/**
@defgroup Curves
@addtogroup Curves
@{
@fn int ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
@fn int ENgetheadcurveindex(int index, int *curveindex)
@fn int ENgetpumptype(int index, int *type)
@fn int ENgetheadcurve(int linkIndex, char *curveId)
@fn int ENgetcurveindex(char *id, int *index)
@fn int ENgetcurveid(int index, char *id)
@fn int ENgetcurvelen(int index, int *len)
@fn int ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
@fn int ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
@fn int ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len)
@fn int ENaddcurve(char *id)
@}
*/

View File

@@ -1,20 +0,0 @@
/**
@defgroup FileManagement File Management
@addtogroup FileManagement
@{
@fn int ENwriteline (char *line)
@fn int ENreport ()
@fn int ENresetreport ()
@fn int ENsetreport (char *reportFormat)
@fn int ENopen (char *inpFile, char *rptFile, char *binOutFile)
@fn int ENsaveinpfile (char *filename)
@fn int ENclose()
@}
*/

View File

@@ -1,41 +0,0 @@
/**
@defgroup HydraulicFunctions Hydraulic Analysis
~~~~~~~~~~~~~~~{.c}
int errcode;
long t, tstep;
errcode = ENopenH();
if (!errcode) {
errcode = ENinitH(EN_SAVE);
if (!errcode) {
do {
tstep = 0;
ERRCODE(ENrunH(&t));
ERRCODE(ENnextH(&tstep));
} while (tstep > 0);
}
}
ENcloseH();
~~~~~~~~~~~~~~~
@addtogroup HydraulicFunctions
@{
@fn int ENsolveH()
@fn int ENsaveH()
@fn int ENopenH()
@fn int ENinitH(int initFlag)
@fn int ENrunH(long *currentTime)
@fn int ENnextH(long *tStep)
@fn int ENcloseH()
@fn int ENsavehydfile(char *filename)
@fn int ENusehydfile(char *filename)
@fn int ENgetstatistic(int code, EN_API_FLOAT_TYPE* value)
@}
*/

View File

@@ -1,16 +0,0 @@
/**
@defgroup NetworkInfo Network Info
@addtogroup NetworkInfo
@{
@fn int ENgetcount (int code, int *count)
@fn int ENgetnodeindex (char *id, int *index)
@fn int ENgetnodeid (int index, char *id)
@fn int ENgetnodetype (int index, int *code)
@fn int ENgetnodevalue (int index, int code, EN_API_FLOAT_TYPE *value)
@fn int ENgetcoord (int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
@fn int ENsetcoord (int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
@}
*/

View File

@@ -1,18 +0,0 @@
/**
@defgroup Patterns
@addtogroup Patterns
@{
@fn int ENgetpatternindex (char *id, int *index)
@fn int ENgetpatternid (int index, char *id)
@fn int ENgetpatternlen (int index, int *len)
@fn int ENgetpatternvalue (int index, int period, EN_API_FLOAT_TYPE *value)
@fn int ENgetaveragepatternvalue (int index, EN_API_FLOAT_TYPE *value)
@fn int ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIndex)
@fn int ENaddpattern(char *id)
@fn int ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len)
@fn int ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value)
@}
*/

View File

@@ -1,17 +0,0 @@
/**
@defgroup QualityFunctions Water Quality Functions
@addtogroup QualityFunctions
@{
@fn int ENsolveQ ()
@fn int ENopenQ ()
@fn int ENinitQ (int saveFlag)
@fn int ENrunQ (long *currentTime)
@fn int ENnextQ (long *tStep)
@fn int ENstepQ (long *timeLeft)
@fn int ENcloseQ ()
@}
*/

View File

@@ -1,14 +0,0 @@
/**
@defgroup ToolkitOptions Toolkit Options
@addtogroup ToolkitOptions
@{
@fn int ENgetoption (int code, EN_API_FLOAT_TYPE *value)
@fn int ENgettimeparam (int code, long *value)
@fn int ENgetflowunits (int *code)
@fn int ENgetqualtype (int *qualcode, int *tracenode)
@fn int ENgeterror (int errcode, char *errmsg, int maxLen)
@}
*/

15
doc/newfooter.html Normal file
View File

@@ -0,0 +1,15 @@
<!-- HTML footer for doxygen 1.8.10-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">OWA-EPANET Toolkit 2.2 &copy 2019</li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<li class="footer">OWA-EPANET Toolkit 2.2 &copy 2019</li>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

140
doc/output-format.dox Normal file
View File

@@ -0,0 +1,140 @@
/**
@addtogroup OutFileFormat
@{
The Toolkit uses an unformatted binary output file to store both hydraulic and water quality results at uniform reporting intervals. Data written to the file is either 4-byte integers, 4-byte floats, or fixed-size strings whose size is a multiple of 4 bytes. This allows the file to be divided conveniently into 4-byte records. The file consists of four sections of the following sizes in bytes:
| Section | Size in Bytes |
|----------------|----------------------------------------|
|Prolog | 884 + 36*Nnodes + 52*Nlinks + 8*Ntanks |
|Energy Usage | 28*Npumps + 4 |
|Dynamic Results | (16*Nnodes + 32*Nlinks)*Nperiods |
|Epilog | 28 |
where:
- Nnodes = number of nodes (junctions + reservoirs + tanks),
- Nlinks = number of links (pipes + pumps + valves),
- Ntanks = number of tanks and reservoirs,
- Npumps = number of pumps,
- Nperiods = number of reporting periods.
All of these counts are themselves written to the file's Prolog or Epilog sections.
@}
*/
/**
@page Output_Prolog Prolog Section
@ingroup OutFileFormat
The Prolog section of an EPANET binary output file contains the following data:
|Item | Type | # Bytes |
|----------------|-----------|-----------|
| Magic Number = 516114521 | Integer | 4 |
| Version (= 200) | Integer | 4 |
| Number of Nodes | Integer | 4 |
| Number of Reservoirs & Tanks | Integer | 4|
| Number of Links | Integer | 4 |
| Number of Pumps | Integer | 4 |
| Number of Valves | Integer | 4 |
| Water Quality Option - see @ref EN_QualityType | Integer | 4 |
| Traced Node Index | Integer | 4 |
| Flow Units Option | Integer | 4 |
| Pressure Units Option | Integer | 4 |
| 0 = psi || |
| 1 = meters || |
| 2 = kPa || |
| Report Statistic Type - see @ref EN_StatisticType | Integer | 4 |
| Reporting Start Time (sec) | Integer | 4 |
| Reporting Time Step (sec) | Integer | 4 |
| Simulation Duration (sec) | Integer | 4 |
| Project Title (1st line) | Char | 80 |
| Project Title (2nd line) | Char | 80 |
| Project Title (3rd line) | Char | 80 |
| Name of Input File | Char | 260 |
| Name of Report File | Char | 260 |
| Name of Quality Chemical | Char | 32 |
| Chemical Concentration Units | Char | 32 |
| ID String of Each Node | Char | 32*Nnodes |
| ID String of Each Link | Char | 32*Nlinks |
| Index of Head Node of Each Link | Integer | 4*Nlinks |
| Index of Tail Node of Each Link | Integer | 4*Nlinks |
| Type Code of Each Link (see @ref EN_LinkType) | Integer | 4*Nlinks |
| Node Index of Each Tank | Integer | 4*Ntanks |
| Surface Area of Each Tank | Float | 4*Ntanks |
| Elevation of Each Node | Float | 4*Nnodes |
| Length of Each Link | Float | 4*Nlinks |
| Diameter of Each Link | Float | 4*Nlinks |
*/
/**
@page Output_Energy Energy Usage Section
@ingroup OutFileFormat
The Energy Usage section of an EPANET binary output file contains the following data:
|Item (Repeated for Each Pump) | Type | # Bytes |
|------------------------------|---------|---------|
| Pump Index in list of links | Integer | 4 |
| Pump Utilization (%) | Float | 4 |
| Average Efficiency (%) | Float | 4 |
| Average kwatts/MGal (or kwatts/cu m) | Float | 4 |
| Average kwatts | Float | 4 |
| Peak kwatts | Float | 4 |
| Average Cost per Day | Float | 4 |
| Peak Energy Usage (kw-hrs) | Float | 4 |
*/
/**
@page Output_Results Dynamic Results Section
@ingroup OutFileFormat
The Dynamic Results section of an EPANET binary output file contains the following set of data for each reporting period (the reporting time step is written to the Output File's @ref Output_Prolog and the number of such steps is written to the @ref Output_Epilog):
| Item | Type | # Bytes |
|------|------|---------|
|Demand at Each Node | Float | 4*Nnodes |
|Head (Grade) at Each Node | Float | 4*Nnodes |
|Pressure at Each Node | Float | 4*Nnodes |
|Water Quality at Each Node | Float | 4*Nnodes |
|Flow in Each Link | Float | 4*Nlinks |
|(negative for reverse flow) || |
|Velocity in Each Link | Float | 4*Nlinks |
|Headloss per 1000 Units of Length for Each Link | Float | 4*Nlinks |
|(total head for pumps and head loss for valves) || |
|Average Water Quality in Each Link | Float | 4*Nlinks |
| Status Code for Each Link | Float | 4*Nlinks |
| 0 = closed (pump shutoff head exceeded) || |
| 1 = temporarily closed || |
| 2 = closed || |
| 3 = open || |
| 4 = active (partially open || |
| 5 = open (pump max. flow exceeded) || |
| 6 = open (FCV can't supply flow || |
| 7 = open (PRV/PSV can't supply pressure) || |
| Setting for Each Link | Float | 4*Nlinks |
|Reaction Rate for Each Link (mass/L/day) | Float | 4*Nlinks |
|Friction Factor for Each Link | Float | 4*Nlinks |
*/
/**
@page Output_Epilog Epilog Section
@ingroup OutFileFormat
The Epilog section of an EPANET binary output file contains the following data:
|Item | Type | # Bytes |
|-----|------|---------|
|Average bulk reaction rate (mass/hr) | Float | 4 |
|Average wall reaction rate (mass/hr) | Float | 4 |
|Average tank reaction rate (mass/hr) | Float | 4 |
|Average source inflow rate (mass/hr) | Float | 4 |
|Number of Reporting Periods | Integer | 4 |
|Warning Flag: | Integer | 4 |
|0 = no warnings || |
|1 = warnings were generated || |
|Magic Number = 516114521 | Integer | 4 |
*/

61
doc/readme.txt Normal file
View File

@@ -0,0 +1,61 @@
Generating Documentation for OWA-EPANET 2.2
===========================================
You must have Doxygen (http://www.doxygen.nl/)installed on your machine to generate
documentation for OWA-EPANET's API (aka Toolkit). Assuming this is the case, open a
terminal window, navigate to the project's 'doc' directory and issue the command
'doxygen' to generate documentation in the following formats:
- HTML documentation will be placed in the 'html' sub-directory. Launch 'index.html'
to view it in a web browser.
- Latex documentation will be placed in the 'latex' sub-directory. Assuming you
have a TeX system, such as MikTex (https://miktex.org), installed on your machine
you can generate a PDF of the documentation by issuing the 'make pdf' command from
within the 'latex' directory. The resulting pdf file will be named 'refman.pdf'.
To generate a Windows compiled HTML Help file you must have Microsoft's HTML Help Workshop
(https://www.microsoft.com/en-us/download/details.aspx?id=21138) installed. In this case
you need to first edit the Doxygen configuration file 'Doxyfile' as follows:
1. Change the 'GENERATE_HTMLHELP' setting to 'YES'.
2. Enter the location where the Help Workshop system was installed next to the
'HHC_LOCATION' setting.
After running 'doxygen' again the resulting Help file named 'owa-epanet.chm' will
appear in the 'html' sub-directory.
Doxygen uses the special comments placed in the project's 'epanet2_2.h' and
'epanet2_enums.h' header files to document EPANET's API. It also uses supplementary
material contained in the following files of the project's 'doc' folder to generate
additional pages of documentation:
main.dox - generates the Overview pages.
toolkit-usage.dox: generates the Toolkit Usage page.
toolkit-examples.dox : generates the Toolkit Examples pages.
modules.dox: generates the Reference section of the document consisting of several
module pages that describe Toolkit functions by group, enumerated
constants, file descriptions, error codes, property units, and output
file format.
output-format.dox: generates the pages that describe the format used in different
sections of the output file.
Finally, a group of special Doxygen files are used to customize the format of the
generated documentation. These include the following:
Doxyfile - the main Doxygen configuration file
DoxygenLayout.xml - replaces the title "Modules" with "Reference" and hides the
"Files" section in the tree view pane of the document.
extrastylesheet.css - reduces the size of the the h1 heading style.
newfooter.html - replaces the default Doxygen footer in HTML output with a custom one.
header.tex - replaces the standard title page and footer text used in Latex output.

223
doc/toolkit-examples.dox Normal file
View File

@@ -0,0 +1,223 @@
/** @page ToolkitExamples Examples
Here are several examples of how the Toolkit can be used for different types of network analyses.
- @subpage Example1 "Embedded Engine Example"
- @subpage Example2 "Network Building Example"
- @subpage Example3 "Hydrant Rating Curve Example"
- @subpage Example4 "Chlorine Dosage Example"
*/
/** @page Example1 Embedded Engine Example
This example shows how simple it is for the Toolkit to provide a network analysis engine for other applications. There are three steps that the application would need to take:
-# Have the application write network data to an EPANET-formatted input file.
-# Create a project and call EN_runproject, supplying the name of the EPANET input file, the name of a Report file where status and error messages are written, and the name of a binary Output file which will contain analysis results.
-# Have the application access the output file to display desired analysis results (see @ref OutFileFormat).
Here is an example where a callback function `writeConsole` is provided to write EPANET's progress messages to the console:
\code {.c}
#include "epanet2_2.h"
void writeConsole(char *s)
{
fprintf(stdout, "\n%s", s);
}
int runEpanet(char* inpFile, char* rptFile, char* outFile)
{
int errcode;
EN_project ph;
EN_createproject(&pH);
errcode = EN_runproject(ph, inpFile, rptFile, outFile, &writeConsole);
EN_deleteproject(&ph);
return errcode;
}
\endcode
*/
/** @page Example2 Network Building Example
This example shows how a network can be built just through toolkit function calls, eliminating the
need to always use an EPANET formatted input file. This creates opportunities to use other sources
of network data in one's code, such as relational database files or GIS/CAD files.
Below is a schematic of the network to be built.
@image html Example2.png
\code {.c}
#include "epanet2_2.h"
void netbuilder()
{
// Create a project that uses gpm for flow units and
// the Hazen-Williams formula for head loss
EN_Project ph;
EN_createproject(&ph);
EN_init(ph, "", "", EN_GPM, EN_HW);
// Add the first junction node to the project with
// an elevation of 700 ft and a demand of 0
EN_addnode(ph, "J1", EN_JUNCTION);
EN_setjuncdata(ph, 1, 700, 0, "");
// Add the remaining two junctions with elevations of
// 710 ft and demands of 250 and 500 gpm, respectively
EN_addnode(ph, "J2", EN_JUNCTION);
EN_setjuncdata(ph, 2, 710, 250, "");
EN_addnode(ph, "J3", EN_JUNCTION);
EN_setjuncdata(ph, 3, 710, 500, "");
// Add the reservoir at an elevation of 650 ft
EN_addnode(ph, "R1", EN_RESERVOIR);
EN_setnodevalue(ph, 4, EN_ELEVATION, 650);
// Add the tank node at elevation of 850 ft, initial water level
// at 120 ft, minimum level at 100 ft, maximum level at 150 ft
// and a diameter of 50.5 ft
EN_addnode(ph, "T1", EN_TANK);
EN_settankdata(ph, 5, 850, 120, 100, 150, 50.5, 0, "");
// Add the pipes to the project, setting their length,
// diameter, and roughness values
EN_addlink(ph, "P1", EN_PIPE, "J1", "J2");
EN_setpipedata(ph, 1, 10560, 12, 100, 0);
EN_addlink(ph, "P2", EN_PIPE, "J1", "T1");
EN_setpipedata(ph, 2, 5280, 14, 100, 0);
EN_addlink(ph, "P3", EN_PIPE, "J1", "J3");
EN_setpipedata(ph, 3, 5280, 14, 100, 0);
EN_addlink(ph, "P4", EN_PIPE, "J2", "J3");
EN_setpipedata(ph, 4, 5280, 14, 100, 0);
// Add a pump to the project
EN_addlink(ph, "PUMP", EN_PUMP, "R1", "J1");
// Create a single point head curve (index = 1) and
// assign it to the pump (index = 5)
EN_addcurve(ph, "C1");
EN_setcurvevalue(ph, 1, 1, 1500, 250);
EN_setlinkvalue(ph, 5, EN_PUMP_HCURVE, 1);
// Save the project for future use
EN_saveinpfile(ph, "example2.inp");
// Delete the project
EN_deleteproject(&ph);
}
\endcode
*/
/** @page Example3 Hydrant Rating Curve Example
This example illustrates how the Toolkit could be used to develop a hydrant rating curve used in fire flow studies. This curve shows the amount of flow available at a node in the system as a function of pressure. The curve is generated by running a number of steady state hydraulic analyses with the node of interest subjected to a different demand in each analysis. For this example we assume that the ID label of the node of interest is `MyNode` and that `N` different demand levels stored in the array `D` need to be examined. The corresponding pressures will be stored in `P`. To keep the code more readable, no error checking is made on the results returned from the Toolkit function calls.
\code {.c}
#include "epanet2_2.h"
void HydrantRating(char *MyNode, int N, double D[], double P[])
{
EN_Project ph;
int i, nodeindex;
long t;
double pressure;
// Create a project
EN_createproject(&ph);
// Retrieve network data from an input file
EN_open(ph, "example2.inp", "example2.rpt", "");
// Open the hydraulic solver
EN_openH(ph);
// Get the index of the node of interest
EN_getnodeindex(ph, MyNode, &nodeindex);
// Iterate over all demands
for (i=1; i<N; i++)
{
// Set nodal demand, initialize hydraulics, make a
// single period run, and retrieve pressure
EN_setnodevalue(ph, nodeindex, EN_BASEDEMAND, D[i]);
EN_initH(ph, 0);
EN_runH(ph, &t);
EN_getnodevalue(ph, nodeindex, EN_PRESSURE, &pressure);
P[i] = pressure;
}
// Close hydraulics solver & delete the project
EN_closeH(ph);
EN_deleteproject(&ph);
}
\endcode
*/
/** @page Example4 Chlorine Dosage Example
This example illustrates how the Toolkit could be used to determine the lowest dose of chlorine applied at the entrance to a distribution system needed to ensure that a minimum residual is met throughout the system. We assume that the EPANET input file contains the proper set of kinetic coefficients that describe the rate at which chlorine will decay in the system being studied. In the example code, the ID label of the source node is contained in `SourceID`, the minimum residual target is given by `Ctarget`, and the target is only checked after a start-up duration of 5 days (432,000 seconds). To keep the code more readable, no error checking is made on the results returned from the Toolkit function calls.
\code {.c}
#include "epanet2_2.h"
double cl2dose(char *SourceID, double Ctarget)
{
int i, nnodes, sourceindex, violation;
double c, csource;
long t, tstep;
EN_Project ph;
// Open the toolkit & obtain a hydraulic solution
EN_createproject(&ph);
EN_open(ph, "example3.inp", "example3.rpt", "");
EN_solveH(ph);
// Get the number of nodes and the source node's index
EN_getcount(ph, EN_NODES, &nnodes);
EN_getnodeindex(ph, SourceID, &sourceindex);
// Setup the system to analyze for chlorine
// (in case it was not done in the input file)
EN_setqualtype(ph, EN_CHEM, "Chlorine", "mg/L", "");
// Open the water quality solver
EN_openQ(ph);
// Begin the search for the source concentration
csource = 0.0;
do {
// Update source concentration to next level
csource = csource + 0.1;
EN_setnodevalue(ph, sourceindex, EN_SOURCEQUAL, csource);
// Run WQ simulation checking for target violations
violation = 0;
EN_initQ(ph, 0);
do {
EN_runQ(ph, &t);
if (t > 432000) {
for (i=1; i<=nnodes; i++) {
EN_getnodevalue(ph, i, EN_QUALITY, &c);
if (c < Ctarget) {
violation = 1;
break;
}
}
}
EN_nextQ(ph, &tstep);
// End WQ run if violation found
} while (!violation && tstep > 0);
// Continue search if violation found
} while (violation && csource <= 4.0);
// Close up the WQ solver and delete the project
EN_closeQ(ph);
EN_deleteproject(&ph);
return csource;
}
\endcode
*/

241
doc/toolkit-usage.dox Normal file
View File

@@ -0,0 +1,241 @@
/**
@page toolkit-usage Usage
The following topics briefly describe how to accomplish some basic tasks using the OWA-EPANET Toolkit. See the @ref ToolkitExamples topic for code listings of complete applications of the Toolkit.
@section CreateProject Creating a Project
Before any use is made of the Toolkit, a project and its handle must be created. After all processing is
completed the project should be deleted. See the code snippet below:
\code {.c}
EN_Project ph; // a project handle
EN_createproject(&ph);
// Call functions that perform desired analysis
EN_deleteproject(&ph);
\endcode
@section DetectingErrors Detecting Error Conditions
All of the Toolkit functions return an error/warning code. A 0 indicates that the function ran successfully. A number greater than 0 but less than 100 indicates that a warning condition was generated while a number higher than 100 indicates that the function failed.
The meaning of specific error and warning codes are listed in the @ref ErrorCodes and @ref WarningCodes sections of this guide. The Toolkit function @ref EN_geterror can be used to obtain the text of a specific error/warning code. The following example uses a macro named `ERRCODE` along with a variable named `errcode` to execute Toolkit commands only if no fatal errors have already been detected:
\code {.c}
#define ERRCODE(x) (errcode = ((errcode > 100) ? (errcode) : (x)))
void runHydraulics(EN_Project ph, char *inputFile, char *reportFile)
{
int errcode = 0;
char errmsg[EN_MAXMSG + 1];
ERRCODE(EN_open(ph, inputFile, reportFile, ""));
ERRCODE(EN_solveH(ph));
ERRCODE(EN_saveH(ph));
ERRCODE(EN_report(ph));
EN_geterror(ph, errcode, errmsg);
if (errcode) printf("\n%s\n", errmsg);
}
\endcode
@section NetworkData Providing Network Data
Once a project is created there are two ways in which it can be populated with data. The first is to use the @ref EN_open function to load an EPANET-formatted input file that provides a description of the network to be analyzed. The format of this file is described in Appendix C of the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>. This function should be called immediately after a project is created. It takes as arguments the name of the input file to open and the names of a report file and a binary output file, both of which are optional. Here is a code sample showing this approach:
\code {.c}
EN_Project ph;
int errcode;
EN_createproject(&ph);
errcode = EN_open(ph, "net1.inp", "net1.rpt", "");
if (errcode == 0)
{
// Call functions that perform desired analysis
}
EN_deleteproject(&ph);
\endcode
Note that after an input file has been loaded in this fashion the resulting network can have objects added or deleted, and their properties set using various Toolkit functions .
The second method for supplying network data to a project is to use the Toolkit's functions to add objects and to set their properties via code. In this case the @ref EN_init function should be called immediately after creating a project, passing in the names of a report and binary output files (both optional) as well as the choices of flow units and head loss formulas to use. After that the various `EN_add` functions, such as @ref EN_addnode, @ref EN_addlink, @ref EN_addpattern, @ref EN_addcontrol, etc., can be called to add new objects to the network. Here is a partial example:
\code {.c}
EN_Project ph;
EN_createproject(&ph);
EN_init(ph, "net1.rpt", "", EN_GPM, EN_HW);
EN_addnode(ph, "J1", EN_JUNCTION);
EN_addnode(ph, "J2", EN_JUNCTION);
EN_addlink(ph, "P1", EN_PIPE, "J1", "J2");
// additional function calls to complete building the network
\endcode
See the @ref Example2 for a more complete example. While adding objects their properties can be set as described in the next section. Attemtping to change a network's structure by adding or deleting nodes and links while the Toolkit's hydraulic or water quality solvers are open will result in an error condition.
@section Properties Setting Object Properties
The Toolkit contains several functions for retrieving and setting the properties of a network's objects and its analysis options. The names of retrieval functions all begin with `EN_get` (e.g., @ref EN_getnodevalue, @ref EN_getoption, etc.) while the functions used for setting parameter values begin with `EN_set` (e.g., @ref EN_setnodevalue, @ref EN_setoption, etc.).
Most of these functions use an index number to refer to a specific network component (such as a node, link, time pattern or data curve). This number is simply the position of the component in the list of all components of similar type (e.g., node 10 is the tenth node, starting from 1, in the network) and is not the same as the ID label assigned to the component. A series of functions exist to determine a component's index number given its ID label (see @ref EN_getnodeindex, @ref EN_getlinkindex, @ref EN_getpatternindex, and @ref EN_getcurveindex). Likewise, functions exist to retrieve a component's ID label given its index number (see @ref EN_getlinkid, @ref EN_getnodeid, @ref EN_getpatternid, and @ref EN_getcurveid). The @ref EN_getcount function can be used to determine the number of different components in the network. Be aware that a component's index can change as elements are added or deleted from the network.
The code below is an example of using the property retrieval and setting functions. It changes all links with diameter of 10 inches to 12 inches.
\code {.c}
void changeDiameters(EN_Project ph)
{
int i, nLinks;
double diam;
EN_getcount(ph, EN_LINKCOUNT, &nLinks);
for (i = 1; i <= nLinks; i++)
{
EN_getlinkvalue(ph, i, EN_DIAMETER, &diam);
if (diam == 10) ENsetlinkvalue(i, EN_DIAMETER, 12);
}
}
\endcode
@section hydraulics Computing Hydraulics
There are two ways to use the Toolkit to run a hydraulic analysis:
-# Use the @ref EN_solveH function to run a complete extended period analysis, without having access to intermediate results.
-# Use the @ref EN_openH - @ref EN_initH - @ref EN_runH - @ref EN_nextH - @ref EN_closeH series of functions to step through the simulation one hydraulic time step at a time.
Method 1 is useful if you only want to run a single hydraulic analysis, perhaps to provide input to a water quality analysis. With this method hydraulic results are always saved to an intermediate hydraulics file at every time step.
Method 2 must be used if you need to access results between time steps or if you wish to run many analyses efficiently. To accomplish the latter, you would make only one call to `EN_openH` to begin the process, then make successive calls to `EN_initH` - `EN_runH` - `EN_nextH` to perform each analysis, and finally call EN_closeH to close down the hydraulics system. An example of this is shown below (calls to `EN_nextH` are not needed because we are only making a single period analysis in this example).
\code {.c}
void runHydraulics(EN_Project ph, int nRuns)
{
int i;
long t;
EN_openH(ph);
for (i = 1; i <= nRuns; i++)
{
// user-supplied function to set parameters
setparams(ph, i);
// initialize hydraulics; don't save them to file
EN_initH(ph, EN_NOSAVE);
// solve hydraulics
EN_runH(ph, &t);
// user-supplied function to process results
getresults(ph, i);
}
EN_closeH(ph);
}
\endcode
@section quality Computing Water Quality
As with a hydraulic analysis, there are two ways to carry out a water quality analysis:
-# Use the @ref EN_solveQ function to run a complete extended period analysis, without having access to intermediate results. A complete set of hydraulic results must have been generated either from running a hydraulic analysis or from importing a saved hydraulics file from a previous run.
-# Use the @ref EN_openQ - @ref EN_initQ - @ref EN_runQ - @ref EN_nextQ - @ref EN_closeQ series of functions to step through the simulation one hydraulic time step at a time. (Replacing `EN_nextQ` with @ref EN_stepQ will step through one water quality time step at a time.)
The second option can either be carried out after a hydraulic analysis has been run or simultaneously as hydraulics are being computed. Example code for these two alternatives is shown below:
\code {.c}
int runSequentialQuality(EN_Project ph)
{
int err;
long t, tStep;
err = EN_solveH(ph);
if (err > 100) return err;
EN_openQ(ph);
EN_initQ(ph, EN_NOSAVE);
do {
EN_runQ(ph, &t);
// Access quality results for time t here
EN_nextQ(ph, &tStep);
} while (tStep > 0);
EN_closeQ(ph);
return 0;
}
int runConcurrentQuality(EN_Project ph)
{
int err = 0;
long t, tStep;
EN_openH(ph);
EN_initH(ph, EN_NOSAVE);
EN_openQ(ph);
EN_initQ(ph, EN_NOSAVE);
do {
err = EN_runH(ph, &t);
if (err > 100) break;
EN_runQ(ph, &t);
// Access hydraulic & quality results for time t here
EN_nextH(ph, &tStep);
EN_nextQ(ph, &tStep);
} while (tStep > 0);
EN_closeH(ph);
EN_closeQ(ph);
return err;
}
\endcode
@section results Retrieving Computed Results
The @ref EN_getnodevalue and @ref EN_getlinkvalue functions can also be used to retrieve the results of hydraulic and water quality simulations. The computed parameters (and their Toolkit codes) that can be retrieved are as follows:
|For Nodes: | For Links: |
|----------------------------------- | ----------------------------------------- |
|`EN_DEMAND` (demand) |`EN_FLOW` (flow rate) |
|`EN_HEAD` (hydraulic head) |`EN_VELOCITY` (flow velocity) |
|`EN_PRESSURE` (pressure) |`EN_HEADLOSS` (head loss) |
|`EN_TANKLEVEL` (tank water level) |`EN_STATUS` (link status) |
|`EN_TANKVOLUME` (tank water volume) |`EN_SETTING` (pump speed or valve setting) |
|`EN_QUALITY` (water quality) |`EN_ENERGY` (pump energy usage) |
|`EN_SOURCEMASS` (source mass inflow)|`EN_PUMP_EFFIC` (pump efficiency) |
The following code shows how to retrieve the pressure at each node of a network after each time step of a hydraulic analysis (`writetofile` is a user-defined function that will write a record to a file):
\code {.c}
void getPressures(EN_Project ph)
{
int i, numNodes;
long t, tStep;
double p;
char id[EN_MAXID + 1];
EN_getcount(ph, EN_NODECOUNT, &numNodes);
EN_openH(ph);
ENinitH(ph, EN_NOSAVE);
do {
ENrunH(ph, &t);
for (i = 1; i <= NumNodes; i++) {
EN_getnodevalue(ph, i, EN_PRESSURE, &p);
EN_getnodeid(ph, i, id);
writetofile(t, id, p);
}
EN_nextH(&tStep);
} while (tStep > 0);
ENcloseH(ph);
}
\endcode
@section report Writing a Report
The Toolkit has some built-in capabilities to produce formatted output results saved to a file. More specialized reporting needs can always be handled by writing custom code.
The @ref EN_setreport function is used to define the format of a report while the @ref EN_report function actually writes the report. The latter should be called only after a hydraulic or water quality analysis has been made. An example of creating a report that lists all nodes where the pressure variation over the duration of the simulation exceeds 20 psi is shown below:
\code {.c}
void reportPressureVariation(EN_Project ph)
{
// Compute ranges (max - min)
EN_settimeparam(ph, EN_STATISTIC, EN_RANGE);
// Solve and save hydraulics
EN_solveH(ph);
EN_saveH(ph);
// Define contents of the report
EN_resetreport(ph);
ENsetreport(ph, "FILE myfile.rpt");
EN_setreport(ph, "NODES ALL");
EN_setreport(ph, "PRESSURE PRECISION 1");
EN_setreport(ph, "PRESSURE ABOVE 20");
// Write the report to file
EN_report(ph);
}
\endcode
*/

View File

@@ -5,7 +5,7 @@ Attribute VB_Name = "Module1"
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL)
'Last updated on 4/3/07
'Last updated on 01/08/2019
' These are codes used by the DLL functions
Public Const EN_ELEVATION = 0 ' Node parameters
@@ -50,15 +50,16 @@ Public Const EN_HEADLOSS = 10
Public Const EN_STATUS = 11
Public Const EN_SETTING = 12
Public Const EN_ENERGY = 13
Public Const EN_LINKQUAL = 14 'ES
Public Const EN_LINKQUAL = 14
Public Const EN_LINKPATTERN = 15
Public Const EN_EFFICIENCY = 16
Public Const EN_HEADCURVE = 17
Public Const EN_EFFICIENCYCURVE = 18
Public Const EN_PRICEPATTERN = 19
Public Const EN_STATE = 20
Public Const EN_CONST_POWER = 21
Public Const EN_SPEED = 22
Public Const EN_PUMP_STATE = 16
Public Const EN_PUMP_EFFIC = 17
Public Const EN_PUMP_POWER = 18
Public Const EN_PUMP_HCURVE = 19
Public Const EN_PUMP_ECURVE = 20
Public Const EN_PUMP_ECOST = 21
Public Const EN_PUMP_EPAT = 22
Public Const EN_DURATION = 0 ' Time parameters
Public Const EN_HYDSTEP = 1
@@ -76,13 +77,13 @@ Public Const EN_QTIME = 12
Public Const EN_HALTFLAG = 13
Public Const EN_NEXTEVENT = 14
Public Const EN_ITERATIONS = 0
Public Const EN_ITERATIONS = 0 ' Run statistics
Public Const EN_RELATIVEERROR = 1
Public Const EN_MAXHEADERROR = 2
Public Const EN_MAXFLOWCHANGE = 3
Public Const EN_MASSBALANCE = 4
Public Const EN_NODECOUNT = 0 'Component counts
Public Const EN_NODECOUNT = 0 ' Component counts
Public Const EN_TANKCOUNT = 1
Public Const EN_LINKCOUNT = 2
Public Const EN_PATCOUNT = 3
@@ -114,7 +115,7 @@ Public Const EN_MASS = 1
Public Const EN_SETPOINT = 2
Public Const EN_FLOWPACED = 3
Public Const EN_HW = 0 ' Head loss formula
Public Const EN_HW = 0 ' Head loss formulas
Public Const EN_DW = 1
Public Const EN_CM = 2
@@ -132,7 +133,7 @@ Public Const EN_CMD = 9
Public Const EN_DDA = 0 ' Demand driven analysis
Public Const EN_PDA = 1 ' Pressure driven analysis
Public Const EN_TRIALS = 0 ' Misc. options
Public Const EN_TRIALS = 0 ' Hydraulic options
Public Const EN_ACCURACY = 1
Public Const EN_TOLERANCE = 2
Public Const EN_EMITEXPON = 3
@@ -141,172 +142,216 @@ Public Const EN_HEADERROR = 5
Public Const EN_FLOWCHANGE = 6
Public Const EN_DEMANDDEFPAT = 7
Public Const EN_HEADLOSSFORM = 8
Public Const EN_GLOBALEFFIC = 9
Public Const EN_GLOBALPRICE = 10
Public Const EN_GLOBALPATTERN = 11
Public Const EN_DEMANDCHARGE = 12
Public Const EN_LOWLEVEL = 0 ' Control types
Public Const EN_LOWLEVEL = 0 ' Control types
Public Const EN_HILEVEL = 1
Public Const EN_TIMER = 2
Public Const EN_TIMEOFDAY = 3
Public Const EN_AVERAGE = 1 'Time statistic types
Public Const EN_AVERAGE = 1 ' Time statistic types
Public Const EN_MINIMUM = 2
Public Const EN_MAXIMUM = 3
Public Const EN_RANGE = 4
Public Const EN_MIX1 = 0 'Tank mixing models
Public Const EN_MIX1 = 0 ' Tank mixing models
Public Const EN_MIX2 = 1
Public Const EN_FIFO = 2
Public Const EN_LIFO = 3
Public Const EN_NOSAVE = 0 ' Save-results-to-file flag
Public Const EN_NOSAVE = 0 ' Save-results-to-file flag
Public Const EN_SAVE = 1
Public Const EN_INITFLOW = 10 ' Re-initialize flow flag
Public Const EN_SAVE_AND_INIT = 11
Public Const EN_INITFLOW = 10 ' Re-initialize flow flag
Public Const EN_CONST_HP = 0 ' Constant horsepower pump curve
Public Const EN_POWER_FUNC = 1 ' Power function pump cuve
Public Const EN_CUSTOM = 2 ' User-defined custom pump curve
Public Const EN_NOCURVE = 3 ' No pump curve
Public Const EN_CONST_HP = 0 ' constant horsepower
Public Const EN_POWER_FUNC = 1 ' power function
Public Const EN_CUSTOM = 2 ' user-defined custom curve
Public Const EN_NOCURVE = 3 ' no curve
Public Const EN_V_CURVE = 0 ' volume curve
Public Const EN_P_CURVE = 1 ' pump curve
Public Const EN_E_CURVE = 2 ' efficiency curve
Public Const EN_H_CURVE = 3 ' head loss curve
Public Const EN_G_CURVE = 4 ' General\default curve
Public Const EN_VOLUME_CURVE = 0 ' Volume curve
Public Const EN_PUMP_CURVE = 1 ' Pump curve
Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
Public Const EN_GENERIC_CURVE = 4 ' Generic curve
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
Public Const EN_CONDITIONAL = 1 ' Conditional object deletion
Public Const EN_NO_REPORT = 0 ' No status report
Public Const EN_NORMAL_REPORT = 1 ' Normal status report
Public Const EN_FULL_REPORT = 2 ' Full status report
Public Const EN_R_NODE = 6 ' Rule objects
Public Const EN_R_LINK = 7
Public Const EN_R_SYSTEM = 8
Public Const EN_R_DEMAND = 0 ' Rule variables
Public Const EN_R_HEAD = 1
Public Const EN_R_GRADE = 2
Public Const EN_R_LEVEL = 3
Public Const EN_R_PRESSURE = 4
Public Const EN_R_FLOW = 5
Public Const EN_R_STATUS = 6
Public Const EN_R_SETTING = 7
Public Const EN_R_POWER = 8
Public Const EN_R_TIME = 9
Public Const EN_R_CLOCKTIME = 10
Public Const EN_R_FILLTIME = 11
Public Const EN_R_DRAINTIME = 12
Public Const EN_R_EQ = 0 ' Rule operators
Public Const EN_R_NE = 1
Public Const EN_R_LE = 2
Public Const EN_R_GE = 3
Public Const EN_R_LT = 4
Public Const EN_R_GT = 5
Public Const EN_R_IS = 6
Public Const EN_R_NOT = 7
Public Const EN_R_BELOW = 8
Public Const EN_R_ABOVE = 9
Public Const EN_R_IS_OPEN = 1 ' Rule status types
Public Const EN_R_IS_CLOSED = 2
Public Const EN_R_IS_ACTIVE = 3
'These are the external functions that comprise the DLL
'System Functions
Declare Function ENgetversion Lib "epanet2.dll" (value As Long) As Long
Declare Function ENepanet Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String, ByVal F4 As Any) As Long
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal binOutFile As String, ByVal UnitsType As Long, ByVal HeadlossFormula As Long) As Long
Declare Function ENopen Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String) As Long
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal F As String) As Long
Declare Function ENepanet Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String, ByVal pviewprog As Any) As Long
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal outFile As String, ByVal unitsType As Long, ByVal headlossType As Long) As Long
Declare Function ENopen Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Long
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Long
Declare Function ENclose Lib "epanet2.dll" () As Long
'Hydraulic Analysis Functions
Declare Function ENsolveH Lib "epanet2.dll" () As Long
Declare Function ENsaveH Lib "epanet2.dll" () As Long
Declare Function ENopenH Lib "epanet2.dll" () As Long
Declare Function ENinitH Lib "epanet2.dll" (ByVal SaveFlag As Long) As Long
Declare Function ENrunH Lib "epanet2.dll" (T As Long) As Long
Declare Function ENnextH Lib "epanet2.dll" (Tstep As Long) As Long
Declare Function ENinitH Lib "epanet2.dll" (ByVal initFlag As Long) As Long
Declare Function ENrunH Lib "epanet2.dll" (currentTime As Long) As Long
Declare Function ENnextH Lib "epanet2.dll" (tStep As Long) As Long
Declare Function ENcloseH Lib "epanet2.dll" () As Long
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal F As String) As Long
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal F As String) As Long
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal filename As String) As Long
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal filename As String) As Long
'Water Quality Analysis Functions
Declare Function ENsolveQ Lib "epanet2.dll" () As Long
Declare Function ENopenQ Lib "epanet2.dll" () As Long
Declare Function ENinitQ Lib "epanet2.dll" (ByVal SaveFlag As Long) As Long
Declare Function ENrunQ Lib "epanet2.dll" (T As Long) As Long
Declare Function ENnextQ Lib "epanet2.dll" (Tstep As Long) As Long
Declare Function ENstepQ Lib "epanet2.dll" (Tleft As Long) As Long
Declare Function ENinitQ Lib "epanet2.dll" (ByVal saveFlag As Long) As Long
Declare Function ENrunQ Lib "epanet2.dll" (currentTime As Long) As Long
Declare Function ENnextQ Lib "epanet2.dll" (tStep As Long) As Long
Declare Function ENstepQ Lib "epanet2.dll" (timeLeft As Long) As Long
Declare Function ENcloseQ Lib "epanet2.dll" () As Long
'Reporting Functions
Declare Function ENwriteline Lib "epanet2.dll" (ByVal S As String) As Long
Declare Function ENwriteline Lib "epanet2.dll" (ByVal line As String) As Long
Declare Function ENreport Lib "epanet2.dll" () As Long
Declare Function ENresetreport Lib "epanet2.dll" () As Long
Declare Function ENsetreport Lib "epanet2.dll" (ByVal S As String) As Long
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal code As Long) As Long
Declare Function ENgetcount Lib "epanet2.dll" (ByVal code As Long, value As Long) As Long
Declare Function ENgeterror Lib "epanet2.dll" (ByVal ErrCode As Long, ByVal ErrMsg As String, ByVal N As Long) As Long
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal code As Long, ByRef value As Single) As Long
Declare Function ENsetreport Lib "epanet2.dll" (ByVal format As String) As Long
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal level As Long) As Long
Declare Function ENgetcount Lib "epanet2.dll" (ByVal object As Long, count As Long) As Long
Declare Function ENgeterror Lib "epanet2.dll" (ByVal errcode As Long, ByVal errmsg As String, ByVal maxLen As Long) As Long
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Long, ByRef value As Single) As Long
'Analysis Options Functions
Declare Function ENgetoption Lib "epanet2.dll" (ByVal code As Long, value As Single) As Long
Declare Function ENsetoption Lib "epanet2.dll" (ByVal code As Long, ByVal value As Single) As Long
Declare Function ENgetflowunits Lib "epanet2.dll" (code As Long) As Long
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal code As Long) As Long
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal code As Long, value As Long) As Long
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal code As Long, ByVal value As Long) As Long
Declare Function ENgetqualtype Lib "epanet2.dll" (QualCode As Long, TraceNode As Long) As Long
Declare Function ENgetqualinfo Lib "epanet2.dll" (QualCode As Long, ByVal ChemName As String, ByVal ChemUnits As String, TraceNode As Long) As Long
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal QualCode As Long, ByVal ChemName As String, ByVal ChemUnits As String, ByVal TraceNode As String) As Long
Declare Function ENgetoption Lib "epanet2.dll" (ByVal option_ As Long, value As Single) As Long
Declare Function ENsetoption Lib "epanet2.dll" (ByVal option_ As Long, ByVal value As Single) As Long
Declare Function ENgetflowunits Lib "epanet2.dll" (units As Long) As Long
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal units As Long) As Long
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal param As Long, value As Long) As Long
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal param As Long, ByVal value As Long) As Long
Declare Function ENgetqualinfo Lib "epanet2.dll" (qualType As Long, ByVal chemName As String, ByVal chemUnits As String, traceNode As Long) As Long
Declare Function ENgetqualtype Lib "epanet2.dll" (qualType As Long, traceNode As Long) As Long
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal qualType As Long, ByVal chemName As String, ByVal chemUnits As String, ByVal traceNode As String) As Long
'Basic Node Functions
'Node Functions
Declare Function ENaddnode Lib "epanet2.dll" (ByVal id As String, ByVal nodeType As Long) As Long
Declare Function ENdeletenode Lib "epanet2.dll" (ByVal linkIndex As Long, ByVal actionCode As Long) As Long
Declare Function ENdeletenode Lib "epanet2.dll" (ByVal index As Long, ByVal actionCode As Long) As Long
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
Declare Function ENgetnodeid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
Declare Function ENsetnodeid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal index As Long, code As Long) As Long
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal index As Long, ByVal code As Long, value As Single) As Long
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal index As Long, ByVal code As Long, ByVal value As Single) As Long
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal index As Long, X As Single, Y As Single) As Long
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal index As Long, ByVal X As Single, ByVal Y As Single) As Long
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal index As Long, nodeType As Long) As Long
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, value As Single) As Long
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, ByVal value As Single) As Long
Declare Function ENsetjuncdata Lib "epanet2.dll" (ByVal index As Long, ByVal elev As Single, ByVal dmnd As Single, ByVal dmndpat As String) As Long
Declare Function ENsettankdata Lib "epanet2.dll" (ByVal index As Long, ByVal elev As Single, ByVal initlvl As Single, ByVal minlvl As Single, ByVal maxlvl As Single, ByVal diam As Single, ByVal minvol As Single, ByVal volcurve As String) As Long
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal index As Long, x As Single, y As Single) As Long
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal index As Long, ByVal x As Single, ByVal y As Single) As Long
'Nodal Demand Functions
Declare Function ENgetdemandmodel Lib "epanet2.dll" (mtype As Long, pmin As Single, preq As Single, pexp As Single) As Long
Declare Function ENsetdemandmodel Lib "epanet2.dll" (ByVal mtype As Long, ByVal pmin As Single, ByVal preq As Single, ByVal pexp As Single) As Long
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal index As Long, numDemands As Long) As Long
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal index As Long, ByVal DemandIndex As Long, value As Single) As Long
Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal index As Long, ByVal DemandIndex As Long, ByVal BaseDemand As Single) As Long
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal index As Long, ByVal DemandIndex As Long, PatIndex As Long) As Long
Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal index As Long, ByVal DemandIndex As Long, ByVal PatIndex As Long) As Long
Declare Function ENgetdemandname Lib "epanet2.dll" (ByVal index As Long, ByVal DemandIndex As Long, ByVal demandName As String) As Long
Declare Function ENsetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal DemandIndex As Long, ByVal demandName As String) As Long
Declare Function ENgetdemandmodel Lib "epanet2.dll" (type_ As Long, pmin As Single, preq As Single, pexp As Single) As Long
Declare Function ENsetdemandmodel Lib "epanet2.dll" (ByVal type_ As Long, ByVal pmin As Single, ByVal preq As Single, ByVal pexp As Single) As Long
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal nodeIndex As Long, numDemands As Long) As Long
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, value As Single) As Long
Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal BaseDemand As Single) As Long
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, patIndex As Long) As Long
Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal patIndex As Long) As Long
Declare Function ENgetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal demandName As String) As Long
Declare Function ENsetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal demandName As String) As Long
'Basic Link Functions
'Link Functions
Declare Function ENaddlink Lib "epanet2.dll" (ByVal id As String, ByVal linkType As Long, ByVal fromNode As String, ByVal toNode As String) As Long
Declare Function ENdeletelink Lib "epanet2.dll" (ByVal linkIndex As Long, ByVal actionCode As Long) As Long
Declare Function ENdeletelink Lib "epanet2.dll" (ByVal index As Long, ByVal actionCode As Long) As Long
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
Declare Function ENsetlinkid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal index As Long, code As Long) As Long
Declare Function ENsetlinktype Lib "epanet2.dll" (index As Long, ByVal code As Long) As Long
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal index As Long, linkType As Long) As Long
Declare Function ENsetlinktype Lib "epanet2.dll" (index As Long, ByVal linkType As Long, ByVal actionCode As Long) As Long
Declare Function ENgetlinknodes Lib "epanet2.dll" (ByVal index As Long, node1 As Long, node2 As Long) As Long
Declare Function ENsetlinknodes Lib "epanet2.dll" (ByVal index As Long, ByVal node1 As Long, ByVal node2 As Long) As Long
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal index As Long, ByVal code As Long, value As Single) As Long
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal index As Long, ByVal code As Long, ByVal value As Single) As Long
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, value As Single) As Long
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, ByVal value As Single) As Long
Declare Function ENsetpipedata Lib "epanet2.dll" (ByVal index As Long, ByVal length As Single, ByVal diam As Single, ByVal rough As Single, ByVal mloss As Single) As Long
'Pump Functions
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal pumpIndex As Long, curveIndex As Long) As Long
Declare Function ENsetheadcurveindex Lib "epanet2.dll" (ByVal pumpIndex As Long, ByVal curveIndex As Long) As Long
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal index As Long, PumpType As Long) As Long
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Long, curveIndex As Long) As Long
Declare Function ENsetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Long, ByVal curveIndex As Long) As Long
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal linkIndex As Long, pumpType As Long) As Long
'Time Pattern Functions
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal id As String) As Long
Declare Function ENgetpatternindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
Declare Function ENgetpatternid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal index As Long, L As Long) As Long
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal index As Long, ByVal Period As Long, value As Single) As Long
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal index As Long, ByVal Period As Long, ByVal value As Single) As Long
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal index As Long, len_ As Long) As Long
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal index As Long, ByVal period As Long, value As Single) As Long
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal index As Long, ByVal period As Long, ByVal value As Single) As Long
Declare Function ENgetaveragepatternvalue Lib "epanet2.dll" (ByVal index As Long, value As Single) As Long
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal index As Long, F As Any, ByVal N As Long) As Long
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal index As Long, values As Any, ByVal len_ As Long) As Long
'Data Curve Functions
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal id As String) As Long
Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Long, L As Long) As Long
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal curveIndex As Long, CurveType As Long) As Long
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal index As Long, ByVal Ptn As Long, X As Single, Y As Single) As Long
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal index As Long, ByVal Ptn As Long, ByVal X As Single, ByVal Y As Single) As Long
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal curveIndex As Long, ByVal CurveID As String, nValues As Long, xValues As Any, yValues As Any) As Long
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal index As Long, X As Any, Y As Any, ByVal N As Long) As Long
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Long, len_ As Long) As Long
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal index As Long, type_ As Long) As Long
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Long, ByVal pointIndex As Long, x As Single, y As Single) As Long
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Long, ByVal pointIndex As Long, ByVal x As Single, ByVal y As Single) As Long
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal index As Long, ByVal id As String, nPoints As Long, xValues As Any, yValues As Any) As Long
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal index As Long, xValues As Any, yValues As Any, ByVal nPoints As Long) As Long
'Simple Control Functions
Declare Function ENaddcontrol Lib "epanet2.dll" (Cindex As Long, ByVal Ctype As Long, ByVal Lindex As Long, ByVal setting As Single, ByVal Nindex As Long, ByVal Level As Single) As Long
Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal Cindex As Long) As Long
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal Cindex As Long, Ctype As Long, Lindex As Long, setting As Single, Nindex As Long, Level As Single) As Long
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal Cindex As Long, ByVal Ctype As Long, ByVal Lindex As Long, ByVal setting As Single, ByVal Nindex As Long, ByVal Level As Single) As Long
Declare Function ENaddcontrol Lib "epanet2.dll" (ByVal type_ As Long, ByVal linkIndex As Long, ByVal setting As Single, ByVal nodeIndex As Long, ByVal level As Single, index As Long) As Long
Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal index As Long) As Long
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal index As Long, type_ As Long, linkIndex As Long, setting As Single, nodeIndex As Long, level As Single) As Long
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal index As Long, ByVal type_ As Long, ByVal linkIndex As Long, ByVal setting As Single, ByVal nodeIndex As Long, ByVal level As Single) As Long
'Rue-Based Control Functions
'Rule-Based Control Functions
Declare Function ENaddrule Lib "epanet2.dll" (ByVal rule As String) As Long
Declare Function ENdeleterule Lib "epanet2.dll" (ByVal index As Long) As Long
Declare Function ENgetrule Lib "epanet2.dll" (ByVal index As Long, nPremises As Long, nTrueActions As Long, nFalseActions As Long, priority As Single) As Long
Declare Function ENgetruleID Lib "epanet2.dll" (ByVal indexRule As Long, ByVal id As String) As Long
Declare Function ENgetrule Lib "epanet2.dll" (ByVal index As Long, nPremises As Long, nThenActions As Long, nElseActions As Long, priority As Single) As Long
Declare Function ENgetruleID Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
Declare Function ENsetrulepriority Lib "epanet2.dll" (ByVal index As Long, ByVal priority As Single) As Long
Declare Function ENgetpremise Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexPremise As Long, logop As Long, object As Long, indexObj As Long, variable As Long, relop As Long, status As Long, value As Single) As Long
Declare Function ENsetpremise Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexPremise As Long, ByVal logop As Long, ByVal object As Long, ByVal indexObj As Long, ByVal variable As Long, ByVal relop As Long, ByVal status As Long, ByVal value As Single) As Long
Declare Function ENsetpremiseindex Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexPremise As Long, ByVal indexObj As Long) As Long
Declare Function ENsetpremisestatus Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexPremise As Long, ByVal status As Long) As Long
Declare Function ENsetpremisevalue Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexPremise As Long, ByVal value As Single) As Long
Declare Function ENgetthenaction Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexAction As Long, indexLink As Long, status As Long, setting As Single) As Long
Declare Function ENsetthenaction Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexAction As Long, ByVal indexLink As Long, ByVal status As Long, ByVal setting As Single) As Long
Declare Function ENgetelseaction Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexAction As Long, indexLink As Long, status As Long, setting As Single) As Long
Declare Function ENsetelseaction Lib "epanet2.dll" (ByVal indexRule As Long, ByVal indexAction As Long, ByVal indexLink As Long, ByVal status As Long, ByVal setting As Single) As Long
Declare Function ENgetpremise Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, logop As Long, object As Long, objIndex As Long, variable As Long, relop As Long, status As Long, value As Single) As Long
Declare Function ENsetpremise Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal logop As Long, ByVal object As Long, ByVal objIndex As Long, ByVal variable As Long, ByVal relop As Long, ByVal status As Long, ByVal value As Single) As Long
Declare Function ENsetpremiseindex Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal objIndex As Long) As Long
Declare Function ENsetpremisestatus Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal status As Long) As Long
Declare Function ENsetpremisevalue Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal value As Single) As Long
Declare Function ENgetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, linkIndex As Long, status As Long, setting As Single) As Long
Declare Function ENsetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, ByVal linkIndex As Long, ByVal status As Long, ByVal setting As Single) As Long
Declare Function ENgetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, linkIndex As Long, status As Long, setting As Single) As Long
Declare Function ENsetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, ByVal linkIndex As Long, ByVal status As Long, ByVal setting As Single) As Long

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL) for use with VB.Net.
'Last updated on 7/19/15 - LR
'Last updated on 01/08/2019
Imports System.Runtime.InteropServices
Imports System.Text
@@ -55,15 +55,16 @@ Public Const EN_HEADLOSS = 10
Public Const EN_STATUS = 11
Public Const EN_SETTING = 12
Public Const EN_ENERGY = 13
Public Const EN_LINKQUAL = 14 'ES
Public Const EN_LINKQUAL = 14
Public Const EN_LINKPATTERN = 15
Public Const EN_EFFICIENCY = 16
Public Const EN_HEADCURVE = 17
Public Const EN_EFFICIENCYCURVE = 18
Public Const EN_PRICEPATTERN = 19
Public Const EN_STATE = 20
Public Const EN_CONST_POWER = 21
Public Const EN_SPEED = 22
Public Const EN_PUMP_STATE = 16
Public Const EN_PUMP_EFFIC = 17
Public Const EN_PUMP_POWER = 18
Public Const EN_PUMP_HCURVE = 19
Public Const EN_PUMP_ECURVE = 20
Public Const EN_PUMP_ECOST = 21
Public Const EN_PUMP_EPAT = 22
Public Const EN_DURATION = 0 ' Time parameters
Public Const EN_HYDSTEP = 1
@@ -75,7 +76,7 @@ Public Const EN_REPORTSTART = 6
Public Const EN_RULESTEP = 7
Public Const EN_STATISTIC = 8
Public Const EN_PERIODS = 9
Public Const EN_STARTTIME = 10 'ES
Public Const EN_STARTTIME = 10
Public Const EN_HTIME = 11
Public Const EN_QTIME = 12
Public Const EN_HALTFLAG = 13
@@ -119,7 +120,7 @@ Public Const EN_MASS = 1
Public Const EN_SETPOINT = 2
Public Const EN_FLOWPACED = 3
Public Const EN_HW = 0 ' Head loss formula
Public Const EN_HW = 0 ' Head loss formulas
Public Const EN_DW = 1
Public Const EN_CM = 2
@@ -137,7 +138,7 @@ Public Const EN_CMD = 9
Public Const EN_DDA = 0 ' Demand driven analysis
Public Const EN_PDA = 1 ' Pressure driven analysis
Public Const EN_TRIALS = 0 ' Misc. options
Public Const EN_TRIALS = 0 ' Hydraulic options
Public Const EN_ACCURACY = 1
Public Const EN_TOLERANCE = 2
Public Const EN_EMITEXPON = 3
@@ -146,172 +147,218 @@ Public Const EN_HEADERROR = 5
Public Const EN_FLOWCHANGE = 6
Public Const EN_DEMANDDEFPAT = 7
Public Const EN_HEADLOSSFORM = 8
Public Const EN_GLOBALEFFIC = 9
Public Const EN_GLOBALPRICE = 10
Public Const EN_GLOBALPATTERN = 11
Public Const EN_DEMANDCHARGE = 12
Public Const EN_LOWLEVEL = 0 ' Control types
Public Const EN_LOWLEVEL = 0 ' Control types
Public Const EN_HILEVEL = 1
Public Const EN_TIMER = 2
Public Const EN_TIMEOFDAY = 3
Public Const EN_AVERAGE = 1 'Time statistic types
Public Const EN_AVERAGE = 1 ' Time statistic types
Public Const EN_MINIMUM = 2
Public Const EN_MAXIMUM = 3
Public Const EN_RANGE = 4
Public Const EN_MIX1 = 0 'Tank mixing models
Public Const EN_MIX1 = 0 ' Tank mixing models
Public Const EN_MIX2 = 1
Public Const EN_FIFO = 2
Public Const EN_LIFO = 3
Public Const EN_NOSAVE = 0 ' Save-results-to-file flag
Public Const EN_NOSAVE = 0 ' Save-results-to-file flag
Public Const EN_SAVE = 1
Public Const EN_INITFLOW = 10 ' Re-initialize flow flag
Public Const EN_INITFLOW = 10 ' Re-initialize flow flag
Public Const EN_SAVE_AND_INIT = 11
Public Const EN_CONST_HP = 0 ' constant horsepower
Public Const EN_POWER_FUNC = 1 ' power function
Public Const EN_CUSTOM = 2 ' user-defined custom curve
Public Const EN_CONST_HP = 0 ' Constant horsepower pump curve
Public Const EN_POWER_FUNC = 1 ' Power function pump curve
Public Const EN_CUSTOM = 2 ' User-defined custom pump curve
Public Const EN_NOCURVE = 3 ' No pump curve
Public Const EN_V_CURVE = 0 ' volume curve
Public Const EN_P_CURVE = 1 ' pump curve
Public Const EN_E_CURVE = 2 ' efficiency curve
Public Const EN_H_CURVE = 3 ' head loss curve
Public Const EN_G_CURVE = 4 ' General\default curve
Public Const EN_VOLUME_CURVE = 0 ' Volume curve
Public Const EN_PUMP_CURVE = 1 ' Pump curve
Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
Public Const EN_GENERIC_CURVE = 4 ' Generic curve
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
Public Const EN_CONDITIONAL = 1 ' Conditional object deletion
Public Const EN_NO_REPORT = 0 ' No status report
Public Const EN_NORMAL_REPORT = 1 ' Normal status report
Public Const EN_FULL_REPORT = 2 ' Full status report
Public Const EN_R_NODE = 6 ' Rule objects
Public Const EN_R_LINK = 7
Public Const EN_R_SYSTEM = 8
Public Const EN_R_DEMAND = 0 ' Rule variables
Public Const EN_R_HEAD = 1
Public Const EN_R_GRADE = 2
Public Const EN_R_LEVEL = 3
Public Const EN_R_PRESSURE = 4
Public Const EN_R_FLOW = 5
Public Const EN_R_STATUS = 6
Public Const EN_R_SETTING = 7
Public Const EN_R_POWER = 8
Public Const EN_R_TIME = 9
Public Const EN_R_CLOCKTIME = 10
Public Const EN_R_FILLTIME = 11
Public Const EN_R_DRAINTIME = 12
Public Const EN_R_EQ = 0 ' Rule operators
Public Const EN_R_NE = 1
Public Const EN_R_LE = 2
Public Const EN_R_GE = 3
Public Const EN_R_LT = 4
Public Const EN_R_GT = 5
Public Const EN_R_IS = 6
Public Const EN_R_NOT = 7
Public Const EN_R_BELOW = 8
Public Const EN_R_ABOVE = 9
Public Const EN_R_IS_OPEN = 1 ' Rule status types
Public Const EN_R_IS_CLOSED = 2
Public Const EN_R_IS_ACTIVE = 3
'These are the external functions that comprise the DLL
'System Functions
Declare Function ENgetversion Lib "epanet2.dll" (ByRef Value As Int32) As Int32
Declare Function ENepanet Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String, ByVal F4 As String) As Int32
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal binOutFile As String, ByVal UnitsType As Int32, ByVal HeadlossFormula As Int32) As Int32
Declare Function ENopen Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String) As Int32
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal F As String) As Int32
Declare Function ENgetversion Lib "epanet2.dll" (value As Int32) As Int32
Declare Function ENepanet Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String, ByVal pviewprog As Any) As Int32
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal outFile As String, ByVal unitsType As Int32, ByVal headlossType As Int32) As Int32
Declare Function ENopen Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Int32
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Int32
Declare Function ENclose Lib "epanet2.dll" () As Int32
'Hydraulic Analysis Functions
'Hydraulic Analysis Functions
Declare Function ENsolveH Lib "epanet2.dll" () As Int32
Declare Function ENsaveH Lib "epanet2.dll" () As Int32
Declare Function ENopenH Lib "epanet2.dll" () As Int32
Declare Function ENinitH Lib "epanet2.dll" (ByVal SaveFlag As Int32) As Int32
Declare Function ENrunH Lib "epanet2.dll" (ByRef T As Int32) As Int32
Declare Function ENnextH Lib "epanet2.dll" (ByRef Tstep As Int32) As Int32
Declare Function ENinitH Lib "epanet2.dll" (ByVal initFlag As Int32) As Int32
Declare Function ENrunH Lib "epanet2.dll" (currentTime As Int32) As Int32
Declare Function ENnextH Lib "epanet2.dll" (tStep As Int32) As Int32
Declare Function ENcloseH Lib "epanet2.dll" () As Int32
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal F As String) As Int32
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal F As String) As Int32
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal filename As String) As Int32
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal filename As String) As Int32
'Water Quality Analysis Functions
Declare Function ENsolveQ Lib "epanet2.dll" () As Int32
Declare Function ENopenQ Lib "epanet2.dll" () As Int32
Declare Function ENinitQ Lib "epanet2.dll" (ByVal SaveFlag As Int32) As Int32
Declare Function ENrunQ Lib "epanet2.dll" (ByRef T As Int32) As Int32
Declare Function ENnextQ Lib "epanet2.dll" (ByRef Tstep As Int32) As Int32
Declare Function ENstepQ Lib "epanet2.dll" (ByRef Tleft As Int32) As Int32
Declare Function ENinitQ Lib "epanet2.dll" (ByVal saveFlag As Int32) As Int32
Declare Function ENrunQ Lib "epanet2.dll" (currentTime As Int32) As Int32
Declare Function ENnextQ Lib "epanet2.dll" (tStep As Int32) As Int32
Declare Function ENstepQ Lib "epanet2.dll" (timeLeft As Int32) As Int32
Declare Function ENcloseQ Lib "epanet2.dll" () As Int32
'Reporting Functions
Declare Function ENwriteline Lib "epanet2.dll" (ByVal S As String) As Int32
'Reporting Functions
Declare Function ENwriteline Lib "epanet2.dll" (ByVal line As String) As Int32
Declare Function ENreport Lib "epanet2.dll" () As Int32
Declare Function ENresetreport Lib "epanet2.dll" () As Int32
Declare Function ENsetreport Lib "epanet2.dll" (ByVal S As String) As Int32
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal Code As Int32) As Int32
Declare Function ENgetcount Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value As Int32) As Int32
Declare Function ENgeterror Lib "epanet2.dll" (ByVal ErrCode As Int32, ByVal ErrMsg As StringBuilder, ByVal N As Int32) As Int32
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal code As Int32, ByRef value As Single) As Int32
Declare Function ENsetreport Lib "epanet2.dll" (ByVal format As String) As Int32
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal level As Int32) As Int32
Declare Function ENgetcount Lib "epanet2.dll" (ByVal object As Int32, count As Int32) As Int32
Declare Function ENgeterror Lib "epanet2.dll" (ByVal errcode As Int32, ByVal errmsg As String, ByVal maxLen As Int32) As Int32
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Int32, ByRef value As Single) As Int32
'Analysis Options Functions
Declare Function ENgetoption Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value As Single) As Int32
Declare Function ENsetoption Lib "epanet2.dll" (ByVal Code As Int32, ByVal Value As Single) As Int32
Declare Function ENgetflowunits Lib "epanet2.dll" (ByRef Code As Int32) As Int32
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal code As Int32) As Int32
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value As Int32) As Int32
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal Code As Int32, ByVal Value As Int32) As Int32
Declare Function ENgetqualtype Lib "epanet2.dll" (ByRef QualCode As Int32, ByRef TraceNode As Int32) As Int32
Declare Function ENgetqualinfo Lib "epanet2.dll" (ByRef QualCode As Int32, ByVal ChemName As String, ByVal ChemUnits As String, ByRef TraceNode As Int32) As Int32
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal QualCode As Int32, ByVal ChemName As String, ByVal ChemUnits As String, ByVal TraceNode As String) As Int32
Declare Function ENgetoption Lib "epanet2.dll" (ByVal option As Int32, value As Single) As Int32
Declare Function ENsetoption Lib "epanet2.dll" (ByVal option As Int32, ByVal value As Single) As Int32
Declare Function ENgetflowunits Lib "epanet2.dll" (units As Int32) As Int32
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal units As Int32) As Int32
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal param As Int32, value As Int32) As Int32
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal param As Int32, ByVal value As Int32) As Int32
Declare Function ENgetqualinfo Lib "epanet2.dll" (qualType As Int32, ByVal chemName As String, ByVal chemUnits As String, traceNode As Int32) As Int32
Declare Function ENgetqualtype Lib "epanet2.dll" (qualType As Int32, traceNode As Int32) As Int32
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal qualType As Int32, ByVal chemName As String, ByVal chemUnits As String, ByVal traceNode As String) As Int32
'Basic Node Functions
'Node Functions
Declare Function ENaddnode Lib "epanet2.dll" (ByVal id As String, ByVal nodeType As Int32) As Int32
Declare Function ENdeletenode Lib "epanet2.dll" (ByVal linkIndex As Long) As Long
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
Declare Function ENgetnodeid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
Declare Function ENdeletenode Lib "epanet2.dll" (ByVal index As Int32, ByVal actionCode As Int32) As Int32
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
Declare Function ENgetnodeid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
Declare Function ENsetnodeid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal Index As Int32, ByRef Code As Int32) As Int32
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByRef Value As Single) As Int32
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByVal Value As Single) As Int32
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal Index As Int32, ByRef X As Single, ByRef Y As Single) As Int32
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal Index As Int32, ByVal X As Single, ByVal Y As Single) As Int32
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal index As Int32, nodeType As Int32) As Int32
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, value As Single) As Int32
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, ByVal value As Single) As Int32
Declare Function ENsetjuncdata Lib "epanet2.dll" (ByVal index As Int32, ByVal elev As Single, ByVal dmnd As Single, ByVal dmndpat As String) As Int32
Declare Function ENsettankdata Lib "epanet2.dll" (ByVal index As Int32, ByVal elev As Single, ByVal initlvl As Single, ByVal minlvl As Single, ByVal maxlvl As Single, ByVal diam As Single, ByVal minvol As Single, ByVal volcurve As String) As Int32
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal index As Int32, x As Single, y As Single) As Int32
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal index As Int32, ByVal x As Single, ByVal y As Single) As Int32
'Nodal Demand Functions
Declare Function ENgetdemandmodel Lib "epanet2.dll" (ByRef mtype As Int32, ByRef pmin As Single, ByRef preq As Single, ByRef pexp As Single) As Int32
Declare Function ENsetdemandmodel Lib "epanet2.dll" (ByVal mtype As Int32, ByVal pmin As Single, ByVal preq As Single, ByVal pexp As Single) As Int32
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal Index As Int32, ByRef numDemands As Int32) As Int32 'ES
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef BaseDemand As Single) As Int32 'ES
Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByVal BaseDemand As Single) As Int32 'ES
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef PatIndex As Int32) As Int32 'ES
Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal index As Int32, ByVal DemandIndex As Int32, ByVal PatIndex As Int32) As Int32
Declare Function ENgetdemandname Lib "epanet2.dll" (ByVal index As Int32, ByVal DemandIndex As Int32, ByVal demandName As String) As Int32
Declare Function ENsetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal DemandIndex As Int32, ByVal demandName As String) As Int32
Declare Function ENgetdemandmodel Lib "epanet2.dll" (type_ As Int32, pmin As Single, preq As Single, pexp As Single) As Int32
Declare Function ENsetdemandmodel Lib "epanet2.dll" (ByVal type_ As Int32, ByVal pmin As Single, ByVal preq As Single, ByVal pexp As Single) As Int32
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal nodeIndex As Int32, numDemands As Int32) As Int32
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, value As Single) As Int32
Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal BaseDemand As Single) As Int32
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, patIndex As Int32) As Int32
Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal patIndex As Int32) As Int32
Declare Function ENgetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal demandName As String) As Int32
Declare Function ENsetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal demandName As String) As Int32
'Basic Link Functions
'Link Functions
Declare Function ENaddlink Lib "epanet2.dll" (ByVal id As String, ByVal linkType As Int32, ByVal fromNode As String, ByVal toNode As String) As Int32
Declare Function ENdeletelink Lib "epanet2.dll" (ByVal nodeIndex As Long) As Long
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
Declare Function ENdeletelink Lib "epanet2.dll" (ByVal index As Int32, ByVal actionCode As Int32) As Int32
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
Declare Function ENsetlinkid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal Index As Int32, ByRef Code As Int32) As Int32
Declare Function ENsetlinktype Lib "epanet2.dll" (ByRef index As Int32, ByVal code As Int32) As Int32
Declare Function ENgetlinknodes Lib "epanet2.dll" (ByVal Index As Int32, ByRef Node1 As Int32, ByRef Node2 As Int32) As Int32
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal index As Int32, linkType As Int32) As Int32
Declare Function ENsetlinktype Lib "epanet2.dll" (index As Int32, ByVal linkType As Int32, ByVal actionCode As Int32) As Int32
Declare Function ENgetlinknodes Lib "epanet2.dll" (ByVal index As Int32, node1 As Int32, node2 As Int32) As Int32
Declare Function ENsetlinknodes Lib "epanet2.dll" (ByVal index As Int32, ByVal node1 As Int32, ByVal node2 As Int32) As Int32
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByRef Value As Single) As Int32
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByVal Value As Single) As Int32
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, value As Single) As Int32
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, ByVal value As Single) As Int32
Declare Function ENsetpipedata Lib "epanet2.dll" (ByVal index As Int32, ByVal length As Single, ByVal diam As Single, ByVal rough As Single, ByVal mloss As Single) As Int32
'Pump Functions
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal Index As Int32, ByVal CurveIndex As int32) As Int32 'ES
Declare Function ENsetheadcurveindex Lib "epanet2.dll" (ByVal pumpIndex As Int32, ByVal curveIndex As Int32) As Int32
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal Index As Int32, ByRef PumpType As Int32) As Int32 'ES
'Time Pattern Functions
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal ID As String) As Int32
Declare Function ENgetpatternindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
Declare Function ENgetpatternid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal Index As Int32, ByRef L As Int32) As Int32
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Period As Int32, ByRef Value As Single) As Int32
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Period As Int32, ByVal Value As Single) As Int32
Declare Function ENgetaveragepatternvalue Lib "epanet2.dll" (ByVal index As Int32, ByRef value As Single) As Int32
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal Index as Int32, ByRef F as Single, ByVal N as Int32) as Int32
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Int32, curveIndex As Int32) As Int32
Declare Function ENsetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Int32, ByVal curveIndex As Int32) As Int32
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal linkIndex As Int32, pumpType As Int32) As Int32
'Time Pattern Functions
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal id As String) As Int32
Declare Function ENgetpatternindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
Declare Function ENgetpatternid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal index As Int32, len_ As Int32) As Int32
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal period As Int32, value As Single) As Int32
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal period As Int32, ByVal value As Single) As Int32
Declare Function ENgetaveragepatternvalue Lib "epanet2.dll" (ByVal index As Int32, value As Single) As Int32
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal index As Int32, values As Any, ByVal len_ As Int32) As Int32
'Data Curve Functions
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal ID As String) As Int32
Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal Index As Int32, ByRef L As Int32) As Int32
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal curveIndex As Int32, ByRef CurveType As Int32) As Int32
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Pnt As Int32, ByRef X As Single, ByRef Y As Single) As Int32
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Pnt As Int32, ByVal X As Single, ByVal Y As Single) As Int32
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal CurveIndex As Int32, ByRef nValues As Int32, ByRef xValues As Single, ByRef yValues As Single) As Int32 'ES
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal Index as Int32, ByRef X as Single, ByRef Y as Single, ByVal N as Int32) as Int32
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal id As String) As Int32
Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Int32, len_ As Int32) As Int32
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal index As Int32, type_ As Int32) As Int32
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Int32, ByVal pointIndex As Int32, x As Single, y As Single) As Int32
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Int32, ByVal pointIndex As Int32, ByVal x As Single, ByVal y As Single) As Int32
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String, nPoints As Int32, xValues As Any, yValues As Any) As Int32
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal index As Int32, xValues As Any, yValues As Any, ByVal nPoints As Int32) As Int32
'Simple Control Functions
Declare Function ENaddcontrol Lib "epanet2.dll" (ByRef Cindex As Int32, ByVal Ctype As Int32, ByVal Lindex As Int32, ByVal setting As Single, ByVal Nindex As Int32, ByVal Level As Single) As Int32
Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal Cindex as Int32) As Int32
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal Cindex As Int32, ByRef CtlType As Int32, ByRef Lindex As Int32, ByRef Setting As Single, ByRef Nindex As Int32, ByRef Level As Single) As Int32
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal Cindex As Int32, ByVal CtlType As Int32, ByVal Lindex As Int32, ByVal Setting As Single, ByVal Nindex As Int32, ByVal Level As Single) As Int32
Declare Function ENaddcontrol Lib "epanet2.dll" (ByVal type_ As Int32, ByVal linkIndex As Int32, ByVal setting As Single, ByVal nodeIndex As Int32, ByVal level As Single, index As Int32) As Int32
Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal index As Int32) As Int32
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal index As Int32, type_ As Int32, linkIndex As Int32, setting As Single, nodeIndex As Int32, level As Single) As Int32
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal index As Int32, ByVal type_ As Int32, ByVal linkIndex As Int32, ByVal setting As Single, ByVal nodeIndex As Int32, ByVal level As Single) As Int32
'Rule-Based Control Functions
Declare Function ENaddrule Lib "epanet2.dll" (ByVal rule As String) as Int32
'Rule-Based Control Functions
Declare Function ENaddrule Lib "epanet2.dll" (ByVal rule As String) As Int32
Declare Function ENdeleterule Lib "epanet2.dll" (ByVal index As Int32) As Int32
Declare Function ENgetrule Lib "epanet2.dll" (ByVal index As Int32, ByRef nPremises As Int32, ByRef nTrueActions As Int32, ByRef nFalseActions As Int32, ByRef priority As Single) As Int32
Declare Function ENgetruleID Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal id As StringBuilder) As Int32
Declare Function ENgetrule Lib "epanet2.dll" (ByVal index As Int32, nPremises As Int32, nThenActions As Int32, nElseActions As Int32, priority As Single) As Int32
Declare Function ENgetruleID Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
Declare Function ENsetrulepriority Lib "epanet2.dll" (ByVal index As Int32, ByVal priority As Single) As Int32
Declare Function ENgetpremise Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexPremise As Int32, ByRef logop As Int32, ByRef object As Int32, ByRef indexObj As Int32, ByRef variable As Int32, ByRef relop As Int32, ByRef status As Int32, ByRef value As Single) As Int32
Declare Function ENsetpremise Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexPremise As Int32, ByVal logop As Int32, ByVal object As Int32, ByVal indexObj As Int32, ByVal variable As Int32, ByVal relop As Int32, ByVal status As Int32, ByVal value As Single) As Int32
Declare Function ENsetpremiseindex Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexPremise As Int32, ByVal indexObj As Int32) As Int32
Declare Function ENsetpremisestatus Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexPremise As Int32, ByVal status As Int32) As Int32
Declare Function ENsetpremisevalue Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexPremise As Int32, ByVal value As Single) As Int32
Declare Function ENgetthenaction Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexAction As Int32, ByRef indexLink As Int32, ByRef status As Int32, ByRef setting As Single) As Int32
Declare Function ENsetthenaction Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexAction As Int32, ByVal indexLink As Int32, ByVal status As Int32, ByVal setting As Single) As Int32
Declare Function ENgetelseaction Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexAction As Int32, ByRef indexLink As Int32, ByRef status As Int32, ByRef setting As Single) As Int32
Declare Function ENsetelseaction Lib "epanet2.dll" (ByVal indexRule As Int32, ByVal indexAction As Int32, ByVal indexLink As Int32, ByVal status As Int32, ByVal setting As Single) As Int32
Declare Function ENgetpremise Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, logop As Int32, object As Int32, objIndex As Int32, variable As Int32, relop As Int32, status As Int32, value As Single) As Int32
Declare Function ENsetpremise Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal logop As Int32, ByVal object As Int32, ByVal objIndex As Int32, ByVal variable As Int32, ByVal relop As Int32, ByVal status As Int32, ByVal value As Single) As Int32
Declare Function ENsetpremiseindex Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal objIndex As Int32) As Int32
Declare Function ENsetpremisestatus Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal status As Int32) As Int32
Declare Function ENsetpremisevalue Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal value As Single) As Int32
Declare Function ENgetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, linkIndex As Int32, status As Int32, setting As Single) As Int32
Declare Function ENsetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, ByVal linkIndex As Int32, ByVal status As Int32, ByVal setting As Single) As Int32
Declare Function ENgetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, linkIndex As Int32, status As Int32, setting As Single) As Int32
Declare Function ENsetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, ByVal linkIndex As Int32, ByVal status As Int32, ByVal setting As Single) As Int32
End Module

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,15 @@
/** @file epanet2_enums.h
*/
/*
******************************************************************************
Project: OWA EPANET
Version: 2.2
Module: epanet2_enums.h
Description: enums shared between API versions
Description: enumerations of symbolic constants used by the API functions
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/29/2018
Last Updated: 01/14/2019
******************************************************************************
*/
@@ -21,111 +23,139 @@
#define EN_MAXID 31 //!< Max. # characters in ID name
#define EN_MAXMSG 255 //!< Max. # characters in message text
/// Node property codes
/// Node properties
/**
These node properties can be accessed with @ref EN_getnodevalue and
@ref EN_setnodevalue. Those marked as read only are computed values that can
only be retrieved.
*/
typedef enum {
EN_ELEVATION = 0, //!< Elevation
EN_BASEDEMAND = 1, //!< Junction baseline demand, from last demand category
EN_PATTERN = 2, //!< Junction baseline demand pattern
EN_EMITTER = 3, //!< Junction emitter coefficient
EN_BASEDEMAND = 1, //!< Primary demand baseline value
EN_PATTERN = 2, //!< Primary demand time pattern index
EN_EMITTER = 3, //!< Emitter flow coefficient
EN_INITQUAL = 4, //!< Initial quality
EN_SOURCEQUAL = 5, //!< Quality source strength
EN_SOURCEPAT = 6, //!< Quality source pattern
EN_SOURCETYPE = 7, //!< Qualiy source type
EN_TANKLEVEL = 8, //!< Tank water level
EN_DEMAND = 9, //!< Current simulated demand
EN_HEAD = 10, //!< Current hydraulic head
EN_PRESSURE = 11, //!< Current pressure
EN_QUALITY = 12, //!< Current quality
EN_SOURCEMASS = 13, //!< Current source mass inflow
EN_INITVOLUME = 14, //!< Tank initial volume
EN_MIXMODEL = 15, //!< Tank mixing model
EN_MIXZONEVOL = 16, //!< Tank mixing zone volume
EN_SOURCEPAT = 6, //!< Quality source pattern index
EN_SOURCETYPE = 7, //!< Quality source type (see @ref EN_SourceType)
EN_TANKLEVEL = 8, //!< Current computed tank water level (read only)
EN_DEMAND = 9, //!< Current computed demand (read only)
EN_HEAD = 10, //!< Current computed hydraulic head (read only)
EN_PRESSURE = 11, //!< Current computed pressure (read only)
EN_QUALITY = 12, //!< Current computed quality (read only)
EN_SOURCEMASS = 13, //!< Current computed quality source mass inflow (read only)
EN_INITVOLUME = 14, //!< Tank initial volume (read only)
EN_MIXMODEL = 15, //!< Tank mixing model (see @ref EN_MixingModel)
EN_MIXZONEVOL = 16, //!< Tank mixing zone volume (read only)
EN_TANKDIAM = 17, //!< Tank diameter
EN_MINVOLUME = 18, //!< Tank minimum volume
EN_VOLCURVE = 19, //!< Tank volume curve
EN_VOLCURVE = 19, //!< Tank volume curve index
EN_MINLEVEL = 20, //!< Tank minimum level
EN_MAXLEVEL = 21, //!< Tank maximum level
EN_MIXFRACTION = 22, //!< Tank mixing fraction
EN_TANK_KBULK = 23, //!< Tank bulk decay coefficient
EN_TANKVOLUME = 24, //!< Tank current volume
EN_MAXVOLUME = 25 //!< Tank maximum volume
EN_TANKVOLUME = 24, //!< Current computed tank volume (read only)
EN_MAXVOLUME = 25 //!< Tank maximum volume (read only)
} EN_NodeProperty;
/// Link property codes
/// Link properties
/**
These link properties can be accessed with @ref EN_getlinkvalue and @ref EN_setlinkvalue.
Those marked as read only are computed values that can only be retrieved.
*/
typedef enum {
EN_DIAMETER = 0, //!< Pipe/valve diameter
EN_LENGTH = 1, //!> Pipe length
EN_ROUGHNESS = 2, //!> Pipe roughness coefficient
EN_MINORLOSS = 3, //!> Pipe/valve minor loss coefficient
EN_INITSTATUS = 4, //!> Initial status (e.g., OPEN/CLOSED)
EN_INITSETTING = 5, //!> Initial pump speed or valve setting
EN_KBULK = 6, //!> Bulk chemical reaction coefficient
EN_KWALL = 7, //!> Pipe wall chemical reaction coefficient
EN_FLOW = 8, //!> Current link flow rate
EN_VELOCITY = 9, //!> Current link flow velocity
EN_HEADLOSS = 10, //!> Current head loss across link
EN_STATUS = 11, //!> Current link status
EN_SETTING = 12, //!> Current link setting
EN_ENERGY = 13, //!> Current pump energy usage
EN_LINKQUAL = 14, //!> Current link quality
EN_LINKPATTERN = 15, //!> Pump speed time pattern
EN_EFFICIENCY = 16, //!> Current pump efficiency
EN_HEADCURVE = 17, //!> Pump head v. flow curve
EN_EFFICIENCYCURVE = 18, //!> Pump efficiency v. flow curve
EN_PRICEPATTERN = 19, //!> Pump energy price time pattern
EN_STATE = 20, //!> Current pump status
EN_CONST_POWER = 21, //!> Horsepower of constant horsepower pump
EN_SPEED = 22 //!> Current pump speed setting
EN_LENGTH = 1, //!< Pipe length
EN_ROUGHNESS = 2, //!< Pipe roughness coefficient
EN_MINORLOSS = 3, //!< Pipe/valve minor loss coefficient
EN_INITSTATUS = 4, //!< Initial status (see @ref EN_LinkStatusType)
EN_INITSETTING = 5, //!< Initial pump speed or valve setting
EN_KBULK = 6, //!< Bulk chemical reaction coefficient
EN_KWALL = 7, //!< Pipe wall chemical reaction coefficient
EN_FLOW = 8, //!< Current computed flow rate (read only)
EN_VELOCITY = 9, //!< Current computed flow velocity (read only)
EN_HEADLOSS = 10, //!< Current computed head loss (read only)
EN_STATUS = 11, //!< Current link status (see @ref EN_LinkStatusType)
EN_SETTING = 12, //!< Current link setting
EN_ENERGY = 13, //!< Current computed pump energy usage (read only)
EN_LINKQUAL = 14, //!< Current computed link quality (read only)
EN_LINKPATTERN = 15, //!< Pump speed time pattern index
EN_PUMP_STATE = 16, //!< Current computed pump state (read only) (see @ref EN_PumpStateType)
EN_PUMP_EFFIC = 17, //!< Current computed pump efficiency (read only)
EN_PUMP_POWER = 18, //!< Pump constant power rating
EN_PUMP_HCURVE = 19, //!< Pump head v. flow curve index
EN_PUMP_ECURVE = 20, //!< Pump efficiency v. flow curve index
EN_PUMP_ECOST = 21, //!< Pump average energy price
EN_PUMP_EPAT = 22 //!< Pump energy price time pattern index
} EN_LinkProperty;
/// Time parameter codes
/// Time parameters
/**
These time parameters are accessed using @ref EN_gettimeparam and@ref EN_settimeparam.
All times are expressed in seconds The parameters marked as read only are
computed values that can only be retrieved.
*/
typedef enum {
EN_DURATION = 0, //!> Total simulation duration
EN_HYDSTEP = 1, //!> Hydraulic time step
EN_QUALSTEP = 2, //!> Water quality time step
EN_PATTERNSTEP = 3, //!> Time pattern period
EN_PATTERNSTART = 4, //!> Time when time patterns begin
EN_REPORTSTEP = 5, //!> Reporting time step
EN_REPORTSTART = 6, //!> Time when reporting starts
EN_RULESTEP = 7, //!> Rule evaluation time step
EN_STATISTIC = 8, //!> Reporting statistic code
EN_PERIODS = 9, //!> Number of reporting time periods
EN_STARTTIME = 10, //!> Simulation starting time of day
EN_HTIME = 11, //!> Elapsed time of current hydraulic solution
EN_QTIME = 12, //!> Elapsed time of current quality solution
EN_HALTFLAG = 13, //!> Flag indicating if simulation halted
EN_NEXTEVENT = 14, //!> Next time until a tank becomes empty or full
EN_NEXTEVENTIDX = 15 //!> Index of next tank that becomes empty or full
} EN_TimeProperty;
EN_DURATION = 0, //!< Total simulation duration
EN_HYDSTEP = 1, //!< Hydraulic time step
EN_QUALSTEP = 2, //!< Water quality time step
EN_PATTERNSTEP = 3, //!< Time pattern period
EN_PATTERNSTART = 4, //!< Time when time patterns begin
EN_REPORTSTEP = 5, //!< Reporting time step
EN_REPORTSTART = 6, //!< Time when reporting starts
EN_RULESTEP = 7, //!< Rule-based control evaluation time step
EN_STATISTIC = 8, //!< Reporting statistic code (see @ref EN_StatisticType)
EN_PERIODS = 9, //!< Number of reporting time periods (read only)
EN_STARTTIME = 10, //!< Simulation starting time of day
EN_HTIME = 11, //!< Elapsed time of current hydraulic solution (read only)
EN_QTIME = 12, //!< Elapsed time of current quality solution (read only)
EN_HALTFLAG = 13, //!< Flag indicating if the simulation was halted (read only)
EN_NEXTEVENT = 14, //!< Shortest time until a tank becomes empty or full (read only)
EN_NEXTEVENTTANK = 15 //!< Index of tank with shortest time to become empty or full (read only)
} EN_TimeParameter;
/// Analysis statistic codes
/// Analysis convergence statistics
/**
These statistics report the convergence criteria for the most current hydraulic analysis
and the cumulative water quality mass balance error at the current simulation time. They
can be retrieved with @ref EN_getstatistic.
*/
typedef enum {
EN_ITERATIONS = 0, //!< Number of hydraulic iterations
EN_RELATIVEERROR = 1, //!< Sum of all flow changes / total flow
EN_ITERATIONS = 0, //!< Number of hydraulic iterations taken
EN_RELATIVEERROR = 1, //!< Sum of link flow changes / sum of link flows
EN_MAXHEADERROR = 2, //!< Largest head loss error for links
EN_MAXFLOWCHANGE = 3, //!< Largest flow change in links
EN_MASSBALANCE = 4 //!< Water quality mass balance ratio
EN_MASSBALANCE = 4 //!< Cumulative water quality mass balance ratio
} EN_AnalysisStatistic;
/// Object count codes
/// Types of objects to count
/**
These options tell @ref EN_getcount which type of object to count.
*/
typedef enum {
EN_NODECOUNT = 0, //!< Number of nodes (Juntions + Tanks + Reservoirs)
EN_TANKCOUNT = 1, //!< Number of tanks and Reservoirs
EN_LINKCOUNT = 2, //!< Number of links (Pipes + Pumps + Valves)
EN_NODECOUNT = 0, //!< Number of nodes (junctions + tanks + reservoirs)
EN_TANKCOUNT = 1, //!< Number of tanks and reservoirs
EN_LINKCOUNT = 2, //!< Number of links (pipes + pumps + valves)
EN_PATCOUNT = 3, //!< Number of time patterns
EN_CURVECOUNT = 4, //!< Number of curves
EN_CURVECOUNT = 4, //!< Number of data curves
EN_CONTROLCOUNT = 5, //!< Number of simple controls
EN_RULECOUNT = 6 //!< Number of rule-based controls
} EN_CountType;
/// Node type codes
/// Types of nodes
/**
These are the different types of nodes that can be returned by calling @ref EN_getnodetype.
*/
typedef enum {
EN_JUNCTION = 0, //!< Junction node
EN_RESERVOIR = 1, //!< Reservoir node
EN_TANK = 2 //!< Storage tank node
} EN_NodeType;
/// Link type codes
/// Types of links
/**
These are the different types of links that can be returned by calling @ref EN_getlinktype.
*/
typedef enum {
EN_CVPIPE = 0, //!< Pipe with check valve
EN_PIPE = 1, //!< Pipe
@@ -138,7 +168,36 @@ typedef enum {
EN_GPV = 8 //!< General purpose valve
} EN_LinkType;
/// Water quality analysis types
/// Link status
/**
One of these values is returned when @ref EN_getlinkvalue is used to retrieve a link's
initial status (EN_INITSTATUS) or its current status (EN_STATUS). These options are
also used with @ref EN_setlinkvalue to set values for these same properties.
*/
typedef enum {
EN_CLOSED = 0,
EN_OPEN = 1
} EN_LinkStatusType;
/// Pump states
/**
One of these codes is returned when @ref EN_getlinkvalue is used to retrieve a pump's
current operating state (EN_PUMP_STATE). EN_PUMP_XHEAD indicates that the pump has been
shut down because it is being asked to deliver more than its shutoff head. EN_PUMP_XFLOW
indicates that the pump is being asked to deliver more than its maximum flow.
*/
typedef enum {
EN_PUMP_XHEAD = 0, //!< Pump closed - cannot supply head
EN_PUMP_CLOSED = 2, //!< Pump closed
EN_PUMP_OPEN = 3, //!< Pump open
EN_PUMP_XFLOW = 5 //!< Pump open - cannot supply flow
} EN_PumpStateType;
/// Types of water quality analyses
/**
These are the different types of water quality analyses that EPANET can run. They
are used with @ref EN_getqualinfo, @ref EN_getqualtype, and @ref EN_setqualtype.
*/
typedef enum {
EN_NONE = 0, //!< No quality analysis
EN_CHEM = 1, //!< Chemical fate and transport
@@ -146,71 +205,124 @@ typedef enum {
EN_TRACE = 3 //!< Source tracing analysis
} EN_QualityType;
/// Water quality source types
/// Types of water quality sources
/**
These are the options for EN_SOURCETYPE, the type of external water quality
source assigned to a node. They are used in @ref EN_getnodevalue and @ref EN_setnodevalue.
The EN_SOURCEQUAL property is used in these functions to access a source's strength
and EN_SOURCEPATTERN to access a time pattern applied to the source.
*/
typedef enum {
EN_CONCEN = 0, //!< Concentration inflow source
EN_MASS = 1, //!< Mass inflow source
EN_SETPOINT = 2, //!< Concentration setpoint source
EN_FLOWPACED = 3 //!< Concentration flow paced source
EN_CONCEN = 0, //!< Concentration of any external inflow entering a node
EN_MASS = 1, //!< Injects a given mass/minute into a node
EN_SETPOINT = 2, //!< Sets the concentration leaving a node to a given value
EN_FLOWPACED = 3 //!< Adds a given value to the concentration leaving a node
} EN_SourceType;
/// Head loss formulas
/// Head loss formula choices
/**
These are the choices for the EN_HEADLOSSFORM option in @ref EN_getoption and
@ref EN_setoption. They are also used for the head loss type argument in @ref EN_init.
Each head loss formula uses a different type of roughness coefficient (EN_ROUGHNESS)
that can be set with @ref EN_setlinkvalue.
*/
typedef enum {
EN_HW = 0, //!< Hazen-Williams
EN_DW = 1, //!< Darcy-Weisbach
EN_CM = 2 //!< Chezy-Manning
} EN_HeadLossType;
/// Flow units types
/// Flow units choices
/**
These choices for flow units are used with @ref EN_getflowunits and @ref EN_setflowunits.
They are also used for the flow units type argument in @ref EN_init. If flow units are
expressed in US Customary units (EN_CFS through EN_AFD) then all other quantities are
in US Customary units. Otherwise they are in metric units.
*/
typedef enum {
EN_CFS = 0,
EN_GPM = 1,
EN_MGD = 2,
EN_IMGD = 3,
EN_AFD = 4,
EN_LPS = 5,
EN_LPM = 6,
EN_MLD = 7,
EN_CMH = 8,
EN_CMD = 9
EN_CFS = 0, //!< Cubic feet per second
EN_GPM = 1, //!< Gallons per minute
EN_MGD = 2, //!< Million gallons per day
EN_IMGD = 3, //!< Imperial million gallons per day
EN_AFD = 4, //!< Acre-feet per day
EN_LPS = 5, //!< Liters per second
EN_LPM = 6, //!< Liters per minute
EN_MLD = 7, //!< Million liters per day
EN_CMH = 8, //!< Cubic meters per hour
EN_CMD = 9 //!< Cubic meters per day
} EN_FlowUnits;
/// Demand model types
/// Types of demand models
/**
These choices for representing consumer demands are used with @ref EN_getdemandmodel
and @ref EN_setdemandmodel.
A demand driven analysis requires that a junction's full demand be supplied
in each time period independent of how much pressure is available. A pressure
driven analysis makes demand be a power function of pressure, up to the point
where the full demand is met.
*/
typedef enum {
EN_DDA = 0, //!< Demand driven analysis
EN_PDA = 1 //!< Pressure driven analysis
} EN_DemandModel;
/// Simulation Option codes
/// Simulation options
/**
These options specify hydraulic convergence criteria, choice of head loss formula, and
several other parameters applied on a network-wide basis. They are accessed using the
@ref EN_getoption and @ref EN_setoption functions.
*/
typedef enum {
EN_TRIALS = 0, //!> Maximum hydraulic trials allowed
EN_ACCURACY = 1, //!> Hydraulic convergence accuracy
EN_TOLERANCE = 2, //!> Water quality tolerance
EN_EMITEXPON = 3, //!> Exponent for emitter head loss formula
EN_DEMANDMULT = 4, //!> Global demand multiplier
EN_HEADERROR = 5, //!> Maximum allowable head loss error
EN_FLOWCHANGE = 6, //!> Maximum allowable flow change
EN_DEMANDDEFPAT = 7, //!> Default demand time pattern
EN_HEADLOSSFORM = 8 //!> Head loss formula code
EN_TRIALS = 0, //!< Maximum hydraulic trials allowed
EN_ACCURACY = 1, //!< Maximum total relative flow change for hydraulic convergence
EN_TOLERANCE = 2, //!< Water quality tolerance
EN_EMITEXPON = 3, //!< Exponent in emitter discharge formula
EN_DEMANDMULT = 4, //!< Global demand multiplier
EN_HEADERROR = 5, //!< Maximum head loss error for hydraulic convergence
EN_FLOWCHANGE = 6, //!< Maximum flow change for hydraulic convergence
EN_DEFDEMANDPAT = 7, //!< Index of the default demand time pattern
EN_HEADLOSSFORM = 8, //!< Head loss formula (see @ref EN_HeadLossType)
EN_GLOBALEFFIC = 9, //!< Global pump efficiency (percent)
EN_GLOBALPRICE = 10, //!< Global energy price per KWH
EN_GLOBALPATTERN = 11, //!< Index of a global energy price pattern
EN_DEMANDCHARGE = 12 //!< Energy charge per max. KW usage
} EN_Option;
/// Simple control types
/// Types of simple controls
/**
These are the different types of simple (single statement) controls that can be applied
to network links. They are used as an argument to @ref EN_addcontrol,@ref EN_getcontrol,
and @ref EN_setcontrol.
*/
typedef enum {
EN_LOWLEVEL = 0,
EN_HILEVEL = 1,
EN_TIMER = 2,
EN_TIMEOFDAY = 3
EN_LOWLEVEL = 0, //!< Act when pressure or tank level drops below a setpoint
EN_HILEVEL = 1, //!< Act when pressure or tank level rises above a setpoint
EN_TIMER = 2, //!< Act at a prescribed elapsed amount of time
EN_TIMEOFDAY = 3 //!< Act at a particular time of day
} EN_ControlType;
/// Reporting statistic types
/// Reporting statistic choices
/**
These options determine what kind of statistical post-processing should be done on
the time series of simulation results generated before they are reported using
@ref EN_report. An option can be chosen by using `STATISTIC option` as the argument
to @ref EN_setreport.
*/
typedef enum {
EN_AVERAGE = 1, //!> Report average value over simulation period
EN_MINIMUM = 2, //!> Report minimum value over simulation period
EN_MAXIMUM = 3, //!> Report maximum value over simulation period
EN_RANGE = 4 //!> Report maximum - minimum over simulation period
EN_SERIES = 0, //!< Report all time series points
EN_AVERAGE = 1, //!< Report average value over simulation period
EN_MINIMUM = 2, //!< Report minimum value over simulation period
EN_MAXIMUM = 3, //!< Report maximum value over simulation period
EN_RANGE = 4 //!< Report maximum - minimum over simulation period
} EN_StatisticType;
/// Tank mixing models
/**
These are the different types of models that describe water quality mixing in storage tanks.
The choice of model is accessed with the EN_MIXMODEL property of a Tank node using
@ref EN_getnodevalue and @ref EN_setnodevalue.
*/
typedef enum {
EN_MIX1 = 0, //!< Complete mix model
EN_MIX2 = 1, //!< 2-compartment model
@@ -219,14 +331,20 @@ typedef enum {
} EN_MixingModel;
/// Hydraulic initialization options
/**
These options are used to initialize a new hydraulic analysis when @ref EN_initH is called.
*/
typedef enum {
EN_NOSAVE = 0, //!> Don't save hydraulics; don't re-initialize flows
EN_SAVE = 1, //!> Save hydraulics to file, don't re-initialize flows
EN_INITFLOW = 10, //!> Don't save hydraulics; re-initialize flows
EN_SAVE_AND_INIT = 11 //!> Save hydraulics; re-initialize flows
} EN_SaveOption;
EN_NOSAVE = 0, //!< Don't save hydraulics; don't re-initialize flows
EN_SAVE = 1, //!< Save hydraulics to file, don't re-initialize flows
EN_INITFLOW = 10, //!< Don't save hydraulics; re-initialize flows
EN_SAVE_AND_INIT = 11 //!< Save hydraulics; re-initialize flows
} EN_InitHydOption;
/// Pump curve types
/// Types of pump curves
/**
@ref EN_getpumptype returns one of these values when it is called.
*/
typedef enum {
EN_CONST_HP = 0, //!< Constant horsepower
EN_POWER_FUNC = 1, //!< Power function
@@ -234,72 +352,85 @@ typedef enum {
EN_NOCURVE = 3 //!< No curve
} EN_PumpType;
/// Data curve types
/// Types of data curves
/**
These are the different types of physical relationships that a data curve could
represent as returned by calling @ref EN_getcurvetype.
*/
typedef enum {
EN_V_CURVE = 0, //!< Tank volume curve
EN_P_CURVE = 1, //!< Pump characteristic curve
EN_E_CURVE = 2, //!< Pump efficiency curve
EN_H_CURVE = 3, //!< Valve head loss curve
EN_G_CURVE = 4 //!< General\default curve
EN_VOLUME_CURVE = 0, //!< Tank volume v. depth curve
EN_PUMP_CURVE = 1, //!< Pump head v. flow curve
EN_EFFIC_CURVE = 2, //!< Pump efficiency v. flow curve
EN_HLOSS_CURVE = 3, //!< Valve head loss v. flow curve
EN_GENERIC_CURVE = 4 //!< Generic curve
} EN_CurveType;
/// Deletion action types
/// Deletion action codes
/**
These codes are used in @ref EN_deletenode and @ref EN_deletelink to indicate what action
should be taken if the node or link being deleted appears in any simple or rule-based
controls.
*/
typedef enum {
EN_UNCONDITIONAL = 0, //!> Delete all controls that contain object
EN_CONDITIONAL = 1 //!> Cancel object deletion if contained in controls
EN_UNCONDITIONAL = 0, //!< Delete all controls that contain object
EN_CONDITIONAL = 1 //!< Cancel object deletion if contained in controls
} EN_ActionCodeType;
/// Rule object codes
/// Status reporting levels
/**
These choices specify the level of status reporting written to a project's report
file during a hydraulic analysis. The level is set using the @ref EN_setstatusreport function.
*/
typedef enum {
EN_R_NODE = 6,
EN_R_LINK = 7,
EN_R_SYSTEM = 8
EN_NO_REPORT = 0, //!< No status reporting
EN_NORMAL_REPORT = 1, //!< Normal level of status reporting
EN_FULL_REPORT = 2 //!< Full level of status reporting
} EN_StatusReport;
/// Network objects used in rule-based controls
typedef enum {
EN_R_NODE = 6, //!< Clause refers to a node
EN_R_LINK = 7, //!< Clause refers to a link
EN_R_SYSTEM = 8 //!< Clause refers to a system parameter (e.g., time)
} EN_RuleObject;
/// Rule variable codes
/// Object variables used in rule-based controls
typedef enum {
EN_R_DEMAND = 0,
EN_R_HEAD = 1,
EN_R_GRADE = 2,
EN_R_LEVEL = 3,
EN_R_PRESSURE = 4,
EN_R_FLOW = 5,
EN_R_STATUS = 6,
EN_R_SETTING = 7,
EN_R_POWER = 8,
EN_R_TIME = 9,
EN_R_CLOCKTIME = 10,
EN_R_FILLTIME = 11,
EN_R_DRAINTIME = 12
EN_R_DEMAND = 0, //!< Nodal demand
EN_R_HEAD = 1, //!< Nodal hydraulic head
EN_R_GRADE = 2, //!< Nodal hydraulic grade
EN_R_LEVEL = 3, //!< Tank water level
EN_R_PRESSURE = 4, //!< Nodal pressure
EN_R_FLOW = 5, //!< Link flow rate
EN_R_STATUS = 6, //!< Link status
EN_R_SETTING = 7, //!< Link setting
EN_R_POWER = 8, //!< Pump power output
EN_R_TIME = 9, //!< Elapsed simulation time
EN_R_CLOCKTIME = 10, //!< Time of day
EN_R_FILLTIME = 11, //!< Time to fill a tank
EN_R_DRAINTIME = 12 //!< Time to drain a tank
} EN_RuleVariable;
/// Rule operator types
/// Comparison operators used in rule-based controls
typedef enum {
EN_R_EQ = 0,
EN_R_NE = 1,
EN_R_LE = 2,
EN_R_GE = 3,
EN_R_LT = 4,
EN_R_GT = 5,
EN_R_IS = 6,
EN_R_NOT = 7,
EN_R_BELOW = 8,
EN_R_ABOVE = 9
EN_R_EQ = 0, //!< Equal to
EN_R_NE = 1, //!< Not equal
EN_R_LE = 2, //!< Less than or equal to
EN_R_GE = 3, //!< Greater than or equal to
EN_R_LT = 4, //!< Less than
EN_R_GT = 5, //!< Greater than
EN_R_IS = 6, //!< Is equal to
EN_R_NOT = 7, //!< Is not equal to
EN_R_BELOW = 8, //!< Is below
EN_R_ABOVE = 9 //!< Is above
} EN_RuleOperator;
/// Rule status types
/// Link status codes used in rule-based controls
typedef enum {
EN_R_IS_OPEN = 1,
EN_R_IS_CLOSED = 2,
EN_R_IS_ACTIVE = 3
EN_R_IS_OPEN = 1, //!< Link is open
EN_R_IS_CLOSED = 2, //!< Link is closed
EN_R_IS_ACTIVE = 3 //!< Control valve is active
} EN_RuleStatus;
/// Status report types
typedef enum {
EN_NO_REPORT = 0,
EN_NORMAL_REPORT = 1,
EN_FULL_REPORT = 2
} EN_StatusReport;
#endif //EPANET2_ENUMS_H

File diff suppressed because it is too large Load Diff

View File

@@ -7,10 +7,15 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/29/2018
Last Updated: 01/09/2019
******************************************************************************
*/
#ifndef __APPLE__
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#include <string.h>
#include "types.h"
#include "funcs.h"
@@ -46,13 +51,13 @@ void removetmpfiles()
********************************************************************/
int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3,
void (*pviewprog)(char *))
int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile,
const char *outFile, void (*pviewprog)(char *))
{
/*------------------------------------------------------------------------
** Input: f1 = name of EPANET formatted input file
** f2 = name of report file
** f3 = name of binary output file
** Input: inpFile = name of EPANET formatted input file
** rptFile = name of report file
** outFile = name of binary output file
** pviewprog = see note below
** Output: none
** Returns: error code
@@ -71,7 +76,7 @@ int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3,
// Run the project and record any warning
createtmpfiles();
errcode = EN_runproject(_defaultProject, f1, f2, f3, pviewprog);
errcode = EN_runproject(_defaultProject, inpFile, rptFile, outFile, pviewprog);
if (errcode < 100) warncode = errcode;
removetmpfiles();
@@ -80,20 +85,20 @@ int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3,
return errcode;
}
int DLLEXPORT ENinit(const char *f2, const char *f3, int UnitsType,
int HeadlossFormula)
int DLLEXPORT ENinit(const char *rptFile, const char *outFile, int unitsType,
int headlossType)
{
int errcode = 0;
createtmpfiles();
errcode = EN_init(_defaultProject, f2, f3, UnitsType, HeadlossFormula);
errcode = EN_init(_defaultProject, rptFile, outFile, unitsType, headlossType);
return errcode;
}
int DLLEXPORT ENopen(const char *f1, const char *f2, const char *f3)
int DLLEXPORT ENopen(const char *inpFile, const char *rptFile, const char *outFile)
{
int errcode = 0;
createtmpfiles();
errcode = EN_open(_defaultProject, f1, f2, f3);
errcode = EN_open(_defaultProject, inpFile, rptFile, outFile);
return errcode;
}
@@ -121,11 +126,11 @@ int DLLEXPORT ENsaveH() { return EN_saveH(_defaultProject); }
int DLLEXPORT ENopenH() { return EN_openH(_defaultProject); }
int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultProject, flag); }
int DLLEXPORT ENinitH(int initFlag) { return EN_initH(_defaultProject, initFlag); }
int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultProject, t); }
int DLLEXPORT ENrunH(long *currentTime) { return EN_runH(_defaultProject, currentTime); }
int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultProject, tstep); }
int DLLEXPORT ENnextH(long *tStep) { return EN_nextH(_defaultProject, tStep); }
int DLLEXPORT ENcloseH() { return EN_closeH(_defaultProject); }
@@ -149,13 +154,13 @@ int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultProject); }
int DLLEXPORT ENopenQ() { return EN_openQ(_defaultProject); }
int DLLEXPORT ENinitQ(int saveflag) { return EN_initQ(_defaultProject, saveflag); }
int DLLEXPORT ENinitQ(int saveFlag) { return EN_initQ(_defaultProject, saveFlag); }
int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultProject, t); }
int DLLEXPORT ENrunQ(long *currentTime) { return EN_runQ(_defaultProject, currentTime); }
int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultProject, tstep); }
int DLLEXPORT ENnextQ(long *tStep) { return EN_nextQ(_defaultProject, tStep); }
int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultProject, tleft); }
int DLLEXPORT ENstepQ(long *timeLeft) { return EN_stepQ(_defaultProject, timeLeft); }
int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultProject); }
@@ -171,28 +176,31 @@ int DLLEXPORT ENreport() { return EN_report(_defaultProject); }
int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultProject); }
int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultProject, s); }
int DLLEXPORT ENsetreport(char *format) { return EN_setreport(_defaultProject, format); }
int DLLEXPORT ENsetstatusreport(int code)
int DLLEXPORT ENsetstatusreport(int level)
{
return EN_setstatusreport(_defaultProject, code);
return EN_setstatusreport(_defaultProject, level);
}
int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); }
int DLLEXPORT ENgetversion(int *version) { return EN_getversion(version); }
int DLLEXPORT ENgetcount(int code, int *count)
int DLLEXPORT ENgetcount(int object, int *count)
{
return EN_getcount(_defaultProject, (EN_CountType)code, count);
return EN_getcount(_defaultProject, object, count);
}
int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n)
int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen)
{
return EN_geterror(errcode, errmsg, n);
return EN_geterror(errcode, errmsg, maxLen);
}
int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetstatistic(int type, EN_API_FLOAT_TYPE *value)
{
return EN_getstatistic(_defaultProject, code, value);
double v = 0.0;
int errcode = EN_getstatistic(_defaultProject, type, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
/********************************************************************
@@ -201,45 +209,54 @@ int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value)
********************************************************************/
int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetoption(int option, EN_API_FLOAT_TYPE *value)
{
return EN_getoption(_defaultProject, (EN_Option)code, value);
double v = 0.0;
int errcode = EN_getoption(_defaultProject, option, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v)
int DLLEXPORT ENsetoption(int option, EN_API_FLOAT_TYPE value)
{
return EN_setoption(_defaultProject, code, v);
return EN_setoption(_defaultProject, option, value);
}
int DLLEXPORT ENgetflowunits(int *code) { return EN_getflowunits(_defaultProject, code); }
int DLLEXPORT ENsetflowunits(int code) { return EN_setflowunits(_defaultProject, code); }
int DLLEXPORT ENgettimeparam(int code, long *value)
int DLLEXPORT ENgetflowunits(int *units)
{
return EN_gettimeparam(_defaultProject, code, value);
return EN_getflowunits(_defaultProject, units);
}
int DLLEXPORT ENsettimeparam(int code, long value)
int DLLEXPORT ENsetflowunits(int units)
{
return EN_settimeparam(_defaultProject, code, value);
return EN_setflowunits(_defaultProject, units);
}
int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits,
int *tracenode)
int DLLEXPORT ENgettimeparam(int param, long *value)
{
return EN_getqualinfo(_defaultProject, qualcode, chemname, chemunits, tracenode);
return EN_gettimeparam(_defaultProject, param, value);
}
int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode)
int DLLEXPORT ENsettimeparam(int param, long value)
{
return EN_getqualtype(_defaultProject, qualcode, tracenode);
return EN_settimeparam(_defaultProject, param, value);
}
int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits,
char *tracenode)
int DLLEXPORT ENgetqualinfo(int *qualType, char *chemName, char *chemUnits,
int *traceNode)
{
return EN_setqualtype(_defaultProject, qualcode, chemname, chemunits, tracenode);
return EN_getqualinfo(_defaultProject, qualType, chemName, chemUnits, traceNode);
}
int DLLEXPORT ENgetqualtype(int *qualType, int *traceNode)
{
return EN_getqualtype(_defaultProject, qualType, traceNode);
}
int DLLEXPORT ENsetqualtype(int qualType, char *chemName, char *chemUnits,
char *traceNode)
{
return EN_setqualtype(_defaultProject, qualType, chemName, chemUnits, traceNode);
}
/********************************************************************
@@ -248,7 +265,7 @@ int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits,
********************************************************************/
int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType)
int DLLEXPORT ENaddnode(char *id, int nodeType)
{
return EN_addnode(_defaultProject, id, nodeType);
}
@@ -273,24 +290,46 @@ int DLLEXPORT ENsetnodeid(int index, char *newid)
return EN_setnodeid(_defaultProject, index, newid);
}
int DLLEXPORT ENgetnodetype(int index, int *code)
int DLLEXPORT ENgetnodetype(int index, int *nodeType)
{
return EN_getnodetype(_defaultProject, index, code);
return EN_getnodetype(_defaultProject, index, nodeType);
}
int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetnodevalue(int index, int property, EN_API_FLOAT_TYPE *value)
{
return EN_getnodevalue(_defaultProject, index, code, value);
double v = 0.0;
int errcode = EN_getnodevalue(_defaultProject, index, property, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v)
int DLLEXPORT ENsetnodevalue(int index, int property, EN_API_FLOAT_TYPE value)
{
return EN_setnodevalue(_defaultProject, index, code, v);
return EN_setnodevalue(_defaultProject, index, property, value);
}
int DLLEXPORT ENsetjuncdata(int index, EN_API_FLOAT_TYPE elev, EN_API_FLOAT_TYPE dmnd,
char *dmndpat)
{
return EN_setjuncdata(_defaultProject, index, elev, dmnd, dmndpat);
}
int DLLEXPORT ENsettankdata(int index, EN_API_FLOAT_TYPE elev,
EN_API_FLOAT_TYPE initlvl, EN_API_FLOAT_TYPE minlvl,
EN_API_FLOAT_TYPE maxlvl, EN_API_FLOAT_TYPE diam,
EN_API_FLOAT_TYPE minvol, char *volcurve)
{
return EN_settankdata(_defaultProject, index, elev, initlvl, minlvl, maxlvl,
diam, minvol, volcurve);
}
int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
{
return EN_getcoord(_defaultProject, index, x, y);
double xx = 0.0, yy = 0.0;
int errcode = EN_getcoord(_defaultProject, index, &xx, &yy);
*x = (EN_API_FLOAT_TYPE)xx;
*y = (EN_API_FLOAT_TYPE)yy;
return errcode;
}
int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
@@ -304,16 +343,21 @@ int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
********************************************************************/
int DLLEXPORT ENgetdemandmodel(int *type, EN_API_FLOAT_TYPE *pmin,
EN_API_FLOAT_TYPE *preq, EN_API_FLOAT_TYPE *pexp)
int DLLEXPORT ENgetdemandmodel(int *model, EN_API_FLOAT_TYPE *pmin,
EN_API_FLOAT_TYPE *preq, EN_API_FLOAT_TYPE *pexp)
{
return EN_getdemandmodel(_defaultProject, type, pmin, preq, pexp);
double pmin2 = 0.0, preq2 = 0.0, pexp2 = 0.0;
int errcode = EN_getdemandmodel(_defaultProject, model, &pmin2, &preq2, &pexp2);
*pmin = (EN_API_FLOAT_TYPE)pmin2;
*preq = (EN_API_FLOAT_TYPE)preq2;
*pexp = (EN_API_FLOAT_TYPE)pexp2;
return errcode;
}
int DLLEXPORT ENsetdemandmodel(int type, EN_API_FLOAT_TYPE pmin,
EN_API_FLOAT_TYPE preq, EN_API_FLOAT_TYPE pexp)
int DLLEXPORT ENsetdemandmodel(int model, EN_API_FLOAT_TYPE pmin,
EN_API_FLOAT_TYPE preq, EN_API_FLOAT_TYPE pexp)
{
return EN_setdemandmodel(_defaultProject, type, pmin, preq, pexp);
return EN_setdemandmodel(_defaultProject, model, pmin, preq, pexp);
}
int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands)
@@ -321,34 +365,39 @@ int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands)
return EN_getnumdemands(_defaultProject, nodeIndex, numDemands);
}
int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand)
int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIndex,
EN_API_FLOAT_TYPE *baseDemand)
{
return EN_getbasedemand(_defaultProject, nodeIndex, demandIdx, baseDemand);
double bd2 = 0.0;
int errcode = EN_getbasedemand(_defaultProject, nodeIndex, demandIndex, &bd2);
*baseDemand = (EN_API_FLOAT_TYPE)bd2;
return errcode;
}
int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand)
int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIndex,
EN_API_FLOAT_TYPE baseDemand)
{
return EN_setbasedemand(_defaultProject, nodeIndex, demandIdx, baseDemand);
return EN_setbasedemand(_defaultProject, nodeIndex, demandIndex, baseDemand);
}
int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIdx, int patIndex)
int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIndex, int patIndex)
{
return EN_setdemandpattern(_defaultProject, nodeIndex, demandIdx, patIndex);
return EN_setdemandpattern(_defaultProject, nodeIndex, demandIndex, patIndex);
}
int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx)
int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIdx)
{
return EN_getdemandpattern(_defaultProject, nodeIndex, demandIdx, pattIdx);
return EN_getdemandpattern(_defaultProject, nodeIndex, demandIndex, pattIdx);
}
int DLLEXPORT ENgetdemandname(int nodeIndex, int demandIdx, char *demandName)
int DLLEXPORT ENgetdemandname(int nodeIndex, int demandIndex, char *demandName)
{
return EN_getdemandname(_defaultProject, nodeIndex, demandIdx, demandName);
return EN_getdemandname(_defaultProject, nodeIndex, demandIndex, demandName);
}
int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIdx, char *demandName)
int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIndex, char *demandName)
{
return EN_setdemandname(_defaultProject, nodeIndex, demandIdx, demandName);
return EN_setdemandname(_defaultProject, nodeIndex, demandIndex, demandName);
}
/********************************************************************
@@ -357,7 +406,7 @@ int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIdx, char *demandName)
********************************************************************/
int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, char *toNode)
int DLLEXPORT ENaddlink(char *id, int linkType, char *fromNode, char *toNode)
{
return EN_addlink(_defaultProject, id, linkType, fromNode, toNode);
}
@@ -382,14 +431,14 @@ int DLLEXPORT ENsetlinkid(int index, char *newid)
return EN_setlinkid(_defaultProject, index, newid);
}
int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code)
int DLLEXPORT ENgetlinktype(int index, int *linkType)
{
return EN_getlinktype(_defaultProject, index, code);
return EN_getlinktype(_defaultProject, index, linkType);
}
int DLLEXPORT ENsetlinktype(int *index, EN_LinkType type, int actionCode)
int DLLEXPORT ENsetlinktype(int *index, int linkType, int actionCode)
{
return EN_setlinktype(_defaultProject, index, type, actionCode);
return EN_setlinktype(_defaultProject, index, linkType, actionCode);
}
int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2)
@@ -402,35 +451,45 @@ int DLLEXPORT ENsetlinknodes(int index, int node1, int node2)
return EN_setlinknodes(_defaultProject, index, node1, node2);
}
int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetlinkvalue(int index, int property, EN_API_FLOAT_TYPE *value)
{
return EN_getlinkvalue(_defaultProject, index, (EN_LinkProperty)code, value);
double v = 0.0;
int errcode = EN_getlinkvalue(_defaultProject, index, property, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v)
int DLLEXPORT ENsetlinkvalue(int index, int property, EN_API_FLOAT_TYPE value)
{
return EN_setlinkvalue(_defaultProject, index, code, v);
return EN_setlinkvalue(_defaultProject, index, property, value);
}
int DLLEXPORT ENsetpipedata(int index, EN_API_FLOAT_TYPE length,
EN_API_FLOAT_TYPE diam, EN_API_FLOAT_TYPE rough, EN_API_FLOAT_TYPE mloss)
{
return EN_setpipedata(_defaultProject, index, length, diam, rough, mloss);
}
/********************************************************************
Pump Functions
********************************************************************/
int DLLEXPORT ENgetpumptype(int index, int *type)
int DLLEXPORT ENgetpumptype(int linkIndex, int *pumpType)
{
return EN_getpumptype(_defaultProject, index, type);
return EN_getpumptype(_defaultProject, linkIndex, pumpType);
}
int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex)
int DLLEXPORT ENgetheadcurveindex(int linkIndex, int *curveIndex)
{
return EN_getheadcurveindex(_defaultProject, index, curveindex);
return EN_getheadcurveindex(_defaultProject, linkIndex, curveIndex);
}
int DLLEXPORT ENsetheadcurveindex(int index, int curveindex)
int DLLEXPORT ENsetheadcurveindex(int linkIndex, int curveIndex)
{
return EN_setheadcurveindex(_defaultProject, index, curveindex);
return EN_setheadcurveindex(_defaultProject, linkIndex, curveIndex);
}
/********************************************************************
@@ -461,7 +520,10 @@ int DLLEXPORT ENgetpatternlen(int index, int *len)
int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value)
{
return EN_getpatternvalue(_defaultProject, index, period, value);
double v = 0.0;
int errcode = EN_getpatternvalue(_defaultProject, index, period, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value)
@@ -471,12 +533,25 @@ int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value)
int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value)
{
return EN_getaveragepatternvalue(_defaultProject, index, value);
double v;
int errcode = EN_getaveragepatternvalue(_defaultProject, index, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n)
int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *values, int len)
{
return EN_setpattern(_defaultProject, index, f, n);
double *v = NULL;
int i, errcode;
v = (double *)calloc(len, sizeof(double));
if (v)
{
for (i = 0; i < len; i++) v[i] = values[i];
errcode = EN_setpattern(_defaultProject, index, v, len);
}
else errcode = 101;
free(v);
return errcode;
}
/********************************************************************
@@ -505,32 +580,67 @@ int DLLEXPORT ENgetcurvelen(int index, int *len)
return EN_getcurvelen(_defaultProject, index, len);
}
int DLLEXPORT ENgetcurvetype(int curveindex, int *type)
int DLLEXPORT ENgetcurvetype(int index, int *type)
{
return EN_getcurvetype(_defaultProject, curveindex, type);
return EN_getcurvetype(_defaultProject, index, type);
}
int DLLEXPORT ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y)
int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y)
{
return EN_getcurvevalue(_defaultProject, index, pnt, x, y);
double xx = 0.0, yy = 0.0;
int errcode = EN_getcurvevalue(_defaultProject, curveIndex, pointIndex, &xx, &yy);
*x = (EN_API_FLOAT_TYPE)xx;
*y = (EN_API_FLOAT_TYPE)yy;
return errcode;
}
int DLLEXPORT ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x,
EN_API_FLOAT_TYPE y)
int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x,
EN_API_FLOAT_TYPE y)
{
return EN_setcurvevalue(_defaultProject, index, pnt, x, y);
return EN_setcurvevalue(_defaultProject, curveIndex, pointIndex, x, y);
}
int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues,
EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
int DLLEXPORT ENgetcurve(int index, char *id, int *nPoints,
EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
{
return EN_getcurve(_defaultProject, curveIndex, id, nValues, xValues, yValues);
int i;
Network *net = &_defaultProject->network;
Scurve *curve;
if (index <= 0 || index > net->Ncurves) return 206;
curve = &net->Curve[index];
strncpy(id, curve->ID, MAXID);
*nPoints = curve->Npts;
for (i = 0; i < curve->Npts; i++)
{
*xValues[i] = (EN_API_FLOAT_TYPE)curve->X[i];
*yValues[i] = (EN_API_FLOAT_TYPE)curve->Y[i];
}
return 0;
}
int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n)
int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *xValues,
EN_API_FLOAT_TYPE *yValues, int nPoints)
{
return EN_setcurve(_defaultProject, index, x, y, n);
double *xx = NULL;
double *yy = NULL;
int i, errcode;
xx = (double *)calloc(nPoints, sizeof(double));
yy = (double *)calloc(nPoints, sizeof(double));
if (xx && yy)
{
for (i = 0; i < nPoints; i++)
{
xx[i] = xValues[i];
yy[i] = yValues[i];
}
errcode = EN_setcurve(_defaultProject, index, xx, yy, nPoints);
}
else errcode = 101;
free(xx);
free(yy);
return errcode;
}
/********************************************************************
@@ -539,27 +649,34 @@ int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y,
********************************************************************/
int DLLEXPORT ENaddcontrol(int *cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting,
int nindex, EN_API_FLOAT_TYPE level)
int DLLEXPORT ENaddcontrol(int type, int linkIndex, EN_API_FLOAT_TYPE setting,
int nodeIndex, EN_API_FLOAT_TYPE level, int *index)
{
return EN_addcontrol(_defaultProject, cindex, ctype, lindex, setting, nindex, level);
return EN_addcontrol(_defaultProject, type, linkIndex, setting, nodeIndex,
level, index);
}
int DLLEXPORT ENdeletecontrol(int cindex)
int DLLEXPORT ENdeletecontrol(int index)
{
return EN_deletecontrol(_defaultProject, cindex);
return EN_deletecontrol(_defaultProject, index);
}
int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, EN_API_FLOAT_TYPE *setting,
int *nindex, EN_API_FLOAT_TYPE *level)
int DLLEXPORT ENgetcontrol(int index, int *type, int *linkIndex,
EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level)
{
return EN_getcontrol(_defaultProject, cindex, ctype, lindex, setting, nindex, level);
double setting2 = 0.0, level2 = 0.0;
int errcode = EN_getcontrol(_defaultProject, index, type, linkIndex, &setting2,
nodeIndex, &level2);
*setting = (EN_API_FLOAT_TYPE)setting2;
*level = (EN_API_FLOAT_TYPE)level2;
return errcode;
}
int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting,
int nindex, EN_API_FLOAT_TYPE level)
int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex,
EN_API_FLOAT_TYPE setting, int nodeIndex, EN_API_FLOAT_TYPE level)
{
return EN_setcontrol(_defaultProject, cindex, ctype, lindex, setting, nindex, level);
return EN_setcontrol(_defaultProject, index, type, linkIndex, setting,
nodeIndex, level);
}
/********************************************************************
@@ -578,10 +695,14 @@ int DLLEXPORT ENdeleterule(int index)
return EN_deleterule(_defaultProject, index);
}
int DLLEXPORT ENgetrule(int index, int *nPremises, int *nThenActions, int *nElseActions,
EN_API_FLOAT_TYPE *priority)
int DLLEXPORT ENgetrule(int index, int *nPremises, int *nThenActions,
int *nElseActions, EN_API_FLOAT_TYPE *priority)
{
return EN_getrule(_defaultProject, index, nPremises, nThenActions, nElseActions, priority);
double priority2 = 0.0;
int errcode = EN_getrule(_defaultProject, index, nPremises, nThenActions,
nElseActions, &priority2);
*priority = (EN_API_FLOAT_TYPE)priority2;
return errcode;
}
int DLLEXPORT ENgetruleID(int index, char* id)
@@ -589,17 +710,19 @@ int DLLEXPORT ENgetruleID(int index, char* id)
return EN_getruleID(_defaultProject, index, id);
}
int DLLEXPORT ENgetpremise(int ruleIndex, int premiseIndex, int *logop,
int *object, int *objIndex, int *variable,
int *relop, int *status, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetpremise(int ruleIndex, int premiseIndex, int *logop, int *object,
int *objIndex, int *variable, int *relop, int *status,
EN_API_FLOAT_TYPE *value)
{
return EN_getpremise(_defaultProject, ruleIndex, premiseIndex, logop, object,
objIndex, variable, relop, status, value);
double v = 0.0;
int errcode = EN_getpremise(_defaultProject, ruleIndex, premiseIndex, logop,
object, objIndex, variable, relop, status, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetpremise(int ruleIndex, int premiseIndex, int logop,
int object, int objIndex, int variable, int relop,
int status, EN_API_FLOAT_TYPE value)
int DLLEXPORT ENsetpremise(int ruleIndex, int premiseIndex, int logop, int object,
int objIndex, int variable, int relop, int status, EN_API_FLOAT_TYPE value)
{
return EN_setpremise(_defaultProject, ruleIndex, premiseIndex, logop, object,
objIndex, variable, relop, status, value);
@@ -621,28 +744,34 @@ int DLLEXPORT ENsetpremisevalue(int ruleIndex, int premiseIndex, EN_API_FLOAT_TY
}
int DLLEXPORT ENgetthenaction(int ruleIndex, int actionIndex, int *linkIndex,
int *status, EN_API_FLOAT_TYPE *setting)
int *status, EN_API_FLOAT_TYPE *setting)
{
return EN_getthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);
double setting2 = 0.0;
int errcode = EN_getthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, &setting2);
*setting = (EN_API_FLOAT_TYPE)setting2;
return errcode;
}
int DLLEXPORT ENsetthenaction(int ruleIndex, int actionIndex, int linkIndex,
int status, EN_API_FLOAT_TYPE setting)
int status, EN_API_FLOAT_TYPE setting)
{
return EN_setthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);
}
int DLLEXPORT ENgetelseaction(int ruleIndex, int actionIndex, int *linkIndex,
int *status, EN_API_FLOAT_TYPE *setting)
int *status, EN_API_FLOAT_TYPE *setting)
{
return EN_getelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);
double setting2 = 0.0;
int errcode = EN_getelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, &setting2);
*setting = (EN_API_FLOAT_TYPE)setting2;
return errcode;
}
int DLLEXPORT ENsetelseaction(int ruleIndex, int actionIndex, int linkIndex,
int status, EN_API_FLOAT_TYPE setting)
int status, EN_API_FLOAT_TYPE setting)
{
return EN_setelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);

View File

@@ -8,7 +8,6 @@ DAT(105,"water quality solver not opened")
DAT(106,"no results saved to report on")
DAT(107,"hydraulics supplied from external file")
DAT(108,"cannot use external file while hydraulics solver is active")
DAT(109,"cannot change time parameter when solver is active")
DAT(110,"cannot solve network hydraulic equations")
DAT(120,"cannot solve water quality transport equations")
@@ -23,9 +22,7 @@ DAT(204,"undefined link")
DAT(205,"undefined time pattern")
DAT(206,"undefined curve")
DAT(207,"attempt to control CV/GPV link")
DAT(208,"reference to undefined node")
DAT(209,"illegal node property value")
DAT(210,"reference to undefined link")
DAT(211,"illegal link property value")
DAT(212,"undefined trace node")
DAT(213,"invalid option value")

View File

@@ -100,6 +100,8 @@ int hydsolve(Project *pr, int *iter, double *relerr)
// Initialize status checking & relaxation factor
nextcheck = hyd->CheckFreq;
hyd->RelaxFactor = 1.0;
hydbal.maxheaderror = 0.0;
hydbal.maxflowchange = 0.0;
// Repeat iterations until convergence or trial limit is exceeded.
// (ExtraIter used to increase trials in case of status cycling.)
@@ -121,7 +123,7 @@ int hydsolve(Project *pr, int *iter, double *relerr)
// Matrix ill-conditioning problem - if control valve causing problem,
// fix its status & continue, otherwise quit with no solution.
if (errcode > 0)
{
{
if (badvalve(pr, sm->Order[errcode])) continue;
else break;
}
@@ -360,7 +362,6 @@ double newflows(Project *pr, Hydbalance *hbal)
**----------------------------------------------------------------
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
double dqsum, // Network flow change

View File

@@ -102,7 +102,6 @@ int saveinpfile(Project *pr, const char *fname)
Times *time = &pr->times;
int i, j, n;
int errcode;
double d, kc, ke, km, ucf;
char s[MAXLINE + 1], s1[MAXLINE + 1], s2[MAXLINE + 1];
Pdemand demand;
@@ -116,7 +115,7 @@ int saveinpfile(Project *pr, const char *fname)
Scurve *curve;
// Open the new text file
if ((f = fopen(fname, "wt")) == NULL) return (308);
if ((f = fopen(fname, "wt")) == NULL) return 302;
// Write [TITLE] section
fprintf(f, s_TITLE);
@@ -451,7 +450,7 @@ int saveinpfile(Project *pr, const char *fname)
for (i = 1; i <= net->Nrules; i++)
{
fprintf(f, "\nRULE %s", pr->network.Rule[i].label);
errcode = writerule(pr, f, i); // see RULES.C
writerule(pr, f, i); // see RULES.C
fprintf(f, "\n");
}
@@ -489,7 +488,7 @@ int saveinpfile(Project *pr, const char *fname)
fprintf(f, s_MIXING);
for (i = 1; i <= net->Ntanks; i++)
{
Stank *tank = &net->Tank[i];
tank = &net->Tank[i];
if (tank->A == 0.0) continue;
fprintf(f, "\n %-31s %-8s %12.4f", net->Node[tank->Node].ID,
MixTxt[tank->MixModel], (tank->V1max / tank->Vmax));
@@ -719,7 +718,7 @@ int saveinpfile(Project *pr, const char *fname)
j = 0;
for (i = 1; i <= net->Nlinks; i++)
{
Slink *link = &net->Link[i];
link = &net->Link[i];
if (link->Rpt == 1)
{
if (j % 5 == 0) fprintf(f, "\n LINKS ");

View File

@@ -7,7 +7,7 @@ Description: reads and interprets network data from an EPANET input file
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 12/15/2018
Last Updated: 01/01/2019
******************************************************************************
*/
@@ -381,7 +381,7 @@ int updatepumpparams(Project *pr, int pumpindex)
curveindex = pump->Hcurve;
if (curveindex == 0) return 226;
curve = &net->Curve[curveindex];
curve->Type = P_CURVE;
curve->Type = PUMP_CURVE;
npts = curve->Npts;
// Generic power function curve

View File

@@ -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: 12/15/2018
Last Updated: 01/01/2019
******************************************************************************
*/
@@ -45,7 +45,7 @@ static int getpumpcurve(Project *, int);
static void changestatus(Network *, int, StatusType, double);
static int setError(Parser *, int, int);
int setError(Parser *parser, int tokindex, int errcode)
/*
**--------------------------------------------------------------
@@ -85,7 +85,7 @@ int juncdata(Project *pr)
Pdemand demand; // demand record
STmplist *patlist; // list of demands
Snode *node;
// Add new junction to data base
n = parser->Ntokens;
if (net->Nnodes == parser->MaxNodes) return 200;
@@ -117,7 +117,7 @@ int juncdata(Project *pr)
node->Type = JUNCTION;
strcpy(node->Comment, parser->Comment);
// create a demand record, even if no demand is specified here.
demand = (struct Sdemand *) malloc(sizeof(struct Sdemand));
if (demand == NULL) return 101;
@@ -162,7 +162,7 @@ int tankdata(Project *pr)
STmplist *tmplist;
Snode *node;
Stank *tank;
// Add new tank to data base
n = parser->Ntokens;
if (net->Ntanks == parser->MaxTanks ||
@@ -189,7 +189,7 @@ int tankdata(Project *pr)
}
}
else if (n < 6) return 201;
// Tank is a storage tank
else
{
@@ -205,7 +205,7 @@ int tankdata(Project *pr)
tmplist = getlistitem(parser->Tok[7], parser->Curvelist);
if (tmplist == NULL) return setError(parser, 7, 206);
curve = tmplist->i;
net->Curve[curve].Type = V_CURVE;
net->Curve[curve].Type = VOLUME_CURVE;
}
if (initlevel < 0.0) return setError(parser, 2, 209);
if (minlevel < 0.0) return setError(parser, 3, 209);
@@ -232,7 +232,7 @@ int tankdata(Project *pr)
tank->A = diam;
tank->Pat = pattern;
tank->Kb = MISSING;
//*******************************************************************
// NOTE: The min, max, & initial volumes set here are based on a
// nominal tank diameter. They will be modified in INPUT1.C if
@@ -275,7 +275,7 @@ int pipedata(Project *pr)
LinkType type = PIPE; // Link type
StatusType status = OPEN; // Link status
Slink *link;
// Add new pipe to data base
n = parser->Ntokens;
if (net->Nlinks == parser->MaxLinks) return 200;
@@ -354,10 +354,10 @@ int pumpdata(Project *pr)
Network *net = &pr->network;
Parser *parser = &pr->parser;
int j,
int j,
j1, // Start-node index
j2, // End-node index
m, n; // # data items
m, n; // # data items
double y;
STmplist *tmplist; // Temporary list
Slink *link;
@@ -380,7 +380,7 @@ int pumpdata(Project *pr)
// Save pump data
link = &net->Link[net->Nlinks];
pump = &net->Pump[net->Npumps];
link->N1 = j1;
link->N2 = j2;
link->Diam = 0;
@@ -426,25 +426,25 @@ int pumpdata(Project *pr)
if (y <= 0.0) return setError(parser, m, 202);
pump->Ptype = CONST_HP;
link->Km = y;
}
}
else if (match(parser->Tok[m - 1], w_HEAD)) // Custom pump curve
{
tmplist = getlistitem(parser->Tok[m], parser->Curvelist);
if (tmplist == NULL) return setError(parser, m, 206);
pump->Hcurve = tmplist->i;
}
}
else if (match(parser->Tok[m - 1], w_PATTERN)) // Speed/status pattern
{
tmplist = getlistitem(parser->Tok[m], parser->Patlist);
if (tmplist == NULL) return setError(parser, m, 205);
pump->Upat = tmplist->i;
}
}
else if (match(parser->Tok[m - 1], w_SPEED)) // Speed setting
{
if (!getfloat(parser->Tok[m], &y)) return setError(parser, m, 202);
if (y < 0.0) return setError(parser, m, 211);
link->Kc = y;
}
}
else return 201;
m = m + 2; // Move to next keyword token
}
@@ -476,7 +476,7 @@ int valvedata(Project *pr)
lcoeff = 0.0; // Minor loss coeff.
STmplist *tmplist; // Temporary list
Slink *link;
// Add new valve to data base
n = parser->Ntokens;
if (net->Nlinks == parser->MaxLinks ||
@@ -499,16 +499,16 @@ int valvedata(Project *pr)
else if (match(parser->Tok[4], w_GPV)) type = GPV;
else return setError(parser, 4, 213);
if (!getfloat(parser->Tok[3], &diam)) return setError(parser, 3, 202); 202;
if (!getfloat(parser->Tok[3], &diam)) return setError(parser, 3, 202);
if (diam <= 0.0) return setError(parser, 3, 211);
// Find headloss curve for GPV
// Find headloss curve for GPV
if (type == GPV)
{
{
tmplist = getlistitem(parser->Tok[5], parser->Curvelist);
if (tmplist == NULL) return setError(parser, 5, 206);
setting = tmplist->i;
net->Curve[tmplist->i].Type = H_CURVE;
net->Curve[tmplist->i].Type = HLOSS_CURVE;
status = OPEN;
}
else if (!getfloat(parser->Tok[5], &setting)) return setError(parser, 5, 202);
@@ -532,7 +532,7 @@ int valvedata(Project *pr)
link->Km = lcoeff;
link->Kb = 0.0;
link->Kw = 0.0;
link->Type = type;
link->Type = type;
link->Status = status;
link->Rpt = 0;
strcpy(link->Comment, parser->Comment);
@@ -658,11 +658,11 @@ int coordata(Project *pr)
int j;
double x, y;
Snode *node;
// Check for valid node ID
if (parser->Ntokens < 3) return 201;
if ((j = findnode(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
// Check for valid data
if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
@@ -768,7 +768,7 @@ int controldata(Project *pr)
{
Network *net = &pr->network;
Parser *parser = &pr->parser;
int i = 0, // Node index
k, // Link index
n; // # data items
@@ -779,7 +779,7 @@ int controldata(Project *pr)
ControlType ctltype; // Control type
LinkType linktype; // Link type
Scontrol *control;
// Check for sufficient number of input tokens
n = parser->Ntokens;
if (n < 6) return 201;
@@ -878,7 +878,7 @@ int sourcedata(Project *pr)
{
Network *net = &pr->network;
Parser *parser = &pr->parser;
int i, // Token with quality value
j, // Node index
n, // # data items
@@ -912,7 +912,7 @@ int sourcedata(Project *pr)
// Parse optional source time pattern
if (n > i + 1 && strlen(parser->Tok[i + 1]) > 0 &&
strcmp(parser->Tok[i + 1], "*") != 0)
strcmp(parser->Tok[i + 1], "*") != 0)
{
patlist = getlistitem(parser->Tok[i + 1], parser->Patlist);
if (patlist == NULL) return setError(parser, i+1, 205);
@@ -921,7 +921,7 @@ int sourcedata(Project *pr)
// Destroy any existing source assigned to node
if (net->Node[j].S != NULL) free(net->Node[j].S);
// Create a new source & assign it to the node
source = (struct Ssource *)malloc(sizeof(struct Ssource));
if (source == NULL) return 101;
@@ -946,7 +946,7 @@ int emitterdata(Project *pr)
{
Network *net = &pr->network;
Parser *parser = &pr->parser;
int j, // Node index
n; // # data items
double k; // Flow coeff.
@@ -984,7 +984,7 @@ int qualdata(Project *pr)
long i, i1, i2;
double c0;
Snode *Node = net->Node;
if (net->Nnodes == 0) return setError(parser, 0, 203); // No nodes defined yet
n = parser->Ntokens;
if (n < 2) return 0;
@@ -1016,7 +1016,7 @@ int qualdata(Project *pr)
if (i >= i1 && i <= i2) Node[j].C0 = c0;
}
}
// Otherwise use lexicographic comparison
else
{
@@ -1058,7 +1058,7 @@ int reactdata(Project *pr)
long i, i1, i2;
double y;
// Skip line if insufficient data
// Skip line if insufficient data
n = parser->Ntokens;
if (n < 3) return 0;
@@ -1093,7 +1093,7 @@ int reactdata(Project *pr)
qual->Climit = y;
return 0;
}
// Keyword is GLOBAL
if (match(parser->Tok[0], w_GLOBAL))
{
@@ -1125,7 +1125,7 @@ int reactdata(Project *pr)
if ((j = findnode(net,parser->Tok[1])) <= net->Njuncs) return 0;
net->Tank[j - net->Njuncs].Kb = y;
}
// Case where a numerical range of tank IDs is specified
else if ((i1 = atol(parser->Tok[1])) > 0 &&
(i2 = atol(parser->Tok[2])) > 0)
@@ -1160,7 +1160,7 @@ int reactdata(Project *pr)
if (item == 1) net->Link[j].Kb = y;
else net->Link[j].Kw = y;
}
// Case where a numerical range of link IDs is specified
else if ((i1 = atol(parser->Tok[1])) > 0 &&
(i2 = atol(parser->Tok[2])) > 0)
@@ -1168,14 +1168,14 @@ int reactdata(Project *pr)
for (j = 1; j <= net->Nlinks; j++)
{
i = atol(net->Link[j].ID);
if (i >= i1 && i <= i2)
if (i >= i1 && i <= i2)
{
if (item == 1) net->Link[j].Kb = y;
else net->Link[j].Kw = y;
}
}
}
// Case where a general range of link IDs is specified
else for (j = 1; j <= net->Nlinks; j++)
{
@@ -1210,7 +1210,7 @@ int mixingdata(Project *pr)
m, // Type of mixing model
n; // Number of data items
double v; // Mixing zone volume fraction
// Check for valid data
if (net->Nnodes == 0) return setError(parser, 0, 203);
n = parser->Ntokens;
@@ -1254,7 +1254,7 @@ int statusdata(Project *pr)
long i, i1, i2;
double y = 0.0;
char status = ACTIVE;
if (net->Nlinks == 0) return setError(parser, 0, 204);
n = parser->Ntokens - 1;
if (n < 1) return 201;
@@ -1272,7 +1272,7 @@ int statusdata(Project *pr)
if (n == 1)
{
if ((j = findlink(net, parser->Tok[0])) == 0) return setError(parser, 0, 204);
// Cannot change status of a Check Valve
if (net->Link[j].Type == CVPIPE) return setError(parser, 0, 207);
@@ -1291,7 +1291,7 @@ int statusdata(Project *pr)
if (i >= i1 && i <= i2) changestatus(net, j, status, y);
}
}
// A range of general link ID's was supplied
else for (j = 1; j <= net->Nlinks; j++)
{
@@ -1319,14 +1319,14 @@ int energydata(Project *pr)
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Parser *parser = &pr->parser;
int j, k, n;
double y;
STmplist *listitem;
Slink *Link = net->Link;
Spump *Pump = net->Pump;
// Check for sufficient data
n = parser->Ntokens;
if (n < 3) return 201;
@@ -1345,7 +1345,7 @@ int energydata(Project *pr)
{
j = 0;
}
// First keyword is PUMP (remaining data refer to a specific pump)
else if (match(parser->Tok[0], w_PUMP))
{
@@ -1366,7 +1366,7 @@ int energydata(Project *pr)
else Pump[j].Ecost = y;
return 0;
}
// Price PATTERN being set
else if (match(parser->Tok[n - 2], w_PATTERN))
{
@@ -1376,7 +1376,7 @@ int energydata(Project *pr)
else Pump[j].Epat = listitem->i;
return 0;
}
// Pump EFFIC being set
else if (match(parser->Tok[n - 2], w_EFFIC))
{
@@ -1389,9 +1389,9 @@ int energydata(Project *pr)
else
{
listitem = getlistitem(parser->Tok[n - 1], parser->Curvelist);
if (listitem == NULL) return setError(parser, n - 1, 206);
if (listitem == NULL) return setError(parser, n - 1, 206);
Pump[j].Ecurve = listitem->i;
net->Curve[listitem->i].Type = E_CURVE;
net->Curve[listitem->i].Type = EFFIC_CURVE;
}
return 0;
}
@@ -1423,10 +1423,10 @@ int reportdata(Project *pr)
Network *net = &pr->network;
Report *rpt = &pr->report;
Parser *parser = &pr->parser;
int i, j, n;
double y;
n = parser->Ntokens - 1;
if (n < 1) return 201;
@@ -1479,10 +1479,10 @@ int reportdata(Project *pr)
else if (match(parser->Tok[n], w_ALL)) rpt->Nodeflag = 1; // All nodes
else
{
if (net->Nnodes == 0) return setError(parser, 1, 208);
if (net->Nnodes == 0) return setError(parser, 1, 203);
for (i = 1; i <= n; i++)
{
if ((j = findnode(net, parser->Tok[i])) == 0) return setError(parser, i, 208);
if ((j = findnode(net, parser->Tok[i])) == 0) return setError(parser, i, 203);
net->Node[j].Rpt = 1;
}
rpt->Nodeflag = 2;
@@ -1497,10 +1497,10 @@ int reportdata(Project *pr)
else if (match(parser->Tok[n], w_ALL)) rpt->Linkflag = 1;
else
{
if (net->Nlinks == 0) return setError(parser, 1, 210);
if (net->Nlinks == 0) return setError(parser, 1, 204);
for (i = 1; i <= n; i++)
{
if ((j = findlink(net, parser->Tok[i])) == 0) return setError(parser, i, 210);
if ((j = findlink(net, parser->Tok[i])) == 0) return setError(parser, i, 204);
net->Link[j].Rpt = 1;
}
rpt->Linkflag = 2;
@@ -1511,8 +1511,8 @@ int reportdata(Project *pr)
// Report fields specified
// Special case needed to distinguish "HEAD" from "HEADLOSS"
if (strcomp(parser->Tok[0], t_HEADLOSS)) i = HEADLOSS;
else i = findmatch(parser->Tok[0], Fldname);
if (i >= 0)
else i = findmatch(parser->Tok[0], Fldname);
if (i >= 0)
{
if (i > FRICTION) return setError(parser, 0, 213);
if (parser->Ntokens == 1 || match(parser->Tok[1], w_YES))
@@ -1552,7 +1552,7 @@ int reportdata(Project *pr)
return 0;
}
// If get to here then return error condition
// If get to here then return error condition
return 201;
}
@@ -1690,10 +1690,10 @@ int optionchoice(Project *pr, int n)
Quality *qual = &pr->quality;
Parser *parser = &pr->parser;
Outfile *out = &pr->outfile;
int choice;
// Check if 1st token matches a parameter name and
// Check if 1st token matches a parameter name and
// process the input for the matched parameter
if (n < 0) return 201;
@@ -1725,7 +1725,7 @@ int optionchoice(Project *pr, int n)
else if (match(parser->Tok[1], w_METERS)) parser->Pressflag = METERS;
else return setError(parser, 1, 213);
}
// HEADLOSS formula
else if (match(parser->Tok[0], w_HEADLOSS))
{
@@ -1735,7 +1735,7 @@ int optionchoice(Project *pr, int n)
else if (match(parser->Tok[1], w_CM)) hyd->Formflag = CM;
else return setError(parser, 1, 213);
}
// HYDRUALICS USE/SAVE file option
else if (match(parser->Tok[0], w_HYDRAULIC))
{
@@ -1777,19 +1777,19 @@ int optionchoice(Project *pr, int n)
strncpy(qual->ChemUnits, u_HOURS, MAXID);
}
}
// MAP file name
else if (match(parser->Tok[0], w_MAP))
{
if (n < 1) return 0;
strncpy(pr->MapFname, parser->Tok[1], MAXFNAME);
}
else if (match(parser->Tok[0], w_VERIFY))
{
// Deprecated
}
// Hydraulics UNBALANCED option
else if (match(parser->Tok[0], w_UNBALANCED))
{
@@ -1802,7 +1802,7 @@ int optionchoice(Project *pr, int n)
}
else return setError(parser, 1, 213);
}
// Default demand PATTERN
else if (match(parser->Tok[0], w_PATTERN))
{
@@ -1854,7 +1854,7 @@ int optionvalue(Project *pr, int n)
** RQTOL value
** CHECKFREQ value
** MAXCHECK value
** DAMPLIMIT value
** DAMPLIMIT value
**--------------------------------------------------------------
*/
{
@@ -1890,19 +1890,19 @@ int optionvalue(Project *pr, int n)
// Diffusivity
if (match(tok0, w_DIFFUSIVITY))
{
{
if (y < 0.0) return setError(parser, nvalue, 213);
qual->Diffus = y;
return 0;
}
// Hydraulic damping limit option */
// Hydraulic damping limit option */
if (match(tok0, w_DAMPLIMIT))
{
hyd->DampLimit = y;
return 0;
}
// Flow change limit
else if (match(tok0, w_FLOWCHANGE))
{
@@ -1989,7 +1989,7 @@ int getpumpcurve(Project *pr, int n)
double a, b, c, h0, h1, h2, q1, q2;
Spump *pump = &net->Pump[net->Npumps];
// Constant HP curve
if (n == 1)
{
@@ -1997,7 +1997,7 @@ int getpumpcurve(Project *pr, int n)
pump->Ptype = CONST_HP;
net->Link[net->Nlinks].Km = parser->X[0];
}
// Power function curve
else
{
@@ -2080,7 +2080,7 @@ void changestatus(Network *net, int j, StatusType status, double y)
*/
{
Slink *link = &net->Link[j];
if (link->Type == PIPE || link->Type == GPV)
{
if (status != ACTIVE) link->Status = status;

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 12/15/2018
Last Updated: 01/01/2019
******************************************************************************
*/
@@ -151,7 +151,7 @@ int openhydfile(Project *pr)
if (version != ENGINE_VERSION) return 306;
if (fread(nsize, sizeof(INT4), 6, pr->outfile.HydFile) < 6) return 306;
if (nsize[0] != Nnodes || nsize[1] != Nlinks || nsize[2] != Ntanks ||
nsize[3] != Npumps || nsize[4] != Nvalves ||
nsize[3] != Npumps || nsize[4] != Nvalves ||
nsize[5] != pr->times.Dur
) return 306;
pr->outfile.SaveHflag = TRUE;
@@ -187,7 +187,7 @@ int openoutfile(Project *pr)
}
// If output file name was supplied, then attempt to
// open it. Otherwise open a temporary output file.
// open it. Otherwise open a temporary output file.
if (pr->outfile.Outflag == SAVE)
{
pr->outfile.OutFile = fopen(pr->outfile.OutFname, "w+b");
@@ -305,7 +305,7 @@ int allocdata(Project *pr)
ERRCODE(MEMCHECK(pr->quality.NodeQual));
}
// Allocate memory for network links
// Allocate memory for network links
if (!errcode)
{
n = pr->parser.MaxLinks + 1;
@@ -354,7 +354,7 @@ int allocdata(Project *pr)
for (n = 0; n <= pr->parser.MaxCurves; n++)
{
pr->network.Curve[n].Npts = 0;
pr->network.Curve[n].Type = G_CURVE;
pr->network.Curve[n].Type = GENERIC_CURVE;
pr->network.Curve[n].X = NULL;
pr->network.Curve[n].Y = NULL;
}
@@ -442,7 +442,7 @@ void freedata(Project *pr)
free(demand);
demand = nextdemand;
}
// Free memory used for WQ source data
// Free memory used for WQ source data
source = pr->network.Node[j].S;
if (source != NULL) free(source);
}
@@ -579,7 +579,6 @@ int incontrols(Project *pr, int objType, int index)
*/
{
Network *net = &pr->network;
Rules *rules = &pr->rules;
int i, ruleObject;
Spremise *premise;
@@ -652,7 +651,7 @@ int valvecheck(Project *pr, int type, int j1, int j2)
{
// Can't be connected to a fixed grade node
if (j1 > net->Njuncs || j2 > net->Njuncs) return 219;
// Examine each existing valve
for (k = 1; k <= net->Nvalves; k++)
{
@@ -832,7 +831,7 @@ double interp(int n, double x[], double y[], double xx)
double dx, dy;
m = n - 1; // Highest data index
if (xx <= x[0]) return (y[0]); // xx off low end of curve
if (xx <= x[0]) return (y[0]); // xx off low end of curve
for (k = 1; k <= m; k++) // Bracket xx on curve
{
if (x[k] >= xx) // Interp. over interval

View File

@@ -35,7 +35,7 @@ const double Q_STAGNANT = 0.005 / GPMperCFS; // 0.005 gpm = 1.114e-5 cfs
//int stepqual(Project *, long *);
//int closequal(Project *);
//double avgqual(Project *, int);
double findsourcequal(Project *, int, double, double, long);
double findsourcequal(Project *, int, double, long);
// Imported functions
extern char setreactflag(Project *);
@@ -78,21 +78,21 @@ int openqual(Project *pr)
// Create a memory pool for water quality segments
qual->OutOfMemory = FALSE;
qual->SegPool = mempool_create();
if (qual->SegPool == NULL) errcode = 101;
if (qual->SegPool == NULL) errcode = 101;
// Allocate arrays for link flow direction & reaction rates
n = net->Nlinks + 1;
qual->FlowDir = (FlowDirection *)calloc(n, sizeof(FlowDirection));
qual->PipeRateCoeff = (double *)calloc(n, sizeof(double));
// Allocate arrays used for volume segments in links & tanks
// Allocate arrays used for volume segments in links & tanks
n = net->Nlinks + net->Ntanks + 1;
qual->FirstSeg = (Pseg *)calloc(n, sizeof(Pseg));
qual->LastSeg = (Pseg *)calloc(n, sizeof(Pseg));
// Allocate memory for topologically sorted nodes
// Allocate memory for topologically sorted nodes
qual->SortedNodes = (int *)calloc(n, sizeof(int));
ERRCODE(MEMCHECK(qual->FlowDir));
ERRCODE(MEMCHECK(qual->PipeRateCoeff));
ERRCODE(MEMCHECK(qual->FirstSeg));
@@ -119,7 +119,7 @@ int initqual(Project *pr)
int i;
int errcode = 0;
// Re-position hydraulics file
// Re-position hydraulics file
if (!hyd->OpenHflag)
{
fseek(pr->outfile.HydFile, pr->outfile.HydOffset, SEEK_SET);
@@ -148,7 +148,7 @@ int initqual(Project *pr)
// Initialize quality at trace node (if applicable)
if (qual->Qualflag == TRACE) qual->NodeQual[qual->TraceNode] = 100.0;
// Compute Schmidt number
if (qual->Diffus > 0.0) qual->Sc = hyd->Viscos / qual->Diffus;
else qual->Sc = 0.0;
@@ -202,17 +202,17 @@ int runqual(Project *pr, long *t)
Quality *qual = &pr->quality;
Times *time = &pr->times;
long hydtime; // Hydraulic solution time
long hydstep; // Hydraulic time step
long hydtime = 0; // Hydraulic solution time
long hydstep = 0; // Hydraulic time step
int errcode = 0;
// Update reported simulation time
*t = time->Qtime;
// Read hydraulic solution from hydraulics file
// Read hydraulic solution from hydraulics file
if (time->Qtime == time->Htime)
{
// Read hydraulic results from file
// Read hydraulic results from file
if (!hyd->OpenHflag)
{
if (!readhyd(pr, &hydtime)) return 307;
@@ -220,7 +220,7 @@ int runqual(Project *pr, long *t)
time->Htime = hydtime;
}
// Save current results to output file
// Save current results to output file
if (time->Htime >= time->Rtime)
{
if (pr->outfile.Saveflag)
@@ -263,7 +263,7 @@ int nextqual(Project *pr, long *tstep)
{
Quality *qual = &pr->quality;
Times *time = &pr->times;
long hydstep; // Time step until next hydraulic event
long dt, qtime;
int errcode = 0;
@@ -316,7 +316,7 @@ int stepqual(Project *pr, long *tleft)
** Input: none
** Output: tleft = time left in simulation
** Returns: error code
** Purpose: updates quality conditions over a single
** Purpose: updates quality conditions over a single
** quality time step
**--------------------------------------------------------------
*/
@@ -402,7 +402,7 @@ int closequal(Project *pr)
int errcode = 0;
if (qual->SegPool) mempool_delete(qual->SegPool);
FREE(qual->FirstSeg);
FREE(qual->FirstSeg);
FREE(qual->LastSeg);
FREE(qual->PipeRateCoeff);
FREE(qual->FlowDir);
@@ -452,11 +452,10 @@ double avgqual(Project *pr, int k)
}
double findsourcequal(Project *pr, int n, double volin, double volout, long tstep)
double findsourcequal(Project *pr, int n, double volout, long tstep)
/*
**---------------------------------------------------------------------
** Input: n = node index
** volin = volume of node inflow over time step
** volout = volume of node outflow over time step
** tstep = current quality time step
** Output: returns concentration added by an external quality source.
@@ -543,7 +542,6 @@ double sourcequal(Project *pr, Psource source)
*/
{
Network *net = &pr->network;
Quality *qual = &pr->quality;
Times *time = &pr->times;
int i;

View File

@@ -222,7 +222,7 @@ double piperate(Project *pr, int k)
d = net->Link[k].Diam; // Pipe diameter, ft
// Ignore mass transfer if Schmidt No. is 0
// Ignore mass transfer if Schmidt No. is 0
if (qual->Sc == 0.0)
{
if (qual->WallOrder == 0.0) return BIG;
@@ -445,7 +445,6 @@ double mixtank(Project *pr, int n, double volin, double massin, double volout)
*/
{
Network *net = &pr->network;
Quality *qual = &pr->quality;
int i;
double vnet;
@@ -475,7 +474,6 @@ void tankmix1(Project *pr, int i, double vin, double win, double vnet)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int k;
@@ -544,7 +542,7 @@ void tankmix2(Project *pr, int i, double vin, double win, double vnet)
}
}
// Tank is emptying
// Tank is emptying
else if (vnet < 0.0)
{
if (stagzone->v > 0.0) vt = MIN(stagzone->v, (-vnet));
@@ -555,7 +553,7 @@ void tankmix2(Project *pr, int i, double vin, double win, double vnet)
}
}
// Update segment volumes
// Update segment volumes
if (vt > 0.0)
{
mixzone->v = vmz;
@@ -589,7 +587,6 @@ void tankmix3(Project *pr, int i, double vin, double win, double vnet)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int k;
@@ -640,7 +637,7 @@ void tankmix3(Project *pr, int i, double vin, double win, double vnet)
}
// Use quality withdrawn from 1st segment
// to represent overall quality of tank
// to represent overall quality of tank
if (vsum > 0.0) tank->C = wsum / vsum;
else if (qual->FirstSeg[k] == NULL) tank->C = 0.0;
else tank->C = qual->FirstSeg[k]->c;
@@ -662,7 +659,7 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
Network *net = &pr->network;
Quality *qual = &pr->quality;
int k, n;
int k;
double cin, vsum, wsum, vseg;
Pseg seg;
Stank *tank = &pr->network.Tank[i];
@@ -671,7 +668,6 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
if (qual->LastSeg[k] == NULL || qual->FirstSeg[k] == NULL) return;
// Find inflows & outflows
n = tank->Node;
if (vin > 0.0) cin = win / vin;
else cin = 0.0;
@@ -691,7 +687,7 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
qual->LastSeg[k]->prev = seg;
}
// ... update reported tank quality
// ... update reported tank quality
tank->C = qual->LastSeg[k]->c;
}

View File

@@ -35,7 +35,7 @@ void reversesegs(Project *, int);
void addseg(Project *, int, double, double);
// Imported functions
extern double findsourcequal(Project *, int, double, double, long);
extern double findsourcequal(Project *, int, double, long);
extern void reactpipes(Project *, long);
extern void reacttanks(Project *, long);
extern double mixtank(Project *, int, double, double, double);
@@ -147,7 +147,6 @@ void evalnodeinflow(Project *pr, int k, long tstep, double *volin,
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
@@ -251,7 +250,7 @@ double findnodequal(Project *pr, int n, double volin,
}
// Find quality contribued by any external chemical source
else qual->SourceQual = findsourcequal(pr, n, volin, volout, tstep);
else qual->SourceQual = findsourcequal(pr, n, volout, tstep);
if (qual->SourceQual == 0.0) return qual->NodeQual[n];
// Combine source quality with node quality
@@ -285,7 +284,6 @@ double noflowqual(Project *pr, int n)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int k, inflow, kount = 0;
@@ -300,7 +298,7 @@ double noflowqual(Project *pr, int n)
k = alink->link;
dir = qual->FlowDir[k];
// Node n is link's downstream node - add quality
// Node n is link's downstream node - add quality
// of link's first segment to average
if (net->Link[k].N2 == n && dir >= 0) inflow = TRUE;
else if (net->Link[k].N1 == n && dir < 0) inflow = TRUE;
@@ -311,7 +309,7 @@ double noflowqual(Project *pr, int n)
kount++;
}
// Node n is link's upstream node - add quality
// Node n is link's upstream node - add quality
// of link's last segment to average
else if (inflow == FALSE && qual->LastSeg[k] != NULL)
{
@@ -428,7 +426,6 @@ int sortnodes(Project *pr)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int i, j, k, n;
@@ -578,7 +575,6 @@ void initsegs(Project *pr)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int j, k;

View File

@@ -69,8 +69,8 @@ int writereport(Project *pr)
{
Report *rpt = &pr->report;
Parser *parser = &pr->parser;
char tflag;
int tflag;
FILE *tfile;
int errcode = 0;
@@ -82,7 +82,7 @@ int writereport(Project *pr)
if (rpt->Energyflag) writeenergy(pr);
errcode = writeresults(pr);
}
// A secondary report file was specified
else if (strlen(rpt->Rpt2Fname) > 0)
{
@@ -145,7 +145,7 @@ void writelogo(Project *pr)
char s[80];
time_t timer; // time_t structure & functions time() &
// ctime() are defined in time.h
version = CODEVERSION;
major = version / 10000;
minor = (version % 10000) / 100;
@@ -230,12 +230,12 @@ void writesummary(Project *pr)
writeline(pr, s);
}
sprintf(s, FMT27a, hyd->CheckFreq);
writeline(pr, s);
sprintf(s, FMT27b, hyd->MaxCheck);
writeline(pr, s);
sprintf(s, FMT27c, hyd->DampLimit);
writeline(pr, s);
sprintf(s, FMT27a, hyd->CheckFreq);
writeline(pr, s);
sprintf(s, FMT27b, hyd->MaxCheck);
writeline(pr, s);
sprintf(s, FMT27c, hyd->DampLimit);
writeline(pr, s);
sprintf(s, FMT28, hyd->MaxIter);
writeline(pr, s);
@@ -341,7 +341,7 @@ void writehydstat(Project *pr, int iter, double relerr)
}
}
// Display status changes for links
// Display status changes for links
for (i = 1; i <= net->Nlinks; i++)
{
if (hyd->LinkStatus[i] != hyd->OldStatus[i])
@@ -399,7 +399,7 @@ void writemassbalance(Project *pr)
writeline(pr, s1);
snprintf(s1, MAXMSG, "Final Mass: %12.5e", qual->MassBalance.final);
writeline(pr, s1);
snprintf(s1, MAXMSG, "Mass Ratio: %-0.5f", qual->MassBalance.ratio);
snprintf(s1, MAXMSG, "Mass Ratio: %-.5f", qual->MassBalance.ratio);
writeline(pr, s1);
snprintf(s1, MAXMSG, "================================\n");
writeline(pr, s1);
@@ -426,7 +426,7 @@ void writeenergy(Project *pr)
if (net->Npumps == 0) return;
writeline(pr, " ");
writeheader(pr,ENERHDR, 0);
csum = 0.0;
for (j = 1; j <= net->Npumps; j++)
{
@@ -534,7 +534,7 @@ int writeresults(Project *pr)
}
}
// Free allocated memory
// Free allocated memory
for (j = 0; j < m; j++) free(x[j]);
free(x);
return errcode;
@@ -572,7 +572,7 @@ void writenodetable(Project *pr, Pfloat *x)
if ((rpt->Nodeflag == 1 || node->Rpt) &&
checklimits(rpt, y, ELEV, QUALITY))
{
// Check if new page needed
// Check if new page needed
if (rpt->LineNum == (long)rpt->PageSize) writeheader(pr, NODEHDR, 1);
// Add node ID and each reported field to string s
@@ -618,7 +618,7 @@ void writelinktable(Project *pr, Pfloat *x)
double y[MAXVAR];
double *Ucf = pr->Ucf;
Slink *Link = net->Link;
// Write table header
writeheader(pr, LINKHDR, 0);
@@ -686,7 +686,7 @@ void writeheader(Project *pr, int type, int contin)
Quality *qual = &pr->quality;
Parser *parser = &pr->parser;
Times *time = &pr->times;
char s[MAXLINE + 1], s1[MAXLINE + 1], s2[MAXLINE + 1], s3[MAXLINE + 1];
int i, n;
@@ -697,7 +697,7 @@ void writeheader(Project *pr, int type, int contin)
}
writeline(pr, " ");
// Hydraulic Status Table
// Hydraulic Status Table
if (type == STATHDR)
{
sprintf(s, FMT49);
@@ -737,12 +737,12 @@ void writeheader(Project *pr, int type, int contin)
else sprintf(s, FMT78, clocktime(rpt->Atime, time->Htime));
if (contin) strcat(s, t_CONTINUED);
writeline(pr, s);
n = 15;
sprintf(s2, "%15s", "");
strcpy(s, t_NODEID);
sprintf(s3, "%-15s", s);
for (i = ELEV; i < QUALITY; i++)
{
if (rpt->Field[i].Enabled == TRUE)
@@ -846,7 +846,7 @@ void writerelerr(Project *pr, int iter, double relerr)
{
Report *rpt = &pr->report;
Times *time = &pr->times;
if (iter == 0)
{
sprintf(pr->Msg, FMT64, clocktime(rpt->Atime, time->Htime));
@@ -878,7 +878,7 @@ void writestatchange(Project *pr, int k, char s1, char s2)
double *Ucf = pr->Ucf;
double *LinkSetting = hyd->LinkSetting;
Slink *Link = net->Link;
// We have a pump/valve setting change instead of a status change
if (s1 == s2)
{
@@ -934,7 +934,7 @@ void writecontrolaction(Project *pr, int k, int i)
Snode *Node = net->Node;
Slink *Link = net->Link;
Scontrol *Control = net->Control;
switch (Control[i].Type)
{
case LOWLEVEL:
@@ -944,7 +944,7 @@ void writecontrolaction(Project *pr, int k, int i)
LinkTxt[Link[k].Type], Link[k].ID,
NodeTxt[getnodetype(net, n)], Node[n].ID);
break;
case TIMER:
case TIMEOFDAY:
sprintf(pr->Msg, FMT55, clocktime(rpt->Atime, time->Htime),
@@ -1001,7 +1001,7 @@ int writehydwarn(Project *pr, int iter, double relerr)
int i, j;
char flag = 0;
char s;
int s;
Snode *Node = net->Node;
Slink *Link = net->Link;
Spump *Pump = net->Pump;
@@ -1010,7 +1010,7 @@ int writehydwarn(Project *pr, int iter, double relerr)
double *NodeDemand = hyd->NodeDemand;
double *LinkFlow = hyd->LinkFlow;
double *LinkSetting = hyd->LinkSetting;
// Check if system unstable
if (iter > hyd->MaxIter && relerr <= hyd->Hacc)
{
@@ -1046,19 +1046,19 @@ int writehydwarn(Project *pr, int iter, double relerr)
}
}
// Check for abnormal pump condition
// Check for abnormal pump condition
for (i = 1; i <= net->Npumps; i++)
{
j = Pump[i].Link;
s = hyd->LinkStatus[j];
if (hyd->LinkStatus[j] >= OPEN)
{
if (LinkFlow[j] > LinkSetting[j] * Pump[i].Qmax) s = XFLOW;
if (LinkFlow[j] < 0.0) s = XHEAD;
}
if (s == XHEAD || s == XFLOW)
s = hyd->LinkStatus[j];
if (hyd->LinkStatus[j] >= OPEN)
{
sprintf(pr->Msg, WARN04, Link[j].ID, StatTxt[s],
if (LinkFlow[j] > LinkSetting[j] * Pump[i].Qmax) s = XFLOW;
if (LinkFlow[j] < 0.0) s = XHEAD;
}
if (s == XHEAD || s == XFLOW)
{
sprintf(pr->Msg, WARN04, Link[j].ID, StatTxt[s],
clocktime(rpt->Atime, time->Htime));
if (rpt->Messageflag) writeline(pr, pr->Msg);
flag = 4;
@@ -1098,7 +1098,7 @@ void writehyderr(Project *pr, int errnode)
Times *time = &pr->times;
Snode *Node = net->Node;
sprintf(pr->Msg, FMT62, clocktime(rpt->Atime, time->Htime),
Node[errnode].ID);
if (rpt->Messageflag) writeline(pr, pr->Msg);
@@ -1218,7 +1218,7 @@ void marknodes(Project *pr, int m, int *nodelist, char *marked)
int i, j, k, n;
Padjlist alink;
// Scan each successive entry of node list
n = 1;
while (n <= m)
@@ -1232,7 +1232,7 @@ void marknodes(Project *pr, int m, int *nodelist, char *marked)
j = alink->node;
if (marked[j]) continue;
// Check if valve connection is in correct direction
// Check if valve connection is in correct direction
switch (net->Link[k].Type)
{
case CVPIPE:
@@ -1299,7 +1299,7 @@ void writelimits(Project *pr, int j1, int j2)
{
Report *rpt = &pr->report;
int j;
for (j = j1; j <= j2; j++)
{
if (rpt->Field[j].RptLim[LOW] < BIG)

View File

@@ -193,7 +193,7 @@ int ruledata(Project *pr)
switch (key)
{
case -1:
err = 201; // Unrecognized keyword
err = 201; // Unrecognized keyword
break;
case r_RULE:
@@ -328,7 +328,6 @@ void adjustrules(Project *pr, int objtype, int index)
//-----------------------------------------------------------
{
Network *net = &pr->network;
Rules *rules = &pr->rules;
int i, delete;
Spremise *p;
@@ -453,7 +452,6 @@ int writerule(Project *pr, FILE *f, int ruleIndex)
//-----------------------------------------------------------------------------
{
Network *net = &pr->network;
Rules *rules = &pr->rules;
Srule *rule = &net->Rule[ruleIndex];
Spremise *p;
@@ -678,7 +676,7 @@ int newpremise(Project *pr, int logop)
{
if (!getfloat(Tok[parser->Ntokens - 1], &x))
return (202);
if (v == r_FILLTIME || v == r_DRAINTIME) x = x * 3600.0;
if (v == r_FILLTIME || v == r_DRAINTIME) x = x * 3600.0;
}
// Create new premise structure
@@ -715,7 +713,7 @@ int newaction(Project *pr)
double x;
Saction *a;
char **Tok = parser->Tok;
// Check for correct number of tokens
if (parser->Ntokens != 6) return 201;
@@ -848,7 +846,7 @@ int checktime(Project *pr, Spremise *p)
{
t1 = rules->Time1;
t2 = time->Htime;
}
}
else if (p->variable == r_CLOCKTIME)
{
t1 = (rules->Time1 + time->Tstart) % SECperDAY;
@@ -878,7 +876,7 @@ int checktime(Project *pr, Spremise *p)
case EQ:
case NE:
flag = FALSE;
if (t2 < t1) // E.g., 11:00 am to 1:00 am
if (t2 < t1) // E.g., 11:00 am to 1:00 am
{
if (x >= t1 || x <= t2)
flag = TRUE;
@@ -893,7 +891,7 @@ int checktime(Project *pr, Spremise *p)
break;
}
// If we get to here then premise was satisfied
// If we get to here then premise was satisfied
return 1;
}
@@ -906,7 +904,7 @@ int checkstatus(Project *pr, Spremise *p)
char i;
int j;
switch (p->status)
{
case IS_OPEN:
@@ -930,7 +928,7 @@ int checkvalue(Project *pr, Spremise *p)
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
int i, j, v;
double x, // A variable's value
tol = 1.e-3; // Equality tolerance
@@ -942,7 +940,7 @@ int checkvalue(Project *pr, Spremise *p)
Snode *Node = net->Node;
Slink *Link = net->Link;
Stank *Tank = net->Tank;
// Find the value being checked
i = p->index;
v = p->variable;
@@ -1099,13 +1097,13 @@ int takeactions(Project *pr)
Hydraul *hyd = &pr->hydraul;
Report *rpt = &pr->report;
Rules *rules = &pr->rules;
char flag;
int k, s, n;
double tol = 1.e-3, v, x;
Saction *a;
SactionList *actionItem;
n = 0;
actionItem = rules->ActionList;
while (actionItem != NULL)

View File

@@ -81,9 +81,9 @@ static void transpose(int, int *, int *, int *, int *,
int createsparse(Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: creates sparse representation of coeff. matrix
** Input: none
** Output: returns error code
** Purpose: creates sparse representation of coeff. matrix
**--------------------------------------------------------------
*/
{
@@ -104,7 +104,7 @@ int createsparse(Project *pr)
errcode = localadjlists(net, sm);
if (errcode) return errcode;
// Re-order nodes to minimize number of non-zero coeffs.
// Re-order nodes to minimize number of non-zero coeffs.
// in factorized solution matrix
ERRCODE(reordernodes(pr));
@@ -134,9 +134,9 @@ int createsparse(Project *pr)
int allocsmatrix(Smatrix *sm, int Nnodes, int Nlinks)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: allocates memory for representing a sparse matrix
** Input: none
** Output: returns error code
** Purpose: allocates memory for representing a sparse matrix
**--------------------------------------------------------------
*/
{
@@ -192,20 +192,19 @@ int alloclinsolve(Smatrix *sm, int n)
void freesparse(Project *pr)
/*
**----------------------------------------------------------------
** Input: None
** Output: None
** Purpose: Frees memory used for sparse matrix storage
** Input: None
** Output: None
** Purpose: Frees memory used for sparse matrix storage
**----------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
// stoptimer(SmatrixTimer);
// printf("\n");
// printf("\n Processing Time = %7.3f s", gettimer(SmatrixTimer));
// printf("\n");
FREE(sm->Order);
FREE(sm->Row);
FREE(sm->Ndx);
@@ -247,7 +246,7 @@ int localadjlists(Network *net, Smatrix *sm)
i = net->Link[k].N1;
j = net->Link[k].N2;
pmark = paralink(net, sm, i, j, k); // Parallel link check
// Include link in start node i's list
alink = (struct Sadjlist *) malloc(sizeof(struct Sadjlist));
if (alink == NULL) return(101);
@@ -261,7 +260,7 @@ int localadjlists(Network *net, Smatrix *sm)
alink = (struct Sadjlist *) malloc(sizeof(struct Sadjlist));
if (alink == NULL) return(101);
if (!pmark) alink->node = i;
else alink->node = 0; // Parallel link marker
else alink->node = 0; // Parallel link marker
alink->link = k;
alink->next = net->Adjlist[j];
net->Adjlist[j] = alink;
@@ -276,7 +275,7 @@ int localadjlists(Network *net, Smatrix *sm)
int paralink(Network *net, Smatrix *sm, int i, int j, int k)
/*
**--------------------------------------------------------------
** Input: i = index of start node of link
** Input: i = index of start node of link
** j = index of end node of link
** k = link index
** Output: returns 1 if link k parallels another link, else 0
@@ -350,10 +349,10 @@ void xparalinks(Network *net)
int reordernodes(Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns 1 if successful, 0 if not
** Purpose: re-orders nodes to minimize # of non-zeros that
** will appear in factorized solution matrix
** Input: none
** Output: returns 1 if successful, 0 if not
** Purpose: re-orders nodes to minimize # of non-zeros that
** will appear in factorized solution matrix
**--------------------------------------------------------------
*/
{
@@ -376,7 +375,7 @@ int reordernodes(Project *pr)
int *qsize = NULL;
int *llist = NULL;
int *marker = NULL;
// Default ordering
for (k = 1; k <= net->Nnodes; k++)
{
@@ -483,17 +482,17 @@ int factorize(Project *pr)
int growlist(Project *pr, int knode)
/*
**--------------------------------------------------------------
** Input: knode = node index
** Output: returns 1 if successful, 0 if not
** Purpose: creates new entries in knode's adjacency list for
** all unlinked pairs of active nodes that are
** adjacent to knode
** Input: knode = node index
** Output: returns 1 if successful, 0 if not
** Purpose: creates new entries in knode's adjacency list for
** all unlinked pairs of active nodes that are
** adjacent to knode
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
int node;
Padjlist alink;
@@ -517,16 +516,16 @@ int growlist(Project *pr, int knode)
int newlink(Project *pr, Padjlist alink)
/*
**--------------------------------------------------------------
** Input: alink = element of node's adjacency list
** Output: returns 1 if successful, 0 if not
** Purpose: links end of current adjacent link to end nodes of
** all links that follow it on adjacency list
** Input: alink = element of node's adjacency list
** Output: returns 1 if successful, 0 if not
** Purpose: links end of current adjacent link to end nodes of
** all links that follow it on adjacency list
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
int inode, jnode;
Padjlist blink;
@@ -535,7 +534,7 @@ int newlink(Project *pr, Padjlist alink)
for (blink = alink->next; blink != NULL; blink = blink->next)
{
jnode = blink->node; // End node of next connection
// If jnode still active, and inode not connected to jnode,
// then add a new connection between inode and jnode.
if (jnode > 0 && sm->Degree[jnode] > 0) // jnode still active
@@ -545,7 +544,7 @@ int newlink(Project *pr, Padjlist alink)
// Since new connection represents a non-zero coeff.
// in the solution matrix, update the coeff. count.
sm->Ncoeffs++;
// Update adjacency lists for inode & jnode to
// reflect the new connection.
if (!addlink(net, inode, jnode, sm->Ncoeffs)) return 0;
@@ -562,10 +561,10 @@ int newlink(Project *pr, Padjlist alink)
int linked(Network *net, int i, int j)
/*
**--------------------------------------------------------------
** Input: i = node index
** j = node index
** Output: returns 1 if nodes i and j are linked, 0 if not
** Purpose: checks if nodes i and j are already linked.
** Input: i = node index
** j = node index
** Output: returns 1 if nodes i and j are linked, 0 if not
** Purpose: checks if nodes i and j are already linked.
**--------------------------------------------------------------
*/
{
@@ -581,11 +580,11 @@ int linked(Network *net, int i, int j)
int addlink(Network *net, int i, int j, int n)
/*
**--------------------------------------------------------------
** Input: i = node index
** j = node index
** n = link index
** Output: returns 1 if successful, 0 if not
** Purpose: augments node i's adjacency list with node j
** Input: i = node index
** j = node index
** n = link index
** Output: returns 1 if successful, 0 if not
** Purpose: augments node i's adjacency list with node j
**--------------------------------------------------------------
*/
{
@@ -603,20 +602,20 @@ int addlink(Network *net, int i, int j, int n)
int storesparse(Project *pr, int n)
/*
**--------------------------------------------------------------
** Input: n = number of rows in solution matrix
** Output: returns error code
** Purpose: stores row indexes of non-zeros of each column of
** lower triangular portion of factorized matrix
** Input: n = number of rows in solution matrix
** Output: returns error code
** Purpose: stores row indexes of non-zeros of each column of
** lower triangular portion of factorized matrix
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
int i, ii, j, k, l, m;
int errcode = 0;
Padjlist alink;
// Allocate sparse matrix storage
sm->XLNZ = (int *) calloc(n+2, sizeof(int));
sm->NZSUB = (int *) calloc(sm->Ncoeffs+2, sizeof(int));
@@ -625,7 +624,7 @@ int storesparse(Project *pr, int n)
ERRCODE(MEMCHECK(sm->NZSUB));
ERRCODE(MEMCHECK(sm->LNZ));
if (errcode) return errcode;
// Generate row index pointers for each column of matrix
k = 0;
sm->XLNZ[1] = 1;
@@ -655,20 +654,20 @@ int storesparse(Project *pr, int n)
int sortsparse(Smatrix *sm, int n)
/*
**--------------------------------------------------------------
** Input: n = number of rows in solution matrix
** Output: returns eror code
** Purpose: puts row indexes in ascending order in NZSUB
** Input: n = number of rows in solution matrix
** Output: returns eror code
** Purpose: puts row indexes in ascending order in NZSUB
**--------------------------------------------------------------
*/
{
int i, k;
int *xlnzt, *nzsubt, *lnzt, *nzt;
int errcode = 0;
int *LNZ = sm->LNZ;
int *XLNZ = sm->XLNZ;
int *NZSUB = sm->NZSUB;
xlnzt = (int *) calloc(n+2, sizeof(int));
nzsubt = (int *) calloc(sm->Ncoeffs+2, sizeof(int));
lnzt = (int *) calloc(sm->Ncoeffs+2, sizeof(int));
@@ -687,12 +686,12 @@ int sortsparse(Smatrix *sm, int n)
}
xlnzt[1] = 1;
for (i = 1; i <= n; i++) xlnzt[i+1] = xlnzt[i] + nzt[i];
// Transpose matrix twice to order column indexes
transpose(n, XLNZ, NZSUB, LNZ, xlnzt, nzsubt, lnzt, nzt);
transpose(n, xlnzt, nzsubt, lnzt, XLNZ, NZSUB, LNZ, nzt);
}
// Reclaim memory
free(xlnzt);
free(nzsubt);
@@ -706,11 +705,11 @@ void transpose(int n, int *il, int *jl, int *xl, int *ilt, int *jlt,
int *xlt, int *nzt)
/*
**---------------------------------------------------------------------
** Input: n = matrix order
** il,jl,xl = sparse storage scheme for original matrix
** nzt = work array
** Output: ilt,jlt,xlt = sparse storage scheme for transposed matrix
** Purpose: Determines sparse storage scheme for transpose of a matrix
** Input: n = matrix order
** il,jl,xl = sparse storage scheme for original matrix
** nzt = work array
** Output: ilt,jlt,xlt = sparse storage scheme for transposed matrix
** Purpose: Determines sparse storage scheme for transpose of a matrix
**---------------------------------------------------------------------
*/
{
@@ -735,25 +734,25 @@ int linsolve(Smatrix *sm, int n)
/*
**--------------------------------------------------------------
** Input: sm = sparse matrix struct
n = number of equations
** Output: sm->F = solution values
** returns 0 if solution found, or index of
** equation causing system to be ill-conditioned
** Purpose: solves sparse symmetric system of linear
** equations using Cholesky factorization
**
** NOTE: This procedure assumes that the solution matrix has
** been symbolically factorized with the positions of
** the lower triangular, off-diagonal, non-zero coeffs.
** stored in the following integer arrays:
** XLNZ (start position of each column in NZSUB)
** NZSUB (row index of each non-zero in each column)
** LNZ (position of each NZSUB entry in Aij array)
**
** This procedure has been adapted from subroutines GSFCT and
** GSSLV in the book "Computer Solution of Large Sparse
** Positive Definite Systems" by A. George and J. W-H Liu
** (Prentice-Hall, 1981).
n = number of equations
** Output: sm->F = solution values
** returns 0 if solution found, or index of
** equation causing system to be ill-conditioned
** Purpose: solves sparse symmetric system of linear
** equations using Cholesky factorization
**
** NOTE: This procedure assumes that the solution matrix has
** been symbolically factorized with the positions of
** the lower triangular, off-diagonal, non-zero coeffs.
** stored in the following integer arrays:
** XLNZ (start position of each column in NZSUB)
** NZSUB (row index of each non-zero in each column)
** LNZ (position of each NZSUB entry in Aij array)
**
** This procedure has been adapted from subroutines GSFCT and
** GSSLV in the book "Computer Solution of Large Sparse
** Positive Definite Systems" by A. George and J. W-H Liu
** (Prentice-Hall, 1981).
**--------------------------------------------------------------
*/
{
@@ -766,7 +765,7 @@ int linsolve(Smatrix *sm, int n)
int *NZSUB = sm->NZSUB;
int *link = sm->link;
int *first = sm->first;
int i, istop, istrt, isub, j, k, kfirst, newk;
double bj, diagj, ljk;

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 12/15/2018
Last Updated: 01/01/2019
******************************************************************************
*/
@@ -157,11 +157,11 @@ typedef enum {
} QualType;
typedef enum {
V_CURVE, // volume curve
P_CURVE, // pump curve
E_CURVE, // efficiency curve
H_CURVE, // head loss curve
G_CURVE // general\default curve
VOLUME_CURVE, // volume curve
PUMP_CURVE, // pump curve
EFFIC_CURVE, // efficiency curve
HLOSS_CURVE, // head loss curve
GENERIC_CURVE // generic curve
} CurveType;
typedef enum {
@@ -384,7 +384,7 @@ typedef struct // Node Object
Psource S; // source pointer
double C0; // initial quality
double Ke; // emitter coeff.
char Rpt; // reporting flag
int Rpt; // reporting flag
NodeType Type; // node type
char Comment[MAXMSG+1]; // node comment
} Snode;
@@ -405,7 +405,7 @@ typedef struct // Link Object
double Qa; // low flow limit
LinkType Type; // link type
StatusType Status; // initial status
char Rpt; // reporting flag
int Rpt; // reporting flag
char Comment[MAXMSG+1]; // link Comment
} Slink;
@@ -466,7 +466,7 @@ typedef struct // Field Object of Report Table
{
char Name[MAXID+1]; // name of reported variable
char Units[MAXID+1]; // units of reported variable
char Enabled; // enabled if in table
int Enabled; // enabled if in table
int Precision; // number of decimal places
double RptLim[2]; // lower/upper report limits
} SField;
@@ -544,9 +544,6 @@ typedef struct {
FILE *InFile; // Input file handle
char
Unitsflag, // Unit system flag
Flowflag, // Flow units flag
Pressflag, // Pressure units flag
DefPatID[MAXID+1], // Default demand pattern ID
InpFname[MAXFNAME+1], // Input file name
*Tok[MAXTOKS], // Array of token strings
@@ -566,7 +563,10 @@ typedef struct {
MaxCurves, // Curve count " " "
Ntokens, // Number of tokens in line of input
Ntitle, // Number of title lines
ErrTok; // Index of error-producing token
ErrTok, // Index of error-producing token
Unitsflag, // Unit system flag
Flowflag, // Flow units flag
Pressflag; // Pressure units flag
STmplist
*Patlist, // Temporary time pattern list
@@ -605,13 +605,7 @@ typedef struct {
int
Nperiods, // Number of reporting periods
PageSize; // Lines/page in output report/
long
LineNum, // Current line number
PageNum; // Current page number
char
PageSize, // Lines/page in output report/
Rptflag, // Report flag
Tstatflag, // Report time series statistic flag
Summaryflag, // Report summary flag
@@ -620,11 +614,17 @@ typedef struct {
Energyflag, // Energy report flag
Nodeflag, // Node report flag
Linkflag, // Link report flag
Fprinterr; // File write error flag
long
LineNum, // Current line number
PageNum; // Current page number
char
Atime[13], // Clock time (hrs:min:sec)
Rpt1Fname[MAXFNAME+1], // Primary report file name
Rpt2Fname[MAXFNAME+1], // Secondary report file name
DateStamp[26], // Current date & time
Fprinterr; // File write error flag
DateStamp[26]; // Current date & time
SField Field[MAXVAR]; // Output reporting fields
@@ -635,7 +635,9 @@ typedef struct {
char
HydFname[MAXFNAME+1], // Hydraulics file name
OutFname[MAXFNAME+1], // Binary output file name
OutFname[MAXFNAME+1]; // Binary output file name
int
Outflag, // Output file flag
Hydflag, // Hydraulics flag
SaveHflag, // Hydraulic results saved flag
@@ -732,22 +734,20 @@ typedef struct {
DefPat, // Default demand pattern
Epat, // Energy cost time pattern
DemandModel, // Fixed or pressure dependent
Formflag, // Head loss formula flag
Iterations, // Number of hydraulic trials taken
MaxIter, // Max. hydraulic trials allowed
ExtraIter, // Extra hydraulic trials
CheckFreq, // Hydraulic trials between status checks
MaxCheck, // Hydraulic trials limit on status checks
OpenHflag, // Hydraulic system opened flag
Haltflag; // Flag to halt simulation
StatusType
*LinkStatus, // Link status
*OldStatus; // Previous link/tank status
char
OpenHflag, // Hydraulic system opened flag
Formflag; // Head loss formula flag
Smatrix smatrix; // Sparse matrix storage
Smatrix smatrix; // Sparse matrix storage
} Hydraul;
@@ -757,20 +757,18 @@ struct Mempool;
// Water Quality Solver Wrapper
typedef struct {
char
int
Qualflag, // Water quality analysis flag
OpenQflag, // Quality system opened flag
Reactflag, // Reaction indicator
OutOfMemory; // Out of memory indicator
OutOfMemory, // Out of memory indicator
TraceNode, // Source node for flow tracing
*SortedNodes; // Topologically sorted node indexes
char
ChemName[MAXID + 1], // Name of chemical
ChemUnits[MAXID + 1]; // Units of chemical
int
TraceNode, // Source node for flow tracing
*SortedNodes; // Topologically sorted node indexes
double
Ctol, // Water quality tolerance
Diffus, // Diffusivity (sq ft/sec)
@@ -854,9 +852,11 @@ typedef struct Project {
double Ucf[MAXVAR]; // Unit conversion factors
char
int
Openflag, // Project open flag
Warnflag, // Warning flag
Warnflag; // Warning flag
char
Msg[MAXMSG+1], // General-purpose string: errors, messages
Title[MAXTITLE][TITLELEN+1], // Project title
MapFname[MAXFNAME+1], // Map file name

View File

@@ -43,7 +43,7 @@ int main(int argc, char *argv[])
int error = 0;
int ruleCount, nP, nTA, nEA;
int link113, node23, link22, pump9_before, pump9_after;
float priority;
double priority;
EN_Project ph = NULL;
EN_createproject(&ph);

View File

@@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
int flag = 00;
long t, tstep;
int i, ind, Lindex, Nindex, Cindex;
float h_orig, h_build, h_build_loaded;
double h_orig, h_build, h_build_loaded;
// first we load Net1.inp, run it and record the head in Tank 2 at the end of the simulation (h_orig)
EN_Project ph = NULL;
@@ -80,13 +80,13 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
// ------------------------------------------------------------------------
// now we build Net1 from scratch...
char juncs[9][10] = { "10", "11", "12", "13", "21", "22", "23", "31", "32" };
float e[9] = {710, 710, 700, 695, 700, 695, 690, 700, 710};
float d[9] = {0, 150, 150, 100, 150, 200, 150, 100, 100 };
float X[9] = {20, 30, 50, 70, 30, 50, 70, 30, 50};
float Y[9] = {70, 70, 70, 70, 40, 40, 40, 10, 10 };
float L[12] = {10530, 5280, 5280, 5280, 5280, 5280, 200, 5280, 5280, 5280, 5280, 5280};
float dia[12] = { 18, 14, 10, 10, 12, 6, 18, 10, 12, 8, 8, 6 };
float P[12] = { 1.0f, 1.2f, 1.4f, 1.6f, 1.4f, 1.2f, 1.0f, 0.8f, 0.6f, 0.4f, 0.6f, 0.8f };
double e[9] = {710, 710, 700, 695, 700, 695, 690, 700, 710};
double d[9] = {0, 150, 150, 100, 150, 200, 150, 100, 100 };
double X[9] = {20, 30, 50, 70, 30, 50, 70, 30, 50};
double Y[9] = {70, 70, 70, 70, 40, 40, 40, 10, 10 };
double L[12] = {10530, 5280, 5280, 5280, 5280, 5280, 200, 5280, 5280, 5280, 5280, 5280};
double dia[12] = { 18, 14, 10, 10, 12, 6, 18, 10, 12, 8, 8, 6 };
double P[12] = { 1.0f, 1.2f, 1.4f, 1.6f, 1.4f, 1.2f, 1.0f, 0.8f, 0.6f, 0.4f, 0.6f, 0.8f };
error = EN_createproject(&ph);
error = EN_init(ph, "net.rpt", "net.out", EN_GPM, EN_HW);
@@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
BOOST_REQUIRE(error == 0);
error = EN_setpattern(ph, 1, P, 12);
BOOST_REQUIRE(error == 0);
error = EN_setoption(ph, EN_DEMANDDEFPAT, 1);
error = EN_setoption(ph, EN_DEFDEMANDPAT, 1);
BOOST_REQUIRE(error == 0);
for (i = 0; i < 9; i++)
{
@@ -187,9 +187,9 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
BOOST_REQUIRE(error == 0);
// Add controls
error = EN_addcontrol(ph, &Cindex, EN_LOWLEVEL, Lindex, 1, Nindex, 110);
error = EN_addcontrol(ph, EN_LOWLEVEL, Lindex, 1, Nindex, 110, &Cindex);
BOOST_REQUIRE(error == 0);
error = EN_addcontrol(ph, &Cindex, EN_HILEVEL, Lindex, 0, Nindex, 140);
error = EN_addcontrol(ph, EN_HILEVEL, Lindex, 0, Nindex, 140, &Cindex);
BOOST_REQUIRE(error == 0);
error = EN_openH(ph);
@@ -250,10 +250,10 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
// if we got this far we can compare results
// compare the original to the build & saved network
BOOST_REQUIRE(h_orig == h_build_loaded);
BOOST_REQUIRE(abs(h_orig - h_build_loaded) < 0.0001);
// compare the original to the build without saving
BOOST_REQUIRE(h_orig == h_build); // this seems to fail :(
BOOST_REQUIRE(abs(h_orig - h_build) < 0.0001);
}

View File

@@ -0,0 +1,114 @@
// Test of EPANET's Network Building Functions
//
// This is a test of the API functions EN_setjuncdata, EN_settankdata & EN_setpipedata
//
#define _CRT_SECURE_NO_DEPRECATE
//#define NO_BOOST
#ifndef NO_BOOST
#define BOOST_TEST_MODULE "toolkit"
#include <boost/test/included/unit_test.hpp>
#endif
#include <iostream>
#include <string>
#include "epanet2_2.h"
#define DATA_PATH_INP "./net1.inp"
#define DATA_PATH_RPT "./test.rpt"
#define DATA_PATH_OUT "./test.out"
#ifdef NO_BOOST
#define BOOST_REQUIRE(x) (((x)) ? cout << "\nPassed at line " << __LINE__ : cout << "\nFailed at line " << __LINE__ )
#endif
using namespace std;
#ifndef NO_BOOST
BOOST_AUTO_TEST_SUITE (test_toolkit)
BOOST_AUTO_TEST_CASE(test_setlinktype)
{
#else
int main(int argc, char *argv[])
{
#endif
int index;
char id[EN_MAXID+1];
double p1_1, p2_1, p1_2, p2_2;
double q1_1, q2_1, q1_2, q2_2;
// Create & initialize a project
EN_Project ph = NULL;
EN_createproject(&ph);
EN_init(ph, "", "", EN_GPM, EN_HW);
// Build a network
EN_addnode(ph, (char *)"N1", EN_JUNCTION);
EN_addnode(ph, (char *)"N2", EN_JUNCTION);
EN_addnode(ph, (char *)"N3", EN_RESERVOIR);
EN_addnode(ph, (char *)"N4", EN_TANK);
EN_addlink(ph, (char *)"L1", EN_PUMP, (char *)"N3", (char *)"N1");
EN_addlink(ph, (char *)"L2", EN_PIPE, (char *)"N1", (char *)"N3");
EN_addlink(ph, (char *)"L3", EN_PIPE, (char *)"N1", (char *)"N2");
EN_addcurve(ph, (char *)"C1");
// Set network data using the new helper functions
EN_setcurvevalue(ph, 1, 1, 1500, 250);
EN_setjuncdata(ph, 1, 700, 500, "");
EN_setjuncdata(ph, 2, 710, 500, "");
EN_setnodevalue(ph, 3, EN_ELEVATION, 800);
EN_settankdata(ph, 4, 850, 120, 100, 150, 50.5, 0, "");
EN_setlinkvalue(ph, 1, EN_PUMP_HCURVE, 1);
EN_setpipedata(ph, 2, 10560, 12, 100, 0);
EN_setpipedata(ph, 3, 5280, 14, 100, 0);
// Run hydraulics
EN_solveH(ph);
// Save results
EN_getnodevalue(ph, 1, EN_PRESSURE, &p1_1);
EN_getnodevalue(ph, 2, EN_PRESSURE, &p2_1);
EN_getlinkvalue(ph, 1, EN_FLOW, &q1_1);
EN_getlinkvalue(ph, 2, EN_FLOW, &q2_1);
// Save project
EN_saveinpfile(ph, "test2.inp");
// Close project
EN_close(ph);
// Open the saved project file
EN_open(ph, "test2.inp", "", "");
// Run hydraulics
EN_solveH(ph);
// Save these new results
EN_getnodevalue(ph, 1, EN_PRESSURE, &p1_2);
EN_getnodevalue(ph, 2, EN_PRESSURE, &p2_2);
EN_getlinkindex(ph, (char *)"L1", &index);
EN_getlinkvalue(ph, index, EN_FLOW, &q1_2);
EN_getlinkindex(ph, (char *)"L2", &index);
EN_getlinkvalue(ph, index, EN_FLOW, &q2_2);
// Display old & new results
cout << "\n Node N1 Pressure: " << p1_1 << " " << p1_2;
cout << "\n Node N2 Pressure: " << p2_1 << " " << p2_2;
cout << "\n Link L1 Flow: " << q1_1 << " " << q1_2;
cout << "\n Link L2 Flow: " << q2_1 << " " << q2_2;
// Compare old & new results
BOOST_REQUIRE(abs(p1_1 - p1_2) < 1.e-5);
BOOST_REQUIRE(abs(p2_1 - p2_2) < 1.e-5);
BOOST_REQUIRE(abs(q1_1 - q1_2) < 1.e-5);
BOOST_REQUIRE(abs(q2_1 - q2_2) < 1.e-5);
// Close project
EN_close(ph);
EN_deleteproject(&ph);
}
#ifndef NO_BOOST
BOOST_AUTO_TEST_SUITE_END()
#endif

View File

@@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(test_setlinktype)
{
int error = 0;
int p113, n31, p121, n113_1, n113_2;
float q113 = 0.0f, p31 = 0.0f, diam;
double q113 = 0.0, p31 = 0.0, diam;
EN_Project ph = NULL;
EN_createproject(&ph);

View File

@@ -301,7 +301,7 @@ BOOST_FIXTURE_TEST_CASE(test_add_control, Fixture)
{
int flag = 00;
long t, tstep;
float h1, h2;
double h1, h2;
int Cindex;
// run with original controls
@@ -328,10 +328,10 @@ BOOST_FIXTURE_TEST_CASE(test_add_control, Fixture)
BOOST_REQUIRE(error == 0);
// add new controls
error = EN_addcontrol(ph, &Cindex, 0, 13, 1, 11, 110);
error = EN_addcontrol(ph, 0, 13, 1, 11, 110, &Cindex);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(Cindex == 3);
error = EN_addcontrol(ph, &Cindex, 1, 13, 0, 11, 140);
error = EN_addcontrol(ph, 1, 13, 0, 11, 140, &Cindex);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(Cindex == 4);
@@ -352,7 +352,7 @@ BOOST_FIXTURE_TEST_CASE(test_add_control, Fixture)
error = EN_closeH(ph);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(h1 == h2); // end head should be the same with new controls
BOOST_CHECK(abs(h1 - h2) < 1.e-5); // end head should be the same with new controls
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -85,6 +85,7 @@ EXPORTS
ENsetelseaction = _ENsetelseaction@20
ENsetflowunits = _ENsetflowunits@4
ENsetheadcurveindex = _ENsetheadcurveindex@8
ENsetjuncdata = _ENsetjuncdata@16
ENsetlinkid = _ENsetlinkid@8
ENsetlinknodes = _ENsetlinknodes@12
ENsetlinktype = _ENsetlinktype@12
@@ -93,7 +94,8 @@ EXPORTS
ENsetnodevalue = _ENsetnodevalue@12
ENsetoption = _ENsetoption@8
ENsetpattern = _ENsetpattern@12
ENsetpatternvalue = _ENsetpatternvalue@12
ENsetpatternvalue = _ENsetpatternvalue@12
ENsetpipedata = _ENsetpipedata@20
ENsetpremise = _ENsetpremise@36
ENsetpremiseindex = _ENsetpremiseindex@12
ENsetpremisestatus = _ENsetpremisestatus@12
@@ -101,7 +103,8 @@ EXPORTS
ENsetqualtype = _ENsetqualtype@16
ENsetreport = _ENsetreport@4
ENsetrulepriority = _ENsetrulepriority@8
ENsetstatusreport = _ENsetstatusreport@4
ENsetstatusreport = _ENsetstatusreport@4
ENsettankdata = _ENsettankdata@32
ENsetthenaction = _ENsetthenaction@20
ENsettimeparam = _ENsettimeparam@8
ENsolveH = _ENsolveH@0