Initial commit
This commit is contained in:
966
src/input2.c
Normal file
966
src/input2.c
Normal file
@@ -0,0 +1,966 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
|
||||
INPUT2.C -- Input data file interpreter for EPANET
|
||||
|
||||
VERSION: 2.00
|
||||
DATE: 5/30/00
|
||||
9/7/00
|
||||
10/25/00
|
||||
AUTHOR: L. Rossman
|
||||
US EPA - NRMRL
|
||||
|
||||
This module reads and interprets the input data from file InFile.
|
||||
|
||||
The entry points for this module are:
|
||||
netsize() -- called from ENopen() in EPANET.C
|
||||
readdata() -- called from getdata() in INPUT1.C
|
||||
|
||||
The following utility functions are all called from INPUT3.C
|
||||
addnodeID()
|
||||
addlinkID()
|
||||
findID()
|
||||
getfloat()
|
||||
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include "hash.h"
|
||||
#include "text.h"
|
||||
#include "types.h"
|
||||
#include "funcs.h"
|
||||
#define EXTERN extern
|
||||
#include "vars.h"
|
||||
|
||||
#define MAXERRS 10 /* Max. input errors reported */
|
||||
|
||||
int Ntokens, /* Number of tokens in input line */
|
||||
Ntitle; /* Number of title lines */
|
||||
char *Tok[MAXTOKS]; /* Array of token strings */
|
||||
|
||||
/* Used in INPUT3.C: */
|
||||
STmplist *PrevPat; /* Pointer to pattern list element */
|
||||
STmplist *PrevCurve; /* Pointer to curve list element */
|
||||
|
||||
/* Defined in enumstxt.h in EPANET.C */
|
||||
extern char *SectTxt[]; /* Input section keywords */
|
||||
extern char *RptSectTxt[];
|
||||
|
||||
|
||||
int netsize()
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: determines number of system components
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
char line[MAXLINE+1]; /* Line from input data file */
|
||||
char *tok; /* First token of line */
|
||||
int sect,newsect; /* Input data sections */
|
||||
int errcode = 0; /* Error code */
|
||||
|
||||
/* Initialize network component counts */
|
||||
MaxJuncs = 0;
|
||||
MaxTanks = 0;
|
||||
MaxPipes = 0;
|
||||
MaxPumps = 0;
|
||||
MaxValves = 0;
|
||||
MaxControls = 0;
|
||||
MaxRules = 0;
|
||||
MaxCurves = 0;
|
||||
sect = -1;
|
||||
|
||||
/* Add a default pattern 0 */
|
||||
MaxPats = -1;
|
||||
addpattern("");
|
||||
|
||||
/* Make pass through data file counting number of each component */
|
||||
while (fgets(line,MAXLINE,InFile) != NULL)
|
||||
{
|
||||
/* Skip blank lines & those beginning with a comment */
|
||||
tok = strtok(line,SEPSTR);
|
||||
if (tok == NULL) continue;
|
||||
if (*tok == ';') continue;
|
||||
|
||||
/* Check if line begins with a new section heading */
|
||||
if (*tok == '[')
|
||||
{
|
||||
newsect = findmatch(tok,SectTxt);
|
||||
if (newsect >= 0)
|
||||
{
|
||||
sect = newsect;
|
||||
if (sect == _END) break;
|
||||
continue;
|
||||
}
|
||||
else continue;
|
||||
}
|
||||
|
||||
/* Add to count of current component */
|
||||
switch(sect)
|
||||
{
|
||||
case _JUNCTIONS: MaxJuncs++; break;
|
||||
case _RESERVOIRS:
|
||||
case _TANKS: MaxTanks++; break;
|
||||
case _PIPES: MaxPipes++; break;
|
||||
case _PUMPS: MaxPumps++; break;
|
||||
case _VALVES: MaxValves++; break;
|
||||
case _CONTROLS: MaxControls++; break;
|
||||
case _RULES: addrule(tok); break; /* See RULES.C */
|
||||
case _PATTERNS: errcode = addpattern(tok);
|
||||
break;
|
||||
case _CURVES: errcode = addcurve(tok);
|
||||
break;
|
||||
}
|
||||
if (errcode) break;
|
||||
}
|
||||
|
||||
MaxNodes = MaxJuncs + MaxTanks;
|
||||
MaxLinks = MaxPipes + MaxPumps + MaxValves;
|
||||
if (MaxPats < 1) MaxPats = 1;
|
||||
if (!errcode)
|
||||
{
|
||||
if (MaxJuncs < 1) errcode = 223; /* Not enough nodes */
|
||||
else if (MaxTanks == 0) errcode = 224; /* No tanks */
|
||||
}
|
||||
return(errcode);
|
||||
} /* End of netsize */
|
||||
|
||||
|
||||
int readdata()
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: reads contents of input data file
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
char line[MAXLINE+1], /* Line from input data file */
|
||||
wline[MAXLINE+1]; /* Working copy of input line */
|
||||
int sect,newsect, /* Data sections */
|
||||
errcode = 0, /* Error code */
|
||||
inperr,errsum; /* Error code & total error count */
|
||||
|
||||
/* Allocate input buffer */
|
||||
X = (double *) calloc(MAXTOKS, sizeof(double));
|
||||
ERRCODE(MEMCHECK(X));
|
||||
|
||||
if (!errcode)
|
||||
{
|
||||
|
||||
/* Initialize number of network components */
|
||||
Ntitle = 0;
|
||||
Nnodes = 0;
|
||||
Njuncs = 0;
|
||||
Ntanks = 0;
|
||||
Nlinks = 0;
|
||||
Npipes = 0;
|
||||
Npumps = 0;
|
||||
Nvalves = 0;
|
||||
Ncontrols = 0;
|
||||
Nrules = 0;
|
||||
Ncurves = MaxCurves;
|
||||
Npats = MaxPats;
|
||||
PrevPat = NULL;
|
||||
PrevCurve = NULL;
|
||||
sect = -1;
|
||||
errsum = 0;
|
||||
|
||||
/* Read each line from input file. */
|
||||
while (fgets(line,MAXLINE,InFile) != NULL)
|
||||
{
|
||||
|
||||
/* Make copy of line and scan for tokens */
|
||||
strcpy(wline,line);
|
||||
Ntokens = gettokens(wline);
|
||||
|
||||
/* Skip blank lines and comments */
|
||||
if (Ntokens == 0) continue;
|
||||
if (*Tok[0] == ';') continue;
|
||||
|
||||
/* Check if max. length exceeded */
|
||||
if (strlen(line) >= MAXLINE)
|
||||
{
|
||||
sprintf(Msg,ERR214);
|
||||
writeline(Msg);
|
||||
writeline(line);
|
||||
errsum++;
|
||||
}
|
||||
|
||||
/* Check if at start of a new input section */
|
||||
if (*Tok[0] == '[')
|
||||
{
|
||||
newsect = findmatch(Tok[0],SectTxt);
|
||||
if (newsect >= 0)
|
||||
{
|
||||
sect = newsect;
|
||||
if (sect == _END) break;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
inperrmsg(201,sect,line);
|
||||
errsum++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise process next line of input in current section */
|
||||
else
|
||||
{
|
||||
inperr = newline(sect,line);
|
||||
if (inperr > 0)
|
||||
{
|
||||
inperrmsg(inperr,sect,line);
|
||||
errsum++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop if reach end of file or max. error count */
|
||||
if (errsum == MAXERRS) break;
|
||||
} /* End of while */
|
||||
|
||||
/* Check for errors */
|
||||
if (errsum > 0) errcode = 200;
|
||||
}
|
||||
|
||||
/* Check for unlinked nodes */
|
||||
if (!errcode) errcode = unlinked();
|
||||
|
||||
/* Get pattern & curve data from temp. lists */
|
||||
if (!errcode) errcode = getpatterns();
|
||||
if (!errcode) errcode = getcurves();
|
||||
if (!errcode) errcode = getpumpparams();
|
||||
|
||||
/* Free input buffer */
|
||||
free(X);
|
||||
return(errcode);
|
||||
|
||||
} /* End of readdata */
|
||||
|
||||
|
||||
int newline(int sect, char *line)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: sect = current section of input file
|
||||
** *line = line read from input file
|
||||
** Output: returns error code or 0 if no error found
|
||||
** Purpose: processes a new line of data from input file
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int n;
|
||||
switch (sect)
|
||||
{
|
||||
case _TITLE: if (Ntitle < 3)
|
||||
{
|
||||
n = strlen(line);
|
||||
if (line[n-1] == 10) line[n-1] = ' ';
|
||||
strncpy(Title[Ntitle],line,MAXMSG);
|
||||
Ntitle++;
|
||||
}
|
||||
return(0);
|
||||
case _JUNCTIONS: return(juncdata());
|
||||
case _RESERVOIRS:
|
||||
case _TANKS: return(tankdata());
|
||||
case _PIPES: return(pipedata());
|
||||
case _PUMPS: return(pumpdata());
|
||||
case _VALVES: return(valvedata());
|
||||
case _PATTERNS: return(patterndata());
|
||||
case _CURVES: return(curvedata());
|
||||
case _DEMANDS: return(demanddata());
|
||||
case _CONTROLS: return(controldata());
|
||||
case _RULES: return(ruledata()); /* See RULES.C */
|
||||
case _SOURCES: return(sourcedata());
|
||||
case _EMITTERS: return(emitterdata());
|
||||
case _QUALITY: return(qualdata());
|
||||
case _STATUS: return(statusdata());
|
||||
case _ROUGHNESS: return(0);
|
||||
case _ENERGY: return(energydata());
|
||||
case _REACTIONS: return(reactdata());
|
||||
case _MIXING: return(mixingdata());
|
||||
case _REPORT: return(reportdata());
|
||||
case _TIMES: return(timedata());
|
||||
case _OPTIONS: return(optiondata());
|
||||
|
||||
/* Data in these sections are not used for any computations */
|
||||
case _COORDS: return(0);
|
||||
case _LABELS: return(0);
|
||||
case _TAGS: return(0);
|
||||
case _VERTICES: return(0);
|
||||
case _BACKDROP: return(0);
|
||||
}
|
||||
return(201);
|
||||
} /* end of newline */
|
||||
|
||||
|
||||
int getpumpparams(void)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: computes & checks pump curve parameters
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
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;
|
||||
|
||||
for (i=1; i<=Npumps; i++)
|
||||
{
|
||||
k = Pump[i].Link;
|
||||
if (Pump[i].Ptype == CONST_HP) /* Constant Hp pump */
|
||||
{
|
||||
Pump[i].H0 = 0.0;
|
||||
Pump[i].R = -8.814*Link[k].Km;
|
||||
Pump[i].N = -1.0;
|
||||
Pump[i].Hmax = BIG; /* No head limit */
|
||||
Pump[i].Qmax = BIG; /* No flow limit */
|
||||
Pump[i].Q0 = 1.0; /* Init. flow = 1 cfs */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set parameters for pump curves */
|
||||
else if (Pump[i].Ptype == NOCURVE) /* Pump curve specified */
|
||||
{
|
||||
j = Pump[i].Hcurve; /* Get index of head curve */
|
||||
if (j == 0)
|
||||
{ /* Error: No head curve */
|
||||
sprintf(Msg,ERR226,Link[k].ID);
|
||||
writeline(Msg);
|
||||
return(200);
|
||||
}
|
||||
n = Curve[j].Npts;
|
||||
if (n == 1) /* Only a single h-q point */
|
||||
{ /* supplied so use generic */
|
||||
Pump[i].Ptype = POWER_FUNC; /* power function curve. */
|
||||
q1 = Curve[j].X[0];
|
||||
h1 = Curve[j].Y[0];
|
||||
h0 = 1.33334*h1;
|
||||
q2 = 2.0*q1;
|
||||
h2 = 0.0;
|
||||
}
|
||||
else if (n == 3
|
||||
&& Curve[j].X[0] == 0.0) /* 3 h-q points supplied with */
|
||||
{ /* shutoff head so use fitted */
|
||||
Pump[i].Ptype = POWER_FUNC; /* power function curve. */
|
||||
h0 = Curve[j].Y[0];
|
||||
q1 = Curve[j].X[1];
|
||||
h1 = Curve[j].Y[1];
|
||||
q2 = Curve[j].X[2];
|
||||
h2 = Curve[j].Y[2];
|
||||
}
|
||||
else Pump[i].Ptype = CUSTOM; /* Else use custom pump curve.*/
|
||||
|
||||
/* Compute shape factors & limits of power function pump curves */
|
||||
if (Pump[i].Ptype == POWER_FUNC)
|
||||
{
|
||||
if (!powercurve(h0,h1,h2,q1,q2,&a,&b,&c))
|
||||
{ /* Error: Invalid curve */
|
||||
sprintf(Msg,ERR227,Link[k].ID);
|
||||
writeline(Msg);
|
||||
return(200);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pump[i].H0 = -a;
|
||||
Pump[i].R = -b;
|
||||
Pump[i].N = c;
|
||||
Pump[i].Q0 = q1;
|
||||
Pump[i].Qmax = pow((-a/b),(1.0/c));
|
||||
Pump[i].Hmax = h0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign limits to custom pump curves */
|
||||
if (Pump[i].Ptype == CUSTOM)
|
||||
{
|
||||
for (m=1; m<n; m++)
|
||||
{
|
||||
if (Curve[j].Y[m] >= Curve[j].Y[m-1])
|
||||
{ /* Error: Invalid curve */
|
||||
sprintf(Msg,ERR227,Link[k].ID);
|
||||
writeline(Msg);
|
||||
return(200);
|
||||
}
|
||||
}
|
||||
Pump[i].Qmax = Curve[j].X[n-1];
|
||||
Pump[i].Q0 = (Curve[j].X[0] + Pump[i].Qmax)/2.0;
|
||||
Pump[i].Hmax = Curve[j].Y[0];
|
||||
}
|
||||
} /* Next pump */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int addnodeID(int n, char *id)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: n = node index
|
||||
** id = ID label
|
||||
** Output: returns 0 if ID already in use, 1 if not
|
||||
** Purpose: adds a node ID to the Node Hash Table
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
if (findnode(id)) return(0); /* see EPANET.C */
|
||||
strncpy(Node[n].ID, id, MAXID);
|
||||
HTinsert(Nht, Node[n].ID, n); /* see HASH.C */
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int addlinkID(int n, char *id)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: n = link index
|
||||
** id = ID label
|
||||
** Output: returns 0 if ID already in use, 1 if not
|
||||
** Purpose: adds a link ID to the Link Hash Table
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
if (findlink(id)) return(0); /* see EPANET.C */
|
||||
strncpy(Link[n].ID, id, MAXID);
|
||||
HTinsert(Lht, Link[n].ID, n); /* see HASH.C */
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int addpattern(char *id)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: id = pattern ID label
|
||||
** Output: returns error code
|
||||
** Purpose: adds a new pattern to the database
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
STmplist *p;
|
||||
|
||||
/* Check if ID is same as last one processed */
|
||||
if (Patlist != NULL && strcmp(id,Patlist->ID) == 0) return(0);
|
||||
|
||||
/* Check that pattern was not already created */
|
||||
if (findID(id,Patlist) == NULL)
|
||||
{
|
||||
|
||||
/* Update pattern count & create new list element */
|
||||
(MaxPats)++;
|
||||
p = (STmplist *) malloc(sizeof(STmplist));
|
||||
if (p == NULL) return(101);
|
||||
|
||||
/* Initialize list element properties */
|
||||
else
|
||||
{
|
||||
p->i = MaxPats;
|
||||
strncpy(p->ID,id,MAXID);
|
||||
p->x = NULL;
|
||||
p->y = NULL;
|
||||
p->next = Patlist;
|
||||
Patlist = p;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int addcurve(char *id)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: id = curve ID label
|
||||
** Output: returns error code
|
||||
** Purpose: adds a new curve to the database
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
STmplist *c;
|
||||
|
||||
/* Check if ID is same as last one processed */
|
||||
if (Curvelist != NULL && strcmp(id,Curvelist->ID) == 0) return(0);
|
||||
|
||||
/* Check that curve was not already created */
|
||||
if (findID(id,Curvelist) == NULL)
|
||||
{
|
||||
|
||||
/* Update curve count & create new list element */
|
||||
(MaxCurves)++;
|
||||
c = (STmplist *) malloc(sizeof(STmplist));
|
||||
if (c == NULL) return(101);
|
||||
|
||||
/* Initialize list element properties */
|
||||
else
|
||||
{
|
||||
c->i = MaxCurves;
|
||||
strncpy(c->ID,id,MAXID);
|
||||
c->x = NULL;
|
||||
c->y = NULL;
|
||||
c->next = Curvelist;
|
||||
Curvelist = c;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
STmplist *findID(char *id, STmplist *list)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: id = ID label
|
||||
** list = pointer to head of a temporary list
|
||||
** Output: returns list item with requested ID label
|
||||
** Purpose: searches for item in temporary list
|
||||
**-------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
STmplist *item;
|
||||
for (item = list; item != NULL; item = item->next)
|
||||
{
|
||||
if (strcmp(item->ID,id) == 0)
|
||||
{
|
||||
return(item);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
int unlinked()
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code if any unlinked junctions found
|
||||
** Purpose: checks for unlinked junctions in network
|
||||
**
|
||||
** NOTE: unlinked tanks have no effect on computations.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
char *marked;
|
||||
int i,err, errcode;
|
||||
errcode = 0;
|
||||
err = 0;
|
||||
marked = (char *) calloc(Nnodes+1,sizeof(char));
|
||||
ERRCODE(MEMCHECK(marked));
|
||||
if (!errcode)
|
||||
{
|
||||
memset(marked,0,(Nnodes+1)*sizeof(char));
|
||||
for (i=1; i<=Nlinks; i++) /* Mark end nodes of each link */
|
||||
{
|
||||
marked[Link[i].N1]++;
|
||||
marked[Link[i].N2]++;
|
||||
}
|
||||
for (i=1; i<=Njuncs; i++) /* Check each junction */
|
||||
{
|
||||
if (marked[i] == 0) /* If not marked then error */
|
||||
{
|
||||
err++;
|
||||
sprintf(Msg,ERR233,Node[i].ID);
|
||||
writeline(Msg);
|
||||
}
|
||||
if (err >= MAXERRS) break;
|
||||
}
|
||||
if (err > 0) errcode = 200;
|
||||
}
|
||||
free(marked);
|
||||
return(errcode);
|
||||
} /* End of unlinked */
|
||||
|
||||
|
||||
int getpatterns(void)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: retrieves pattern data from temporary linked list
|
||||
**-------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i,j;
|
||||
SFloatlist *f;
|
||||
STmplist *pat;
|
||||
|
||||
/* Start at head of list */
|
||||
pat = Patlist;
|
||||
|
||||
/* Traverse list of patterns */
|
||||
while (pat != NULL)
|
||||
{
|
||||
|
||||
/* Get index of current pattern in Pattern array */
|
||||
i = pat->i;
|
||||
|
||||
/* Check if this is the default pattern */
|
||||
if (strcmp(pat->ID, DefPatID) == 0) DefPat = i;
|
||||
if (i >= 0 && i <= MaxPats)
|
||||
{
|
||||
/* Save pattern ID */
|
||||
strcpy(Pattern[i].ID, pat->ID);
|
||||
|
||||
/* Give pattern a length of at least 1 */
|
||||
if (Pattern[i].Length == 0) Pattern[i].Length = 1;
|
||||
Pattern[i].F = (double *) calloc(Pattern[i].Length, sizeof(double));
|
||||
if (Pattern[i].F == NULL) return(101);
|
||||
|
||||
/* Start at head of pattern multiplier list */
|
||||
/* (which holds multipliers in reverse order)*/
|
||||
f = pat->x;
|
||||
j = Pattern[i].Length - 1;
|
||||
|
||||
/* Use at least one multiplier equal to 1.0 */
|
||||
if (f == NULL) Pattern[i].F[0] = 1.0;
|
||||
|
||||
/* Traverse list, storing multipliers in Pattern array */
|
||||
else while (f != NULL && j >= 0)
|
||||
{
|
||||
Pattern[i].F[j] = f->value;
|
||||
f = f->next;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
pat = pat->next;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int getcurves(void)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: retrieves curve data from temporary linked list
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i,j;
|
||||
double x;
|
||||
SFloatlist *fx, *fy;
|
||||
STmplist *c;
|
||||
|
||||
/* Start at head of curve list */
|
||||
c = Curvelist;
|
||||
|
||||
/* Traverse list of curves */
|
||||
while (c != NULL)
|
||||
{
|
||||
i = c->i;
|
||||
if (i >= 1 && i <= MaxCurves)
|
||||
{
|
||||
|
||||
/* Save curve ID */
|
||||
strcpy(Curve[i].ID, c->ID);
|
||||
|
||||
/* Check that curve has data points */
|
||||
if (Curve[i].Npts <= 0)
|
||||
{
|
||||
sprintf(Msg,ERR230,c->ID);
|
||||
writeline(Msg);
|
||||
return(200);
|
||||
}
|
||||
|
||||
/* Allocate memory for curve data */
|
||||
Curve[i].X = (double *) calloc(Curve[i].Npts, sizeof(double));
|
||||
Curve[i].Y = (double *) calloc(Curve[i].Npts, sizeof(double));
|
||||
if (Curve[i].X == NULL || Curve[i].Y == NULL) return(101);
|
||||
|
||||
/* Traverse list of x,y data */
|
||||
x = BIG;
|
||||
fx = c->x;
|
||||
fy = c->y;
|
||||
j = Curve[i].Npts - 1;
|
||||
while (fx != NULL && fy != NULL && j >= 0)
|
||||
{
|
||||
|
||||
/* Check that x data is in ascending order */
|
||||
if (fx->value >= x)
|
||||
{
|
||||
sprintf(Msg,ERR230,c->ID);
|
||||
writeline(Msg);
|
||||
return(200);
|
||||
}
|
||||
x = fx->value;
|
||||
|
||||
/* Save x,y data in Curve structure */
|
||||
Curve[i].X[j] = fx->value;
|
||||
fx = fx->next;
|
||||
Curve[i].Y[j] = fy->value;
|
||||
fy = fy->next;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int findmatch(char *line, char *keyword[])
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: *line = line from input file
|
||||
** *keyword[] = list of NULL terminated keywords
|
||||
** Output: returns index of matching keyword or
|
||||
** -1 if no match found
|
||||
** Purpose: determines which keyword appears on input line
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i = 0;
|
||||
while (keyword[i] != NULL)
|
||||
{
|
||||
if (match(line,keyword[i])) return(i);
|
||||
i++;
|
||||
}
|
||||
return(-1);
|
||||
} /* end of findmatch */
|
||||
|
||||
|
||||
|
||||
int match(char *str, char *substr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: *str = string being searched
|
||||
** *substr = substring being searched for
|
||||
** Output: returns 1 if substr found in str, 0 if not
|
||||
** Purpose: sees if substr matches any part of str
|
||||
**
|
||||
** (Not case sensitive)
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i,j;
|
||||
|
||||
/*** Updated 9/7/00 ***/
|
||||
/* Fail if substring is empty */
|
||||
if (!substr[0]) return(0);
|
||||
|
||||
/* Skip leading blanks of str. */
|
||||
for (i=0; str[i]; i++)
|
||||
if (str[i] != ' ') break;
|
||||
|
||||
/* Check if substr matches remainder of str. */
|
||||
for (i=i,j=0; substr[j]; i++,j++)
|
||||
if (!str[i] || UCHAR(str[i]) != UCHAR(substr[j]))
|
||||
return(0);
|
||||
return(1);
|
||||
} /* end of match */
|
||||
|
||||
|
||||
/*** Updated 10/25/00 ***/
|
||||
/* The gettokens function has been totally re-written. */
|
||||
|
||||
int gettokens(char *s)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: *s = string to be tokenized
|
||||
** Output: returns number of tokens in s
|
||||
** Purpose: scans string for tokens, saving pointers to them
|
||||
** in module global variable Tok[]
|
||||
**
|
||||
** Tokens can be separated by the characters listed in SEPSTR
|
||||
** (spaces, tabs, newline, carriage return) which is defined
|
||||
** in TYPES.H. Text between quotes is treated as a single token.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int len, m, n;
|
||||
char *c;
|
||||
|
||||
/* Begin with no tokens */
|
||||
for (n=0; n<MAXTOKS; n++) Tok[n] = NULL;
|
||||
n = 0;
|
||||
|
||||
/* Truncate s at start of comment */
|
||||
c = strchr(s,';');
|
||||
if (c) *c = '\0';
|
||||
len = strlen(s);
|
||||
|
||||
/* Scan s for tokens until nothing left */
|
||||
while (len > 0 && n < MAXTOKS)
|
||||
{
|
||||
m = strcspn(s,SEPSTR); /* Find token length */
|
||||
len -= m+1; /* Update length of s */
|
||||
if (m == 0) s++; /* No token found */
|
||||
else
|
||||
{
|
||||
if (*s == '"') /* Token begins with quote */
|
||||
{
|
||||
s++; /* Start token after quote */
|
||||
m = strcspn(s,"\"\n\r"); /* Find end quote (or EOL) */
|
||||
}
|
||||
s[m] = '\0'; /* Null-terminate the token */
|
||||
Tok[n] = s; /* Save pointer to token */
|
||||
n++; /* Update token count */
|
||||
s += m+1; /* Begin next token */
|
||||
}
|
||||
}
|
||||
return(n);
|
||||
} /* End of gettokens */
|
||||
|
||||
|
||||
double hour(char *time, char *units)
|
||||
/*
|
||||
**---------------------------------------------------------
|
||||
** Input: *time = string containing a time value
|
||||
** *units = string containing time units
|
||||
** Output: returns numerical value of time in hours,
|
||||
** or -1 if an error occurs
|
||||
** Purpose: converts time from units to hours
|
||||
**---------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int n;
|
||||
double y[3];
|
||||
char *s;
|
||||
|
||||
/* Separate clock time into hrs, min, sec. */
|
||||
for (n=0; n<3; n++) y[n] = 0.0;
|
||||
n = 0;
|
||||
s = strtok(time,":");
|
||||
while (s != NULL && n <= 3)
|
||||
{
|
||||
if (!getfloat(s,&y[n])) return(-1.0);
|
||||
s = strtok(NULL,":");
|
||||
n++;
|
||||
}
|
||||
|
||||
/* If decimal time with units attached then convert to hours. */
|
||||
if (n == 1)
|
||||
{
|
||||
/*if (units[0] == '\0') return(y[0]);*/
|
||||
if (strlen(units) == 0) return(y[0]);
|
||||
if (match(units,w_SECONDS)) return(y[0]/3600.0);
|
||||
if (match(units,w_MINUTES)) return(y[0]/60.0);
|
||||
if (match(units,w_HOURS)) return(y[0]);
|
||||
if (match(units,w_DAYS)) return(y[0]*24.0);
|
||||
}
|
||||
|
||||
/* Convert hh:mm:ss format to decimal hours */
|
||||
if (n > 1) y[0] = y[0] + y[1]/60.0 + y[2]/3600.0;
|
||||
|
||||
/* If am/pm attached then adjust hour accordingly */
|
||||
/* (12 am is midnight, 12 pm is noon) */
|
||||
if (units[0] == '\0') return(y[0]);
|
||||
if (match(units,w_AM))
|
||||
{
|
||||
if (y[0] >= 13.0) return(-1.0);
|
||||
if (y[0] >= 12.0) return(y[0]-12.0);
|
||||
else return(y[0]);
|
||||
}
|
||||
if (match(units,w_PM))
|
||||
{
|
||||
if (y[0] >= 13.0) return(-1.0);
|
||||
if (y[0] >= 12.0) return(y[0]);
|
||||
else return(y[0]+12.0);
|
||||
}
|
||||
return(-1.0);
|
||||
} /* end of hour */
|
||||
|
||||
|
||||
int getfloat(char *s, double *y)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: *s = character string
|
||||
** Output: *y = floating point number
|
||||
** returns 1 if conversion successful, 0 if not
|
||||
** Purpose: converts string to floating point number
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
char *endptr;
|
||||
*y = (double) strtod(s,&endptr);
|
||||
if (*endptr > 0) return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int setreport(char *s)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: *s = report format command
|
||||
** Output: none
|
||||
** Returns: error code
|
||||
** Purpose: processes a report formatting command
|
||||
** issued by the ENsetreport function
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Ntokens = gettokens(s);
|
||||
return(reportdata());
|
||||
}
|
||||
|
||||
|
||||
void inperrmsg(int err, int sect, char *line)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: err = error code
|
||||
** sect = input data section
|
||||
** *line = line from input file
|
||||
** Output: none
|
||||
** Purpose: displays input error message
|
||||
**-------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
char fmt[MAXMSG+1];
|
||||
char id[MAXMSG+1];
|
||||
|
||||
/* Retrieve ID label of object with input error */
|
||||
/* (No ID used for CONTROLS or REPORT sections).*/
|
||||
if (sect == _CONTROLS || sect == _REPORT) strcpy(id,"");
|
||||
else if (sect == _ENERGY) strcpy(id,Tok[1]);
|
||||
else strcpy(id,Tok[0]);
|
||||
|
||||
/* Copy error messge to string variable fmt */
|
||||
switch (err)
|
||||
{
|
||||
case 201: strcpy(fmt,ERR201); break;
|
||||
case 202: strcpy(fmt,ERR202); break;
|
||||
case 203: strcpy(fmt,ERR203); break;
|
||||
case 204: strcpy(fmt,ERR204); break;
|
||||
case 205: strcpy(fmt,ERR205); break;
|
||||
case 206: strcpy(fmt,ERR206); break;
|
||||
case 207: strcpy(fmt,ERR207); break;
|
||||
case 208: strcpy(fmt,ERR208); break;
|
||||
case 209: strcpy(fmt,ERR209); break;
|
||||
case 210: strcpy(fmt,ERR210); break;
|
||||
case 211: strcpy(fmt,ERR211); break;
|
||||
case 212: strcpy(fmt,ERR212); break;
|
||||
case 213: strcpy(id,"");
|
||||
strcpy(fmt,ERR213); break;
|
||||
case 214: strcpy(id,"");
|
||||
strcpy(fmt,ERR214); break;
|
||||
case 215: strcpy(fmt,ERR215); break;
|
||||
case 216: strcpy(fmt,ERR216); break;
|
||||
case 217: strcpy(fmt,ERR217); break;
|
||||
case 219: strcpy(fmt,ERR219); break;
|
||||
case 220: strcpy(fmt,ERR220); break;
|
||||
|
||||
/*** Updated 10/25/00 ***/
|
||||
case 222: strcpy(fmt,ERR222); break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
||||
/* Write error message to Report file */
|
||||
sprintf(Msg,fmt,RptSectTxt[sect],id);
|
||||
writeline(Msg);
|
||||
|
||||
/* Echo input line for syntax errors, and */
|
||||
/* errors in CONTROLS and OPTIONS sections. */
|
||||
if (sect == _CONTROLS || err == 201 || err == 213) writeline(line);
|
||||
else writeline("");
|
||||
}
|
||||
|
||||
/********************** END OF INPUT2.C ************************/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user