Merge pull request #320 from LRossman/lrossman-dev
Fixed bug setting pump curve params (#314) and in setting demand categories
This commit is contained in:
@@ -3835,6 +3835,7 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v)
|
||||
for (demand = node->D; demand != NULL; demand = demand->next) {
|
||||
if (demand->Pat == tmpPat) {
|
||||
demand->Pat = (int)value;
|
||||
strcpy(demand->Name, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3973,7 +3974,7 @@ int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveinde
|
||||
pump->Ptype = NOCURVE;
|
||||
pump->Hcurve = curveindex;
|
||||
// update pump parameters
|
||||
getpumpparams(p);
|
||||
updatepumpparams(p, pIdx);
|
||||
// convert units
|
||||
if (pump->Ptype == POWER_FUNC) {
|
||||
pump->H0 /= Ucf[HEAD];
|
||||
@@ -4871,8 +4872,6 @@ int DLLEXPORT EN_setdemandname(EN_ProjectHandle ph, int nodeIndex, int demandIdx
|
||||
const int Nnodes = net->Nnodes;
|
||||
const int Njuncs = net->Njuncs;
|
||||
|
||||
double *Ucf = pr->Ucf;
|
||||
|
||||
Pdemand d;
|
||||
int n = 1;
|
||||
/* Check for valid arguments */
|
||||
@@ -5047,6 +5046,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
|
||||
demand = (struct Sdemand *)malloc(sizeof(struct Sdemand));
|
||||
demand->Base = 0.0;
|
||||
demand->Pat = hyd->DefPat; // Use default pattern
|
||||
strcpy(demand->Name, "");
|
||||
demand->next = NULL;
|
||||
node->D = demand;
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ int addcurve(parser_data_t *par, char *); /* Adds curve to data base
|
||||
STmplist *findID(char *, STmplist *); /* Locates ID on linked list */
|
||||
int unlinked(EN_Project *pr); /* Checks for unlinked nodes */
|
||||
int getpumpparams(EN_Project *pr); /* Computes pump curve coeffs.*/
|
||||
int updatepumpparams(EN_Project *pr, int); // Updates pump curve coeffs.
|
||||
int getpatterns(EN_Project *pr); /* Gets pattern data from list*/
|
||||
int getcurves(EN_Project *pr); /* Gets curve data from list */
|
||||
int findmatch(char *, char *[]); /* Finds keyword in line */
|
||||
|
||||
@@ -356,6 +356,7 @@ void adjustdata(EN_Project *pr)
|
||||
for (demand = node->D; demand != NULL; demand = demand->next) {
|
||||
if (demand->Pat == 0) {
|
||||
demand->Pat = hyd->DefPat;
|
||||
strcpy(demand->Name, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
215
src/input2.c
215
src/input2.c
@@ -40,10 +40,10 @@ The following utility functions are all called from INPUT3.C
|
||||
|
||||
#define MAXERRS 10 /* Max. input errors reported */
|
||||
|
||||
|
||||
/* Defined in enumstxt.h in EPANET.C */
|
||||
extern char *SectTxt[]; /* Input section keywords */
|
||||
|
||||
|
||||
int netsize(EN_Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
@@ -206,9 +206,10 @@ int readdata(EN_Project *pr)
|
||||
|
||||
/* Check if max. length exceeded */
|
||||
if (strlen(line) >= MAXLINE) {
|
||||
char errMsg[MAXMSG+1];
|
||||
EN_geterror(214, errMsg, MAXMSG);
|
||||
sprintf(pr->Msg, "%s section: %s", errMsg, SectTxt[sect]);
|
||||
// char errMsg[MAXMSG+1];
|
||||
// EN_geterror(214, errMsg, MAXMSG);
|
||||
// sprintf(pr->Msg, "%s section: %s", errMsg, SectTxt[sect]);
|
||||
sprintf(pr->Msg, "%s section: %s", geterrmsg(214, pr->Msg), SectTxt[sect]);
|
||||
writeline(pr, pr->Msg);
|
||||
writeline(pr, line);
|
||||
errsum++;
|
||||
@@ -363,101 +364,121 @@ int getpumpparams(EN_Project *pr)
|
||||
**-------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: computes & checks pump curve parameters
|
||||
** Purpose: computes pump curve coefficients for all pumps
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i, j = 0, k, m, n = 0;
|
||||
double a, b, c, h0 = 0.0, h1 = 0.0, h2 = 0.0, q1 = 0.0, q2 = 0.0;
|
||||
char errMsg[MAXMSG+1];
|
||||
Spump *pump;
|
||||
Slink *link;
|
||||
Scurve *curve;
|
||||
|
||||
EN_Network *net = &pr->network;
|
||||
|
||||
for (i = 1; i <= net->Npumps; i++) {
|
||||
pump = &net->Pump[i];
|
||||
k = pump->Link;
|
||||
link = &net->Link[k];
|
||||
if (pump->Ptype == CONST_HP) { /* Constant Hp pump */
|
||||
pump->H0 = 0.0;
|
||||
pump->R = -8.814 * link->Km;
|
||||
pump->N = -1.0;
|
||||
pump->Hmax = BIG; /* No head limit */
|
||||
pump->Qmax = BIG; /* No flow limit */
|
||||
pump->Q0 = 1.0; /* Init. flow = 1 cfs */
|
||||
continue;
|
||||
}
|
||||
else if (pump->Ptype == NOCURVE) { /* Pump curve specified */
|
||||
j = pump->Hcurve; /* Get index of head curve */
|
||||
if (j == 0) { /* Error: No head curve */
|
||||
EN_geterror(226, errMsg, MAXMSG);
|
||||
sprintf(pr->Msg, "%s link: %s", errMsg, link->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return (200);
|
||||
}
|
||||
curve = &net->Curve[j];
|
||||
curve->Type = P_CURVE;
|
||||
n = curve->Npts;
|
||||
if (n == 1) { /* Only a single h-q point supplied so use generic */
|
||||
pump->Ptype = POWER_FUNC; /* power function curve. */
|
||||
q1 = curve->X[0];
|
||||
h1 = curve->Y[0];
|
||||
h0 = 1.33334 * h1;
|
||||
q2 = 2.0 * q1;
|
||||
h2 = 0.0;
|
||||
} else if (n == 3 && curve->X[0] == 0.0) /* 3 h-q points supplied with */
|
||||
{ /* shutoff head so use fitted */
|
||||
pump->Ptype = POWER_FUNC; /* power function curve. */
|
||||
h0 = curve->Y[0];
|
||||
q1 = curve->X[1];
|
||||
h1 = curve->Y[1];
|
||||
q2 = curve->X[2];
|
||||
h2 = curve->Y[2];
|
||||
}
|
||||
else { // use a custom curve, referenced by ID
|
||||
pump->Ptype = CUSTOM; /* Else use custom pump curve.*/
|
||||
// at this point, j is set to that curve's index.
|
||||
}
|
||||
|
||||
/* Compute shape factors & limits of power function pump curves */
|
||||
if (pump->Ptype == POWER_FUNC) {
|
||||
if (!powercurve(h0, h1, h2, q1, q2, &a, &b, &c)) { /* Error: Invalid curve */
|
||||
EN_geterror(227, errMsg, MAXMSG);
|
||||
sprintf(pr->Msg, "%s link: %s", errMsg, link->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return (200);
|
||||
} else {
|
||||
pump->H0 = -a;
|
||||
pump->R = -b;
|
||||
pump->N = c;
|
||||
pump->Q0 = q1;
|
||||
pump->Qmax = pow((-a / b), (1.0 / c));
|
||||
pump->Hmax = h0;
|
||||
int i, k, errcode = 0;
|
||||
EN_Network *net = &pr->network;
|
||||
|
||||
for (i = 1; i <= net->Npumps; i++)
|
||||
{
|
||||
errcode = updatepumpparams(pr, i);
|
||||
if (errcode)
|
||||
{
|
||||
k = net->Pump[i].Link;
|
||||
sprintf(pr->Msg, "%s link: %s", geterrmsg(errcode, pr->Msg),
|
||||
net->Link[k].ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int updatepumpparams(EN_Project *pr, int pumpindex)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: pumpindex = index of a pump
|
||||
** Output: returns error code
|
||||
** Purpose: computes & checks a pump's head curve coefficients
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int m;
|
||||
int curveindex;
|
||||
int npts = 0;
|
||||
int errcode = 0;
|
||||
double a, b, c, h0 = 0.0, h1 = 0.0, h2 = 0.0, q1 = 0.0, q2 = 0.0;
|
||||
|
||||
EN_Network *net = &pr->network;
|
||||
Spump *pump;
|
||||
Scurve *curve;
|
||||
|
||||
pump = &net->Pump[pumpindex];
|
||||
if (pump->Ptype == CONST_HP) // Constant Hp pump
|
||||
{
|
||||
pump->H0 = 0.0;
|
||||
pump->R = -8.814 * net->Link[pump->Link].Km;
|
||||
pump->N = -1.0;
|
||||
pump->Hmax = BIG; // No head limit
|
||||
pump->Qmax = BIG; // No flow limit
|
||||
pump->Q0 = 1.0; // Init. flow = 1 cfs
|
||||
return errcode;
|
||||
}
|
||||
|
||||
/* Assign limits to custom pump curves */
|
||||
if (pump->Ptype == CUSTOM) {
|
||||
curve = &net->Curve[j];
|
||||
for (m = 1; m < n; m++) {
|
||||
if (curve->Y[m] >= curve->Y[m - 1]) { /* Error: Invalid curve */
|
||||
EN_geterror(227, errMsg, MAXMSG);
|
||||
sprintf(pr->Msg, "%s link: %s", errMsg, link->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return (200);
|
||||
else if (pump->Ptype == NOCURVE) // Pump curve specified
|
||||
{
|
||||
curveindex = pump->Hcurve;
|
||||
if (curveindex == 0) return 226;
|
||||
curve = &net->Curve[curveindex];
|
||||
curve->Type = P_CURVE;
|
||||
npts = curve->Npts;
|
||||
|
||||
// Generic power function curve
|
||||
if (npts == 1)
|
||||
{
|
||||
pump->Ptype = POWER_FUNC;
|
||||
q1 = curve->X[0];
|
||||
h1 = curve->Y[0];
|
||||
h0 = 1.33334 * h1;
|
||||
q2 = 2.0 * q1;
|
||||
h2 = 0.0;
|
||||
}
|
||||
|
||||
// 3 point curve with shutoff head
|
||||
else if (npts == 3 && curve->X[0] == 0.0)
|
||||
{
|
||||
pump->Ptype = POWER_FUNC;
|
||||
h0 = curve->Y[0];
|
||||
q1 = curve->X[1];
|
||||
h1 = curve->Y[1];
|
||||
q2 = curve->X[2];
|
||||
h2 = curve->Y[2];
|
||||
}
|
||||
|
||||
// Custom pump curve
|
||||
else
|
||||
{
|
||||
pump->Ptype = CUSTOM;
|
||||
for (m = 1; m < npts; m++)
|
||||
{
|
||||
if (curve->Y[m] >= curve->Y[m - 1]) return 227;
|
||||
}
|
||||
pump->Qmax = curve->X[npts - 1];
|
||||
pump->Q0 = (curve->X[0] + pump->Qmax) / 2.0;
|
||||
pump->Hmax = curve->Y[0];
|
||||
}
|
||||
|
||||
// Compute shape factors & limits of power function curves
|
||||
if (pump->Ptype == POWER_FUNC)
|
||||
{
|
||||
if (!powercurve(h0, h1, h2, q1, q2, &a, &b, &c)) return 227;
|
||||
else
|
||||
{
|
||||
pump->H0 = -a;
|
||||
pump->R = -b;
|
||||
pump->N = c;
|
||||
pump->Q0 = q1;
|
||||
pump->Qmax = pow((-a / b), (1.0 / c));
|
||||
pump->Hmax = h0;
|
||||
}
|
||||
}
|
||||
}
|
||||
pump->Qmax = curve->X[n - 1];
|
||||
pump->Q0 = (curve->X[0] + pump->Qmax) / 2.0;
|
||||
pump->Hmax = curve->Y[0];
|
||||
}
|
||||
} /* Next pump */
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int addnodeID(EN_Network *net, int n, char *id)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
@@ -603,7 +624,6 @@ int unlinked(EN_Project *pr)
|
||||
EN_Network *net = &pr->network;
|
||||
int *marked;
|
||||
int i, err, errcode;
|
||||
char errMsg[MAXMSG+1];
|
||||
|
||||
errcode = 0;
|
||||
err = 0;
|
||||
@@ -621,8 +641,7 @@ int unlinked(EN_Project *pr)
|
||||
if (marked[i] == 0) /* If not marked then error */
|
||||
{
|
||||
err++;
|
||||
EN_geterror(233, errMsg, MAXMSG);
|
||||
sprintf(pr->Msg, "%s node: %s", errMsg, net->Node[i].ID);
|
||||
sprintf(pr->Msg, "%s link: %s", geterrmsg(233, pr->Msg), net->Node[i].ID);
|
||||
writeline(pr, pr->Msg);
|
||||
}
|
||||
if (err >= MAXERRS)
|
||||
@@ -732,9 +751,7 @@ int getcurves(EN_Project *pr)
|
||||
|
||||
/* Check that curve has data points */
|
||||
if (curve->Npts <= 0) {
|
||||
char errMsg[MAXMSG+1];
|
||||
EN_geterror(230, errMsg, MAXMSG);
|
||||
sprintf(pr->Msg, "%s curve: %s", errMsg, curve->ID);
|
||||
sprintf(pr->Msg, "%s link: %s", geterrmsg(230, pr->Msg), curve->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return (200);
|
||||
}
|
||||
@@ -754,9 +771,7 @@ int getcurves(EN_Project *pr)
|
||||
|
||||
/* Check that x data is in ascending order */
|
||||
if (fx->value >= x) {
|
||||
char errMsg[MAXMSG+1];
|
||||
EN_geterror(230, errMsg, MAXMSG);
|
||||
sprintf(pr->Msg, "%s node: %s", errMsg, curve->ID);
|
||||
sprintf(pr->Msg, "%s link: %s", geterrmsg(230, pr->Msg), curve->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return (200);
|
||||
}
|
||||
@@ -1012,10 +1027,8 @@ void inperrmsg(EN_Project *pr, int err, int sect, char *line)
|
||||
char errStr[MAXMSG + 1];
|
||||
char id[MAXMSG + 1];
|
||||
|
||||
EN_geterror(err, errStr, MAXMSG);
|
||||
|
||||
/* get text for error message */
|
||||
sprintf(pr->Msg, "%s - section: %s", errStr, SectTxt[sect]);
|
||||
sprintf(pr->Msg, "%s - section: %s", geterrmsg(err, errStr), SectTxt[sect]);
|
||||
|
||||
// append ID?
|
||||
/* Retrieve ID label of object with input error */
|
||||
|
||||
@@ -51,7 +51,7 @@ typedef int INT4;
|
||||
#define TITLELEN 79 // Max. # characters in a title line
|
||||
#define MAXID 31 /* Max. # characters in ID name */
|
||||
#define MAXMSG 255 /* Max. # characters in message text */
|
||||
#define MAXLINE 255 /* Max. # characters read from input line */
|
||||
#define MAXLINE 1024 /* Max. # characters read from input line */
|
||||
#define MAXFNAME 259 /* Max. # characters in file name */
|
||||
#define MAXTOKS 40 /* Max. items per line of input */
|
||||
#define TZERO 1.E-4 /* Zero time tolerance */
|
||||
|
||||
Reference in New Issue
Block a user