Skip to content

Commit

Permalink
Add EN_openX function
Browse files Browse the repository at this point in the history
EN_openX allows an EPANET input file to be opened even if it has errors. This required re-arranging code, mainly in input3.c, so that default values are assigned to an object before its input line is parsed.
  • Loading branch information
LRossman committed Oct 4, 2023
1 parent c84c6ba commit 10d5079
Show file tree
Hide file tree
Showing 18 changed files with 990 additions and 720 deletions.
3 changes: 2 additions & 1 deletion include/epanet2.bas
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Attribute VB_Name = "Module1"
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL)

'Last updated on 07/18/2023
'Last updated on 09/28/2023

' These are codes used by the DLL functions
Public Const EN_ELEVATION = 0 ' Node parameters
Expand Down Expand Up @@ -280,6 +280,7 @@ Public Const EN_SET_OPEN As Double = 1.0E10
Declare Function ENepanet Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String, ByVal pviewprog As Any) As Long
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal outFile As String, ByVal unitsType As Long, ByVal headlossType As Long) As Long
Declare Function ENopen Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Long
Declare Function ENopenX Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Long
Declare Function ENgettitle Lib "epanet2.dll" (ByVal line1 As String, ByVal line2 As String, ByVal line3 As String) As Long
Declare Function ENsettitle Lib "epanet2.dll" (ByVal titleline1 As String, ByVal titleline2 As String, ByVal titleline3 As String) As Long
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Long
Expand Down
5 changes: 4 additions & 1 deletion include/epanet2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Runtime.InteropServices;

//epanet2.cs[By Oscar Vegas]
//Last updated on 07/18/2023
//Last updated on 09/28/2023

//Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
//(EPANET2.DLL) for use with C#
Expand Down Expand Up @@ -286,6 +286,9 @@ public static class Epanet
[DllImport(EPANETDLL, EntryPoint = "ENopen")]
public static extern int ENopen(string inpFile, string rptFile, string outFile);

[DllImport(EPANETDLL, EntryPoint = "ENopenX")]
public static extern int ENopenX(string inpFile, string rptFile, string outFile);

[DllImport(EPANETDLL, EntryPoint = "ENgettitle")]
public static extern int ENgettitle(string titleline1, string titleline2, string titleline3);

Expand Down
3 changes: 2 additions & 1 deletion include/epanet2.def
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,5 @@ EXPORTS
ENstepQ = _ENstepQ@4
ENusehydfile = _ENusehydfile@4
ENwriteline = _ENwriteline@4
ENtimetonextevent = _ENtimetonextevent@12
ENtimetonextevent = _ENtimetonextevent@12
ENopenX = _ENopenX@12
5 changes: 4 additions & 1 deletion include/epanet2.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 02/01/2020
Last Updated: 09/28/2023
******************************************************************************
*/

Expand Down Expand Up @@ -73,6 +73,9 @@ extern "C" {
int DLLEXPORT ENopen(const char *inpFile, const char *rptFile,
const char *outFile);

int DLLEXPORT ENopenX(const char *inpFile, const char *rptFile,
const char *outFile);

int DLLEXPORT ENgettitle(char *line1, char *line2, char *line3);

int DLLEXPORT ENsettitle(const char *line1, const char *line2, const char *line3);
Expand Down
3 changes: 2 additions & 1 deletion include/epanet2.pas
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{ Declarations of imported procedures from the EPANET PROGRAMMERs TOOLKIT }
{ (EPANET2.DLL) }

{Last updated on 09/11/2023}
{Last updated on 09/28/2023}

interface

Expand Down Expand Up @@ -281,6 +281,7 @@ interface
function ENepanet(F1: PAnsiChar; F2: PAnsiChar; F3: PAnsiChar; F4: Pointer): Integer; stdcall; external EpanetLib;
function ENinit(F2: PAnsiChar; F3: PAnsiChar; UnitsType: Integer; HeadlossType: Integer): Integer; stdcall; external EpanetLib;
function ENopen(F1: PAnsiChar; F2: PAnsiChar; F3: PAnsiChar): Integer; stdcall; external EpanetLib;
function ENopenX(F1: PAnsiChar; F2: PAnsiChar; F3: PAnsiChar): Integer; stdcall; external EpanetLib;
function ENgetcount(Code: Integer; var Count: Integer): Integer; stdcall; external EpanetLib;
function ENgettitle(Line1: PAnsiChar; Line2: PAnsiChar; Line3: PAnsiChar): Integer; stdcall; external EpanetLib;
function ENsettitle(Line1: PAnsiChar; Line2: PAnsiChar; Line3: PAnsiChar): Integer; stdcall; external EpanetLib;
Expand Down
3 changes: 2 additions & 1 deletion include/epanet2.vb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL) for use with VB.Net.

'Last updated on 07/18/2023
'Last updated on 09/28/2023

Imports System.Runtime.InteropServices
Imports System.Text
Expand Down Expand Up @@ -268,6 +268,7 @@ Public Const EN_SET_OPEN As Double = 1.0E10
Declare Function ENepanet Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String, ByVal pviewprog As Any) As Int32
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal outFile As String, ByVal unitsType As Int32, ByVal headlossType As Int32) As Int32
Declare Function ENopen Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Int32
Declare Function ENopenX Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Int32
Declare Function ENgettitle Lib "epanet2.dll" (ByVal titleline1 As String, ByVal titleline2 As String, ByVal titleline3 As String) As Int32
Declare Function ENsettitle Lib "epanet2.dll" (ByVal titleline1 As String, ByVal titleline2 As String, ByVal titleline3 As String) As Int32
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Int32
Expand Down
22 changes: 19 additions & 3 deletions include/epanet2_2.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 02/01/2020
Last Updated: 09/28/2023
******************************************************************************
*/

Expand Down Expand Up @@ -113,19 +113,35 @@ typedef struct Project *EN_Project;
int unitsType, int headLossType);

/**
@brief Opens an EPANET input file & reads in network data.
@brief Reads an EPANET input file with no errors allowed.
@param ph an EPANET project handle.
@param inpFile the name of an existing EPANET-formatted input file.
@param rptFile the name of a report file to be created (or "" if not needed).
@param outFile the name of a binary output file to be created (or "" if not needed).
@return an error code.
This function should be called immediately after ::EN_createproject if an EPANET-formatted
input file will be used to supply network data.
input file will be used to supply network data. If errors are detected then the project is
not opened and will not accept toolkit function calls.
*/
int DLLEXPORT EN_open(EN_Project ph, const char *inpFile, const char *rptFile,
const char *outFile);

/**
@brief Reads an EPANET input file with errors allowed.
@param ph an EPANET project handle.
@param inpFile the name of an existing EPANET-formatted input file.
@param rptFile the name of a report file to be created (or "" if not needed).
@param outFile the name of a binary output file to be created (or "" if not needed).
@return an error code.
This function should be called immediately after ::EN_createproject if an EPANET-formatted
input file will be used to supply network data. If formatting errors are detected (error
code = 200) then the project remains open and will accept toolkit function calls.
*/
int DLLEXPORT EN_openX(EN_Project ph, const char *inpFile, const char *rptFile,
const char *outFile);

/**
@brief Retrieves the title lines of the project
@param ph an EPANET project handle.
Expand Down
142 changes: 36 additions & 106 deletions src/epanet.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 07/17/2023
Last Updated: 09/28/2023
******************************************************************************
*/

Expand Down Expand Up @@ -179,61 +179,30 @@ int DLLEXPORT EN_open(EN_Project p, const char *inpFile, const char *rptFile,
** outFile = name of binary output file
** Output: none
** Returns: error code
** Purpose: opens an EPANET input file & reads in network data
** Purpose: reads an EPANET input file with no errors allowed.
**----------------------------------------------------------------
*/
{
int errcode = 0;

// Set system flags
p->Openflag = FALSE;
p->hydraul.OpenHflag = FALSE;
p->quality.OpenQflag = FALSE;
p->outfile.SaveHflag = FALSE;
p->outfile.SaveQflag = FALSE;
p->Warnflag = FALSE;
p->report.Messageflag = TRUE;
p->report.Rptflag = 1;

// Initialize data arrays to NULL
initpointers(p);

// Open input & report files
ERRCODE(openfiles(p, inpFile, rptFile, outFile));
if (errcode > 0)
{
errmsg(p, errcode);
return errcode;
}

// Allocate memory for project's data arrays
writewin(p->viewprog, FMT100);
ERRCODE(netsize(p));
ERRCODE(allocdata(p));

// Read input data
ERRCODE(getdata(p));

// Close input file
if (p->parser.InFile != NULL)
{
fclose(p->parser.InFile);
p->parser.InFile = NULL;
}
{
writewin(p->viewprog, FMT100);
return openproject(p, inpFile, rptFile, outFile, FALSE);
}

// If using previously saved hydraulics file then open it
if (p->outfile.Hydflag == USE) ERRCODE(openhydfile(p));
int DLLEXPORT EN_openX(EN_Project p, const char *inpFile,
const char *rptFile, const char *outFile)
/*----------------------------------------------------------------
** Input: inpFile = name of input file
** rptFile = name of report file
** outFile = name of binary output file
** Output: none
** Returns: error code
** Purpose: reads an EPANET input file with errors allowed.
**----------------------------------------------------------------
*/
{
writewin(p->viewprog, FMT100);
return openproject(p, inpFile, rptFile, outFile, TRUE);
}

// Write input summary to report file
if (!errcode)
{
if (p->report.Summaryflag) writesummary(p);
writetime(p, FMT104);
p->Openflag = TRUE;
}
else errmsg(p, errcode);
return errcode;
}

int DLLEXPORT EN_gettitle(EN_Project p, char *line1, char *line2, char *line3)
/*----------------------------------------------------------------
Expand Down Expand Up @@ -359,7 +328,6 @@ int DLLEXPORT EN_close(EN_Project p)
*/
{
// Free all project data
if (p->Openflag) writetime(p, FMT105);
freedata(p);

// Close output file
Expand Down Expand Up @@ -495,7 +463,11 @@ int DLLEXPORT EN_openH(EN_Project p)

// Open hydraulics solver
ERRCODE(openhyd(p));
if (!errcode) p->hydraul.OpenHflag = TRUE;
if (!errcode)
{
p->hydraul.OpenHflag = TRUE;
writetime(p, FMT104);
}
else errmsg(p, errcode);
return errcode;
}
Expand Down Expand Up @@ -834,6 +806,7 @@ int DLLEXPORT EN_closeQ(EN_Project p)
closequal(p);
p->quality.OpenQflag = FALSE;
closeoutfile(p);
writetime(p, FMT105);
return 0;
}

Expand Down Expand Up @@ -1929,7 +1902,7 @@ int DLLEXPORT EN_addnode(EN_Project p, const char *id, int nodeType, int *index)
if (control->Node > net->Njuncs - 1) control->Node += 1;
}
// adjust indices of tanks/reservoirs in Rule premises (see RULES.C)
adjusttankrules(p);
adjusttankrules(p, 1);
}

// Actions taken when a new Tank/Reservoir is added
Expand Down Expand Up @@ -4086,12 +4059,7 @@ int DLLEXPORT EN_setlinkvalue(EN_Project p, int index, int property, double valu
pumpIndex = findpump(&p->network, index);
net->Pump[pumpIndex].Ptype = CONST_HP;
net->Pump[pumpIndex].Hcurve = 0;
net->Link[index].Km = value;
updatepumpparams(p, pumpIndex);
net->Pump[pumpIndex].R /= Ucf[POWER];
net->Pump[pumpIndex].Q0 /= Ucf[FLOW];
net->Pump[pumpIndex].Qmax /= Ucf[FLOW];
net->Pump[pumpIndex].Hmax /= Ucf[HEAD];
net->Link[index].Km = value / Ucf[POWER];
}
break;

Expand Down Expand Up @@ -4380,10 +4348,7 @@ int DLLEXPORT EN_setheadcurveindex(EN_Project p, int linkIndex, int curveIndex)
{
Network *net = &p->network;

double *Ucf = p->Ucf;
int pumpIndex;
int oldCurveIndex;
int newCurveType;
int err = 0;
Spump *pump;

Expand All @@ -4393,43 +4358,12 @@ int DLLEXPORT EN_setheadcurveindex(EN_Project p, int linkIndex, int curveIndex)
if (PUMP != net->Link[linkIndex].Type) return 0;
if (curveIndex < 0 || curveIndex > net->Ncurves) return 206;

// Save values that need to be restored in case new curve is invalid
pumpIndex = findpump(net, linkIndex);
pump = &p->network.Pump[pumpIndex];
oldCurveIndex = pump->Hcurve;
newCurveType = p->network.Curve[curveIndex].Type;

// Assign the new curve to the pump
pump->Ptype = NOCURVE;
pumpIndex = findpump(net, linkIndex);
pump = &net->Pump[pumpIndex];
pump->Hcurve = curveIndex;
if (curveIndex == 0) return 0;

// Update the pump's head curve parameters (which also changes
// the new curve's Type to PUMP_CURVE)
err = updatepumpparams(p, pumpIndex);

// If the parameter updating failed (new curve was not a valid pump curve)
// restore the pump's original curve and its parameters
if (err > 0)
{
p->network.Curve[curveIndex].Type = newCurveType;
pump->Ptype = NOCURVE;
pump->Hcurve = oldCurveIndex;
if (oldCurveIndex == 0) return err;
updatepumpparams(p, pumpIndex);
}

// Convert the units of the updated pump parameters to feet and cfs
if (pump->Ptype == POWER_FUNC)
{
pump->H0 /= Ucf[HEAD];
pump->R *= (pow(Ucf[FLOW], pump->N) / Ucf[HEAD]);
}
pump->Q0 /= Ucf[FLOW];
pump->Qmax /= Ucf[FLOW];
pump->Hmax /= Ucf[HEAD];

return err;
net->Link[linkIndex].Km = 0.0;
return 0;
}

/********************************************************************
Expand Down Expand Up @@ -4907,7 +4841,7 @@ int DLLEXPORT EN_setcurvetype(EN_Project p, int index, int type)
Network *net = &p->network;
if (!p->Openflag) return 102;
if (index < 1 || index > net->Ncurves) return 206;
if (type < 0 || type > EN_GENERIC_CURVE) return 251;
if (type < 0 || type > EN_VALVE_CURVE) return 251;
net->Curve[index].Type = type;
return 0;
}
Expand Down Expand Up @@ -4981,9 +4915,7 @@ int DLLEXPORT EN_setcurvevalue(EN_Project p, int curveIndex, int pointIndex,
// Insert new point into curve
curve->X[n] = x;
curve->Y[n] = y;

// Adjust parameters for pumps using curve as a head curve
return adjustpumpparams(p, curveIndex);
return 0;
}

int DLLEXPORT EN_getcurve(EN_Project p, int index, char *id, int *nPoints,
Expand Down Expand Up @@ -5055,9 +4987,7 @@ int DLLEXPORT EN_setcurve(EN_Project p, int index, double *xValues,
curve->X[j] = xValues[j];
curve->Y[j] = yValues[j];
}

// Adjust parameters for pumps using curve as a head curve
return adjustpumpparams(p, index);
return 0;
}

/********************************************************************
Expand Down
Loading

0 comments on commit 10d5079

Please sign in to comment.