GCC Code Coverage Report


Directory: src/solver/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 77.9% 194 / 0 / 249
Functions: 93.3% 14 / 0 / 15
Branches: 55.1% 102 / 0 / 185

iface.c
Line Branch Exec Source
1 //-----------------------------------------------------------------------------
2 // iface.c
3 //
4 // Project: EPA SWMM5
5 // Version: 5.2
6 // Date: 11/01/21 (Build 5.2.0)
7 // Author: L. Rossman
8 //
9 // Routing interface file functions.
10 //
11 // Build 5.2.0:
12 // - Support added for relative file names.
13 //-----------------------------------------------------------------------------
14 #define _CRT_SECURE_NO_DEPRECATE
15
16 #include <stdlib.h>
17 #include <string.h>
18 #include "headers.h"
19
20 //-----------------------------------------------------------------------------
21 // Imported variables
22 //-----------------------------------------------------------------------------
23 extern double Qcf[]; // flow units conversion factors
24 // (see swmm5.c)
25
26 //-----------------------------------------------------------------------------
27 // Shared variables
28 //-----------------------------------------------------------------------------
29 static int IfaceFlowUnits; // flow units for routing interface file
30 static int IfaceStep; // interface file time step (sec)
31 static int NumIfacePolluts; // number of pollutants in interface file
32 static int* IfacePolluts; // indexes of interface file pollutants
33 static int NumIfaceNodes; // number of nodes on interface file
34 static int* IfaceNodes; // indexes of nodes on interface file
35 static double** OldIfaceValues; // interface flows & WQ at previous time
36 static double** NewIfaceValues; // interface flows & WQ at next time
37 static double IfaceFrac; // fraction of interface file time step
38 static DateTime OldIfaceDate; // previous date of interface values
39 static DateTime NewIfaceDate; // next date of interface values
40
41 //-----------------------------------------------------------------------------
42 // External Functions (declared in funcs.h)
43 //-----------------------------------------------------------------------------
44 // iface_readFileParams (called by input_readLine)
45 // iface_openRoutingFiles (called by routing_open)
46 // iface_closeRoutingFiles (called by routing_close)
47 // iface_getNumIfaceNodes (called by addIfaceInflows in routing.c)
48 // iface_getIfaceNode (called by addIfaceInflows in routing.c)
49 // iface_getIfaceFlow (called by addIfaceInflows in routing.c)
50 // iface_getIfaceQual (called by addIfaceInflows in routing.c)
51 // iface_saveOutletResults (called by output_saveResults)
52
53 //-----------------------------------------------------------------------------
54 // Local functions
55 //-----------------------------------------------------------------------------
56 static void openFileForOutput(void);
57 static void openFileForInput(void);
58 static int getIfaceFilePolluts(void);
59 static int getIfaceFileNodes(void);
60 static void setOldIfaceValues(void);
61 static void readNewIfaceValues(void);
62 static int isOutletNode(int node);
63
64 //=============================================================================
65
66 13 int iface_readFileParams(char* tok[], int ntoks)
67 //
68 // Input: tok[] = array of string tokens
69 // ntoks = number of tokens
70 // Output: returns an error code
71 // Purpose: reads interface file information from a line of input data.
72 //
73 // Data format is:
74 // USE/SAVE FileType FileName
75 //
76 {
77 char k;
78 int j;
79 char fname[MAXFNAME+1];
80
81 // --- determine file disposition and type
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, "");
83 13 k = (char)findmatch(tok[0], FileModeWords);
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if ( k < 0 ) return error_setInpError(ERR_KEYWORD, tok[0]);
85 13 j = findmatch(tok[1], FileTypeWords);
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if ( j < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]);
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if ( ntoks < 3 ) return 0;
88 13 sstrncpy(fname, tok[2], MAXFNAME);
89
90 // --- process file name
91
6/7
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
13 switch ( j )
92 {
93 2 case RAINFALL_FILE:
94 2 Frain.mode = k;
95 2 sstrncpy(Frain.name, addAbsolutePath(fname), MAXFNAME);
96 2 break;
97
98 4 case RUNOFF_FILE:
99 4 Frunoff.mode = k;
100 4 sstrncpy(Frunoff.name, addAbsolutePath(fname), MAXFNAME);
101 4 break;
102
103 2 case HOTSTART_FILE:
104
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 if ( k == USE_FILE )
105 {
106 1 Fhotstart1.mode = k;
107 1 sstrncpy(Fhotstart1.name, addAbsolutePath(fname), MAXFNAME);
108 }
109
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 else if ( k == SAVE_FILE )
110 {
111 1 Fhotstart2.mode = k;
112 1 sstrncpy(Fhotstart2.name, addAbsolutePath(fname), MAXFNAME);
113 }
114 2 break;
115
116 3 case RDII_FILE:
117 3 Frdii.mode = k;
118 3 sstrncpy(Frdii.name, fname, MAXFNAME);
119 3 break;
120
121 1 case INFLOWS_FILE:
122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( k != USE_FILE ) return error_setInpError(ERR_ITEMS, "");
123 1 Finflows.mode = k;
124 1 sstrncpy(Finflows.name, addAbsolutePath(fname), MAXFNAME);
125 1 break;
126
127 1 case OUTFLOWS_FILE:
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( k != SAVE_FILE ) return error_setInpError(ERR_ITEMS, "");
129 1 Foutflows.mode = k;
130 1 sstrncpy(Foutflows.name, addAbsolutePath(fname), MAXFNAME);
131 1 break;
132 }
133 13 return 0;
134 }
135
136 //=============================================================================
137
138 58 void iface_openRoutingFiles()
139 //
140 // Input: none
141 // Output: none
142 // Purpose: opens routing interface files.
143 //
144 {
145 // --- initialize shared variables
146 58 NumIfacePolluts = 0;
147 58 IfacePolluts = NULL;
148 58 NumIfaceNodes = 0;
149 58 IfaceNodes = NULL;
150 58 OldIfaceValues = NULL;
151 58 NewIfaceValues = NULL;
152
153 // --- check that inflows & outflows files are not the same
154
3/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
58 if ( Foutflows.mode != NO_FILE && Finflows.mode != NO_FILE )
155 {
156 if ( strcomp(Foutflows.name, Finflows.name) )
157 {
158 report_writeErrorMsg(ERR_ROUTING_FILE_NAMES, "");
159 return;
160 }
161 }
162
163 // --- open the file for reading or writing
164
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 if ( Foutflows.mode == SAVE_FILE ) openFileForOutput();
165
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 if ( Finflows.mode == USE_FILE ) openFileForInput();
166 }
167
168 //=============================================================================
169
170 58 void iface_closeRoutingFiles()
171 //
172 // Input: none
173 // Output: none
174 // Purpose: closes routing interface files.
175 //
176 {
177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 FREE(IfacePolluts);
178
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 FREE(IfaceNodes);
179
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 if ( OldIfaceValues != NULL ) project_freeMatrix(OldIfaceValues);
180
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 if ( NewIfaceValues != NULL ) project_freeMatrix(NewIfaceValues);
181
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 if ( Finflows.file ) fclose(Finflows.file);
182
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 if ( Foutflows.file ) fclose(Foutflows.file);
183 58 }
184
185 //=============================================================================
186
187 4321 int iface_getNumIfaceNodes(DateTime currentDate)
188 //
189 // Input: currentDate = current date/time
190 // Output: returns number of interface nodes if data exists or
191 // 0 otherwise
192 // Purpose: reads inflow data from interface file at current date.
193 //
194 {
195 // --- return 0 if file begins after current date
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4321 times.
4321 if ( OldIfaceDate > currentDate ) return 0;
197
198 // --- keep updating new interface values until current date bracketed
199
3/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4321 times.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
4393 while ( NewIfaceDate < currentDate && NewIfaceDate != NO_DATE )
200 {
201 72 setOldIfaceValues();
202 72 readNewIfaceValues();
203 }
204
205 // --- return 0 if no data available
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4321 times.
4321 if ( NewIfaceDate == NO_DATE ) return 0;
207
208 // --- find fraction current date is bewteen old & new interface dates
209 4321 IfaceFrac = (currentDate - OldIfaceDate) / (NewIfaceDate - OldIfaceDate);
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4321 times.
4321 IfaceFrac = MAX(0.0, IfaceFrac);
211
1/2
✓ Branch 0 taken 4321 times.
✗ Branch 1 not taken.
4321 IfaceFrac = MIN(IfaceFrac, 1.0);
212
213 // --- return number of interface nodes
214 4321 return NumIfaceNodes;
215 }
216
217 //=============================================================================
218
219 4321 int iface_getIfaceNode(int index)
220 //
221 // Input: index = interface file node index
222 // Output: returns project node index
223 // Purpose: finds index of project node associated with interface node index
224 //
225 {
226
2/4
✓ Branch 0 taken 4321 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4321 times.
✗ Branch 3 not taken.
4321 if ( index >= 0 && index < NumIfaceNodes ) return IfaceNodes[index];
227 else return -1;
228 }
229
230 //=============================================================================
231
232 4321 double iface_getIfaceFlow(int index)
233 //
234 // Input: index = interface file node index
235 // Output: returns inflow to node
236 // Purpose: finds interface flow for particular node index.
237 //
238 {
239 double q1, q2;
240
241
2/4
✓ Branch 0 taken 4321 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4321 times.
✗ Branch 3 not taken.
4321 if ( index >= 0 && index < NumIfaceNodes )
242 {
243 // --- interpolate flow between old and new values
244 4321 q1 = OldIfaceValues[index][0];
245 4321 q2 = NewIfaceValues[index][0];
246 4321 return (1.0 - IfaceFrac)*q1 + IfaceFrac*q2;
247 }
248 else return 0.0;
249 }
250
251 //=============================================================================
252
253 double iface_getIfaceQual(int index, int pollut)
254 //
255 // Input: index = index of node on interface file
256 // pollut = index of pollutant on interface file
257 // Output: returns inflow pollutant concentration
258 // Purpose: finds interface concentration for particular node index & pollutant.
259 //
260 {
261 int j;
262 double c1, c2;
263
264 if ( index >= 0 && index < NumIfaceNodes )
265 {
266 // --- find index of pollut on interface file
267 j = IfacePolluts[pollut];
268 if ( j < 0 ) return 0.0;
269
270 // --- interpolate flow between old and new values
271 // (remember that 1st col. of values matrix is for flow)
272 c1 = OldIfaceValues[index][j+1];
273 c2 = NewIfaceValues[index][j+1];
274 return (1.0 - IfaceFrac)*c1 + IfaceFrac*c2;
275 }
276 else return 0.0;
277 }
278
279 //=============================================================================
280
281 73 void iface_saveOutletResults(DateTime reportDate, FILE* file)
282 //
283 // Input: reportDate = reporting date/time
284 // file = ptr. to interface file
285 // Output: none
286 // Purpose: saves system outflows to routing interface file.
287 //
288 {
289 int i, p, yr, mon, day, hr, min, sec;
290 char theDate[26];
291 73 datetime_decodeDate(reportDate, &yr, &mon, &day);
292 73 datetime_decodeTime(reportDate, &hr, &min, &sec);
293 73 snprintf(theDate, 26, " %04d %02d %02d %02d %02d %02d ",
294 yr, mon, day, hr, min, sec);
295
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 73 times.
219 for (i=0; i<Nobjects[NODE]; i++)
296 {
297 // --- check that node is an outlet node
298
2/2
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 73 times.
146 if ( !isOutletNode(i) ) continue;
299
300 // --- write node ID, date, flow, and quality to file
301 73 fprintf(file, "\n%-16s", Node[i].ID);
302 73 fprintf(file, "%s", theDate);
303 73 fprintf(file, " %-10f", Node[i].inflow * UCF(FLOW));
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 for ( p = 0; p < Nobjects[POLLUT]; p++ )
305 {
306 fprintf(file, " %-10f", Node[i].newQual[p]);
307 }
308 }
309 73 }
310
311 //=============================================================================
312
313 1 void openFileForOutput()
314 //
315 // Input: none
316 // Output: none
317 // Purpose: opens a routing interface file for writing.
318 //
319 {
320 int i, n;
321
322 // --- open the routing file for writing text
323 1 Foutflows.file = fopen(Foutflows.name, "wt");
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( Foutflows.file == NULL )
325 {
326 report_writeErrorMsg(ERR_ROUTING_FILE_OPEN, Foutflows.name);
327 return;
328 }
329
330 // --- write title & reporting time step to file
331 1 fprintf(Foutflows.file, "SWMM5 Interface File");
332 1 fprintf(Foutflows.file, "\n%s", Title[0]);
333 1 fprintf(Foutflows.file, "\n%-4d - reporting time step in sec", ReportStep);
334
335 // --- write number & names of each constituent (including flow) to file
336 1 fprintf(Foutflows.file, "\n%-4d - number of constituents as listed below:",
337 1 Nobjects[POLLUT] + 1);
338 1 fprintf(Foutflows.file, "\nFLOW %s", FlowUnitWords[FlowUnits]);
339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (i=0; i<Nobjects[POLLUT]; i++)
340 {
341 fprintf(Foutflows.file, "\n%s %s", Pollut[i].ID,
342 QualUnitsWords[Pollut[i].units]);
343 }
344
345 // --- count number of outlet nodes
346 1 n = 0;
347
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 for (i=0; i<Nobjects[NODE]; i++)
348 {
349
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2 if ( isOutletNode(i) ) n++;
350 }
351
352 // --- write number and names of outlet nodes to file
353 1 fprintf(Foutflows.file, "\n%-4d - number of nodes as listed below:", n);
354
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 for (i=0; i<Nobjects[NODE]; i++)
355 {
356
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2 if ( isOutletNode(i) )
357 1 fprintf(Foutflows.file, "\n%s", Node[i].ID);
358 }
359
360 // --- write column headings
361 1 fprintf(Foutflows.file,
362 "\nNode Year Mon Day Hr Min Sec FLOW ");
363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (i=0; i<Nobjects[POLLUT]; i++)
364 {
365 fprintf(Foutflows.file, " %-10s", Pollut[i].ID);
366 }
367
368 // --- if reporting starts immediately, save initial outlet values
369
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if ( ReportStart == StartDateTime )
370 {
371 1 iface_saveOutletResults(ReportStart, Foutflows.file);
372 }
373 }
374
375 //=============================================================================
376
377 1 void openFileForInput()
378 //
379 // Input: none
380 // Output: none
381 // Purpose: opens a routing interface file for reading.
382 //
383 {
384 int err; // error code
385 char line[MAXLINE+1]; // line from Routing interface file
386 char s[MAXLINE+1]; // general string variable
387
388 // --- open the routing interface file for reading text
389 1 Finflows.file = fopen(Finflows.name, "rt");
390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( Finflows.file == NULL )
391 {
392 report_writeErrorMsg(ERR_ROUTING_FILE_OPEN, Finflows.name);
393 return;
394 }
395
396 // --- check for correct file type
397 1 fgets(line, MAXLINE, Finflows.file);
398
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
1 if ( !sscanf(line, "%s", s) || !strcomp(s, "SWMM5") )
399 {
400 report_writeErrorMsg(ERR_ROUTING_FILE_FORMAT, Finflows.name);
401 return;
402 }
403
404 // --- skip title line
405 1 fgets(line, MAXLINE, Finflows.file);
406
407 // --- read reporting time step (sec)
408 1 IfaceStep = 0;
409 1 fgets(line, MAXLINE, Finflows.file);
410
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if ( !sscanf(line, "%d", &IfaceStep) || IfaceStep <= 0 )
411 {
412 report_writeErrorMsg(ERR_ROUTING_FILE_FORMAT, Finflows.name);
413 return;
414 }
415
416 // --- match constituents in file with those in project
417 1 err = getIfaceFilePolluts();
418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( err > 0 )
419 {
420 report_writeErrorMsg(err, Finflows.name);
421 return;
422 }
423
424 // --- match nodes in file with those in project
425 1 err = getIfaceFileNodes();
426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( err > 0 )
427 {
428 report_writeErrorMsg(err, Finflows.name);
429 return;
430 }
431
432 // --- create matrices for old & new interface flows & WQ values
433 1 OldIfaceValues = project_createMatrix(NumIfaceNodes,
434 1+NumIfacePolluts);
435 1 NewIfaceValues = project_createMatrix(NumIfaceNodes,
436 1+NumIfacePolluts);
437
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if ( OldIfaceValues == NULL || NewIfaceValues == NULL )
438 {
439 report_writeErrorMsg(ERR_MEMORY, "");
440 return;
441 }
442
443 // --- read in new interface flows & WQ values
444 1 readNewIfaceValues();
445 1 OldIfaceDate = NewIfaceDate;
446 }
447
448 //=============================================================================
449
450 1 int getIfaceFilePolluts()
451 //
452 // Input: none
453 // Output: returns an error code
454 // Purpose: reads names of pollutants saved on the inflows interface file.
455 //
456 {
457 int i, j;
458 char line[MAXLINE+1]; // line from inflows interface file
459 char s1[MAXLINE+1]; // general string variable
460 char s2[MAXLINE+1];
461
462 // --- read number of pollutants (minus FLOW)
463 1 fgets(line, MAXLINE, Finflows.file);
464 1 NumIfacePolluts = -1;
465
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if (sscanf(line, "%d", &NumIfacePolluts))
466 1 NumIfacePolluts--;
467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( NumIfacePolluts < 0 ) return ERR_ROUTING_FILE_FORMAT;
468
469 // --- read flow units
470 1 fgets(line, MAXLINE, Finflows.file);
471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (sscanf(line, "%s %s", s1, s2) < 2)
472 return ERR_ROUTING_FILE_FORMAT;
473
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if ( !strcomp(s1, "FLOW") )
474 return ERR_ROUTING_FILE_FORMAT;
475 1 IfaceFlowUnits = findmatch(s2, FlowUnitWords);
476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( IfaceFlowUnits < 0 )
477 return ERR_ROUTING_FILE_FORMAT;
478
479 // --- allocate memory for pollutant index array
480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( Nobjects[POLLUT] > 0 )
481 {
482 IfacePolluts = (int *) calloc(Nobjects[POLLUT], sizeof(int));
483 if ( !IfacePolluts ) return ERR_MEMORY;
484 for (i=0; i<Nobjects[POLLUT]; i++) IfacePolluts[i] = -1;
485 }
486
487 // --- read pollutant names & units
488
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ( NumIfacePolluts > 0 && Nobjects[POLLUT] > 0 )
489 {
490 // --- check each pollutant name on file with project's pollutants
491 for (i=0; i<NumIfacePolluts; i++)
492 {
493 if ( feof(Finflows.file) )
494 return ERR_ROUTING_FILE_FORMAT;
495 fgets(line, MAXLINE, Finflows.file);
496 if ( sscanf(line, "%s %s", s1, s2) < 2 )
497 return ERR_ROUTING_FILE_FORMAT;
498 j = project_findObject(POLLUT, s1);
499 if ( j < 0 ) continue;
500 if ( !strcomp(s2, QualUnitsWords[Pollut[j].units]) )
501 return ERR_ROUTING_FILE_NOMATCH;
502 IfacePolluts[j] = i;
503 }
504 }
505 1 return 0;
506 }
507
508 //=============================================================================
509
510 1 int getIfaceFileNodes()
511 //
512 // Input: none
513 // Output: returns an error code
514 // Purpose: reads names of nodes contained on inflows interface file.
515 //
516 {
517 int i;
518 char line[MAXLINE+1]; // line from inflows interface file
519 char s[MAXLINE+1]; // general string variable
520
521 // --- read number of interface nodes
522 1 fgets(line, MAXLINE, Finflows.file);
523
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if ( !sscanf(line, "%d", &NumIfaceNodes) || NumIfaceNodes <= 0 )
524 return ERR_ROUTING_FILE_FORMAT;
525
526 // --- allocate memory for interface nodes index array
527 1 IfaceNodes = (int *) calloc(NumIfaceNodes, sizeof(int));
528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( !IfaceNodes ) return ERR_MEMORY;
529
530 // --- read names of interface nodes from file & save their indexes
531
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 for ( i=0; i<NumIfaceNodes; i++ )
532 {
533
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if ( feof(Finflows.file) )
534 return ERR_ROUTING_FILE_FORMAT;
535 1 IfaceNodes[i] = 0;
536 1 fgets(line, MAXLINE, Finflows.file);
537
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (!sscanf(line, "%s", s))
538 return ERR_ROUTING_FILE_FORMAT;
539 1 IfaceNodes[i] = project_findObject(NODE, s);
540 }
541
542 // --- skip over column headings line
543
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if ( feof(Finflows.file) ) return ERR_ROUTING_FILE_FORMAT;
544 1 fgets(line, MAXLINE, Finflows.file);
545 1 return 0;
546 }
547
548 //=============================================================================
549
550 73 void readNewIfaceValues()
551 //
552 // Input: none
553 // Output: none
554 // Purpose: reads data from inflows interface file for next date.
555 //
556 {
557 int i, j;
558 char* s;
559 73 int yr = 0, mon = 0, day = 0,
560 73 hr = 0, min = 0, sec = 0; // year, month, day, hour, minute, second
561 char line[MAXLINE+1]; // line from interface file
562
563 // --- read a line for each interface node
564 73 NewIfaceDate = NO_DATE;
565
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 73 times.
146 for (i=0; i<NumIfaceNodes; i++)
566 {
567
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
73 if ( feof(Finflows.file) ) return;
568 73 fgets(line, MAXLINE, Finflows.file);
569
570 // --- parse date & time from line
571
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
73 if ( strtok(line, SEPSTR) == NULL ) return;
572 73 s = strtok(NULL, SEPSTR);
573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if ( s == NULL ) return;
574 73 yr = atoi(s);
575 73 s = strtok(NULL, SEPSTR);
576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if ( s == NULL ) return;
577 73 mon = atoi(s);
578 73 s = strtok(NULL, SEPSTR);
579
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if ( s == NULL ) return;
580 73 day = atoi(s);
581 73 s = strtok(NULL, SEPSTR);
582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if ( s == NULL ) return;
583 73 hr = atoi(s);
584 73 s = strtok(NULL, SEPSTR);
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if ( s == NULL ) return;
586 73 min = atoi(s);
587 73 s = strtok(NULL, SEPSTR);
588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if ( s == NULL ) return;
589 73 sec = atoi(s);
590
591 // --- parse flow value
592 73 s = strtok(NULL, SEPSTR);
593
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if ( s == NULL ) return;
594 73 NewIfaceValues[i][0] = atof(s) / Qcf[IfaceFlowUnits];
595
596 // --- parse pollutant values
597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 for (j=1; j<=NumIfacePolluts; j++)
598 {
599 s = strtok(NULL, SEPSTR);
600 if ( s == NULL ) return;
601 NewIfaceValues[i][j] = atof(s);
602 }
603
604 }
605
606 // --- encode date & time values
607 146 NewIfaceDate = datetime_encodeDate(yr, mon, day) +
608 73 datetime_encodeTime(hr, min, sec);
609 }
610
611 //=============================================================================
612
613 72 void setOldIfaceValues()
614 //
615 // Input: none
616 // Output: none
617 // Purpose: replaces old values read from routing interface file with new ones.
618 //
619 {
620 int i, j;
621 72 OldIfaceDate = NewIfaceDate;
622
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 72 times.
144 for ( i=0; i<NumIfaceNodes; i++)
623 {
624
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 72 times.
144 for ( j=0; j<NumIfacePolluts+1; j++ )
625 {
626 72 OldIfaceValues[i][j] = NewIfaceValues[i][j];
627 }
628 }
629 72 }
630
631 //=============================================================================
632
633 150 int isOutletNode(int i)
634 //
635 // Input: i = node index
636 // Output: returns 1 if node is an outlet, 0 if not.
637 // Purpose: determines if a node is an outlet point or not.
638 //
639 {
640 // --- for DW routing only outfalls are outlets
641
1/2
✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
150 if ( RouteModel == DW )
642 {
643 150 return (Node[i].type == OUTFALL);
644 }
645
646 // --- otherwise outlets are nodes with no outflow links (degree is 0)
647 else return (Node[i].degree == 0);
648 }
649