Merge pull request #688 from OpenWaterAnalytics/681-request-additional-api-function-for-getting-finer-grained-time-step-information
adds an API function to get information about upcoming events
This commit is contained in:
@@ -25,6 +25,7 @@ This document describes the changes and updates that have been made in version 2
|
|||||||
- A possible loss of network connectivity when evaluating a Pressure Sustaining Valve was prevented.
|
- 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.
|
- 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.
|
- 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.
|
||||||
|
- A new set of functions have been added to get information about upcoming time step events. Users will now see what type of event is going to cause the end of a time step to occur. See ENtimetonextevent and EN_timetonextevent.
|
||||||
|
- A new set of functions have been added to allow users to set a reporting callback function. The user-supplied function will recieve all output normally directed to the report file.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -253,6 +253,12 @@ Public Const EN_R_IS_OPEN = 1 ' Rule status types
|
|||||||
Public Const EN_R_IS_CLOSED = 2
|
Public Const EN_R_IS_CLOSED = 2
|
||||||
Public Const EN_R_IS_ACTIVE = 3
|
Public Const EN_R_IS_ACTIVE = 3
|
||||||
|
|
||||||
|
Public Const EN_STEP_REPORT = 0 ' Types of events that can cause a timestep to end
|
||||||
|
Public Const EN_STEP_HYD = 1
|
||||||
|
Public Const EN_STEP_WQ = 2
|
||||||
|
Public Const EN_STEP_TANKEVENT = 3
|
||||||
|
Public Const EN_STEP_CONTROLEVENT = 4
|
||||||
|
|
||||||
Public Const EN_MISSING As Double = -1.0E10
|
Public Const EN_MISSING As Double = -1.0E10
|
||||||
|
|
||||||
'These are the external functions that comprise the DLL
|
'These are the external functions that comprise the DLL
|
||||||
@@ -302,6 +308,7 @@ Public Const EN_MISSING As Double = -1.0E10
|
|||||||
Declare Function ENgeterror Lib "epanet2.dll" (ByVal errcode As Long, ByVal errmsg As String, ByVal maxLen As Long) As Long
|
Declare Function ENgeterror Lib "epanet2.dll" (ByVal errcode As Long, ByVal errmsg As String, ByVal maxLen As Long) As Long
|
||||||
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Long, ByRef value As Single) As Long
|
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Long, ByRef value As Single) As Long
|
||||||
Declare Function ENgetresultindex Lib "epanet2.dll" (ByVal type_ As Long, ByVal index As Long, ByRef value As Long) As Long
|
Declare Function ENgetresultindex Lib "epanet2.dll" (ByVal type_ As Long, ByVal index As Long, ByRef value As Long) As Long
|
||||||
|
Declare Function ENtimetonextevent Lib "epanet2.dll" (eventType As Long, duration As Long, elementIndex As Long) As Long
|
||||||
|
|
||||||
'Analysis Options Functions
|
'Analysis Options Functions
|
||||||
Declare Function ENgetoption Lib "epanet2.dll" (ByVal option_ As Long, value As Single) As Long
|
Declare Function ENgetoption Lib "epanet2.dll" (ByVal option_ As Long, value As Single) As Long
|
||||||
|
|||||||
@@ -131,3 +131,4 @@ EXPORTS
|
|||||||
ENstepQ = _ENstepQ@4
|
ENstepQ = _ENstepQ@4
|
||||||
ENusehydfile = _ENusehydfile@4
|
ENusehydfile = _ENusehydfile@4
|
||||||
ENwriteline = _ENwriteline@4
|
ENwriteline = _ENwriteline@4
|
||||||
|
ENtimetonextevent = _ENtimetonextevent@12
|
||||||
@@ -159,6 +159,8 @@ extern "C" {
|
|||||||
|
|
||||||
int DLLEXPORT ENgetresultindex(int type, int index, int *value);
|
int DLLEXPORT ENgetresultindex(int type, int index, int *value);
|
||||||
|
|
||||||
|
int DLLEXPORT ENtimetonextevent(int *eventType, long *duration, int *elementIndex);
|
||||||
|
|
||||||
int DLLEXPORT ENsetreportcallback(void (*callback)(void *userData, void *EN_projectHandle, char*));
|
int DLLEXPORT ENsetreportcallback(void (*callback)(void *userData, void *EN_projectHandle, char*));
|
||||||
int DLLEXPORT ENsetreportcallbackuserdata(void *userData);
|
int DLLEXPORT ENsetreportcallbackuserdata(void *userData);
|
||||||
|
|
||||||
|
|||||||
@@ -650,6 +650,16 @@ typedef struct Project *EN_Project;
|
|||||||
*/
|
*/
|
||||||
int DLLEXPORT EN_getstatistic(EN_Project ph, int type, double* out_value);
|
int DLLEXPORT EN_getstatistic(EN_Project ph, int type, double* out_value);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Get information about upcoming time step events, and what causes them.
|
||||||
|
@param ph an EPANET project handle.
|
||||||
|
@param[out] eventType the type of event that will occur (see @ref EN_TimestepEvent).
|
||||||
|
@param[out] duration the amount of time in the future this event will occur
|
||||||
|
@param[out] elementIndex the index of the element causing the event.
|
||||||
|
**/
|
||||||
|
int DLLEXPORT EN_timetonextevent(EN_Project ph, int *eventType, long *duration, int *elementIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Retrieves the order in which a node or link appears in an @ref OutFile "output file".
|
@brief Retrieves the order in which a node or link appears in an @ref OutFile "output file".
|
||||||
@param ph an EPANET project handle.
|
@param ph an EPANET project handle.
|
||||||
|
|||||||
@@ -126,6 +126,18 @@ typedef enum {
|
|||||||
EN_NEXTEVENTTANK = 15 //!< Index of tank with shortest time to become empty or full (read only)
|
EN_NEXTEVENTTANK = 15 //!< Index of tank with shortest time to become empty or full (read only)
|
||||||
} EN_TimeParameter;
|
} EN_TimeParameter;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
These are the types of events that can cause a timestep to end.
|
||||||
|
**/
|
||||||
|
typedef enum {
|
||||||
|
EN_STEP_REPORT = 0,
|
||||||
|
EN_STEP_HYD = 1,
|
||||||
|
EN_STEP_WQ = 2,
|
||||||
|
EN_STEP_TANKEVENT = 3,
|
||||||
|
EN_STEP_CONTROLEVENT = 4
|
||||||
|
} EN_TimestepEvent;
|
||||||
|
|
||||||
/// Analysis convergence statistics
|
/// Analysis convergence statistics
|
||||||
/**
|
/**
|
||||||
These statistics report the convergence criteria for the most current hydraulic analysis
|
These statistics report the convergence criteria for the most current hydraulic analysis
|
||||||
|
|||||||
36
src/epanet.c
36
src/epanet.c
@@ -1623,6 +1623,42 @@ int DLLEXPORT EN_settimeparam(EN_Project p, int param, long value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// get the time to next event, and give a reason for the time step truncation
|
||||||
|
int DLLEXPORT EN_timetonextevent(EN_Project p, int *eventType, long *duration, int *elementIndex)
|
||||||
|
{
|
||||||
|
Times *time = &p->times;
|
||||||
|
long hydStep, tankStep, controlStep;
|
||||||
|
int iTank, iControl;
|
||||||
|
|
||||||
|
hydStep = time->Hstep;
|
||||||
|
tankStep = hydStep;
|
||||||
|
controlStep = hydStep;
|
||||||
|
|
||||||
|
iTank = tanktimestep(p, &tankStep);
|
||||||
|
iControl = controltimestep(p, &controlStep);
|
||||||
|
|
||||||
|
// return the lesser of the three step lengths
|
||||||
|
if (controlStep < tankStep) {
|
||||||
|
*eventType = (int)EN_STEP_CONTROLEVENT;
|
||||||
|
*duration = controlStep;
|
||||||
|
*elementIndex = iControl;
|
||||||
|
}
|
||||||
|
else if (tankStep < hydStep) {
|
||||||
|
*eventType = (int)EN_STEP_TANKEVENT;
|
||||||
|
*duration = tankStep;
|
||||||
|
*elementIndex = iTank;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*eventType = (int)EN_STEP_HYD;
|
||||||
|
*duration = hydStep;
|
||||||
|
*elementIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int DLLEXPORT EN_getqualinfo(EN_Project p, int *qualType, char *chemName,
|
int DLLEXPORT EN_getqualinfo(EN_Project p, int *qualType, char *chemName,
|
||||||
char *chemUnits, int *traceNode)
|
char *chemUnits, int *traceNode)
|
||||||
/*----------------------------------------------------------------
|
/*----------------------------------------------------------------
|
||||||
|
|||||||
@@ -242,6 +242,10 @@ int DLLEXPORT ENgetresultindex(int type, int index, int *value)
|
|||||||
return EN_getresultindex(_defaultProject, type, index, value);
|
return EN_getresultindex(_defaultProject, type, index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DLLEXPORT ENtimetonextevent(int *eventType, long *duration, int *elementIndex)
|
||||||
|
{
|
||||||
|
return EN_timetonextevent(_defaultProject, eventType, duration, elementIndex);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ void closehyd(Project *);
|
|||||||
void setlinkstatus(Project *, int, char, StatusType *, double *);
|
void setlinkstatus(Project *, int, char, StatusType *, double *);
|
||||||
void setlinksetting(Project *, int, double, StatusType *, double *);
|
void setlinksetting(Project *, int, double, StatusType *, double *);
|
||||||
int tanktimestep(Project *, long *);
|
int tanktimestep(Project *, long *);
|
||||||
|
int controltimestep(Project *, long *);
|
||||||
void getenergy(Project *, int, double *, double *);
|
void getenergy(Project *, int, double *, double *);
|
||||||
double tankvolume(Project *, int, double);
|
double tankvolume(Project *, int, double);
|
||||||
double tankgrade(Project *, int, double);
|
double tankgrade(Project *, int, double);
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ void initlinkflow(Project *, int, char, double);
|
|||||||
void demands(Project *);
|
void demands(Project *);
|
||||||
int controls(Project *);
|
int controls(Project *);
|
||||||
long timestep(Project *);
|
long timestep(Project *);
|
||||||
void controltimestep(Project *, long *);
|
|
||||||
void ruletimestep(Project *, long *);
|
void ruletimestep(Project *, long *);
|
||||||
void addenergy(Project *, long);
|
void addenergy(Project *, long);
|
||||||
void tanklevels(Project *, long);
|
void tanklevels(Project *, long);
|
||||||
@@ -706,7 +705,7 @@ int tanktimestep(Project *pr, long *tstep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void controltimestep(Project *pr, long *tstep)
|
int controltimestep(Project *pr, long *tstep)
|
||||||
/*
|
/*
|
||||||
**------------------------------------------------------------------
|
**------------------------------------------------------------------
|
||||||
** Input: *tstep = current time step
|
** Input: *tstep = current time step
|
||||||
@@ -719,7 +718,7 @@ void controltimestep(Project *pr, long *tstep)
|
|||||||
Network *net = &pr->network;
|
Network *net = &pr->network;
|
||||||
Hydraul *hyd = &pr->hydraul;
|
Hydraul *hyd = &pr->hydraul;
|
||||||
|
|
||||||
int i, j, k, n;
|
int i, j, k, n, controlIndex;
|
||||||
double h, q, v;
|
double h, q, v;
|
||||||
long t, t1, t2;
|
long t, t1, t2;
|
||||||
Slink *link;
|
Slink *link;
|
||||||
@@ -776,9 +775,14 @@ void controltimestep(Project *pr, long *tstep)
|
|||||||
k = control->Link;
|
k = control->Link;
|
||||||
link = &net->Link[k];
|
link = &net->Link[k];
|
||||||
if ( (link->Type > PIPE && hyd->LinkSetting[k] != control->Setting)
|
if ( (link->Type > PIPE && hyd->LinkSetting[k] != control->Setting)
|
||||||
|| (hyd->LinkStatus[k] != control->Status) ) *tstep = t;
|
|| (hyd->LinkStatus[k] != control->Status) )
|
||||||
|
{
|
||||||
|
*tstep = t;
|
||||||
|
controlIndex = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return controlIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1133,4 +1137,3 @@ void resetpumpflow(Project *pr, int i)
|
|||||||
if (pump->Ptype == CONST_HP)
|
if (pump->Ptype == CONST_HP)
|
||||||
pr->hydraul.LinkFlow[i] = pump->Q0;
|
pr->hydraul.LinkFlow[i] = pump->Q0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -885,14 +885,14 @@ void writeline(Project *pr, char *s)
|
|||||||
**--------------------------------------------------------------
|
**--------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
Report *rpt = &pr->report;
|
||||||
|
|
||||||
if (pr->report.reportCallback != NULL)
|
if (pr->report.reportCallback != NULL)
|
||||||
{
|
{
|
||||||
pr->report.reportCallback(pr->report.reportCallbackUserData, pr, s);
|
pr->report.reportCallback(pr->report.reportCallbackUserData, pr, s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Report *rpt = &pr->report;
|
|
||||||
|
|
||||||
if (rpt->RptFile == NULL) return;
|
if (rpt->RptFile == NULL) return;
|
||||||
if (rpt->Rptflag)
|
if (rpt->Rptflag)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user