rethinking the python wrapper (#511)

* renames certain function parameter declarations and removes double pointer call from the deleteproject function

* deprecates conditonal compilation, removes python-specific headers and function renaming

* fixes tests and docs

* fixes test
This commit is contained in:
Sam Hatchett
2019-07-17 15:19:25 -04:00
committed by GitHub
parent 4cc16913df
commit 3fe11b98ee
18 changed files with 216 additions and 1240 deletions

View File

@@ -81,7 +81,6 @@ IF (MSVC)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF (MSVC) ENDIF (MSVC)
# configure file groups # configure file groups
file(GLOB EPANET_SOURCES RELATIVE ${PROJECT_SOURCE_DIR} src/*.c src/util/*.c) file(GLOB EPANET_SOURCES RELATIVE ${PROJECT_SOURCE_DIR} src/*.c src/util/*.c)
file(GLOB EPANET_LIB_ALL RELATIVE ${PROJECT_SOURCE_DIR} src/* src/util/*) file(GLOB EPANET_LIB_ALL RELATIVE ${PROJECT_SOURCE_DIR} src/* src/util/*)
@@ -89,49 +88,12 @@ file(GLOB EPANET_LIB_ALL RELATIVE ${PROJECT_SOURCE_DIR} src/* src/util/*)
list(REMOVE_ITEM EPANET_LIB_ALL "src/epanet_py.c") list(REMOVE_ITEM EPANET_LIB_ALL "src/epanet_py.c")
source_group("Library" FILES ${EPANET_LIB_ALL}) source_group("Library" FILES ${EPANET_LIB_ALL})
# the shared library
IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)" OR NOT MSVC)
add_library(epanet2 SHARED ${EPANET_LIB_ALL})
ELSE(TRUE)
add_library(epanet2 SHARED ${EPANET_LIB_ALL} ${PROJECT_SOURCE_DIR}/include/epanet2.def)
set_source_files_properties(${PROJECT_SOURCE_DIR}/include/epanet2.def PROPERTIES_HEADER_FILE_ONLY TRUE)
ENDIF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)" OR NOT MSVC)
# create build target for epanet library with python API
IF (BUILD_PY_LIB)
# exclude legacy epanet 2.0 API and include epanet py API
list(REMOVE_ITEM EPANET_LIB_ALL "src/epanet2.c")
add_library(epanet_py SHARED ${EPANET_LIB_ALL} src/epanet_py.c src/util/errormanager.c)
target_include_directories(epanet_py PUBLIC ${PROJECT_SOURCE_DIR}/include)
include(GenerateExportHeader)
GENERATE_EXPORT_HEADER(epanet_py
BASE_NAME epanet_py
EXPORT_MACRO_NAME EXPORT_PY_API
EXPORT_FILE_NAME epanet_py_export.h
STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC)
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/epanet_py_export.h
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include)
# create build target for code coverage
ELSEIF (BUILD_COVERAGE)
include(CodeCoverage)
set(CMAKE_BUILD_TYPE "Debug")
APPEND_COVERAGE_COMPILER_FLAGS()
set(CMAKE_C_FLAGS_DEBUG "-O0")
add_library(epanet2 SHARED ${EPANET_LIB_ALL})
target_include_directories(epanet2 PUBLIC ${PROJECT_SOURCE_DIR}/include) target_include_directories(epanet2 PUBLIC ${PROJECT_SOURCE_DIR}/include)
# create build target for default epanet library with 2.0 and 2.2 API
ELSE (BUILD_PY_LIB)
# the shared library
IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)" OR NOT MSVC)
add_library(epanet2 SHARED ${EPANET_LIB_ALL})
ELSE(TRUE)
add_library(epanet2 SHARED ${EPANET_LIB_ALL} ${PROJECT_SOURCE_DIR}/include/epanet2.def)
set_source_files_properties(${PROJECT_SOURCE_DIR}/include/epanet2.def PROPERTIES_HEADER_FILE_ONLY TRUE)
ENDIF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)" OR NOT MSVC)
target_include_directories(epanet2 PUBLIC ${PROJECT_SOURCE_DIR}/include)
ENDIF (BUILD_PY_LIB)

View File

@@ -12,7 +12,7 @@ one would use:
`EN_getnodevalue(ph, nodeIndex, EN_ELEVATION, &elev)` `EN_getnodevalue(ph, nodeIndex, EN_ELEVATION, &elev)`
where `ph` is the handle assigned to the project. where `ph` is the handle assigned to the project.
Two new functions have been added to the API to manage the creation and deletion of project handles. `EN_createproject` creates a new project along with its handle, while `EN_deleteproject` deletes a project. An example of using the thread-safe version of the API is shown below: 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:
``` ```
@@ -27,7 +27,7 @@ int runEpanet(char *finp, char *frpt)
if (!err) err = EN_solveH(ph); if (!err) err = EN_solveH(ph);
if (!err) err = EN_report(ph); if (!err) err = EN_report(ph);
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
return err; return err;
} }
``` ```
@@ -47,32 +47,32 @@ int buildandrunEpanet(char *rptfile)
err = EN_createproject(&ph); err = EN_createproject(&ph);
if (err) return err; if (err) return err;
EN_init(ph, rptfile, "", EN_GPM, EN_HW); EN_init(ph, rptfile, "", EN_GPM, EN_HW);
//Add a junction node with 710 ft elevation and 500 gpm demand //Add a junction node with 710 ft elevation and 500 gpm demand
EN_addnode(ph, "J1", EN_JUNCTION, &index); EN_addnode(ph, "J1", EN_JUNCTION, &index);
EN_setjuncdata(ph, index, 710, 500, ""); EN_setjuncdata(ph, index, 710, 500, "");
// Add a reservoir node at 800 ft elevation // Add a reservoir node at 800 ft elevation
EN_addnode(ph, "R1", EN_RESERVOIR, &index); EN_addnode(ph, "R1", EN_RESERVOIR, &index);
EN_setnodevalue(ph, index, EN_ELEVATION, 800); EN_setnodevalue(ph, index, EN_ELEVATION, 800);
// Add a 5280 ft long, 14-inch pipe with C-factor of 100 // Add a 5280 ft long, 14-inch pipe with C-factor of 100
// from the reservoir to the demand node // from the reservoir to the demand node
EN_addlink(ph, "P1", EN_PIPE, "R1", "J1", &index); EN_addlink(ph, "P1", EN_PIPE, "R1", "J1", &index);
EN_setpipedata(ph, index, 5280, 14, 100, 0); EN_setpipedata(ph, index, 5280, 14, 100, 0);
// Solve for hydraulics and report nodal results // Solve for hydraulics and report nodal results
EN_setreport(ph, "NODES ALL"); EN_setreport(ph, "NODES ALL");
err = EN_solveH(ph); err = EN_solveH(ph);
if (!err) err = EN_report(ph); if (!err) err = EN_report(ph);
// Close and delete the project // Close and delete the project
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
return err; 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. 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
@@ -82,13 +82,13 @@ Two new analysis options have been added to provide more rigorous convergence cr
`EN_FLOWCHANGE` is the largest change in flow that any network element (link, emitter, or pressure-dependent demand) can have for hydraulic convergence to occur. It is specified in whatever flow units the project is using. The default value of 0 indicates that no flow change limit applies. `EN_FLOWCHANGE` is the largest change in flow that any network element (link, emitter, or pressure-dependent demand) can have for hydraulic convergence to occur. It is specified in whatever flow units the project is using. The default value of 0 indicates that no flow change limit applies.
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.
## More Efficient Node Re-ordering ## More Efficient Node Re-ordering
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 efficient **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, where most of the work is for node-reordering, by an average of 55%. Since MMD did not reduce the time needed to solve the linear equations generated at each iteration of the hydraulic solver longer extended period simulations will not exhibit a similar speedup. EPANET's original node re-ordering scheme has been replaced by the more efficient **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, where most of the work is for node-reordering, by an average of 55%. Since MMD did not reduce the time needed to solve the linear equations generated at each iteration of the hydraulic solver longer extended period simulations will not exhibit a similar speedup.
## Improved Handling of Near-Zero Flows ## Improved Handling of Near-Zero Flows
@@ -98,7 +98,7 @@ The hydraulic solver has been modified to use a linear head loss v. flow relatio
## 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:
@@ -163,7 +163,7 @@ With this change EPANET 2.2 now produces perfect mass balances when tested again
|`EN_deleterule`|Deletes a rule-based control from the project| |`EN_deleterule`|Deletes a rule-based control from the project|
|`EN_setnodeid`|Changes the ID name for a node| |`EN_setnodeid`|Changes the ID name for a node|
|`EN_setjuncdata` |Sets values for a junction's parameters | |`EN_setjuncdata` |Sets values for a junction's parameters |
|`EN_settankdata` |Sets values for a tank's parameters| |`EN_settankdata` |Sets values for a tank's parameters|
|`EN_setlinkid`|Changes the ID name for a link| |`EN_setlinkid`|Changes the ID name for a link|
|`EN_setlinknodes`|Sets a link's start- and end-nodes| |`EN_setlinknodes`|Sets a link's start- and end-nodes|
|`EN_setlinktype`|Changes the type of a specific link| |`EN_setlinktype`|Changes the type of a specific link|
@@ -205,7 +205,7 @@ In addition to these new functions, a tank's volume curve `EN_VOLCURVE` can be s
- `EN_PUMP_ECOST` (average energy price) - `EN_PUMP_ECOST` (average energy price)
- `EN_PUMP_EPAT` (energy pricing pattern) - `EN_PUMP_EPAT` (energy pricing pattern)
- `EN_LINKPATTERN` (speed setting pattern) - `EN_LINKPATTERN` (speed setting pattern)
Access to the following global energy options have been added to `EN_getoption` and `EN_setoption`: Access to the following global energy options have been added to `EN_getoption` and `EN_setoption`:
- `EN_GLOBALEFFIC` (global pump efficiency) - `EN_GLOBALEFFIC` (global pump efficiency)
- `EN_GLOBALPRICE` (global average energy price per kW-Hour) - `EN_GLOBALPRICE` (global average energy price per kW-Hour)
@@ -254,7 +254,7 @@ Access to the following global energy options have been added to `EN_getoption`
- `EN_WALLORDER` - `EN_WALLORDER`
- `EN_TANKORDER` - `EN_TANKORDER`
- `EN_CONCENLIMIT` - `EN_CONCENLIMIT`
### Simulation statistic types: ### Simulation statistic types:
- `EN_MAXHEADERROR` - `EN_MAXHEADERROR`
- `EN_MAXFLOWCHANGE` - `EN_MAXFLOWCHANGE`
@@ -276,7 +276,7 @@ Access to the following global energy options have been added to `EN_getoption`
- `EN_PDA` - `EN_PDA`
## Documentation ## Documentation
Doxygen files have been created to generate a complete Users Guide for version 2.2's API. The guide's format is similar to the original EPANET Programmer's Toolkit help file and can be produced as a set of HTML pages, a Windows help file or a PDF document. Doxygen files have been created to generate a complete Users Guide for version 2.2's API. The guide's format is similar to the original EPANET Programmer's Toolkit help file and can be produced as a set of HTML pages, a Windows help file or a PDF document.
## Authors contributing to this release: ## Authors contributing to this release:
- List item - List item

View File

@@ -67,7 +67,7 @@ These are the toolkit's enumerated types whose members are used as function argu
@addtogroup Project @addtogroup Project
@{ @{
@fn int EN_createproject(EN_Project *ph) @fn int EN_createproject(EN_Project *ph)
@fn int EN_deleteproject(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_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_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_open(EN_Project ph, const char *inpFile, const char *rptFile, const char *binOutFile)
@@ -376,5 +376,5 @@ These are the toolkit's enumerated types whose members are used as function argu
|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 | |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 | |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 | |6 | System has negative pressures - negative pressures occurred at one or more junctions with positive demand |
*/ */

View File

@@ -9,7 +9,7 @@ Here are several examples of how the Toolkit can be used for different types of
*/ */
/** @page Example1 Embedded Engine 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: 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. -# Have the application write network data to an EPANET-formatted input file.
-# Create a project and call @ref 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. -# Create a project and call @ref 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.
@@ -32,9 +32,9 @@ int runEpanet(char* inpFile, char* rptFile, char* outFile)
EN_project ph; EN_project ph;
EN_createproject(&pH); EN_createproject(&pH);
errcode = EN_runproject(ph, inpFile, rptFile, outFile, &writeConsole); errcode = EN_runproject(ph, inpFile, rptFile, outFile, &writeConsole);
EN_deleteproject(&ph); EN_deleteproject(ph);
return errcode; return errcode;
} }
\endcode \endcode
*/ */
@@ -62,12 +62,12 @@ void netbuilder()
EN_Project ph; EN_Project ph;
EN_createproject(&ph); EN_createproject(&ph);
EN_init(ph, "", "", EN_GPM, EN_HW); EN_init(ph, "", "", EN_GPM, EN_HW);
// Add the first junction node to the project with // Add the first junction node to the project with
// an elevation of 700 ft and a demand of 0 // an elevation of 700 ft and a demand of 0
EN_addnode(ph, "J1", EN_JUNCTION, &index); EN_addnode(ph, "J1", EN_JUNCTION, &index);
EN_setjuncdata(ph, index, 700, 0, ""); EN_setjuncdata(ph, index, 700, 0, "");
// Add the remaining two junctions with elevations of // Add the remaining two junctions with elevations of
// 710 ft and demands of 250 and 500 gpm, respectively // 710 ft and demands of 250 and 500 gpm, respectively
EN_addnode(ph, "J2", EN_JUNCTION, &index); EN_addnode(ph, "J2", EN_JUNCTION, &index);
@@ -84,7 +84,7 @@ void netbuilder()
// and a diameter of 50.5 ft // and a diameter of 50.5 ft
EN_addnode(ph, "T1", EN_TANK, &index); EN_addnode(ph, "T1", EN_TANK, &index);
EN_settankdata(ph, index, 850, 120, 100, 150, 50.5, 0, ""); EN_settankdata(ph, index, 850, 120, 100, 150, 50.5, 0, "");
// Add the pipes to the project, setting their length, // Add the pipes to the project, setting their length,
// diameter, and roughness values // diameter, and roughness values
EN_addlink(ph, "P1", EN_PIPE, "J1", "J2", &index); EN_addlink(ph, "P1", EN_PIPE, "J1", "J2", &index);
@@ -95,10 +95,10 @@ void netbuilder()
EN_setpipedata(ph, index, 5280, 14, 100, 0); EN_setpipedata(ph, index, 5280, 14, 100, 0);
EN_addlink(ph, "P4", EN_PIPE, "J2", "J3", &index); EN_addlink(ph, "P4", EN_PIPE, "J2", "J3", &index);
EN_setpipedata(ph, index, 5280, 14, 100, 0); EN_setpipedata(ph, index, 5280, 14, 100, 0);
// Add a pump to the project // Add a pump to the project
EN_addlink(ph, "PUMP", EN_PUMP, "R1", "J1", &index); EN_addlink(ph, "PUMP", EN_PUMP, "R1", "J1", &index);
// Create a single point head curve (index = 1) and // Create a single point head curve (index = 1) and
// assign it to the pump // assign it to the pump
EN_addcurve(ph, "C1"); EN_addcurve(ph, "C1");
@@ -109,53 +109,53 @@ void netbuilder()
EN_saveinpfile(ph, "example2.inp"); EN_saveinpfile(ph, "example2.inp");
// Delete the project // Delete the project
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
\endcode \endcode
*/ */
/** @page Example3 Hydrant Rating Curve Example /** @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. 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} \code {.c}
#include "epanet2_2.h" #include "epanet2_2.h"
void HydrantRating(char *MyNode, int N, double D[], double P[]) void HydrantRating(char *MyNode, int N, double D[], double P[])
{ {
EN_Project ph; EN_Project ph;
int i, nodeindex; int i, nodeindex;
long t; long t;
double pressure; double pressure;
// Create a project // Create a project
EN_createproject(&ph); EN_createproject(&ph);
// Retrieve network data from an input file // Retrieve network data from an input file
EN_open(ph, "example2.inp", "example2.rpt", ""); EN_open(ph, "example2.inp", "example2.rpt", "");
// Open the hydraulic solver // Open the hydraulic solver
EN_openH(ph); EN_openH(ph);
// Get the index of the node of interest // Get the index of the node of interest
EN_getnodeindex(ph, MyNode, &nodeindex); EN_getnodeindex(ph, MyNode, &nodeindex);
// Iterate over all demands // Iterate over all demands
for (i=1; i<N; i++) for (i=1; i<N; i++)
{ {
// Set nodal demand, initialize hydraulics, make a // Set nodal demand, initialize hydraulics, make a
// single period run, and retrieve pressure // single period run, and retrieve pressure
EN_setnodevalue(ph, nodeindex, EN_BASEDEMAND, D[i]); EN_setnodevalue(ph, nodeindex, EN_BASEDEMAND, D[i]);
EN_initH(ph, 0); EN_initH(ph, 0);
EN_runH(ph, &t); EN_runH(ph, &t);
EN_getnodevalue(ph, nodeindex, EN_PRESSURE, &pressure); EN_getnodevalue(ph, nodeindex, EN_PRESSURE, &pressure);
P[i] = pressure; P[i] = pressure;
} }
// Close hydraulics solver & delete the project // Close hydraulics solver & delete the project
EN_closeH(ph); EN_closeH(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
\endcode \endcode
*/ */
@@ -164,66 +164,66 @@ void HydrantRating(char *MyNode, int N, double D[], double P[])
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. 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} \code {.c}
#include "epanet2_2.h" #include "epanet2_2.h"
double cl2dose(char *SourceID, double Ctarget) double cl2dose(char *SourceID, double Ctarget)
{ {
int i, nnodes, sourceindex, violation; int i, nnodes, sourceindex, violation;
double c, csource; double c, csource;
long t, tstep; long t, tstep;
EN_Project ph; EN_Project ph;
// Open the toolkit & obtain a hydraulic solution // Open the toolkit & obtain a hydraulic solution
EN_createproject(&ph); EN_createproject(&ph);
EN_open(ph, "example3.inp", "example3.rpt", ""); EN_open(ph, "example3.inp", "example3.rpt", "");
EN_solveH(ph); EN_solveH(ph);
// Get the number of nodes and the source node's index // Get the number of nodes and the source node's index
EN_getcount(ph, EN_NODECOUNT, &nnodes); EN_getcount(ph, EN_NODECOUNT, &nnodes);
EN_getnodeindex(ph, SourceID, &sourceindex); EN_getnodeindex(ph, SourceID, &sourceindex);
// Setup the system to analyze for chlorine // Setup the system to analyze for chlorine
// (in case it was not done in the input file) // (in case it was not done in the input file)
EN_setqualtype(ph, EN_CHEM, "Chlorine", "mg/L", ""); EN_setqualtype(ph, EN_CHEM, "Chlorine", "mg/L", "");
// Open the water quality solver // Open the water quality solver
EN_openQ(ph); EN_openQ(ph);
// Begin the search for the source concentration // Begin the search for the source concentration
csource = 0.0; csource = 0.0;
do { do {
// Update source concentration to next level // Update source concentration to next level
csource = csource + 0.1; csource = csource + 0.1;
EN_setnodevalue(ph, sourceindex, EN_SOURCEQUAL, csource); EN_setnodevalue(ph, sourceindex, EN_SOURCEQUAL, csource);
// Run WQ simulation checking for target violations // Run WQ simulation checking for target violations
violation = 0; violation = 0;
EN_initQ(ph, 0); EN_initQ(ph, 0);
do { do {
EN_runQ(ph, &t); EN_runQ(ph, &t);
if (t > 432000) { if (t > 432000) {
for (i=1; i<=nnodes; i++) { for (i=1; i<=nnodes; i++) {
EN_getnodevalue(ph, i, EN_QUALITY, &c); EN_getnodevalue(ph, i, EN_QUALITY, &c);
if (c < Ctarget) { if (c < Ctarget) {
violation = 1; violation = 1;
break; break;
} }
} }
} }
EN_nextQ(ph, &tstep); EN_nextQ(ph, &tstep);
// End WQ run if violation found // End WQ run if violation found
} while (!violation && tstep > 0); } while (!violation && tstep > 0);
// Continue search if violation found // Continue search if violation found
} while (violation && csource <= 4.0); } while (violation && csource <= 4.0);
// Close up the WQ solver and delete the project // Close up the WQ solver and delete the project
EN_closeQ(ph); EN_closeQ(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
return csource; return csource;
} }
\endcode \endcode
*/ */

View File

@@ -1,7 +1,7 @@
/** /**
@page toolkit-usage Usage @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. 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 @section CreateProject Creating a Project
@@ -13,14 +13,14 @@ EN_createproject(&ph);
// Call functions that perform desired analysis // Call functions that perform desired analysis
EN_deleteproject(&ph); EN_deleteproject(ph);
\endcode \endcode
@section DetectingErrors Detecting Error Conditions @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. 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: 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} \code {.c}
#define ERRCODE(x) (errcode = ((errcode > 100) ? (errcode) : (x))) #define ERRCODE(x) (errcode = ((errcode > 100) ? (errcode) : (x)))
@@ -29,7 +29,7 @@ void runHydraulics(EN_Project ph, char *inputFile, char *reportFile)
{ {
int errcode = 0; int errcode = 0;
char errmsg[EN_MAXMSG + 1]; char errmsg[EN_MAXMSG + 1];
ERRCODE(EN_open(ph, inputFile, reportFile, "")); ERRCODE(EN_open(ph, inputFile, reportFile, ""));
ERRCODE(EN_solveH(ph)); ERRCODE(EN_solveH(ph));
ERRCODE(EN_saveH(ph)); ERRCODE(EN_saveH(ph));
@@ -37,7 +37,7 @@ void runHydraulics(EN_Project ph, char *inputFile, char *reportFile)
EN_geterror(ph, errcode, errmsg); EN_geterror(ph, errcode, errmsg);
if (errcode) printf("\n%s\n", errmsg); if (errcode) printf("\n%s\n", errmsg);
} }
\endcode \endcode
@section NetworkData Providing Network Data @section NetworkData Providing Network Data
@@ -45,14 +45,14 @@ Once a project is created there are two ways in which it can be populated with d
\code {.c} \code {.c}
EN_Project ph; EN_Project ph;
int errcode; int errcode;
EN_createproject(&ph); EN_createproject(&ph);
errcode = EN_open(ph, "net1.inp", "net1.rpt", ""); errcode = EN_open(ph, "net1.inp", "net1.rpt", "");
if (errcode == 0) if (errcode == 0)
{ {
// Call functions that perform desired analysis // Call functions that perform desired analysis
} }
EN_deleteproject(&ph); EN_deleteproject(ph);
\endcode \endcode
After an input file has been loaded in this fashion the resulting network can have objects added or deleted, and their properties set using the various Toolkit functions . After an input file has been loaded in this fashion the resulting network can have objects added or deleted, and their properties set using the various Toolkit functions .
@@ -78,36 +78,36 @@ The Toolkit contains several functions for retrieving and setting the properties
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 @ref EN_addnode and @ref EN_addlink functions return the index of the newly added node or link as a convenience for immediately setting their properties. 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 @ref EN_addnode and @ref EN_addlink functions return the index of the newly added node or link as a convenience for immediately setting their properties.
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. 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} \code {.c}
void changeDiameters(EN_Project ph) void changeDiameters(EN_Project ph)
{ {
int i, nLinks; int i, nLinks;
double diam; double diam;
EN_getcount(ph, EN_LINKCOUNT, &nLinks); EN_getcount(ph, EN_LINKCOUNT, &nLinks);
for (i = 1; i <= nLinks; i++) for (i = 1; i <= nLinks; i++)
{ {
EN_getlinkvalue(ph, i, EN_DIAMETER, &diam); EN_getlinkvalue(ph, i, EN_DIAMETER, &diam);
if (diam == 10) EN_setlinkvalue(ph, i, EN_DIAMETER, 12); if (diam == 10) EN_setlinkvalue(ph, i, EN_DIAMETER, 12);
} }
} }
\endcode \endcode
@section hydraulics Computing Hydraulics @section hydraulics Computing Hydraulics
There are two ways to use the Toolkit to run a hydraulic analysis: 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_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. -# 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 \b EN_openH to begin the process, then make successive calls to <b>EN_initH - EN_runH - EN_nextH</b> to perform each analysis, and finally call \b EN_closeH to close down the hydraulics system. An example of this is shown below (calls to \b EN_nextH are not needed because we are only making a single period analysis in this example). 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 \b EN_openH to begin the process, then make successive calls to <b>EN_initH - EN_runH - EN_nextH</b> to perform each analysis, and finally call \b EN_closeH to close down the hydraulics system. An example of this is shown below (calls to \b EN_nextH are not needed because we are only making a single period analysis in this example).
\code {.c} \code {.c}
void runHydraulics(EN_Project ph, int nRuns) void runHydraulics(EN_Project ph, int nRuns)
{ {
int i; int i;
long t; long t;
EN_openH(ph); EN_openH(ph);
for (i = 1; i <= nRuns; i++) for (i = 1; i <= nRuns; i++)
@@ -127,7 +127,7 @@ void runHydraulics(EN_Project ph, int nRuns)
@section quality Computing Water Quality @section quality Computing Water Quality
As with a hydraulic analysis, there are two ways to carry out a water quality analysis: 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_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 @ref EN_nextQ with @ref EN_stepQ will step through one water quality time step at a time.) -# 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 @ref EN_nextQ with @ref EN_stepQ will step through one water quality time step at a time.)
@@ -144,7 +144,7 @@ int runSequentialQuality(EN_Project ph)
EN_openQ(ph); EN_openQ(ph);
EN_initQ(ph, EN_NOSAVE); EN_initQ(ph, EN_NOSAVE);
do { do {
EN_runQ(ph, &t); EN_runQ(ph, &t);
// Access quality results for time t here // Access quality results for time t here
EN_nextQ(ph, &tStep); EN_nextQ(ph, &tStep);
} while (tStep > 0); } while (tStep > 0);
@@ -176,9 +176,9 @@ int runConcurrentQuality(EN_Project ph)
@section results Retrieving Computed Results @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: 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: | |For Nodes: | For Links: |
|----------------------------------- | ----------------------------------------- | |----------------------------------- | ----------------------------------------- |
|\b EN_DEMAND (demand) |\b EN_FLOW (flow rate) | |\b EN_DEMAND (demand) |\b EN_FLOW (flow rate) |
|\b EN_HEAD (hydraulic head) |\b EN_VELOCITY (flow velocity) | |\b EN_HEAD (hydraulic head) |\b EN_VELOCITY (flow velocity) |
|\b EN_PRESSURE (pressure) |\b EN_HEADLOSS (head loss) | |\b EN_PRESSURE (pressure) |\b EN_HEADLOSS (head loss) |
@@ -186,57 +186,57 @@ The @ref EN_getnodevalue and @ref EN_getlinkvalue functions can also be used to
|\b EN_TANKVOLUME (tank water volume) |\b EN_SETTING (pump speed or valve setting) | |\b EN_TANKVOLUME (tank water volume) |\b EN_SETTING (pump speed or valve setting) |
|\b EN_QUALITY (water quality) |\b EN_ENERGY (pump energy usage) | |\b EN_QUALITY (water quality) |\b EN_ENERGY (pump energy usage) |
|\b EN_SOURCEMASS (source mass inflow)|\b EN_PUMP_EFFIC (pump efficiency) | |\b EN_SOURCEMASS (source mass inflow)|\b 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): 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} \code {.c}
void getPressures(EN_Project ph) void getPressures(EN_Project ph)
{ {
int i, numNodes; int i, numNodes;
long t, tStep; long t, tStep;
double p; double p;
char id[EN_MAXID + 1]; char id[EN_MAXID + 1];
EN_getcount(ph, EN_NODECOUNT, &numNodes); EN_getcount(ph, EN_NODECOUNT, &numNodes);
EN_openH(ph); EN_openH(ph);
EN_initH(ph, EN_NOSAVE); EN_initH(ph, EN_NOSAVE);
do { do {
EN_runH(ph, &t); EN_runH(ph, &t);
for (i = 1; i <= NumNodes; i++) { for (i = 1; i <= NumNodes; i++) {
EN_getnodevalue(ph, i, EN_PRESSURE, &p); EN_getnodevalue(ph, i, EN_PRESSURE, &p);
EN_getnodeid(ph, i, id); EN_getnodeid(ph, i, id);
writetofile(t, id, p); writetofile(t, id, p);
} }
EN_nextH(&tStep); EN_nextH(&tStep);
} while (tStep > 0); } while (tStep > 0);
EN_closeH(ph); EN_closeH(ph);
} }
\endcode \endcode
@section report Producing a Report @section report Producing 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 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: 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} \code {.c}
void reportPressureVariation(EN_Project ph) void reportPressureVariation(EN_Project ph)
{ {
// Compute ranges (max - min) // Compute ranges (max - min)
EN_settimeparam(ph, EN_STATISTIC, EN_RANGE); EN_settimeparam(ph, EN_STATISTIC, EN_RANGE);
// Solve and save hydraulics // Solve and save hydraulics
EN_solveH(ph); EN_solveH(ph);
EN_saveH(ph); EN_saveH(ph);
// Define contents of the report // Define contents of the report
EN_resetreport(ph); EN_resetreport(ph);
EN_setreport(ph, "FILE myfile.rpt"); EN_setreport(ph, "FILE myfile.rpt");
EN_setreport(ph, "NODES ALL"); EN_setreport(ph, "NODES ALL");
EN_setreport(ph, "PRESSURE PRECISION 1"); EN_setreport(ph, "PRESSURE PRECISION 1");
EN_setreport(ph, "PRESSURE ABOVE 20"); EN_setreport(ph, "PRESSURE ABOVE 20");
// Write the report to file // Write the report to file
EN_report(ph); EN_report(ph);
} }
\endcode \endcode
*/ */

View File

@@ -70,7 +70,7 @@ typedef struct Project *EN_Project;
EN_deleteproject should be called after all network analysis has been completed. EN_deleteproject should be called after all network analysis has been completed.
*/ */
int DLLEXPORT EN_deleteproject(EN_Project *ph); int DLLEXPORT EN_deleteproject(EN_Project ph);
/** /**
@brief Runs a complete EPANET simulation. @brief Runs a complete EPANET simulation.
@@ -94,7 +94,7 @@ typedef struct Project *EN_Project;
the pviewprog argument should be `NULL`. the pviewprog argument should be `NULL`.
*/ */
int DLLEXPORT EN_runproject(EN_Project ph, const char *inpFile, const char *rptFile, int DLLEXPORT EN_runproject(EN_Project ph, const char *inpFile, const char *rptFile,
const char *outFile, void (*pviewprog)(char *)); const char *outputFile, void (*pviewprog)(char *));
/** /**
@brief Initializes an EPANET project. @brief Initializes an EPANET project.
@@ -134,7 +134,7 @@ typedef struct Project *EN_Project;
@param[out] line3 third title line @param[out] line3 third title line
@return an error code @return an error code
*/ */
int DLLEXPORT EN_gettitle(EN_Project ph, char *line1, char *line2, char *line3); int DLLEXPORT EN_gettitle(EN_Project ph, char *out_line1, char *out_line2, char *out_line3);
/** /**
@brief Sets the title lines of the project @brief Sets the title lines of the project
@@ -154,7 +154,7 @@ typedef struct Project *EN_Project;
@param[out] comment the comment string assigned to the object @param[out] comment the comment string assigned to the object
@return an error code @return an error code
*/ */
int DLLEXPORT EN_getcomment(EN_Project ph, int object, int index, char *comment); int DLLEXPORT EN_getcomment(EN_Project ph, int object, int index, char *out_comment);
/** /**
@brief Assigns a descriptive comment to a Node, Link, Pattern or Curve. @brief Assigns a descriptive comment to a Node, Link, Pattern or Curve.
@@ -627,7 +627,7 @@ typedef struct Project *EN_Project;
Error message strings should be at least @ref EN_SizeLimits "EN_MAXMSG" characters in length. Error message strings should be at least @ref EN_SizeLimits "EN_MAXMSG" characters in length.
*/ */
int DLLEXPORT EN_geterror(int errcode, char *errmsg, int maxLen); int DLLEXPORT EN_geterror(int errcode, char *out_errmsg, int maxLen);
/** /**
@brief Retrieves a particular simulation statistic. @brief Retrieves a particular simulation statistic.
@@ -712,8 +712,8 @@ typedef struct Project *EN_Project;
@param[out] traceNode index of the node being traced (if applicable). @param[out] traceNode index of the node being traced (if applicable).
@return an error code. @return an error code.
*/ */
int DLLEXPORT EN_getqualinfo(EN_Project ph, int *qualType, char *chemName, int DLLEXPORT EN_getqualinfo(EN_Project ph, int *qualType, char *out_chemName,
char *chemUnits, int *traceNode); char *out_chemUnits, int *traceNode);
/** /**
@brief Retrieves the type of water quality analysis to be run. @brief Retrieves the type of water quality analysis to be run.
@@ -792,7 +792,7 @@ typedef struct Project *EN_Project;
The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters. The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters.
*/ */
int DLLEXPORT EN_getnodeid(EN_Project ph, int index, char *id); int DLLEXPORT EN_getnodeid(EN_Project ph, int index, char *out_id);
/** /**
@brief Changes the ID name of a node. @brief Changes the ID name of a node.
@@ -1037,7 +1037,7 @@ typedef struct Project *EN_Project;
\b demandName must be sized to contain at least @ref EN_SizeLimits "EN_MAXID" characters. \b demandName must be sized to contain at least @ref EN_SizeLimits "EN_MAXID" characters.
*/ */
int DLLEXPORT EN_getdemandname(EN_Project ph, int nodeIndex, int demandIndex, char *demandName); int DLLEXPORT EN_getdemandname(EN_Project ph, int nodeIndex, int demandIndex, char *out_demandName);
/** /**
@brief Assigns a name to a node's demand category. @brief Assigns a name to a node's demand category.
@@ -1072,7 +1072,7 @@ typedef struct Project *EN_Project;
- Hazen-Williams formula: 130 - Hazen-Williams formula: 130
- Darcy-Weisbach formula: 0.5 millifeet (0.15 mm) - Darcy-Weisbach formula: 0.5 millifeet (0.15 mm)
- Chezy-Manning formula: 0.01 - Chezy-Manning formula: 0.01
All other pipe properties are set to 0. All other pipe properties are set to 0.
A new pump has a status of \b EN_OPEN, a speed setting of 1, and has no pump A new pump has a status of \b EN_OPEN, a speed setting of 1, and has no pump
@@ -1116,7 +1116,7 @@ typedef struct Project *EN_Project;
The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters. The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters.
*/ */
int DLLEXPORT EN_getlinkid(EN_Project ph, int index, char *id); int DLLEXPORT EN_getlinkid(EN_Project ph, int index, char *out_id);
/** /**
@brief Changes the ID name of a link. @brief Changes the ID name of a link.
@@ -1151,7 +1151,7 @@ typedef struct Project *EN_Project;
\b EN_CONDITIONAL then the type change is cancelled if the link appears in any \b EN_CONDITIONAL then the type change is cancelled if the link appears in any
control and error 261 is returned. control and error 261 is returned.
*/ */
int DLLEXPORT EN_setlinktype(EN_Project ph, int *index, int linkType, int actionCode); int DLLEXPORT EN_setlinktype(EN_Project ph, int *inout_index, int linkType, int actionCode);
/** /**
@brief Gets the indexes of a link's start- and end-nodes. @brief Gets the indexes of a link's start- and end-nodes.
@@ -1288,7 +1288,7 @@ typedef struct Project *EN_Project;
The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters. The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters.
*/ */
int DLLEXPORT EN_getpatternid(EN_Project ph, int index, char *id); int DLLEXPORT EN_getpatternid(EN_Project ph, int index, char *out_id);
/** /**
@brief Changes the ID name of a time pattern given its index. @brief Changes the ID name of a time pattern given its index.
@@ -1396,7 +1396,7 @@ typedef struct Project *EN_Project;
The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters. The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters.
*/ */
int DLLEXPORT EN_getcurveid(EN_Project ph, int index, char *id); int DLLEXPORT EN_getcurveid(EN_Project ph, int index, char *out_id);
/** /**
@brief Changes the ID name of a data curve given its index. @brief Changes the ID name of a data curve given its index.
@@ -1465,7 +1465,7 @@ typedef struct Project *EN_Project;
to hold `nPoints` number of data points and for sizing `id` to hold at least to hold `nPoints` number of data points and for sizing `id` to hold at least
@ref EN_SizeLimits "EN_MAXID" characters. @ref EN_SizeLimits "EN_MAXID" characters.
*/ */
int DLLEXPORT EN_getcurve(EN_Project ph, int index, char* id, int *nPoints, int DLLEXPORT EN_getcurve(EN_Project ph, int index, char *out_id, int *nPoints,
double *xValues, double *yValues); double *xValues, double *yValues);
/** /**
@@ -1595,7 +1595,7 @@ typedef struct Project *EN_Project;
The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters. The ID name must be sized to hold at least @ref EN_SizeLimits "EN_MAXID" characters.
*/ */
int DLLEXPORT EN_getruleID(EN_Project ph, int index, char* id); int DLLEXPORT EN_getruleID(EN_Project ph, int index, char *out_id);
/** /**
@brief Gets the properties of a premise in a rule-based control. @brief Gets the properties of a premise in a rule-based control.

View File

@@ -1,178 +0,0 @@
/*
******************************************************************************
Project: OWA EPANET
Version: 2.2
Module: epanet_py.h
Description: EPANET API functions for Python SWIG wrap
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 02/08/2019
******************************************************************************
*/
#ifndef EPANET_PY_H
#define EPANET_PY_H
// Opaque pointer to project
typedef void *Handle;
#include "epanet2_enums.h"
#include "epanet_py_export.h"
#if defined(__cplusplus)
extern "C" {
#endif
int EXPORT_PY_API proj_create(Handle *ph_out);
int EXPORT_PY_API proj_delete(Handle *ph_inout);
int EXPORT_PY_API proj_run(Handle ph, const char *input_path, const char *report_path, const char *output_path);
int EXPORT_PY_API proj_init(Handle ph, const char *rptFile, const char *outFile, EN_FlowUnits unitsType, EN_HeadLossType headLossType);
int EXPORT_PY_API proj_open(Handle ph, const char *inpFile, const char *rptFile, const char *binOutFile);
int EXPORT_PY_API proj_gettitle(Handle ph, char *line1, char *line2, char *line3);
int EXPORT_PY_API proj_settitle(Handle ph, const char *line1, const char *line2, const char *line3);
int EXPORT_PY_API proj_getcount(Handle ph, EN_CountType code, int *count);
int EXPORT_PY_API proj_savefile(Handle ph, const char *inpfilename);
int EXPORT_PY_API proj_close(Handle ph);
int EXPORT_PY_API hydr_solve(Handle ph);
int EXPORT_PY_API hydr_save(Handle ph);
int EXPORT_PY_API hydr_open(Handle ph);
int EXPORT_PY_API hydr_init(Handle ph, EN_InitHydOption saveFlag);
int EXPORT_PY_API hydr_run(Handle ph, long *currentTime);
int EXPORT_PY_API hydr_next(Handle ph, long *tStep);
int EXPORT_PY_API hydr_close(Handle ph);
int EXPORT_PY_API hydr_savefile(Handle ph, char *filename);
int EXPORT_PY_API hydr_usefile(Handle ph, char *filename);
int EXPORT_PY_API qual_solve(Handle ph);
int EXPORT_PY_API qual_open(Handle ph);
int EXPORT_PY_API qual_init(Handle ph, EN_InitHydOption saveFlag);
int EXPORT_PY_API qual_run(Handle ph, long *currentTime);
int EXPORT_PY_API qual_next(Handle ph, long *tStep);
int EXPORT_PY_API qual_step(Handle ph, long *timeLeft);
int EXPORT_PY_API qual_close(Handle ph);
int EXPORT_PY_API rprt_writeline(Handle ph, char *line);
int EXPORT_PY_API rprt_writeresults(Handle ph);
int EXPORT_PY_API rprt_clear(Handle ph);
int EXPORT_PY_API rprt_reset(Handle ph);
int EXPORT_PY_API rprt_set(Handle ph, char *reportCommand);
int EXPORT_PY_API rprt_setlevel(Handle ph, EN_StatusReport code);
int EXPORT_PY_API rprt_anlysstats(Handle ph, EN_AnalysisStatistic code, double* value);
int EXPORT_PY_API anlys_getoption(Handle ph, EN_Option code, double *value);
int EXPORT_PY_API anlys_setoption(Handle ph, EN_Option code, double value);
int EXPORT_PY_API anlys_getflowunits(Handle ph, int *code);
int EXPORT_PY_API anlys_setflowunits(Handle ph, EN_FlowUnits code);
int EXPORT_PY_API anlys_gettimeparam(Handle ph, EN_TimeParameter code, long *value);
int EXPORT_PY_API anlys_settimeparam(Handle ph, EN_TimeParameter code, long value);
int EXPORT_PY_API anlys_getqualinfo(Handle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode);
int EXPORT_PY_API anlys_getqualtype(Handle ph, int *qualcode, int *tracenode);
int EXPORT_PY_API anlys_setqualtype(Handle ph, EN_QualityType qualcode, char *chemname, char *chemunits, char *tracenode);
int EXPORT_PY_API node_add(Handle ph, char *id, EN_NodeType nodeType, int *index);
int EXPORT_PY_API node_delete(Handle ph, int index, int actionCode);
int EXPORT_PY_API node_getindex(Handle ph, char *id, int *index);
int EXPORT_PY_API node_getid(Handle ph, int index, char *id);
int EXPORT_PY_API node_setid(Handle ph, int index, char *newid);
int EXPORT_PY_API node_gettype(Handle ph, int index, int *code);
int EXPORT_PY_API node_getvalue(Handle ph, int index, EN_NodeProperty code, double *value);
int EXPORT_PY_API node_setvalue(Handle ph, int index, EN_NodeProperty code, double value);
int EXPORT_PY_API node_getcoord(Handle ph, int index, double *x, double *y);
int EXPORT_PY_API node_setcoord(Handle ph, int index, double x, double y);
int EXPORT_PY_API dmnd_getmodel(Handle ph, int *type, double *pmin, double *preq, double *pexp);
int EXPORT_PY_API dmnd_setmodel(Handle ph, int type, double pmin, double preq, double pexp);
int EXPORT_PY_API dmnd_getcount(Handle ph, int nodeIndex, int *numDemands);
int EXPORT_PY_API dmnd_getbase(Handle ph, int nodeIndex, int demandIndex, double *baseDemand);
int EXPORT_PY_API dmnd_setbase(Handle ph, int nodeIndex, int demandIndex, double baseDemand);
int EXPORT_PY_API dmnd_getpattern(Handle ph, int nodeIndex, int demandIndex, int *pattIndex);
int EXPORT_PY_API dmnd_setpattern(Handle ph, int nodeIndex, int demandIndex, int patIndex);
int EXPORT_PY_API dmnd_getname(Handle ph, int nodeIndex, int demandIdx, char *demandName);
int EXPORT_PY_API dmnd_setname(Handle ph, int nodeIndex, int demandIdx, char *demandName);
int EXPORT_PY_API link_add(Handle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode, int *index);
int EXPORT_PY_API link_delete(Handle ph, int index, int actionCode);
int EXPORT_PY_API link_getindex(Handle ph, char *id, int *index);
int EXPORT_PY_API link_getid(Handle ph, int index, char *id);
int EXPORT_PY_API link_setid(Handle ph, int index, char *newid);
int EXPORT_PY_API link_gettype(Handle ph, int index, int *code);
int EXPORT_PY_API link_settype(Handle ph, int *index, EN_LinkType type, int actionCode);
int EXPORT_PY_API link_getnodes(Handle ph, int index, int *node1, int *node2);
int EXPORT_PY_API link_setnodes(Handle ph, int index, int node1, int node2);
int EXPORT_PY_API link_getvalue(Handle ph, int index, EN_LinkProperty code, double *value);
int EXPORT_PY_API link_setvalue(Handle ph, int index, int code, double v);
int EXPORT_PY_API pump_gettype(Handle ph, int linkIndex, int *outType);
int EXPORT_PY_API pump_getheadcurveindex(Handle ph, int pumpIndex, int *curveIndex);
int EXPORT_PY_API pump_setheadcurveindex(Handle ph, int pumpIndex, int curveIndex);
int EXPORT_PY_API ptrn_add(Handle ph, char *id);
int EXPORT_PY_API ptrn_getindex(Handle ph, char *id, int *index);
int EXPORT_PY_API ptrn_getid(Handle ph, int index, char *id);
int EXPORT_PY_API ptrn_getlength(Handle ph, int index, int *len);
int EXPORT_PY_API ptrn_getvalue(Handle ph, int index, int period, double *value);
int EXPORT_PY_API ptrn_setvalue(Handle ph, int index, int period, double value);
int EXPORT_PY_API ptrn_getavgvalue(Handle ph, int index, double *value);
int EXPORT_PY_API ptrn_set(Handle ph, int index, double *f, int len);
int EXPORT_PY_API curv_add(Handle ph, char *id);
int EXPORT_PY_API curv_getindex(Handle ph, char *id, int *index);
int EXPORT_PY_API curv_getid(Handle ph, int index, char *id);
int EXPORT_PY_API curv_getlength(Handle ph, int index, int *len);
int EXPORT_PY_API curv_gettype(Handle ph, int curveIndex, int *outType);
int EXPORT_PY_API curv_getvalue(Handle ph, int curveIndex, int pointIndex, double *x, double *y);
int EXPORT_PY_API curv_setvalue(Handle ph, int curveIndex, int pointIndex, double x, double y);
int EXPORT_PY_API curv_get(Handle ph, int curveIndex, char* id, int *nValues, double *xValues, double *yValues);
int EXPORT_PY_API curv_set(Handle ph, int index, double *x, double *y, int len);
int EXPORT_PY_API scntl_add(Handle ph, int type, int linkIndex, double setting, int nodeIndex, double level, int *index);
int EXPORT_PY_API scntl_delete(Handle ph, int index);
int EXPORT_PY_API scntl_get(Handle ph, int controlIndex, int *controlType, int *linkIndex, double *setting, int *nodeIndex, double *level);
int EXPORT_PY_API scntl_set(Handle ph, int cindex, int ctype, int lindex, double setting, int nindex, double level);
int EXPORT_PY_API rcntl_add(Handle ph, char *rule);
int EXPORT_PY_API rcntl_delete(Handle ph, int index);
int EXPORT_PY_API rcntl_get(Handle ph, int index, int *nPremises, int *nThenActions, int *nElseActions, double *priority);
int EXPORT_PY_API rcntl_getid(Handle ph, int index, char* id);
int EXPORT_PY_API rcntl_getpremise(Handle ph, int ruleIndex, int premiseIndex, int *logop, int *object, int *objIndex, int *variable, int *relop, int *status, double *value);
int EXPORT_PY_API rcntl_setpremise(Handle ph, int ruleIndex, int premiseIndex, int logop, int object, int objIndex, int variable, int relop, int status, double value);
int EXPORT_PY_API rcntl_setpremiseindex(Handle ph, int ruleIndex, int premiseIndex, int objIndex);
int EXPORT_PY_API rcntl_setpremisestatus(Handle ph, int ruleIndex, int premiseIndex, int status);
int EXPORT_PY_API rcntl_setpremisevalue(Handle ph, int ruleIndex, int premiseIndex, double value);
int EXPORT_PY_API rcntl_getthenaction(Handle ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting);
int EXPORT_PY_API rcntl_setthenaction(Handle ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting);
int EXPORT_PY_API rcntl_getelseaction(Handle ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting);
int EXPORT_PY_API rcntl_setelseaction(Handle ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting);
int EXPORT_PY_API rcntl_setrulepriority(Handle ph, int index, double priority);
void EXPORT_PY_API err_clear(Handle ph);
int EXPORT_PY_API err_check(Handle ph, char** msg_buffer);
void EXPORT_PY_API toolkit_free(void **memory);
int EXPORT_PY_API toolkit_getversion(int *version);
#if defined(__cplusplus)
}
#endif
#endif //EPANET_PY_H

View File

@@ -51,7 +51,7 @@ int DLLEXPORT EN_createproject(EN_Project *p)
return 0; return 0;
} }
int DLLEXPORT EN_deleteproject(EN_Project *p) int DLLEXPORT EN_deleteproject(EN_Project p)
/*---------------------------------------------------------------- /*----------------------------------------------------------------
** Input: none ** Input: none
** Output: none ** Output: none
@@ -60,13 +60,15 @@ int DLLEXPORT EN_deleteproject(EN_Project *p)
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
{ {
if (*p == NULL) return -1; if (p == NULL) return -1;
if ((*p)->Openflag) EN_close(*p); if (p->Openflag) {
remove((*p)->TmpHydFname); EN_close(p);
remove((*p)->TmpOutFname); }
remove((*p)->TmpStatFname); remove(p->TmpHydFname);
free(*p); remove(p->TmpOutFname);
*p = NULL; remove(p->TmpStatFname);
free(p);
p = NULL;
return 0; return 0;
} }

View File

@@ -1,809 +0,0 @@
/*
******************************************************************************
Project: OWA EPANET
Version: 2.2
Module: epanet_py.c
Description: EPANET API functions for Python SWIG wrap
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 05/15/2019
******************************************************************************
*/
#include <stdlib.h>
#include <string.h>
#include "epanet_py.h"
#include "util/errormanager.h"
#include "epanet2_2.h"
#include "text.h"
#include "types.h"
typedef struct
{
Project *project;
error_handle_t *error;
} handle_t;
// Extern functions
extern char *geterrmsg(int, char *);
// Local functions
void error_lookup(int errcode, char *errmsg, int len);
int EXPORT_PY_API proj_create(Handle *ph)
{
handle_t *handle = (handle_t *)calloc(1, sizeof(handle_t));
if (handle != NULL)
{
EN_createproject(&handle->project);
handle->error = create_error_manager(&error_lookup);
*ph = handle;
return 0;
}
return -1;
}
int EXPORT_PY_API proj_delete(Handle *ph)
{
handle_t *handle = (handle_t *)*ph;
if (handle == NULL)
return -1;
else
{
EN_deleteproject(&handle->project);
delete_error_manager(handle->error);
}
free(handle);
*ph = NULL;
return 0;
}
int EXPORT_PY_API proj_run(Handle ph, const char *input_path,
const char *report_path, const char *output_path)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_runproject(pr->project, input_path, report_path, output_path, NULL));
}
int EXPORT_PY_API proj_init(Handle ph, const char *rptFile, const char *outFile,
EN_FlowUnits unitsType, EN_HeadLossType headLossType)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_init(pr->project, rptFile, outFile, unitsType, headLossType));
}
int EXPORT_PY_API proj_open(Handle ph, const char *inpFile, const char *rptFile,
const char *binOutFile)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_open(pr->project, inpFile, rptFile, binOutFile));
}
int EXPORT_PY_API proj_gettitle(Handle ph, char *line1, char *line2, char *line3)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_gettitle(pr->project, line1, line2, line3));
}
int EXPORT_PY_API proj_settitle(Handle ph, const char *line1, const char *line2, const char *line3)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_settitle(pr->project, (char *)line1, (char *)line2, (char *)line3));
}
int EXPORT_PY_API proj_getcount(Handle ph, EN_CountType code, int *count)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcount(pr->project, code, count));
}
int EXPORT_PY_API proj_savefile(Handle ph, const char *filename)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_saveinpfile(pr->project, filename));
}
int EXPORT_PY_API proj_close(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_close(pr->project));
}
int EXPORT_PY_API hydr_solve(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_solveH(pr->project));
}
int EXPORT_PY_API hydr_save(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_saveH(pr->project));
}
int EXPORT_PY_API hydr_open(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_openH(pr->project));
}
int EXPORT_PY_API hydr_init(Handle ph, EN_InitHydOption saveFlag)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_initH(pr->project, saveFlag));
}
int EXPORT_PY_API hydr_run(Handle ph, long *currentTime)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_runH(pr->project, currentTime));
}
int EXPORT_PY_API hydr_next(Handle ph, long *tStep)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_nextH(pr->project, tStep));
}
int EXPORT_PY_API hydr_close(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_closeH(pr->project));
}
int EXPORT_PY_API hydr_savefile(Handle ph, char *filename)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_savehydfile(pr->project, filename));
}
int EXPORT_PY_API hydr_usefile(Handle ph, char *filename)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_usehydfile(pr->project, filename));
}
int EXPORT_PY_API qual_solve(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_solveQ(pr->project));
}
int EXPORT_PY_API qual_open(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_openQ(pr->project));
}
int EXPORT_PY_API qual_init(Handle ph, EN_InitHydOption saveFlag)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_initQ(pr->project, saveFlag));
}
int EXPORT_PY_API qual_run(Handle ph, long *currentTime)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_runQ(pr->project, currentTime));
}
int EXPORT_PY_API qual_next(Handle ph, long *tStep)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_nextQ(pr->project, tStep));
}
int EXPORT_PY_API qual_step(Handle ph, long *timeLeft)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_stepQ(pr->project, timeLeft));
}
int EXPORT_PY_API qual_close(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_closeQ(pr->project));
}
int EXPORT_PY_API rprt_writeline(Handle ph, char *line)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_writeline(pr->project, line));
}
int EXPORT_PY_API rprt_writeresults(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_report(pr->project));
}
int EXPORT_PY_API rprt_clear(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_clearreport(pr->project));
}
int EXPORT_PY_API rprt_reset(Handle ph)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_resetreport(pr->project));
}
int EXPORT_PY_API rprt_set(Handle ph, char *reportCommand)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setreport(pr->project, reportCommand));
}
int EXPORT_PY_API rprt_setlevel(Handle ph, EN_StatusReport code)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setstatusreport(pr->project, code));
}
int EXPORT_PY_API rprt_anlysstats(Handle ph, EN_AnalysisStatistic code, double* value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getstatistic(pr->project, code, value));
}
int EXPORT_PY_API anlys_getoption(Handle ph, EN_Option code, double *value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getoption(pr->project, (int)code, value));
}
int EXPORT_PY_API anlys_setoption(Handle ph, EN_Option code, double value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setoption(pr->project, (int)code, value));
}
int EXPORT_PY_API anlys_getflowunits(Handle ph, int *code)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getflowunits(pr->project, code));
}
int EXPORT_PY_API anlys_setflowunits(Handle ph, EN_FlowUnits code)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setflowunits(pr->project, code));
}
int EXPORT_PY_API anlys_gettimeparam(Handle ph, EN_TimeParameter code, long *value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_gettimeparam(pr->project, code, value));
}
int EXPORT_PY_API anlys_settimeparam(Handle ph, EN_TimeParameter code, long value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_settimeparam(pr->project, code, value));
}
int EXPORT_PY_API anlys_getqualinfo(Handle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getqualinfo(pr->project, qualcode, chemname, chemunits, tracenode));
}
int EXPORT_PY_API anlys_getqualtype(Handle ph, int *qualcode, int *tracenode)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getqualtype(pr->project, qualcode, tracenode));
}
int EXPORT_PY_API anlys_setqualtype(Handle ph, EN_QualityType qualcode, char *chemname, char *chemunits, char *tracenode)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setqualtype(pr->project, qualcode, chemname, chemunits, tracenode));
}
int EXPORT_PY_API node_add(Handle ph, char *id, EN_NodeType nodeType, int *index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_addnode(pr->project, id, nodeType, index));
}
int EXPORT_PY_API node_delete(Handle ph, int index, int actionCode)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_deletenode(pr->project, index, actionCode));
}
int EXPORT_PY_API node_getindex(Handle ph, char *id, int *index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getnodeindex(pr->project, id, index));
}
int EXPORT_PY_API node_getid(Handle ph, int index, char *id)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getnodeid(pr->project, index, id));
}
int EXPORT_PY_API node_setid(Handle ph, int index, char *newid)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getnodeid(pr->project, index, newid));
}
int EXPORT_PY_API node_gettype(Handle ph, int index, int *code)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getnodetype(pr->project, index, code));
}
int EXPORT_PY_API node_getvalue(Handle ph, int index, EN_NodeProperty code, double *value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getnodevalue(pr->project, index, (int)code, value));
}
int EXPORT_PY_API node_setvalue(Handle ph, int index, EN_NodeProperty code, double value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setnodevalue(pr->project, index, (int)code, value));
}
int EXPORT_PY_API node_getcoord(Handle ph, int index, double *x, double *y)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcoord(pr->project, index, x, y));
}
int EXPORT_PY_API node_setcoord(Handle ph, int index, double x, double y)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setcoord(pr->project, index, x, y));
}
int EXPORT_PY_API dmnd_getmodel(Handle ph, int *type, double *pmin, double *preq, double *pexp)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getdemandmodel(pr->project, type, pmin, preq, pexp));
}
int EXPORT_PY_API dmnd_setmodel(Handle ph, int type, double pmin, double preq, double pexp)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setdemandmodel(pr->project, type, pmin, preq, pexp));
}
int EXPORT_PY_API dmnd_getcount(Handle ph, int nodeIndex, int *numDemands)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getnumdemands(pr->project, nodeIndex, numDemands));
}
int EXPORT_PY_API dmnd_getbase(Handle ph, int nodeIndex, int demandIndex, double *baseDemand)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getbasedemand(pr->project, nodeIndex, demandIndex, baseDemand));
}
int EXPORT_PY_API dmnd_setbase(Handle ph, int nodeIndex, int demandIndex, double baseDemand)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setbasedemand(pr->project, nodeIndex, demandIndex, baseDemand));
}
int EXPORT_PY_API dmnd_getpattern(Handle ph, int nodeIndex, int demandIndex, int *patIndex)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getdemandpattern(pr->project, nodeIndex, demandIndex, patIndex));
}
int EXPORT_PY_API dmnd_setpattern(Handle ph, int nodeIndex, int demandIndex, int patIndex)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setdemandpattern(pr->project, nodeIndex, demandIndex, patIndex));
}
int EXPORT_PY_API dmnd_getname(Handle ph, int nodeIndex, int demandIdx, char *demandName)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getdemandname(pr->project, nodeIndex, demandIdx, demandName));
}
int EXPORT_PY_API dmnd_setname(Handle ph, int nodeIndex, int demandIdx, char *demandName)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setdemandname(pr->project, nodeIndex, demandIdx, demandName));
}
int EXPORT_PY_API link_add(Handle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode, int *index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_addlink(pr->project, id, linkType, fromNode, toNode, index));
}
int EXPORT_PY_API link_delete(Handle ph, int index, int actionCode)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_deletelink(pr->project, index, actionCode));
}
int EXPORT_PY_API link_getindex(Handle ph, char *id, int *index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getlinkindex(pr->project, id, index));
}
int EXPORT_PY_API link_getid(Handle ph, int index, char *id)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getlinkid(pr->project, index, id));
}
int EXPORT_PY_API link_setid(Handle ph, int index, char *newid)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setlinkid(pr->project, index, newid));
}
int EXPORT_PY_API link_gettype(Handle ph, int index, int *code)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getlinktype(pr->project, index, code));
}
int EXPORT_PY_API link_settype(Handle ph, int *index, EN_LinkType type, int actionCode)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setlinktype(pr->project, index, type, actionCode));
}
int EXPORT_PY_API link_getnodes(Handle ph, int index, int *node1, int *node2)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getlinknodes(pr->project, index, node1, node2));
}
int EXPORT_PY_API link_setnodes(Handle ph, int index, int node1, int node2)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setlinknodes(pr->project, index, node1, node2));
}
int EXPORT_PY_API link_getvalue(Handle ph, int index, EN_LinkProperty code, double *value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getlinkvalue(pr->project, index, code, value));
}
int EXPORT_PY_API link_setvalue(Handle ph, int index, int code, double value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setlinkvalue(pr->project, index, code, value));
}
int EXPORT_PY_API pump_gettype(Handle ph, int linkIndex, int *outType)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getpumptype(pr->project, linkIndex, outType));
}
int EXPORT_PY_API pump_getheadcurveindex(Handle ph, int pumpIndex, int *curveIndex)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getheadcurveindex(pr->project, pumpIndex, curveIndex));
}
int EXPORT_PY_API pump_setheadcurveindex(Handle ph, int pumpIndex, int curveIndex)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setheadcurveindex(pr->project, pumpIndex, curveIndex));
}
int EXPORT_PY_API ptrn_add(Handle ph, char *id)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_addpattern(pr->project, id));
}
int EXPORT_PY_API ptrn_getindex(Handle ph, char *id, int *index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getpatternindex(pr->project, id, index));
}
int EXPORT_PY_API ptrn_getid(Handle ph, int index, char *id)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getpatternid(pr->project, index, id));
}
int EXPORT_PY_API ptrn_getlength(Handle ph, int index, int *len)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getpatternlen(pr->project, index, len));
}
int EXPORT_PY_API ptrn_getvalue(Handle ph, int index, int period, double *value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getpatternvalue(pr->project, index, period, value));
}
int EXPORT_PY_API ptrn_setvalue(Handle ph, int index, int period, double value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setpatternvalue(pr->project, index, period, value));
}
int EXPORT_PY_API ptrn_getavgvalue(Handle ph, int index, double *value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getaveragepatternvalue(pr->project, index, value));
}
int EXPORT_PY_API ptrn_set(Handle ph, int index, double *values, int len)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setpattern(pr->project, index, values, len));
}
int EXPORT_PY_API curv_add(Handle ph, char *id)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_addcurve(pr->project, id));
}
int EXPORT_PY_API curv_getindex(Handle ph, char *id, int *index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcurveindex(pr->project, id, index));
}
int EXPORT_PY_API curv_getid(Handle ph, int index, char *id)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcurveid(pr->project, index, id));
}
int EXPORT_PY_API curv_getlength(Handle ph, int index, int *len)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcurvelen(pr->project, index, len));
}
int EXPORT_PY_API curv_gettype(Handle ph, int index, int *type)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcurvetype(pr->project, index, type));
}
int EXPORT_PY_API curv_getvalue(Handle ph, int curveIndex, int pointIndex, double *x, double *y)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcurvevalue(pr->project, curveIndex, pointIndex, x, y));
}
int EXPORT_PY_API curv_setvalue(Handle ph, int curveIndex, int pointIndex, double x, double y)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setcurvevalue(pr->project, curveIndex, pointIndex, x, y));
}
int EXPORT_PY_API curv_get(Handle ph, int curveIndex, char* id, int *nValues, double *xValues, double *yValues)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcurve(pr->project, curveIndex, id, nValues, xValues, yValues));
}
int EXPORT_PY_API curv_set(Handle ph, int index, double *x, double *y, int len)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setcurve(pr->project, index, x, y, len));
}
int EXPORT_PY_API scntl_add(Handle ph, int type, int linkIndex, double setting, int nodeIndex, double level, int *index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_addcontrol(pr->project, type, linkIndex, setting, nodeIndex, level, index));
}
int EXPORT_PY_API scntl_delete(Handle ph, int index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_deletecontrol(pr->project, index));
}
int EXPORT_PY_API scntl_get(Handle ph, int controlIndex, int *controlType, int *linkIndex, double *setting, int *nodeIndex, double *level)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getcontrol(pr->project, controlIndex, controlType, linkIndex, setting, nodeIndex, level));
}
int EXPORT_PY_API scntl_set(Handle ph, int cindex, int ctype, int lindex, double setting, int nindex, double level)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setcontrol(pr->project, cindex, ctype, lindex, setting, nindex, level));
}
int EXPORT_PY_API rcntl_add(Handle ph, char *rule)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_addrule(pr->project, rule));
}
int EXPORT_PY_API rcntl_delete(Handle ph, int index)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_deleterule(pr->project, index));
}
int EXPORT_PY_API rcntl_get(Handle ph, int index, int *nPremises, int *nThenActions, int *nElseActions, double *priority)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getrule(pr->project, index, nPremises, nThenActions, nElseActions, priority));
}
int EXPORT_PY_API rcntl_getid(Handle ph, int index, char *id)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getruleID(pr->project, index, id));
}
int EXPORT_PY_API rcntl_getpremise(Handle ph, int ruleIndex, int premiseIndex, int *logop, int *object, int *objIndex, int *variable, int *relop, int *status, double *value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getpremise(pr->project, ruleIndex, premiseIndex, logop, object, objIndex, variable, relop, status, value));
}
int EXPORT_PY_API rcntl_setpremise(Handle ph, int ruleIndex, int premiseIndex, int logop, int object, int objIndex, int variable, int relop, int status, double value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setpremise(pr->project, ruleIndex, premiseIndex, logop, object, objIndex, variable, relop, status, value));
}
int EXPORT_PY_API rcntl_setpremiseindex(Handle ph, int ruleIndex, int premiseIndex, int objIndex)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setpremiseindex(pr->project, ruleIndex, premiseIndex, objIndex));
}
int EXPORT_PY_API rcntl_setpremisestatus(Handle ph, int ruleIndex, int premiseIndex, int status)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setpremisestatus(pr->project, ruleIndex, premiseIndex, status));
}
int EXPORT_PY_API rcntl_setpremisevalue(Handle ph, int ruleIndex, int premiseIndex, double value)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setpremisevalue(pr->project, ruleIndex, premiseIndex, value));
}
int EXPORT_PY_API rcntl_getthenaction(Handle ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getthenaction(pr->project, ruleIndex, actionIndex, linkIndex, status, setting));
}
int EXPORT_PY_API rcntl_setthenaction(Handle ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setthenaction(pr->project, ruleIndex, actionIndex, linkIndex, status, setting));
}
int EXPORT_PY_API rcntl_getelseaction(Handle ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_getelseaction(pr->project, ruleIndex, actionIndex, linkIndex, status, setting));
}
int EXPORT_PY_API rcntl_setelseaction(Handle ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setelseaction(pr->project, ruleIndex, actionIndex, linkIndex, status, setting));
}
int EXPORT_PY_API rcntl_setrulepriority(Handle ph, int index, double priority)
{
handle_t *pr = (handle_t *)ph;
return set_error(pr->error, EN_setrulepriority(pr->project, index, priority));
}
void EXPORT_PY_API err_clear(Handle ph)
{
handle_t *pr = (handle_t *)ph;
clear_error(pr->error);
}
int EXPORT_PY_API err_check(Handle ph, char** msg_buffer)
//
// Purpose: Returns the error code and message or 0 and NULL respectively.
//
// Note: Caller must free memory allocated by EN_check_error
//
{
handle_t *pr = (handle_t *)ph;
return check_error(pr->error, msg_buffer);
}
int EXPORT_PY_API toolkit_getversion(int *version)
{
return EN_getversion(version);
}
void EXPORT_PY_API toolkit_free(void **memory)
{
free(*memory);
*memory = NULL;
}
void error_lookup(int errcode, char *dest_msg, int dest_len)
// Purpose: takes error code returns error message
{
char *msg = NULL;
char new_msg[MAXMSG + 1];
switch (errcode)
{
case 1: msg = WARN1;
break;
case 2: msg = WARN2;
break;
case 3: msg = WARN3;
break;
case 4: msg = WARN4;
break;
case 5: msg = WARN5;
break;
case 6: msg = WARN6;
break;
default: msg = geterrmsg(errcode, new_msg);
}
strncpy(dest_msg, msg, dest_len);
}

View File

@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(test_categories_save)
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
error = EN_deleteproject(&ph); error = EN_deleteproject(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
} }
@@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(test_categories_reopen, * boost::unit_test::depends_on("tes
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
error = EN_deleteproject(&ph); error = EN_deleteproject(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
} }
@@ -106,10 +106,10 @@ BOOST_FIXTURE_TEST_CASE(test_adddemand, FixtureSingleNode)
error = EN_adddemand(ph, node_qhut, 1.0, "TertiaryPattern", "TertiaryDemand"); error = EN_adddemand(ph, node_qhut, 1.0, "TertiaryPattern", "TertiaryDemand");
BOOST_CHECK(error == 0); BOOST_CHECK(error == 0);
error = EN_getnumdemands(ph, node_qhut, &nD1); error = EN_getnumdemands(ph, node_qhut, &nD1);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
error = EN_getdemandindex(ph, node_qhut, "TertiaryDemand", &Dindex); error = EN_getdemandindex(ph, node_qhut, "TertiaryDemand", &Dindex);
BOOST_CHECK(error == 0); BOOST_CHECK(error == 0);
BOOST_CHECK(Dindex == nD1); BOOST_CHECK(Dindex == nD1);

View File

@@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(test_setlinktype)
// Close and delete project // Close and delete project
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
@@ -178,7 +178,7 @@ BOOST_AUTO_TEST_CASE(test_link_setid_save)
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_AUTO_TEST_CASE(test_link_setid_reopen, * boost::unit_test::depends_on("test_link/test_link_setid_save")) BOOST_AUTO_TEST_CASE(test_link_setid_reopen, * boost::unit_test::depends_on("test_link/test_link_setid_save"))
@@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(test_link_setid_reopen, * boost::unit_test::depends_on("tes
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_FIXTURE_TEST_CASE(test_link_comments, FixtureOpenClose) BOOST_FIXTURE_TEST_CASE(test_link_comments, FixtureOpenClose)

View File

@@ -43,7 +43,7 @@ struct FixtureInitClose {
~FixtureInitClose() { ~FixtureInitClose() {
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
int error; int error;
EN_Project ph; EN_Project ph;
@@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(test_open_net1, * boost::unit_test::depends_on("test_net_bu
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// if we got this far we can compare results // if we got this far we can compare results
@@ -408,7 +408,7 @@ BOOST_AUTO_TEST_CASE(test_reopen_net2, *boost::unit_test::depends_on("test_net_b
// Close project // Close project
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(test_setid_save)
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
@@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(test_setid_reopen, * boost::unit_test::depends_on("setid_sa
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
@@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(test_reopen_comment, * boost::unit_test::depends_on("node_c
// Close project // Close project
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }

View File

@@ -89,14 +89,14 @@ BOOST_AUTO_TEST_CASE(test_tank_overflow)
BOOST_REQUIRE(spillage > 0.0001); BOOST_REQUIRE(spillage > 0.0001);
error = EN_getlinkvalue(ph, Lindex, EN_FLOW, &inflow); error = EN_getlinkvalue(ph, Lindex, EN_FLOW, &inflow);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
BOOST_REQUIRE(abs(-inflow - spillage) < 0.0001); BOOST_REQUIRE(abs(-inflow - spillage) < 0.0001);
// Save project to file and then close it // Save project to file and then close it
error = EN_saveinpfile(ph, testFile); error = EN_saveinpfile(ph, testFile);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
// Re-open saved file & run it // Re-open saved file & run it
error = EN_open(ph, testFile, DATA_PATH_RPT, ""); error = EN_open(ph, testFile, DATA_PATH_RPT, "");
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
@@ -107,13 +107,13 @@ BOOST_AUTO_TEST_CASE(test_tank_overflow)
error = EN_getnodevalue(ph, Nindex, EN_DEMAND, &spillage2); error = EN_getnodevalue(ph, Nindex, EN_DEMAND, &spillage2);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
BOOST_REQUIRE(abs(spillage - spillage2) < 0.0001); BOOST_REQUIRE(abs(spillage - spillage2) < 0.0001);
// Clean up // Clean up
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
error = EN_deleteproject(&ph); error = EN_deleteproject(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(test_add_set)
BOOST_REQUIRE(y == y3[0]); BOOST_REQUIRE(y == y3[0]);
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_FIXTURE_TEST_CASE(test_pattern_comments, FixtureOpenClose) BOOST_FIXTURE_TEST_CASE(test_pattern_comments, FixtureOpenClose)

View File

@@ -31,10 +31,9 @@ BOOST_AUTO_TEST_CASE (test_create_delete)
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
BOOST_CHECK(ph != NULL); BOOST_CHECK(ph != NULL);
error = EN_deleteproject(&ph); error = EN_deleteproject(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
BOOST_CHECK(ph == NULL);
} }
BOOST_AUTO_TEST_CASE (test_open_close) BOOST_AUTO_TEST_CASE (test_open_close)
@@ -51,7 +50,7 @@ BOOST_AUTO_TEST_CASE (test_open_close)
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_AUTO_TEST_CASE(test_init_close) BOOST_AUTO_TEST_CASE(test_init_close)
@@ -65,7 +64,7 @@ BOOST_AUTO_TEST_CASE(test_init_close)
error = EN_close(ph); error = EN_close(ph);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_AUTO_TEST_CASE(test_save) BOOST_AUTO_TEST_CASE(test_save)
@@ -85,7 +84,7 @@ BOOST_AUTO_TEST_CASE(test_save)
error = EN_close(ph_save); error = EN_close(ph_save);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph_save); EN_deleteproject(ph_save);
} }
BOOST_AUTO_TEST_CASE(test_reopen, * boost::unit_test::depends_on("test_project/test_save")) BOOST_AUTO_TEST_CASE(test_reopen, * boost::unit_test::depends_on("test_project/test_save"))
@@ -100,7 +99,7 @@ BOOST_AUTO_TEST_CASE(test_reopen, * boost::unit_test::depends_on("test_project/t
error = EN_close(ph_reopen); error = EN_close(ph_reopen);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph_reopen); EN_deleteproject(ph_reopen);
} }
BOOST_AUTO_TEST_CASE(test_run) BOOST_AUTO_TEST_CASE(test_run)
@@ -114,7 +113,7 @@ BOOST_AUTO_TEST_CASE(test_run)
error = EN_runproject(ph, DATA_PATH_NET1, DATA_PATH_RPT, DATA_PATH_OUT, NULL); error = EN_runproject(ph, DATA_PATH_NET1, DATA_PATH_RPT, DATA_PATH_OUT, NULL);
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@@ -42,7 +42,7 @@ void epanet_thread(long i)
EN_createproject(&ph); EN_createproject(&ph);
errorcode = EN_runproject(ph, input.c_str(), report.c_str(), output.c_str(), NULL); errorcode = EN_runproject(ph, input.c_str(), report.c_str(), output.c_str(), NULL);
EN_deleteproject(&ph); EN_deleteproject(ph);
printf("Thread #%ld EPANET done. Status = %d\n", i, errorcode); printf("Thread #%ld EPANET done. Status = %d\n", i, errorcode);
} }

View File

@@ -33,7 +33,7 @@ struct FixtureOpenClose{
~FixtureOpenClose() { ~FixtureOpenClose() {
error = EN_close(ph); error = EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
int error; int error;
@@ -52,7 +52,7 @@ struct FixtureInitClose {
~FixtureInitClose() { ~FixtureInitClose() {
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
int error; int error;
EN_Project ph; EN_Project ph;
@@ -94,7 +94,7 @@ struct FixtureAfterStep{
BOOST_REQUIRE(error == 0); BOOST_REQUIRE(error == 0);
error = EN_close(ph); error = EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
int error, flag; int error, flag;
@@ -115,7 +115,7 @@ struct FixtureSingleNode {
~FixtureSingleNode() { ~FixtureSingleNode() {
EN_close(ph); EN_close(ph);
EN_deleteproject(&ph); EN_deleteproject(ph);
} }
int error, index, node_qhut; int error, index, node_qhut;
EN_Project ph; EN_Project ph;