Fixes #172 (adjust controls when node/link is deleted) & EN_addrule added

- Deleting controls with node/link deletion made conditional.
- New EN_addrule function added along with a test file.
- Rule structures re-named & rules.c heavily modified.
- Issue with exceeding limit on number of temporary file names fixed.
- VB declaration and DEF files updated.
This commit is contained in:
Lew Rossman
2018-11-07 23:09:47 -05:00
parent ee335ab077
commit 7443cea9d4
25 changed files with 2197 additions and 1800 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ DAT(208,ENERR_SPEC_UNDEF_NODE,"undefined Node")
DAT(209,ENERR_ILLEGAL_VAL_NODE,"illegal value for Node")
DAT(210,ENERR_SPEC_UNDEF_LINK,"specified for undefined Link")
DAT(211,ENERR_ILLEGAL_VAL_LINK,"illegal value for Link")
DAT(212,ENERR_TRACE_NODE,"trace node")
DAT(212,ENERR_TRACE_NODE,"invalid trace node")
DAT(213,ENERR_ILLEGAL_OPT,"illegal option value in section")
DAT(214,ENERR_TOO_MANY_CHAR,"following line of section contains too many characters")
DAT(215,ENERR_DUPLICATE_ID,"duplicate ID")
@@ -33,6 +33,7 @@ DAT(216,ENERR_UNDEF_PUMP,"data specified for undefined Pump")
DAT(217,ENERR_INVALID_DATA_PUMP,"invalid data for Pump")
DAT(219,ENERR_ILLEGAL_CON_TANK,"illegally connected to a tank")
DAT(220,ENERR_ILLEGAL_CON_VALVE,"illegally connected to another valve")
DAT(221,ENERR_RULE_CLAUSE, "mis-placed rule clause")
DAT(222,ENERR_SAME_START_END,"same start and end nodes")
@@ -48,12 +49,15 @@ DAT(241,ENERR_UNDEF_CONTROL,"refers to undefined control")
DAT(250,ENERR_INVALID_FORMAT,"function call contains invalid format")
DAT(251,ENERR_INVALID_CODE,"function call contains invalid parameter code")
DAT(253,ENERR_NO_DEMAND_CAT,"Function call error - No such demand category index")
DAT(254,ENERR_NO_COORDS,"Function call error - Node have no coordinates")
DAT(255,ENERR_COORDS_NOT_LOADED,"Function call error - Coordinates were not loaded")
DAT(253,ENERR_NO_DEMAND_CAT,"function applied to nonexistent demand category")
DAT(254,ENERR_NO_COORDS,"function applied to node with no coordinates")
DAT(255,ENERR_COORDS_NOT_LOADED,"function fails because no node coordinates were supplied")
DAT(257,ENERR_NO_RULE,"rule does not exist")
DAT(258,ENERR_NO_CONDITION_ACTION,"condition or action index specified in rule does not exist")
DAT(257,ENERR_NO_RULE,"function applied to nonexistent rule")
DAT(258,ENERR_NO_CONDITION_ACTION,"function applied to nonexistent rule clause")
DAT(260,ENERR_DEL_TRACE_NODE,"cannot delete node assigned as a Trace Node")
DAT(261,ENERR_DEL_NODE_LINK, "cannot delete a node or link contained in a control")
DAT(301,ENERR_FILES_ARE_SAME,"identical file names")
DAT(302,ENERR_CANT_OPEN_INP,"cannot open input file")

View File

@@ -29,8 +29,6 @@ AUTHOR: L. Rossman
#ifndef FUNCS_H
#define FUNCS_H
#include "types.h"
void initpointers(EN_Project *pr); /* Initializes pointers */
int allocdata(EN_Project *pr); /* Allocates memory */
void freeTmplist(STmplist *); /* Frees items in linked list */
@@ -41,7 +39,7 @@ int openfiles(EN_Project *pr, const char *,
int openhydfile(EN_Project *pr); /* Opens hydraulics file */
int openoutfile(EN_Project *pr); /* Opens binary output file */
int strcomp(const char *, const char *); /* Compares two strings */
char* getTmpName(EN_Project *p, char* fname); /* Gets temporary file name */
char* getTmpName(char* fname); /* Gets temporary file name */
double interp(int n, double x[], double y[],
double xx); /* Interpolates a data curve */
@@ -118,16 +116,19 @@ void changestatus(EN_Network *net, int, StatType,
double); /* Changes status of a link */
/* -------------- RULES.C --------------*/
void initrules(rules_t *rules); /* Initializes rule base */
void initrules(EN_Project *pr); /* Initializes rule base */
void addrule(parser_data_t *par, char *); /* Adds rule to rule base */
int allocrules(EN_Project *pr); /* Allocates memory for rule */
void adjustrules(EN_Project *pr, int, int); // Shifts object indices down
void adjusttankrules(EN_Project *pr); // Shifts tank indices up
int ruledata(EN_Project *pr); /* Processes rule input data */
int checkrules(EN_Project *pr, long); /* Checks all rules */
void freerules(EN_Project *pr); /* Frees rule base memory */
int writeRuleinInp(EN_Project *pr, FILE *f, /* Writes rule to an INP file */
int RuleIdx);
void deleterule(EN_Project *pr, int); // Deletes a rule
void freerules(EN_Project *pr); /* Frees rule base memory */
int writerule(EN_Project *pr, FILE *, int); /* Writes rule to an INP file */
void ruleerrmsg(EN_Project *pr); /* Reports rule parser error */
Spremise *getpremise(Spremise *, int); // Retrieves a rule's premise
Saction *getaction(Saction *, int); // Retrieves a rule's action
/* ------------- REPORT.C --------------*/
int writereport(EN_Project *pr); /* Writes formatted report */
@@ -169,8 +170,8 @@ void setlinksetting(EN_Project *pr, int, double,
int tanktimestep(EN_Project *pr, long *); /* Time till tanks fill/drain */
void getenergy(EN_Project *pr, int, double *,
double *); /* Computes link energy use */
double tankvolume(EN_Project *pr, int,double); /* Finds tank vol. from grade */
double tankgrade(EN_Project *pr, int,double); /* Finds tank grade from vol. */
double tankvolume(EN_Project *pr, int, double); /* Finds tank vol. from grade */
double tankgrade(EN_Project *pr, int, double); /* Finds tank grade from vol. */
/* ----------- HYDSOLVER.C - ----------*/
int hydsolve(EN_Project *pr, int *,double *); /* Solves network equations */

View File

@@ -14,6 +14,7 @@ HYDCOEFFS.C -- hydraulic coefficients for the EPANET Program
#include <stdlib.h>
#endif
#include <math.h>
#include "types.h"
#include "funcs.h"
@@ -82,8 +83,8 @@ void resistcoeff(EN_Project *pr, int k)
// ... Link is a pipe. Compute resistance based on headloss formula.
// Friction factor for D-W formula gets included during head loss
// calculation.
case EN_CVPIPE:
case EN_PIPE:
case CVPIPE:
case PIPE:
e = link->Kc; // Roughness coeff.
d = link->Diam; // Diameter
L = link->Len; // Length
@@ -108,7 +109,7 @@ void resistcoeff(EN_Project *pr, int k)
break;
// ... Link is a pump. Use huge resistance.
case EN_PUMP:
case PUMP:
link->R = CBIG;
break;
@@ -138,25 +139,25 @@ void headlosscoeffs(EN_Project *pr)
{
switch (net->Link[k].Type)
{
case EN_CVPIPE:
case EN_PIPE:
case CVPIPE:
case PIPE:
pipecoeff(pr, k);
break;
case EN_PUMP:
case PUMP:
pumpcoeff(pr, k);
break;
case EN_PBV:
case PBV:
pbvcoeff(pr, k);
break;
case EN_TCV:
case TCV:
tcvcoeff(pr, k);
break;
case EN_GPV:
case GPV:
gpvcoeff(pr, k);
break;
case EN_FCV:
case EN_PRV:
case EN_PSV:
case FCV:
case PRV:
case PSV:
if (hyd->LinkSetting[k] == MISSING) valvecoeff(pr, k);
else hyd->solver.P[k] = 0.0;
}
@@ -317,13 +318,13 @@ void valvecoeffs(EN_Project *pr)
// Call valve-specific function
switch (link->Type)
{
case EN_PRV:
case PRV:
prvcoeff(pr, k, n1, n2);
break;
case EN_PSV:
case PSV:
psvcoeff(pr, k, n1, n2);
break;
case EN_FCV:
case FCV:
fcvcoeff(pr, k, n1, n2);
break;
default: continue;

View File

@@ -54,9 +54,10 @@ AUTHOR: L. Rossman
#include <stdlib.h>
#endif
#include <math.h>
#include "text.h"
#include "types.h"
#include "funcs.h"
#include "text.h"
#define QZERO 1.e-6 /* Equivalent to zero flow */
@@ -146,8 +147,8 @@ void inithyd(EN_Project *pr, int initflag)
/* Start active control valves in ACTIVE position */
if (
(link->Type == EN_PRV || link->Type == EN_PSV
|| link->Type == EN_FCV) && (link->Kc != MISSING)
(link->Type == PRV || link->Type == PSV
|| link->Type == FCV) && (link->Kc != MISSING)
) hyd->LinkStatus[i] = ACTIVE;
/*** Updated 3/1/01 ***/
@@ -391,7 +392,7 @@ void initlinkflow(EN_Project *pr, int i, char s, double k)
if (s == CLOSED) {
hyd->LinkFlows[i] = QZERO;
}
else if (link->Type == EN_PUMP) {
else if (link->Type == PUMP) {
hyd->LinkFlows[i] = k * n->Pump[findpump(n,i)].Q0;
}
else {
@@ -421,8 +422,8 @@ void setlinkflow(EN_Project *pr, int k, double dh)
switch (link->Type)
{
case EN_CVPIPE:
case EN_PIPE:
case CVPIPE:
case PIPE:
/* For Darcy-Weisbach formula: */
/* use approx. inverse of formula. */
@@ -447,7 +448,7 @@ void setlinkflow(EN_Project *pr, int k, double dh)
break;
case EN_PUMP:
case PUMP:
/* Convert headloss to pump head gain */
dh = -dh;
@@ -492,15 +493,15 @@ void setlinkstatus(EN_Project *pr, int index, char value, StatType *s, double *
{
EN_Network *net = &pr->network;
Slink *link = &net->Link[index];
EN_LinkType t = link->Type;
LinkType t = link->Type;
/* Status set to open */
if (value == 1) {
/* Adjust link setting for pumps & valves */
if (t == EN_PUMP) {
if (t == PUMP) {
*k = 1.0;
}
if (t > EN_PUMP && t != EN_GPV) {
if (t > PUMP && t != GPV) {
*k = MISSING;
}
/* Reset link flow if it was originally closed */
@@ -510,10 +511,10 @@ void setlinkstatus(EN_Project *pr, int index, char value, StatType *s, double *
/* Status set to closed */
else if (value == 0) {
/* Adjust link setting for pumps & valves */
if (t == EN_PUMP) {
if (t == PUMP) {
*k = 0.0;
}
if (t > EN_PUMP && t != EN_GPV) {
if (t > PUMP && t != GPV) {
*k = MISSING;
}
/* Reset link flow if it was originally open */
@@ -536,10 +537,10 @@ void setlinksetting(EN_Project *pr, int index, double value, StatType *s, doubl
{
EN_Network *net = &pr->network;
Slink *link = &net->Link[index];
EN_LinkType t = link->Type;
LinkType t = link->Type;
/* For a pump, status is OPEN if speed > 0, CLOSED otherwise */
if (t == EN_PUMP)
if (t == PUMP)
{
*k = value;
if (value > 0 && *s <= CLOSED) {
@@ -551,7 +552,7 @@ void setlinksetting(EN_Project *pr, int index, double value, StatType *s, doubl
}
/* For FCV, activate it */
else if (t == EN_FCV) {
else if (t == FCV) {
*k = value;
*s = ACTIVE;
}
@@ -709,7 +710,7 @@ int controls(EN_Project *pr)
s2 = control->Status;
k1 = hyd->LinkSetting[k];
k2 = k1;
if (link->Type > EN_PIPE) {
if (link->Type > PIPE) {
k2 = control->Setting;
}
if (s1 != s2 || k1 != k2) {
@@ -891,7 +892,7 @@ void controltimestep(EN_Project *pr, long *tstep)
/* Check if rule actually changes link status or setting */
k = control->Link;
link = &net->Link[k];
if ( (link->Type > EN_PIPE && hyd->LinkSetting[k] != control->Setting)
if ( (link->Type > PIPE && hyd->LinkSetting[k] != control->Setting)
|| (hyd->LinkStatus[k] != control->Status) ) {
*tstep = t;
}
@@ -1103,7 +1104,7 @@ void getenergy(EN_Project *pr, int k, double *kw, double *eff)
dh = ABS(hyd->NodeHead[link->N1] - hyd->NodeHead[link->N2]);
/* For pumps, find effic. at current flow */
if (link->Type == EN_PUMP)
if (link->Type == PUMP)
{
j = findpump(net,k);
e = hyd->Epump;

View File

@@ -18,9 +18,10 @@ The solver implements Todini's Global Gradient Algorithm.
#include <stdlib.h>
#endif
#include <math.h>
#include "text.h"
#include "types.h"
#include "funcs.h"
#include "text.h"
// Hydraulic balance error for network being analyzed
typedef struct {
@@ -241,7 +242,7 @@ int badvalve(EN_Project *pr, int n)
report_options_t *rep = &pr->report;
time_options_t *time = &pr->time_options;
Slink *link;
EN_LinkType t;
LinkType t;
for (i = 1; i <= net->Nvalves; i++)
{
@@ -252,7 +253,7 @@ int badvalve(EN_Project *pr, int n)
if (n == n1 || n == n2)
{
t = link->Type;
if (t == EN_PRV || t == EN_PSV || t == EN_FCV)
if (t == PRV || t == PSV || t == FCV)
{
if (hyd->LinkStatus[k] == ACTIVE)
{
@@ -261,7 +262,7 @@ int badvalve(EN_Project *pr, int n)
sprintf(pr->Msg, FMT61, clocktime(rep->Atime, time->Htime), link->ID);
writeline(pr, pr->Msg);
}
if (link->Type == EN_FCV)
if (link->Type == FCV)
{
hyd->LinkStatus[k] = XFCV;
}
@@ -332,15 +333,15 @@ int pswitch(EN_Project *pr)
link = &net->Link[k];
change = 0;
s = hyd->LinkStatus[k];
if (link->Type == EN_PIPE)
if (link->Type == PIPE)
{
if (s != net->Control[i].Status) change = 1;
}
if (link->Type == EN_PUMP)
if (link->Type == PUMP)
{
if (hyd->LinkSetting[k] != net->Control[i].Setting) change = 1;
}
if (link->Type >= EN_PRV)
if (link->Type >= PRV)
{
if (hyd->LinkSetting[k] != net->Control[i].Setting) change = 1;
else if (hyd->LinkSetting[k] == MISSING && s != net->Control[i].Status)
@@ -353,7 +354,7 @@ int pswitch(EN_Project *pr)
if (change)
{
hyd->LinkStatus[k] = net->Control[i].Status;
if (link->Type > EN_PIPE)
if (link->Type > PIPE)
{
hyd->LinkSetting[k] = net->Control[i].Setting;
}
@@ -450,7 +451,7 @@ void newlinkflows(EN_Project *pr, Hydbalance *hbal, double *qsum, double *dqsum
dq *= hyd->RelaxFactor;
// Prevent flow in constant HP pumps from going negative
if (link->Type == EN_PUMP)
if (link->Type == PUMP)
{
n = findpump(net, k);
if (net->Pump[n].Ptype == CONST_HP && dq > hyd->LinkFlows[k])

View File

@@ -63,12 +63,12 @@ int valvestatus(EN_Project *pr)
// Evaluate valve's new status
switch (link->Type)
{
case EN_PRV:
case PRV:
hset = net->Node[n2].El + hyd->LinkSetting[k];
hyd->LinkStatus[k] = prvstatus(pr, k, status, hset,
hyd->NodeHead[n1], hyd->NodeHead[n2]);
break;
case EN_PSV:
case PSV:
hset = net->Node[n1].El + hyd->LinkSetting[k];
hyd->LinkStatus[k] = psvstatus(pr, k, status, hset,
hyd->NodeHead[n1], hyd->NodeHead[n2]);
@@ -129,19 +129,19 @@ int linkstatus(EN_Project *pr)
}
// Check for status changes in CVs and pumps
if (link->Type == EN_CVPIPE)
if (link->Type == CVPIPE)
{
hyd->LinkStatus[k] = cvstatus(pr, hyd->LinkStatus[k], dh,
hyd->LinkFlows[k]);
}
if (link->Type == EN_PUMP && hyd->LinkStatus[k] >= OPEN &&
if (link->Type == PUMP && hyd->LinkStatus[k] >= OPEN &&
hyd->LinkSetting[k] > 0.0)
{
hyd->LinkStatus[k] = pumpstatus(pr, k, -dh);
}
// Check for status changes in non-fixed FCVs
if (link->Type == EN_FCV && hyd->LinkSetting[k] != MISSING)
if (link->Type == FCV && hyd->LinkSetting[k] != MISSING)
{
hyd->LinkStatus[k] = fcvstatus(pr, k, status, hyd->NodeHead[n1],
hyd->NodeHead[n2]);
@@ -430,7 +430,7 @@ void tankstatus(EN_Project *pr, int k, int n1, int n2)
if (hyd->NodeHead[n1] >= tank->Hmax - hyd->Htol)
{
// Case 1: Link is a pump discharging into tank
if (link->Type == EN_PUMP)
if (link->Type == PUMP)
{
if (link->N2 == n1) hyd->LinkStatus[k] = TEMPCLOSED;
}
@@ -447,7 +447,7 @@ void tankstatus(EN_Project *pr, int k, int n1, int n2)
if (hyd->NodeHead[n1] <= tank->Hmin + hyd->Htol)
{
// Case 1: Link is a pump discharging from tank
if (link->Type == EN_PUMP)
if (link->Type == PUMP)
{
if (link->N1 == n1) hyd->LinkStatus[k] = TEMPCLOSED;
}

View File

@@ -26,14 +26,12 @@ data describing a piping network to a file in EPANET's text format.
#else
#include <stdlib.h>
#endif
#include <math.h>
#include "hash.h"
#include "text.h"
#include "types.h"
#include "funcs.h"
#include <math.h>
//#define EXTERN extern
//#include "vars.h"
#include "hash.h"
#include "text.h"
/* Defined in enumstxt.h in EPANET.C */
extern char *LinkTxt[];
@@ -216,7 +214,7 @@ int saveinpfile(EN_Project *pr, const char *fname)
fprintf(f, s_PIPES);
for (i = 1; i <= net->Nlinks; i++) {
link = &net->Link[i];
if (link->Type <= EN_PIPE) {
if (link->Type <= PIPE) {
d = link->Diam;
kc = link->Kc;
if (hyd->Formflag == DW)
@@ -229,7 +227,7 @@ int saveinpfile(EN_Project *pr, const char *fname)
sprintf(s1, "%12.4f %12.4f", kc, km);
else
sprintf(s1, "%12.4f %12.4f", kc, km);
if (link->Type == EN_CVPIPE)
if (link->Type == CVPIPE)
sprintf(s2, "CV");
else if (link->Stat == CLOSED)
sprintf(s2, "CLOSED");
@@ -295,12 +293,12 @@ int saveinpfile(EN_Project *pr, const char *fname)
if (kc == MISSING)
kc = 0.0;
switch (link->Type) {
case EN_FCV:
case FCV:
kc *= pr->Ucf[FLOW];
break;
case EN_PRV:
case EN_PSV:
case EN_PBV:
case PRV:
case PSV:
case PBV:
kc *= pr->Ucf[PRESSURE];
break;
default:
@@ -312,7 +310,7 @@ int saveinpfile(EN_Project *pr, const char *fname)
sprintf(s, " %-31s %-31s %-31s %12.4f %5s", link->ID, net->Node[link->N1].ID,
net->Node[link->N2].ID, d * pr->Ucf[DIAM], LinkTxt[link->Type]);
if (link->Type == EN_GPV && (j = ROUND(link->Kc)) > 0)
if (link->Type == GPV && (j = ROUND(link->Kc)) > 0)
sprintf(s1, "%-31s %12.4f", net->Curve[j].ID, km);
else
sprintf(s1, "%12.4f %12.4f", kc, km);
@@ -355,12 +353,12 @@ int saveinpfile(EN_Project *pr, const char *fname)
fprintf(f, s_STATUS);
for (i = 1; i <= net->Nlinks; i++) {
link = &net->Link[i];
if (link->Type <= EN_PUMP) {
if (link->Type <= PUMP) {
if (link->Stat == CLOSED)
fprintf(f, "\n %-31s %s", link->ID, StatTxt[CLOSED]);
/* Write pump speed here for pumps with old-style pump curve input */
else if (link->Type == EN_PUMP) {
else if (link->Type == PUMP) {
n = findpump(net, i);
pump = &net->Pump[n];
if (pump->Hcurve == 0 && pump->Ptype != CONST_HP &&
@@ -419,12 +417,12 @@ int saveinpfile(EN_Project *pr, const char *fname)
else {
kc = control->Setting;
switch (link->Type) {
case EN_PRV:
case EN_PSV:
case EN_PBV:
case PRV:
case PSV:
case PBV:
kc *= pr->Ucf[PRESSURE];
break;
case EN_FCV:
case FCV:
kc *= pr->Ucf[FLOW];
break;
default:
@@ -467,8 +465,8 @@ int saveinpfile(EN_Project *pr, const char *fname)
fprintf(f, "\n\n");
fprintf(f, s_RULES);
for (i = 1; i <= net->Nrules; i++) {
fprintf(f, "\nRULE %s", pr->rules.Rule[i].label);
errcode = writeRuleinInp(pr, f, i);
fprintf(f, "\nRULE %s", pr->network.Rule[i].label);
errcode = writerule(pr, f, i);
fprintf(f, "\n");
}
@@ -528,7 +526,7 @@ int saveinpfile(EN_Project *pr, const char *fname)
fprintf(f, "\n ROUGHNESS CORRELATION %-.6f", qu->Rfactor);
for (i = 1; i <= net->Nlinks; i++) {
link = &net->Link[i];
if (link->Type > EN_PIPE)
if (link->Type > PIPE)
continue;
if (link->Kb != qu->Kbulk)
fprintf(f, "\n BULK %-31s %-.6f", link->ID, link->Kb * SECperDAY);

View File

@@ -27,11 +27,11 @@ AUTHOR: L. Rossman
#ifndef __APPLE__
#include <malloc.h>
#endif
#include "types.h"
#include "funcs.h"
#include "hash.h"
#include "text.h"
#include "types.h"
#include "epanet2.h"
#include "funcs.h"
#include <math.h>
/*
@@ -107,8 +107,6 @@ void setdefaults(EN_Project *pr)
strncpy(pr->Title[0], "", TITLELEN);
strncpy(pr->Title[1], "", TITLELEN);
strncpy(pr->Title[2], "", TITLELEN);
strncpy(out->TmpDir, "", MAXFNAME);
strncpy(out->TmpFname, "", MAXFNAME);
strncpy(out->HydFname, "", MAXFNAME);
strncpy(pr->MapFname, "", MAXFNAME);
strncpy(qu->ChemName, t_CHEMICAL, MAXID);
@@ -324,7 +322,7 @@ void adjustdata(EN_Project *pr)
/* See if default reaction coeffs. apply */
for (i = 1; i <= net->Nlinks; i++) {
Slink *link = &net->Link[i];
if (link->Type > EN_PIPE)
if (link->Type > PIPE)
continue;
if (link->Kb == MISSING)
link->Kb = qu->Kbulk; /* Bulk coeff. */
@@ -406,9 +404,8 @@ int inittanks(EN_Project *pr)
/* Report error in levels if found */
if (levelerr) {
char errMsg[MAXMSG+1];
EN_geterror(225, errMsg, MAXMSG);
sprintf(pr->Msg, "%s node: %s", errMsg, net->Node[tank->Node].ID);
sprintf(pr->Msg, "%s node: %s", geterrmsg(225, pr->Msg),
net->Node[tank->Node].ID);
writeline(pr, pr->Msg);
errcode = 200;
}
@@ -629,7 +626,7 @@ void convertunits(EN_Project *pr)
/* Convert units of link parameters */
for (k = 1; k <= net->Nlinks; k++) {
link = &net->Link[k];
if (link->Type <= EN_PIPE) {
if (link->Type <= PIPE) {
/* Convert pipe parameter units: */
/* - for Darcy-Weisbach formula, convert roughness */
/* from millifeet (or mm) to ft (or m) */
@@ -647,7 +644,7 @@ void convertunits(EN_Project *pr)
link->Kw /= SECperDAY;
}
else if (link->Type == EN_PUMP) {
else if (link->Type == PUMP) {
/* Convert units for pump curve parameters */
i = findpump(net, k);
pump = &net->Pump[i];
@@ -676,12 +673,12 @@ void convertunits(EN_Project *pr)
link->Km = 0.02517 * link->Km / SQR(link->Diam) / SQR(link->Diam);
if (link->Kc != MISSING)
switch (link->Type) {
case EN_FCV:
case FCV:
link->Kc /= pr->Ucf[FLOW];
break;
case EN_PRV:
case EN_PSV:
case EN_PBV:
case PRV:
case PSV:
case PBV:
link->Kc /= pr->Ucf[PRESSURE];
break;
default:
@@ -716,12 +713,12 @@ void convertunits(EN_Project *pr)
/* Convert units on valve settings */
if (control->Setting != MISSING) {
switch (link->Type) {
case EN_PRV:
case EN_PSV:
case EN_PBV:
case PRV:
case PSV:
case PBV:
control->Setting /= pr->Ucf[PRESSURE];
break;
case EN_FCV:
case FCV:
control->Setting /= pr->Ucf[FLOW];
default:
break;

View File

@@ -31,12 +31,12 @@ The following utility functions are all called from INPUT3.C
#ifndef __APPLE__
#include <malloc.h>
#endif
#include <math.h>
#include "types.h"
#include "funcs.h"
#include "hash.h"
#include "text.h"
#include "types.h"
#include "epanet2.h"
#include "funcs.h"
#include <math.h>
#define MAXERRS 10 /* Max. input errors reported */
@@ -206,9 +206,6 @@ 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]);
sprintf(pr->Msg, "%s section: %s", geterrmsg(214, pr->Msg), SectTxt[sect]);
writeline(pr, pr->Msg);
writeline(pr, line);
@@ -317,7 +314,12 @@ int newline(EN_Project *pr, int sect, char *line)
case _CONTROLS:
return (controldata(pr));
case _RULES:
return (ruledata(pr)); /* See RULES.C */
if (ruledata(pr) > 0)
{
ruleerrmsg(pr);
return 200;
}
else return 0;
case _SOURCES:
return (sourcedata(pr));
case _EMITTERS:

View File

@@ -26,12 +26,12 @@ All functions in this module are called from newline() in INPUT2.C.
#ifndef __APPLE__
#include <malloc.h>
#endif
#include "epanet2.h"
#include <math.h>
#include "types.h"
#include "funcs.h"
#include "hash.h"
#include "text.h"
#include "types.h"
#include <math.h>
/* Defined in enumstxt.h in EPANET.C */
extern char *MixTxt[];
@@ -98,7 +98,7 @@ int juncdata(EN_Project *pr)
node->S = NULL;
node->Ke = 0.0;
node->Rpt = 0;
node->Type = EN_JUNCTION;
node->Type = JUNCTION;
strcpy(node->Comment, par->Comment);
@@ -214,7 +214,7 @@ int tankdata(EN_Project *pr)
node->C0 = 0.0; /* Init. quality. */
node->S = NULL; /* WQ source data */
node->Ke = 0.0; /* Emitter coeff. */
node->Type = (diam == 0) ? EN_RESERVOIR : EN_TANK;
node->Type = (diam == 0) ? RESERVOIR : TANK;
strcpy(node->Comment, par->Comment);
tank->Node = i; /* Node index. */
tank->H0 = initlevel; /* Init. level. */
@@ -258,7 +258,7 @@ int pipedata(EN_Project *pr)
int j1, /* Start-node index */
j2, /* End-node index */
n; /* # data items */
EN_LinkType type = EN_PIPE; /* Link type */
LinkType type = PIPE; /* Link type */
StatType status = OPEN; /* Link status */
double length, /* Link length */
diam, /* Link diameter */
@@ -298,7 +298,7 @@ int pipedata(EN_Project *pr)
/* Case where either loss coeff. or status supplied */
if (n == 7) {
if (match(par->Tok[6], w_CV))
type = EN_CVPIPE;
type = CVPIPE;
else if (match(par->Tok[6], w_CLOSED))
status = CLOSED;
else if (match(par->Tok[6], w_OPEN))
@@ -312,7 +312,7 @@ int pipedata(EN_Project *pr)
if (!getfloat(par->Tok[6], &lcoeff))
return (202);
if (match(par->Tok[7], w_CV))
type = EN_CVPIPE;
type = CVPIPE;
else if (match(par->Tok[7], w_CLOSED))
status = CLOSED;
else if (match(par->Tok[7], w_OPEN))
@@ -401,7 +401,7 @@ int pumpdata(EN_Project *pr)
link->Km = 0.0; /* Horsepower. */
link->Kb = 0.0;
link->Kw = 0.0;
link->Type = EN_PUMP; /* Link type. */
link->Type = PUMP; /* Link type. */
link->Stat = OPEN; /* Link status. */
link->Rpt = 0; /* Report flag. */
strcpy(link->Comment, par->Comment);
@@ -514,24 +514,24 @@ int valvedata(EN_Project *pr)
return (222);
if (match(par->Tok[4], w_PRV))
type = EN_PRV;
type = PRV;
else if (match(par->Tok[4], w_PSV))
type = EN_PSV;
type = PSV;
else if (match(par->Tok[4], w_PBV))
type = EN_PBV;
type = PBV;
else if (match(par->Tok[4], w_FCV))
type = EN_FCV;
type = FCV;
else if (match(par->Tok[4], w_TCV))
type = EN_TCV;
type = TCV;
else if (match(par->Tok[4], w_GPV))
type = EN_GPV;
type = GPV;
else
return (201); /* Illegal valve type.*/
if (!getfloat(par->Tok[3], &diam))
return (202);
if (diam <= 0.0)
return (202); /* Illegal diameter.*/
if (type == EN_GPV) { /* Headloss curve for GPV */
if (type == GPV) { /* Headloss curve for GPV */
t = findID(par->Tok[5], par->Curvelist);
if (t == NULL) {
return (206);
@@ -549,7 +549,7 @@ int valvedata(EN_Project *pr)
/* Check that PRV, PSV, or FCV not connected to a tank & */
/* check for illegal connections between pairs of valves.*/
if ((j1 > net->Njuncs || j2 > net->Njuncs) &&
(type == EN_PRV || type == EN_PSV || type == EN_FCV))
(type == PRV || type == PSV || type == FCV))
return (219);
if (!valvecheck(pr, type, j1, j2))
return (220);
@@ -820,7 +820,7 @@ int controldata(EN_Project *pr)
n; /* # data items */
StatType status = ACTIVE; /* Link status */
ControlType c_type; /* control type */
EN_LinkType l_type; /* Link Type */
LinkType l_type; /* Link Type */
double setting = MISSING, /* Link setting */
time = 0.0, /* Simulation time */
level = 0.0; /* Pressure or tank level */
@@ -836,24 +836,24 @@ int controldata(EN_Project *pr)
if (k == 0)
return (204);
l_type = net->Link[k].Type;
if (l_type == EN_CVPIPE) {
if (l_type == CVPIPE) {
return (207); /* Cannot control check valve. */
}
/*** Updated 9/7/00 ***/
/* Parse control setting into a status level or numerical setting. */
if (match(par->Tok[2], w_OPEN)) {
status = OPEN;
if (l_type == EN_PUMP)
if (l_type == PUMP)
setting = 1.0;
if (l_type == EN_GPV)
if (l_type == GPV)
setting = net->Link[k].Kc;
} else if (match(par->Tok[2], w_CLOSED)) {
status = CLOSED;
if (l_type == EN_PUMP)
if (l_type == PUMP)
setting = 0.0;
if (l_type == EN_GPV)
if (l_type == GPV)
setting = net->Link[k].Kc;
} else if (l_type == EN_GPV) {
} else if (l_type == GPV) {
return (206);
} else if (!getfloat(par->Tok[2], &setting)) {
return (202);
@@ -863,7 +863,7 @@ int controldata(EN_Project *pr)
/* Set status for pump in case speed setting was supplied */
/* or for pipe if numerical setting was supplied */
if (l_type == EN_PUMP || l_type == EN_PIPE) {
if (l_type == PUMP || l_type == PIPE) {
if (setting != MISSING) {
if (setting < 0.0)
return (202);
@@ -1321,12 +1321,12 @@ int statusdata(EN_Project *pr)
if ((j = findlink(net, par->Tok[0])) == 0)
return (0);
/* Cannot change status of a Check Valve */
if (net->Link[j].Type == EN_CVPIPE)
if (net->Link[j].Type == CVPIPE)
return (211);
/*** Updated 9/7/00 ***/
/* Cannot change setting for a GPV */
if (net->Link[j].Type == EN_GPV && status == ACTIVE)
if (net->Link[j].Type == GPV && status == ACTIVE)
return (211);
changestatus(net, j, status, y);
@@ -1398,7 +1398,7 @@ int energydata(EN_Project *pr)
k = findlink(net,par->Tok[1]); /* Check that pump exists */
if (k == 0)
return (216);
if (Link[k].Type != EN_PUMP)
if (Link[k].Type != PUMP)
return (216);
j = findpump(net, k);
} else
@@ -2150,7 +2150,7 @@ int valvecheck(EN_Project *pr, int type, int j1, int j2)
EN_Network *net = &pr->network;
int k, vj1, vj2;
EN_LinkType vtype;
LinkType vtype;
/* Examine each existing valve */
for (k = 1; k <= net->Nvalves; k++) {
@@ -2161,35 +2161,35 @@ int valvecheck(EN_Project *pr, int type, int j1, int j2)
vtype = link->Type;
/* Cannot have two PRVs sharing downstream nodes or in series */
if (vtype == EN_PRV && type == EN_PRV) {
if (vtype == PRV && type == PRV) {
if (vj2 == j2 || vj2 == j1 || vj1 == j2)
return (0);
}
/* Cannot have two PSVs sharing upstream nodes or in series */
if (vtype == EN_PSV && type == EN_PSV) {
if (vtype == PSV && type == PSV) {
if (vj1 == j1 || vj1 == j2 || vj2 == j1)
return (0);
}
/* Cannot have PSV connected to downstream node of PRV */
if (vtype == EN_PSV && type == EN_PRV && vj1 == j2)
if (vtype == PSV && type == PRV && vj1 == j2)
return (0);
if (vtype == EN_PRV && type == EN_PSV && vj2 == j1)
if (vtype == PRV && type == PSV && vj2 == j1)
return (0);
/*** Updated 3/1/01 ***/
/* Cannot have PSV connected to downstream node of FCV */
/* nor have PRV connected to upstream node of FCV */
if (vtype == EN_FCV && type == EN_PSV && vj2 == j1)
if (vtype == FCV && type == PSV && vj2 == j1)
return (0);
if (vtype == EN_FCV && type == EN_PRV && vj1 == j2)
if (vtype == FCV && type == PRV && vj1 == j2)
return (0);
/*** Updated 4/14/05 ***/
if (vtype == EN_PSV && type == EN_FCV && vj1 == j2)
if (vtype == PSV && type == FCV && vj1 == j2)
return (0);
if (vtype == EN_PRV && type == EN_FCV && vj2 == j1)
if (vtype == PRV && type == FCV && vj2 == j1)
return (0);
}
return (1);
@@ -2213,10 +2213,10 @@ void changestatus(EN_Network *net, int j, StatType status, double y)
{
Slink *link = &net->Link[j];
if (link->Type == EN_PIPE || link->Type == EN_GPV) {
if (link->Type == PIPE || link->Type == GPV) {
if (status != ACTIVE)
link->Stat = status;
} else if (link->Type == EN_PUMP) {
} else if (link->Type == PUMP) {
if (status == ACTIVE) {
link->Kc = y;
status = OPEN;
@@ -2226,7 +2226,7 @@ void changestatus(EN_Network *net, int j, StatType status, double y)
link->Kc = 1.0;
}
link->Stat = status;
} else if (link->Type >= EN_PRV) {
} else if (link->Type >= PRV) {
link->Kc = y;
link->Stat = status;
if (status != ACTIVE) {

View File

@@ -19,12 +19,12 @@ AUTHOR: L. Rossman
#else
#include <stdlib.h>
#endif
#include "funcs.h"
#include "text.h"
#include "types.h"
#include <math.h>
#include "types.h"
#include "funcs.h"
#include "hash.h"
#include "text.h"
/* write x[1] to x[n] to file */
size_t f_save(REAL4 *x, int n, FILE *file) {
@@ -139,7 +139,7 @@ int savenetdata(EN_Project *pr)
f_save(x, net->Nlinks, outFile);
for (i = 1; i <= net->Nlinks; i++) {
if (net->Link[i].Type != EN_PUMP)
if (net->Link[i].Type != PUMP)
x[i] = (REAL4)(net->Link[i].Diam * pr->Ucf[DIAM]);
else
x[i] = 0.0f;
@@ -500,7 +500,7 @@ int linkoutput(EN_Project *pr, int j, REAL4 *x, double ucf)
break;
case VELOCITY:
for (i = 1; i <= net->Nlinks; i++) {
if (net->Link[i].Type == EN_PUMP)
if (net->Link[i].Type == PUMP)
x[i] = 0.0f;
else {
q = ABS(hyd->LinkFlows[i]);
@@ -515,9 +515,9 @@ int linkoutput(EN_Project *pr, int j, REAL4 *x, double ucf)
x[i] = 0.0f;
else {
h = hyd->NodeHead[net->Link[i].N1] - hyd->NodeHead[net->Link[i].N2];
if (net->Link[i].Type != EN_PUMP)
if (net->Link[i].Type != PUMP)
h = ABS(h);
if (net->Link[i].Type <= EN_PIPE)
if (net->Link[i].Type <= PIPE)
x[i] = (REAL4)(1000.0 * h / net->Link[i].Len);
else
x[i] = (REAL4)(h * ucf);
@@ -537,22 +537,22 @@ int linkoutput(EN_Project *pr, int j, REAL4 *x, double ucf)
double setting = hyd->LinkSetting[i];
if (setting != MISSING)
switch (net->Link[i].Type) {
case EN_CVPIPE:
case EN_PIPE:
case CVPIPE:
case PIPE:
x[i] = (REAL4)setting;
break;
case EN_PUMP:
case PUMP:
x[i] = (REAL4)setting;
break;
case EN_PRV:
case EN_PSV:
case EN_PBV:
case PRV:
case PSV:
case PBV:
x[i] = (REAL4)(setting * pr->Ucf[PRESSURE]);
break;
case EN_FCV:
case FCV:
x[i] = (REAL4)(setting * pr->Ucf[FLOW]);
break;
case EN_TCV:
case TCV:
x[i] = (REAL4)setting;
break;
default:
@@ -573,7 +573,7 @@ int linkoutput(EN_Project *pr, int j, REAL4 *x, double ucf)
/* u = velocity, g = grav. accel., h = head */
/*loss, d = diam., & L = pipe length */
for (i = 1; i <= net->Nlinks; i++) {
if (net->Link[i].Type <= EN_PIPE && ABS(hyd->LinkFlows[i]) > TINY) {
if (net->Link[i].Type <= PIPE && ABS(hyd->LinkFlows[i]) > TINY) {
h = ABS(hyd->NodeHead[net->Link[i].N1] - hyd->NodeHead[net->Link[i].N2]);
f = 39.725 * h * pow(net->Link[i].Diam, 5) / net->Link[i].Len / SQR(hyd->LinkFlows[i]);
x[i] = (REAL4)f;

View File

@@ -495,7 +495,7 @@ double findsourcequal(EN_Project *pr, int n, double volin, double volout, long t
{
// Concentration Source:
case CONCEN:
if (net->Node[n].Type == EN_JUNCTION)
if (net->Node[n].Type == JUNCTION)
{
// ... source requires a negative demand at the node
if (hyd->NodeDemand[n] < 0.0)

View File

@@ -52,7 +52,7 @@ char setreactflag(EN_Project *pr)
{
for (i = 1; i <= net->Nlinks; i++)
{
if (net->Link[i].Type <= EN_PIPE)
if (net->Link[i].Type <= PIPE)
{
if (net->Link[i].Kb != 0.0 || net->Link[i].Kw != 0.0) return 1;
}
@@ -127,7 +127,7 @@ void reactpipes(EN_Project *pr, long dt)
for (k = 1; k <= net->Nlinks; k++)
{
// Skip non-pipe links (pumps & valves)
if (net->Link[k].Type != EN_PIPE) continue;
if (net->Link[k].Type != PIPE) continue;
rsum = 0.0;
vsum = 0.0;

View File

@@ -94,7 +94,7 @@ void transport(EN_Project *pr, long tstep)
}
// ... if node is a junction, add on any external outflow (e.g., demands)
if (net->Node[n].Type == EN_JUNCTION)
if (net->Node[n].Type == JUNCTION)
{
volout += MAX(0.0, hyd->NodeDemand[n]);
}
@@ -204,7 +204,7 @@ double findnodequal(EN_Project *pr, int n, double volin,
quality_t *qual = &pr->quality;
// Node is a junction - update its water quality
if (net->Node[n].Type == EN_JUNCTION)
if (net->Node[n].Type == JUNCTION)
{
// ... dilute inflow with any external negative demand
volin -= MIN(0.0, hyd->NodeDemand[n]) * tstep;
@@ -217,7 +217,7 @@ double findnodequal(EN_Project *pr, int n, double volin,
}
// Node is a tank - use its mixing model to update its quality
else if (net->Node[n].Type == EN_TANK)
else if (net->Node[n].Type == TANK)
{
qual->NodeQual[n] = mixtank(pr, n, volin, massin, volout);
}
@@ -232,7 +232,7 @@ double findnodequal(EN_Project *pr, int n, double volin,
{
// ... quality added to network is difference between tracer
// concentration (100 mg/L) and current node quality
if (net->Node[n].Type == EN_RESERVOIR) qual->SourceQual = 100.0;
if (net->Node[n].Type == RESERVOIR) qual->SourceQual = 100.0;
else qual->SourceQual = MAX(100.0 - qual->NodeQual[n], 0.0);
qual->NodeQual[n] = 100.0;
}
@@ -246,14 +246,14 @@ double findnodequal(EN_Project *pr, int n, double volin,
// Combine source quality with node quality
switch (net->Node[n].Type)
{
case EN_JUNCTION:
case JUNCTION:
qual->NodeQual[n] += qual->SourceQual;
return qual->NodeQual[n];
case EN_TANK:
case TANK:
return qual->NodeQual[n] + qual->SourceQual;
case EN_RESERVOIR:
case RESERVOIR:
qual->NodeQual[n] = qual->SourceQual;
return qual->SourceQual;
}
@@ -382,21 +382,21 @@ void updatemassbalance(EN_Project *pr, int n, double massin,
switch (net->Node[n].Type)
{
// Junctions lose mass from outflow demand & gain it from source inflow
case EN_JUNCTION:
case JUNCTION:
masslost = MAX(0.0, hyd->NodeDemand[n]) * tstep * qual->NodeQual[n];
massadded = qual->SourceQual * volout;
break;
// Reservoirs add mass from quality source if specified or from a fixed
// initial quality
case EN_RESERVOIR:
case RESERVOIR:
masslost = massin;
if (qual->SourceQual > 0.0) massadded = qual->SourceQual * volout;
else massadded = qual->NodeQual[n] * volout;
break;
// Tanks add mass only from external source inflow
case EN_TANK:
case TANK:
massadded = qual->SourceQual * volout;
break;
}
@@ -664,7 +664,7 @@ void initsegs(EN_Project *pr)
{
qual->FirstSeg[k] = NULL;
qual->LastSeg[k] = NULL;
if (net->Link[k].Type == EN_PIPE)
if (net->Link[k].Type == PIPE)
{
v = LINKVOL(k);
j = net->Link[k].N2;

View File

@@ -32,13 +32,13 @@ formatted string S to the report file.
#else
#include <stdlib.h>
#endif
#include <math.h>
#include <time.h>
#include "types.h"
#include "funcs.h"
#include "hash.h"
#include "text.h"
#include "types.h"
#include <math.h>
#include <time.h>
#undef WINDOWS
#ifdef _WIN32
@@ -692,7 +692,7 @@ void writelinktable(EN_Project *pr, Pfloat *x)
}
/* Note if link is a pump or valve */
if ((j = Link[i].Type) > EN_PIPE) {
if ((j = Link[i].Type) > PIPE) {
strcat(s, " ");
strcat(s, LinkTxt[j]);
}
@@ -909,12 +909,12 @@ void writestatchange(EN_Project *pr, int k, char s1, char s2)
setting = LinkSetting[k]; // Link[k].Kc;
switch (Link[k].Type) {
case EN_PRV:
case EN_PSV:
case EN_PBV:
case PRV:
case PSV:
case PBV:
setting *= Ucf[PRESSURE];
break;
case EN_FCV:
case FCV:
setting *= Ucf[FLOW];
default:
break;
@@ -1243,9 +1243,9 @@ void marknodes(EN_Project *pr, int m, int *nodelist, char *marked)
/* Check if valve connection is in correct direction */
switch (net->Link[k].Type) {
case EN_CVPIPE:
case EN_PRV:
case EN_PSV:
case CVPIPE:
case PRV:
case PSV:
if (j == net->Link[k].N1) {
continue;
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@ AUTHOR: L. Rossman
#ifndef TYPES_H
#define TYPES_H
#include "epanet2.h"
//#include "epanet2.h"
#include "hash.h"
#include "util/errormanager.h"
#include <stdio.h>
@@ -103,7 +103,7 @@ typedef int INT4;
---------------------------------------------------------------------
*/
#define MEMCHECK(x) (((x) == NULL) ? 101 : 0 )
#define FREE(x) if ((x)) free((x))
#define FREE(x) do { free(x); (x) = NULL; } while(0)
/*
---------------------------------------------------------------------
@@ -130,25 +130,47 @@ typedef int INT4;
*/
#define ERRCODE(x) (errcode = ((errcode>100) ? (errcode) : (x)))
/*
----------------------------------------------
Global Enumeration Types
----------------------------------------------
*/
typedef enum {
NODE = 0,
LINK = 1
} ObjectType;
typedef enum {
JUNCTION = 0,
RESERVOIR = 1,
TANK = 2
} NodeType;
typedef enum {
CVPIPE = 0,
PIPE = 1,
PUMP = 2,
PRV = 3,
PSV = 4,
PBV = 5,
FCV = 6,
TCV = 7,
GPV = 8
} LinkType;
typedef enum {
USE, /* use from previous run */
SAVE, /* save after current run */
SCRATCH
} Hydtype; /* use temporary file */
SCRATCH /* use temporary file */
} HydFiletype;
typedef enum {
NONE, /* no quality analysis */
CHEM, /* analyze a chemical */
AGE, /* analyze water age */
TRACE
} QualType; /* trace % of flow from a source */
TRACE /* trace % of flow from a source */
} QualType;
typedef enum {
V_CURVE, /* volume curve */
@@ -169,8 +191,8 @@ typedef enum {
CONCEN, /* inflow concentration */
MASS, /* mass inflow booster */
SETPOINT, /* setpoint booster */
FLOWPACED
} SourceType; /* flow paced booster */
FLOWPACED /* flow paced booster */
} SourceType;
typedef enum {
LOWLEVEL, /* act when grade below set level */
@@ -189,14 +211,14 @@ typedef enum {
XFCV, /* FCV cannot supply flow */
XPRESSURE, /* valve cannot supply pressure */
FILLING, /* tank filling */
EMPTYING
} StatType; /* tank emptying */
EMPTYING /* tank emptying */
} StatType;
typedef enum {
HW, /* Hazen-Williams */
DW, /* Darcy-Weisbach */
CM /* Chezy-Manning */
} FormType;
} HeadLossType;
typedef enum {
US, /* US */
@@ -398,7 +420,7 @@ typedef struct /* NODE OBJECT */
double C0; /* Initial quality */
double Ke; /* Emitter coeff. */
char Rpt; /* Reporting flag */
EN_NodeType Type; /* Node Type */
NodeType Type; /* Node Type */
char Comment[MAXMSG+1]; /* Node Comment */
} Snode;
@@ -416,7 +438,7 @@ typedef struct /* LINK OBJECT */
double R; /* Flow resistance */
double Rc; /* Reaction coeff. */
double Qa; // Low flow limit
EN_LinkType Type; /* Link type */
LinkType Type; // Link type */
StatType Stat; /* Initial status */
char Rpt; /* Reporting flag */
char Comment[MAXMSG+1]; /* Link Comment */
@@ -514,7 +536,7 @@ typedef struct s_Premise /* Rule Premise Clause */
int status; /* Variable's status */
double value; /* Variable's value */
struct s_Premise *next;
} Premise;
} Spremise;
typedef struct s_Action /* Rule Action Clause */
{
@@ -522,24 +544,23 @@ typedef struct s_Action /* Rule Action Clause */
int status; /* Link's status */
double setting; /* Link's setting */
struct s_Action *next;
} Action;
} Saction;
typedef struct s_aRule /* Control Rule Structure */
typedef struct /* Control Rule Structure */
{
char label[MAXID+1]; /* Rule character label */
char label[MAXID+1]; /* Rule label */
double priority; /* Priority level */
Premise *Pchain; /* Linked list of premises */
Action *Tchain; /* Linked list of actions if true */
Action *Fchain; /* Linked list of actions if false */
//struct s_aRule *next;
} aRule;
Spremise *Premises; /* Linked list of premises */
Saction *ThenActions; /* Linked list of THEN actions */
Saction *ElseActions; /* Linked list of ELSE actions */
} Srule;
typedef struct s_ActItem /* Action list item */
typedef struct s_ActionItem /* Action list item */
{
int ruleindex; /* Index of rule action belongs to */
struct s_Action *action; /* An action structure */
struct s_ActItem *next;
} ActItem;
int ruleIndex; /* Index of rule action belongs to */
Saction *action; /* An action structure */
struct s_ActionItem *next;
} SactionList;
typedef struct
{
@@ -707,12 +728,9 @@ typedef struct {
char
HydFname[MAXFNAME+1], /* Hydraulics file name */
OutFname[MAXFNAME+1], /* Binary output file name */
TmpFname[MAXFNAME+1], /* Temporary file name */
TmpDir[MAXFNAME+1], /* Temporary directory name */
Outflag, /* Output file flag */
Hydflag; /* Hydraulics flag */
long
HydOffset, /* Hydraulics file byte offset */
OutOffset1, /* 1st output file byte offset */
@@ -734,18 +752,6 @@ typedef struct {
} save_options_t;
typedef struct {
aRule *Rule; /* Array of rules */
ActItem *ActList; /* Linked list of action items */
int RuleState; /* State of rule interpreter */
long Time1; /* Start of rule evaluation time interval (sec) */
Premise *Plast; /* Previous premise clause */
Action *Tlast; /* Previous true action */
Action *Flast; /* Previous false action */
} rules_t;
/*
** NOTE: Hydraulic analysis of the pipe network at a given point in time
** is done by repeatedly solving a linearized version of the
@@ -851,6 +857,16 @@ typedef struct {
} hydraulics_t;
typedef struct {
SactionList *ActionList; /* Linked list of action items */
int RuleState; /* State of rule interpreter */
int Errcode; // Rule parser error code
long Time1; /* Start of rule evaluation time interval (sec) */
Spremise *LastPremise; /* Previous premise clause */
Saction *LastThenAction; /* Previous THEN action */
Saction *LastElseAction; /* Previous ELSE action */
} rules_t;
typedef struct {
int Nnodes, /* Number of network nodes */
Ntanks, /* Number of tanks */
@@ -863,17 +879,18 @@ typedef struct {
Nrules, /* Number of control rules */
Npats, /* Number of time patterns */
Ncurves, /* Number of data curves */
Ncoords; /* Number of Coords */
Ncoords; /* Number of node coordinates */
Snode *Node; /* Node data */
Slink *Link; /* Link data */
Stank *Tank; /* Tank data */
Spump *Pump; /* Pump data */
Svalve *Valve; /* Valve data */
Spattern *Pattern; /* Time patterns */
Scurve *Curve; /* Curve data */
Scoord *Coord; /* Coordinate data */
Scontrol *Control; /* Control data */
Snode *Node; /* Node array */
Slink *Link; /* Link array */
Stank *Tank; /* Tank array */
Spump *Pump; /* Pump array */
Svalve *Valve; /* Valve array */
Spattern *Pattern; /* Time pattern array */
Scurve *Curve; /* Data curve array */
Scoord *Coord; /* Node coordinate array */
Scontrol *Control; /* Simple controls array */
Srule *Rule; /* Rule-based controls array */
HashTable
*NodeHashTable,
*LinkHashTable; /* Hash tables for ID labels */
@@ -896,18 +913,21 @@ typedef struct EN_Project {
out_file_t out_files;
save_options_t save_options;
double Ucf[MAXVAR];
double Ucf[MAXVAR]; // Unit conversion factors
char
Openflag, /// Toolkit open flag
Warnflag, /// Warning flag
Msg[MAXMSG+1], /// General-purpose string: errors, messages
Title[MAXTITLE][TITLELEN+1],/// Project title
MapFname[MAXFNAME+1]; /// Map file name
Openflag, // Toolkit open flag
Warnflag, // Warning flag
Msg[MAXMSG+1], // General-purpose string: errors, messages
Title[MAXTITLE][TITLELEN+1], // Project title
MapFname[MAXFNAME+1], // Map file name
TmpHydFname[MAXFNAME+1], // Temporary hydraulics file name
TmpOutFname[MAXFNAME+1], // Temporary output file name
TmpStatFname[MAXFNAME+1]; // Temporary statistic file name
error_handle_t* error_handle; //Simple error manager
error_handle_t* error_handle; // Simple error manager
void (* viewprog) (char *); /* Pointer to progress viewing function */
void (* viewprog) (char *); // Pointer to progress viewing function
} EN_Project;