int storage_readInfilParams(int j, char* tok[], int ntoks, int n) { int i, k; double x[3]; TGrnAmpt* infil; // --- read Grenn-Ampt infiltration parameters from input tokens if ( ntoks < n + 3 ) return error_setInpError(ERR_ITEMS, ""); for (i = 0; i < 3; i++) { if ( ! getDouble(tok[n+i], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[n+i]); } // --- create a Green-Ampt infiltration object for the storage node k = Node[j].subIndex; infil = Storage[k].infil; if ( infil == NULL ) { infil = (TGrnAmpt *) malloc(sizeof(TGrnAmpt)); if ( infil == NULL ) return error_setInpError(ERR_MEMORY, ""); Storage[k].infil = infil; } // --- add the infiltration parameters to the Green-Ampt object if ( !grnampt_setParams(infil, x) ) return error_setInpError(ERR_NUMBER, ""); 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 readControl(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns error code // Purpose: reads a line of input for a control rule. // { int index; int keyword; // --- check for minimum number of tokens if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); // --- get index of control rule keyword keyword = findmatch(tok[0], RuleKeyWords); if ( keyword < 0 ) return error_setInpError(ERR_KEYWORD, tok[0]); // --- if line begins a new control rule, add rule ID to the database if ( keyword == 0 ) { if ( !project_addObject(CONTROL, tok[1], Mobjects[CONTROL]) ) { return error_setInpError(ERR_DUP_NAME, Tok[1]); } Mobjects[CONTROL]++; } // --- get index of last control rule processed index = Mobjects[CONTROL] - 1; if ( index < 0 ) return error_setInpError(ERR_RULE, ""); // --- add current line as a new clause to the control rule return controls_addRuleClause(index, keyword, Tok, Ntokens); }
int createStorageExfil(int k, double x[]) // // Input: k = index of storage unit node // x = array of Green-Ampt infiltration parameters // Output: returns an error code. // Purpose: creates an exfiltration object for a storage node. // // Note: the exfiltration object is freed in project.c. // { TExfil* exfil; // --- create an exfiltration object for the storage node exfil = Storage[k].exfil; if ( exfil == NULL ) { exfil = (TExfil *) malloc(sizeof(TExfil)); if ( exfil == NULL ) return error_setInpError(ERR_MEMORY, ""); Storage[k].exfil = exfil; // --- create Green-Ampt infiltration objects for the bottom & banks exfil->btmExfil = NULL; exfil->bankExfil = NULL; exfil->btmExfil = (TGrnAmpt *) malloc(sizeof(TGrnAmpt)); if ( exfil->btmExfil == NULL ) return error_setInpError(ERR_MEMORY, ""); exfil->bankExfil = (TGrnAmpt *) malloc(sizeof(TGrnAmpt)); if ( exfil->bankExfil == NULL ) return error_setInpError(ERR_MEMORY, ""); } // --- initialize the Green-Ampt parameters if ( !grnampt_setParams(exfil->btmExfil, x) ) return error_setInpError(ERR_NUMBER, ""); grnampt_setParams(exfil->bankExfil, x); 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 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 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 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 junc_readParams(int j, int k, char* tok[], int ntoks) // // Input: j = node index // k = junction index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error message // Purpose: reads a junction's properties from a tokenized line of input. // // Format of input line is: // nodeID elev maxDepth initDepth surDepth aPond { int i; double x[6]; char* id; if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); id = project_findID(NODE, tok[0]); if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); // --- parse invert elev., max. depth, init. depth, surcharged depth, // & ponded area values for ( i = 1; i <= 5; i++ ) { x[i-1] = 0.0; if ( i < ntoks ) { if ( ! getDouble(tok[i], &x[i-1]) ) return error_setInpError(ERR_NUMBER, tok[i]); } } // --- check for non-negative values (except for invert elev.) for ( i = 1; i <= 4; i++ ) { if ( x[i] < 0.0 ) return error_setInpError(ERR_NUMBER, tok[i+1]); } // --- add parameters to junction object Node[j].ID = id; node_setParams(j, JUNCTION, k, x); return 0; }
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 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 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 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 exfil_readStorageParams(int k, char* tok[], int ntoks, int n) // // Input: k = storage unit index // tok[] = array of string tokens // ntoks = number of tokens // n = last token processed // Output: returns an error code // Purpose: reads a storage unit's exfiltration parameters from a // tokenized line of input. // { int i; double x[3]; //suction head, Ksat, IMDmax // --- read Ksat if it's the only remaining token if ( ntoks == n+1 ) { if ( ! getDouble(tok[n], &x[1]) ) return error_setInpError(ERR_NUMBER, tok[n]); x[0] = 0.0; x[2] = 0.0; } // --- otherwise read Green-Ampt infiltration parameters from input tokens else if ( ntoks < n + 3 ) return error_setInpError(ERR_ITEMS, ""); else for (i = 0; i < 3; i++) { if ( ! getDouble(tok[n+i], &x[i]) ) return error_setInpError(ERR_NUMBER, tok[n+i]); } // --- no exfiltration if Ksat is 0 if ( x[1] == 0.0 ) return 0; // --- create an exfiltration object return createStorageExfil(k, x); }
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 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 landuse_readParams(Project* project, int j, char* tok[], int ntoks) // // Input: j = land use index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads landuse parameters from a tokenized line of input. // // Data format is: // landuseID (sweepInterval sweepRemoval sweepDays0) // { char *id; if ( ntoks < 1 ) return error_setInpError(ERR_ITEMS, ""); id = project_findID(project,LANDUSE, tok[0]); if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); project->Landuse[j].ID = id; if ( ntoks > 1 ) { if ( ntoks < 4 ) return error_setInpError(ERR_ITEMS, ""); if ( ! getDouble(tok[1], &project->Landuse[j].sweepInterval) ) return error_setInpError(ERR_NUMBER, tok[1]); if ( ! getDouble(tok[2], &project->Landuse[j].sweepRemoval) ) return error_setInpError(ERR_NUMBER, tok[2]); if ( ! getDouble(tok[3], &project->Landuse[j].sweepDays0) ) return error_setInpError(ERR_NUMBER, tok[3]); } else { project->Landuse[j].sweepInterval = 0.0; project->Landuse[j].sweepRemoval = 0.0; project->Landuse[j].sweepDays0 = 0.0; } if ( project->Landuse[j].sweepRemoval < 0.0 || project->Landuse[j].sweepRemoval > 1.0 ) return error_setInpError(ERR_NUMBER, tok[2]); 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 readGageFileFormat(char* tok[], int ntoks, double x[]) { int m, u; DateTime aDate; DateTime aTime; // --- 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] *= 3600; 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_NUMBER, tok[3]); // --- get rain depth units u = findmatch(tok[7], RainUnitsWords); if ( u < 0 ) return error_setInpError(ERR_KEYWORD, tok[7]); x[6] = (double)u; // --- get start date (if present) if ( ntoks > 8 && *tok[8] != '*') { if ( !datetime_strToDate(tok[8], &aDate) ) return error_setInpError(ERR_DATETIME, tok[8]); x[4] = (float) aDate; } 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 project_readOption(char* s1, char* s2) // // Input: s1 = option keyword // s2 = string representation of option's value // Output: returns error code // Purpose: reads a project option from a pair of string tokens. // // NOTE: all project options have default values assigned in setDefaults(). // { int k, m, h, s; double tStep; char strDate[25]; DateTime aTime; DateTime aDate; // --- determine which option is being read k = findmatch(s1, OptionWords); if ( k < 0 ) return error_setInpError(ERR_KEYWORD, s1); switch ( k ) { // --- choice of flow units case FLOW_UNITS: m = findmatch(s2, FlowUnitWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); FlowUnits = m; if ( FlowUnits <= MGD ) UnitSystem = US; else UnitSystem = SI; break; // --- choice of infiltration modeling method case INFIL_MODEL: m = findmatch(s2, InfilModelWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); InfilModel = m; break; // --- choice of flow routing method case ROUTE_MODEL: m = findmatch(s2, RouteModelWords); if ( m < 0 ) m = findmatch(s2, OldRouteModelWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); if ( m == NO_ROUTING ) IgnoreRouting = TRUE; else RouteModel = m; if ( RouteModel == EKW ) RouteModel = KW; break; // --- simulation start date case START_DATE: if ( !datetime_strToDate(s2, &StartDate) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- simulation start time of day case START_TIME: if ( !datetime_strToTime(s2, &StartTime) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- simulation ending date case END_DATE: if ( !datetime_strToDate(s2, &EndDate) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- simulation ending time of day case END_TIME: if ( !datetime_strToTime(s2, &EndTime) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- reporting start date case REPORT_START_DATE: if ( !datetime_strToDate(s2, &ReportStartDate) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- reporting start time of day case REPORT_START_TIME: if ( !datetime_strToTime(s2, &ReportStartTime) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- day of year when street sweeping begins or when it ends // (year is arbitrarily set to 1947 so that the dayOfYear // function can be applied) case SWEEP_START: case SWEEP_END: strcpy(strDate, s2); strcat(strDate, "/1947"); if ( !datetime_strToDate(strDate, &aDate) ) { return error_setInpError(ERR_DATETIME, s2); } m = datetime_dayOfYear(aDate); if ( k == SWEEP_START ) SweepStart = m; else SweepEnd = m; break; // --- number of antecedent dry days case START_DRY_DAYS: StartDryDays = atof(s2); if ( StartDryDays < 0.0 ) { return error_setInpError(ERR_NUMBER, s2); } break; // --- runoff or reporting time steps // (input is in hrs:min:sec format, time step saved as seconds) case WET_STEP: case DRY_STEP: case REPORT_STEP: if ( !datetime_strToTime(s2, &aTime) ) { return error_setInpError(ERR_DATETIME, s2); } datetime_decodeTime(aTime, &h, &m, &s); h += 24*(int)aTime; s = s + 60*m + 3600*h; if ( s <= 0 ) return error_setInpError(ERR_NUMBER, s2); switch ( k ) { case WET_STEP: WetStep = s; break; case DRY_STEP: DryStep = s; break; case REPORT_STEP: ReportStep = s; break; } break; // --- type of damping applied to inertial terms of dynamic wave routing case INERT_DAMPING: m = findmatch(s2, InertDampingWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); else InertDamping = m; break; // --- Yes/No options (NO = 0, YES = 1) case ALLOW_PONDING: case SLOPE_WEIGHTING: case SKIP_STEADY_STATE: case IGNORE_RAINFALL: case IGNORE_SNOWMELT: case IGNORE_GWATER: case IGNORE_ROUTING: case IGNORE_QUALITY: case IGNORE_RDII: //(5.1.004) m = findmatch(s2, NoYesWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); switch ( k ) { case ALLOW_PONDING: AllowPonding = m; break; case SLOPE_WEIGHTING: SlopeWeighting = m; break; case SKIP_STEADY_STATE: SkipSteadyState = m; break; case IGNORE_RAINFALL: IgnoreRainfall = m; break; case IGNORE_SNOWMELT: IgnoreSnowmelt = m; break; case IGNORE_GWATER: IgnoreGwater = m; break; case IGNORE_ROUTING: IgnoreRouting = m; break; case IGNORE_QUALITY: IgnoreQuality = m; break; case IGNORE_RDII: IgnoreRDII = m; break; //(5.1.004) } break; case NORMAL_FLOW_LTD: m = findmatch(s2, NormalFlowWords); if ( m < 0 ) m = findmatch(s2, NoYesWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); NormalFlowLtd = m; break; case FORCE_MAIN_EQN: m = findmatch(s2, ForceMainEqnWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); ForceMainEqn = m; break; case LINK_OFFSETS: m = findmatch(s2, LinkOffsetWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); LinkOffsets = m; break; // --- compatibility option for selecting solution method for // dynamic wave flow routing (NOT CURRENTLY USED) case COMPATIBILITY: if ( strcomp(s2, "3") ) Compatibility = SWMM3; else if ( strcomp(s2, "4") ) Compatibility = SWMM4; else if ( strcomp(s2, "5") ) Compatibility = SWMM5; else return error_setInpError(ERR_KEYWORD, s2); break; // --- routing or lengthening time step (in decimal seconds) // (lengthening time step is used in Courant stability formula // to artificially lengthen conduits for dynamic wave flow routing // (a value of 0 means that no lengthening is used)) case ROUTE_STEP: case LENGTHENING_STEP: if ( !getDouble(s2, &tStep) ) { if ( !datetime_strToTime(s2, &aTime) ) { return error_setInpError(ERR_NUMBER, s2); } else { datetime_decodeTime(aTime, &h, &m, &s); h += 24*(int)aTime; s = s + 60*m + 3600*h; tStep = s; } } if ( k == ROUTE_STEP ) { if ( tStep <= 0.0 ) return error_setInpError(ERR_NUMBER, s2); RouteStep = tStep; } else LengtheningStep = MAX(0.0, tStep); break; // --- safety factor applied to variable time step estimates under // dynamic wave flow routing (value of 0 indicates that variable // time step option not used) case VARIABLE_STEP: if ( !getDouble(s2, &CourantFactor) ) return error_setInpError(ERR_NUMBER, s2); if ( CourantFactor < 0.0 || CourantFactor > 2.0 ) return error_setInpError(ERR_NUMBER, s2); break; // --- minimum surface area (ft2 or sq. meters) associated with nodes // under dynamic wave flow routing case MIN_SURFAREA: MinSurfArea = atof(s2); break; // --- minimum conduit slope (%) case MIN_SLOPE: if ( !getDouble(s2, &MinSlope) ) return error_setInpError(ERR_NUMBER, s2); if ( MinSlope < 0.0 || MinSlope >= 100 ) return error_setInpError(ERR_NUMBER, s2); MinSlope /= 100.0; break; // --- maximum trials / time step for dynamic wave routing case MAX_TRIALS: m = atoi(s2); if ( m < 0 ) return error_setInpError(ERR_NUMBER, s2); MaxTrials = m; break; // --- head convergence tolerance for dynamic wave routing case HEAD_TOL: if ( !getDouble(s2, &HeadTol) ) { return error_setInpError(ERR_NUMBER, s2); } break; // --- steady state tolerance on system inflow - outflow case SYS_FLOW_TOL: if ( !getDouble(s2, &SysFlowTol) ) { return error_setInpError(ERR_NUMBER, s2); } SysFlowTol /= 100.0; break; // --- steady state tolerance on nodal lateral inflow case LAT_FLOW_TOL: if ( !getDouble(s2, &LatFlowTol) ) { return error_setInpError(ERR_NUMBER, s2); } LatFlowTol /= 100.0; break; case TEMPDIR: // Temporary Directory sstrncpy(TempDir, s2, MAXFNAME); break; } 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 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 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 input_countObjects() // // Input: none // Output: returns error code // Purpose: reads input file to determine number of system objects. // { char line[MAXLINE+1]; // line from input data file char wLine[MAXLINE+1]; // working copy of input line char *tok; // first string token of line int sect = -1, newsect; // input data sections int errcode = 0; // error code int errsum = 0; // number of errors found int i; long lineCount = 0; // --- initialize number of objects & set default values if ( ErrorCode ) return ErrorCode; error_setInpError(0, ""); for (i = 0; i < MAX_OBJ_TYPES; i++) Nobjects[i] = 0; for (i = 0; i < MAX_NODE_TYPES; i++) Nnodes[i] = 0; for (i = 0; i < MAX_LINK_TYPES; i++) Nlinks[i] = 0; // --- make pass through data file counting number of each object while ( fgets(line, MAXLINE, Finp.file) != NULL ) { // --- skip blank lines & those beginning with a comment lineCount++; strcpy(wLine, line); // make working copy of line tok = strtok(wLine, SEPSTR); // get first text token on line if ( tok == NULL ) continue; if ( *tok == ';' ) continue; // --- check if line begins with a new section heading if ( *tok == '[' ) { // --- look for heading in list of section keywords newsect = findmatch(tok, SectWords); if ( newsect >= 0 ) { sect = newsect; continue; } else { sect = -1; errcode = ERR_KEYWORD; } } // --- if in OPTIONS section then read the option setting // otherwise add object and its ID name (tok) to project if ( sect == s_OPTION ) errcode = readOption(line); else if ( sect >= 0 ) errcode = addObject(sect, tok); // --- report any error found if ( errcode ) { report_writeInputErrorMsg(errcode, sect, line, lineCount); errsum++; if (errsum >= MAXERRS ) break; } } // --- set global error code if input errors were found if ( errsum > 0 ) ErrorCode = ERR_INPUT; return ErrorCode; }
int input_readData() // // Input: none // Output: returns error code // Purpose: reads input file to determine input parameters for each object. // { char line[MAXLINE+1]; // line from input data file char wLine[MAXLINE+1]; // working copy of input line char* comment; // ptr. to start of comment in input line int sect, newsect; // data sections int inperr, errsum; // error code & total error count int lineLength; // number of characters in input line int i; long lineCount = 0; // --- initialize working item count arrays // (final counts in Mobjects, Mnodes & Mlinks should // match those in Nobjects, Nnodes and Nlinks). if ( ErrorCode ) return ErrorCode; error_setInpError(0, ""); for (i = 0; i < MAX_OBJ_TYPES; i++) Mobjects[i] = 0; for (i = 0; i < MAX_NODE_TYPES; i++) Mnodes[i] = 0; for (i = 0; i < MAX_LINK_TYPES; i++) Mlinks[i] = 0; // --- initialize starting date for all time series for ( i = 0; i < Nobjects[TSERIES]; i++ ) { Tseries[i].lastDate = StartDate + StartTime; } // --- read each line from input file sect = 0; errsum = 0; rewind(Finp.file); while ( fgets(line, MAXLINE, Finp.file) != NULL ) { // --- make copy of line and scan for tokens lineCount++; strcpy(wLine, line); Ntokens = getTokens(wLine); // --- skip blank lines and comments if ( Ntokens == 0 ) continue; if ( *Tok[0] == ';' ) continue; // --- check if max. line length exceeded lineLength = strlen(line); if ( lineLength >= MAXLINE ) { // --- don't count comment if present comment = strchr(line, ';'); if ( comment ) lineLength = comment - line; // Pointer math here if ( lineLength >= MAXLINE ) { inperr = ERR_LINE_LENGTH; report_writeInputErrorMsg(inperr, sect, line, lineCount); errsum++; } } // --- check if at start of a new input section if (*Tok[0] == '[') { // --- match token against list of section keywords newsect = findmatch(Tok[0], SectWords); if (newsect >= 0) { // --- SPECIAL CASE FOR TRANSECTS // finish processing the last set of transect data if ( sect == s_TRANSECT ) transect_validate(Nobjects[TRANSECT]-1); // --- begin a new input section sect = newsect; continue; } else { inperr = error_setInpError(ERR_KEYWORD, Tok[0]); report_writeInputErrorMsg(inperr, sect, line, lineCount); errsum++; break; } } // --- otherwise parse tokens from input line else { inperr = parseLine(sect, line); if ( inperr > 0 ) { errsum++; if ( errsum > MAXERRS ) report_writeLine(FMT19); else report_writeInputErrorMsg(inperr, sect, line, lineCount); } } // --- stop if reach end of file or max. error count if (errsum > MAXERRS) break; } /* End of while */ // --- check for errors if (errsum > 0) ErrorCode = ERR_INPUT; return ErrorCode; }
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 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 gage_readParams(int j, char* tok[], int ntoks) // // Input: j = rain gage index // tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads rain gage parameters from a line of input data // // Data formats are: // Name RainType RecdFreq SCF TIMESERIES SeriesName // Name RainType RecdFreq SCF FILE FileName Station Units StartDate // { int k, err; char *id; char fname[MAXFNAME+1]; char staID[MAXMSG+1]; double x[7]; // --- check that gage exists if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, ""); id = project_findID(GAGE, tok[0]); if ( id == NULL ) return error_setInpError(ERR_NAME, tok[0]); // --- assign default parameter values x[0] = -1.0; // No time series index x[1] = 1.0; // Rain type is volume x[2] = 3600.0; // Recording freq. is 3600 sec x[3] = 1.0; // Snow catch deficiency factor x[4] = NO_DATE; // Default is no start/end date x[5] = NO_DATE; x[6] = 0.0; // US units strcpy(fname, ""); strcpy(staID, ""); if ( ntoks < 5 ) return error_setInpError(ERR_ITEMS, ""); k = findmatch(tok[4], GageDataWords); if ( k == RAIN_TSERIES ) { err = readGageSeriesFormat(tok, ntoks, x); } else if ( k == RAIN_FILE ) { if ( ntoks < 8 ) return error_setInpError(ERR_ITEMS, ""); sstrncpy(fname, tok[5], MAXFNAME); sstrncpy(staID, tok[6], MAXMSG); err = readGageFileFormat(tok, ntoks, x); } else return error_setInpError(ERR_KEYWORD, tok[4]); // --- save parameters to rain gage object if ( err > 0 ) return err; Gage[j].ID = id; Gage[j].tSeries = (int)x[0]; Gage[j].rainType = (int)x[1]; Gage[j].rainInterval = (int)x[2]; Gage[j].snowFactor = x[3]; Gage[j].rainUnits = (int)x[6]; if ( Gage[j].tSeries >= 0 ) Gage[j].dataSource = RAIN_TSERIES; else Gage[j].dataSource = RAIN_FILE; if ( Gage[j].dataSource == RAIN_FILE ) { sstrncpy(Gage[j].fname, fname, MAXFNAME); sstrncpy(Gage[j].staID, staID, MAXMSG); Gage[j].startFileDate = x[4]; Gage[j].endFileDate = x[5]; } Gage[j].unitsFactor = 1.0; Gage[j].coGage = -1; Gage[j].isUsed = FALSE; 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; }