GCC Code Coverage Report


Directory: src/solver/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 86.9% 398 / 0 / 458
Functions: 96.3% 26 / 0 / 27
Branches: 62.8% 169 / 0 / 269

massbal.c
Line Branch Exec Source
1 //-----------------------------------------------------------------------------
2 // massbal.c
3 //
4 // Project: EPA SWMM5
5 // Version: 5.2
6 // Date: 11/01/21 (Build 5.2.0)
7 // Author: L. Rossman
8 // M. Tryby (EPA)
9 //
10 // Mass balance functions
11 //
12 // Update History
13 // ==============
14 // Build 5.1.007:
15 // - Mass balances modified to to correctly handle negative external inflows.
16 // - Volume from minimum surface area at nodes included in mass balances.
17 // Build 5.1.008:
18 // - massbal_updateRunoffTotals() modified.
19 // - LID drain flows and returned outfall flows added to components of
20 // runoff mass balance.
21 // - Seepage pollutant loss added into mass balances.
22 // Build 5.1.010:
23 // - Remaining pollutant mass in "dry" elements now added to final storage.
24 // Build 5.1.011:
25 // - Final stored pollutant mass in links ignored for Steady Flow routing.
26 // Build 5.1.012:
27 // - Terminal storage nodes no longer treated as non-storage terminal
28 // nodes are when updating total outflow volume.
29 // Build 5.1.013:
30 // - Volume from MinSurfArea no longer included in initial & final storage.
31 //-----------------------------------------------------------------------------
32 #define _CRT_SECURE_NO_DEPRECATE
33
34 #include <string.h>
35 #include <stdlib.h>
36 #include <math.h>
37 #include "headers.h"
38
39 //-----------------------------------------------------------------------------
40 // Constants
41 //-----------------------------------------------------------------------------
42 static const double MAX_RUNOFF_BALANCE_ERR = 10.0;
43 static const double MAX_FLOW_BALANCE_ERR = 10.0;
44
45 //-----------------------------------------------------------------------------
46 // Shared variables
47 //-----------------------------------------------------------------------------
48 TRunoffTotals RunoffTotals; // overall surface runoff continuity totals
49 TLoadingTotals* LoadingTotals; // overall WQ washoff continuity totals
50 TGwaterTotals GwaterTotals; // overall groundwater continuity totals
51 TRoutingTotals FlowTotals; // overall routed flow continuity totals
52 TRoutingTotals* QualTotals; // overall routed WQ continuity totals
53 TRoutingTotals StepFlowTotals; // routed flow totals over time step
54 TRoutingTotals OldStepFlowTotals;
55 TRoutingTotals* StepQualTotals; // routed WQ totals over time step
56
57 //-----------------------------------------------------------------------------
58 // Exportable variables
59 //-----------------------------------------------------------------------------
60 double* NodeInflow; // total inflow volume to each node (ft3)
61 double* NodeOutflow; // total outflow volume from each node (ft3)
62 double TotalArea; // total drainage area (ft2)
63
64 //-----------------------------------------------------------------------------
65 // External functions (declared in funcs.h)
66 //-----------------------------------------------------------------------------
67 // massbal_open (called from swmm_start in swmm5.c)
68 // massbal_close (called from swmm_end in swmm5.c)
69 // massbal_report (called from swmm_end in swmm5.c)
70 // massbal_updateRunoffTotals (called from subcatch_getRunoff)
71 // massbal_updateDrainTotals (called from evalLidUnit in lid.c)
72 // massbal_updateLoadingTotals (called from subcatch_getBuildup)
73 // massbal_updateGwaterTotals (called from updateMassBal in gwater.c)
74 // massbal_updateRoutingTotals (called from routing_execute)
75 // massbal_initTimeStepTotals (called from routing_execute)
76 // massbal_addInflowFlow (called from routing.c)
77 // massbal_addInflowQual (called from routing.c)
78 // massbal_addOutflowFlow (called from removeOutflows in routing.c)
79 // massbal_addOutflowQual (called from removeOutflows in routing.c)
80 // massbal_addNodeLosses (called from removeStorageLosses in routing.c)
81 // massbal_addLinkLosses (called from removeConduitLosses in routing.c)
82 // massbal_addReactedMass (called from qualrout.c & treatmnt.c)
83 // massbal_addSeepageLoss (called from routing.c)
84 // massbal_addToFinalStorage (called from qualrout.c)
85 // massbal_getStepFlowError (called from routing.c)
86
87 //-----------------------------------------------------------------------------
88 // Local Functions
89 //-----------------------------------------------------------------------------
90 double massbal_getBuildup(int pollut);
91 double massbal_getStorage(char isFinalStorage);
92 double massbal_getStoredMass(int pollut);
93 double massbal_getLoadingError(void);
94 double massbal_getGwaterError(void);
95 double massbal_getQualError(void);
96
97
98 //=============================================================================
99
100 61 int massbal_open()
101 //
102 // Input: none
103 // Output: returns error code
104 // Purpose: opens and initializes mass balance continuity checking.
105 //
106 {
107 int j, n;
108
109 // --- initialize global continuity errors
110 61 RunoffError = 0.0;
111 61 GwaterError = 0.0;
112 61 FlowError = 0.0;
113 61 QualError = 0.0;
114
115 // --- initialize runoff totals
116 61 RunoffTotals.rainfall = 0.0;
117 61 RunoffTotals.evap = 0.0;
118 61 RunoffTotals.infil = 0.0;
119 61 RunoffTotals.runoff = 0.0;
120 61 RunoffTotals.runon = 0.0;
121 61 RunoffTotals.drains = 0.0;
122 61 RunoffTotals.snowRemoved = 0.0;
123 61 RunoffTotals.initStorage = 0.0;
124 61 RunoffTotals.initSnowCover = 0.0;
125 61 TotalArea = 0.0;
126
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 61 times.
157 for (j = 0; j < Nobjects[SUBCATCH]; j++)
127 {
128 96 RunoffTotals.initStorage += subcatch_getStorage(j);
129 96 RunoffTotals.initSnowCover += snow_getSnowCover(j);
130 96 TotalArea += Subcatch[j].area;
131 }
132
133 // --- initialize groundwater totals
134 61 GwaterTotals.infil = 0.0;
135 61 GwaterTotals.upperEvap = 0.0;
136 61 GwaterTotals.lowerEvap = 0.0;
137 61 GwaterTotals.lowerPerc = 0.0;
138 61 GwaterTotals.gwater = 0.0;
139 61 GwaterTotals.initStorage = 0.0;
140 61 GwaterTotals.finalStorage = 0.0;
141
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 61 times.
157 for ( j = 0; j < Nobjects[SUBCATCH]; j++ )
142 {
143 96 GwaterTotals.initStorage += gwater_getVolume(j) * Subcatch[j].area;
144 }
145
146 // --- initialize node flow & storage totals
147 61 FlowTotals.dwInflow = 0.0;
148 61 FlowTotals.wwInflow = 0.0;
149 61 FlowTotals.gwInflow = 0.0;
150 61 FlowTotals.iiInflow = 0.0;
151 61 FlowTotals.exInflow = 0.0;
152 61 FlowTotals.flooding = 0.0;
153 61 FlowTotals.outflow = 0.0;
154 61 FlowTotals.evapLoss = 0.0;
155 61 FlowTotals.seepLoss = 0.0;
156 61 FlowTotals.reacted = 0.0;
157 61 FlowTotals.initStorage = 0.0;
158
2/2
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 61 times.
484 for (j = 0; j < Nobjects[NODE]; j++)
159 423 FlowTotals.initStorage += Node[j].newVolume;
160
2/2
✓ Branch 0 taken 332 times.
✓ Branch 1 taken 61 times.
393 for (j = 0; j < Nobjects[LINK]; j++)
161 332 FlowTotals.initStorage += Link[j].newVolume;
162 61 StepFlowTotals = FlowTotals;
163
164 // --- initialize arrays to null
165 61 LoadingTotals = NULL;
166 61 QualTotals = NULL;
167 61 StepQualTotals = NULL;
168 61 NodeInflow = NULL;
169 61 NodeOutflow = NULL;
170
171 // --- allocate memory for WQ washoff continuity totals
172 61 n = Nobjects[POLLUT];
173
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 52 times.
61 if ( n > 0 )
174 {
175 9 LoadingTotals = (TLoadingTotals *) calloc(n, sizeof(TLoadingTotals));
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if ( LoadingTotals == NULL )
177 {
178 report_writeErrorMsg(ERR_MEMORY, "");
179 return ErrorCode;
180 }
181
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 9 times.
34 for (j = 0; j < n; j++)
182 {
183 25 LoadingTotals[j].initLoad = massbal_getBuildup(j);
184 25 LoadingTotals[j].buildup = 0.0;
185 25 LoadingTotals[j].deposition = 0.0;
186 25 LoadingTotals[j].sweeping = 0.0;
187 25 LoadingTotals[j].infil = 0.0;
188 25 LoadingTotals[j].bmpRemoval = 0.0;
189 25 LoadingTotals[j].runoff = 0.0;
190 25 LoadingTotals[j].finalLoad = 0.0;
191 }
192 }
193
194 // --- allocate memory for nodal WQ continuity totals
195
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 52 times.
61 if ( n > 0 )
196 {
197 9 QualTotals = (TRoutingTotals *) calloc(n, sizeof(TRoutingTotals));
198 9 StepQualTotals = (TRoutingTotals *) calloc(n, sizeof(TRoutingTotals));
199
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 if ( QualTotals == NULL || StepQualTotals == NULL )
200 {
201 report_writeErrorMsg(ERR_MEMORY, "");
202 return ErrorCode;
203 }
204 }
205
206 // --- initialize WQ totals
207
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 61 times.
86 for (j = 0; j < n; j++)
208 {
209 25 QualTotals[j].dwInflow = 0.0;
210 25 QualTotals[j].wwInflow = 0.0;
211 25 QualTotals[j].gwInflow = 0.0;
212 25 QualTotals[j].exInflow = 0.0;
213 25 QualTotals[j].flooding = 0.0;
214 25 QualTotals[j].outflow = 0.0;
215 25 QualTotals[j].evapLoss = 0.0;
216 25 QualTotals[j].seepLoss = 0.0;
217 25 QualTotals[j].reacted = 0.0;
218 25 QualTotals[j].initStorage = massbal_getStoredMass(j);
219 }
220
221 // --- initialize totals used over a single time step
222 61 massbal_initTimeStepTotals();
223
224 // --- allocate memory for nodal flow continuity
225
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 if ( Nobjects[NODE] > 0 )
226 {
227 61 NodeInflow = (double *) calloc(Nobjects[NODE], sizeof(double));
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if ( NodeInflow == NULL )
229 {
230 report_writeErrorMsg(ERR_MEMORY, "");
231 return ErrorCode;
232 }
233 61 NodeOutflow = (double *) calloc(Nobjects[NODE], sizeof(double));
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if ( NodeOutflow == NULL )
235 {
236 report_writeErrorMsg(ERR_MEMORY, "");
237 return ErrorCode;
238 }
239
2/2
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 61 times.
484 for (j = 0; j < Nobjects[NODE]; j++) NodeInflow[j] = Node[j].newVolume;
240 }
241 61 return ErrorCode;
242 }
243
244 //=============================================================================
245
246 61 void massbal_close()
247 //
248 // Input: none
249 // Output: none
250 // Purpose: frees memory used by mass balance system.
251 //
252 {
253
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 52 times.
61 FREE(LoadingTotals);
254
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 52 times.
61 FREE(QualTotals);
255
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 52 times.
61 FREE(StepQualTotals);
256
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 FREE(NodeInflow);
257
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 FREE(NodeOutflow);
258 61 }
259
260 //=============================================================================
261
262 61 void massbal_report()
263 //
264 // Input: none
265 // Output: none
266 // Purpose: reports mass balance results.
267 //
268 {
269 int j;
270 61 double gwArea = 0.0;
271
272
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 26 times.
61 if ( Nobjects[SUBCATCH] > 0 )
273 {
274
1/2
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
35 if ( massbal_getRunoffError() > MAX_RUNOFF_BALANCE_ERR ||
275
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 RptFlags.continuity == TRUE
276 35 ) report_writeRunoffError(&RunoffTotals, TotalArea);
277
278
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1 time.
35 if ( Nobjects[POLLUT] > 0 && !IgnoreQuality )
279 {
280
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 if ( massbal_getLoadingError() > MAX_RUNOFF_BALANCE_ERR ||
281
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 RptFlags.continuity == TRUE
282 7 ) report_writeLoadingError(LoadingTotals);
283 }
284 }
285
286
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
61 if ( Nobjects[AQUIFER] > 0 && !IgnoreGwater )
287 {
288
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if ( massbal_getGwaterError() > MAX_RUNOFF_BALANCE_ERR ||
289
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 RptFlags.continuity == TRUE )
290 {
291
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
13 for ( j = 0; j < Nobjects[SUBCATCH]; j++ )
292 {
293
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if ( Subcatch[j].groundwater ) gwArea += Subcatch[j].area;
294 }
295
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( gwArea > 0.0 ) report_writeGwaterError(&GwaterTotals, gwArea);
296 }
297 }
298
299
2/4
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
61 if ( Nobjects[NODE] > 0 && !IgnoreRouting )
300 {
301
2/2
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 1 time.
61 if ( massbal_getFlowError() > MAX_FLOW_BALANCE_ERR ||
302
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 RptFlags.continuity == TRUE
303 61 ) report_writeFlowError(&FlowTotals);
304
305
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1 time.
61 if ( Nobjects[POLLUT] > 0 && !IgnoreQuality )
306 {
307
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if ( massbal_getQualError() > MAX_FLOW_BALANCE_ERR ||
308
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 RptFlags.continuity == TRUE
309 8 ) report_writeQualError(QualTotals);
310 }
311 }
312 61 }
313
314 //=============================================================================
315
316 43 double massbal_getBuildup(int p)
317 //
318 // Input: p = pollutant index
319 // Output: returns total pollutant buildup (lbs or kg)
320 // Purpose: computes current total buildup of a pollutant over study area.
321 //
322 {
323 int i, j;
324 43 double load = 0.0;
325
326
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 43 times.
219 for (j = 0; j < Nobjects[SUBCATCH]; j++)
327 {
328
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 176 times.
448 for (i = 0; i < Nobjects[LANDUSE]; i++)
329 {
330 272 load += Subcatch[j].landFactor[i].buildup[p];
331 }
332 176 load += Subcatch[j].pondedQual[p] * Pollut[p].mcf;
333 }
334 43 return load;
335 }
336
337 //=============================================================================
338
339 502083 void massbal_updateRunoffTotals(int flowType, double v)
340 //
341 // Input: flowType = type of flow
342 // v = flow volume (ft3)
343 // Output: none
344 // Purpose: updates runoff totals after current time step.
345 //
346 {
347
6/7
✓ Branch 0 taken 118699 times.
✓ Branch 1 taken 118699 times.
✓ Branch 2 taken 118699 times.
✓ Branch 3 taken 118699 times.
✓ Branch 4 taken 27048 times.
✓ Branch 5 taken 239 times.
✗ Branch 6 not taken.
502083 switch(flowType)
348 {
349 118699 case RUNOFF_RAINFALL: RunoffTotals.rainfall += v; break;
350 118699 case RUNOFF_EVAP: RunoffTotals.evap += v; break;
351 118699 case RUNOFF_INFIL: RunoffTotals.infil += v; break;
352 118699 case RUNOFF_RUNOFF: RunoffTotals.runoff += v; break;
353 27048 case RUNOFF_DRAINS: RunoffTotals.drains += v; break;
354 239 case RUNOFF_RUNON: RunoffTotals.runon += v; break;
355 }
356 502083 }
357
358 //=============================================================================
359
360 26160 void massbal_updateGwaterTotals(double vInfil, double vUpperEvap, double vLowerEvap,
361 double vLowerPerc, double vGwater)
362 //
363 // Input: vInfil = volume depth of infiltrated water (ft)
364 // vUpperEvap = volume depth of upper evaporation (ft)
365 // vLowerEvap = volume depth of lower evaporation (ft)
366 // vLowerPerc = volume depth of percolation to deep GW (ft)
367 // vGwater = volume depth of groundwater outflow (ft)
368 // Output: none
369 // Purpose: updates groundwater totals after current time step.
370 //
371 {
372 26160 GwaterTotals.infil += vInfil;
373 26160 GwaterTotals.upperEvap += vUpperEvap;
374 26160 GwaterTotals.lowerEvap += vLowerEvap;
375 26160 GwaterTotals.lowerPerc += vLowerPerc;
376 26160 GwaterTotals.gwater += vGwater;
377 26160 }
378
379 //=============================================================================
380
381 1110563 void massbal_initTimeStepTotals()
382 //
383 // Input: none
384 // Output: none
385 // Purpose: initializes routing totals for current time step.
386 //
387 {
388 int j;
389 1110563 OldStepFlowTotals = StepFlowTotals;
390 1110563 StepFlowTotals.dwInflow = 0.0;
391 1110563 StepFlowTotals.wwInflow = 0.0;
392 1110563 StepFlowTotals.gwInflow = 0.0;
393 1110563 StepFlowTotals.iiInflow = 0.0;
394 1110563 StepFlowTotals.exInflow = 0.0;
395 1110563 StepFlowTotals.flooding = 0.0;
396 1110563 StepFlowTotals.outflow = 0.0;
397 1110563 StepFlowTotals.evapLoss = 0.0;
398 1110563 StepFlowTotals.seepLoss = 0.0;
399 1110563 StepFlowTotals.reacted = 0.0;
400
2/2
✓ Branch 0 taken 427452 times.
✓ Branch 1 taken 1110563 times.
1538015 for (j=0; j<Nobjects[POLLUT]; j++)
401 {
402 427452 StepQualTotals[j].dwInflow = 0.0;
403 427452 StepQualTotals[j].wwInflow = 0.0;
404 427452 StepQualTotals[j].gwInflow = 0.0;
405 427452 StepQualTotals[j].iiInflow = 0.0;
406 427452 StepQualTotals[j].exInflow = 0.0;
407 427452 StepQualTotals[j].flooding = 0.0;
408 427452 StepQualTotals[j].outflow = 0.0;
409 427452 StepQualTotals[j].reacted = 0.0;
410 427452 StepQualTotals[j].seepLoss = 0.0;
411 427452 StepQualTotals[j].initStorage = 0.0;
412 427452 StepQualTotals[j].finalStorage = 0.0;
413 }
414 1110563 }
415
416 //=============================================================================
417
418 37074620 void massbal_addInflowFlow(int type, double q)
419 //
420 // Input: type = type of inflow
421 // q = inflow rate (cfs)
422 // Output: none
423 // Purpose: adds flow inflow to routing totals for current time step.
424 //
425 {
426
5/6
✓ Branch 0 taken 65549 times.
✓ Branch 1 taken 2075540 times.
✓ Branch 2 taken 41087 times.
✓ Branch 3 taken 4794 times.
✓ Branch 4 taken 34887650 times.
✗ Branch 5 not taken.
37074620 switch (type)
427 {
428 65549 case DRY_WEATHER_INFLOW: StepFlowTotals.dwInflow += q; break;
429 2075540 case WET_WEATHER_INFLOW: StepFlowTotals.wwInflow += q; break;
430 41087 case GROUNDWATER_INFLOW: StepFlowTotals.gwInflow += q; break;
431 4794 case RDII_INFLOW: StepFlowTotals.iiInflow += q; break;
432 34887650 case EXTERNAL_INFLOW: StepFlowTotals.exInflow += q; break;
433 }
434 37074620 }
435
436 //=============================================================================
437
438 819279 void massbal_updateLoadingTotals(int type, int p, double w)
439 //
440 // Input: type = type of inflow
441 // p = pollutant index
442 // w = mass loading
443 // Output: none
444 // Purpose: adds inflow mass loading to loading totals for current time step.
445 //
446 {
447
6/8
✓ Branch 0 taken 190668 times.
✓ Branch 1 taken 158454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 152804 times.
✓ Branch 4 taken 153825 times.
✓ Branch 5 taken 158454 times.
✓ Branch 6 taken 5074 times.
✗ Branch 7 not taken.
819279 switch (type)
448 {
449 190668 case BUILDUP_LOAD: LoadingTotals[p].buildup += w; break;
450 158454 case DEPOSITION_LOAD: LoadingTotals[p].deposition += w; break;
451 case SWEEPING_LOAD: LoadingTotals[p].sweeping += w; break;
452 152804 case INFIL_LOAD: LoadingTotals[p].infil += w; break;
453 153825 case BMP_REMOVAL_LOAD: LoadingTotals[p].bmpRemoval += w; break;
454 158454 case RUNOFF_LOAD: LoadingTotals[p].runoff += w; break;
455 5074 case FINAL_LOAD: LoadingTotals[p].finalLoad += w; break;
456 }
457 819279 }
458
459 //=============================================================================
460
461 3139889 void massbal_addInflowQual(int type, int p, double w)
462 //
463 // Input: type = type of inflow
464 // p = pollutant index
465 // w = mass flow rate (mass/sec)
466 // Output: none
467 // Purpose: adds quality inflow to routing totals for current time step.
468 //
469 {
470
2/4
✓ Branch 0 taken 3139889 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3139889 times.
3139889 if ( p < 0 || p >= Nobjects[POLLUT] ) return;
471
4/6
✓ Branch 0 taken 51720 times.
✓ Branch 1 taken 3044320 times.
✓ Branch 2 taken 25848 times.
✓ Branch 3 taken 18001 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3139889 switch (type)
472 {
473 51720 case DRY_WEATHER_INFLOW: StepQualTotals[p].dwInflow += w; break;
474 3044320 case WET_WEATHER_INFLOW: StepQualTotals[p].wwInflow += w; break;
475 25848 case GROUNDWATER_INFLOW: StepQualTotals[p].gwInflow += w; break;
476 18001 case EXTERNAL_INFLOW: StepQualTotals[p].exInflow += w; break;
477 case RDII_INFLOW: StepQualTotals[p].iiInflow += w; break;
478 }
479 }
480
481 //=============================================================================
482
483 731818 void massbal_addOutflowFlow(double q, int isFlooded)
484 //
485 // Input: q = outflow flow rate (cfs)
486 // isFlooded = TRUE if outflow represents internal flooding
487 // Output: none
488 // Purpose: adds flow outflow over current time step to routing totals.
489 //
490 {
491
2/2
✓ Branch 0 taken 41093 times.
✓ Branch 1 taken 690725 times.
731818 if ( isFlooded ) StepFlowTotals.flooding += q;
492 690725 else StepFlowTotals.outflow += q;
493 731818 }
494
495 //=============================================================================
496
497 395144 void massbal_addOutflowQual(int p, double w, int isFlooded)
498 //
499 // Input: p = pollutant index
500 // w = mass outflow rate (mass/sec)
501 // isFlooded = TRUE if outflow represents internal flooding
502 // Output: none
503 // Purpose: adds pollutant outflow over current time step to routing totals.
504 //
505 {
506
2/4
✓ Branch 0 taken 395144 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 395144 times.
395144 if ( p < 0 || p >= Nobjects[POLLUT] ) return;
507
1/2
✓ Branch 0 taken 395144 times.
✗ Branch 1 not taken.
395144 if ( w >= 0.0 )
508 {
509
2/2
✓ Branch 0 taken 6620 times.
✓ Branch 1 taken 388524 times.
395144 if ( isFlooded ) StepQualTotals[p].flooding += w;
510 388524 else StepQualTotals[p].outflow += w;
511 }
512 else StepQualTotals[p].exInflow -= w;
513 }
514
515 //=============================================================================
516
517 126971 void massbal_addReactedMass(int p, double w)
518 //
519 // Input: p = pollutant index
520 // w = rate of mass reacted (mass/sec)
521 // Output: none
522 // Purpose: adds mass reacted during current time step to routing totals.
523 //
524 {
525
2/4
✓ Branch 0 taken 126971 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 126971 times.
126971 if ( p < 0 || p >= Nobjects[POLLUT] ) return;
526 126971 StepQualTotals[p].reacted += w;
527 }
528
529 //=============================================================================
530
531 4604544 void massbal_addSeepageLoss(int p, double w)
532 //
533 // Input: p = pollutant index
534 // w = mass seepage rate (mass/sec)
535 // Output: none
536 // Purpose: adds mass lost to seepage during current time step to routing totals.
537 //
538 {
539
2/4
✓ Branch 0 taken 4604544 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4604544 times.
4604544 if ( p < 0 || p >= Nobjects[POLLUT] ) return;
540 4604544 StepQualTotals[p].seepLoss += w;
541 }
542
543 //=============================================================================
544
545 1544720 void massbal_addToFinalStorage(int p, double w)
546 //
547 // Input: p = pollutant index
548 // w = pollutant mass
549 // Output: none
550 // Purpose: adds mass remaining on dry surface to routing totals.
551 //
552 {
553
2/4
✓ Branch 0 taken 1544720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1544720 times.
1544720 if ( p < 0 || p >= Nobjects[POLLUT] ) return;
554 1544720 StepQualTotals[p].finalStorage += w;
555 }
556
557 //=============================================================================
558
559 1094014 void massbal_addNodeLosses(double evapLoss, double seepLoss)
560 //
561 // Input: evapLoss = evaporation loss from all nodes (ft3/sec)
562 // seepLoss = seepage loss from all nodes (ft3/sec)
563 // Output: none
564 // Purpose: adds node losses over current time step to routing totals.
565 //
566 {
567 1094014 StepFlowTotals.evapLoss += evapLoss;
568 1094014 StepFlowTotals.seepLoss += seepLoss;
569 1094014 }
570
571 //=============================================================================
572
573 1094014 void massbal_addLinkLosses(double evapLoss, double seepLoss)
574 //
575 // Input: evapLoss = evaporation loss from all links (ft3/sec)
576 // infilLoss = infiltration loss from all links (ft3/sec)
577 // Output: none
578 // Purpose: adds link losses over current time step to routing totals.
579 //
580 {
581 1094014 StepFlowTotals.evapLoss += evapLoss;
582 1094014 StepFlowTotals.seepLoss += seepLoss;
583 1094014 }
584
585 //=============================================================================
586
587 2221004 void massbal_updateRoutingTotals(double tStep)
588 //
589 // Input: tStep = time step (sec)
590 // Output: none
591 // Purpose: updates overall routing totals with totals from current time step.
592 //
593 {
594 int j;
595 2221004 FlowTotals.dwInflow += StepFlowTotals.dwInflow * tStep;
596 2221004 FlowTotals.wwInflow += StepFlowTotals.wwInflow * tStep;
597 2221004 FlowTotals.gwInflow += StepFlowTotals.gwInflow * tStep;
598 2221004 FlowTotals.iiInflow += StepFlowTotals.iiInflow * tStep;
599 2221004 FlowTotals.exInflow += StepFlowTotals.exInflow * tStep;
600 2221004 FlowTotals.flooding += StepFlowTotals.flooding * tStep;
601 2221004 FlowTotals.outflow += StepFlowTotals.outflow * tStep;
602 2221004 FlowTotals.evapLoss += StepFlowTotals.evapLoss * tStep;
603 2221004 FlowTotals.seepLoss += StepFlowTotals.seepLoss * tStep;
604
605
2/2
✓ Branch 0 taken 854854 times.
✓ Branch 1 taken 2221004 times.
3075858 for (j = 0; j < Nobjects[POLLUT]; j++)
606 {
607 854854 QualTotals[j].dwInflow += StepQualTotals[j].dwInflow * tStep;
608 854854 QualTotals[j].wwInflow += StepQualTotals[j].wwInflow * tStep;
609 854854 QualTotals[j].gwInflow += StepQualTotals[j].gwInflow * tStep;
610 854854 QualTotals[j].iiInflow += StepQualTotals[j].iiInflow * tStep;
611 854854 QualTotals[j].exInflow += StepQualTotals[j].exInflow * tStep;
612 854854 QualTotals[j].flooding += StepQualTotals[j].flooding * tStep;
613 854854 QualTotals[j].outflow += StepQualTotals[j].outflow * tStep;
614 854854 QualTotals[j].reacted += StepQualTotals[j].reacted * tStep;
615 854854 QualTotals[j].seepLoss += StepQualTotals[j].seepLoss * tStep;
616 854854 QualTotals[j].finalStorage += StepQualTotals[j].finalStorage;
617 }
618
619
2/2
✓ Branch 0 taken 36077656 times.
✓ Branch 1 taken 2221004 times.
38298660 for (j = 0; j < Nobjects[NODE]; j++)
620 {
621 36077656 NodeInflow[j] += Node[j].inflow * tStep;
622
2/2
✓ Branch 0 taken 33314588 times.
✓ Branch 1 taken 2763068 times.
36077656 if (Node[j].type == OUTFALL ||
623
4/4
✓ Branch 0 taken 325286 times.
✓ Branch 1 taken 32989302 times.
✓ Branch 2 taken 322406 times.
✓ Branch 3 taken 2880 times.
33314588 (Node[j].degree == 0 && Node[j].type != STORAGE))
624 {
625 3085474 NodeOutflow[j] += Node[j].inflow * tStep;
626 }
627 else
628 {
629 32992182 NodeOutflow[j] += Node[j].outflow * tStep;
630
2/2
✓ Branch 0 taken 32815636 times.
✓ Branch 1 taken 176546 times.
32992182 if (Node[j].newVolume <= Node[j].fullVolume)
631 32815636 NodeOutflow[j] += Node[j].overflow * tStep;
632 }
633 }
634 2221004 }
635
636 //=============================================================================
637
638 61 double massbal_getStorage(char isFinalStorage)
639 //
640 // Input: isFinalStorage = TRUE if at final time period
641 // Output: returns storage volume used (ft3)
642 // Purpose: computes total system storage (nodes + links) filled
643 //
644 {
645 int j;
646 61 double totalStorage = 0.0;
647 double nodeStorage;
648
649 // --- get volume in nodes
650
2/2
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 61 times.
484 for (j = 0; j < Nobjects[NODE]; j++)
651 {
652 423 nodeStorage = Node[j].newVolume;
653
1/2
✓ Branch 0 taken 423 times.
✗ Branch 1 not taken.
423 if ( isFinalStorage ) NodeOutflow[j] += nodeStorage;
654 423 totalStorage += nodeStorage;
655 }
656
657 // --- skip final link storage for Steady Flow routing
658
3/4
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 60 times.
61 if ( isFinalStorage && RouteModel == SF ) return totalStorage;
659
660 // --- add on volume stored in links
661
2/2
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 60 times.
371 for (j = 0; j < Nobjects[LINK]; j++)
662 {
663 311 totalStorage += Link[j].newVolume;
664 }
665 60 return totalStorage;
666 }
667
668 //=============================================================================
669
670 void massbal_getSysFlows(double f, double sysFlows[])
671 //
672 // Input: f = time weighting factor
673 // Output: sysFlows = array of total system flows
674 // Purpose: retrieves time-weighted average of old and new system flows.
675 //
676 {
677 double f1 = 1.0 - f;
678 sysFlows[SYS_DWFLOW] = (f1 * OldStepFlowTotals.dwInflow +
679 f * StepFlowTotals.dwInflow) * UCF(FLOW);
680 sysFlows[SYS_GWFLOW] = (f1 * OldStepFlowTotals.gwInflow +
681 f * StepFlowTotals.gwInflow) * UCF(FLOW);
682 sysFlows[SYS_IIFLOW] = (f1 * OldStepFlowTotals.iiInflow +
683 f * StepFlowTotals.iiInflow) * UCF(FLOW);
684 sysFlows[SYS_EXFLOW] = (f1 * OldStepFlowTotals.exInflow +
685 f * StepFlowTotals.exInflow) * UCF(FLOW);
686 sysFlows[SYS_FLOODING] = (f1 * OldStepFlowTotals.flooding +
687 f * StepFlowTotals.flooding) * UCF(FLOW);
688 sysFlows[SYS_OUTFLOW] = (f1 * OldStepFlowTotals.outflow +
689 f * StepFlowTotals.outflow) * UCF(FLOW);
690 sysFlows[SYS_STORAGE] = (f1 * OldStepFlowTotals.finalStorage +
691 f * StepFlowTotals.finalStorage) * UCF(VOLUME);
692 }
693
694 //=============================================================================
695
696 35 double massbal_getRunoffError()
697 //
698 // Input: none
699 // Output: none
700 // Purpose: computes runoff mass balance error.
701 //
702 {
703 int j;
704 double totalInflow;
705 double totalOutflow;
706
707 // --- find final storage on all subcatchments
708 35 RunoffTotals.finalStorage = 0.0;
709 35 RunoffTotals.finalSnowCover = 0.0;
710
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 35 times.
131 for (j = 0; j < Nobjects[SUBCATCH]; j++)
711 {
712 96 RunoffTotals.finalStorage += subcatch_getStorage(j);
713 96 RunoffTotals.finalSnowCover += snow_getSnowCover(j);
714 }
715
716 // --- get snow removed from system
717 35 RunoffTotals.snowRemoved = Snow.removed;
718
719 // --- compute % difference between total inflow and outflow
720 35 totalInflow = RunoffTotals.rainfall +
721 35 RunoffTotals.runon +
722 35 RunoffTotals.initStorage +
723 35 RunoffTotals.initSnowCover;
724 35 totalOutflow = RunoffTotals.evap +
725 35 RunoffTotals.infil +
726 35 RunoffTotals.runoff +
727 35 RunoffTotals.drains +
728 35 RunoffTotals.snowRemoved +
729 35 RunoffTotals.finalStorage +
730 35 RunoffTotals.finalSnowCover;
731 35 RunoffTotals.pctError = 0.0;
732
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 33 times.
35 if ( fabs(totalInflow - totalOutflow) < 1.0 )
733 {
734 2 RunoffTotals.pctError = TINY;
735 }
736
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 else if ( totalInflow > 0.0 )
737 {
738 33 RunoffTotals.pctError = 100.0 * (1.0 - totalOutflow / totalInflow);
739 }
740 else if ( totalOutflow > 0.0 )
741 {
742 RunoffTotals.pctError = 100.0 * (totalInflow / totalOutflow - 1.0);
743 }
744 35 RunoffError = RunoffTotals.pctError;
745 35 return RunoffTotals.pctError;
746 }
747
748 //=============================================================================
749
750 7 double massbal_getLoadingError()
751 //
752 // Input: none
753 // Output: none
754 // Purpose: computes runoff load mass balance error.
755 //
756 {
757 int j;
758 double loadIn;
759 double loadOut;
760 7 double maxError = 0.0;
761
762
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 7 times.
25 for (j = 0; j < Nobjects[POLLUT]; j++)
763 {
764 // --- get final pollutant loading remaining on land surface
765 18 LoadingTotals[j].finalLoad += massbal_getBuildup(j);
766
767 // --- compute total load added to study area
768 18 loadIn = LoadingTotals[j].initLoad +
769 18 LoadingTotals[j].buildup +
770 18 LoadingTotals[j].deposition;
771
772 // --- compute total load removed from study area
773 18 loadOut = LoadingTotals[j].sweeping +
774 18 LoadingTotals[j].infil +
775 18 LoadingTotals[j].bmpRemoval +
776 18 LoadingTotals[j].runoff +
777 18 LoadingTotals[j].finalLoad;
778
779 // --- compute mass balance error
780 18 LoadingTotals[j].pctError = 0.0;
781
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 10 times.
18 if ( fabs(loadIn - loadOut) < 0.001 )
782 {
783 8 LoadingTotals[j].pctError = TINY;
784 }
785
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 else if ( loadIn > 0.0 )
786 {
787 10 LoadingTotals[j].pctError = 100.0 * (1.0 - loadOut / loadIn);
788 }
789 else if ( loadOut > 0.0 )
790 {
791 LoadingTotals[j].pctError = 100.0 * (loadIn / loadOut - 1.0);
792 }
793
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 7 times.
18 maxError = MAX(maxError, LoadingTotals[j].pctError);
794
795 // --- report total counts as log10
796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if ( Pollut[j].units == COUNT )
797 {
798 LoadingTotals[j].initLoad = LOG10(LoadingTotals[j].initLoad);
799 LoadingTotals[j].buildup = LOG10(LoadingTotals[j].buildup);
800 LoadingTotals[j].deposition = LOG10(LoadingTotals[j].deposition);
801 LoadingTotals[j].sweeping = LOG10(LoadingTotals[j].sweeping);
802 LoadingTotals[j].infil = LOG10(LoadingTotals[j].infil);
803 LoadingTotals[j].bmpRemoval = LOG10(LoadingTotals[j].bmpRemoval);
804 LoadingTotals[j].runoff = LOG10(LoadingTotals[j].runoff);
805 LoadingTotals[j].finalLoad = LOG10(LoadingTotals[j].finalLoad);
806 }
807 }
808 7 return maxError;
809 }
810
811 //=============================================================================
812
813 3 double massbal_getGwaterError()
814 //
815 // Input: none
816 // Output: none
817 // Purpose: computes groundwater mass balance error.
818 //
819 {
820 int j;
821 double totalInflow;
822 double totalOutflow;
823
824 // --- find final storage in groundwater
825 3 GwaterTotals.finalStorage = 0.0;
826
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
13 for ( j = 0; j < Nobjects[SUBCATCH]; j++ )
827 {
828 10 GwaterTotals.finalStorage += gwater_getVolume(j) * Subcatch[j].area;
829 }
830
831 // --- compute % difference between total inflow and outflow
832 3 totalInflow = GwaterTotals.infil +
833 3 GwaterTotals.initStorage;
834 3 totalOutflow = GwaterTotals.upperEvap +
835 3 GwaterTotals.lowerEvap +
836 3 GwaterTotals.lowerPerc +
837 3 GwaterTotals.gwater +
838 3 GwaterTotals.finalStorage;
839 3 GwaterTotals.pctError = 0.0;
840
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
3 if ( fabs(totalInflow - totalOutflow) < 1.0 )
841 {
842 1 GwaterTotals.pctError = TINY;
843 }
844
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else if ( totalInflow > 0.0 )
845 {
846 2 GwaterTotals.pctError = 100.0 * (1.0 - totalOutflow / totalInflow);
847 }
848 else if ( totalOutflow > 0.0 )
849 {
850 GwaterTotals.pctError = 100.0 * (totalInflow / totalOutflow - 1.0);
851 }
852 3 GwaterError = GwaterTotals.pctError;
853 3 return GwaterTotals.pctError;
854 }
855
856 //=============================================================================
857
858 61 double massbal_getFlowError()
859 //
860 // Input: none
861 // Output: none
862 // Purpose: computes flow routing mass balance error.
863 //
864 {
865 double totalInflow;
866 double totalOutflow;
867
868 // --- get final volume of nodes and links
869 61 FlowTotals.finalStorage = massbal_getStorage(TRUE);
870
871 // --- add contributions to total inflow and outflow that are always positive
872 61 totalInflow = FlowTotals.initStorage + FlowTotals.wwInflow + FlowTotals.iiInflow;
873 61 totalOutflow = FlowTotals.finalStorage + FlowTotals.flooding + FlowTotals.evapLoss +
874 61 FlowTotals.seepLoss + FlowTotals.reacted;
875
876 // --- add on contributions that might be either positive or negative
877
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 if ( FlowTotals.dwInflow >= 0.0 ) totalInflow += FlowTotals.dwInflow;
878 else totalOutflow -= FlowTotals.dwInflow;
879
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 2 times.
61 if ( FlowTotals.gwInflow >= 0.0 ) totalInflow += FlowTotals.gwInflow;
880 2 else totalOutflow -= FlowTotals.gwInflow;
881
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 if ( FlowTotals.exInflow >= 0.0 ) totalInflow += FlowTotals.exInflow;
882 else totalOutflow -= FlowTotals.exInflow;
883
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 if ( FlowTotals.outflow >= 0.0 ) totalOutflow += FlowTotals.outflow;
884 else totalInflow -= FlowTotals.outflow;
885
886 // --- find percent difference between total inflow and outflow
887 61 FlowTotals.pctError = 0.0;
888
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 39 times.
61 if ( fabs(totalInflow - totalOutflow) < 1.0 )
889 {
890 22 FlowTotals.pctError = TINY;
891 }
892
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 else if ( fabs(totalInflow) > 0.0 )
893 {
894 39 FlowTotals.pctError = 100.0 * (1.0 - totalOutflow / totalInflow);
895 }
896 else if ( fabs(totalOutflow) > 0.0 )
897 {
898 FlowTotals.pctError = 100.0 * (totalInflow / totalOutflow - 1.0);
899 }
900 61 FlowError = FlowTotals.pctError;
901 61 return FlowTotals.pctError;
902 }
903
904 //=============================================================================
905
906 8 double massbal_getQualError()
907 //
908 // Input: none
909 // Output: none
910 // Purpose: computes water quality routing mass balance error.
911 //
912 {
913 int p;
914 8 double maxQualError = 0.0;
915 double totalInflow;
916 double totalOutflow;
917 double cf;
918
919 // --- analyze each pollutant
920
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 8 times.
27 for (p = 0; p < Nobjects[POLLUT]; p++)
921 {
922 // --- get final mass stored in nodes and links
923 19 QualTotals[p].finalStorage += massbal_getStoredMass(p);
924
925 // --- compute % difference between total inflow and outflow
926 19 totalInflow = QualTotals[p].dwInflow +
927 19 QualTotals[p].wwInflow +
928 19 QualTotals[p].gwInflow +
929 19 QualTotals[p].iiInflow +
930 19 QualTotals[p].exInflow +
931 19 QualTotals[p].initStorage;
932 19 totalOutflow = QualTotals[p].flooding +
933 19 QualTotals[p].outflow +
934 19 QualTotals[p].reacted +
935 19 QualTotals[p].seepLoss +
936 19 QualTotals[p].finalStorage;
937 19 QualTotals[p].pctError = 0.0;
938
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 18 times.
19 if ( fabs(totalInflow - totalOutflow) < 0.001 )
939 {
940 1 QualTotals[p].pctError = TINY;
941 }
942
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 else if ( totalInflow > 0.0 )
943 {
944 18 QualTotals[p].pctError = 100.0 * (1.0 - totalOutflow / totalInflow);
945 }
946 else if ( totalOutflow > 0.0 )
947 {
948 QualTotals[p].pctError = 100.0 * (totalInflow / totalOutflow - 1.0);
949 }
950
951 // --- update max. error among all pollutants
952
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 6 times.
19 if ( fabs(QualTotals[p].pctError) > fabs(maxQualError) )
953 {
954 13 maxQualError = QualTotals[p].pctError;
955 }
956
957 // --- convert totals to reporting units (lbs, kg, or Log(Count))
958 19 cf = LperFT3;
959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if ( Pollut[p].units == COUNT )
960 {
961 QualTotals[p].dwInflow = LOG10(cf * QualTotals[p].dwInflow);
962 QualTotals[p].wwInflow = LOG10(cf * QualTotals[p].wwInflow);
963 QualTotals[p].gwInflow = LOG10(cf * QualTotals[p].gwInflow);
964 QualTotals[p].iiInflow = LOG10(cf * QualTotals[p].iiInflow);
965 QualTotals[p].exInflow = LOG10(cf * QualTotals[p].exInflow);
966 QualTotals[p].flooding = LOG10(cf * QualTotals[p].flooding);
967 QualTotals[p].outflow = LOG10(cf * QualTotals[p].outflow);
968 QualTotals[p].reacted = LOG10(cf * QualTotals[p].reacted);
969 QualTotals[p].seepLoss = LOG10(cf * QualTotals[p].seepLoss);
970 QualTotals[p].initStorage = LOG10(cf * QualTotals[p].initStorage);
971 QualTotals[p].finalStorage = LOG10(cf * QualTotals[p].finalStorage);
972 }
973 else
974 {
975 19 cf = cf * UCF(MASS);
976
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 17 times.
19 if ( Pollut[p].units == UG ) cf /= 1000.0;
977 19 QualTotals[p].dwInflow *= cf;
978 19 QualTotals[p].wwInflow *= cf;
979 19 QualTotals[p].gwInflow *= cf;
980 19 QualTotals[p].iiInflow *= cf;
981 19 QualTotals[p].exInflow *= cf;
982 19 QualTotals[p].flooding *= cf;
983 19 QualTotals[p].outflow *= cf;
984 19 QualTotals[p].reacted *= cf;
985 19 QualTotals[p].seepLoss *= cf;
986 19 QualTotals[p].initStorage *= cf;
987 19 QualTotals[p].finalStorage *= cf;
988 }
989 }
990 8 QualError = maxQualError;
991 8 return maxQualError;
992 }
993 //=============================================================================
994
995 1110502 double massbal_getStepFlowError()
996 //
997 // Input: none
998 // Output: returns fractional difference between total inflow and outflow.
999 // Purpose: computes flow routing mass balance error at current time step.
1000 //
1001 {
1002 double totalInflow;
1003 double totalOutflow;
1004
1005 // --- compute % difference between total inflow and outflow
1006 1110502 totalInflow = StepFlowTotals.dwInflow +
1007 1110502 StepFlowTotals.wwInflow +
1008 1110502 StepFlowTotals.gwInflow +
1009 1110502 StepFlowTotals.iiInflow +
1010 1110502 StepFlowTotals.exInflow;
1011 1110502 totalOutflow = StepFlowTotals.flooding +
1012 1110502 StepFlowTotals.outflow +
1013 1110502 StepFlowTotals.evapLoss +
1014 1110502 StepFlowTotals.seepLoss +
1015 1110502 StepFlowTotals.reacted;
1016
2/2
✓ Branch 0 taken 458496 times.
✓ Branch 1 taken 652006 times.
1110502 if ( fabs(totalInflow) > 0.0 )
1017 458496 return 1.0 - totalOutflow / totalInflow;
1018
2/2
✓ Branch 0 taken 16530 times.
✓ Branch 1 taken 635476 times.
652006 else if ( fabs(totalOutflow) > 0.0 )
1019 16530 return totalInflow / totalOutflow - 1.0;
1020 635476 else return 0.0;
1021 }
1022
1023 //=============================================================================
1024
1025 44 double massbal_getStoredMass(int p)
1026 //
1027 // Input: p = pollutant index
1028 // Output: returns mass of pollutant.
1029 // Purpose: computes mass of pollutant stored in conveyance network.
1030 //
1031 {
1032 int j;
1033 44 double storedMass = 0.0;
1034
1035 // --- get mass stored in nodes
1036
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 44 times.
320 for (j = 0; j < Nobjects[NODE]; j++)
1037 276 storedMass += Node[j].newVolume * Node[j].newQual[p];
1038
1039 // --- get mass stored in links (except for Steady Flow routing)
1040
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if ( RouteModel != SF )
1041 {
1042
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 44 times.
286 for (j = 0; j < Nobjects[LINK]; j++)
1043 242 storedMass += Link[j].newVolume * Link[j].newQual[p];
1044 }
1045 44 return storedMass;
1046 }
1047