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

This commit is contained in:
Michael Tryby
2019-01-28 10:41:23 -05:00
61 changed files with 35539 additions and 3263 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. This document describes the changes and updates that have been made to version 2.2 of EPANET.
## Thread-Safe API Functions ## 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)` `ENgetnodevalue(nodeIndex, EN_ELEVATION, &elev)`
@@ -17,10 +16,10 @@ 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: 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) int runEpanet(char *finp, char *frpt)
{ {
EN_ProjectHandle ph = 0; EN_Project ph = 0;
int err; int err;
err = EN_createproject(&ph); err = EN_createproject(&ph);
if (err) return err; if (err) return err;
@@ -32,6 +31,35 @@ int runEpanet(char *finp, char *frpt)
return err; 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 ## 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. 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 ## 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 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%. 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 ## 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)). EPANET's hydraulic solver can generate an ill-conditioned solution matrix when pipe flows approach zero unless some adjustment is made (i.e., as a pipe's flow approaches 0 its head loss gradient also approaches 0 causing its reciprocal, which is used to form the solution matrix's coefficients, to approach infinity). EPANET 2.0 used an arbitrary cutoff on head loss gradient to prevent it from becoming 0. This approach doesn't allow a pipe to follow any head loss v. flow relation in the region below the cutoff and can produce incorrect solutions for some networks (see [Estrada et al., 2009](https://ascelibrary.org/doi/full/10.1061/%28ASCE%29IR.1943-4774.0000100)).
The hydraulic solver has been modified to use a linear head loss v. flow relation for flows approaching zero. For the Darcy-Weisbach equation, the linear Hagen-Poiseuille formula is used for laminar flow where the Reynolds Number is <= 2000. For the Hazen-Williams and Chezy-Manning equations, a flow limit `Qa` is established for each pipe, equal to the flow that produces the EPANET 2 gradient cutoff. For flows below this a linear head loss relation is used between 0 and the head loss at `Qa` and the gradient always equals the cutoff. EPANET 2.2 is now able to correctly solve the examples presented in Estrada et al. (2009) as well as those in [Gorev et al., (2013)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000694) and [Elhay and Simpson (2011)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000411). The hydraulic solver has been modified to use a linear head loss v. flow relation for flows approaching zero. For the Darcy-Weisbach equation, the linear Hagen-Poiseuille formula is used for laminar flow where the Reynolds Number is <= 2000. For the Hazen-Williams and Chezy-Manning equations, a flow limit `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 ## 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. EPANET has always employed a Demand Driven Analysis (**DDA**) when modeling network hydraulics. Under this approach nodal demands at a given point in time are fixed values that must be delivered no matter what nodal heads and link flows are produced by a hydraulic solution. This can result in situations where required demands are satisfied at nodes that have negative pressures - a physical impossibility.
To address this issue EPANET has been extended to use a Pressure Driven Analysis (**PDA**) if so desired. Under **PDA**, the demand *D* delivered at a node depends on the node's available pressure *P* according to: To address this issue EPANET has been extended to use a Pressure Driven Analysis (**PDA**) if so desired. Under **PDA**, the demand *D* delivered at a node depends on the node's available pressure *P* according to:
@@ -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: To implement pressure driven analysis four new parameters have been added to the [OPTIONS] section of the EPANET input file:
| Parameter | Description | Default | | Parameter | Description | Default |
|--|--|--| |--|--|--|
| DEMAND MODEL | either DDA or PDA | DDA | | 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>*. - *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 ## 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. As described by [Davis et al. (2018)](https://www.drink-water-eng-sci.net/11/25/2018/dwes-11-25-2018.pdf) EPANET's water quality simulations can result in some significant mass balance errors when modeling short term mass injections (errors are much smaller for continuous source flows). The entire water quality engine has been re-written to eliminate these errors. It still uses the Lagrangian Time Driven transport method but now analyzes each network node in topologically sorted order rather than in arbitrary order.
A Mass Balance Report now appears the end of a simulation's Status Report that lists the various components (inflow, outflow, reaction) that comprise the network's overall mass balance. In addition `EN_MASSBALANCE` can be used as a parameter in the `ENgetstatistic` (or `EN_getstatistic`) function to retrieve the Mass Balance Ratio (Total Outflow Mass / Total Inflow Mass) at any point during a water quality simulation. A Mass Balance Report now appears the end of a simulation's Status Report that lists the various components (inflow, outflow, reaction) that comprise the network's overall mass balance. In addition `EN_MASSBALANCE` can be used as a parameter in the `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,95 +137,106 @@ 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). 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 ## New API functions
|Function|Description| |Function|Description|
|--|--| |--|--|
|`ENinit`|Initializes an EPANET session| |`EN_createproject` | creates a new EPANET project |
|`ENsetflowunits`|Sets the flow units| |`EN_deleteproject` | deletes an EPANET project |
|`ENgetdemandmodel`|Retrieves the type of demand model in use and its parameters| |`EN_init`|Initializes an EPANET project|
|`ENsetdemandmodel`|Sets the type of demand model to use and its parameters| |`EN_setflowunits`|Sets the project's flow units|
|`ENgetdemandname`|Sets the node's demand name for a category| |`EN_addnode`|Adds a new node to a project|
|`ENsetdemandname`|Sets the node's demand name for a category| |`EN_addlink`|Adds a new link to a project|
|`ENsetdemandpattern`|Sets the index of the demand pattern assigned to a node for a category index| |`EN_addcontrol`|Adds a new simple control to a project|
|`ENsetheadcurveindex`|Sets the curve id for a specified pump index| |`EN_addrule`|Adds a new control rule to a project|
|`ENgetrule`|Gets the number of premises, true actions, and false actions and the priority of an existing rule-based control| |`EN_deletenode`|Deletes a node from the project|
|`ENsetrulepriority`|Sets the priority of the existing rule-based control| |`EN_deletelink`|Deletes a link from the project|
|`ENgetpremise`|Gets the components of a premise/condition in an existing rule-based control| |`EN_deletecontrol`|Deletes a simple control from the project|
|`ENsetpremise`|Sets the components of a premise/condition in an existing rule-based control| |`EN_deleterule`|Deletes a rule-based control from the project|
|`ENsetpremiseindex`|Sets the index of an object in a premise of an existing rule-based control| |`EN_setnodeid`|Changes the ID name for a node|
|`ENsetpremisestatus`|Sets the status in a premise of an existing rule-based control| |`EN_setjuncdata` |Sets values for a junction's parameters |
|`ENsetpremisevalue`|Sets the value in a premise of an existing rule-based control| |`EN_settankdata` |Sets values for a tank's parameters|
|`ENgetthenaction`|Get the components of a THEN action in a rule-based control| |`EN_setlinkid`|Changes the ID name for a link|
|`ENsetthenaction`|Set the components of a THEN action in a rule-based control| |`EN_setlinknodes`|Sets a link's start- and end-nodes|
|`ENgetelseaction`|Get the components of an ELSE action in a rule-based control| |`EN_setlinktype`|Changes the type of a specific link|
|`ENsetelseaction`|Set the components of an ELSE action in a rule-based control| |`EN_setpipedata`|Sets values for a pipe's parameters|
|`ENgetruleID`|Returns the ID of a rule| |`EN_getdemandmodel`|Retrieves the type of demand model in use |
|`ENgetcurvetype`|Get the type of a curve| |`EN_setdemandmodel`|Sets the type of demand model to use|
|`ENsetlinknodes`|Set the indexes of a link's start- and end-nodes| |`EN_getdemandname`|Gets the name of a node's demand category|
|`ENsetlinktype`|Set the link type code for a specified link| |`EN_setdemandname`|Sets the name of a node's demand category|
|`ENaddnode`|Adds a new node| |`EN_setdemandpattern`|Assigns a time pattern to a node's demand category |
|`ENaddlink`|Adds a new link| |`EN_getcurvetype`|Gets a curve's type|
|`ENaddcontrol`|Specify parameters to add a new simple control| |`EN_setheadcurveindex`|Sets the index of a head curve used by a pump |
|`ENaddrule`|Add a new control rule to the project| |`EN_getrule`|Gets the number of elements in a rule-based control |
|`ENdeletenode`|Deletes a node| |`EN_getruleid` | Gets the name assigned to a rule-based control |
|`ENdeletelink`|Deletes a link| |`EN_getpremise`|Gets the contents of a premise in a rule-based control|
|`ENdeletecontrol`|Delete an existing simple control| |`EN_setpremise`|Sets the contents of a premise in a rule-based control|
|`ENdeleterule`|Delete a rule-based control| |`EN_setpremiseindex`|Sets the index of an object in a premise of a rule-based control|
|`ENsetnodeid`|Change the ID name for a node| |`EN_setpremisestatus`|Sets the status of an object in a premise of a rule-based control|
|`ENsetlinkid`|Change the ID name for a link| |`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: ### Link value types:
- `EN_EFFICIENCY` - `EN_PUMP_STATE`
- `EN_HEADCURVE` - `EN_PUMP_EFFIC`
- `EN_EFFICIENCYCURVE` - `EN_PUMP_POWER`
- `EN_PRICEPATTERN` - `EN_PUMP_HCURVE`
- `EN_STATE` - `EN_PUMP_ECURVE`
- `EN_CONST_POWER` - `EN_PUMP_ECOST`
- `EN_SPEED` - `EN_PUMP_EPAT`
### Count types: ### Count types:
- `EN_RULECOUNT` - `EN_RULECOUNT`
### Head loss formula: ### Head loss formula:
- `EN_HW` - `EN_HW`
- `EN_DW` - `EN_DW`
- `EN_CM` - `EN_CM`
### Option types:
### Hydraulic option types:
- `EN_HEADERROR` - `EN_HEADERROR`
- `EN_FLOWCHANGE` - `EN_FLOWCHANGE`
- `EN_DEMANDDEFPAT` - `EN_DEFDEMANDPAT`
- `EN_HEADLOSSFORM` - `EN_HEADLOSSFORM`
### Time statistic types: - `EN_GLOBALEFFIC`
- `EN_GLOBALPRICE`
- `EN_GLOBALPATTERN`
- `EN_DEMANDCHARGE`
### Simulation statistic types:
- `EN_MAXHEADERROR` - `EN_MAXHEADERROR`
- `EN_MAXFLOWCHANGE` - `EN_MAXFLOWCHANGE`
- `EN_MASSBALANCE` - `EN_MASSBALANCE`
### Action code types: ### Action code types:
- `EN_UNCONDITIONAL` - `EN_UNCONDITIONAL`
- `EN_CONDITIONAL` - `EN_CONDITIONAL`
### Curve types: ### Curve types:
- `EN_V_CURVE` - `EN_VOLUME_CURVE`
- `EN_P_CURVE` - `EN_PUMP_CURVE`
- `EN_E_CURVE` - `EN_EFFIC_CURVE`
- `EN_H_CURVE` - `EN_HLOSS_CURVE`
- `EN_G_CURVE` - `EN_GENERIC_CURVE`
### Demand model types: ### Demand model types:
- `EN_DDA` - `EN_DDA`
- `EN_PDA` - `EN_PDA`

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 # This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project. # 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. # title of most generated pages and in a few other places.
# The default value is: My Project. # 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 # 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 # could be handy for archiving the generated documentation or if some version
# control system is used. # 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 # 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 # 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 # entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used. # 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- # 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 # 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. # uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4. # 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 # This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form: # 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 # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty. # 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 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 # 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 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 # 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 # 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 # 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 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = ../include \ INPUT = main.dox \
../src \ toolkit-usage.dox \
../doc \ 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 # 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 # 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, # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. # *.vhdl, *.ucf, *.qsf, *.as and *.js.
FILE_PATTERNS = *.c \ FILE_PATTERNS = *.c \
*.cc \ *.cc \
@@ -856,7 +853,7 @@ FILE_PATTERNS = *.c \
# be searched for input files as well. # be searched for input files as well.
# The default value is: NO. # The default value is: NO.
RECURSIVE = NO RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be # 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 # 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 # that contain images that are to be included in the documentation (see the
# \image command). # \image command).
IMAGE_PATH = IMAGE_PATH = .
# The INPUT_FILTER tag can be used to specify a program that doxygen should # 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 # 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 # 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 # code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly. # 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 = INPUT_FILTER =
@@ -947,10 +940,6 @@ INPUT_FILTER =
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # (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 # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied. # 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 = FILTER_PATTERNS =
@@ -1068,7 +1057,7 @@ VERBATIM_HEADERS = YES
# rich C++ code for which doxygen's built-in parser lacks the necessary type # rich C++ code for which doxygen's built-in parser lacks the necessary type
# information. # information.
# Note: The availability of this option depends on whether or not doxygen was # 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. # The default value is: NO.
CLANG_ASSISTED_PARSING = NO CLANG_ASSISTED_PARSING = NO
@@ -1122,7 +1111,7 @@ GENERATE_HTML = YES
# The default directory is: html. # The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES. # 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 # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp). # generated HTML page (for example: .htm, .php, .asp).
@@ -1159,7 +1148,7 @@ HTML_HEADER =
# that doxygen normally uses. # that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES. # 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 # 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 # 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. # list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES. # 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 # 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 # 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. # written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. # 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 # 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, # 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. # The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. # 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 # 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). # (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. # The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES. # 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 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag # 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. # Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES. # 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 # 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. # 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. # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES. # 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 # 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 # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -1729,7 +1718,7 @@ EXTRA_PACKAGES =
# to HTML_HEADER. # to HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES. # 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 # 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 # generated LaTeX document. The footer should contain everything after the last
@@ -1792,7 +1781,7 @@ LATEX_BATCHMODE = NO
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES. # 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 # If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output. # code with syntax highlighting in the LaTeX output.
@@ -1812,14 +1801,6 @@ LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain 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 # Configuration options related to the RTF output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
@@ -2059,7 +2040,7 @@ MACRO_EXPANSION = YES
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # 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 # If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found. # INCLUDE_PATH will be searched if a #include is found.
@@ -2175,7 +2156,7 @@ PERL_PATH = /usr/bin/perl
# powerful graphs. # powerful graphs.
# The default value is: YES. # The default value is: YES.
CLASS_DIAGRAMS = YES CLASS_DIAGRAMS = NO
# You can define message sequence charts within doxygen comments using the \msc # You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see: # 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 'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL) '(EPANET2.DLL)
'Last updated on 4/3/07 'Last updated on 01/08/2019
' These are codes used by the DLL functions ' These are codes used by the DLL functions
Public Const EN_ELEVATION = 0 ' Node parameters Public Const EN_ELEVATION = 0 ' Node parameters
@@ -50,15 +50,16 @@ Public Const EN_HEADLOSS = 10
Public Const EN_STATUS = 11 Public Const EN_STATUS = 11
Public Const EN_SETTING = 12 Public Const EN_SETTING = 12
Public Const EN_ENERGY = 13 Public Const EN_ENERGY = 13
Public Const EN_LINKQUAL = 14 'ES Public Const EN_LINKQUAL = 14
Public Const EN_LINKPATTERN = 15 Public Const EN_LINKPATTERN = 15
Public Const EN_EFFICIENCY = 16
Public Const EN_HEADCURVE = 17 Public Const EN_PUMP_STATE = 16
Public Const EN_EFFICIENCYCURVE = 18 Public Const EN_PUMP_EFFIC = 17
Public Const EN_PRICEPATTERN = 19 Public Const EN_PUMP_POWER = 18
Public Const EN_STATE = 20 Public Const EN_PUMP_HCURVE = 19
Public Const EN_CONST_POWER = 21 Public Const EN_PUMP_ECURVE = 20
Public Const EN_SPEED = 22 Public Const EN_PUMP_ECOST = 21
Public Const EN_PUMP_EPAT = 22
Public Const EN_DURATION = 0 ' Time parameters Public Const EN_DURATION = 0 ' Time parameters
Public Const EN_HYDSTEP = 1 Public Const EN_HYDSTEP = 1
@@ -76,7 +77,7 @@ Public Const EN_QTIME = 12
Public Const EN_HALTFLAG = 13 Public Const EN_HALTFLAG = 13
Public Const EN_NEXTEVENT = 14 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_RELATIVEERROR = 1
Public Const EN_MAXHEADERROR = 2 Public Const EN_MAXHEADERROR = 2
Public Const EN_MAXFLOWCHANGE = 3 Public Const EN_MAXFLOWCHANGE = 3
@@ -114,7 +115,7 @@ Public Const EN_MASS = 1
Public Const EN_SETPOINT = 2 Public Const EN_SETPOINT = 2
Public Const EN_FLOWPACED = 3 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_DW = 1
Public Const EN_CM = 2 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_DDA = 0 ' Demand driven analysis
Public Const EN_PDA = 1 ' Pressure 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_ACCURACY = 1
Public Const EN_TOLERANCE = 2 Public Const EN_TOLERANCE = 2
Public Const EN_EMITEXPON = 3 Public Const EN_EMITEXPON = 3
@@ -141,6 +142,10 @@ Public Const EN_HEADERROR = 5
Public Const EN_FLOWCHANGE = 6 Public Const EN_FLOWCHANGE = 6
Public Const EN_DEMANDDEFPAT = 7 Public Const EN_DEMANDDEFPAT = 7
Public Const EN_HEADLOSSFORM = 8 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_HILEVEL = 1
@@ -159,154 +164,194 @@ 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_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_CONST_HP = 0 ' Constant horsepower pump curve
Public Const EN_POWER_FUNC = 1 ' power function Public Const EN_POWER_FUNC = 1 ' Power function pump cuve
Public Const EN_CUSTOM = 2 ' user-defined custom curve Public Const EN_CUSTOM = 2 ' User-defined custom pump curve
Public Const EN_NOCURVE = 3 ' no curve Public Const EN_NOCURVE = 3 ' No pump curve
Public Const EN_V_CURVE = 0 ' volume curve Public Const EN_VOLUME_CURVE = 0 ' Volume curve
Public Const EN_P_CURVE = 1 ' pump curve Public Const EN_PUMP_CURVE = 1 ' Pump curve
Public Const EN_E_CURVE = 2 ' efficiency curve Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
Public Const EN_H_CURVE = 3 ' head loss curve Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
Public Const EN_G_CURVE = 4 ' General\default curve Public Const EN_GENERIC_CURVE = 4 ' Generic curve
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
Public Const EN_CONDITIONAL = 1 ' Conditional 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 'These are the external functions that comprise the DLL
'System Functions 'System Functions
Declare Function ENgetversion Lib "epanet2.dll" (value As Long) As Long 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 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 binOutFile As String, ByVal UnitsType As Long, ByVal HeadlossFormula As Long) 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 F1 As String, ByVal F2 As String, ByVal F3 As String) 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 F As String) As Long Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Long
Declare Function ENclose Lib "epanet2.dll" () As Long Declare Function ENclose Lib "epanet2.dll" () As Long
'Hydraulic Analysis Functions 'Hydraulic Analysis Functions
Declare Function ENsolveH Lib "epanet2.dll" () As Long Declare Function ENsolveH Lib "epanet2.dll" () As Long
Declare Function ENsaveH Lib "epanet2.dll" () As Long Declare Function ENsaveH Lib "epanet2.dll" () As Long
Declare Function ENopenH 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 ENinitH Lib "epanet2.dll" (ByVal initFlag As Long) As Long
Declare Function ENrunH Lib "epanet2.dll" (T 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 ENnextH Lib "epanet2.dll" (tStep As Long) As Long
Declare Function ENcloseH Lib "epanet2.dll" () As Long Declare Function ENcloseH Lib "epanet2.dll" () As Long
Declare Function ENsavehydfile 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 F As String) As Long Declare Function ENusehydfile Lib "epanet2.dll" (ByVal filename As String) As Long
'Water Quality Analysis Functions 'Water Quality Analysis Functions
Declare Function ENsolveQ Lib "epanet2.dll" () As Long Declare Function ENsolveQ Lib "epanet2.dll" () As Long
Declare Function ENopenQ 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 ENinitQ Lib "epanet2.dll" (ByVal saveFlag As Long) As Long
Declare Function ENrunQ Lib "epanet2.dll" (T 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 ENnextQ Lib "epanet2.dll" (tStep As Long) As Long
Declare Function ENstepQ Lib "epanet2.dll" (Tleft As Long) As Long Declare Function ENstepQ Lib "epanet2.dll" (timeLeft As Long) As Long
Declare Function ENcloseQ Lib "epanet2.dll" () As Long Declare Function ENcloseQ Lib "epanet2.dll" () As Long
'Reporting Functions '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 ENreport Lib "epanet2.dll" () As Long
Declare Function ENresetreport 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 ENsetreport Lib "epanet2.dll" (ByVal format As String) As Long
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal code As Long) As Long Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal level As Long) As Long
Declare Function ENgetcount Lib "epanet2.dll" (ByVal code As Long, value 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 N 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 code As Long, ByRef value As Single) As Long Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Long, ByRef value As Single) As Long
'Analysis Options Functions 'Analysis Options Functions
Declare Function ENgetoption Lib "epanet2.dll" (ByVal code As Long, value As Single) As Long Declare Function ENgetoption Lib "epanet2.dll" (ByVal option_ 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 ENsetoption Lib "epanet2.dll" (ByVal option_ As Long, ByVal value As Single) As Long
Declare Function ENgetflowunits Lib "epanet2.dll" (code As Long) As Long Declare Function ENgetflowunits Lib "epanet2.dll" (units As Long) As Long
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal code As Long) As Long Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal units As Long) As Long
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal code As Long, value 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 code As Long, ByVal value As Long) As Long Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal param 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" (qualType As Long, ByVal chemName As String, ByVal chemUnits As String, 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 ENgetqualtype Lib "epanet2.dll" (qualType As Long, 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 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 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 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 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 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 ENgetnodetype Lib "epanet2.dll" (ByVal index As Long, nodeType 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 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 code As Long, ByVal 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 ENgetcoord Lib "epanet2.dll" (ByVal index As Long, X As Single, Y 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 ENsetcoord Lib "epanet2.dll" (ByVal index As Long, ByVal X As Single, ByVal Y As Single) 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 '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 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 mtype As Long, ByVal pmin As Single, ByVal preq As Single, ByVal 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 index As Long, numDemands As Long) As Long Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal nodeIndex 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 ENgetbasedemand Lib "epanet2.dll" (ByVal nodeIndex 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 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 index As Long, ByVal DemandIndex As Long, PatIndex As Long) 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 index As Long, ByVal DemandIndex As Long, ByVal 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 index As Long, ByVal DemandIndex As Long, ByVal demandName As String) 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 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 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 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 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 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 ENgetlinktype Lib "epanet2.dll" (ByVal index As Long, linkType As Long) As Long
Declare Function ENsetlinktype Lib "epanet2.dll" (index As Long, ByVal code 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 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 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 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 code As Long, ByVal 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 'Pump Functions
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal pumpIndex As Long, curveIndex 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 pumpIndex As Long, ByVal 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 index As Long, PumpType As Long) As Long Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal linkIndex As Long, pumpType As Long) As Long
'Time Pattern Functions 'Time Pattern Functions
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal id As String) As Long 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 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 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 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 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 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 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 'Data Curve Functions
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal id As String) As Long 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 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 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 ENgetcurvelen Lib "epanet2.dll" (ByVal index As Long, len_ As Long) As Long
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal curveIndex As Long, CurveType 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 index As Long, ByVal Ptn As Long, X As Single, Y As Single) 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 index As Long, ByVal Ptn As Long, ByVal X As Single, ByVal 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 curveIndex As Long, ByVal CurveID As String, nValues As Long, xValues As Any, yValues As Any) 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, X As Any, Y As Any, ByVal N As Long) 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 '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 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 Cindex As Long) As Long Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal index 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 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 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 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 ENaddrule Lib "epanet2.dll" (ByVal rule As String) As Long
Declare Function ENdeleterule Lib "epanet2.dll" (ByVal index As Long) 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 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 indexRule As Long, ByVal id As String) 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 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 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 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 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 indexRule As Long, ByVal indexPremise As Long, ByVal indexObj As Long) 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 indexRule As Long, ByVal indexPremise As Long, ByVal status 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 indexRule As Long, ByVal indexPremise As Long, ByVal value As Single) 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 indexRule As Long, ByVal indexAction As Long, indexLink As Long, status As Long, setting 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 indexRule As Long, ByVal indexAction As Long, ByVal indexLink As Long, ByVal status As Long, ByVal 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 indexRule As Long, ByVal indexAction As Long, indexLink As Long, status As Long, 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 indexRule As Long, ByVal indexAction As Long, ByVal indexLink As Long, ByVal status As Long, ByVal 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 'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL) for use with VB.Net. '(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.Runtime.InteropServices
Imports System.Text Imports System.Text
@@ -55,15 +55,16 @@ Public Const EN_HEADLOSS = 10
Public Const EN_STATUS = 11 Public Const EN_STATUS = 11
Public Const EN_SETTING = 12 Public Const EN_SETTING = 12
Public Const EN_ENERGY = 13 Public Const EN_ENERGY = 13
Public Const EN_LINKQUAL = 14 'ES Public Const EN_LINKQUAL = 14
Public Const EN_LINKPATTERN = 15 Public Const EN_LINKPATTERN = 15
Public Const EN_EFFICIENCY = 16
Public Const EN_HEADCURVE = 17 Public Const EN_PUMP_STATE = 16
Public Const EN_EFFICIENCYCURVE = 18 Public Const EN_PUMP_EFFIC = 17
Public Const EN_PRICEPATTERN = 19 Public Const EN_PUMP_POWER = 18
Public Const EN_STATE = 20 Public Const EN_PUMP_HCURVE = 19
Public Const EN_CONST_POWER = 21 Public Const EN_PUMP_ECURVE = 20
Public Const EN_SPEED = 22 Public Const EN_PUMP_ECOST = 21
Public Const EN_PUMP_EPAT = 22
Public Const EN_DURATION = 0 ' Time parameters Public Const EN_DURATION = 0 ' Time parameters
Public Const EN_HYDSTEP = 1 Public Const EN_HYDSTEP = 1
@@ -75,7 +76,7 @@ Public Const EN_REPORTSTART = 6
Public Const EN_RULESTEP = 7 Public Const EN_RULESTEP = 7
Public Const EN_STATISTIC = 8 Public Const EN_STATISTIC = 8
Public Const EN_PERIODS = 9 Public Const EN_PERIODS = 9
Public Const EN_STARTTIME = 10 'ES Public Const EN_STARTTIME = 10
Public Const EN_HTIME = 11 Public Const EN_HTIME = 11
Public Const EN_QTIME = 12 Public Const EN_QTIME = 12
Public Const EN_HALTFLAG = 13 Public Const EN_HALTFLAG = 13
@@ -119,7 +120,7 @@ Public Const EN_MASS = 1
Public Const EN_SETPOINT = 2 Public Const EN_SETPOINT = 2
Public Const EN_FLOWPACED = 3 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_DW = 1
Public Const EN_CM = 2 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_DDA = 0 ' Demand driven analysis
Public Const EN_PDA = 1 ' Pressure 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_ACCURACY = 1
Public Const EN_TOLERANCE = 2 Public Const EN_TOLERANCE = 2
Public Const EN_EMITEXPON = 3 Public Const EN_EMITEXPON = 3
@@ -146,6 +147,10 @@ Public Const EN_HEADERROR = 5
Public Const EN_FLOWCHANGE = 6 Public Const EN_FLOWCHANGE = 6
Public Const EN_DEMANDDEFPAT = 7 Public Const EN_DEMANDDEFPAT = 7
Public Const EN_HEADLOSSFORM = 8 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_HILEVEL = 1
@@ -165,153 +170,195 @@ 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_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_CONST_HP = 0 ' Constant horsepower pump curve
Public Const EN_POWER_FUNC = 1 ' power function Public Const EN_POWER_FUNC = 1 ' Power function pump curve
Public Const EN_CUSTOM = 2 ' user-defined custom 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_VOLUME_CURVE = 0 ' Volume curve
Public Const EN_P_CURVE = 1 ' pump curve Public Const EN_PUMP_CURVE = 1 ' Pump curve
Public Const EN_E_CURVE = 2 ' efficiency curve Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
Public Const EN_H_CURVE = 3 ' head loss curve Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
Public Const EN_G_CURVE = 4 ' General\default curve Public Const EN_GENERIC_CURVE = 4 ' Generic curve
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
Public Const EN_CONDITIONAL = 1 ' Conditional 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 'These are the external functions that comprise the DLL
'System Functions 'System Functions
Declare Function ENgetversion Lib "epanet2.dll" (ByRef Value As Int32) As Int32 Declare Function ENgetversion Lib "epanet2.dll" (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 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 binOutFile As String, ByVal UnitsType As Int32, ByVal HeadlossFormula As Int32) 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 F1 As String, ByVal F2 As String, ByVal F3 As String) 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 F As String) As Int32 Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Int32
Declare Function ENclose Lib "epanet2.dll" () 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 ENsolveH Lib "epanet2.dll" () As Int32
Declare Function ENsaveH Lib "epanet2.dll" () As Int32 Declare Function ENsaveH Lib "epanet2.dll" () As Int32
Declare Function ENopenH 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 ENinitH Lib "epanet2.dll" (ByVal initFlag As Int32) As Int32
Declare Function ENrunH Lib "epanet2.dll" (ByRef T As Int32) As Int32 Declare Function ENrunH Lib "epanet2.dll" (currentTime As Int32) As Int32
Declare Function ENnextH Lib "epanet2.dll" (ByRef Tstep 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 ENcloseH Lib "epanet2.dll" () As Int32
Declare Function ENsavehydfile 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 F As String) As Int32 Declare Function ENusehydfile Lib "epanet2.dll" (ByVal filename As String) As Int32
'Water Quality Analysis Functions 'Water Quality Analysis Functions
Declare Function ENsolveQ Lib "epanet2.dll" () As Int32 Declare Function ENsolveQ Lib "epanet2.dll" () As Int32
Declare Function ENopenQ 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 ENinitQ Lib "epanet2.dll" (ByVal saveFlag As Int32) As Int32
Declare Function ENrunQ Lib "epanet2.dll" (ByRef T As Int32) As Int32 Declare Function ENrunQ Lib "epanet2.dll" (currentTime As Int32) As Int32
Declare Function ENnextQ Lib "epanet2.dll" (ByRef Tstep As Int32) As Int32 Declare Function ENnextQ Lib "epanet2.dll" (tStep As Int32) As Int32
Declare Function ENstepQ Lib "epanet2.dll" (ByRef Tleft As Int32) As Int32 Declare Function ENstepQ Lib "epanet2.dll" (timeLeft As Int32) As Int32
Declare Function ENcloseQ Lib "epanet2.dll" () As Int32 Declare Function ENcloseQ Lib "epanet2.dll" () As Int32
'Reporting Functions 'Reporting Functions
Declare Function ENwriteline Lib "epanet2.dll" (ByVal S As String) As Int32 Declare Function ENwriteline Lib "epanet2.dll" (ByVal line As String) As Int32
Declare Function ENreport Lib "epanet2.dll" () As Int32 Declare Function ENreport Lib "epanet2.dll" () As Int32
Declare Function ENresetreport 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 ENsetreport Lib "epanet2.dll" (ByVal format As String) As Int32
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal Code As Int32) As Int32 Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal level As Int32) As Int32
Declare Function ENgetcount Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value 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 StringBuilder, ByVal N 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 code As Int32, ByRef value As Single) As Int32 Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Int32, ByRef value As Single) As Int32
'Analysis Options Functions 'Analysis Options Functions
Declare Function ENgetoption Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value As Single) As Int32 Declare Function ENgetoption Lib "epanet2.dll" (ByVal option As Int32, value As Single) As Int32
Declare Function ENsetoption Lib "epanet2.dll" (ByVal Code As Int32, ByVal 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" (ByRef Code As Int32) As Int32 Declare Function ENgetflowunits Lib "epanet2.dll" (units As Int32) As Int32
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal code As Int32) As Int32 Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal units As Int32) As Int32
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value 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 Code As Int32, ByVal Value As Int32) As Int32 Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal param 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" (qualType As Int32, ByVal chemName As String, ByVal chemUnits As String, 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 ENgetqualtype Lib "epanet2.dll" (qualType As Int32, 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 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 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 ENdeletenode Lib "epanet2.dll" (ByVal index As Int32, ByVal actionCode As Int32) As Int32
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index 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 StringBuilder) 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 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 ENgetnodetype Lib "epanet2.dll" (ByVal index As Int32, nodeType 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 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 Code As Int32, ByVal 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 ENgetcoord Lib "epanet2.dll" (ByVal Index As Int32, ByRef X As Single, ByRef Y 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 ENsetcoord Lib "epanet2.dll" (ByVal Index As Int32, ByVal X As Single, ByVal Y As Single) 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 '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 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 mtype As Int32, ByVal pmin As Single, ByVal preq As Single, ByVal 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 Index As Int32, ByRef numDemands As Int32) As Int32 'ES Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal nodeIndex As Int32, numDemands As Int32) As Int32
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef BaseDemand As Single) As Int32 'ES 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 Index As Int32, ByVal DemandIndex As Int32, ByVal BaseDemand As Single) As Int32 'ES 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 Index As Int32, ByVal DemandIndex As Int32, ByRef PatIndex As Int32) As Int32 'ES 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 index As Int32, ByVal DemandIndex As Int32, ByVal 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 index As Int32, ByVal DemandIndex As Int32, ByVal demandName As String) 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 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 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 ENdeletelink Lib "epanet2.dll" (ByVal index As Int32, ByVal actionCode As Int32) As Int32
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index 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 StringBuilder) 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 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 ENgetlinktype Lib "epanet2.dll" (ByVal index As Int32, linkType As Int32) As Int32
Declare Function ENsetlinktype Lib "epanet2.dll" (ByRef index As Int32, ByVal code 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, ByRef Node1 As Int32, ByRef Node2 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 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 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 Code As Int32, ByVal 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 'Pump Functions
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal Index As Int32, ByVal CurveIndex As int32) As Int32 'ES Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Int32, curveIndex As Int32) As Int32
Declare Function ENsetheadcurveindex Lib "epanet2.dll" (ByVal pumpIndex As Int32, ByVal 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 Index As Int32, ByRef PumpType As Int32) As Int32 'ES Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal linkIndex As Int32, pumpType As Int32) As Int32
'Time Pattern Functions 'Time Pattern Functions
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal ID As String) As Int32 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 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 StringBuilder) 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, ByRef L As Int32) 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, ByRef Value As Single) 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 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 ENgetaveragepatternvalue Lib "epanet2.dll" (ByVal index As Int32, 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 ENsetpattern Lib "epanet2.dll" (ByVal index As Int32, values As Any, ByVal len_ As Int32) As Int32
'Data Curve Functions 'Data Curve Functions
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal ID As String) As Int32 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 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 StringBuilder) 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, ByRef L As Int32) As Int32 Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Int32, len_ As Int32) As Int32
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal curveIndex As Int32, ByRef CurveType 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 Index As Int32, ByVal Pnt As Int32, ByRef X As Single, ByRef Y As Single) 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 Index As Int32, ByVal Pnt As Int32, ByVal X As Single, ByVal 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 CurveIndex As Int32, ByRef nValues As Int32, ByRef xValues As Single, ByRef yValues As Single) As Int32 'ES 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, ByRef X as Single, ByRef Y as Single, ByVal N as Int32) 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 '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 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 Cindex as Int32) As Int32 Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal index 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 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 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 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 'Rule-Based Control Functions
Declare Function ENaddrule Lib "epanet2.dll" (ByVal rule As String) as Int32 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 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 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 indexRule As Int32, ByVal id As StringBuilder) 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 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 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 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 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 indexRule As Int32, ByVal indexPremise As Int32, ByVal indexObj As Int32) 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 indexRule As Int32, ByVal indexPremise As Int32, ByVal status 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 indexRule As Int32, ByVal indexPremise As Int32, ByVal value As Single) 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 indexRule As Int32, ByVal indexAction As Int32, ByRef indexLink As Int32, ByRef status As Int32, ByRef setting 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 indexRule As Int32, ByVal indexAction As Int32, ByVal indexLink As Int32, ByVal status As Int32, ByVal 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 indexRule As Int32, ByVal indexAction As Int32, ByRef indexLink As Int32, ByRef status As Int32, ByRef 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 indexRule As Int32, ByVal indexAction As Int32, ByVal indexLink As Int32, ByVal status As Int32, ByVal 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 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 Project: OWA EPANET
Version: 2.2 Version: 2.2
Module: epanet2_enums.h Module: epanet2_enums.h
Description: enums shared between API versions Description: enumerations of symbolic constants used by the API functions
Authors: see AUTHORS Authors: see AUTHORS
Copyright: see AUTHORS Copyright: see AUTHORS
License: see LICENSE 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_MAXID 31 //!< Max. # characters in ID name
#define EN_MAXMSG 255 //!< Max. # characters in message text #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 { typedef enum {
EN_ELEVATION = 0, //!< Elevation EN_ELEVATION = 0, //!< Elevation
EN_BASEDEMAND = 1, //!< Junction baseline demand, from last demand category EN_BASEDEMAND = 1, //!< Primary demand baseline value
EN_PATTERN = 2, //!< Junction baseline demand pattern EN_PATTERN = 2, //!< Primary demand time pattern index
EN_EMITTER = 3, //!< Junction emitter coefficient EN_EMITTER = 3, //!< Emitter flow coefficient
EN_INITQUAL = 4, //!< Initial quality EN_INITQUAL = 4, //!< Initial quality
EN_SOURCEQUAL = 5, //!< Quality source strength EN_SOURCEQUAL = 5, //!< Quality source strength
EN_SOURCEPAT = 6, //!< Quality source pattern EN_SOURCEPAT = 6, //!< Quality source pattern index
EN_SOURCETYPE = 7, //!< Qualiy source type EN_SOURCETYPE = 7, //!< Quality source type (see @ref EN_SourceType)
EN_TANKLEVEL = 8, //!< Tank water level EN_TANKLEVEL = 8, //!< Current computed tank water level (read only)
EN_DEMAND = 9, //!< Current simulated demand EN_DEMAND = 9, //!< Current computed demand (read only)
EN_HEAD = 10, //!< Current hydraulic head EN_HEAD = 10, //!< Current computed hydraulic head (read only)
EN_PRESSURE = 11, //!< Current pressure EN_PRESSURE = 11, //!< Current computed pressure (read only)
EN_QUALITY = 12, //!< Current quality EN_QUALITY = 12, //!< Current computed quality (read only)
EN_SOURCEMASS = 13, //!< Current source mass inflow EN_SOURCEMASS = 13, //!< Current computed quality source mass inflow (read only)
EN_INITVOLUME = 14, //!< Tank initial volume EN_INITVOLUME = 14, //!< Tank initial volume (read only)
EN_MIXMODEL = 15, //!< Tank mixing model EN_MIXMODEL = 15, //!< Tank mixing model (see @ref EN_MixingModel)
EN_MIXZONEVOL = 16, //!< Tank mixing zone volume EN_MIXZONEVOL = 16, //!< Tank mixing zone volume (read only)
EN_TANKDIAM = 17, //!< Tank diameter EN_TANKDIAM = 17, //!< Tank diameter
EN_MINVOLUME = 18, //!< Tank minimum volume 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_MINLEVEL = 20, //!< Tank minimum level
EN_MAXLEVEL = 21, //!< Tank maximum level EN_MAXLEVEL = 21, //!< Tank maximum level
EN_MIXFRACTION = 22, //!< Tank mixing fraction EN_MIXFRACTION = 22, //!< Tank mixing fraction
EN_TANK_KBULK = 23, //!< Tank bulk decay coefficient EN_TANK_KBULK = 23, //!< Tank bulk decay coefficient
EN_TANKVOLUME = 24, //!< Tank current volume EN_TANKVOLUME = 24, //!< Current computed tank volume (read only)
EN_MAXVOLUME = 25 //!< Tank maximum volume EN_MAXVOLUME = 25 //!< Tank maximum volume (read only)
} EN_NodeProperty; } 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 { typedef enum {
EN_DIAMETER = 0, //!< Pipe/valve diameter EN_DIAMETER = 0, //!< Pipe/valve diameter
EN_LENGTH = 1, //!> Pipe length EN_LENGTH = 1, //!< Pipe length
EN_ROUGHNESS = 2, //!> Pipe roughness coefficient EN_ROUGHNESS = 2, //!< Pipe roughness coefficient
EN_MINORLOSS = 3, //!> Pipe/valve minor loss coefficient EN_MINORLOSS = 3, //!< Pipe/valve minor loss coefficient
EN_INITSTATUS = 4, //!> Initial status (e.g., OPEN/CLOSED) EN_INITSTATUS = 4, //!< Initial status (see @ref EN_LinkStatusType)
EN_INITSETTING = 5, //!> Initial pump speed or valve setting EN_INITSETTING = 5, //!< Initial pump speed or valve setting
EN_KBULK = 6, //!> Bulk chemical reaction coefficient EN_KBULK = 6, //!< Bulk chemical reaction coefficient
EN_KWALL = 7, //!> Pipe wall chemical reaction coefficient EN_KWALL = 7, //!< Pipe wall chemical reaction coefficient
EN_FLOW = 8, //!> Current link flow rate EN_FLOW = 8, //!< Current computed flow rate (read only)
EN_VELOCITY = 9, //!> Current link flow velocity EN_VELOCITY = 9, //!< Current computed flow velocity (read only)
EN_HEADLOSS = 10, //!> Current head loss across link EN_HEADLOSS = 10, //!< Current computed head loss (read only)
EN_STATUS = 11, //!> Current link status EN_STATUS = 11, //!< Current link status (see @ref EN_LinkStatusType)
EN_SETTING = 12, //!> Current link setting EN_SETTING = 12, //!< Current link setting
EN_ENERGY = 13, //!> Current pump energy usage EN_ENERGY = 13, //!< Current computed pump energy usage (read only)
EN_LINKQUAL = 14, //!> Current link quality EN_LINKQUAL = 14, //!< Current computed link quality (read only)
EN_LINKPATTERN = 15, //!> Pump speed time pattern EN_LINKPATTERN = 15, //!< Pump speed time pattern index
EN_EFFICIENCY = 16, //!> Current pump efficiency EN_PUMP_STATE = 16, //!< Current computed pump state (read only) (see @ref EN_PumpStateType)
EN_HEADCURVE = 17, //!> Pump head v. flow curve EN_PUMP_EFFIC = 17, //!< Current computed pump efficiency (read only)
EN_EFFICIENCYCURVE = 18, //!> Pump efficiency v. flow curve EN_PUMP_POWER = 18, //!< Pump constant power rating
EN_PRICEPATTERN = 19, //!> Pump energy price time pattern EN_PUMP_HCURVE = 19, //!< Pump head v. flow curve index
EN_STATE = 20, //!> Current pump status EN_PUMP_ECURVE = 20, //!< Pump efficiency v. flow curve index
EN_CONST_POWER = 21, //!> Horsepower of constant horsepower pump EN_PUMP_ECOST = 21, //!< Pump average energy price
EN_SPEED = 22 //!> Current pump speed setting EN_PUMP_EPAT = 22 //!< Pump energy price time pattern index
} EN_LinkProperty; } 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 { typedef enum {
EN_DURATION = 0, //!> Total simulation duration EN_DURATION = 0, //!< Total simulation duration
EN_HYDSTEP = 1, //!> Hydraulic time step EN_HYDSTEP = 1, //!< Hydraulic time step
EN_QUALSTEP = 2, //!> Water quality time step EN_QUALSTEP = 2, //!< Water quality time step
EN_PATTERNSTEP = 3, //!> Time pattern period EN_PATTERNSTEP = 3, //!< Time pattern period
EN_PATTERNSTART = 4, //!> Time when time patterns begin EN_PATTERNSTART = 4, //!< Time when time patterns begin
EN_REPORTSTEP = 5, //!> Reporting time step EN_REPORTSTEP = 5, //!< Reporting time step
EN_REPORTSTART = 6, //!> Time when reporting starts EN_REPORTSTART = 6, //!< Time when reporting starts
EN_RULESTEP = 7, //!> Rule evaluation time step EN_RULESTEP = 7, //!< Rule-based control evaluation time step
EN_STATISTIC = 8, //!> Reporting statistic code EN_STATISTIC = 8, //!< Reporting statistic code (see @ref EN_StatisticType)
EN_PERIODS = 9, //!> Number of reporting time periods EN_PERIODS = 9, //!< Number of reporting time periods (read only)
EN_STARTTIME = 10, //!> Simulation starting time of day EN_STARTTIME = 10, //!< Simulation starting time of day
EN_HTIME = 11, //!> Elapsed time of current hydraulic solution EN_HTIME = 11, //!< Elapsed time of current hydraulic solution (read only)
EN_QTIME = 12, //!> Elapsed time of current quality solution EN_QTIME = 12, //!< Elapsed time of current quality solution (read only)
EN_HALTFLAG = 13, //!> Flag indicating if simulation halted EN_HALTFLAG = 13, //!< Flag indicating if the simulation was halted (read only)
EN_NEXTEVENT = 14, //!> Next time until a tank becomes empty or full EN_NEXTEVENT = 14, //!< Shortest time until a tank becomes empty or full (read only)
EN_NEXTEVENTIDX = 15 //!> Index of next tank that becomes empty or full EN_NEXTEVENTTANK = 15 //!< Index of tank with shortest time to become empty or full (read only)
} EN_TimeProperty; } 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 { typedef enum {
EN_ITERATIONS = 0, //!< Number of hydraulic iterations EN_ITERATIONS = 0, //!< Number of hydraulic iterations taken
EN_RELATIVEERROR = 1, //!< Sum of all flow changes / total flow EN_RELATIVEERROR = 1, //!< Sum of link flow changes / sum of link flows
EN_MAXHEADERROR = 2, //!< Largest head loss error for links EN_MAXHEADERROR = 2, //!< Largest head loss error for links
EN_MAXFLOWCHANGE = 3, //!< Largest flow change in 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; } EN_AnalysisStatistic;
/// Object count codes /// Types of objects to count
/**
These options tell @ref EN_getcount which type of object to count.
*/
typedef enum { typedef enum {
EN_NODECOUNT = 0, //!< Number of nodes (Juntions + Tanks + Reservoirs) EN_NODECOUNT = 0, //!< Number of nodes (junctions + tanks + reservoirs)
EN_TANKCOUNT = 1, //!< Number of tanks and Reservoirs EN_TANKCOUNT = 1, //!< Number of tanks and reservoirs
EN_LINKCOUNT = 2, //!< Number of links (Pipes + Pumps + Valves) EN_LINKCOUNT = 2, //!< Number of links (pipes + pumps + valves)
EN_PATCOUNT = 3, //!< Number of time patterns 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_CONTROLCOUNT = 5, //!< Number of simple controls
EN_RULECOUNT = 6 //!< Number of rule-based controls EN_RULECOUNT = 6 //!< Number of rule-based controls
} EN_CountType; } 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 { typedef enum {
EN_JUNCTION = 0, //!< Junction node EN_JUNCTION = 0, //!< Junction node
EN_RESERVOIR = 1, //!< Reservoir node EN_RESERVOIR = 1, //!< Reservoir node
EN_TANK = 2 //!< Storage tank node EN_TANK = 2 //!< Storage tank node
} EN_NodeType; } 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 { typedef enum {
EN_CVPIPE = 0, //!< Pipe with check valve EN_CVPIPE = 0, //!< Pipe with check valve
EN_PIPE = 1, //!< Pipe EN_PIPE = 1, //!< Pipe
@@ -138,7 +168,36 @@ typedef enum {
EN_GPV = 8 //!< General purpose valve EN_GPV = 8 //!< General purpose valve
} EN_LinkType; } 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 { typedef enum {
EN_NONE = 0, //!< No quality analysis EN_NONE = 0, //!< No quality analysis
EN_CHEM = 1, //!< Chemical fate and transport EN_CHEM = 1, //!< Chemical fate and transport
@@ -146,71 +205,124 @@ typedef enum {
EN_TRACE = 3 //!< Source tracing analysis EN_TRACE = 3 //!< Source tracing analysis
} EN_QualityType; } 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 { typedef enum {
EN_CONCEN = 0, //!< Concentration inflow source EN_CONCEN = 0, //!< Concentration of any external inflow entering a node
EN_MASS = 1, //!< Mass inflow source EN_MASS = 1, //!< Injects a given mass/minute into a node
EN_SETPOINT = 2, //!< Concentration setpoint source EN_SETPOINT = 2, //!< Sets the concentration leaving a node to a given value
EN_FLOWPACED = 3 //!< Concentration flow paced source EN_FLOWPACED = 3 //!< Adds a given value to the concentration leaving a node
} EN_SourceType; } 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 { typedef enum {
EN_HW = 0, //!< Hazen-Williams EN_HW = 0, //!< Hazen-Williams
EN_DW = 1, //!< Darcy-Weisbach EN_DW = 1, //!< Darcy-Weisbach
EN_CM = 2 //!< Chezy-Manning EN_CM = 2 //!< Chezy-Manning
} EN_HeadLossType; } 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 { typedef enum {
EN_CFS = 0, EN_CFS = 0, //!< Cubic feet per second
EN_GPM = 1, EN_GPM = 1, //!< Gallons per minute
EN_MGD = 2, EN_MGD = 2, //!< Million gallons per day
EN_IMGD = 3, EN_IMGD = 3, //!< Imperial million gallons per day
EN_AFD = 4, EN_AFD = 4, //!< Acre-feet per day
EN_LPS = 5, EN_LPS = 5, //!< Liters per second
EN_LPM = 6, EN_LPM = 6, //!< Liters per minute
EN_MLD = 7, EN_MLD = 7, //!< Million liters per day
EN_CMH = 8, EN_CMH = 8, //!< Cubic meters per hour
EN_CMD = 9 EN_CMD = 9 //!< Cubic meters per day
} EN_FlowUnits; } 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 { typedef enum {
EN_DDA = 0, //!< Demand driven analysis EN_DDA = 0, //!< Demand driven analysis
EN_PDA = 1 //!< Pressure driven analysis EN_PDA = 1 //!< Pressure driven analysis
} EN_DemandModel; } 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 { typedef enum {
EN_TRIALS = 0, //!> Maximum hydraulic trials allowed EN_TRIALS = 0, //!< Maximum hydraulic trials allowed
EN_ACCURACY = 1, //!> Hydraulic convergence accuracy EN_ACCURACY = 1, //!< Maximum total relative flow change for hydraulic convergence
EN_TOLERANCE = 2, //!> Water quality tolerance EN_TOLERANCE = 2, //!< Water quality tolerance
EN_EMITEXPON = 3, //!> Exponent for emitter head loss formula EN_EMITEXPON = 3, //!< Exponent in emitter discharge formula
EN_DEMANDMULT = 4, //!> Global demand multiplier EN_DEMANDMULT = 4, //!< Global demand multiplier
EN_HEADERROR = 5, //!> Maximum allowable head loss error EN_HEADERROR = 5, //!< Maximum head loss error for hydraulic convergence
EN_FLOWCHANGE = 6, //!> Maximum allowable flow change EN_FLOWCHANGE = 6, //!< Maximum flow change for hydraulic convergence
EN_DEMANDDEFPAT = 7, //!> Default demand time pattern EN_DEFDEMANDPAT = 7, //!< Index of the default demand time pattern
EN_HEADLOSSFORM = 8 //!> Head loss formula code 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; } 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 { typedef enum {
EN_LOWLEVEL = 0, EN_LOWLEVEL = 0, //!< Act when pressure or tank level drops below a setpoint
EN_HILEVEL = 1, EN_HILEVEL = 1, //!< Act when pressure or tank level rises above a setpoint
EN_TIMER = 2, EN_TIMER = 2, //!< Act at a prescribed elapsed amount of time
EN_TIMEOFDAY = 3 EN_TIMEOFDAY = 3 //!< Act at a particular time of day
} EN_ControlType; } 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 { typedef enum {
EN_AVERAGE = 1, //!> Report average value over simulation period EN_SERIES = 0, //!< Report all time series points
EN_MINIMUM = 2, //!> Report minimum value over simulation period EN_AVERAGE = 1, //!< Report average value over simulation period
EN_MAXIMUM = 3, //!> Report maximum value over simulation period EN_MINIMUM = 2, //!< Report minimum value over simulation period
EN_RANGE = 4 //!> Report maximum - minimum over simulation period EN_MAXIMUM = 3, //!< Report maximum value over simulation period
EN_RANGE = 4 //!< Report maximum - minimum over simulation period
} EN_StatisticType; } EN_StatisticType;
/// Tank mixing models /// 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 { typedef enum {
EN_MIX1 = 0, //!< Complete mix model EN_MIX1 = 0, //!< Complete mix model
EN_MIX2 = 1, //!< 2-compartment model EN_MIX2 = 1, //!< 2-compartment model
@@ -219,14 +331,20 @@ typedef enum {
} EN_MixingModel; } EN_MixingModel;
/// Hydraulic initialization options /// Hydraulic initialization options
/**
These options are used to initialize a new hydraulic analysis when @ref EN_initH is called.
*/
typedef enum { typedef enum {
EN_NOSAVE = 0, //!> Don't save hydraulics; don't re-initialize flows 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_SAVE = 1, //!< Save hydraulics to file, don't re-initialize flows
EN_INITFLOW = 10, //!> Don't save hydraulics; re-initialize flows EN_INITFLOW = 10, //!< Don't save hydraulics; re-initialize flows
EN_SAVE_AND_INIT = 11 //!> Save hydraulics; re-initialize flows EN_SAVE_AND_INIT = 11 //!< Save hydraulics; re-initialize flows
} EN_SaveOption; } EN_InitHydOption;
/// Pump curve types /// Types of pump curves
/**
@ref EN_getpumptype returns one of these values when it is called.
*/
typedef enum { typedef enum {
EN_CONST_HP = 0, //!< Constant horsepower EN_CONST_HP = 0, //!< Constant horsepower
EN_POWER_FUNC = 1, //!< Power function EN_POWER_FUNC = 1, //!< Power function
@@ -234,72 +352,85 @@ typedef enum {
EN_NOCURVE = 3 //!< No curve EN_NOCURVE = 3 //!< No curve
} EN_PumpType; } 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 { typedef enum {
EN_V_CURVE = 0, //!< Tank volume curve EN_VOLUME_CURVE = 0, //!< Tank volume v. depth curve
EN_P_CURVE = 1, //!< Pump characteristic curve EN_PUMP_CURVE = 1, //!< Pump head v. flow curve
EN_E_CURVE = 2, //!< Pump efficiency curve EN_EFFIC_CURVE = 2, //!< Pump efficiency v. flow curve
EN_H_CURVE = 3, //!< Valve head loss curve EN_HLOSS_CURVE = 3, //!< Valve head loss v. flow curve
EN_G_CURVE = 4 //!< General\default curve EN_GENERIC_CURVE = 4 //!< Generic curve
} EN_CurveType; } 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 { typedef enum {
EN_UNCONDITIONAL = 0, //!> Delete all controls that contain object EN_UNCONDITIONAL = 0, //!< Delete all controls that contain object
EN_CONDITIONAL = 1 //!> Cancel object deletion if contained in controls EN_CONDITIONAL = 1 //!< Cancel object deletion if contained in controls
} EN_ActionCodeType; } 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 { typedef enum {
EN_R_NODE = 6, EN_NO_REPORT = 0, //!< No status reporting
EN_R_LINK = 7, EN_NORMAL_REPORT = 1, //!< Normal level of status reporting
EN_R_SYSTEM = 8 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; } EN_RuleObject;
/// Rule variable codes /// Object variables used in rule-based controls
typedef enum { typedef enum {
EN_R_DEMAND = 0, EN_R_DEMAND = 0, //!< Nodal demand
EN_R_HEAD = 1, EN_R_HEAD = 1, //!< Nodal hydraulic head
EN_R_GRADE = 2, EN_R_GRADE = 2, //!< Nodal hydraulic grade
EN_R_LEVEL = 3, EN_R_LEVEL = 3, //!< Tank water level
EN_R_PRESSURE = 4, EN_R_PRESSURE = 4, //!< Nodal pressure
EN_R_FLOW = 5, EN_R_FLOW = 5, //!< Link flow rate
EN_R_STATUS = 6, EN_R_STATUS = 6, //!< Link status
EN_R_SETTING = 7, EN_R_SETTING = 7, //!< Link setting
EN_R_POWER = 8, EN_R_POWER = 8, //!< Pump power output
EN_R_TIME = 9, EN_R_TIME = 9, //!< Elapsed simulation time
EN_R_CLOCKTIME = 10, EN_R_CLOCKTIME = 10, //!< Time of day
EN_R_FILLTIME = 11, EN_R_FILLTIME = 11, //!< Time to fill a tank
EN_R_DRAINTIME = 12 EN_R_DRAINTIME = 12 //!< Time to drain a tank
} EN_RuleVariable; } EN_RuleVariable;
/// Rule operator types /// Comparison operators used in rule-based controls
typedef enum { typedef enum {
EN_R_EQ = 0, EN_R_EQ = 0, //!< Equal to
EN_R_NE = 1, EN_R_NE = 1, //!< Not equal
EN_R_LE = 2, EN_R_LE = 2, //!< Less than or equal to
EN_R_GE = 3, EN_R_GE = 3, //!< Greater than or equal to
EN_R_LT = 4, EN_R_LT = 4, //!< Less than
EN_R_GT = 5, EN_R_GT = 5, //!< Greater than
EN_R_IS = 6, EN_R_IS = 6, //!< Is equal to
EN_R_NOT = 7, EN_R_NOT = 7, //!< Is not equal to
EN_R_BELOW = 8, EN_R_BELOW = 8, //!< Is below
EN_R_ABOVE = 9 EN_R_ABOVE = 9 //!< Is above
} EN_RuleOperator; } EN_RuleOperator;
/// Rule status types /// Link status codes used in rule-based controls
typedef enum { typedef enum {
EN_R_IS_OPEN = 1, EN_R_IS_OPEN = 1, //!< Link is open
EN_R_IS_CLOSED = 2, EN_R_IS_CLOSED = 2, //!< Link is closed
EN_R_IS_ACTIVE = 3 EN_R_IS_ACTIVE = 3 //!< Control valve is active
} EN_RuleStatus; } 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 #endif //EPANET2_ENUMS_H

File diff suppressed because it is too large Load Diff

View File

@@ -7,10 +7,15 @@
Authors: see AUTHORS Authors: see AUTHORS
Copyright: see AUTHORS Copyright: see AUTHORS
License: see LICENSE 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 "types.h"
#include "funcs.h" #include "funcs.h"
@@ -46,13 +51,13 @@ void removetmpfiles()
********************************************************************/ ********************************************************************/
int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile,
void (*pviewprog)(char *)) const char *outFile, void (*pviewprog)(char *))
{ {
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
** Input: f1 = name of EPANET formatted input file ** Input: inpFile = name of EPANET formatted input file
** f2 = name of report file ** rptFile = name of report file
** f3 = name of binary output file ** outFile = name of binary output file
** pviewprog = see note below ** pviewprog = see note below
** Output: none ** Output: none
** Returns: error code ** 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 // Run the project and record any warning
createtmpfiles(); createtmpfiles();
errcode = EN_runproject(_defaultProject, f1, f2, f3, pviewprog); errcode = EN_runproject(_defaultProject, inpFile, rptFile, outFile, pviewprog);
if (errcode < 100) warncode = errcode; if (errcode < 100) warncode = errcode;
removetmpfiles(); removetmpfiles();
@@ -80,20 +85,20 @@ int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3,
return errcode; return errcode;
} }
int DLLEXPORT ENinit(const char *f2, const char *f3, int UnitsType, int DLLEXPORT ENinit(const char *rptFile, const char *outFile, int unitsType,
int HeadlossFormula) int headlossType)
{ {
int errcode = 0; int errcode = 0;
createtmpfiles(); createtmpfiles();
errcode = EN_init(_defaultProject, f2, f3, UnitsType, HeadlossFormula); errcode = EN_init(_defaultProject, rptFile, outFile, unitsType, headlossType);
return errcode; 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; int errcode = 0;
createtmpfiles(); createtmpfiles();
errcode = EN_open(_defaultProject, f1, f2, f3); errcode = EN_open(_defaultProject, inpFile, rptFile, outFile);
return errcode; return errcode;
} }
@@ -121,11 +126,11 @@ int DLLEXPORT ENsaveH() { return EN_saveH(_defaultProject); }
int DLLEXPORT ENopenH() { return EN_openH(_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); } 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 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); } 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 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 ENgetflowunits(int *units)
int DLLEXPORT ENsetflowunits(int code) { return EN_setflowunits(_defaultProject, code); }
int DLLEXPORT ENgettimeparam(int code, long *value)
{ {
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 DLLEXPORT ENgettimeparam(int param, long *value)
int *tracenode)
{ {
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, int DLLEXPORT ENgetqualinfo(int *qualType, char *chemName, char *chemUnits,
char *tracenode) 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); return EN_addnode(_defaultProject, id, nodeType);
} }
@@ -273,24 +290,46 @@ int DLLEXPORT ENsetnodeid(int index, char *newid)
return EN_setnodeid(_defaultProject, index, 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) 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) 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, int DLLEXPORT ENgetdemandmodel(int *model, EN_API_FLOAT_TYPE *pmin,
EN_API_FLOAT_TYPE *preq, EN_API_FLOAT_TYPE *pexp) 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, int DLLEXPORT ENsetdemandmodel(int model, EN_API_FLOAT_TYPE pmin,
EN_API_FLOAT_TYPE preq, EN_API_FLOAT_TYPE pexp) 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) int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands)
@@ -321,34 +365,39 @@ int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands)
return EN_getnumdemands(_defaultProject, nodeIndex, 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); 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); 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) 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); 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 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) 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) 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) 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); 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, int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y) 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, int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x,
EN_API_FLOAT_TYPE y) 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, int DLLEXPORT ENgetcurve(int index, char *id, int *nPoints,
EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues) 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 DLLEXPORT ENaddcontrol(int type, int linkIndex, EN_API_FLOAT_TYPE setting,
int nindex, EN_API_FLOAT_TYPE level) 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 DLLEXPORT ENgetcontrol(int index, int *type, int *linkIndex,
int *nindex, EN_API_FLOAT_TYPE *level) 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 DLLEXPORT ENsetcontrol(int index, int type, int linkIndex,
int nindex, EN_API_FLOAT_TYPE level) 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); return EN_deleterule(_defaultProject, index);
} }
int DLLEXPORT ENgetrule(int index, int *nPremises, int *nThenActions, int *nElseActions, int DLLEXPORT ENgetrule(int index, int *nPremises, int *nThenActions,
EN_API_FLOAT_TYPE *priority) 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) int DLLEXPORT ENgetruleID(int index, char* id)
@@ -589,17 +710,19 @@ int DLLEXPORT ENgetruleID(int index, char* id)
return EN_getruleID(_defaultProject, index, id); return EN_getruleID(_defaultProject, index, id);
} }
int DLLEXPORT ENgetpremise(int ruleIndex, int premiseIndex, int *logop, int DLLEXPORT ENgetpremise(int ruleIndex, int premiseIndex, int *logop, int *object,
int *object, int *objIndex, int *variable, int *objIndex, int *variable, int *relop, int *status,
int *relop, int *status, EN_API_FLOAT_TYPE *value) EN_API_FLOAT_TYPE *value)
{ {
return EN_getpremise(_defaultProject, ruleIndex, premiseIndex, logop, object, double v = 0.0;
objIndex, variable, relop, status, value); 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 DLLEXPORT ENsetpremise(int ruleIndex, int premiseIndex, int logop, int object,
int object, int objIndex, int variable, int relop, int objIndex, int variable, int relop, int status, EN_API_FLOAT_TYPE value)
int status, EN_API_FLOAT_TYPE value)
{ {
return EN_setpremise(_defaultProject, ruleIndex, premiseIndex, logop, object, return EN_setpremise(_defaultProject, ruleIndex, premiseIndex, logop, object,
objIndex, variable, relop, status, value); objIndex, variable, relop, status, value);
@@ -623,8 +746,11 @@ int DLLEXPORT ENsetpremisevalue(int ruleIndex, int premiseIndex, EN_API_FLOAT_TY
int DLLEXPORT ENgetthenaction(int ruleIndex, int actionIndex, int *linkIndex, 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, double setting2 = 0.0;
status, setting); 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 DLLEXPORT ENsetthenaction(int ruleIndex, int actionIndex, int linkIndex,
@@ -637,8 +763,11 @@ int DLLEXPORT ENsetthenaction(int ruleIndex, int actionIndex, int linkIndex,
int DLLEXPORT ENgetelseaction(int ruleIndex, int actionIndex, int *linkIndex, 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, double setting2 = 0.0;
status, setting); 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 DLLEXPORT ENsetelseaction(int ruleIndex, int actionIndex, int linkIndex,

View File

@@ -1,76 +1,69 @@
//EPANET 2 Error Messages
DAT(0,"ok")
DAT(101,"insufficient memory available")
DAT(102,"no network data available")
DAT(103,"hydraulic solver not opened")
DAT(104,"no hydraulics for water quality analysis")
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(110,"cannot solve network hydraulic equations")
DAT(120,"cannot solve water quality transport equations")
DAT(0,EN_OK,"ok") // These errors apply only to an input file
DAT(101,ENERR_INSUF_MEM,"insufficient memory available") DAT(200,"one or more errors in input file")
DAT(102,ENERR_NO_NET_DATA,"no network data available") DAT(201,"syntax error")
DAT(103,ENERR_HYD_NOT_INIT,"hydraulics not initialized")
DAT(104,ENERR_NO_HYD,"no hydraulics for water quality analysis")
DAT(105,ENERR_WQ_NOT_INIT,"water quality not initialized")
DAT(106,ENERR_NO_RESULT,"no results saved to report on")
DAT(107,ENERR_HYD_EXT_FILE,"hydraulics supplied from external file")
DAT(108,ENERR_CANT_USE_EXT_FILE,"cannot use external file while hydraulics solver is active")
DAT(109,ENERR_CANT_CHANGE_TIME_PARAM,"cannot change time parameter when solver is active")
DAT(110,ENERR_CANT_SOLVE_HYD,"cannot solve network hydraulic equations")
DAT(120,ENERR_CANT_SOLVE_WQ,"cannot solve water quality transport equations")
DAT(200,ENERR_INP_ERR,"one or more errors in input file") // These errors apply to both an input file and to API functions
DAT(201,ENERR_SYNTAX_LINE,"syntax error in following line of section") DAT(202,"illegal numeric value")
DAT(202,ENERR_ILLEGAL_NUM,"function call contains illegal numeric value") DAT(203,"undefined node")
DAT(203,ENERR_UNDEF_NODE,"function call refers to undefined node") DAT(204,"undefined link")
DAT(204,ENERR_UNDEF_LINK,"function call refers to undefined link") DAT(205,"undefined time pattern")
DAT(205,ENERR_UNDEF_PAT,"function call refers to undefined time pattern") DAT(206,"undefined curve")
DAT(206,ENERR_UNDEF_CURVE,"function call refers to undefined curve") DAT(207,"attempt to control CV/GPV link")
DAT(207,ENERR_CANT_CONTROL_CV,"function call attempts to control a CV") DAT(209,"illegal node property value")
DAT(211,"illegal link property value")
DAT(212,"undefined trace node")
DAT(213,"invalid option value")
DAT(214,"too many characters in input line")
DAT(215,"duplicate ID label")
DAT(216,"reference to undefined pump")
DAT(217,"invalid pump energy data")
DAT(219,"illegal valve connection to tank node")
DAT(220,"illegal valve connection to another valve")
DAT(221,"mis-placed rule clause in rule-based control")
DAT(222,"same start and end nodes for link")
DAT(208,ENERR_SPEC_UNDEF_NODE,"undefined Node") // These errors apply to network consistency check
DAT(209,ENERR_ILLEGAL_VAL_NODE,"illegal value for Node") DAT(223,"not enough nodes in network")
DAT(210,ENERR_SPEC_UNDEF_LINK,"specified for undefined Link") DAT(224,"no tanks or reservoirs in network")
DAT(211,ENERR_ILLEGAL_VAL_LINK,"illegal value for Link") DAT(225,"invalid lower/upper levels for tank")
DAT(212,ENERR_TRACE_NODE,"invalid trace node") DAT(226,"no head curve or power rating for pump")
DAT(213,ENERR_ILLEGAL_OPT,"illegal option value in section") DAT(227,"invalid head curve for pump")
DAT(214,ENERR_TOO_MANY_CHAR,"following line of section contains too many characters") DAT(230,"nonincreasing x-values for curve")
DAT(215,ENERR_DUPLICATE_ID,"duplicate ID") DAT(233,"network has unconnected node")
DAT(216,ENERR_UNDEF_PUMP,"data specified for undefined Pump")
DAT(217,ENERR_INVALID_DATA_PUMP,"invalid data for Pump")
DAT(219,ENERR_ILLEGAL_CON_TANK,"illegally connected to a tank")
DAT(220,ENERR_ILLEGAL_CON_VALVE,"illegally connected to another valve")
DAT(221,ENERR_RULE_CLAUSE, "mis-placed rule clause")
DAT(222,ENERR_SAME_START_END,"same start and end nodes")
DAT(223,ENERR_NOT_ENOUGH_NODES,"not enough nodes in network")
DAT(224,ENERR_NO_TANKS_RES,"no tanks or reservoirs in network")
DAT(225,ENERR_INVALID_LEVELS,"invalid lower/upper levels for Tank")
DAT(226,ENERR_NO_HEAD_CURVE,"no head curve supplied for Pump")
DAT(227,ENERR_INVALID_HEAD_CURVE,"invalid head curve for Pump")
DAT(230,ENERR_X_NONINCREASING,"Curve has nonincreasing x-values")
DAT(233,ENERR_NODE_UNCONNECTED,"Node is unconnected")
DAT(240,ENERR_UNDEF_SOURCE,"undefined source")
DAT(241,ENERR_UNDEF_CONTROL,"refers to undefined control")
DAT(250,ENERR_INVALID_FORMAT,"function call contains invalid format")
DAT(251,ENERR_INVALID_CODE,"function call contains invalid parameter code")
DAT(253,ENERR_NO_DEMAND_CAT,"function applied to nonexistent demand category")
DAT(254,ENERR_NO_COORDS,"function applied to node with no coordinates")
DAT(255,ENERR_COORDS_NOT_LOADED,"function fails because no node coordinates were supplied")
DAT(257,ENERR_NO_RULE,"function applied to nonexistent rule")
DAT(258,ENERR_NO_CONDITION_ACTION,"function applied to nonexistent rule clause")
DAT(260,ENERR_DEL_TRACE_NODE,"cannot delete node assigned as a Trace Node")
DAT(261,ENERR_DEL_NODE_LINK, "cannot delete a node or link contained in a control")
DAT(301,ENERR_FILES_ARE_SAME,"identical file names")
DAT(302,ENERR_CANT_OPEN_INP,"cannot open input file")
DAT(303,ENERR_CANT_OPEN_RPT,"cannot open report file")
DAT(304,ENERR_CANT_OPEN_BIN,"cannot open binary output file")
DAT(305,ENERR_CANT_OPEN_HYD,"cannot open hydraulics file")
DAT(306,ENERR_HYD_FILE_NOMATCH,"hydraulics file does not match network data")
DAT(307,ENERR_CANT_READ_HYD,"cannot read hydraulics file")
DAT(308,ENERR_CANT_SAVE_RES,"cannot save results to file")
DAT(309,ENERR_CANT_SAVE_RPT,"cannot save results to report file")
DAT(411,ENERR_NO_MEM_ALLOC,"no memory allocated for results")
DAT(412,ENERR_NO_RESULTS_NO_FILE,"no results; binary file hasn't been opened")
DAT(435,ENERR_RUN_TERMINATED,"run terminated; no results in binary file")
// These errors apply only to API functions
DAT(240,"nonexistent source")
DAT(241,"nonexistent control")
DAT(250,"invalid format")
DAT(251,"invalid parameter code")
DAT(253,"nonexistent demand category")
DAT(254,"node with no coordinates")
DAT(257,"nonexistent rule")
DAT(258,"nonexistent rule clause")
DAT(260,"attempt to delete node assigned as a Trace Node")
DAT(261,"attempt to delete a node or link contained in a control")
DAT(262,"attempt to modify network structure while solver is active")
// File errors
DAT(301,"identical file names")
DAT(302,"cannot open input file")
DAT(303,"cannot open report file")
DAT(304,"cannot open binary output file")
DAT(305,"cannot open hydraulics file")
DAT(306,"hydraulics file does not match network data")
DAT(307,"cannot read hydraulics file")
DAT(308,"cannot save results to file")
DAT(309,"cannot save results to report file")

View File

@@ -29,6 +29,7 @@ int buildadjlists(Network *);
void freeadjlists(Network *); void freeadjlists(Network *);
int incontrols(Project *, int, int); int incontrols(Project *, int, int);
int valvecheck(Project *, int, int, int);
int findnode(Network *, char *); int findnode(Network *, char *);
int findlink(Network *, char *); int findlink(Network *, char *);
int findtank(Network *, int); int findtank(Network *, int);
@@ -88,7 +89,6 @@ int statusdata(Project *);
int reportdata(Project *); int reportdata(Project *);
int timedata(Project *); int timedata(Project *);
int optiondata(Project *); int optiondata(Project *);
int valvecheck(Project *, int, int, int);
// ------- RULES.C ------------------ // ------- RULES.C ------------------

View File

@@ -771,11 +771,19 @@ void pumpcoeff(Project *pr, int k)
return; return;
} }
// Obtain reference to pump object & its speed setting // Obtain reference to pump object
q = ABS(hyd->LinkFlow[k]); q = ABS(hyd->LinkFlow[k]);
p = findpump(&pr->network, k); p = findpump(&pr->network, k);
pump = &pr->network.Pump[p]; pump = &pr->network.Pump[p];
// If no pump curve treat pump as an open valve
if (pump->Ptype == NOCURVE)
{
hyd->P[k] = 1.0 / CSMALL;
hyd->Y[k] = hyd->LinkFlow[k];
return;
}
// Get pump curve coefficients for custom pump curve // Get pump curve coefficients for custom pump curve
// (Other pump types have pre-determined coeffs.) // (Other pump types have pre-determined coeffs.)
if (pump->Ptype == CUSTOM) if (pump->Ptype == CUSTOM)

View File

@@ -58,12 +58,26 @@ int openhyd(Project *pr)
int errcode = 0; int errcode = 0;
Slink *link; Slink *link;
// Check for too few nodes & no fixed grade nodes
if (pr->network.Nnodes < 2) errcode = 223;
else if (pr->network.Ntanks == 0) errcode = 224;
// Allocate memory for sparse matrix structures (see SMATRIX.C) // Allocate memory for sparse matrix structures (see SMATRIX.C)
ERRCODE(createsparse(pr)); ERRCODE(createsparse(pr));
// Allocate memory for hydraulic variables // Allocate memory for hydraulic variables
ERRCODE(allocmatrix(pr)); ERRCODE(allocmatrix(pr));
// Check for unconnected nodes
if (!errcode) for (i = 1; i <= pr->network.Njuncs; i++)
{
if (pr->network.Adjlist[i] == NULL)
{
errcode = 233;
break;
}
}
// Initialize link flows // Initialize link flows
if (!errcode) for (i = 1; i <= pr->network.Nlinks; i++) if (!errcode) for (i = 1; i <= pr->network.Nlinks; i++)
{ {

View File

@@ -100,6 +100,8 @@ int hydsolve(Project *pr, int *iter, double *relerr)
// Initialize status checking & relaxation factor // Initialize status checking & relaxation factor
nextcheck = hyd->CheckFreq; nextcheck = hyd->CheckFreq;
hyd->RelaxFactor = 1.0; hyd->RelaxFactor = 1.0;
hydbal.maxheaderror = 0.0;
hydbal.maxflowchange = 0.0;
// Repeat iterations until convergence or trial limit is exceeded. // Repeat iterations until convergence or trial limit is exceeded.
// (ExtraIter used to increase trials in case of status cycling.) // (ExtraIter used to increase trials in case of status cycling.)
@@ -360,7 +362,6 @@ double newflows(Project *pr, Hydbalance *hbal)
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
{ {
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul; Hydraul *hyd = &pr->hydraul;
double dqsum, // Network flow change double dqsum, // Network flow change

View File

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

View File

@@ -7,7 +7,7 @@ Description: retrieves network data from an EPANET input file
Authors: see AUTHORS Authors: see AUTHORS
Copyright: see AUTHORS Copyright: see AUTHORS
License: see LICENSE License: see LICENSE
Last Updated: 11/10/2018 Last Updated: 12/15/2018
****************************************************************************** ******************************************************************************
*/ */
@@ -357,6 +357,7 @@ int inittanks(Project *pr)
int i, j, n = 0; int i, j, n = 0;
double a; double a;
int errcode = 0, levelerr; int errcode = 0, levelerr;
char errmsg[MAXMSG+1] = "";
Stank *tank; Stank *tank;
Scurve *curve; Scurve *curve;
@@ -383,14 +384,6 @@ int inittanks(Project *pr)
levelerr = 1; levelerr = 1;
} }
// Report error in levels if found
if (levelerr)
{
sprintf(pr->Msg, "%s node: %s", geterrmsg(225, pr->Msg),
net->Node[tank->Node].ID);
writeline(pr, pr->Msg);
errcode = 200;
}
else else
{ {
// Find min., max., and initial volumes from curve // Find min., max., and initial volumes from curve
@@ -403,6 +396,15 @@ int inittanks(Project *pr)
tank->A = sqrt(4.0 * a / PI); tank->A = sqrt(4.0 * a / PI);
} }
} }
// Report error in levels if found
if (levelerr)
{
sprintf(pr->Msg, "Error 225: %s node %s", geterrmsg(225, errmsg),
net->Node[tank->Node].ID);
writeline(pr, pr->Msg);
errcode = 200;
}
} }
return errcode; return errcode;
} }

View File

@@ -7,7 +7,7 @@ Description: reads and interprets network data from an EPANET input file
Authors: see AUTHORS Authors: see AUTHORS
Copyright: see AUTHORS Copyright: see AUTHORS
License: see LICENSE License: see LICENSE
Last Updated: 11/10/2018 Last Updated: 01/01/2019
****************************************************************************** ******************************************************************************
*/ */
@@ -179,6 +179,7 @@ int readdata(Project *pr)
parser->Comment); parser->Comment);
// Skip blank lines and comments // Skip blank lines and comments
parser->ErrTok = -1;
if (parser->Ntokens == 0) continue; if (parser->Ntokens == 0) continue;
if (*parser->Tok[0] == ';') continue; if (*parser->Tok[0] == ';') continue;
@@ -327,6 +328,7 @@ int getpumpparams(Project *pr)
{ {
Network *net = &pr->network; Network *net = &pr->network;
int i, k, errcode = 0; int i, k, errcode = 0;
char errmsg[MAXMSG+1];
for (i = 1; i <= net->Npumps; i++) for (i = 1; i <= net->Npumps; i++)
{ {
@@ -334,8 +336,8 @@ int getpumpparams(Project *pr)
if (errcode) if (errcode)
{ {
k = net->Pump[i].Link; k = net->Pump[i].Link;
sprintf(pr->Msg, "%s link: %s", geterrmsg(errcode, pr->Msg), sprintf(pr->Msg, "Error %d: %s %s",
net->Link[k].ID); errcode, geterrmsg(errcode, errmsg), net->Link[k].ID);
writeline(pr, pr->Msg); writeline(pr, pr->Msg);
return 200; return 200;
} }
@@ -379,7 +381,7 @@ int updatepumpparams(Project *pr, int pumpindex)
curveindex = pump->Hcurve; curveindex = pump->Hcurve;
if (curveindex == 0) return 226; if (curveindex == 0) return 226;
curve = &net->Curve[curveindex]; curve = &net->Curve[curveindex];
curve->Type = P_CURVE; curve->Type = PUMP_CURVE;
npts = curve->Npts; npts = curve->Npts;
// Generic power function curve // Generic power function curve
@@ -596,8 +598,7 @@ int unlinked(Project *pr)
if (marked[i] == 0) if (marked[i] == 0)
{ {
err++; err++;
sprintf(pr->Msg, "%s link: %s", geterrmsg(233, pr->Msg), sprintf(pr->Msg, "Error 233: %s %s", geterrmsg(233, pr->Msg), net->Node[i].ID);
net->Node[i].ID);
writeline(pr, pr->Msg); writeline(pr, pr->Msg);
} }
if (err >= MAXERRS) break; if (err >= MAXERRS) break;
@@ -685,6 +686,7 @@ int getcurves(Project *pr)
int i, j; int i, j;
double x; double x;
char errmsg[MAXMSG+1];
SFloatlist *fx, *fy; SFloatlist *fx, *fy;
STmplist *tmpcurve; STmplist *tmpcurve;
Scurve *curve; Scurve *curve;
@@ -705,10 +707,9 @@ int getcurves(Project *pr)
// Check that network curve has data points // Check that network curve has data points
if (curve->Npts <= 0) if (curve->Npts <= 0)
{ {
sprintf(pr->Msg, "%s link: %s", geterrmsg(230, pr->Msg), sprintf(pr->Msg, "Error 230: %s %s", geterrmsg(230, errmsg), curve->ID);
curve->ID);
writeline(pr, pr->Msg); writeline(pr, pr->Msg);
return (200); return 200;
} }
// Allocate memory for network's curve data // Allocate memory for network's curve data
@@ -726,10 +727,9 @@ int getcurves(Project *pr)
// Check that x data is in ascending order // Check that x data is in ascending order
if (fx->value >= x) if (fx->value >= x)
{ {
sprintf(pr->Msg, "%s link: %s", geterrmsg(230, pr->Msg), sprintf(pr->Msg, "Error 230: %s %s", geterrmsg(230, errmsg), curve->ID);
curve->ID);
writeline(pr, pr->Msg); writeline(pr, pr->Msg);
return (200); return 200;
} }
x = fx->value; x = fx->value;
@@ -967,33 +967,18 @@ void inperrmsg(Project *pr, int err, int sect, char *line)
{ {
Parser *parser = &pr->parser; Parser *parser = &pr->parser;
char errStr[MAXMSG + 1]; char errStr[MAXMSG + 1] = "";
char id[MAXMSG + 1]; char tok[MAXMSG + 1];
// get text for error message // Get token associated with input error
sprintf(pr->Msg, "%s - section: %s", geterrmsg(err, errStr), SectTxt[sect]); if (parser->ErrTok >= 0) strcpy(tok, parser->Tok[parser->ErrTok]);
else strcpy(tok, "");
// Retrieve ID label of object with input error // write error message to report file
// (No ID used for CONTROLS or REPORT sections) sprintf(pr->Msg, "Error %d: %s %s in %s section:",
switch (sect) err, geterrmsg(err, errStr), tok, SectTxt[sect]);
{
case _CONTROLS:
case _REPORT:
// don't append
break;
case _ENERGY:
sprintf(id, " id: %s", parser->Tok[1]);
break;
default:
sprintf(id, " id: %s", parser->Tok[0]);
break;
}
strcat(pr->Msg, id);
writeline(pr, pr->Msg); writeline(pr, pr->Msg);
// Echo input line for syntax errors, and // Echo input line
// errors in CONTROLS and OPTIONS sections writeline(pr, line);
if (sect == _CONTROLS || err == 201 || err == 213) writeline(pr, line);
else writeline(pr, "");
} }

View File

@@ -7,7 +7,7 @@ Description: parses network data from a line of an EPANET input file
Authors: see AUTHORS Authors: see AUTHORS
Copyright: see AUTHORS Copyright: see AUTHORS
License: see LICENSE License: see LICENSE
Last Updated: 11/10/2018 Last Updated: 01/01/2019
****************************************************************************** ******************************************************************************
*/ */
@@ -43,8 +43,24 @@ static int optionchoice(Project *, int);
static int optionvalue(Project *, int); static int optionvalue(Project *, int);
static int getpumpcurve(Project *, int); static int getpumpcurve(Project *, int);
static void changestatus(Network *, int, StatusType, double); static void changestatus(Network *, int, StatusType, double);
static int setError(Parser *, int, int);
int setError(Parser *parser, int tokindex, int errcode)
/*
**--------------------------------------------------------------
** Input: tokindex = index of input line token
** errcode = an error code
** Output: returns error code
** Purpose: records index of token from line of input associated
** with an error
**--------------------------------------------------------------
*/
{
parser->ErrTok = tokindex;
return errcode;
}
int juncdata(Project *pr) int juncdata(Project *pr)
/* /*
**-------------------------------------------------------------- **--------------------------------------------------------------
@@ -76,16 +92,16 @@ int juncdata(Project *pr)
net->Njuncs++; net->Njuncs++;
net->Nnodes++; net->Nnodes++;
njuncs = net->Njuncs; njuncs = net->Njuncs;
if (!addnodeID(net, net->Njuncs, parser->Tok[0])) return 215; if (!addnodeID(net, net->Njuncs, parser->Tok[0])) return setError(parser, 0, 215);
// Check for valid data // Check for valid data
if (n < 2) return 201; if (n < 2) return 201;
if (!getfloat(parser->Tok[1], &el)) return 202; if (!getfloat(parser->Tok[1], &el)) return setError(parser, 1, 202);
if (n >= 3 && !getfloat(parser->Tok[2], &y)) return 202; if (n >= 3 && !getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
if (n >= 4) if (n >= 4)
{ {
patlist = getlistitem(parser->Tok[3], parser->Patlist); patlist = getlistitem(parser->Tok[3], parser->Patlist);
if (patlist == NULL) return 205; if (patlist == NULL) return setError(parser, 3, 205);
p = patlist->i; p = patlist->i;
} }
@@ -155,11 +171,11 @@ int tankdata(Project *pr)
net->Nnodes++; net->Nnodes++;
i = parser->MaxJuncs + net->Ntanks; i = parser->MaxJuncs + net->Ntanks;
if (!addnodeID(net, i, parser->Tok[0])) return 215; if (!addnodeID(net, i, parser->Tok[0])) return setError(parser, 0, 215);
// Check for valid data // Check for valid data
if (n < 2) return (201); if (n < 2) return 201;
if (!getfloat(parser->Tok[1], &el)) return 202; if (!getfloat(parser->Tok[1], &el)) return setError(parser, 1, 202);
// Tank is reservoir // Tank is reservoir
if (n <= 3) if (n <= 3)
@@ -168,7 +184,7 @@ int tankdata(Project *pr)
if (n == 3) if (n == 3)
{ {
tmplist = getlistitem(parser->Tok[2], parser->Patlist); tmplist = getlistitem(parser->Tok[2], parser->Patlist);
if (tmplist == NULL) return 205; if (tmplist == NULL) return setError(parser, 2, 205);
pattern = tmplist->i; pattern = tmplist->i;
} }
} }
@@ -177,21 +193,25 @@ int tankdata(Project *pr)
// Tank is a storage tank // Tank is a storage tank
else else
{ {
if (!getfloat(parser->Tok[2], &initlevel)) return 202; if (!getfloat(parser->Tok[2], &initlevel)) return setError(parser, 2, 202);
if (!getfloat(parser->Tok[3], &minlevel)) return 202; if (!getfloat(parser->Tok[3], &minlevel)) return setError(parser, 3, 202);
if (!getfloat(parser->Tok[4], &maxlevel)) return 202; if (!getfloat(parser->Tok[4], &maxlevel)) return setError(parser, 4, 202);
if (!getfloat(parser->Tok[5], &diam)) return 202; if (!getfloat(parser->Tok[5], &diam)) return setError(parser, 5, 202);
if (diam < 0.0) return 202; if (n >= 7 && !getfloat(parser->Tok[6], &minvol)) return setError(parser, 6, 202);
if (n >= 7 && !getfloat(parser->Tok[6], &minvol)) return 202;
// If volume curve supplied check it exists // If volume curve supplied check it exists
if (n == 8) if (n == 8)
{ {
tmplist = getlistitem(parser->Tok[7], parser->Curvelist); tmplist = getlistitem(parser->Tok[7], parser->Curvelist);
if (tmplist == NULL) return 202; if (tmplist == NULL) return setError(parser, 7, 206);
curve = tmplist->i; 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);
if (maxlevel < 0.0) return setError(parser, 4, 209);
if (diam < 0.0) return setError(parser, 5, 209);
if (minvol < 0.0) return setError(parser, 6, 209);
} }
node = &net->Node[i]; node = &net->Node[i];
tank = &net->Tank[net->Ntanks]; tank = &net->Tank[net->Ntanks];
@@ -261,18 +281,20 @@ int pipedata(Project *pr)
if (net->Nlinks == parser->MaxLinks) return 200; if (net->Nlinks == parser->MaxLinks) return 200;
net->Npipes++; net->Npipes++;
net->Nlinks++; net->Nlinks++;
if (!addlinkID(net, net->Nlinks, parser->Tok[0])) return 215; if (!addlinkID(net, net->Nlinks, parser->Tok[0])) return setError(parser, 0, 215);
// Check for valid data // Check for valid data
if (n < 6) return 201; if (n < 6) return 201;
if ((j1 = findnode(net, parser->Tok[1])) == 0 || if ((j1 = findnode(net, parser->Tok[1])) == 0) return setError(parser, 1, 203);
(j2 = findnode(net, parser->Tok[2])) == 0) return 203; if ((j2 = findnode(net, parser->Tok[2])) == 0) return setError(parser, 2, 203);
if (j1 == j2) return 222; if (j1 == j2) return setError(parser, 0, 222);
if (!getfloat(parser->Tok[3], &length) || if (!getfloat(parser->Tok[3], &length)) return setError(parser, 3, 202);
!getfloat(parser->Tok[4], &diam) || if (length <= 0.0) return setError(parser, 3, 211);
!getfloat(parser->Tok[5], &rcoeff)) return 202; if (!getfloat(parser->Tok[4], &diam)) return setError(parser, 4, 202);
if (length <= 0.0 || diam <= 0.0 || rcoeff <= 0.0) return 202; if (diam <= 0.0) return setError(parser, 4, 211);
if (!getfloat(parser->Tok[5], &rcoeff)) return setError(parser, 5, 202);
if (rcoeff <= 0.0) setError(parser, 5, 211);
// Either a loss coeff. or a status is supplied // Either a loss coeff. or a status is supplied
if (n == 7) if (n == 7)
@@ -280,19 +302,19 @@ int pipedata(Project *pr)
if (match(parser->Tok[6], w_CV)) type = CVPIPE; if (match(parser->Tok[6], w_CV)) type = CVPIPE;
else if (match(parser->Tok[6], w_CLOSED)) status = CLOSED; else if (match(parser->Tok[6], w_CLOSED)) status = CLOSED;
else if (match(parser->Tok[6], w_OPEN)) status = OPEN; else if (match(parser->Tok[6], w_OPEN)) status = OPEN;
else if (!getfloat(parser->Tok[6], &lcoeff)) return (202); else if (!getfloat(parser->Tok[6], &lcoeff)) return setError(parser, 6, 202);
} }
// Both a loss coeff. and a status is supplied // Both a loss coeff. and a status is supplied
if (n == 8) if (n == 8)
{ {
if (!getfloat(parser->Tok[6], &lcoeff)) return 202; if (!getfloat(parser->Tok[6], &lcoeff)) return setError(parser, 6, 202);
if (match(parser->Tok[7], w_CV)) type = CVPIPE; if (match(parser->Tok[7], w_CV)) type = CVPIPE;
else if (match(parser->Tok[7], w_CLOSED)) status = CLOSED; else if (match(parser->Tok[7], w_CLOSED)) status = CLOSED;
else if (match(parser->Tok[7], w_OPEN)) status = OPEN; else if (match(parser->Tok[7], w_OPEN)) status = OPEN;
else return 202; else return setError(parser, 7, 213);
} }
if (lcoeff < 0.0) return 202; if (lcoeff < 0.0) return setError(parser, 6, 211);
// Save pipe data // Save pipe data
link = &net->Link[net->Nlinks]; link = &net->Link[net->Nlinks];
@@ -347,13 +369,13 @@ int pumpdata(Project *pr)
net->Npumps == parser->MaxPumps) return 200; net->Npumps == parser->MaxPumps) return 200;
net->Nlinks++; net->Nlinks++;
net->Npumps++; net->Npumps++;
if (!addlinkID(net, net->Nlinks, parser->Tok[0])) return 215; if (!addlinkID(net, net->Nlinks, parser->Tok[0])) return setError(parser, 0, 215);
// Check for valid data // Check for valid data
if (n < 4) return 201; if (n < 3) return 201;
if ((j1 = findnode(net, parser->Tok[1])) == 0 || if ((j1 = findnode(net, parser->Tok[1])) == 0) return setError(parser, 1, 203);
(j2 = findnode(net, parser->Tok[2])) == 0) return 203; if ((j2 = findnode(net, parser->Tok[2])) == 0) return setError(parser, 2, 203);
if (j1 == j2) return 222; if (j1 == j2) return setError(parser, 0, 222);
// Save pump data // Save pump data
link = &net->Link[net->Nlinks]; link = &net->Link[net->Nlinks];
@@ -378,6 +400,7 @@ int pumpdata(Project *pr)
pump->Upat = 0; pump->Upat = 0;
pump->Ecost = 0.0; pump->Ecost = 0.0;
pump->Epat = 0; pump->Epat = 0;
if (n < 4) return 0;
// If 4-th token is a number then input follows Version 1.x format // If 4-th token is a number then input follows Version 1.x format
// so retrieve pump curve parameters // so retrieve pump curve parameters
@@ -386,7 +409,7 @@ int pumpdata(Project *pr)
m = 1; m = 1;
for (j = 4; j < n; j++) for (j = 4; j < n; j++)
{ {
if (!getfloat(parser->Tok[j], &parser->X[m])) return 202; if (!getfloat(parser->Tok[j], &parser->X[m])) return setError(parser, j, 202);
m++; m++;
} }
return (getpumpcurve(pr, m)); return (getpumpcurve(pr, m));
@@ -400,26 +423,26 @@ int pumpdata(Project *pr)
if (match(parser->Tok[m - 1], w_POWER)) // Const. HP curve if (match(parser->Tok[m - 1], w_POWER)) // Const. HP curve
{ {
y = atof(parser->Tok[m]); y = atof(parser->Tok[m]);
if (y <= 0.0) return (202); if (y <= 0.0) return setError(parser, m, 202);
pump->Ptype = CONST_HP; pump->Ptype = CONST_HP;
link->Km = y; link->Km = y;
} }
else if (match(parser->Tok[m - 1], w_HEAD)) // Custom pump curve else if (match(parser->Tok[m - 1], w_HEAD)) // Custom pump curve
{ {
tmplist = getlistitem(parser->Tok[m], parser->Curvelist); tmplist = getlistitem(parser->Tok[m], parser->Curvelist);
if (tmplist == NULL) return 206; if (tmplist == NULL) return setError(parser, m, 206);
pump->Hcurve = tmplist->i; pump->Hcurve = tmplist->i;
} }
else if (match(parser->Tok[m - 1], w_PATTERN)) // Speed/status pattern else if (match(parser->Tok[m - 1], w_PATTERN)) // Speed/status pattern
{ {
tmplist = getlistitem(parser->Tok[m], parser->Patlist); tmplist = getlistitem(parser->Tok[m], parser->Patlist);
if (tmplist == NULL) return 205; if (tmplist == NULL) return setError(parser, m, 205);
pump->Upat = tmplist->i; pump->Upat = tmplist->i;
} }
else if (match(parser->Tok[m - 1], w_SPEED)) // Speed setting else if (match(parser->Tok[m - 1], w_SPEED)) // Speed setting
{ {
if (!getfloat(parser->Tok[m], &y)) return 202; if (!getfloat(parser->Tok[m], &y)) return setError(parser, m, 202);
if (y < 0.0) return 202; if (y < 0.0) return setError(parser, m, 211);
link->Kc = y; link->Kc = y;
} }
else return 201; else return 201;
@@ -460,13 +483,13 @@ int valvedata(Project *pr)
net->Nvalves == parser->MaxValves) return 200; net->Nvalves == parser->MaxValves) return 200;
net->Nvalves++; net->Nvalves++;
net->Nlinks++; net->Nlinks++;
if (!addlinkID(net, net->Nlinks, parser->Tok[0])) return 215; if (!addlinkID(net, net->Nlinks, parser->Tok[0])) return setError(parser, 0, 215);
// Check for valid data // Check for valid data
if (n < 6) return 201; if (n < 6) return 201;
if ((j1 = findnode(net, parser->Tok[1])) == 0 || if ((j1 = findnode(net, parser->Tok[1])) == 0) return setError(parser, 1, 203);
(j2 = findnode(net, parser->Tok[2])) == 0) return (203); if ((j2 = findnode(net, parser->Tok[2])) == 0) return setError(parser, 2, 203);
if (j1 == j2) return 222; if (j1 == j2) return setError(parser, 0, 222);
if (match(parser->Tok[4], w_PRV)) type = PRV; if (match(parser->Tok[4], w_PRV)) type = PRV;
else if (match(parser->Tok[4], w_PSV)) type = PSV; else if (match(parser->Tok[4], w_PSV)) type = PSV;
@@ -474,28 +497,30 @@ int valvedata(Project *pr)
else if (match(parser->Tok[4], w_FCV)) type = FCV; else if (match(parser->Tok[4], w_FCV)) type = FCV;
else if (match(parser->Tok[4], w_TCV)) type = TCV; else if (match(parser->Tok[4], w_TCV)) type = TCV;
else if (match(parser->Tok[4], w_GPV)) type = GPV; else if (match(parser->Tok[4], w_GPV)) type = GPV;
else return 201; else return setError(parser, 4, 213);
if (!getfloat(parser->Tok[3], &diam)) return 202; if (!getfloat(parser->Tok[3], &diam)) return setError(parser, 3, 202);
if (diam <= 0.0) return 202; if (diam <= 0.0) return setError(parser, 3, 211);
// Find headloss curve for GPV // Find headloss curve for GPV
if (type == GPV) if (type == GPV)
{ {
tmplist = getlistitem(parser->Tok[5], parser->Curvelist); tmplist = getlistitem(parser->Tok[5], parser->Curvelist);
if (tmplist == NULL) return 206; if (tmplist == NULL) return setError(parser, 5, 206);
setting = tmplist->i; setting = tmplist->i;
net->Curve[tmplist->i].Type = H_CURVE; net->Curve[tmplist->i].Type = HLOSS_CURVE;
status = OPEN; status = OPEN;
} }
else if (!getfloat(parser->Tok[5], &setting)) return 202; else if (!getfloat(parser->Tok[5], &setting)) return setError(parser, 5, 202);
if (n >= 7 && !getfloat(parser->Tok[6], &lcoeff)) return 202; if (n >= 7 && !getfloat(parser->Tok[6], &lcoeff)) return setError(parser, 6, 202);
// Check that PRV, PSV, or FCV not connected to a tank & // Check for illegal connections
// check for illegal connections between pairs of valves if (valvecheck(pr, type, j1, j2))
if ((j1 > net->Njuncs || j2 > net->Njuncs) && {
(type == PRV || type == PSV || type == FCV)) return 219; if (j1 > net->Njuncs) return setError(parser, 1, 219);
if (!valvecheck(pr, type, j1, j2)) return 220; else if (j2 > net->Njuncs) return setError(parser, 2, 219);
else return setError(parser, -1, 220);
}
// Save valve data // Save valve data
link = &net->Link[net->Nlinks]; link = &net->Link[net->Nlinks];
@@ -542,12 +567,12 @@ int patterndata(Project *pr)
if (parser->PrevPat != NULL && if (parser->PrevPat != NULL &&
strcmp(parser->Tok[0], parser->PrevPat->ID) == 0) p = parser->PrevPat; strcmp(parser->Tok[0], parser->PrevPat->ID) == 0) p = parser->PrevPat;
else p = getlistitem(parser->Tok[0], parser->Patlist); else p = getlistitem(parser->Tok[0], parser->Patlist);
if (p == NULL) return 205; if (p == NULL) return setError(parser, 0, 205);
// Add parsed multipliers to the pattern // Add parsed multipliers to the pattern
for (i = 1; i <= n; i++) for (i = 1; i <= n; i++)
{ {
if (!getfloat(parser->Tok[i], &x)) return 202; if (!getfloat(parser->Tok[i], &x)) return setError(parser, i, 202);
f = (SFloatlist *)malloc(sizeof(SFloatlist)); f = (SFloatlist *)malloc(sizeof(SFloatlist));
if (f == NULL) return 101; if (f == NULL) return 101;
f->value = x; f->value = x;
@@ -587,11 +612,11 @@ int curvedata(Project *pr)
if (parser->PrevCurve != NULL && if (parser->PrevCurve != NULL &&
strcmp(parser->Tok[0], parser->PrevCurve->ID) == 0) c = parser->PrevCurve; strcmp(parser->Tok[0], parser->PrevCurve->ID) == 0) c = parser->PrevCurve;
else c = getlistitem(parser->Tok[0], parser->Curvelist); else c = getlistitem(parser->Tok[0], parser->Curvelist);
if (c == NULL) return 205; if (c == NULL) return setError(parser, 0, 206);
// Check for valid data // Check for valid data
if (!getfloat(parser->Tok[1], &x)) return 202; if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
if (!getfloat(parser->Tok[2], &y)) return 202; if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
// Add new data point to curve // Add new data point to curve
fx = (SFloatlist *)malloc(sizeof(SFloatlist)); fx = (SFloatlist *)malloc(sizeof(SFloatlist));
@@ -636,11 +661,11 @@ int coordata(Project *pr)
// Check for valid node ID // Check for valid node ID
if (parser->Ntokens < 3) return 201; if (parser->Ntokens < 3) return 201;
if ((j = findnode(net, parser->Tok[0])) == 0) return 203; if ((j = findnode(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
// Check for valid data // Check for valid data
if (!getfloat(parser->Tok[1], &x)) return 202; if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
if (!getfloat(parser->Tok[2], &y)) return 202; if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
// Save coord data // Save coord data
node = &net->Node[j]; node = &net->Node[j];
@@ -678,23 +703,23 @@ int demanddata(Project *pr)
// Extract data from tokens // Extract data from tokens
n = parser->Ntokens; n = parser->Ntokens;
if (n < 2) return 201; if (n < 2) return 201;
if (!getfloat(parser->Tok[1], &y)) return 202; if (!getfloat(parser->Tok[1], &y)) return setError(parser, 1, 202);
// If MULTIPLY command, save multiplier // If MULTIPLY command, save multiplier
if (match(parser->Tok[0], w_MULTIPLY)) if (match(parser->Tok[0], w_MULTIPLY))
{ {
if (y <= 0.0) return 202; if (y <= 0.0) return setError(parser, 1, 213);
else hyd->Dmult = y; else hyd->Dmult = y;
return 0; return 0;
} }
// Otherwise find node (and pattern) being referenced // Otherwise find node (and pattern) being referenced
if ((j = findnode(net, parser->Tok[0])) == 0) return 208; if ((j = findnode(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
if (j > net->Njuncs) return 208; if (j > net->Njuncs) return 0;
if (n >= 3) if (n >= 3)
{ {
patlist = getlistitem(parser->Tok[2], parser->Patlist); patlist = getlistitem(parser->Tok[2], parser->Patlist);
if (patlist == NULL) return 205; if (patlist == NULL) return setError(parser, 2, 205);
p = patlist->i; p = patlist->i;
} }
@@ -761,11 +786,11 @@ int controldata(Project *pr)
// Check that controlled link exists // Check that controlled link exists
k = findlink(net, parser->Tok[1]); k = findlink(net, parser->Tok[1]);
if (k == 0) return 204; if (k == 0) return setError(parser, 1, 204);
// Cannot control a check valve // Cannot control a check valve
linktype = net->Link[k].Type; linktype = net->Link[k].Type;
if (linktype == CVPIPE) return 207; if (linktype == CVPIPE) return setError(parser, 1, 207);
// Parse control setting into a status level or numerical setting // Parse control setting into a status level or numerical setting
if (match(parser->Tok[2], w_OPEN)) if (match(parser->Tok[2], w_OPEN))
@@ -780,8 +805,8 @@ int controldata(Project *pr)
if (linktype == PUMP) setting = 0.0; if (linktype == PUMP) setting = 0.0;
if (linktype == GPV) setting = net->Link[k].Kc; if (linktype == GPV) setting = net->Link[k].Kc;
} }
else if (linktype == GPV) return 206; else if (linktype == GPV) return setError(parser, 1, 207);
else if (!getfloat(parser->Tok[2], &setting)) return 202; else if (!getfloat(parser->Tok[2], &setting)) return setError(parser, 2, 202);
// Set status for pump in case speed setting was supplied // Set status for pump in case speed setting was supplied
// or for pipe if numerical setting was supplied // or for pipe if numerical setting was supplied
@@ -789,7 +814,7 @@ int controldata(Project *pr)
{ {
if (setting != MISSING) if (setting != MISSING)
{ {
if (setting < 0.0) return 202; if (setting < 0.0) return setError(parser, 2, 211);
else if (setting == 0.0) status = CLOSED; else if (setting == 0.0) status = CLOSED;
else status = OPEN; else status = OPEN;
} }
@@ -801,10 +826,10 @@ int controldata(Project *pr)
else else
{ {
if (n < 8) return 201; if (n < 8) return 201;
if ((i = findnode(net, parser->Tok[5])) == 0) return 203; if ((i = findnode(net, parser->Tok[5])) == 0) return setError(parser, 5, 203);
if (match(parser->Tok[6], w_BELOW)) ctltype = LOWLEVEL; if (match(parser->Tok[6], w_BELOW)) ctltype = LOWLEVEL;
else if (match(parser->Tok[6], w_ABOVE)) ctltype = HILEVEL; else if (match(parser->Tok[6], w_ABOVE)) ctltype = HILEVEL;
else return 201; else return setError(parser, 6, 213);
} }
// Parse control level or time // Parse control level or time
@@ -814,11 +839,11 @@ int controldata(Project *pr)
case TIMEOFDAY: case TIMEOFDAY:
if (n == 6) time = hour(parser->Tok[5], ""); if (n == 6) time = hour(parser->Tok[5], "");
if (n == 7) time = hour(parser->Tok[5], parser->Tok[6]); if (n == 7) time = hour(parser->Tok[5], parser->Tok[6]);
if (time < 0.0) return 201; if (time < 0.0) return setError(parser, 5, 213);
break; break;
case LOWLEVEL: case LOWLEVEL:
case HILEVEL: case HILEVEL:
if (!getfloat(parser->Tok[7], &level)) return 202; if (!getfloat(parser->Tok[7], &level)) return setError(parser, 7, 202);
break; break;
} }
@@ -866,7 +891,7 @@ int sourcedata(Project *pr)
// Check for enough tokens & that source node exists // Check for enough tokens & that source node exists
n = parser->Ntokens; n = parser->Ntokens;
if (n < 2) return 201; if (n < 2) return 201;
if ((j = findnode(net, parser->Tok[0])) == 0) return 203; if ((j = findnode(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
// Parse source type // Parse source type
// NOTE: Under old 1.1 format, SourceType not supplied so // NOTE: Under old 1.1 format, SourceType not supplied so
@@ -879,14 +904,18 @@ int sourcedata(Project *pr)
else i = 1; else i = 1;
// Parse source quality // Parse source quality
if (!getfloat(parser->Tok[i], &c0)) return 202; if (!getfloat(parser->Tok[i], &c0))
{
if (i == 1) return setError(parser, i, 213);
else return setError(parser, i, 202);
}
// Parse optional source time pattern // Parse optional source time pattern
if (n > i + 1 && strlen(parser->Tok[i + 1]) > 0 && 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); patlist = getlistitem(parser->Tok[i + 1], parser->Patlist);
if (patlist == NULL) return (205); if (patlist == NULL) return setError(parser, i+1, 205);
p = patlist->i; p = patlist->i;
} }
@@ -925,12 +954,12 @@ int emitterdata(Project *pr)
// Check that node exists & is a junction // Check that node exists & is a junction
n = parser->Ntokens; n = parser->Ntokens;
if (n < 2) return 201; if (n < 2) return 201;
if ((j = findnode(net, parser->Tok[0])) == 0) return 203; if ((j = findnode(net, parser->Tok[0])) == 0) return setError(parser, 0, 203);
if (j > net->Njuncs) return 209; if (j > net->Njuncs) return 0;
// Parse emitter flow coeff. // Parse emitter flow coeff.
if (!getfloat(parser->Tok[1], &k)) return 202; if (!getfloat(parser->Tok[1], &k)) return setError(parser, 1, 202);
if (k < 0.0) return 202; if (k < 0.0) return setError(parser, 1, 209);
net->Node[j].Ke = k; net->Node[j].Ke = k;
return 0; return 0;
} }
@@ -956,15 +985,16 @@ int qualdata(Project *pr)
double c0; double c0;
Snode *Node = net->Node; Snode *Node = net->Node;
if (net->Nnodes == 0) return 208; // No nodes defined yet if (net->Nnodes == 0) return setError(parser, 0, 203); // No nodes defined yet
n = parser->Ntokens; n = parser->Ntokens;
if (n < 2) return 0; if (n < 2) return 0;
// Single node name supplied // Single node name supplied
if (n == 2) if (n == 2)
{ {
if ((j = findnode(net,parser->Tok[0])) == 0) return 0; if ((j = findnode(net,parser->Tok[0])) == 0) return setError(parser, 0, 203);
if (!getfloat(parser->Tok[1], &c0)) return 209; if (!getfloat(parser->Tok[1], &c0)) return setError(parser, 1, 202);
if (c0 < 0.0) return setError(parser, 1, 209);
Node[j].C0 = c0; Node[j].C0 = c0;
} }
@@ -972,7 +1002,8 @@ int qualdata(Project *pr)
else else
{ {
// Parse quality value // Parse quality value
if (!getfloat(parser->Tok[2], &c0)) return 209; if (!getfloat(parser->Tok[2], &c0)) return setError(parser, 2, 202);
if (c0 < 0.0) return setError(parser, 2, 209);
// If numerical node names supplied, then use numerical comparison // If numerical node names supplied, then use numerical comparison
// to find which nodes are assigned the quality value // to find which nodes are assigned the quality value
@@ -1034,23 +1065,23 @@ int reactdata(Project *pr)
// Keyword is ORDER // Keyword is ORDER
if (match(parser->Tok[0], w_ORDER)) if (match(parser->Tok[0], w_ORDER))
{ {
if (!getfloat(parser->Tok[n - 1], &y)) return 213; if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n-1, 202);
if (match(parser->Tok[1], w_BULK)) qual->BulkOrder = y; if (match(parser->Tok[1], w_BULK)) qual->BulkOrder = y;
else if (match(parser->Tok[1], w_TANK)) qual->TankOrder = y; else if (match(parser->Tok[1], w_TANK)) qual->TankOrder = y;
else if (match(parser->Tok[1], w_WALL)) else if (match(parser->Tok[1], w_WALL))
{ {
if (y == 0.0) qual->WallOrder = 0.0; if (y == 0.0) qual->WallOrder = 0.0;
else if (y == 1.0) qual->WallOrder = 1.0; else if (y == 1.0) qual->WallOrder = 1.0;
else return 213; else return setError(parser, n-1, 213);
} }
else return 213; else return setError(parser, 1, 213);
return 0; return 0;
} }
// Keyword is ROUGHNESS // Keyword is ROUGHNESS
if (match(parser->Tok[0], w_ROUGHNESS)) if (match(parser->Tok[0], w_ROUGHNESS))
{ {
if (!getfloat(parser->Tok[n - 1], &y)) return 213; if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n-1, 202);
qual->Rfactor = y; qual->Rfactor = y;
return 0; return 0;
} }
@@ -1058,7 +1089,7 @@ int reactdata(Project *pr)
// Keyword is LIMITING // Keyword is LIMITING
if (match(parser->Tok[0], w_LIMITING)) if (match(parser->Tok[0], w_LIMITING))
{ {
if (!getfloat(parser->Tok[n - 1], &y)) return 213; if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n-1, 202);
qual->Climit = y; qual->Climit = y;
return 0; return 0;
} }
@@ -1066,10 +1097,10 @@ int reactdata(Project *pr)
// Keyword is GLOBAL // Keyword is GLOBAL
if (match(parser->Tok[0], w_GLOBAL)) if (match(parser->Tok[0], w_GLOBAL))
{ {
if (!getfloat(parser->Tok[n - 1], &y)) return 213; if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n-1, 202);
if (match(parser->Tok[1], w_BULK)) qual->Kbulk = y; if (match(parser->Tok[1], w_BULK)) qual->Kbulk = y;
else if (match(parser->Tok[1], w_WALL)) qual->Kwall = y; else if (match(parser->Tok[1], w_WALL)) qual->Kwall = y;
else return 201; else return setError(parser, 1, 213);
return 0; return 0;
} }
@@ -1077,7 +1108,7 @@ int reactdata(Project *pr)
if (match(parser->Tok[0], w_BULK)) item = 1; if (match(parser->Tok[0], w_BULK)) item = 1;
else if (match(parser->Tok[0], w_WALL)) item = 2; else if (match(parser->Tok[0], w_WALL)) item = 2;
else if (match(parser->Tok[0], w_TANK)) item = 3; else if (match(parser->Tok[0], w_TANK)) item = 3;
else return 201; else return setError(parser, 0, 213);
// Save the first link/node ID in the first token // Save the first link/node ID in the first token
strcpy(parser->Tok[0], parser->Tok[1]); strcpy(parser->Tok[0], parser->Tok[1]);
@@ -1086,7 +1117,7 @@ int reactdata(Project *pr)
if (item == 3) if (item == 3)
{ {
// Get the rate coeff. value // Get the rate coeff. value
if (!getfloat(parser->Tok[n - 1], &y)) return 209; if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n-1, 202);
// Case where just a single tank is specified // Case where just a single tank is specified
if (n == 3) if (n == 3)
@@ -1119,7 +1150,7 @@ int reactdata(Project *pr)
else else
{ {
// Get the rate coeff. value // Get the rate coeff. value
if (!getfloat(parser->Tok[n - 1], &y)) return 211; /* Rate coeff. */ if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n-1, 202);
if (net->Nlinks == 0) return 0; if (net->Nlinks == 0) return 0;
// Case where just a single link is specified // Case where just a single link is specified
@@ -1181,15 +1212,18 @@ int mixingdata(Project *pr)
double v; // Mixing zone volume fraction double v; // Mixing zone volume fraction
// Check for valid data // Check for valid data
if (net->Nnodes == 0) return 208; if (net->Nnodes == 0) return setError(parser, 0, 203);
n = parser->Ntokens; n = parser->Ntokens;
if (n < 2) return 0; if (n < 2) return 0;
if ((j = findnode(net, parser->Tok[0])) <= net->Njuncs) return 0; j = findnode(net, parser->Tok[0]);
if ((m = findmatch(parser->Tok[1], MixTxt)) < 0) return 201; if (j == 0) return setError(parser, 0, 203);
if (j <= net->Njuncs) return 0;
if ((m = findmatch(parser->Tok[1], MixTxt)) < 0) return setError(parser, 1, 213);
// Find mixing zone volume fraction (which can't be 0) // Find mixing zone volume fraction (which can't be 0)
v = 1.0; v = 1.0;
if ((m == MIX2) && (n == 3) && (!getfloat(parser->Tok[2], &v))) return 209; if ((m == MIX2) && (n == 3) &&
(!getfloat(parser->Tok[2], &v))) return setError(parser, 2, 202);
if (v == 0.0) v = 1.0; if (v == 0.0) v = 1.0;
// Assign mixing data to tank (return if tank is a reservoir) // Assign mixing data to tank (return if tank is a reservoir)
@@ -1221,26 +1255,29 @@ int statusdata(Project *pr)
double y = 0.0; double y = 0.0;
char status = ACTIVE; char status = ACTIVE;
if (net->Nlinks == 0) return 210; if (net->Nlinks == 0) return setError(parser, 0, 204);
n = parser->Ntokens - 1; n = parser->Ntokens - 1;
if (n < 1) return 201; if (n < 1) return 201;
// Check for legal status setting // Check for legal status setting
if (match(parser->Tok[n], w_OPEN)) status = OPEN; if (match(parser->Tok[n], w_OPEN)) status = OPEN;
else if (match(parser->Tok[n], w_CLOSED)) status = CLOSED; else if (match(parser->Tok[n], w_CLOSED)) status = CLOSED;
else if (!getfloat(parser->Tok[n], &y)) return 211; else
if (y < 0.0) return 211; {
if (!getfloat(parser->Tok[n], &y)) return setError(parser, n, 202);
if (y < 0.0) return setError(parser, n, 211);
}
// A single link ID was supplied // A single link ID was supplied
if (n == 1) if (n == 1)
{ {
if ((j = findlink(net, parser->Tok[0])) == 0) return 0; if ((j = findlink(net, parser->Tok[0])) == 0) return setError(parser, 0, 204);
// Cannot change status of a Check Valve // Cannot change status of a Check Valve
if (net->Link[j].Type == CVPIPE) return 211; if (net->Link[j].Type == CVPIPE) return setError(parser, 0, 207);
// Cannot change setting for a GPV // Cannot change setting for a GPV
if (net->Link[j].Type == GPV && status == ACTIVE) return 211; if (net->Link[j].Type == GPV && status == ACTIVE) return setError(parser, 0, 207);
changestatus(net, j, status, y); changestatus(net, j, status, y);
} }
@@ -1297,7 +1334,8 @@ int energydata(Project *pr)
// First keyword is DEMAND // First keyword is DEMAND
if (match(parser->Tok[0], w_DMNDCHARGE)) if (match(parser->Tok[0], w_DMNDCHARGE))
{ {
if (!getfloat(parser->Tok[2], &y)) return 213; if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
if (y < 0.0) return setError(parser, 2, 213);
hyd->Dcost = y; hyd->Dcost = y;
return 0; return 0;
} }
@@ -1313,20 +1351,17 @@ int energydata(Project *pr)
{ {
if (n < 4) return 201; if (n < 4) return 201;
k = findlink(net,parser->Tok[1]); k = findlink(net,parser->Tok[1]);
if (k == 0) return 216; if (k == 0) return setError(parser, 1, 216);
if (Link[k].Type != PUMP) return 216; if (Link[k].Type != PUMP) return setError(parser, 1, 216);
j = findpump(net, k); j = findpump(net, k);
} }
else return 201; else return setError(parser, 0, 213);
// PRICE parameter being set // PRICE parameter being set
if (match(parser->Tok[n - 2], w_PRICE)) if (match(parser->Tok[n - 2], w_PRICE))
{ {
if (!getfloat(parser->Tok[n - 1], &y)) if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n-1, 202);
{ if (y < 0.0) return setError(parser, n-1, 217);
if (j == 0) return 213;
else return 217;
}
if (j == 0) hyd->Ecost = y; if (j == 0) hyd->Ecost = y;
else Pump[j].Ecost = y; else Pump[j].Ecost = y;
return 0; return 0;
@@ -1336,11 +1371,7 @@ int energydata(Project *pr)
else if (match(parser->Tok[n - 2], w_PATTERN)) else if (match(parser->Tok[n - 2], w_PATTERN))
{ {
listitem = getlistitem(parser->Tok[n - 1], parser->Patlist); listitem = getlistitem(parser->Tok[n - 1], parser->Patlist);
if (listitem == NULL) if (listitem == NULL) return setError(parser, n - 1, 205);
{
if (j == 0) return 213;
else return 217;
}
if (j == 0) hyd->Epat = listitem->i; if (j == 0) hyd->Epat = listitem->i;
else Pump[j].Epat = listitem->i; else Pump[j].Epat = listitem->i;
return 0; return 0;
@@ -1351,16 +1382,16 @@ int energydata(Project *pr)
{ {
if (j == 0) if (j == 0)
{ {
if (!getfloat(parser->Tok[n - 1], &y)) return 213; if (!getfloat(parser->Tok[n - 1], &y)) return setError(parser, n - 1, 202);
if (y <= 0.0) return 213; if (y <= 0.0) return setError(parser, n - 1, 217);
hyd->Epump = y; hyd->Epump = y;
} }
else else
{ {
listitem = getlistitem(parser->Tok[n - 1], parser->Curvelist); listitem = getlistitem(parser->Tok[n - 1], parser->Curvelist);
if (listitem == NULL) return 217; if (listitem == NULL) return setError(parser, n - 1, 206);
Pump[j].Ecurve = listitem->i; Pump[j].Ecurve = listitem->i;
net->Curve[listitem->i].Type = E_CURVE; net->Curve[listitem->i].Type = EFFIC_CURVE;
} }
return 0; return 0;
} }
@@ -1402,8 +1433,8 @@ int reportdata(Project *pr)
// Value for page size // Value for page size
if (match(parser->Tok[0], w_PAGE)) if (match(parser->Tok[0], w_PAGE))
{ {
if (!getfloat(parser->Tok[n], &y)) return 213; if (!getfloat(parser->Tok[n], &y)) return setError(parser, n, 202);
if (y < 0.0 || y > 255.0) return 213; if (y < 0.0 || y > 255.0) return setError(parser, n, 213);
rpt->PageSize = (int)y; rpt->PageSize = (int)y;
return 0; return 0;
} }
@@ -1448,10 +1479,10 @@ int reportdata(Project *pr)
else if (match(parser->Tok[n], w_ALL)) rpt->Nodeflag = 1; // All nodes else if (match(parser->Tok[n], w_ALL)) rpt->Nodeflag = 1; // All nodes
else else
{ {
if (net->Nnodes == 0) return 208; if (net->Nnodes == 0) return setError(parser, 1, 203);
for (i = 1; i <= n; i++) for (i = 1; i <= n; i++)
{ {
if ((j = findnode(net, parser->Tok[i])) == 0) return 208; if ((j = findnode(net, parser->Tok[i])) == 0) return setError(parser, i, 203);
net->Node[j].Rpt = 1; net->Node[j].Rpt = 1;
} }
rpt->Nodeflag = 2; rpt->Nodeflag = 2;
@@ -1466,10 +1497,10 @@ int reportdata(Project *pr)
else if (match(parser->Tok[n], w_ALL)) rpt->Linkflag = 1; else if (match(parser->Tok[n], w_ALL)) rpt->Linkflag = 1;
else else
{ {
if (net->Nlinks == 0) return 210; if (net->Nlinks == 0) return setError(parser, 1, 204);
for (i = 1; i <= n; i++) for (i = 1; i <= n; i++)
{ {
if ((j = findlink(net, parser->Tok[i])) == 0) return 210; if ((j = findlink(net, parser->Tok[i])) == 0) return setError(parser, i, 204);
net->Link[j].Rpt = 1; net->Link[j].Rpt = 1;
} }
rpt->Linkflag = 2; rpt->Linkflag = 2;
@@ -1483,7 +1514,7 @@ int reportdata(Project *pr)
else i = findmatch(parser->Tok[0], Fldname); else i = findmatch(parser->Tok[0], Fldname);
if (i >= 0) if (i >= 0)
{ {
if (i > FRICTION) return 201; if (i > FRICTION) return setError(parser, 0, 213);
if (parser->Ntokens == 1 || match(parser->Tok[1], w_YES)) if (parser->Ntokens == 1 || match(parser->Tok[1], w_YES))
{ {
rpt->Field[i].Enabled = TRUE; rpt->Field[i].Enabled = TRUE;
@@ -1497,14 +1528,14 @@ int reportdata(Project *pr)
} }
// Get field qualifier type // Get field qualifier type
if (parser->Ntokens < 3) return (201); if (parser->Ntokens < 3) return 201;
if (match(parser->Tok[1], w_BELOW)) j = LOW; if (match(parser->Tok[1], w_BELOW)) j = LOW;
else if (match(parser->Tok[1], w_ABOVE)) j = HI; else if (match(parser->Tok[1], w_ABOVE)) j = HI;
else if (match(parser->Tok[1], w_PRECISION)) j = PREC; else if (match(parser->Tok[1], w_PRECISION)) j = PREC;
else return 201; else return setError(parser, 1, 213);
// Get field qualifier value // Get field qualifier value
if (!getfloat(parser->Tok[2], &y)) return 201; if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
if (j == PREC) if (j == PREC)
{ {
rpt->Field[i].Enabled = TRUE; rpt->Field[i].Enabled = TRUE;
@@ -1566,7 +1597,7 @@ int timedata(Project *pr)
else if (match(parser->Tok[n], w_MIN)) rpt->Tstatflag = MIN; else if (match(parser->Tok[n], w_MIN)) rpt->Tstatflag = MIN;
else if (match(parser->Tok[n], w_MAX)) rpt->Tstatflag = MAX; else if (match(parser->Tok[n], w_MAX)) rpt->Tstatflag = MAX;
else if (match(parser->Tok[n], w_RANGE)) rpt->Tstatflag = RANGE; else if (match(parser->Tok[n], w_RANGE)) rpt->Tstatflag = RANGE;
else return 201; else return setError(parser, n, 213);
return 0; return 0;
} }
@@ -1581,7 +1612,10 @@ int timedata(Project *pr)
{ {
if ((y = hour(parser->Tok[n], "")) < 0.0) if ((y = hour(parser->Tok[n], "")) < 0.0)
{ {
if ((y = hour(parser->Tok[n - 1], parser->Tok[n])) < 0.0) return 213; if ((y = hour(parser->Tok[n - 1], parser->Tok[n])) < 0.0)
{
return setError(parser, n-1, 213);
}
} }
} }
t = (long)(3600.0 * y + 0.5); t = (long)(3600.0 * y + 0.5);
@@ -1596,16 +1630,16 @@ int timedata(Project *pr)
{ {
if (match(parser->Tok[1], w_TIME)) time->Pstep = t; if (match(parser->Tok[1], w_TIME)) time->Pstep = t;
else if (match(parser->Tok[1], w_START)) time->Pstart = t; else if (match(parser->Tok[1], w_START)) time->Pstart = t;
else return 201; else return setError(parser, 1, 213);
} }
else if (match(parser->Tok[0], w_REPORT)) else if (match(parser->Tok[0], w_REPORT))
{ {
if (match(parser->Tok[1], w_TIME)) time->Rstep = t; if (match(parser->Tok[1], w_TIME)) time->Rstep = t;
else if (match(parser->Tok[1], w_START)) time->Rstart = t; else if (match(parser->Tok[1], w_START)) time->Rstart = t;
else return 201; else return setError(parser, 1, 213);
} }
else if (match(parser->Tok[0], w_START)) time->Tstart = t % SECperDAY; else if (match(parser->Tok[0], w_START)) time->Tstart = t % SECperDAY;
else return 201; else return setError(parser, 0, 213);
return 0; return 0;
} }
@@ -1633,7 +1667,7 @@ int optiondata(Project *pr)
int optionchoice(Project *pr, int n) int optionchoice(Project *pr, int n)
/* /*
**-------------------------------------------------------------- **--------------------------------------------------------------
** Input: n = index of last input token saved in par->Tok[] ** Input: n = index of last input token
** Output: returns error code or 0 if option belongs to ** Output: returns error code or 0 if option belongs to
** those listed below, or -1 otherwise ** those listed below, or -1 otherwise
** Purpose: processes fixed choice [OPTIONS] data ** Purpose: processes fixed choice [OPTIONS] data
@@ -1678,7 +1712,7 @@ int optionchoice(Project *pr, int n)
else if (match(parser->Tok[1], w_CMD)) parser->Flowflag = CMD; else if (match(parser->Tok[1], w_CMD)) parser->Flowflag = CMD;
else if (match(parser->Tok[1], w_MLD)) parser->Flowflag = MLD; else if (match(parser->Tok[1], w_MLD)) parser->Flowflag = MLD;
else if (match(parser->Tok[1], w_SI)) parser->Flowflag = LPS; else if (match(parser->Tok[1], w_SI)) parser->Flowflag = LPS;
else return 201; else return setError(parser, 1, 213);
} }
// PRESSURE units // PRESSURE units
@@ -1689,7 +1723,7 @@ int optionchoice(Project *pr, int n)
else if (match(parser->Tok[1], w_PSI)) parser->Pressflag = PSI; else if (match(parser->Tok[1], w_PSI)) parser->Pressflag = PSI;
else if (match(parser->Tok[1], w_KPA)) parser->Pressflag = KPA; else if (match(parser->Tok[1], w_KPA)) parser->Pressflag = KPA;
else if (match(parser->Tok[1], w_METERS)) parser->Pressflag = METERS; else if (match(parser->Tok[1], w_METERS)) parser->Pressflag = METERS;
else return 201; else return setError(parser, 1, 213);
} }
// HEADLOSS formula // HEADLOSS formula
@@ -1699,7 +1733,7 @@ int optionchoice(Project *pr, int n)
else if (match(parser->Tok[1], w_HW)) hyd->Formflag = HW; else if (match(parser->Tok[1], w_HW)) hyd->Formflag = HW;
else if (match(parser->Tok[1], w_DW)) hyd->Formflag = DW; else if (match(parser->Tok[1], w_DW)) hyd->Formflag = DW;
else if (match(parser->Tok[1], w_CM)) hyd->Formflag = CM; else if (match(parser->Tok[1], w_CM)) hyd->Formflag = CM;
else return 201; else return setError(parser, 1, 213);
} }
// HYDRUALICS USE/SAVE file option // HYDRUALICS USE/SAVE file option
@@ -1708,14 +1742,14 @@ int optionchoice(Project *pr, int n)
if (n < 2) return 0; if (n < 2) return 0;
else if (match(parser->Tok[1], w_USE)) out->Hydflag = USE; else if (match(parser->Tok[1], w_USE)) out->Hydflag = USE;
else if (match(parser->Tok[1], w_SAVE)) out->Hydflag = SAVE; else if (match(parser->Tok[1], w_SAVE)) out->Hydflag = SAVE;
else return 201; else return setError(parser, 1, 213);
strncpy(out->HydFname, parser->Tok[2], MAXFNAME); strncpy(out->HydFname, parser->Tok[2], MAXFNAME);
} }
// Water QUALITY option // Water QUALITY option
else if (match(parser->Tok[0], w_QUALITY)) else if (match(parser->Tok[0], w_QUALITY))
{ {
if (n < 1) return (0); if (n < 1) return 0;
else if (match(parser->Tok[1], w_NONE)) qual->Qualflag = NONE; else if (match(parser->Tok[1], w_NONE)) qual->Qualflag = NONE;
else if (match(parser->Tok[1], w_CHEM)) qual->Qualflag = CHEM; else if (match(parser->Tok[1], w_CHEM)) qual->Qualflag = CHEM;
else if (match(parser->Tok[1], w_AGE)) qual->Qualflag = AGE; else if (match(parser->Tok[1], w_AGE)) qual->Qualflag = AGE;
@@ -1730,10 +1764,10 @@ int optionchoice(Project *pr, int n)
{ {
// Copy Trace Node ID to parser->Tok[0] for error reporting // Copy Trace Node ID to parser->Tok[0] for error reporting
strcpy(parser->Tok[0], ""); strcpy(parser->Tok[0], "");
if (n < 2) return 212; if (n < 2) return 201;
strcpy(parser->Tok[0], parser->Tok[2]); strcpy(parser->Tok[0], parser->Tok[2]);
qual->TraceNode = findnode(net, parser->Tok[2]); qual->TraceNode = findnode(net, parser->Tok[2]);
if (qual->TraceNode == 0) return 212; if (qual->TraceNode == 0) return setError(parser, 2, 212);
strncpy(qual->ChemName, u_PERCENT, MAXID); strncpy(qual->ChemName, u_PERCENT, MAXID);
strncpy(qual->ChemUnits, parser->Tok[2], MAXID); strncpy(qual->ChemUnits, parser->Tok[2], MAXID);
} }
@@ -1766,7 +1800,7 @@ int optionchoice(Project *pr, int n)
if (n >= 2) hyd->ExtraIter = atoi(parser->Tok[2]); if (n >= 2) hyd->ExtraIter = atoi(parser->Tok[2]);
else hyd->ExtraIter = 0; else hyd->ExtraIter = 0;
} }
else return 201; else return setError(parser, 1, 213);
} }
// Default demand PATTERN // Default demand PATTERN
@@ -1782,7 +1816,7 @@ int optionchoice(Project *pr, int n)
if (n < 2) return 0; if (n < 2) return 0;
if (!match(parser->Tok[1], w_MODEL)) return -1; if (!match(parser->Tok[1], w_MODEL)) return -1;
choice = findmatch(parser->Tok[2], DemandModelTxt); choice = findmatch(parser->Tok[2], DemandModelTxt);
if (choice < 0) return 201; if (choice < 0) return setError(parser, 2, 213);
hyd->DemandModel = choice; hyd->DemandModel = choice;
} }
@@ -1844,12 +1878,12 @@ int optionvalue(Project *pr, int n)
if (n < nvalue) return 0; if (n < nvalue) return 0;
// Check for valid numerical input // Check for valid numerical input
if (!getfloat(parser->Tok[nvalue], &y)) return 213; if (!getfloat(parser->Tok[nvalue], &y)) return setError(parser, nvalue, 202);
// Quality tolerance option (which can be 0) // Quality tolerance option (which can be 0)
if (match(tok0, w_TOLERANCE)) if (match(tok0, w_TOLERANCE))
{ {
if (y < 0.0) return 213; if (y < 0.0) return setError(parser, nvalue, 213);
qual->Ctol = y; qual->Ctol = y;
return 0; return 0;
} }
@@ -1857,7 +1891,7 @@ int optionvalue(Project *pr, int n)
// Diffusivity // Diffusivity
if (match(tok0, w_DIFFUSIVITY)) if (match(tok0, w_DIFFUSIVITY))
{ {
if (y < 0.0) return 213; if (y < 0.0) return setError(parser, nvalue, 213);
qual->Diffus = y; qual->Diffus = y;
return 0; return 0;
} }
@@ -1872,7 +1906,7 @@ int optionvalue(Project *pr, int n)
// Flow change limit // Flow change limit
else if (match(tok0, w_FLOWCHANGE)) else if (match(tok0, w_FLOWCHANGE))
{ {
if (y < 0.0) return 213; if (y < 0.0) return setError(parser, nvalue, 213);
hyd->FlowChangeLimit = y; hyd->FlowChangeLimit = y;
return 0; return 0;
} }
@@ -1880,7 +1914,7 @@ int optionvalue(Project *pr, int n)
// Head loss error limit // Head loss error limit
else if (match(tok0, w_HEADERROR)) else if (match(tok0, w_HEADERROR))
{ {
if (y < 0.0) return 213; if (y < 0.0) return setError(parser, nvalue, 213);
hyd->HeadErrorLimit = y; hyd->HeadErrorLimit = y;
return 0; return 0;
} }
@@ -1888,25 +1922,25 @@ int optionvalue(Project *pr, int n)
// Pressure dependent demand parameters // Pressure dependent demand parameters
else if (match(tok0, w_MINIMUM)) else if (match(tok0, w_MINIMUM))
{ {
if (y < 0.0) return 213; if (y < 0.0) return setError(parser, nvalue, 213);
hyd->Pmin = y; hyd->Pmin = y;
return 0; return 0;
} }
else if (match(tok0, w_REQUIRED)) else if (match(tok0, w_REQUIRED))
{ {
if (y < 0.0) return 213; if (y < 0.0) return setError(parser, nvalue, 213);
hyd->Preq = y; hyd->Preq = y;
return 0; return 0;
} }
else if (match(tok0, w_PRESSURE)) else if (match(tok0, w_PRESSURE))
{ {
if (y < 0.0) return 213; if (y < 0.0) return setError(parser, nvalue, 213);
hyd->Pexp = y; hyd->Pexp = y;
return 0; return 0;
} }
// All other options must be > 0 // All other options must be > 0
if (y <= 0.0) return 213; if (y <= 0.0) return setError(parser, nvalue, 213);
// Assign value to all other options // Assign value to all other options
if (match(tok0, w_VISCOSITY)) hyd->Viscos = y; if (match(tok0, w_VISCOSITY)) hyd->Viscos = y;
@@ -2029,59 +2063,6 @@ int powercurve(double h0, double h1, double h2, double q1, double q2,
return 1; return 1;
} }
int valvecheck(Project *pr, int type, int j1, int j2)
/*
**--------------------------------------------------------------
** Input: type = valve type
** j1 = index of upstream node
** j2 = index of downstream node
** Output: returns 1 for legal connection, 0 otherwise
** Purpose: checks for legal connections between PRVs & PSVs
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
int k, vj1, vj2;
LinkType vtype;
Slink *link;
Svalve *valve;
// Examine each existing valve
for (k = 1; k <= net->Nvalves; k++)
{
valve = &net->Valve[k];
link = &net->Link[valve->Link];
vj1 = link->N1;
vj2 = link->N2;
vtype = link->Type;
// Cannot have two PRVs sharing downstream nodes or in series
if (vtype == PRV && type == PRV)
{
if (vj2 == j2 || vj2 == j1 || vj1 == j2) return 0;
}
// Cannot have two PSVs sharing upstream nodes or in series
if (vtype == PSV && type == PSV)
{
if (vj1 == j1 || vj1 == j2 || vj2 == j1) return 0;
}
// Cannot have PSV connected to downstream node of PRV
if (vtype == PSV && type == PRV && vj1 == j2) return 0;
if (vtype == PRV && type == PSV && vj2 == j1) return 0;
// Cannot have PSV connected to downstream node of FCV
// nor have PRV connected to upstream node of FCV
if (vtype == FCV && type == PSV && vj2 == j1) return 0;
if (vtype == FCV && type == PRV && vj1 == j2) return 0;
if (vtype == PSV && type == FCV && vj1 == j2) return 0;
if (vtype == PRV && type == FCV && vj2 == j1) return 0;
}
return 1;
}
void changestatus(Network *net, int j, StatusType status, double y) void changestatus(Network *net, int j, StatusType status, double y)
/* /*
**-------------------------------------------------------------- **--------------------------------------------------------------

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS Authors: see AUTHORS
Copyright: see AUTHORS Copyright: see AUTHORS
License: see LICENSE License: see LICENSE
Last Updated: 11/27/2018 Last Updated: 01/01/2019
****************************************************************************** ******************************************************************************
*/ */
@@ -60,8 +60,8 @@ int openfiles(Project *pr, const char *f1, const char *f2, const char *f3)
else pr->outfile.Outflag = SCRATCH; else pr->outfile.Outflag = SCRATCH;
// Check that file names are not identical // Check that file names are not identical
if (strcomp(f1, f2) || strcomp(f1, f3) || if (strlen(f1) > 0 && (strcomp(f1, f2) || strcomp(f1, f3))) return 301;
(strcomp(f2, f3) && (strlen(f2) > 0 || strlen(f3) > 0))) return 301; if (strlen(f3) > 0 && strcomp(f2, f3)) return 301;
// Attempt to open input and report files // Attempt to open input and report files
if (strlen(f1) > 0) if (strlen(f1) > 0)
@@ -69,7 +69,12 @@ int openfiles(Project *pr, const char *f1, const char *f2, const char *f3)
if ((pr->parser.InFile = fopen(f1, "rt")) == NULL) return 302; if ((pr->parser.InFile = fopen(f1, "rt")) == NULL) return 302;
} }
if (strlen(f2) == 0) pr->report.RptFile = stdout; if (strlen(f2) == 0) pr->report.RptFile = stdout;
else if ((pr->report.RptFile = fopen(f2, "wt")) == NULL) return 303; else
{
pr->report.RptFile = fopen(f2, "wt");
if (pr->report.RptFile == NULL) return 303;
}
writelogo(pr);
return 0; return 0;
} }
@@ -349,7 +354,7 @@ int allocdata(Project *pr)
for (n = 0; n <= pr->parser.MaxCurves; n++) for (n = 0; n <= pr->parser.MaxCurves; n++)
{ {
pr->network.Curve[n].Npts = 0; 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].X = NULL;
pr->network.Curve[n].Y = NULL; pr->network.Curve[n].Y = NULL;
} }
@@ -574,7 +579,6 @@ int incontrols(Project *pr, int objType, int index)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Rules *rules = &pr->rules;
int i, ruleObject; int i, ruleObject;
Spremise *premise; Spremise *premise;
@@ -625,6 +629,65 @@ int incontrols(Project *pr, int objType, int index)
return 0; return 0;
} }
int valvecheck(Project *pr, int type, int j1, int j2)
/*
**--------------------------------------------------------------
** Input: type = valve type
** j1 = index of upstream node
** j2 = index of downstream node
** Output: returns an error code
** Purpose: checks for illegal connections between valves
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
int k, vj1, vj2;
LinkType vtype;
Slink *link;
Svalve *valve;
if (type == PRV || type == PSV || type == FCV)
{
// 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++)
{
valve = &net->Valve[k];
link = &net->Link[valve->Link];
vj1 = link->N1;
vj2 = link->N2;
vtype = link->Type;
// Cannot have two PRVs sharing downstream nodes or in series
if (vtype == PRV && type == PRV)
{
if (vj2 == j2 || vj2 == j1 || vj1 == j2) return 220;
}
// Cannot have two PSVs sharing upstream nodes or in series
if (vtype == PSV && type == PSV)
{
if (vj1 == j1 || vj1 == j2 || vj2 == j1) return 220;
}
// Cannot have PSV connected to downstream node of PRV
if (vtype == PSV && type == PRV && vj1 == j2) return 220;
if (vtype == PRV && type == PSV && vj2 == j1) return 220;
// Cannot have PSV connected to downstream node of FCV
// nor have PRV connected to upstream node of FCV
if (vtype == FCV && type == PSV && vj2 == j1) return 220;
if (vtype == FCV && type == PRV && vj1 == j2) return 220;
if (vtype == PSV && type == FCV && vj1 == j2) return 220;
if (vtype == PRV && type == FCV && vj2 == j1) return 220;
}
}
return 0;
}
int findnode(Network *network, char *id) int findnode(Network *network, char *id)
/*---------------------------------------------------------------- /*----------------------------------------------------------------
** Input: id = node ID ** Input: id = node ID
@@ -791,11 +854,14 @@ char *geterrmsg(int errcode, char *msg)
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
{ {
switch (errcode) { /* Warnings */ switch (errcode)
//#define DAT(code,enumer,string) case code: strcpy(msg, string); break; {
#define DAT(code,enumer,string) case code: sprintf(msg, "Error %d: %s", code, string); break;
//#define DAT(code,string) case code: sprintf(msg, "%s", string); break;
#define DAT(code,string) case code: strcpy(msg, string); break;
#include "errors.dat" #include "errors.dat"
#undef DAT #undef DAT
default: default:
strcpy(msg, ""); strcpy(msg, "");
} }
@@ -810,13 +876,15 @@ void errmsg(Project *pr, int errcode)
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
{ {
char errmsg[MAXMSG + 1] = "";
if (errcode == 309) /* Report file write error - */ if (errcode == 309) /* Report file write error - */
{ /* Do not write msg to file. */ { /* Do not write msg to file. */
} }
else if (pr->report.RptFile != NULL && pr->report.Messageflag) else if (pr->report.RptFile != NULL && pr->report.Messageflag && errcode > 100)
{ {
writeline(pr, geterrmsg(errcode, pr->Msg)); sprintf(pr->Msg, "Error %d: %s", errcode, geterrmsg(errcode, errmsg));
writeline(pr, pr->Msg);
} }
} }

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 stepqual(Project *, long *);
//int closequal(Project *); //int closequal(Project *);
//double avgqual(Project *, int); //double avgqual(Project *, int);
double findsourcequal(Project *, int, double, double, long); double findsourcequal(Project *, int, double, long);
// Imported functions // Imported functions
extern char setreactflag(Project *); extern char setreactflag(Project *);
@@ -202,8 +202,8 @@ int runqual(Project *pr, long *t)
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
Times *time = &pr->times; Times *time = &pr->times;
long hydtime; // Hydraulic solution time long hydtime = 0; // Hydraulic solution time
long hydstep; // Hydraulic time step long hydstep = 0; // Hydraulic time step
int errcode = 0; int errcode = 0;
// Update reported simulation time // Update reported simulation time
@@ -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 ** Input: n = node index
** volin = volume of node inflow over time step
** volout = volume of node outflow over time step ** volout = volume of node outflow over time step
** tstep = current quality time step ** tstep = current quality time step
** Output: returns concentration added by an external quality source. ** Output: returns concentration added by an external quality source.
@@ -543,7 +542,6 @@ double sourcequal(Project *pr, Psource source)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Quality *qual = &pr->quality;
Times *time = &pr->times; Times *time = &pr->times;
int i; int i;

View File

@@ -445,7 +445,6 @@ double mixtank(Project *pr, int n, double volin, double massin, double volout)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Quality *qual = &pr->quality;
int i; int i;
double vnet; double vnet;
@@ -475,7 +474,6 @@ void tankmix1(Project *pr, int i, double vin, double win, double vnet)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
int k; int k;
@@ -589,7 +587,6 @@ void tankmix3(Project *pr, int i, double vin, double win, double vnet)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
int k; int k;
@@ -662,7 +659,7 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
Network *net = &pr->network; Network *net = &pr->network;
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
int k, n; int k;
double cin, vsum, wsum, vseg; double cin, vsum, wsum, vseg;
Pseg seg; Pseg seg;
Stank *tank = &pr->network.Tank[i]; 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; if (qual->LastSeg[k] == NULL || qual->FirstSeg[k] == NULL) return;
// Find inflows & outflows // Find inflows & outflows
n = tank->Node;
if (vin > 0.0) cin = win / vin; if (vin > 0.0) cin = win / vin;
else cin = 0.0; else cin = 0.0;

View File

@@ -35,7 +35,7 @@ void reversesegs(Project *, int);
void addseg(Project *, int, double, double); void addseg(Project *, int, double, double);
// Imported functions // Imported functions
extern double findsourcequal(Project *, int, double, double, long); extern double findsourcequal(Project *, int, double, long);
extern void reactpipes(Project *, long); extern void reactpipes(Project *, long);
extern void reacttanks(Project *, long); extern void reacttanks(Project *, long);
extern double mixtank(Project *, int, double, double, double); 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; Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
@@ -251,7 +250,7 @@ double findnodequal(Project *pr, int n, double volin,
} }
// Find quality contribued by any external chemical source // 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]; if (qual->SourceQual == 0.0) return qual->NodeQual[n];
// Combine source quality with node quality // Combine source quality with node quality
@@ -285,7 +284,6 @@ double noflowqual(Project *pr, int n)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
int k, inflow, kount = 0; int k, inflow, kount = 0;
@@ -428,7 +426,6 @@ int sortnodes(Project *pr)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
int i, j, k, n; int i, j, k, n;
@@ -578,7 +575,6 @@ void initsegs(Project *pr)
*/ */
{ {
Network *net = &pr->network; Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality; Quality *qual = &pr->quality;
int j, k; int j, k;

View File

@@ -70,7 +70,7 @@ int writereport(Project *pr)
Report *rpt = &pr->report; Report *rpt = &pr->report;
Parser *parser = &pr->parser; Parser *parser = &pr->parser;
char tflag; int tflag;
FILE *tfile; FILE *tfile;
int errcode = 0; int errcode = 0;
@@ -399,7 +399,7 @@ void writemassbalance(Project *pr)
writeline(pr, s1); writeline(pr, s1);
snprintf(s1, MAXMSG, "Final Mass: %12.5e", qual->MassBalance.final); snprintf(s1, MAXMSG, "Final Mass: %12.5e", qual->MassBalance.final);
writeline(pr, s1); 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); writeline(pr, s1);
snprintf(s1, MAXMSG, "================================\n"); snprintf(s1, MAXMSG, "================================\n");
writeline(pr, s1); writeline(pr, s1);
@@ -1001,7 +1001,7 @@ int writehydwarn(Project *pr, int iter, double relerr)
int i, j; int i, j;
char flag = 0; char flag = 0;
char s; int s;
Snode *Node = net->Node; Snode *Node = net->Node;
Slink *Link = net->Link; Slink *Link = net->Link;
Spump *Pump = net->Pump; Spump *Pump = net->Pump;

View File

@@ -328,7 +328,6 @@ void adjustrules(Project *pr, int objtype, int index)
//----------------------------------------------------------- //-----------------------------------------------------------
{ {
Network *net = &pr->network; Network *net = &pr->network;
Rules *rules = &pr->rules;
int i, delete; int i, delete;
Spremise *p; Spremise *p;
@@ -453,7 +452,6 @@ int writerule(Project *pr, FILE *f, int ruleIndex)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
Network *net = &pr->network; Network *net = &pr->network;
Rules *rules = &pr->rules;
Srule *rule = &net->Rule[ruleIndex]; Srule *rule = &net->Rule[ruleIndex];
Spremise *p; Spremise *p;

View File

@@ -198,7 +198,6 @@ void freesparse(Project *pr)
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
{ {
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix; Smatrix *sm = &pr->hydraul.smatrix;
// stoptimer(SmatrixTimer); // stoptimer(SmatrixTimer);

View File

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

View File

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

View File

@@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
int flag = 00; int flag = 00;
long t, tstep; long t, tstep;
int i, ind, Lindex, Nindex, Cindex; 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) // 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; EN_Project ph = NULL;
@@ -80,13 +80,13 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// now we build Net1 from scratch... // now we build Net1 from scratch...
char juncs[9][10] = { "10", "11", "12", "13", "21", "22", "23", "31", "32" }; 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}; double e[9] = {710, 710, 700, 695, 700, 695, 690, 700, 710};
float d[9] = {0, 150, 150, 100, 150, 200, 150, 100, 100 }; double d[9] = {0, 150, 150, 100, 150, 200, 150, 100, 100 };
float X[9] = {20, 30, 50, 70, 30, 50, 70, 30, 50}; double X[9] = {20, 30, 50, 70, 30, 50, 70, 30, 50};
float Y[9] = {70, 70, 70, 70, 40, 40, 40, 10, 10 }; double 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}; double 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 }; double 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 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_createproject(&ph);
error = EN_init(ph, "net.rpt", "net.out", EN_GPM, EN_HW); 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); BOOST_REQUIRE(error == 0);
error = EN_setpattern(ph, 1, P, 12); error = EN_setpattern(ph, 1, P, 12);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
error = EN_setoption(ph, EN_DEMANDDEFPAT, 1); error = EN_setoption(ph, EN_DEFDEMANDPAT, 1);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
{ {
@@ -187,9 +187,9 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
// Add controls // 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); 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); BOOST_REQUIRE(error == 0);
error = EN_openH(ph); error = EN_openH(ph);
@@ -250,10 +250,10 @@ BOOST_AUTO_TEST_CASE(test_net_builder)
// if we got this far we can compare results // if we got this far we can compare results
// compare the original to the build & saved network // 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 // 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 error = 0;
int p113, n31, p121, n113_1, n113_2; 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_Project ph = NULL;
EN_createproject(&ph); EN_createproject(&ph);

View File

@@ -301,7 +301,7 @@ BOOST_FIXTURE_TEST_CASE(test_add_control, Fixture)
{ {
int flag = 00; int flag = 00;
long t, tstep; long t, tstep;
float h1, h2; double h1, h2;
int Cindex; int Cindex;
// run with original controls // run with original controls
@@ -328,10 +328,10 @@ BOOST_FIXTURE_TEST_CASE(test_add_control, Fixture)
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
// add new controls // 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_REQUIRE(error == 0);
BOOST_CHECK(Cindex == 3); 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_REQUIRE(error == 0);
BOOST_CHECK(Cindex == 4); BOOST_CHECK(Cindex == 4);
@@ -352,7 +352,7 @@ BOOST_FIXTURE_TEST_CASE(test_add_control, Fixture)
error = EN_closeH(ph); error = EN_closeH(ph);
BOOST_REQUIRE(error == 0); 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() BOOST_AUTO_TEST_SUITE_END()

View File

@@ -25,8 +25,8 @@ set SCRIPT_HOME=%~dp0
set TEST_HOME=%~1 set TEST_HOME=%~1
set EXAMPLES_VER=1.0.2-dev.4 set EXAMPLES_VER=1.0.2-dev.5
set BENCHMARK_VER=220dev4 set BENCHMARK_VER=220dev5
set TESTFILES_URL=https://github.com/OpenWaterAnalytics/epanet-example-networks/archive/v%EXAMPLES_VER%.zip set TESTFILES_URL=https://github.com/OpenWaterAnalytics/epanet-example-networks/archive/v%EXAMPLES_VER%.zip

View File

@@ -18,7 +18,7 @@ setlocal
set NRTEST_SCRIPT_PATH=%~1 set NRTEST_SCRIPT_PATH=%~1
set TEST_SUITE_PATH=%~2 set TEST_SUITE_PATH=%~2
set BENCHMARK_VER=220dev4 set BENCHMARK_VER=220dev5
set NRTEST_EXECUTE_CMD=python %NRTEST_SCRIPT_PATH%\nrtest execute set NRTEST_EXECUTE_CMD=python %NRTEST_SCRIPT_PATH%\nrtest execute

View File

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