GCC Code Coverage Report


Directory: src/solver/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 88.9% 160 / 0 / 180
Functions: 100.0% 11 / 0 / 11
Branches: 69.0% 107 / 0 / 155

inflow.c
Line Branch Exec Source
1 //-----------------------------------------------------------------------------
2 // inflow.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 // Manages any Direct External or Dry Weather Flow inflows
10 // that have been assigned to nodes of the drainage system.
11 //
12 // Update History
13 // ==============
14 // Build 5.2.0:
15 // - Removed references to unused extIfaceInflow member of ExtInflow struct.
16 //-----------------------------------------------------------------------------
17 #define _CRT_SECURE_NO_DEPRECATE
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include "headers.h"
22
23 //-----------------------------------------------------------------------------
24 // External Functions (declared in funcs.h)
25 //-----------------------------------------------------------------------------
26 // inflow_initDwfPattern (called createObjects in project.c)
27 // inflow_readExtInflow (called by input_readLine)
28 // inflow_readDwfInflow (called by input_readLine)
29 // inflow_deleteExtInflows (called by deleteObjects in project.c)
30 // inflow_deleteDwfInflows (called by deleteObjects in project.c)
31 // inflow_getExtInflow (called by addExternalInflows in routing.c)
32 // inflow_setExtInflow (called by setNodeInflow in swmm5.c)
33 // inflow_getDwfInflow (called by addDryWeatherInflows in routing.c)
34
35 //-----------------------------------------------------------------------------
36 // Local Functions
37 //-----------------------------------------------------------------------------
38 double getPatternFactor(int p, int month, int day, int hour);
39
40
41 266 int inflow_readExtInflow(char* tok[], int ntoks)
42 //
43 // Input: tok[] = array of string tokens
44 // ntoks = number of tokens
45 // Output: returns an error message
46 // Purpose: reads parameters of a direct external inflow from a line of input.
47 //
48 // Formats of data line are:
49 // nodeID FLOW tSeriesID (FLOW 1.0 scaleFactor baseline basePat)
50 // nodeID pollutID tSeriesID (CONCEN/MASS unitsFactor scaleFactor baseline basePat)
51 //
52 {
53 int j; // object index
54 int param; // FLOW (-1) or pollutant index
55 266 int type = CONCEN_INFLOW; // FLOW, CONCEN or MASS inflow
56 266 int tseries = -1; // time series index
57 266 int basePat = -1; // baseline pattern
58 266 double cf = 1.0; // units conversion factor
59 266 double sf = 1.0; // scaling factor
60 266 double baseline = 0.0; // baseline value
61
62 // --- find index of node receiving the inflow
63
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 266 times.
266 if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, "");
64 266 j = project_findObject(NODE, tok[0]);
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 266 times.
266 if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]);
66
67 // --- find index of inflow pollutant or use -1 for FLOW
68 266 param = project_findObject(POLLUT, tok[1]);
69
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 85 times.
266 if ( param < 0 )
70 {
71
1/2
✓ Branch 1 taken 181 times.
✗ Branch 2 not taken.
181 if ( match(tok[1], w_FLOW) ) param = -1;
72 else return error_setInpError(ERR_NAME, tok[1]);
73 }
74
75 // --- find index of inflow time series (if supplied) in data base
76
2/2
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 185 times.
266 if ( strlen(tok[2]) > 0 )
77 {
78 81 tseries = project_findObject(TSERIES, tok[2]);
79
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
81 if ( tseries < 0 ) return error_setInpError(ERR_NAME, tok[2]);
80 81 Tseries[tseries].refersTo = EXTERNAL_INFLOW;
81 }
82
83 // --- assign type & cf values for a FLOW inflow
84
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 85 times.
266 if (param == -1)
85 {
86 181 type = FLOW_INFLOW;
87 181 cf = 1.0/UCF(FLOW);
88 }
89
90 // --- do the same for a pollutant inflow
91
4/4
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 180 times.
266 if ( ntoks >= 4 && param > -1)
92 {
93
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 if ( match(tok[3], w_CONCEN) ) type = CONCEN_INFLOW;
94 else if ( match(tok[3], w_MASS) ) type = MASS_INFLOW;
95 else return error_setInpError(ERR_KEYWORD, tok[3]);
96
2/4
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 85 times.
85 if ( ntoks >= 5 && type == MASS_INFLOW )
97 {
98 if ( ! getDouble(tok[4], &cf) )
99 {
100 return error_setInpError(ERR_NUMBER, tok[4]);
101 }
102 if ( cf <= 0.0 ) return error_setInpError(ERR_NUMBER, tok[4]);
103 }
104 }
105
106 // --- get sf and baseline values
107
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 1 time.
266 if ( ntoks >= 6 )
108 {
109
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 265 times.
265 if ( ! getDouble(tok[5], &sf) )
110 {
111 return error_setInpError(ERR_NUMBER, tok[5]);
112 }
113 }
114
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 34 times.
266 if ( ntoks >= 7 )
115 {
116
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 232 times.
232 if ( ! getDouble(tok[6], &baseline) )
117 {
118 return error_setInpError(ERR_NUMBER, tok[6]);
119 }
120 }
121
122 // --- get baseline time pattern
123
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 264 times.
266 if ( ntoks >= 8 )
124 {
125 2 basePat = project_findObject(TIMEPATTERN, tok[7]);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( basePat < 0 ) return error_setInpError(ERR_NAME, tok[7]);
127 }
128
129 // --- include LperFT3 term in conversion factor for MASS_INFLOW
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 266 times.
266 if ( type == MASS_INFLOW ) cf /= LperFT3;
131
132 266 return(inflow_setExtInflow(j, param, type, tseries, basePat,
133 cf, baseline, sf));
134 }
135
136 //=============================================================================
137
138 266 int inflow_setExtInflow(int j, int param, int type, int tseries, int basePat,
139 double cf, double baseline, double sf)
140 // Purpose: This function assigns property values to the inflow object
141 // Inputs: j = Node index
142 // param = FLOW (-1) or pollutant index
143 // type = FLOW, CONCEN or MASS inflow
144 // tSeries = time series index
145 // basePat = baseline pattern
146 // cf = units conversion factor
147 // baseline = baseline inflow value
148 // sf = scaling factor
149 // Return: returns Error Code
150
151 {
152 TExtInflow* inflow; // external inflow object
153
154 // --- check if an external inflow object for this constituent already exists
155 266 inflow = Node[j].extInflow;
156
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 266 times.
267 while ( inflow )
157 {
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( inflow->param == param ) break;
159 1 inflow = inflow->next;
160 }
161
162 // --- if it doesn't exist, then create it
163
1/2
✓ Branch 0 taken 266 times.
✗ Branch 1 not taken.
266 if ( inflow == NULL )
164 {
165 266 inflow = (TExtInflow *) malloc(sizeof(TExtInflow));
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 266 times.
266 if ( inflow == NULL )
167 {
168 return error_setInpError(ERR_MEMORY, "");
169 }
170 266 inflow->next = Node[j].extInflow;
171 266 Node[j].extInflow = inflow;
172 }
173
174 // --- assign property values to the inflow object
175 266 inflow->param = param;
176 266 inflow->type = type;
177 266 inflow->tSeries = tseries;
178 266 inflow->cFactor = cf;
179 266 inflow->sFactor = sf;
180 266 inflow->baseline = baseline;
181 266 inflow->basePat = basePat;
182 266 return 0;
183 }
184
185 //=============================================================================
186
187 10183 void inflow_deleteExtInflows(int j)
188 //
189 // Input: j = node index
190 // Output: none
191 // Purpose: deletes all time series inflow data for a node.
192 //
193 {
194 TExtInflow* inflow1;
195 TExtInflow* inflow2;
196 10183 inflow1 = Node[j].extInflow;
197
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 10183 times.
10449 while ( inflow1 )
198 {
199 266 inflow2 = inflow1->next;
200 266 free(inflow1);
201 266 inflow1 = inflow2;
202 }
203 10183 }
204
205 //=============================================================================
206
207 1191123 double inflow_getExtInflow(TExtInflow* inflow, DateTime aDate)
208 //
209 // Input: inflow = external inflow data structure
210 // aDate = current simulation date/time
211 // Output: returns current value of external inflow parameter
212 // Purpose: retrieves the value of an external inflow at a specific
213 // date and time.
214 //
215 {
216 int month, day, hour;
217 1191123 int p = inflow->basePat; // baseline pattern
218 1191123 int k = inflow->tSeries; // time series index
219 1191123 double cf = inflow->cFactor; // units conversion factor
220 1191123 double sf = inflow->sFactor; // scaling factor
221 1191123 double blv = inflow->baseline; // baseline value
222 1191123 double tsv = 0.0; // time series value
223
224
2/2
✓ Branch 0 taken 12287 times.
✓ Branch 1 taken 1178836 times.
1191123 if ( p >= 0 )
225 {
226 12287 month = datetime_monthOfYear(aDate) - 1;
227 12287 day = datetime_dayOfWeek(aDate) - 1;
228 12287 hour = datetime_hourOfDay(aDate);
229 12287 blv *= getPatternFactor(p, month, day, hour);
230 }
231
2/2
✓ Branch 0 taken 1149863 times.
✓ Branch 1 taken 41260 times.
1191123 if ( k >= 0 ) tsv = table_tseriesLookup(&Tseries[k], aDate, FALSE) * sf;
232 1191123 return cf * (tsv + blv);
233 }
234
235 //=============================================================================
236
237 3943 int inflow_readDwfInflow(char* tok[], int ntoks)
238 //
239 // Input: tok[] = array of string tokens
240 // ntoks = number of tokens
241 // Output: returns an error message
242 // Purpose: reads dry weather inflow parameters from line of input data.
243 //
244 // Format of data line is:
245 // nodeID FLOW/pollutID avgValue (pattern1 pattern2 ... pattern4)
246 //
247 {
248 int i;
249 int j; // node index
250 int k; // pollutant index (-1 for flow)
251 int m; // time pattern index
252 int pats[4]; // time pattern index array
253 double x; // avg. DWF value
254 TDwfInflow* inflow; // dry weather flow inflow object
255
256 // --- find index of node receiving the inflow
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3943 times.
3943 if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, "");
258 3943 j = project_findObject(NODE, tok[0]);
259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3943 times.
3943 if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]);
260
261 // --- find index of inflow pollutant (-1 for FLOW)
262 3943 k = project_findObject(POLLUT, tok[1]);
263
2/2
✓ Branch 0 taken 3936 times.
✓ Branch 1 taken 7 times.
3943 if ( k < 0 )
264 {
265
1/2
✓ Branch 1 taken 3936 times.
✗ Branch 2 not taken.
3936 if ( match(tok[1], w_FLOW) ) k = -1;
266 else return error_setInpError(ERR_NAME, tok[1]);
267 }
268
269 // --- get avg. value of DWF inflow
270
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3943 times.
3943 if ( !getDouble(tok[2], &x) )
271 return error_setInpError(ERR_NUMBER, tok[2]);
272
2/2
✓ Branch 0 taken 3936 times.
✓ Branch 1 taken 7 times.
3943 if ( k == -1 ) x /= UCF(FLOW);
273
274 // --- get time patterns assigned to the inflow
275
2/2
✓ Branch 0 taken 15772 times.
✓ Branch 1 taken 3943 times.
19715 for (i=0; i<4; i++) pats[i] = -1;
276
2/2
✓ Branch 0 taken 15772 times.
✓ Branch 1 taken 3943 times.
19715 for (i=3; i<7; i++)
277 {
278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15772 times.
15772 if ( i >= ntoks ) break;
279
2/2
✓ Branch 0 taken 8176 times.
✓ Branch 1 taken 7596 times.
15772 if ( strlen(tok[i]) == 0 ) continue;
280 7596 m = project_findObject(TIMEPATTERN, tok[i]);
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7596 times.
7596 if ( m < 0 ) return error_setInpError(ERR_NAME, tok[i]);
282 7596 pats[i-3] = m;
283 }
284
285 // --- check if inflow for this constituent already exists
286 3943 inflow = Node[j].dwfInflow;
287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3943 times.
3943 while ( inflow )
288 {
289 if ( inflow->param == k ) break;
290 inflow = inflow->next;
291 }
292
293 // --- if it doesn't exist, then create it
294
1/2
✓ Branch 0 taken 3943 times.
✗ Branch 1 not taken.
3943 if ( inflow == NULL )
295 {
296 3943 inflow = (TDwfInflow *) malloc(sizeof(TDwfInflow));
297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3943 times.
3943 if ( inflow == NULL ) return error_setInpError(ERR_MEMORY, "");
298 3943 inflow->next = Node[j].dwfInflow;
299 3943 Node[j].dwfInflow = inflow;
300 }
301
302 // --- assign property values to the inflow object
303 3943 inflow->param = k;
304 3943 inflow->avgValue = x;
305
2/2
✓ Branch 0 taken 15772 times.
✓ Branch 1 taken 3943 times.
19715 for (i=0; i<4; i++) inflow->patterns[i] = pats[i];
306 3943 return 0;
307 }
308
309 //=============================================================================
310
311 10183 void inflow_deleteDwfInflows(int j)
312 //
313 // Input: j = node index
314 // Output: none
315 // Purpose: deletes all dry weather inflow data for a node.
316 //
317 {
318 TDwfInflow* inflow1;
319 TDwfInflow* inflow2;
320 10183 inflow1 = Node[j].dwfInflow;
321
2/2
✓ Branch 0 taken 3943 times.
✓ Branch 1 taken 10183 times.
14126 while ( inflow1 )
322 {
323 3943 inflow2 = inflow1->next;
324 3943 free(inflow1);
325 3943 inflow1 = inflow2;
326 }
327 10183 }
328
329 //=============================================================================
330
331 3943 void inflow_initDwfInflow(TDwfInflow* inflow)
332 //
333 // Input: inflow = dry weather inflow data structure
334 // Output: none
335 // Purpose: initialzes a dry weather inflow by ordering its time patterns.
336 //
337 // This function sorts the user-supplied time patterns for a dry weather
338 // inflow in the order of the PatternType enumeration (monthly, daily,
339 // weekday hourly, weekend hourly) to help speed up pattern processing.
340 //
341 {
342 int i, p;
343 int tmpPattern[4]; // index of each type of DWF pattern
344
345 // --- assume no patterns were supplied
346
2/2
✓ Branch 0 taken 15772 times.
✓ Branch 1 taken 3943 times.
19715 for (i=0; i<4; i++) tmpPattern[i] = -1;
347
348 // --- assign supplied patterns to proper position (by type) in tmpPattern
349
2/2
✓ Branch 0 taken 15772 times.
✓ Branch 1 taken 3943 times.
19715 for (i=0; i<4; i++)
350 {
351 15772 p = inflow->patterns[i];
352
2/2
✓ Branch 0 taken 7596 times.
✓ Branch 1 taken 8176 times.
15772 if ( p >= 0 ) tmpPattern[Pattern[p].type] = p;
353 }
354
355 // --- re-fill inflow pattern array by pattern type
356
2/2
✓ Branch 0 taken 15772 times.
✓ Branch 1 taken 3943 times.
19715 for (i=0; i<4; i++) inflow->patterns[i] = tmpPattern[i];
357 3943 }
358
359 //=============================================================================
360
361 17016441 double inflow_getDwfInflow(TDwfInflow* inflow, int month, int day, int hour)
362 //
363 // Input: inflow = dry weather inflow data structure
364 // month = current month of year of simulation
365 // day = current day of week of simulation
366 // hour = current hour of day of simulation
367 // Output: returns value of dry weather inflow parameter
368 // Purpose: computes dry weather inflow value at a specific point in time.
369 //
370 {
371 int p1, p2; // pattern index
372 17016441 double f = 1.0; // pattern factor
373
374 17016441 p1 = inflow->patterns[MONTHLY_PATTERN];
375
2/2
✓ Branch 0 taken 4303234 times.
✓ Branch 1 taken 12713207 times.
17016441 if ( p1 >= 0 ) f *= getPatternFactor(p1, month, day, hour);
376 17016441 p1 = inflow->patterns[DAILY_PATTERN];
377
2/2
✓ Branch 0 taken 12287 times.
✓ Branch 1 taken 17004154 times.
17016441 if ( p1 >= 0 ) f *= getPatternFactor(p1, month, day, hour);
378 17016441 p1 = inflow->patterns[HOURLY_PATTERN];
379 17016441 p2 = inflow->patterns[WEEKEND_PATTERN];
380
2/2
✓ Branch 0 taken 16942964 times.
✓ Branch 1 taken 73477 times.
17016441 if ( p2 >= 0 )
381 {
382
4/4
✓ Branch 0 taken 43624 times.
✓ Branch 1 taken 16899340 times.
✓ Branch 2 taken 422 times.
✓ Branch 3 taken 43202 times.
16942964 if ( day == 0 || day == 6 )
383 16899762 f *= getPatternFactor(p2, month, day, hour);
384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43202 times.
43202 else if ( p1 >= 0 )
385 f *= getPatternFactor(p1, month, day, hour);
386 }
387
1/2
✓ Branch 0 taken 73477 times.
✗ Branch 1 not taken.
73477 else if ( p1 >= 0 ) f *= getPatternFactor(p1, month, day, hour);
388 17016441 return f * inflow->avgValue;
389
390 }
391
392 //=============================================================================
393
394 452 void inflow_initDwfPattern(int j)
395 //
396 // Input: j = time pattern index
397 // Output: none
398 // Purpose: initialzes a dry weather inflow time pattern.
399 //
400 {
401 int i;
402
2/2
✓ Branch 0 taken 10848 times.
✓ Branch 1 taken 452 times.
11300 for (i=0; i<24; i++) Pattern[j].factor[i] = 1.0;
403 452 Pattern[j].count = 0;
404 452 Pattern[j].type = -1;
405 452 Pattern[j].ID = NULL;
406 452 }
407
408 //=============================================================================
409
410 1729 int inflow_readDwfPattern(char* tok[], int ntoks)
411 //
412 // Input: tok[] = array of string tokens
413 // ntoks = number of tokens
414 // Output: returns an error message
415 // Purpose: reads values of a time pattern from a line of input data.
416 //
417 // Format of data line is:
418 // patternID patternType value(1) value(2) ...
419 // patternID value(n) value(n+1) .... (for continuation lines)
420 {
421 1729 int i, j, k, n = 1;
422
423 // --- check for minimum number of tokens
424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1729 times.
1729 if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, "");
425
426 // --- check that pattern exists in database
427 1729 j = project_findObject(TIMEPATTERN, tok[0]);
428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1729 times.
1729 if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]);
429
430 // --- check if this is first line of pattern
431 // (ID pointer will not have been assigned yet)
432
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 1277 times.
1729 if ( Pattern[j].ID == NULL )
433 {
434 // --- assign ID pointer & pattern type
435 452 Pattern[j].ID = project_findID(TIMEPATTERN, tok[0]);
436 452 k = findmatch(tok[1], PatternTypeWords);
437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 452 times.
452 if ( k < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]);
438 452 Pattern[j].type = k;
439 452 n = 2;
440 }
441
442 // --- start reading pattern factors from rest of line
443
3/4
✓ Branch 0 taken 10324 times.
✓ Branch 1 taken 1729 times.
✓ Branch 2 taken 10324 times.
✗ Branch 3 not taken.
12053 while ( ntoks > n && Pattern[j].count < 24 )
444 {
445 10324 i = Pattern[j].count;
446
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10324 times.
10324 if ( !getDouble(tok[n], &Pattern[j].factor[i]) )
447 return error_setInpError(ERR_NUMBER, tok[n]);
448 10324 Pattern[j].count++;
449 10324 n++;
450 }
451 1729 return 0;
452 }
453
454 //=============================================================================
455
456 21301047 double getPatternFactor(int p, int month, int day, int hour)
457 //
458 // Input: p = time pattern index
459 // month = current month of year of simulation
460 // day = current day of week of simulation
461 // hour = current hour of day of simulation
462 // Output: returns value of a time pattern multiplier
463 // Purpose: computes time pattern multiplier for a specific point in time.
464 {
465
4/5
✓ Branch 0 taken 4315521 times.
✓ Branch 1 taken 12287 times.
✓ Branch 2 taken 73477 times.
✓ Branch 3 taken 16899762 times.
✗ Branch 4 not taken.
21301047 switch ( Pattern[p].type )
466 {
467 4315521 case MONTHLY_PATTERN:
468
2/4
✓ Branch 0 taken 4315521 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4315521 times.
✗ Branch 3 not taken.
4315521 if ( month >= 0 && month < 12 ) return Pattern[p].factor[month];
469 break;
470 12287 case DAILY_PATTERN:
471
2/4
✓ Branch 0 taken 12287 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12287 times.
✗ Branch 3 not taken.
12287 if ( day >= 0 && day < 7 ) return Pattern[p].factor[day];
472 break;
473 73477 case HOURLY_PATTERN:
474
2/4
✓ Branch 0 taken 73477 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73477 times.
✗ Branch 3 not taken.
73477 if ( hour >= 0 && hour < 24 ) return Pattern[p].factor[hour];
475 break;
476 16899762 case WEEKEND_PATTERN:
477
3/4
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 16899340 times.
✓ Branch 2 taken 422 times.
✗ Branch 3 not taken.
16899762 if ( day == 0 || day == 6 )
478 {
479
2/4
✓ Branch 0 taken 16899762 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16899762 times.
✗ Branch 3 not taken.
16899762 if ( hour >= 0 && hour < 24 ) return Pattern[p].factor[hour];
480 }
481 break;
482 }
483 return 1.0;
484 }
485