Merge branch 'dev' into 681-request-additional-api-function-for-getting-finer-grained-time-step-information
This commit is contained in:
12
.github/workflows/ccpp.yml
vendored
12
.github/workflows/ccpp.yml
vendored
@@ -1,6 +1,10 @@
|
||||
name: C/C++ CI
|
||||
name: linux
|
||||
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 1 * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -17,3 +21,7 @@ jobs:
|
||||
- name: make
|
||||
working-directory: ./buildproducts
|
||||
run: make
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: libepanet-output
|
||||
path: /home/runner/work/EPANET/EPANET/buildproducts/
|
||||
|
||||
26
.github/workflows/win32.yml
vendored
Normal file
26
.github/workflows/win32.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: epanet2-win32
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 1 * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: setup_build_dir
|
||||
run: mkdir buildproducts
|
||||
- name: cmake
|
||||
working-directory: ./buildproducts
|
||||
run: cmake .. -A Win32 && cmake --build . --config Release
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: epanet2-win32
|
||||
path: D:\a\EPANET\EPANET\buildproducts\bin\Release\
|
||||
26
.github/workflows/win64.yml
vendored
Normal file
26
.github/workflows/win64.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: epanet2-win64
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 1 * *'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: setup_build_dir
|
||||
run: mkdir buildproducts
|
||||
- name: cmake
|
||||
working-directory: ./buildproducts
|
||||
run: cmake .. -A x64 && cmake --build . --config Release
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: epanet2-win64
|
||||
path: D:\a\EPANET\EPANET\buildproducts\bin\Release\
|
||||
@@ -3,10 +3,13 @@ OWA-EPANET
|
||||
|
||||
## Build Status
|
||||
[](https://ci.appveyor.com/project/OpenWaterAnalytics/epanet)
|
||||
[](https://travis-ci.org/OpenWaterAnalytics/EPANET)
|
||||
|
||||
[](https://codecov.io/gh/OpenWaterAnalytics/EPANET)
|
||||
|
||||
[](https://github.com/OpenWaterAnalytics/EPANET/actions/workflows/ccpp.yml)
|
||||
[](https://github.com/OpenWaterAnalytics/EPANET/actions/workflows/win32.yml)
|
||||
[](https://github.com/OpenWaterAnalytics/EPANET/actions/workflows/win64.yml)
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
**EPANET** is an industry-standard program for modeling the hydraulic and water quality behavior of water distribution system pipe networks. The EPANET Programmer's Toolkit is a library of functions (or API) written in C that allow programmers to customize the use of EPANET's solution engine for their own applications. Both EPANET and its toolkit were originally developed by the U.S. Environmental Protection Agency (USEPA). If you are interested in using/extending the EPANET engine and its API for academic, personal, or commercial use, then you've come to the right place. [Read more about EPANET on Wikipedia](https://en.wikipedia.org/wiki/EPANET). (Please note that this project covers only the EPANET hydraulic and water quality solver engine, not the graphical user interface.)
|
||||
|
||||
@@ -22,6 +22,9 @@ This document describes the changes and updates that have been made in version 2
|
||||
- changing the absolute tolerance used to compare the closeness of test results to benchmark values from 0 to 0.0001
|
||||
- dropping the "correct decimal digits" test
|
||||
- dropping the check for identical status report content since it prevents accepting code changes that produce more accurate solutions in fewer iterations.
|
||||
- A possible loss of network connectivity when evaluating a Pressure Sustaining Valve was prevented.
|
||||
- Having the implied loss coefficient for an active Flow Control Valve be less than its fully opened value was prevented.
|
||||
- A new type of valve, a Positional Control Valve (PCV), was added that uses a valve characteristic curve to relate its loss coefficient to its fraction open setting.
|
||||
|
||||
|
||||
|
||||
|
||||
45
conanfile.py
Normal file
45
conanfile.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from conans import ConanFile
|
||||
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout
|
||||
|
||||
class EpanetConan(ConanFile):
|
||||
name = "epanet"
|
||||
version = "2.2"
|
||||
description = "EPANET is an industry-standard program for modeling the hydraulic and water quality behavior of water distribution system pipe networks."
|
||||
homepage = "https://github.com/OpenWaterAnalytics/EPANET"
|
||||
url = "https://github.com/OpenWaterAnalytics/EPANET"
|
||||
license = "MIT"
|
||||
|
||||
# Binary configuration
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
options = {"shared": [True, False], "fPIC": [True, False]}
|
||||
default_options = {"shared": False, "fPIC": True}
|
||||
|
||||
exports_sources = "CMakeLists.txt", "src/*", "include/*", "run/*"
|
||||
|
||||
def config_options(self):
|
||||
if self.settings.os == "Windows":
|
||||
del self.options.fPIC
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
self.copy("lib/libepanet2.dylib", "lib", keep_path=False)
|
||||
self.copy("lib/libepanet-output.dylib", "lib", keep_path=False)
|
||||
self.copy("*.h", "include", "include", keep_path=False)
|
||||
self.copy("types.h", "include", "src", keep_path=False)
|
||||
self.copy("hash.h", "include", "src", keep_path=False)
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libdirs = ["lib"]
|
||||
self.cpp_info.libs = ["epanet2", "epanet-output"]
|
||||
self.cpp_info.includedirs = ["include"]
|
||||
@@ -92,9 +92,10 @@ __Remarks:__
|
||||
- Head v. Flow for pumps
|
||||
- Efficiency v. Flow for pumps
|
||||
- Volume v. Depth for tanks
|
||||
- Fraction of fully open flow v. fraction open for Positional Control Valves
|
||||
- Head Loss v. Flow for General Purpose Valves
|
||||
2. The points of a curve must be entered in order of increasing X-values (lower to higher).
|
||||
3. If the input file will be used with the Windows version of EPANET, then adding a comment which contains the curve type and description, separated by a colon, directly above the first entry for a curve will ensure that these items appear correctly in EPANET's Curve Editor. Curve types include <B>PUMP, EFFICIENCY, VOLUME</B>, and <B>HEADLOSS</B>. See the examples below.
|
||||
3. If the input file will be used with the Windows version of EPANET, then adding a comment which contains the curve type and description, separated by a colon, directly above the first entry for a curve will ensure that these items appear correctly in EPANET's Curve Editor. Curve types include <B>PUMP, EFFICIENCY, VOLUME, VALVE</B>, and <B>HEADLOSS</B>. See the examples below.
|
||||
|
||||
__Example:__
|
||||
```
|
||||
@@ -1028,7 +1029,8 @@ One line for each valve containing:
|
||||
- Diameter, inches (mm)
|
||||
- Valve type
|
||||
- Valve setting
|
||||
- Minor loss coefficient
|
||||
- Minor loss coefficient when fully open
|
||||
- ID of valve characteristic curve (PCVs only)
|
||||
|
||||
__Remarks:__
|
||||
1. Valve types and settings include:
|
||||
@@ -1038,9 +1040,14 @@ __Remarks:__
|
||||
|<B>PSV</B> (pressure sustaining valve) | Pressure, psi (m) |
|
||||
|<B>PBV</B> (pressure breaker valve) | Pressure, psi (m) |
|
||||
|<B>FCV</B> (flow control valve) | Flow (flow units) |
|
||||
|<B>TCV</B> (throttle control valve) | Loss Coefficient |
|
||||
|<B>TCV</B> (throttle control valve) | Partially open loss coefficient |
|
||||
|<B>PCV</B> (positional control valve) | Fraction open |
|
||||
|<B>GPV</B> (general purpose valve) | ID of head loss curve |
|
||||
2. Shutoff valves and check valves are considered to be part of a pipe, not a separate control valve component (see @ref PipesPage).
|
||||
3. The loss coefficient setting for a TCV should not be less than its fully open loss coefficient.
|
||||
4. The characteristic curve for a PCV relates the valve's fraction of fully open flow to the fraction open. If not supplied then a linear curve is assumed.
|
||||
5. The partially opened loss coefficient for a PCV is the inverse of the squared value from its characteristic curve times the fully open loss coefficient.
|
||||
6. The head loss curve for a GPV relates head loss across the valve to the flow rate through it.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -73,6 +73,9 @@ namespace EpanetCSharpLibrary
|
||||
public const int EN_PUMP_ECURVE = 20;
|
||||
public const int EN_PUMP_ECOST = 21;
|
||||
public const int EN_PUMP_EPAT = 22;
|
||||
public const int EN_LINK_INCONTROL = 23;
|
||||
public const int EN_GPV_CURVE = 24;
|
||||
public const int EN_PCV_CURVE = 25;
|
||||
|
||||
public const int EN_DURATION = 0; //Time parameters
|
||||
public const int EN_HYDSTEP = 1;
|
||||
@@ -126,6 +129,7 @@ namespace EpanetCSharpLibrary
|
||||
public const int EN_FCV = 6;
|
||||
public const int EN_TCV = 7;
|
||||
public const int EN_GPV = 8;
|
||||
public const int EN_PCV = 9;
|
||||
|
||||
public const int EN_NONE = 0; //Quality analysis types
|
||||
public const int EN_CHEM = 1;
|
||||
@@ -209,6 +213,7 @@ namespace EpanetCSharpLibrary
|
||||
public const int EN_EFFIC_CURVE = 2; //Efficiency curve
|
||||
public const int EN_HLOSS_CURVE = 3; //Head loss curve
|
||||
public const int EN_GENERIC_CURVE = 4; //Generic curve
|
||||
public const int EN_VALVE_CURVE = 5; //Valve position curve
|
||||
|
||||
public const int EN_UNCONDITIONAL = 0; //Unconditional object deletion
|
||||
public const int EN_CONDITIONAL = 1; //Conditional object deletion
|
||||
|
||||
@@ -5,7 +5,7 @@ Attribute VB_Name = "Module1"
|
||||
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
|
||||
'(EPANET2.DLL)
|
||||
|
||||
'Last updated on 02/01/2020
|
||||
'Last updated on 07/28/2022
|
||||
|
||||
' These are codes used by the DLL functions
|
||||
Public Const EN_ELEVATION = 0 ' Node parameters
|
||||
@@ -63,6 +63,7 @@ Public Const EN_PUMP_ECOST = 21
|
||||
Public Const EN_PUMP_EPAT = 22
|
||||
Public Const EN_LINK_INCONTROL = 23
|
||||
Public Const EN_GPV_CURVE = 24
|
||||
Public Const EN_PCV_CURVE= 25
|
||||
|
||||
Public Const EN_DURATION = 0 ' Time parameters
|
||||
Public Const EN_HYDSTEP = 1
|
||||
@@ -117,6 +118,7 @@ Public Const EN_PBV = 5
|
||||
Public Const EN_FCV = 6
|
||||
Public Const EN_TCV = 7
|
||||
Public Const EN_GPV = 8
|
||||
Public Const EN_PCV = 9
|
||||
|
||||
Public Const EN_CLOSED = 0 ' Link status types
|
||||
Public Const EN_OPEN = 1
|
||||
@@ -209,6 +211,7 @@ Public Const EN_PUMP_CURVE = 1 ' Pump curve
|
||||
Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
|
||||
Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
|
||||
Public Const EN_GENERIC_CURVE = 4 ' Generic curve
|
||||
Public Const EN_VALVE_CURVE = 5 ' Valve position curve
|
||||
|
||||
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
|
||||
Public Const EN_CONDITIONAL = 1 ' Conditional object deletion
|
||||
|
||||
@@ -161,6 +161,10 @@ extern "C" {
|
||||
|
||||
int DLLEXPORT ENtimetonextevent(int *eventType, long *duration, int *elementIndex);
|
||||
|
||||
int DLLEXPORT ENsetreportcallback(void (*callback)(void *userData, void *EN_projectHandle, char*));
|
||||
int DLLEXPORT ENsetreportcallbackuserdata(void *userData);
|
||||
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Analysis Options Functions
|
||||
|
||||
@@ -3,7 +3,7 @@ unit epanet2;
|
||||
{ Declarations of imported procedures from the EPANET PROGRAMMERs TOOLKIT }
|
||||
{ (EPANET2.DLL) }
|
||||
|
||||
{Last updated on 02/01/2020}
|
||||
{Last updated on 07/28/2022}
|
||||
|
||||
interface
|
||||
|
||||
@@ -69,6 +69,7 @@ const
|
||||
EN_PUMP_EPAT = 22;
|
||||
EN_LINK_INCONTROL = 23;
|
||||
EN_GPV_CURVE = 24;
|
||||
EN_PCV_CURVE = 25;
|
||||
|
||||
EN_DURATION = 0; { Time parameters }
|
||||
EN_HYDSTEP = 1;
|
||||
@@ -123,6 +124,7 @@ const
|
||||
EN_FCV = 6;
|
||||
EN_TCV = 7;
|
||||
EN_GPV = 8;
|
||||
EN_PCV = 9;
|
||||
|
||||
EN_CLOSED = 0; { Link status types }
|
||||
EN_OPEN = 1;
|
||||
@@ -214,7 +216,8 @@ const
|
||||
EN_PUMP_CURVE = 1;
|
||||
EN_EFFIC_CURVE = 2;
|
||||
EN_HLOSS_CURVE = 3;
|
||||
EN_GENERIC_CURVE = 4;
|
||||
EN_GENERIC_CURVE = 4;
|
||||
EN_VALVE_CURVE = 5;
|
||||
|
||||
EN_UNCONDITIONAL = 0; { Deletion action codes }
|
||||
EN_CONDITIONAL = 1;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
|
||||
'(EPANET2.DLL) for use with VB.Net.
|
||||
|
||||
'Last updated on 02/01/2020
|
||||
'Last updated on 07/28/2022
|
||||
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Text
|
||||
@@ -67,6 +67,7 @@ Public Const EN_PUMP_ECOST = 21
|
||||
Public Const EN_PUMP_EPAT = 22
|
||||
Public Const EN_LINK_INCONTROL = 23
|
||||
Public Const EN_GPV_CURVE = 24
|
||||
Public Const EN_PCV_CURVE = 25
|
||||
|
||||
Public Const EN_DURATION = 0 ' Time parameters
|
||||
Public Const EN_HYDSTEP = 1
|
||||
@@ -120,6 +121,7 @@ Public Const EN_PBV = 5
|
||||
Public Const EN_FCV = 6
|
||||
Public Const EN_TCV = 7
|
||||
Public Const EN_GPV = 8
|
||||
Public Const EN_PCV = 9
|
||||
|
||||
Public Const EN_NONE = 0 ' Quality analysis types
|
||||
Public Const EN_CHEM = 1
|
||||
@@ -203,6 +205,7 @@ Public Const EN_PUMP_CURVE = 1 ' Pump curve
|
||||
Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
|
||||
Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
|
||||
Public Const EN_GENERIC_CURVE = 4 ' Generic curve
|
||||
Public Const EN_VALVE_CURVE = 5 ' Valve position curve
|
||||
|
||||
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
|
||||
Public Const EN_CONDITIONAL = 1 ' Conditional object deletion
|
||||
|
||||
@@ -517,6 +517,18 @@ typedef struct Project *EN_Project;
|
||||
|
||||
********************************************************************/
|
||||
|
||||
/**
|
||||
@brief Set a user-supplied callback function for reporting
|
||||
@param ph an EPANET project handle.
|
||||
@param callback a function pointer with declared signature, which gets called by EPANET for reporting.
|
||||
@return an error code.
|
||||
@details The report callback function must have the signature specified - void(void* userData, EN_Project, char*) -
|
||||
use the userData parameter to pass any client context necessary (a context pointer or wrapper object perhaps).
|
||||
Leave un-set or set the report callback to NULL to revert to EPANET's default behavior.
|
||||
**/
|
||||
int DLLEXPORT EN_setreportcallback(EN_Project ph, void (*callback)(void *userData, void *EN_projectHandle, char*));
|
||||
int DLLEXPORT EN_setreportcallbackuserdata(EN_Project ph, void *userData);
|
||||
|
||||
/**
|
||||
@brief Writes a line of text to a project's report file.
|
||||
@param ph an EPANET project handle.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/01/2020
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,8 @@ typedef enum {
|
||||
EN_PUMP_ECOST = 21, //!< Pump average energy price
|
||||
EN_PUMP_EPAT = 22, //!< Pump energy price time pattern index
|
||||
EN_LINK_INCONTROL = 23, //!< Is present in any simple or rule-based control (= 1) or not (= 0)
|
||||
EN_GPV_CURVE = 24 //!< GPV head loss v. flow curve index
|
||||
EN_GPV_CURVE = 24, //!< GPV head loss v. flow curve index
|
||||
EN_PCV_CURVE = 25 //!< PCV loss coeff. curve index
|
||||
} EN_LinkProperty;
|
||||
|
||||
/// Time parameters
|
||||
@@ -203,7 +204,8 @@ typedef enum {
|
||||
EN_PBV = 5, //!< Pressure breaker valve
|
||||
EN_FCV = 6, //!< Flow control valve
|
||||
EN_TCV = 7, //!< Throttle control valve
|
||||
EN_GPV = 8 //!< General purpose valve
|
||||
EN_GPV = 8, //!< General purpose valve
|
||||
EN_PCV = 9 //!< Positional control valve
|
||||
} EN_LinkType;
|
||||
|
||||
/// Link status
|
||||
@@ -409,7 +411,8 @@ typedef enum {
|
||||
EN_PUMP_CURVE = 1, //!< Pump head v. flow curve
|
||||
EN_EFFIC_CURVE = 2, //!< Pump efficiency v. flow curve
|
||||
EN_HLOSS_CURVE = 3, //!< Valve head loss v. flow curve
|
||||
EN_GENERIC_CURVE = 4 //!< Generic curve
|
||||
EN_GENERIC_CURVE = 4, //!< Generic curve
|
||||
EN_VALVE_CURVE = 5 //!< Valve loss coeff. v. frac. open
|
||||
} EN_CurveType;
|
||||
|
||||
/// Deletion action codes
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 06/20/2019
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,8 @@ char *LinkTxt[] = {w_CV,
|
||||
w_PBV,
|
||||
w_FCV,
|
||||
w_TCV,
|
||||
w_GPV};
|
||||
w_GPV,
|
||||
w_PCV};
|
||||
|
||||
char *StatTxt[] = {t_XHEAD,
|
||||
t_TEMPCLOSED,
|
||||
|
||||
39
src/epanet.c
39
src/epanet.c
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 11/08/2020
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -841,6 +841,19 @@ int DLLEXPORT EN_closeQ(EN_Project p)
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
||||
int DLLEXPORT EN_setreportcallback(EN_Project p, void (*callback)(void*,void*,char*))
|
||||
{
|
||||
p->report.reportCallback = callback;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DLLEXPORT EN_setreportcallbackuserdata(EN_Project p, void *userData)
|
||||
{
|
||||
p->report.reportCallbackUserData = userData;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DLLEXPORT EN_writeline(EN_Project p, char *line)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: line = line of text
|
||||
@@ -3184,7 +3197,7 @@ int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
if (EN_getlinkindex(p, id, &i) == 0) return 215;
|
||||
|
||||
// Check for valid link type
|
||||
if (linkType < CVPIPE || linkType > GPV) return 251;
|
||||
if (linkType < CVPIPE || linkType > PCV) return 251;
|
||||
|
||||
// Lookup the link's from and to nodes
|
||||
n1 = hashtable_find(net->NodeHashTable, fromNode);
|
||||
@@ -3244,6 +3257,7 @@ int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
size = (net->Nvalves + 1) * sizeof(Svalve);
|
||||
net->Valve = (Svalve *)realloc(net->Valve, size);
|
||||
net->Valve[net->Nvalves].Link = n;
|
||||
net->Valve[net->Nvalves].Curve = 0;
|
||||
}
|
||||
|
||||
link->Type = linkType;
|
||||
@@ -3503,7 +3517,7 @@ int DLLEXPORT EN_setlinktype(EN_Project p, int *index, int linkType, int actionC
|
||||
if (p->hydraul.OpenHflag || p->quality.OpenQflag) return 262;
|
||||
|
||||
// Check for valid input parameters
|
||||
if (linkType < 0 || linkType > GPV || actionCode < EN_UNCONDITIONAL ||
|
||||
if (linkType < 0 || linkType > PCV || actionCode < EN_UNCONDITIONAL ||
|
||||
actionCode > EN_CONDITIONAL)
|
||||
{
|
||||
return 251;
|
||||
@@ -3828,7 +3842,14 @@ int DLLEXPORT EN_getlinkvalue(EN_Project p, int index, int property, double *val
|
||||
v = (double)Pump[findpump(&p->network, index)].Epat;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case EN_PCV_CURVE:
|
||||
if (Link[index].Type == PCV)
|
||||
{
|
||||
v = net->Valve[findvalve(&p->network, index)].Curve;
|
||||
}
|
||||
break;
|
||||
|
||||
case EN_GPV_CURVE:
|
||||
if (Link[index].Type == GPV)
|
||||
{
|
||||
@@ -3951,6 +3972,7 @@ int DLLEXPORT EN_setlinkvalue(EN_Project p, int index, int property, double valu
|
||||
value /= Ucf[FLOW];
|
||||
break;
|
||||
case TCV:
|
||||
case PCV:
|
||||
break;
|
||||
case GPV:
|
||||
return 207; // Cannot modify setting for GPV
|
||||
@@ -4046,6 +4068,15 @@ int DLLEXPORT EN_setlinkvalue(EN_Project p, int index, int property, double valu
|
||||
net->Pump[pumpIndex].Epat = patIndex;
|
||||
}
|
||||
break;
|
||||
|
||||
case EN_PCV_CURVE:
|
||||
if (Link[index].Type == PCV)
|
||||
{
|
||||
curveIndex = ROUND(value);
|
||||
if (curveIndex < 0 || curveIndex > net->Ncurves) return 206;
|
||||
net->Valve[findvalve(&p->network, index)].Curve = curveIndex;
|
||||
}
|
||||
break;
|
||||
|
||||
case EN_GPV_CURVE:
|
||||
if (Link[index].Type == GPV)
|
||||
|
||||
@@ -212,6 +212,16 @@ int DLLEXPORT ENsetstatusreport(int level)
|
||||
return EN_setstatusreport(_defaultProject, level);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetreportcallback(void (*callback)(void *userData, void *EN_projectHandle, char*))
|
||||
{
|
||||
return EN_setreportcallback(_defaultProject, callback);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetreportcallbackuserdata(void *userData)
|
||||
{
|
||||
return EN_setreportcallbackuserdata(_defaultProject, userData);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetversion(int *version) { return EN_getversion(version); }
|
||||
|
||||
int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/03/2020
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef FUNCS_H
|
||||
@@ -167,6 +167,7 @@ void headlosscoeffs(Project *);
|
||||
void matrixcoeffs(Project *);
|
||||
void emitterheadloss(Project *, int, double *, double *);
|
||||
void demandheadloss(Project *, int, double, double, double *, double *);
|
||||
double pcvlosscoeff(Project *, int, double);
|
||||
|
||||
// ------- QUALITY.C --------------------
|
||||
|
||||
|
||||
123
src/hydcoeffs.c
123
src/hydcoeffs.c
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/30/2022
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,7 @@ const double CBIG = 1.e8;
|
||||
|
||||
// Exported functions
|
||||
//void resistcoeff(Project *, int );
|
||||
//double pcvlosscoeff(Project *, int, double);
|
||||
//void headlosscoeffs(Project *);
|
||||
//void matrixcoeffs(Project *);
|
||||
//void emitterheadloss(Project *, int, double *, double *);
|
||||
@@ -59,6 +60,7 @@ static void valvecoeff(Project *pr, int k);
|
||||
static void gpvcoeff(Project *pr, int k);
|
||||
static void pbvcoeff(Project *pr, int k);
|
||||
static void tcvcoeff(Project *pr, int k);
|
||||
static void pcvcoeff(Project *pr, int k);
|
||||
static void prvcoeff(Project *pr, int k, int n1, int n2);
|
||||
static void psvcoeff(Project *pr, int k, int n1, int n2);
|
||||
static void fcvcoeff(Project *pr, int k, int n1, int n2);
|
||||
@@ -107,6 +109,10 @@ void resistcoeff(Project *pr, int k)
|
||||
case PUMP:
|
||||
link->R = CBIG;
|
||||
break;
|
||||
|
||||
case PCV:
|
||||
link->R = pcvlosscoeff(pr, k, link->Kc);
|
||||
break;
|
||||
|
||||
// ... For all other links (e.g. valves) use a small resistance
|
||||
default:
|
||||
@@ -116,6 +122,86 @@ void resistcoeff(Project *pr, int k)
|
||||
}
|
||||
|
||||
|
||||
double pcvlosscoeff(Project* pr, int k, double s)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** s = valve fraction open setting
|
||||
** Output: returns a valve loss coefficient
|
||||
** Purpose: finds a Positional Control Valve's loss
|
||||
** coefficient from its fraction open setting.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network* net = &pr->network;
|
||||
|
||||
int v = findvalve(net, k); // valve index
|
||||
int c = net->Valve[v].Curve; // Kv curve index
|
||||
double d; // valve diameter
|
||||
double kmo; // fully open loss coeff.
|
||||
double km; // partly open loss coeff.
|
||||
double kvr; // Kv / Kvo (Kvo = Kv at fully open)
|
||||
double *x, *y; // points on kvr v. frac. open curve
|
||||
int k1, k2, npts;
|
||||
Scurve *curve;
|
||||
|
||||
// Valve has no setting so return 0
|
||||
if (s == MISSING) return 0.0;
|
||||
|
||||
// Valve is completely open so return its Km value
|
||||
d = net->Link[k].Diam;
|
||||
kmo = net->Link[k].Km;
|
||||
if (s >= 1.0) return kmo;
|
||||
|
||||
// Valve is completely closed so return a large coeff.
|
||||
if (s <= 0.0) return CBIG;
|
||||
|
||||
// Valve has no assigned curve so assume a linear one
|
||||
if (c == 0) kvr = s;
|
||||
|
||||
else
|
||||
{
|
||||
// Valve curve data
|
||||
curve = &net->Curve[c];
|
||||
npts = curve->Npts;
|
||||
x = curve->X; // x = frac. open
|
||||
y = curve->Y; // y = Kv / Kvo
|
||||
|
||||
// s lies below first point of curve
|
||||
if (s < x[0])
|
||||
kvr = s / x[0] * y[0];
|
||||
|
||||
// s lies above last point of curve
|
||||
else if (s > x[npts-1])
|
||||
{
|
||||
k2 = npts - 1;
|
||||
kvr = (s - x[k2]) / (1. - x[k2]) * (1. - y[k2]) + y[k2];
|
||||
}
|
||||
|
||||
// Otherwise interpolate over curve segment that brackets s
|
||||
else
|
||||
{
|
||||
k2 = 0;
|
||||
while (k2 < npts && x[k2] < s) k2++;
|
||||
if (k2 == 0) k2++;
|
||||
else if (k2 == npts) k2--;
|
||||
k1 = k2 - 1;
|
||||
kvr = (y[k2] - y[k1]) / (x[k2] - x[k1]);
|
||||
kvr = y[k1] + kvr * (s - x[k1]);
|
||||
}
|
||||
}
|
||||
|
||||
// kvr can't be > 1 or <= 0
|
||||
kvr = MIN(kvr, 1.0);
|
||||
kvr = MAX(kvr, CSMALL);
|
||||
|
||||
// Convert from Kv ratio to minor loss coeff.
|
||||
km = kmo / (kvr * kvr);
|
||||
km = MIN(km, CBIG);
|
||||
return km;
|
||||
}
|
||||
|
||||
|
||||
void headlosscoeffs(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
@@ -148,6 +234,9 @@ void headlosscoeffs(Project *pr)
|
||||
case TCV:
|
||||
tcvcoeff(pr, k);
|
||||
break;
|
||||
case PCV:
|
||||
pcvcoeff(pr, k);
|
||||
break;
|
||||
case GPV:
|
||||
gpvcoeff(pr, k);
|
||||
break;
|
||||
@@ -945,6 +1034,36 @@ void tcvcoeff(Project *pr, int k)
|
||||
}
|
||||
|
||||
|
||||
void pcvcoeff(Project *pr, int k)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** Output: none
|
||||
** Purpose: computes P & Y coeffs. for positional control valve
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
double km;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Slink *link = &pr->network.Link[k];
|
||||
|
||||
// Save original loss coeff. for open valve
|
||||
km = link->Km;
|
||||
|
||||
// If valve not fixed OPEN or CLOSED, compute its loss coeff.
|
||||
if (hyd->LinkSetting[k] != MISSING)
|
||||
{
|
||||
link->Km = link->R;
|
||||
}
|
||||
|
||||
// Then apply usual valve formula
|
||||
valvecoeff(pr, k);
|
||||
|
||||
// Restore original loss coeff.
|
||||
link->Km = km;
|
||||
}
|
||||
|
||||
|
||||
void prvcoeff(Project *pr, int k, int n1, int n2)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
@@ -1035,6 +1154,8 @@ void psvcoeff(Project *pr, int k, int n1, int n2)
|
||||
{
|
||||
sm->F[j] += hyd->Xflow[n1];
|
||||
}
|
||||
sm->Aij[sm->Ndx[k]] -= 1.0 / CBIG; // Preserve connectivity
|
||||
sm->Aii[j] += 1.0 / CBIG;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/19/2022
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -449,6 +449,7 @@ void setlinksetting(Project *pr, int index, double value, StatusType *s,
|
||||
else
|
||||
{
|
||||
if (*k == MISSING && *s <= CLOSED) *s = OPEN;
|
||||
if (t == PCV) link->R = pcvlosscoeff(pr, index, link->Kc);
|
||||
*k = value;
|
||||
}
|
||||
}
|
||||
@@ -604,6 +605,7 @@ int controls(Project *pr)
|
||||
{
|
||||
hyd->LinkStatus[k] = s2;
|
||||
hyd->LinkSetting[k] = k2;
|
||||
if (link->Type == PCV) link->R = pcvlosscoeff(pr, k, k2);
|
||||
if (pr->report.Statflag) writecontrolaction(pr,k,i);
|
||||
setsum++;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: updates hydraulic status of network elements
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 05/15/2019
|
||||
Last Updated: 08/08/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -394,6 +394,15 @@ StatusType fcvstatus(Project *pr, int k, StatusType s, double h1, double h2)
|
||||
{
|
||||
status = ACTIVE;
|
||||
}
|
||||
|
||||
// Active valve's loss coeff. can't be < fully open loss coeff.
|
||||
else if (status == ACTIVE)
|
||||
{
|
||||
if ((h1 - h2) / SQR(hyd->LinkFlow[k]) < pr->network.Link[k].Km)
|
||||
{
|
||||
status = XFCV;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: saves network data to an EPANET formatted text file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 10/29/2019
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -312,6 +312,11 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
{
|
||||
sprintf(s1, "%-31s %12.4f", net->Curve[j].ID, km);
|
||||
}
|
||||
// For PCV add loss curve if present
|
||||
else if (link->Type == PCV && (j = net->Valve[i].Curve) > 0)
|
||||
{
|
||||
sprintf(s1, "%12.4f %12.4f %-31s", kc, km, net->Curve[j].ID);
|
||||
}
|
||||
else sprintf(s1, "%12.4f %12.4f", kc, km);
|
||||
fprintf(f, "\n%s %s", s, s1);
|
||||
if (link->Comment) fprintf(f, " ;%s", link->Comment);
|
||||
|
||||
20
src/input3.c
20
src/input3.c
@@ -7,7 +7,7 @@ Description: parses network data from a line of an EPANET input file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/20/2022
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -471,7 +471,7 @@ int valvedata(Project *pr)
|
||||
** Purpose: processes valve data
|
||||
** Format:
|
||||
** [VALVE]
|
||||
** id node1 node2 diam type setting (lcoeff)
|
||||
** id node1 node2 diam type setting (lcoeff lcurve)
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
@@ -488,7 +488,8 @@ int valvedata(Project *pr)
|
||||
setting, // Valve setting
|
||||
lcoeff = 0.0; // Minor loss coeff.
|
||||
Slink *link;
|
||||
int err = 0;
|
||||
int err = 0,
|
||||
losscurve = 0; // Loss coeff. curve
|
||||
|
||||
// Add new valve to data base
|
||||
n = parser->Ntokens;
|
||||
@@ -521,6 +522,8 @@ int valvedata(Project *pr)
|
||||
type = TCV;
|
||||
else if (match(parser->Tok[4], w_GPV))
|
||||
type = GPV;
|
||||
else if (match(parser->Tok[4], w_PCV))
|
||||
type = PCV;
|
||||
else
|
||||
return setError(parser, 4, 213);
|
||||
|
||||
@@ -538,6 +541,16 @@ int valvedata(Project *pr)
|
||||
}
|
||||
else if (!getfloat(parser->Tok[5], &setting)) return setError(parser, 5, 202);
|
||||
if (n >= 7 && !getfloat(parser->Tok[6], &lcoeff)) return setError(parser, 6, 202);
|
||||
|
||||
// Find loss coeff. curve for PCV
|
||||
if (type == PCV && n >= 8)
|
||||
{
|
||||
c = findcurve(net, parser->Tok[7]);
|
||||
if (c == 0) return setError(parser, 7, 206);
|
||||
losscurve = c;
|
||||
net->Curve[c].Type = VALVE_CURVE;
|
||||
if (setting > 1.0) setting = 1.0;
|
||||
}
|
||||
|
||||
// Check for illegal connections
|
||||
if (valvecheck(pr, net->Nlinks, type, j1, j2))
|
||||
@@ -563,6 +576,7 @@ int valvedata(Project *pr)
|
||||
link->ResultIndex = 0;
|
||||
link->Comment = xstrcpy(&link->Comment, parser->Comment, MAXMSG);
|
||||
net->Valve[net->Nvalves].Link = net->Nlinks;
|
||||
net->Valve[net->Nvalves].Curve = losscurve;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: binary file read/write routines
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 05/13/2019
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -567,6 +567,7 @@ int linkoutput(Project *pr, int j, REAL4 *x, double ucf)
|
||||
case FCV:
|
||||
x[i] = (REAL4)(setting * pr->Ucf[FLOW]); break;
|
||||
case TCV:
|
||||
case PCV:
|
||||
x[i] = (REAL4)setting; break;
|
||||
default: x[i] = 0.0f;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/03/2020
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -281,6 +281,8 @@ void initpointers(Project *pr)
|
||||
pr->hydraul.smatrix.NZSUB = NULL;
|
||||
pr->hydraul.smatrix.LNZ = NULL;
|
||||
|
||||
pr->report.reportCallback = NULL;
|
||||
|
||||
initrules(pr);
|
||||
}
|
||||
|
||||
@@ -860,7 +862,7 @@ int findtank(Network *network, int index)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: index = node index
|
||||
** Output: none
|
||||
** Returns: index of tank with given node id, or NOTFOUND if tank not found
|
||||
** Returns: index of tank with given node index, or NOTFOUND if tank not found
|
||||
** Purpose: for use in the deletenode function
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
@@ -877,7 +879,7 @@ int findpump(Network *network, int index)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: index = link ID
|
||||
** Output: none
|
||||
** Returns: index of pump with given link id, or NOTFOUND if pump not found
|
||||
** Returns: index of pump with given link index, or NOTFOUND if pump not found
|
||||
** Purpose: for use in the deletelink function
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
@@ -894,7 +896,7 @@ int findvalve(Network *network, int index)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: index = link ID
|
||||
** Output: none
|
||||
** Returns: index of valve with given link id, or NOTFOUND if valve not found
|
||||
** Returns: index of valve with given link index, or NOTFOUND if valve not found
|
||||
** Purpose: for use in the deletelink function
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
@@ -1010,7 +1012,7 @@ void adjustcurves(Network *network, int index)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int j, k, setting;
|
||||
int j, k, curve;
|
||||
|
||||
// Adjust tank volume curves
|
||||
for (j = 1; j <= network->Ntanks; j++)
|
||||
@@ -1025,15 +1027,25 @@ void adjustcurves(Network *network, int index)
|
||||
adjustcurve(&network->Pump[j].Ecurve, index);
|
||||
}
|
||||
|
||||
// Adjust GPV curves
|
||||
// Adjust PCV & GPV curves
|
||||
for (j = 1; j <= network->Nvalves; j++)
|
||||
{
|
||||
k = network->Valve[j].Link;
|
||||
if (network->Link[k].Type == PCV)
|
||||
{
|
||||
if ((curve = network->Valve[j].Curve) > 0)
|
||||
{
|
||||
adjustcurve(&curve, index);
|
||||
network->Valve[j].Curve = curve;
|
||||
if (curve == 0)
|
||||
network->Link[k].Kc = 0.0;
|
||||
}
|
||||
}
|
||||
if (network->Link[k].Type == GPV)
|
||||
{
|
||||
setting = INT(network->Link[k].Kc);
|
||||
adjustcurve(&setting, index);
|
||||
network->Link[k].Kc = setting;
|
||||
curve = INT(network->Link[k].Kc);
|
||||
adjustcurve(&curve, index);
|
||||
network->Link[k].Kc = curve;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -885,6 +885,12 @@ void writeline(Project *pr, char *s)
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
if (pr->report.reportCallback != NULL)
|
||||
{
|
||||
pr->report.reportCallback(pr->report.reportCallbackUserData, pr, s);
|
||||
return;
|
||||
}
|
||||
|
||||
Report *rpt = &pr->report;
|
||||
|
||||
if (rpt->RptFile == NULL) return;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 07/15/2019
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#define w_FCV "FCV"
|
||||
#define w_TCV "TCV"
|
||||
#define w_GPV "GPV"
|
||||
#define w_PCV "PCV"
|
||||
|
||||
#define w_OPEN "OPEN"
|
||||
#define w_CLOSED "CLOSED"
|
||||
|
||||
14
src/types.h
14
src/types.h
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 07/11/2020
|
||||
Last Updated: 08/13/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -145,7 +145,8 @@ typedef enum {
|
||||
PBV, // pressure breaker valve
|
||||
FCV, // flow control valve
|
||||
TCV, // throttle control valve
|
||||
GPV // general purpose valve
|
||||
GPV, // general purpose valve
|
||||
PCV // positional control valve
|
||||
} LinkType;
|
||||
|
||||
typedef enum {
|
||||
@@ -166,7 +167,8 @@ typedef enum {
|
||||
PUMP_CURVE, // pump curve
|
||||
EFFIC_CURVE, // efficiency curve
|
||||
HLOSS_CURVE, // head loss curve
|
||||
GENERIC_CURVE // generic curve
|
||||
GENERIC_CURVE, // generic curve
|
||||
VALVE_CURVE // positional valve loss curve
|
||||
} CurveType;
|
||||
|
||||
typedef enum {
|
||||
@@ -455,6 +457,7 @@ typedef struct // Pump Object
|
||||
typedef struct // Valve Object
|
||||
{
|
||||
int Link; // link index of valve
|
||||
int Curve; // positional loss coeff. curve
|
||||
} Svalve;
|
||||
|
||||
typedef struct // Control Statement
|
||||
@@ -629,7 +632,10 @@ typedef struct {
|
||||
Rpt2Fname[MAXFNAME+1], // Secondary report file name
|
||||
DateStamp[26]; // Current date & time
|
||||
|
||||
SField Field[MAXVAR]; // Output reporting fields
|
||||
SField Field[MAXVAR]; // Output reporting fields
|
||||
|
||||
void (*reportCallback)(void*,void*,char*); // user-supplied reporting callback
|
||||
void *reportCallbackUserData; // user-supplied reporting context
|
||||
|
||||
} Report;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ set(toolkit_test_srcs
|
||||
test_control.cpp
|
||||
test_overflow.cpp
|
||||
test_pda.cpp
|
||||
test_valve.cpp
|
||||
)
|
||||
|
||||
add_executable(test_toolkit ${toolkit_test_srcs})
|
||||
|
||||
73
tests/test_valve.cpp
Normal file
73
tests/test_valve.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: test_valve.cpp
|
||||
Description: Tests EPANET toolkit api functions
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 07/28/2022
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
Tests PCV valve with position curve
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "test_toolkit.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (test_valve)
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(test_PCV_valve, FixtureOpenClose)
|
||||
|
||||
{
|
||||
int npts = 5;
|
||||
double x[] = { 0.0, 0.25, 0.5, 0.75, 1. };
|
||||
double y[] = {0.0, 0.089, 0.184, 0.406, 1.0};
|
||||
double v;
|
||||
int linkIndex, curveIndex;
|
||||
|
||||
// Make steady state run
|
||||
error = EN_settimeparam(ph, EN_DURATION, 0);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Convert pipe 22 to a PCV
|
||||
error = EN_getlinkindex(ph, (char*)"22", &linkIndex);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
error = EN_setlinktype(ph, &linkIndex, EN_PCV, EN_UNCONDITIONAL);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
error = EN_setlinkvalue(ph, linkIndex, EN_DIAMETER, 12);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
error = EN_setlinkvalue(ph, linkIndex, EN_MINORLOSS, 0.19);
|
||||
|
||||
// Create the PCV's position-loss curve
|
||||
error = EN_addcurve(ph, (char*)"ValveCurve");
|
||||
BOOST_REQUIRE(error == 0);
|
||||
error = EN_getcurveindex(ph, (char*)"ValveCurve", &curveIndex);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
error = EN_setcurve(ph, curveIndex, x, y, npts);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Assign curve & initial setting to PCV
|
||||
error = EN_setlinkvalue(ph, linkIndex, EN_PCV_CURVE, curveIndex);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
error = EN_setlinkvalue(ph, linkIndex, EN_INITSETTING, 0.35);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Solve for hydraulics
|
||||
error = EN_solveH(ph);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// The PCV interpolated relative flow coeff. at 0.35 open is 0.127.
|
||||
// This translates to a minor loss coeff. of 0.19 / 0.127^2 = 11.78.
|
||||
// If the PCV were replaced with a TCV at that setting the resulting
|
||||
// head loss would be 0.0255 ft which should equal the PCV result.
|
||||
error = EN_getlinkvalue(ph, linkIndex, EN_HEADLOSS, &v);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
BOOST_REQUIRE(abs(v - 0.0255) < 0.001);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Reference in New Issue
Block a user