int getVariableIndex(char* s) // // Input: s = name of a process variable or pollutant // Output: returns index of process variable or pollutant // Purpose: finds position of process variable/pollutant in list of names. // { // --- check for a process variable first int k; int m = PVMAX; // PVMAX is number of process variables k = findmatch(s, ProcessVarWords); if ( k >= 0 ) return k; // --- then check for a pollutant concentration k = project_findObject(POLLUT, s); if ( k >= 0 ) return (k + m); // --- finally check for a pollutant removal if ( UCHAR(s[0]) == 'R' && s[1] == '_') { k = project_findObject(POLLUT, s+2); if ( k >= 0 ) return (Nobjects[POLLUT] + k + m); } return -1; }
int treatmnt_readExpression(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads a treatment expression from a tokenized line of input. // { char s[MAXLINE+1]; char* expr; int i, j, k, p; MathExpr* equation; // ptr. to a math. expression //(5.0.010 - LR) // --- retrieve node & pollutant if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); j = project_findObject(NODE, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); p = project_findObject(POLLUT, tok[1]); if ( p < 0 ) return error_setInpError(ERR_NAME, tok[1]); // --- concatenate remaining tokens into a single string strcpy(s, tok[2]); for ( i=3; i<ntoks; i++) { strcat(s, " "); strcat(s, tok[i]); } // --- check treatment type if ( UCHAR(s[0]) == 'R' ) k = 0; else if ( UCHAR(s[0]) == 'C' ) k = 1; else return error_setInpError(ERR_KEYWORD, tok[2]); // --- start treatment expression after equals sign expr = strchr(s, '='); if ( expr == NULL ) return error_setInpError(ERR_KEYWORD, ""); else expr++; // --- create treatment objects at node j if they don't already exist if ( Node[j].treatment == NULL ) { if ( !createTreatment(j) ) return error_setInpError(ERR_MEMORY, ""); } // --- create a parsed expression tree from the string expr // (getVariableIndex is the function that converts a treatment // variable's name into an index number) equation = mathexpr_create(expr, getVariableIndex); if ( equation == NULL ) return error_setInpError(ERR_TREATMENT_EXPR, ""); // --- save the treatment parameters in the node's treatment object Node[j].treatment[p].treatType = k; Node[j].treatment[p].equation = equation; return 0; }
int setActionSetting(char* tok[], int nToks, int* curve, int* tseries, //(5.0.012 - LR) int* attrib, double values[]) //(5.0.012 - LR) // // Input: tok = array of string tokens containing action statement // nToks = number of string tokens // Output: curve = index of controller curve // tseries = index of controller time series // attrib = r_PID if PID controller used //(5.0.012 - LR) // values = values of control settings //(5.0.012 - LR) // returns an error code // Purpose: identifies how control actions settings are determined. // { int k, m; // --- see if control action is determined by a Curve or Time Series if (nToks < 6) return error_setInpError(ERR_ITEMS, ""); k = findmatch(tok[5], SettingTypeWords); if ( k >= 0 && nToks < 7 ) return error_setInpError(ERR_ITEMS, ""); switch (k) { // --- control determined by a curve - find curve index case r_CURVE: m = project_findObject(CURVE, tok[6]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[6]); *curve = m; break; // --- control determined by a time series - find time series index case r_TIMESERIES: m = project_findObject(TSERIES, tok[6]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[6]); *tseries = m; Tseries[m].refersTo = CONTROL; //(5.0.019 - LR) break; // --- control determined by PID controller //(5.0.012 - LR) case r_PID: //(5.0.012 - LR) if (nToks < 9) return error_setInpError(ERR_ITEMS, ""); //(5.0.012 - LR) for (m=6; m<=8; m++) //(5.0.012 - LR) { //(5.0.012 - LR) if ( !getDouble(tok[m], &values[m-6]) ) //(5.0.012 - LR) return error_setInpError(ERR_NUMBER, tok[m]); //(5.0.012 - LR) } //(5.0.012 - LR) *attrib = r_PID; //(5.0.012 - LR) break; //(5.0.012 - LR) // --- direct numerical control is used default: if ( !getDouble(tok[5], &values[0]) ) //(5.0.012 - LR) return error_setInpError(ERR_NUMBER, tok[5]); } return 0; }
int snow_readMeltParams(Project* project, char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads snow melt parameters from a tokenized line of input data. // // Format of data are: // Name SubArea Cmin Cmax Tbase FWF SD0 FW0 SNN0/SD100 // Name REMOVAL SDplow Fout Fimperv Fperv Fimelt Fsubcatch (Subcatch) // { int i, j, k, m, n; double x[7]; if ( ntoks < 8 ) return error_setInpError(ERR_ITEMS, ""); // --- save snow melt parameter set name if not already done so j = project_findObject(project, SNOWMELT, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); if ( project->Snowmelt[j].ID == NULL ) project->Snowmelt[j].ID = project_findID(project, SNOWMELT, tok[0]); // --- identify data keyword k = findmatch(tok[1], SnowmeltWords); if ( k < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]); // --- number of parameters to read n = 7; // 7 for subareas if ( k == SNOW_REMOVAL ) n = 6; // 6 for Removal if ( ntoks < n + 2 ) return error_setInpError(ERR_ITEMS, ""); for (i=0; i<7; i++) x[i] = 0.0; // --- parse each parameter for (i=0; i<n; i++) { if ( ! getDouble(tok[i+2], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[i+2]); } // --- parse name of subcatch receiving snow plowed from current subcatch if ( k == SNOW_REMOVAL ) { x[6] = -1.0; if ( ntoks >= 9 ) { m = project_findObject(project, SUBCATCH, tok[8]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[8]); x[6] = m; } } // --- save snow melt parameters setMeltParams(project, j, k, x); return 0; }
int rdii_readUnitHydParams(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads parameters of an RDII unit hydrograph from a line of input. // { int i, j, m, g; float x[9]; // --- check that RDII UH object exists in database j = project_findObject(UNITHYD, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- assign UH ID to name in hash table if ( UnitHyd[j].ID == NULL ) UnitHyd[j].ID = project_findID(UNITHYD, tok[0]); // --- line has 2 tokens; assign rain gage to UH object if ( ntoks == 2 ) { g = project_findObject(GAGE, tok[1]); if ( g < 0 ) return error_setInpError(ERR_NAME, tok[1]); UnitHyd[j].rainGage = g; return 0; } // --- line has 11 tokens; retrieve & save UH params. if ( ntoks == 11 ) { // --- find which month UH params apply to m = datetime_findMonth(tok[1]); if ( m == 0 ) { if ( !match(tok[1], w_ALL) ) return error_setInpError(ERR_KEYWORD, tok[1]); } // --- read 3 sets of r-t-k values for ( i = 0; i < 9; i++ ) { if ( ! getFloat(tok[i+2], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[i+2]); } // --- save UH params setUnitHydParams(j, m, x); return 0; } else return error_setInpError(ERR_ITEMS, ""); }
int getIfaceFileNodes() // // Input: none // Output: returns an error code // Purpose: reads names of nodes contained on inflows interface file. // { int i; char line[MAXLINE+1]; // line from inflows interface file char s[MAXLINE+1]; // general string variable // --- read number of interface nodes fgets(line, MAXLINE, Finflows.file); sscanf(line, "%d", &NumIfaceNodes); if ( NumIfaceNodes <= 0 ) return ERR_ROUTING_FILE_FORMAT; // --- allocate memory for interface nodes index array IfaceNodes = (int *) calloc(NumIfaceNodes, sizeof(int)); if ( !IfaceNodes ) return ERR_MEMORY; // --- read names of interface nodes from file & save their indexes for ( i=0; i<NumIfaceNodes; i++ ) { if ( feof(Finflows.file) ) return ERR_ROUTING_FILE_FORMAT; fgets(line, MAXLINE, Finflows.file); sscanf(line, "%s", s); IfaceNodes[i] = project_findObject(NODE, s); } // --- skip over column headings line if ( feof(Finflows.file) ) return ERR_ROUTING_FILE_FORMAT; fgets(line, MAXLINE, Finflows.file); return 0; }
int infil_readParams(int m, char* tok[], int ntoks) // // Input: m = infiltration method code // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: sets infiltration parameters from a line of input data. // // Format of data line is: // subcatch p1 p2 ... { int i, j, n, status; double x[5]; // --- check that subcatchment exists j = project_findObject(SUBCATCH, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- number of input tokens depends on infiltration model m if ( m == HORTON ) n = 5; else if ( m == MOD_HORTON ) n = 5; else if ( m == GREEN_AMPT ) n = 4; else if ( m == MOD_GREEN_AMPT ) n = 4; //(5.1.010) else if ( m == CURVE_NUMBER ) n = 4; else return 0; if ( ntoks < n ) return error_setInpError(ERR_ITEMS, ""); // --- parse numerical values from tokens for (i = 0; i < 5; i++) x[i] = 0.0; for (i = 1; i < n; i++) { if ( ! getDouble(tok[i], &x[i-1]) ) return error_setInpError(ERR_NUMBER, tok[i]); } // --- special case for Horton infil. - last parameter is optional if ( (m == HORTON || m == MOD_HORTON) && ntoks > n ) { if ( ! getDouble(tok[n], &x[n-1]) ) return error_setInpError(ERR_NUMBER, tok[n]); } // --- assign parameter values to infil. object Subcatch[j].infil = j; switch (m) { case HORTON: case MOD_HORTON: status = horton_setParams(&HortInfil[j], x); break; case GREEN_AMPT: case MOD_GREEN_AMPT: //(5.1.010) status = grnampt_setParams(&GAInfil[j], x); break; case CURVE_NUMBER: status = curvenum_setParams(&CNInfil[j], x); break; default: status = TRUE; } if ( !status ) return error_setInpError(ERR_NUMBER, ""); return 0; }
int project_addObject(int type, char *id, int n) // // Input: type = object type // id = object ID string // n = object index // Output: returns 0 if object already added, 1 if not, -1 if hashing fails // Purpose: adds an object ID to a hash table // { int result; int len; char *newID; // --- do nothing if object already placed in hash table if ( project_findObject(type, id) >= 0 ) return 0; // --- use memory from the hash tables' common memory pool to store // a copy of the object's ID string len = strlen(id) + 1; newID = (char *) Alloc(len*sizeof(char)); strcpy(newID, id); // --- insert object's ID into the hash table for that type of object result = HTinsert(Htable[type], newID, n); if ( result == 0 ) result = -1; return result; }
int readGageSeriesFormat(char* tok[], int ntoks, double x[]) { int m, ts; DateTime aTime; if ( ntoks < 6 ) return error_setInpError(ERR_ITEMS, ""); // --- determine type of rain data m = findmatch(tok[1], RainTypeWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]); x[1] = (double)m; // --- get data time interval & convert to seconds if ( getDouble(tok[2], &x[2]) ) x[2] = floor(x[2]*3600 + 0.5); else if ( datetime_strToTime(tok[2], &aTime) ) { x[2] = floor(aTime*SECperDAY + 0.5); } else return error_setInpError(ERR_DATETIME, tok[2]); if ( x[2] <= 0.0 ) return error_setInpError(ERR_DATETIME, tok[2]); // --- get snow catch deficiency factor if ( !getDouble(tok[3], &x[3]) ) return error_setInpError(ERR_DATETIME, tok[3]);; // --- get time series index ts = project_findObject(TSERIES, tok[5]); if ( ts < 0 ) return error_setInpError(ERR_NAME, tok[5]); x[0] = (double)ts; strcpy(tok[2], ""); return 0; }
int readRdiiFileHeader() // // Input: none // Output: returns error code // Purpose: reads header information from RDII file. // { int i; char line[MAXLINE+1]; // line from RDII data file char s1[MAXLINE+1]; // general string variable char s2[MAXLINE+1]; // --- check for correct file type fgets(line, MAXLINE, Frdii.file); sscanf(line, "%s", s1); if ( strcmp(s1, "SWMM5") != 0 ) return ERR_RDII_FILE_FORMAT; // --- skip title line fgets(line, MAXLINE, Frdii.file); // --- read RDII UH time step interval (sec) RdiiStep = 0; fgets(line, MAXLINE, Frdii.file); sscanf(line, "%d", &RdiiStep); if ( RdiiStep <= 0 ) return ERR_RDII_FILE_FORMAT; // --- skip over line with number of constituents (= 1 for RDII) fgets(line, MAXLINE, Frdii.file); // --- read flow units fgets(line, MAXLINE, Frdii.file); sscanf(line, "%s %s", s1, s2); RdiiFlowUnits = findmatch(s2, FlowUnitWords); if ( RdiiFlowUnits < 0 ) return ERR_RDII_FILE_FORMAT; // --- read number of RDII nodes fgets(line, MAXLINE, Frdii.file); if ( sscanf(line, "%d", &NumRdiiNodes) < 1 ) return ERR_RDII_FILE_FORMAT; // --- allocate memory for RdiiNodeIndex & RdiiNodeFlow arrays RdiiNodeIndex = (int *) calloc(NumRdiiNodes, sizeof(int)); if ( !RdiiNodeIndex ) return ERR_MEMORY; RdiiNodeFlow = (float *) calloc(NumRdiiNodes, sizeof(float)); if ( !RdiiNodeFlow ) return ERR_MEMORY; // --- read names of RDII nodes from file & save their indexes for ( i=0; i<NumRdiiNodes; i++ ) { if ( feof(Frdii.file) ) return ERR_RDII_FILE_FORMAT; fgets(line, MAXLINE, Frdii.file); sscanf(line, "%s", s1); RdiiNodeIndex[i] = project_findObject(NODE, s1); } // --- skip column heading line if ( feof(Frdii.file) ) return ERR_RDII_FILE_FORMAT; fgets(line, MAXLINE, Frdii.file); return 0; }
int getIfaceFilePolluts() // // Input: none // Output: returns an error code // Purpose: reads names of pollutants saved on the inflows interface file. // { int i, j; char line[MAXLINE+1]; // line from inflows interface file char s1[MAXLINE+1]; // general string variable char s2[MAXLINE+1]; // --- read number of pollutants (minus FLOW) fgets(line, MAXLINE, Finflows.file); sscanf(line, "%d", &NumIfacePolluts); NumIfacePolluts--; if ( NumIfacePolluts < 0 ) return ERR_ROUTING_FILE_FORMAT; // --- read flow units fgets(line, MAXLINE, Finflows.file); sscanf(line, "%s %s", s1, s2); if ( !strcomp(s1, "FLOW") ) return ERR_ROUTING_FILE_FORMAT; IfaceFlowUnits = findmatch(s2, FlowUnitWords); if ( IfaceFlowUnits < 0 ) return ERR_ROUTING_FILE_FORMAT; //// This section was moved out of the if (...) statement below it //// //(5.0.017 - LR) //// so that not all pollutants have to be in the interface file. //// //(5.0.017 - LR) // --- allocate memory for pollutant index array if ( Nobjects[POLLUT] > 0 ) { IfacePolluts = (int *) calloc(Nobjects[POLLUT], sizeof(int)); if ( !IfacePolluts ) return ERR_MEMORY; for (i=0; i<Nobjects[POLLUT]; i++) IfacePolluts[i] = -1; } // --- read pollutant names & units if ( NumIfacePolluts > 0 ) { // --- check each pollutant name on file with project's pollutants for (i=0; i<NumIfacePolluts; i++) { if ( feof(Finflows.file) ) return ERR_ROUTING_FILE_FORMAT; fgets(line, MAXLINE, Finflows.file); sscanf(line, "%s %s", s1, s2); if ( Nobjects[POLLUT] > 0 ) { j = project_findObject(POLLUT, s1); if ( j < 0 ) continue; if ( !strcomp(s2, QualUnitsWords[Pollut[j].units]) ) return ERR_ROUTING_FILE_NOMATCH; IfacePolluts[j] = i; } } } return 0; }
int gwater_readAquiferParams(Project* project, int j, char* tok[], int ntoks) // // Input: j = aquifer index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns error message // Purpose: reads aquifer parameter values from line of input data // // Data line contains following parameters: // ID, porosity, wiltingPoint, fieldCapacity, conductivity, // conductSlope, tensionSlope, upperEvapFraction, lowerEvapDepth, // gwRecession, bottomElev, waterTableElev, upperMoisture // (evapPattern) // { int i, p; double x[12]; char *id; // --- check that aquifer exists if ( ntoks < 13 ) return error_setInpError(ERR_ITEMS, ""); id = project_findID(project, AQUIFER, tok[0]); if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); // --- read remaining tokens as numbers for (i = 0; i < 11; i++) x[i] = 0.0; for (i = 1; i < 13; i++) { if ( ! getDouble(tok[i], &x[i-1]) ) return error_setInpError(ERR_NUMBER, tok[i]); } // --- read upper evap pattern if present p = -1; if ( ntoks > 13 ) { p = project_findObject(project, TIMEPATTERN, tok[13]); if ( p < 0 ) return error_setInpError(ERR_NAME, tok[13]); } // --- assign parameters to aquifer object project->Aquifer[j].ID = id; project->Aquifer[j].porosity = x[0]; project->Aquifer[j].wiltingPoint = x[1]; project->Aquifer[j].fieldCapacity = x[2]; project->Aquifer[j].conductivity = x[3] / UCF(project, RAINFALL); project->Aquifer[j].conductSlope = x[4]; project->Aquifer[j].tensionSlope = x[5] / UCF(project, LENGTH); project->Aquifer[j].upperEvapFrac = x[6]; project->Aquifer[j].lowerEvapDepth = x[7] / UCF(project, LENGTH); project->Aquifer[j].lowerLossCoeff = x[8] / UCF(project, RAINFALL); project->Aquifer[j].bottomElev = x[9] / UCF(project, LENGTH); project->Aquifer[j].waterTableElev = x[10] / UCF(project, LENGTH); project->Aquifer[j].upperMoisture = x[11]; project->Aquifer[j].upperEvapPat = p; return 0; }
int rdii_readRdiiInflow(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads properties of an RDII inflow from a line of input. // { int j, k; float a; TRdiiInflow* inflow; // --- check for proper number of items if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); // --- check that node receiving RDII exists j = project_findObject(NODE, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- check that RDII unit hydrograph exists k = project_findObject(UNITHYD, tok[1]); if ( k < 0 ) return error_setInpError(ERR_NAME, tok[1]); // --- read in sewer area value if ( !getFloat(tok[2], &a) || a < 0.0 ) return error_setInpError(ERR_NUMBER, tok[2]); // --- create the RDII inflow object if it doesn't already exist inflow = Node[j].rdiiInflow; if ( inflow == NULL ) { inflow = (TRdiiInflow *) malloc(sizeof(TRdiiInflow)); if ( !inflow ) return error_setInpError(ERR_MEMORY, ""); } // --- assign UH & area to inflow object inflow->unitHyd = k; inflow->area = a / UCF(LANDAREA); // --- assign inflow object to node Node[j].rdiiInflow = inflow; return 0; }
int gwater_readFlowExpression(Project* project, char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads mathematical expression for lateral or deep groundwater // flow for a subcatchment from a line of input data. // // Format is: subcatch LATERAL/DEEP <expr> // where subcatch is the ID of the subcatchment, LATERAL is for lateral // project->GW flow, DEEP is for deep project->GW flow and <expr> is any well-formed math // expression. // { int i, j, k; char exprStr[MAXLINE+1]; MathExpr* expr; // --- return if too few tokens if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); // --- check that subcatchment exists j = project_findObject(project, SUBCATCH, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- check if expression is for lateral or deep project->GW flow k = 1; if ( match(tok[1], "LAT") ) k = 1; else if ( match(tok[1], "DEEP") ) k = 2; else return error_setInpError(ERR_KEYWORD, tok[1]); // --- concatenate remaining tokens into a single string strcpy(exprStr, tok[2]); for ( i = 3; i < ntoks; i++) { strcat(exprStr, " "); strcat(exprStr, tok[i]); } // --- delete any previous flow eqn. if ( k == 1 ) mathexpr_delete(project->Subcatch[j].gwLatFlowExpr); else mathexpr_delete(project->Subcatch[j].gwDeepFlowExpr); // --- create a parsed expression tree from the string expr // (getVariableIndex is the function that converts a project->GW // variable's name into an index number) expr = mathexpr_create(project,exprStr, getVariableIndex); if ( expr == NULL ) return error_setInpError(ERR_TREATMENT_EXPR, ""); // --- save expression tree with the subcatchment if ( k == 1 ) project->Subcatch[j].gwLatFlowExpr = expr; else project->Subcatch[j].gwDeepFlowExpr = expr; return 0; }
int subcatch_readInitBuildup(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads initial pollutant buildup on subcatchment from // tokenized line of input data. // // Data has format: // Subcatch pollut initLoad .... pollut initLoad // { int j, k, m; double x; // --- check for enough tokens if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); // --- check that named subcatch exists j = project_findObject(SUBCATCH, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- process each pair of pollutant - init. load items for ( k = 2; k <= ntoks; k = k+2) { // --- check for valid pollutant name and loading value m = project_findObject(POLLUT, tok[k-1]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[k-1]); if ( k+1 > ntoks ) return error_setInpError(ERR_ITEMS, ""); if ( ! getDouble(tok[k], &x) ) return error_setInpError(ERR_NUMBER, tok[k]); // --- store loading in subcatch's initBuildup property Subcatch[j].initBuildup[m] = x; } return 0; }
int subcatch_readLanduseParams(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads assignment of landuses to subcatchment from a tokenized // line of input data. // // Data has format: // Subcatch landuse percent .... landuse percent // { int j, k, m; double f; // --- check for enough tokens if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); // --- check that named subcatch exists j = project_findObject(SUBCATCH, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- process each pair of landuse - percent items for ( k = 2; k <= ntoks; k = k+2) { // --- check that named land use exists and is followed by a percent m = project_findObject(LANDUSE, tok[k-1]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[k-1]); if ( k+1 > ntoks ) return error_setInpError(ERR_ITEMS, ""); if ( ! getDouble(tok[k], &f) ) return error_setInpError(ERR_NUMBER, tok[k]); // --- store land use fraction in subcatch's landFactor property Subcatch[j].landFactor[m].fraction = f/100.0; } return 0; }
int table_readCurve(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads a tokenized line of data for a curve table. // { int j, m, k, k1 = 1; double x, y; // --- check for minimum number of tokens if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); // --- check that curve exists in database j = project_findObject(CURVE, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- check if this is first line of curve's data // (curve's ID will not have been assigned yet) if ( Curve[j].ID == NULL ) { // --- assign ID pointer & curve type Curve[j].ID = project_findID(CURVE, tok[0]); m = findmatch(tok[1], CurveTypeWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]); Curve[j].curveType = m; k1 = 2; } // --- start reading pairs of X-Y value tokens for ( k = k1; k < ntoks; k = k+2) { if ( k+1 >= ntoks ) return error_setInpError(ERR_ITEMS, ""); if ( ! getDouble(tok[k], &x) ) return error_setInpError(ERR_NUMBER, tok[k]); if ( ! getDouble(tok[k+1], &y) ) return error_setInpError(ERR_NUMBER, tok[k+1]); table_addEntry(&Curve[j], x, y); } return 0; }
int gwater_readGroundwaterParams(Project* project, char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads groundwater inflow parameters for a subcatchment from // a line of input data. // // Data format is: // subcatch aquifer node surfElev a1 b1 a2 b2 a3 fixedDepth + // (nodeElev bottomElev waterTableElev upperMoisture ) // { int i, j, k, m, n; double x[11]; TGroundwater* gw; // --- check that specified subcatchment, aquifer & node exist if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); j = project_findObject(project, SUBCATCH, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- check for enough tokens if ( ntoks < 11 ) return error_setInpError(ERR_ITEMS, ""); // --- check that specified aquifer and node exists k = project_findObject(project, AQUIFER, tok[1]); if ( k < 0 ) return error_setInpError(ERR_NAME, tok[1]); n = project_findObject(project, NODE, tok[2]); if ( n < 0 ) return error_setInpError(ERR_NAME, tok[2]); // -- read in the flow parameters for ( i = 0; i < 7; i++ ) { if ( ! getDouble(tok[i+3], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[i+3]); } // --- read in optional depth parameters for ( i = 7; i < 11; i++) { x[i] = MISSING; m = i + 3; if ( ntoks > m && *tok[m] != '*' ) { if (! getDouble(tok[m], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[m]); if ( i < 10 ) x[i] /= UCF(project,LENGTH); } } // --- create a groundwater flow object if ( !project->Subcatch[j].groundwater ) { gw = (TGroundwater *) malloc(sizeof(TGroundwater)); if ( !gw ) return error_setInpError(ERR_MEMORY, ""); project->Subcatch[j].groundwater = gw; } else gw = project->Subcatch[j].groundwater; // --- populate the groundwater flow object with its parameters gw->aquifer = k; gw->node = n; gw->surfElev = x[0] / UCF(project,LENGTH); gw->a1 = x[1]; gw->b1 = x[2]; gw->a2 = x[3]; gw->b2 = x[4]; gw->a3 = x[5]; gw->fixedDepth = x[6] / UCF(project,LENGTH); gw->nodeElev = x[7]; //already converted to ft. gw->bottomElev = x[8]; gw->waterTableElev = x[9]; gw->upperMoisture = x[10]; return 0; }
int storage_readParams(int j, int k, char* tok[], int ntoks) // // Input: j = node index // k = storage unit index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error message // Purpose: reads a storage unit's properties from a tokenized line of input. // // Format of input line is: // nodeID elev maxDepth initDepth FUNCTIONAL a1 a2 a0 aPond fEvap (infil) // nodeID elev maxDepth initDepth TABULAR curveID aPond fEvap (infil) // { int i, m, n; double x[9]; char* id; // --- get ID name if ( ntoks < 6 ) return error_setInpError(ERR_ITEMS, ""); id = project_findID(NODE, tok[0]); if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); // --- get invert elev, max. depth, & init. depth for ( i = 1; i <= 3; i++ ) { if ( ! getDouble(tok[i], &x[i-1]) ) return error_setInpError(ERR_NUMBER, tok[i]); } // --- get surf. area relation type m = findmatch(tok[4], RelationWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, tok[4]); x[3] = 0.0; // a1 x[4] = 0.0; // a2 x[5] = 0.0; // a0 x[6] = -1.0; // curveID x[7] = 0.0; // aPond x[8] = 0.0; // fEvap // --- get surf. area function coeffs. if ( m == FUNCTIONAL ) { for (i=5; i<=7; i++) { if ( i < ntoks ) { if ( ! getDouble(tok[i], &x[i-2]) ) return error_setInpError(ERR_NUMBER, tok[i]); } } n = 8; } // --- get surf. area curve name else { m = project_findObject(CURVE, tok[5]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[5]); x[6] = m; n = 6; } // --- ignore next token if present (deprecated ponded area property) //(5.1.007) if ( ntoks > n) { if ( ! getDouble(tok[n], &x[7]) ) return error_setInpError(ERR_NUMBER, tok[n]); n++; } // --- get evaporation fraction if present if ( ntoks > n ) { if ( ! getDouble(tok[n], &x[8]) ) return error_setInpError(ERR_NUMBER, tok[n]); n++; } // --- add parameters to storage unit object Node[j].ID = id; node_setParams(j, STORAGE, k, x); // --- read exfiltration parameters if present if ( ntoks > n ) return exfil_readStorageParams(k, tok, ntoks, n); //(5.1.007) return 0; }
int addAction(int r, char* tok[], int nToks) // // Input: r = control rule index // tok = array of string tokens containing action statement // nToks = number of string tokens // Output: returns an error code // Purpose: adds a new action to a control rule. // { int obj, link, attrib; int curve = -1, tseries = -1; int n; //(5.0.010 - LR) int err; double values[] = {1.0, 0.0, 0.0}; //(5.0.012 - LR) struct TAction* a; // --- check for proper number of tokens if ( nToks < 6 ) return error_setInpError(ERR_ITEMS, ""); // --- check for valid object type obj = findmatch(tok[1], ObjectWords); if ( obj != r_PUMP && obj != r_ORIFICE && obj != r_WEIR && obj != r_OUTLET ) return error_setInpError(ERR_KEYWORD, tok[1]); // --- check that object name exists and is of correct type link = project_findObject(LINK, tok[2]); if ( link < 0 ) return error_setInpError(ERR_NAME, tok[2]); switch (obj) { case r_PUMP: if ( Link[link].type != PUMP ) return error_setInpError(ERR_NAME, tok[2]); break; case r_ORIFICE: if ( Link[link].type != ORIFICE ) return error_setInpError(ERR_NAME, tok[2]); break; case r_WEIR: if ( Link[link].type != WEIR ) return error_setInpError(ERR_NAME, tok[2]); break; case r_OUTLET: if ( Link[link].type != OUTLET ) return error_setInpError(ERR_NAME, tok[2]); break; } // --- check for valid attribute name attrib = findmatch(tok[3], AttribWords); if ( attrib < 0 ) return error_setInpError(ERR_KEYWORD, tok[3]); // --- get control action setting if ( obj == r_PUMP ) { if ( attrib == r_STATUS ) { values[0] = findmatch(tok[5], StatusWords); //(5.0.012 - LR) if ( values[0] < 0.0 ) //(5.0.012 - LR) return error_setInpError(ERR_KEYWORD, tok[5]); //(5.0.012 - LR) } else if ( attrib == r_SETTING ) { err = setActionSetting(tok, nToks, &curve, &tseries, //(5.0.012 - LR) &attrib, values); //(5.0.012 - LR) if ( err > 0 ) return err; } else return error_setInpError(ERR_KEYWORD, tok[3]); } else if ( obj == r_ORIFICE || obj == r_WEIR || obj == r_OUTLET ) { if ( attrib == r_SETTING ) //(5.0.012 - LR) { //(5.0.012 - LR) err = setActionSetting(tok, nToks, &curve, &tseries, //(5.0.012 - LR) &attrib, values); //(5.0.012 - LR) if ( err > 0 ) return err; if ( attrib == r_SETTING //(5.0.012 - LR) && (values[0] < 0.0 || values[0] > 1.0) ) //(5.0.012 - LR) return error_setInpError(ERR_NUMBER, tok[5]); //(5.0.012 - LR) } //(5.0.012 - LR) else return error_setInpError(ERR_KEYWORD, tok[3]); } else return error_setInpError(ERR_KEYWORD, tok[1]); // --- check if another clause is on same line //(5.0.010 - LR) n = 6; //(5.0.010 - LR) if ( curve >= 0 || tseries >= 0 ) n = 7; //(5.0.010 - LR) if ( attrib == r_PID ) n = 9; //(5.0.012 - LR) if ( n < nToks && findmatch(tok[n], RuleKeyWords) >= 0 ) return ERR_RULE; //(5.0.010 - LR) // --- create the action object a = (struct TAction *) malloc(sizeof(struct TAction)); if ( !a ) return ERR_MEMORY; a->rule = r; a->link = link; a->attribute = attrib; a->curve = curve; a->tseries = tseries; a->value = values[0]; //(5.0.012 - LR) if ( attrib == r_PID ) //(5.0.012 - LR) { //(5.0.012 - LR) a->kp = values[0]; //(5.0.012 - LR) a->ki = values[1]; //(5.0.012 - LR) a->kd = values[2]; //(5.0.012 - LR) a->e1 = 0.0; //(5.0.012 - LR) a->e2 = 0.0; //(5.0.012 - LR) } //(5.0.012 - LR) if ( InputState == r_THEN ) { a->next = Rules[r].thenActions; Rules[r].thenActions = a; } else { a->next = Rules[r].elseActions; Rules[r].elseActions = a; } return 0; }
int outfall_readParams(int j, int k, char* tok[], int ntoks) // // Input: j = node index // k = outfall index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error message // Purpose: reads an outfall's properties from a tokenized line of input. // // Format of input line is: // nodeID elev FIXED fixedStage (flapGate) (routeTo) // nodeID elev TIDAL curveID (flapGate) (routeTo) // nodeID elev TIMESERIES tseriesID (flapGate) (routTo) // nodeID elev FREE (flapGate) (routeTo) // nodeID elev NORMAL (flapGate) (routeTo) // { int i, m, n; double x[7]; //(5.1.008) char* id; if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); id = project_findID(NODE, tok[0]); // node ID if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); if ( ! getDouble(tok[1], &x[0]) ) // invert elev. return error_setInpError(ERR_NUMBER, tok[1]); i = findmatch(tok[2], OutfallTypeWords); // outfall type if ( i < 0 ) return error_setInpError(ERR_KEYWORD, tok[2]); x[1] = i; // outfall type x[2] = 0.0; // fixed stage x[3] = -1.; // tidal curve x[4] = -1.; // tide series x[5] = 0.; // flap gate x[6] = -1.; // route to subcatch//(5.1.008) n = 4; if ( i >= FIXED_OUTFALL ) { if ( ntoks < 4 ) return error_setInpError(ERR_ITEMS, ""); n = 5; switch ( i ) { case FIXED_OUTFALL: // fixed stage if ( ! getDouble(tok[3], &x[2]) ) return error_setInpError(ERR_NUMBER, tok[3]); break; case TIDAL_OUTFALL: // tidal curve m = project_findObject(CURVE, tok[3]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[3]); x[3] = m; break; case TIMESERIES_OUTFALL: // stage time series m = project_findObject(TSERIES, tok[3]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[3]); x[4] = m; Tseries[m].refersTo = TIMESERIES_OUTFALL; } } if ( ntoks == n ) { m = findmatch(tok[n-1], NoYesWords); // flap gate if ( m < 0 ) return error_setInpError(ERR_KEYWORD, tok[n-1]); x[5] = m; } //// Added for release 5.1.008. //// //(5.1.008) if ( ntoks == n+1) { m = project_findObject(SUBCATCH, tok[n]); if ( m < 0 ) return error_setInpError(ERR_NAME, tok[n]); x[6] = m; } //// Node[j].ID = id; node_setParams(j, OUTFALL, k, x); return 0; }
int addObject(int objType, char* id) // // Input: objType = object type index // id = object's ID string // Output: returns an error code // Purpose: adds a new object to the project. // { int errcode = 0; switch( objType ) { case s_RAINGAGE: if ( !project_addObject(GAGE, id, Nobjects[GAGE]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[GAGE]++; break; case s_SUBCATCH: if ( !project_addObject(SUBCATCH, id, Nobjects[SUBCATCH]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[SUBCATCH]++; break; case s_AQUIFER: if ( !project_addObject(AQUIFER, id, Nobjects[AQUIFER]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[AQUIFER]++; break; case s_UNITHYD: // --- the same Unit Hydrograph can span several lines if ( project_findObject(UNITHYD, id) < 0 ) { if ( !project_addObject(UNITHYD, id, Nobjects[UNITHYD]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[UNITHYD]++; } break; case s_SNOWMELT: // --- the same Snowmelt object can appear on several lines if ( project_findObject(SNOWMELT, id) < 0 ) { if ( !project_addObject(SNOWMELT, id, Nobjects[SNOWMELT]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[SNOWMELT]++; } break; case s_JUNCTION: if ( !project_addObject(NODE, id, Nobjects[NODE]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[NODE]++; Nnodes[JUNCTION]++; break; case s_OUTFALL: if ( !project_addObject(NODE, id, Nobjects[NODE]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[NODE]++; Nnodes[OUTFALL]++; break; case s_STORAGE: if ( !project_addObject(NODE, id, Nobjects[NODE]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[NODE]++; Nnodes[STORAGE]++; break; case s_DIVIDER: if ( !project_addObject(NODE, id, Nobjects[NODE]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[NODE]++; Nnodes[DIVIDER]++; break; case s_CONDUIT: if ( !project_addObject(LINK, id, Nobjects[LINK]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[LINK]++; Nlinks[CONDUIT]++; break; case s_PUMP: if ( !project_addObject(LINK, id, Nobjects[LINK]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[LINK]++; Nlinks[PUMP]++; break; case s_ORIFICE: if ( !project_addObject(LINK, id, Nobjects[LINK]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[LINK]++; Nlinks[ORIFICE]++; break; case s_WEIR: if ( !project_addObject(LINK, id, Nobjects[LINK]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[LINK]++; Nlinks[WEIR]++; break; case s_OUTLET: if ( !project_addObject(LINK, id, Nobjects[LINK]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[LINK]++; Nlinks[OUTLET]++; break; case s_POLLUTANT: if ( !project_addObject(POLLUT, id, Nobjects[POLLUT]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[POLLUT]++; break; case s_LANDUSE: if ( !project_addObject(LANDUSE, id, Nobjects[LANDUSE]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[LANDUSE]++; break; case s_PATTERN: // --- a time pattern can span several lines if ( project_findObject(TIMEPATTERN, id) < 0 ) { if ( !project_addObject(TIMEPATTERN, id, Nobjects[TIMEPATTERN]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[TIMEPATTERN]++; } break; case s_CURVE: // --- a Curve can span several lines if ( project_findObject(CURVE, id) < 0 ) { if ( !project_addObject(CURVE, id, Nobjects[CURVE]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[CURVE]++; // --- check for a conduit shape curve id = strtok(NULL, SEPSTR); if ( findmatch(id, CurveTypeWords) == SHAPE_CURVE ) Nobjects[SHAPE]++; } break; case s_TIMESERIES: // --- a Time Series can span several lines if ( project_findObject(TSERIES, id) < 0 ) { if ( !project_addObject(TSERIES, id, Nobjects[TSERIES]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[TSERIES]++; } break; case s_CONTROL: if ( match(id, w_RULE) ) Nobjects[CONTROL]++; break; case s_TRANSECT: // --- for TRANSECTS, ID name appears as second entry on X1 line if ( match(id, "X1") ) { id = strtok(NULL, SEPSTR); if ( id ) { if ( !project_addObject(TRANSECT, id, Nobjects[TRANSECT]) ) errcode = error_setInpError(ERR_DUP_NAME, id); Nobjects[TRANSECT]++; } } break; case s_LID_CONTROL: // --- an LID object can span several lines if ( project_findObject(LID, id) < 0 ) { if ( !project_addObject(LID, id, Nobjects[LID]) ) { errcode = error_setInpError(ERR_DUP_NAME, id); } Nobjects[LID]++; } break; } return errcode; }
int addPremise(int r, int type, char* tok[], int nToks) // // Input: r = control rule index // type = type of premise (IF, AND, OR) // tok = array of string tokens containing premise statement // nToks = number of string tokens // Output: returns an error code // Purpose: adds a new premise to a control rule. // { int node = -1; int link = -1; int obj, attrib, op, n; double value; struct TPremise* p; // --- check for proper number of tokens if ( nToks < 5 ) return ERR_ITEMS; // --- get object type obj = findmatch(tok[1], ObjectWords); if ( obj < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]); // --- get object name n = 2; switch (obj) { case r_NODE: node = project_findObject(NODE, tok[n]); if ( node < 0 ) return error_setInpError(ERR_NAME, tok[n]); break; case r_LINK: case r_PUMP: case r_ORIFICE: case r_WEIR: case r_OUTLET: link = project_findObject(LINK, tok[n]); if ( link < 0 ) return error_setInpError(ERR_NAME, tok[n]); break; default: n = 1; } n++; // --- get attribute name attrib = findmatch(tok[n], AttribWords); if ( attrib < 0 ) return error_setInpError(ERR_KEYWORD, tok[n]); // --- check that property belongs to object type if ( obj == r_NODE ) switch (attrib) { case r_DEPTH: case r_HEAD: case r_INFLOW: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else if ( obj == r_LINK ) switch (attrib) { case r_DEPTH: case r_FLOW: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else if ( obj == r_PUMP ) switch (attrib) { case r_FLOW: case r_STATUS: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else if ( obj == r_ORIFICE || obj == r_WEIR || obj == r_OUTLET ) switch (attrib) //(5.0.010 - LR) { case r_SETTING: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else switch (attrib) { case r_TIME: case r_DATE: case r_CLOCKTIME: //(5.0.014 - LR) case r_DAY: //(5.0.014 - LR) case r_MONTH: break; //(5.0.014 - LR) default: return error_setInpError(ERR_KEYWORD, tok[n]); } // --- get operand n++; op = findExactMatch(tok[n], OperandWords); if ( op < 0 ) return error_setInpError(ERR_KEYWORD, tok[n]); n++; if ( n >= nToks ) return error_setInpError(ERR_ITEMS, ""); // --- get value switch (attrib) { case r_STATUS: value = findmatch(tok[n], StatusWords); if ( value < 0.0 ) return error_setInpError(ERR_KEYWORD, tok[n]); break; case r_TIME: case r_CLOCKTIME: if ( !datetime_strToTime(tok[n], &value) ) return error_setInpError(ERR_DATETIME, tok[n]); break; case r_DATE: if ( !datetime_strToDate(tok[n], &value) ) return error_setInpError(ERR_DATETIME, tok[n]); break; case r_DAY: if ( !getDouble(tok[n], &value) ) //(5.0.014 - LR) return error_setInpError(ERR_NUMBER, tok[n]); //(5.0.014 - LR) if ( value < 1.0 || value > 7.0 ) //(5.0.014 - LR) return error_setInpError(ERR_DATETIME, tok[n]); //(5.0.014 - LR) break; //(5.0.014 - LR) case r_MONTH: //(5.0.014 - LR) if ( !getDouble(tok[n], &value) ) //(5.0.014 - LR) return error_setInpError(ERR_NUMBER, tok[n]); //(5.0.014 - LR) if ( value < 1.0 || value > 12.0 ) //(5.0.014 - LR) return error_setInpError(ERR_DATETIME, tok[n]); //(5.0.014 - LR) break; //(5.0.014 - LR) default: if ( !getDouble(tok[n], &value) ) return error_setInpError(ERR_NUMBER, tok[n]); } // --- check if another clause is on same line //(5.0.010 - LR) n++; //(5.0.010 - LR) if ( n < nToks && findmatch(tok[n], RuleKeyWords) >= 0 ) return ERR_RULE; //(5.0.010 - LR) // --- create the premise object p = (struct TPremise *) malloc(sizeof(struct TPremise)); if ( !p ) return ERR_MEMORY; p->type = type; p->node = node; p->link = link; p->attribute = attrib; p->operand = op; p->value = value; p->next = NULL; if ( Rules[r].firstPremise == NULL ) { Rules[r].firstPremise = p; } else { Rules[r].lastPremise->next = p; } Rules[r].lastPremise = p; return 0; }
int climate_readEvapParams(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads evaporation parameters from input line of data. // // Data formats are: // CONSTANT value // MONTHLY v1 ... v12 // TIMESERIES name // FILE (v1 ... v12) // { int i, k; double x; // --- find keyword indicating what form the evaporation data is in if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); k = findmatch(tok[0], EvapTypeWords); if ( k < 0 ) return error_setInpError(ERR_KEYWORD, tok[0]); // --- process data depending on its form Evap.type = k; switch ( k ) { case CONSTANT_EVAP: // --- for constant evap., fill monthly avg. values with same number if ( !getDouble(tok[1], &x) ) return error_setInpError(ERR_NUMBER, tok[1]); for (i=0; i<12; i++) Evap.monthlyEvap[i] = x; break; case MONTHLY_EVAP: // --- for monthly evap., read a value for each month of year if ( ntoks < 13 ) return error_setInpError(ERR_ITEMS, ""); for ( i=0; i<12; i++) if ( !getDouble(tok[i+1], &Evap.monthlyEvap[i]) ) return error_setInpError(ERR_NUMBER, tok[i+1]); break; case TIMESERIES_EVAP: // --- for time series evap., read name of time series i = project_findObject(TSERIES, tok[1]); if ( i < 0 ) return error_setInpError(ERR_NAME, tok[1]); Evap.tSeries = i; break; case FILE_EVAP: // --- for evap. from climate file, read monthly pan coeffs. // if they are provided (default values are 1.0) if ( ntoks > 1 ) { if ( ntoks < 13 ) return error_setInpError(ERR_ITEMS, ""); for (i=0; i<12; i++) { if ( !getDouble(tok[i+1], &Evap.panCoeff[i]) ) return error_setInpError(ERR_NUMBER, tok[i+1]); } } break; } return 0; }
int climate_readParams(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads climate/temperature parameters from input line of data // // Format of data can be // TIMESERIES name // FILE name // WINDSPEED MONTHLY v1 v2 ... v12 // WINDSPEED FILE // SNOWMELT v1 v2 ... v6 // ADC IMPERV/PERV v1 v2 ... v10 // { int i, j, k; double x[6], y; DateTime aDate; // --- identify keyword k = findmatch(tok[0], TempKeyWords); if ( k < 0 ) return error_setInpError(ERR_KEYWORD, tok[0]); switch (k) { case 0: // Time series name // --- check that time series name exists if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); i = project_findObject(TSERIES, tok[1]); if ( i < 0 ) return error_setInpError(ERR_NAME, tok[1]); // --- record the time series as being the data source for temperature Temp.dataSource = TSERIES_TEMP; Temp.tSeries = i; break; case 1: // Climate file // --- record file as being source of temperature data if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); Temp.dataSource = FILE_TEMP; // --- save name and usage mode of external climate file Fclimate.mode = USE_FILE; sstrncpy(Fclimate.name, tok[1], MAXFNAME); // --- save starting date to read from file if one is provided Temp.fileStartDate = NO_DATE; if ( ntoks > 2 ) { if ( *tok[2] != '*') { if ( !datetime_strToDate(tok[2], &aDate) ) return error_setInpError(ERR_DATETIME, tok[2]); Temp.fileStartDate = aDate; } } break; case 2: // Wind speeds // --- check if wind speeds will be supplied from climate file if ( strcomp(tok[1], w_FILE) ) { Wind.type = FILE_WIND; } // --- otherwise read 12 monthly avg. wind speed values else { if ( ntoks < 14 ) return error_setInpError(ERR_ITEMS, ""); Wind.type = MONTHLY_WIND; for (i=0; i<12; i++) { if ( !getDouble(tok[i+2], &y) ) return error_setInpError(ERR_NUMBER, tok[i+2]); Wind.aws[i] = y; } } break; case 3: // Snowmelt params if ( ntoks < 7 ) return error_setInpError(ERR_ITEMS, ""); for (i=1; i<7; i++) { if ( !getDouble(tok[i], &x[i-1]) ) return error_setInpError(ERR_NUMBER, tok[i]); } // --- convert deg. C to deg. F for snowfall temperature if ( UnitSystem == SI ) x[0] = 9./5.*x[0] + 32.0; Snow.snotmp = x[0]; Snow.tipm = x[1]; Snow.rnm = x[2]; Temp.elev = x[3] / UCF(LENGTH); Temp.anglat = x[4]; Temp.dtlong = x[5] / 60.0; break; case 4: // Areal Depletion Curve data // --- check if data is for impervious or pervious areas if ( ntoks < 12 ) return error_setInpError(ERR_ITEMS, ""); if ( match(tok[1], w_IMPERV) ) i = 0; else if ( match(tok[1], w_PERV) ) i = 1; else return error_setInpError(ERR_KEYWORD, tok[1]); // --- read 10 fractional values for (j=0; j<10; j++) { if ( !getDouble(tok[j+2], &y) || y < 0.0 || y > 1.0 ) return error_setInpError(ERR_NUMBER, tok[j+2]); Snow.adc[i][j] = y; } break; } return 0; }
int gwater_readGroundwaterParams(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads groundwater inflow parameters for a subcatchment from // a line of input data. // // Data format is: // subcatch aquifer node surfElev x0 ... x7 (flow parameters) // { int i, j, k, n; double x[8]; TGroundwater* gw; // --- check that specified subcatchment, aquifer & node exist if ( ntoks < 10 ) return error_setInpError(ERR_ITEMS, ""); j = project_findObject(SUBCATCH, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); k = project_findObject(AQUIFER, tok[1]); if ( k < 0 ) return error_setInpError(ERR_NAME, tok[1]); n = project_findObject(NODE, tok[2]); if ( n < 0 ) return error_setInpError(ERR_NAME, tok[2]); // --- read in the groundwater flow parameters as floats for ( i = 0; i < 7; i++ ) { if ( ! getDouble(tok[i+3], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[i+3]); } // --- read in overridden node invert elev. x[7] = MISSING; if ( ntoks > 10 ) { if ( ! getDouble(tok[10], &x[7]) ) return error_setInpError(ERR_NUMBER, tok[10]); x[7] /= UCF(LENGTH); } // --- create a groundwater flow object if ( !Subcatch[j].groundwater ) { gw = (TGroundwater *) malloc(sizeof(TGroundwater)); if ( !gw ) return error_setInpError(ERR_MEMORY, ""); Subcatch[j].groundwater = gw; } else gw = Subcatch[j].groundwater; // --- populate the groundwater flow object with its parameters gw->aquifer = k; gw->node = n; gw->surfElev = x[0] / UCF(LENGTH); gw->a1 = x[1]; gw->b1 = x[2]; gw->a2 = x[3]; gw->b2 = x[4]; gw->a3 = x[5]; gw->fixedDepth = x[6] / UCF(LENGTH); gw->nodeElev = x[7]; //already converted to ft. return 0; }
int divider_readParams(int j, int k, char* tok[], int ntoks) // // Input: j = node index // k = divider index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error message // Purpose: reads a flow divider's properties from a tokenized line of input. // // Format of input line is: // nodeID elev divLink TABULAR curveID (optional params) // nodeID elev divLink OVERFLOW (optional params) // nodeID elev divLink CUTOFF qCutoff (optional params) // nodeID elev divLink WEIR qMin dhMax cWeir (optional params) // where optional params are: // maxDepth initDepth surDepth aPond // { int i, m, m1, m2, n; double x[11]; char* id; // --- get ID name if ( ntoks < 4 ) return error_setInpError(ERR_ITEMS, ""); id = project_findID(NODE, tok[0]); if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); // --- get invert elev. if ( ! getDouble(tok[1], &x[0]) ) return error_setInpError(ERR_NUMBER, tok[1]); // --- initialize parameter values for ( i=1; i<11; i++) x[i] = 0.0; // --- check if no diverted link supplied if ( strlen(tok[2]) == 0 || strcmp(tok[2], "*") == 0 ) x[1] = -1.0; // --- otherwise get index of diverted link else { m1 = project_findObject(LINK, tok[2]); if ( m1 < 0 ) return error_setInpError(ERR_NAME, tok[2]); x[1] = m1; } // --- get divider type n = 4; m1 = findmatch(tok[3], DividerTypeWords); if ( m1 < 0 ) return error_setInpError(ERR_KEYWORD, tok[3]); x[2] = m1; // --- get index of flow diversion curve for Tabular divider x[3] = -1; if ( m1 == TABULAR_DIVIDER ) { if ( ntoks < 5 ) return error_setInpError(ERR_ITEMS, ""); m2 = project_findObject(CURVE, tok[4]); if ( m2 < 0 ) return error_setInpError(ERR_NAME, tok[4]); x[3] = m2; n = 5; } // --- get cutoff flow for Cutoff divider if ( m1 == CUTOFF_DIVIDER ) { if ( ntoks < 5 ) return error_setInpError(ERR_ITEMS, ""); if ( ! getDouble(tok[4], &x[4]) ) return error_setInpError(ERR_NUMBER, tok[4]); n = 5; } // --- get qmin, dhMax, & cWeir for Weir divider if ( m1 == WEIR_DIVIDER ) { if ( ntoks < 7 ) return error_setInpError(ERR_ITEMS, ""); for (i=4; i<7; i++) if ( ! getDouble(tok[i], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[i]); n = 7; } // --- no parameters needed for Overflow divider if ( m1 == OVERFLOW_DIVIDER ) n = 4; // --- retrieve optional full depth, init. depth, surcharged depth // & ponded area m = 7; for (i=n; i<ntoks && m<11; i++) { if ( ! getDouble(tok[i], &x[m]) ) { return error_setInpError(ERR_NUMBER, tok[i]); } m++; } // --- add parameters to data base Node[j].ID = id; node_setParams(j, DIVIDER, k, x); return 0; }
int subcatch_readSubareaParams(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads subcatchment's subarea parameters from a tokenized // line of input data. // // Data has format: // Subcatch Imperv_N Perv_N Imperv_S Perv_S PctZero RouteTo (PctRouted) // { int i, j, k, m; double x[7]; // --- check for enough tokens if ( ntoks < 7 ) return error_setInpError(ERR_ITEMS, ""); // --- check that named subcatch exists j = project_findObject(SUBCATCH, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- read in Mannings n, depression storage, & PctZero values for (i = 0; i < 5; i++) { if ( ! getDouble(tok[i+1], &x[i]) || x[i] < 0.0 ) return error_setInpError(ERR_NAME, tok[i+1]); } // --- check for valid runoff routing keyword m = findmatch(tok[6], RunoffRoutingWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, tok[6]); // --- get percent routed parameter if present (default is 100) x[5] = m; x[6] = 1.0; if ( ntoks >= 8 ) { if ( ! getDouble(tok[7], &x[6]) || x[6] < 0.0 || x[6] > 100.0 ) return error_setInpError(ERR_NUMBER, tok[7]); x[6] /= 100.0; } // --- assign input values to each type of subarea Subcatch[j].subArea[IMPERV0].N = x[0]; Subcatch[j].subArea[IMPERV1].N = x[0]; Subcatch[j].subArea[PERV].N = x[1]; Subcatch[j].subArea[IMPERV0].dStore = 0.0; Subcatch[j].subArea[IMPERV1].dStore = x[2] / UCF(RAINDEPTH); Subcatch[j].subArea[PERV].dStore = x[3] / UCF(RAINDEPTH); Subcatch[j].subArea[IMPERV0].fArea = Subcatch[j].fracImperv * x[4] / 100.0; Subcatch[j].subArea[IMPERV1].fArea = Subcatch[j].fracImperv * (1.0 - x[4] / 100.0); Subcatch[j].subArea[PERV].fArea = (1.0 - Subcatch[j].fracImperv); // --- assume that all runoff from each subarea goes to subcatch outlet for (i = IMPERV0; i <= PERV; i++) { Subcatch[j].subArea[i].routeTo = TO_OUTLET; Subcatch[j].subArea[i].fOutlet = 1.0; } // --- modify routing if pervious runoff routed to impervious area // (fOutlet is the fraction of runoff not routed) k = (int)x[5]; if ( Subcatch[j].fracImperv == 0.0 || Subcatch[j].fracImperv == 1.0 ) k = TO_OUTLET; if ( k == TO_IMPERV && Subcatch[j].fracImperv ) { Subcatch[j].subArea[PERV].routeTo = k; Subcatch[j].subArea[PERV].fOutlet = 1.0 - x[6]; } // --- modify routing if impervious runoff routed to pervious area if ( k == TO_PERV ) { Subcatch[j].subArea[IMPERV0].routeTo = k; Subcatch[j].subArea[IMPERV1].routeTo = k; Subcatch[j].subArea[IMPERV0].fOutlet = 1.0 - x[6]; Subcatch[j].subArea[IMPERV1].fOutlet = 1.0 - x[6]; } return 0; }
int subcatch_readParams(int j, char* tok[], int ntoks) // // Input: j = subcatchment index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads subcatchment parameters from a tokenized line of input data. // // Data has format: // Name RainGage Outlet Area %Imperv Width Slope CurbLength Snowpack // { int i, k, m; char* id; double x[9]; // --- check for enough tokens if ( ntoks < 8 ) return error_setInpError(ERR_ITEMS, ""); // --- check that named subcatch exists id = project_findID(SUBCATCH, tok[0]); if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); // --- check that rain gage exists k = project_findObject(GAGE, tok[1]); if ( k < 0 ) return error_setInpError(ERR_NAME, tok[1]); x[0] = k; // --- check that outlet node or subcatch exists m = project_findObject(NODE, tok[2]); x[1] = m; m = project_findObject(SUBCATCH, tok[2]); x[2] = m; if ( x[1] < 0.0 && x[2] < 0.0 ) return error_setInpError(ERR_NAME, tok[2]); // --- read area, %imperv, width, slope, & curb length for ( i = 3; i < 8; i++) { if ( ! getDouble(tok[i], &x[i]) || x[i] < 0.0 ) return error_setInpError(ERR_NUMBER, tok[i]); } // --- if snowmelt object named, check that it exists x[8] = -1; if ( ntoks > 8 ) { k = project_findObject(SNOWMELT, tok[8]); if ( k < 0 ) return error_setInpError(ERR_NAME, tok[8]); x[8] = k; } // --- assign input values to subcatch's properties Subcatch[j].ID = id; Subcatch[j].gage = (int)x[0]; Subcatch[j].outNode = (int)x[1]; Subcatch[j].outSubcatch = (int)x[2]; Subcatch[j].area = x[3] / UCF(LANDAREA); Subcatch[j].fracImperv = x[4] / 100.0; Subcatch[j].width = x[5] / UCF(LENGTH); Subcatch[j].slope = x[6] / 100.0; Subcatch[j].curbLength = x[7]; // --- create the snow pack object if it hasn't already been created if ( x[8] >= 0 ) { if ( !snow_createSnowpack(j, (int)x[8]) ) return error_setInpError(ERR_MEMORY, ""); } return 0; }
int climate_readEvapParams(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads evaporation parameters from input line of data. // // Data formats are: // CONSTANT value // MONTHLY v1 ... v12 // TIMESERIES name // TEMPERATURE //(5.0.016 - LR) // FILE (v1 ... v12) // RECOVERY name //(5.0.014 - LR) // DRY_ONLY YES/NO //(5.0.019 - LR) // { int i, k; double x; // --- find keyword indicating what form the evaporation data is in //if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); //(5.0.016 - LR) k = findmatch(tok[0], EvapTypeWords); if ( k < 0 ) return error_setInpError(ERR_KEYWORD, tok[0]); // --- check for RECOVERY pattern data //(5.0.014 - LR) if ( k == RECOVERY ) //(5.0.014 - LR) { //(5.0.014 - LR) if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); //(5.0.014 - LR) i = project_findObject(TIMEPATTERN, tok[1]); //(5.0.014 - LR) if ( i < 0 ) return error_setInpError(ERR_NAME, tok[1]); //(5.0.014 - LR) Evap.recoveryPattern = i; //(5.0.014 - LR) return 0; //(5.0.014 - LR) } //(5.0.014 - LR) //// The following code segment was added for release 5.0.019 //// //(5.0.019 - LR) // --- check for no evaporation in wet periods if ( k == DRYONLY ) { if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); if ( strcomp(tok[1], w_NO ) ) Evap.dryOnly = FALSE; else if ( strcomp(tok[1], w_YES ) ) Evap.dryOnly = TRUE; else return error_setInpError(ERR_KEYWORD, tok[1]); return 0; } //// End of new code segment //// // --- process data depending on its form Evap.type = k; if ( k != TEMPERATURE_EVAP && ntoks < 2 ) //(5.0.016 - LR) return error_setInpError(ERR_ITEMS, ""); //(5.0.016 - LR) switch ( k ) { case CONSTANT_EVAP: // --- for constant evap., fill monthly avg. values with same number if ( !getDouble(tok[1], &x) ) return error_setInpError(ERR_NUMBER, tok[1]); for (i=0; i<12; i++) Evap.monthlyEvap[i] = x; break; case MONTHLY_EVAP: // --- for monthly evap., read a value for each month of year if ( ntoks < 13 ) return error_setInpError(ERR_ITEMS, ""); for ( i=0; i<12; i++) if ( !getDouble(tok[i+1], &Evap.monthlyEvap[i]) ) return error_setInpError(ERR_NUMBER, tok[i+1]); break; case TIMESERIES_EVAP: // --- for time series evap., read name of time series i = project_findObject(TSERIES, tok[1]); if ( i < 0 ) return error_setInpError(ERR_NAME, tok[1]); Evap.tSeries = i; Tseries[i].refersTo = TIMESERIES_EVAP; //(5.0.019 - LR) break; case FILE_EVAP: // --- for evap. from climate file, read monthly pan coeffs. // if they are provided (default values are 1.0) if ( ntoks > 1 ) { if ( ntoks < 13 ) return error_setInpError(ERR_ITEMS, ""); for (i=0; i<12; i++) { if ( !getDouble(tok[i+1], &Evap.panCoeff[i]) ) return error_setInpError(ERR_NUMBER, tok[i+1]); } } break; } return 0; }