GCC Code Coverage Report


Directory: src/solver/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 79.3% 169 / 0 / 213
Functions: 100.0% 10 / 0 / 10
Branches: 59.5% 100 / 0 / 168

hotstart.c
Line Branch Exec Source
1 //-----------------------------------------------------------------------------
2 // hotstart.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 // Hot Start file functions.
10 //
11 // A SWMM hot start file contains the state of a SWMM project after
12 // a simulation has been run, allowing it to be used to initialize
13 // a subsequent simulation that picks up where the previous run ended.
14 //
15 // An abridged version of the hot start file (version 2) is available
16 // that contains only variables that appear in the binary output file
17 // (groundwater upper moisture and water table elevation, node depth,
18 // lateral inflow, and quality, and link flow, depth, setting and quality).
19 //
20 // When reading a previously saved hot start file checks are made to
21 // insure the the current SWMM project has the same number of major
22 // components (subcatchments, land uses, nodes, links, and pollutants)
23 // and unit system as does the hot start file. No test is made to
24 // insure that these components are of the same sub-type and maintain
25 // the same order as when the hot start file was created.
26 //
27 // Update History
28 // ==============
29 // Build 5.1.008:
30 // - Storage node hydraulic residence time (HRT) was added to the file.
31 // - Link control settings are now applied when reading a hot start file.
32 // - Runoff read from file assigned to newRunoff property instead of oldRunoff.
33 // - Array indexing bug when reading snowpack state from file fixed.
34 // Build 5.1.011:
35 // - Link control setting bug when reading a hot start file fixed.
36 // Build 5.1.015:
37 // - Support added for multiple infiltration methods within a project.
38 // Build 5.2.5:
39 // - Fixed bug in fwrite count argument when writing of pollutant build-up.
40 //-----------------------------------------------------------------------------
41 #define _CRT_SECURE_NO_DEPRECATE
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <math.h>
47 #include "headers.h"
48
49 //-----------------------------------------------------------------------------
50 // Local Variables
51 //-----------------------------------------------------------------------------
52 static int fileVersion;
53
54 //-----------------------------------------------------------------------------
55 // External functions (declared in funcs.h)
56 //-----------------------------------------------------------------------------
57 // hotstart_open (called by swmm_start in swmm5.c)
58 // hotstart_close (called by swmm_end in swmm5.c)
59
60 //-----------------------------------------------------------------------------
61 // Function declarations
62 //-----------------------------------------------------------------------------
63 static int openHotstartFile1(void);
64 static int openHotstartFile2(void);
65 static void readRunoff(void);
66 static void saveRunoff(void);
67 static void readRouting(void);
68 static void saveRouting(void);
69 static int readFloat(float *x, FILE* f);
70 static int readDouble(double* x, FILE* f);
71
72 //=============================================================================
73
74 58 int hotstart_open()
75 {
76 // --- open hot start files
77
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
58 if ( !openHotstartFile1() ) return FALSE; //input hot start file
78
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
58 if ( !openHotstartFile2() ) return FALSE; //output hot start file
79 58 return TRUE;
80 }
81
82 //=============================================================================
83
84 58 void hotstart_close()
85 {
86
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 57 times.
58 if ( Fhotstart2.file )
87 {
88 1 saveRunoff();
89 1 saveRouting();
90 1 fclose(Fhotstart2.file);
91 }
92 58 }
93
94 //=============================================================================
95
96 58 int openHotstartFile1()
97 //
98 // Input: none
99 // Output: none
100 // Purpose: opens a previously saved routing hotstart file.
101 //
102 {
103 int nSubcatch;
104 int nNodes;
105 int nLinks;
106 int nPollut;
107 int nLandUses;
108 int flowUnits;
109 58 char fStamp[] = "SWMM5-HOTSTART";
110 58 char fileStamp[] = "SWMM5-HOTSTART";
111 58 char fStampx[] = "SWMM5-HOTSTARTx";
112 58 char fileStamp2[] = "SWMM5-HOTSTART2";
113 58 char fileStamp3[] = "SWMM5-HOTSTART3";
114 58 char fileStamp4[] = "SWMM5-HOTSTART4";
115
116 // --- try to open the file
117
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 1 time.
58 if ( Fhotstart1.mode != USE_FILE ) return TRUE;
118
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if ( (Fhotstart1.file = fopen(Fhotstart1.name, "r+b")) == NULL)
119 {
120 report_writeErrorMsg(ERR_HOTSTART_FILE_OPEN, Fhotstart1.name);
121 return FALSE;
122 }
123
124 // --- check that file contains proper header records
125 1 fread(fStampx, sizeof(char), strlen(fileStamp2), Fhotstart1.file);
126
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if ( strcmp(fStampx, fileStamp4) == 0 ) fileVersion = 4;
127 else if ( strcmp(fStampx, fileStamp3) == 0 ) fileVersion = 3;
128 else if ( strcmp(fStampx, fileStamp2) == 0 ) fileVersion = 2;
129 else
130 {
131 rewind(Fhotstart1.file);
132 fread(fStamp, sizeof(char), strlen(fileStamp), Fhotstart1.file);
133 if ( strcmp(fStamp, fileStamp) != 0 )
134 {
135 report_writeErrorMsg(ERR_HOTSTART_FILE_FORMAT, "");
136 return FALSE;
137 }
138 fileVersion = 1;
139 }
140
141 1 nSubcatch = -1;
142 1 nNodes = -1;
143 1 nLinks = -1;
144 1 nPollut = -1;
145 1 nLandUses = -1;
146 1 flowUnits = -1;
147
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if ( fileVersion >= 2 )
148 {
149 1 fread(&nSubcatch, sizeof(int), 1, Fhotstart1.file);
150 }
151 else nSubcatch = Nobjects[SUBCATCH];
152
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if ( fileVersion >= 3 )
153 {
154 1 fread(&nLandUses, sizeof(int), 1, Fhotstart1.file);
155 }
156 else nLandUses = Nobjects[LANDUSE];
157 1 fread(&nNodes, sizeof(int), 1, Fhotstart1.file);
158 1 fread(&nLinks, sizeof(int), 1, Fhotstart1.file);
159 1 fread(&nPollut, sizeof(int), 1, Fhotstart1.file);
160 1 fread(&flowUnits, sizeof(int), 1, Fhotstart1.file);
161
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if ( nSubcatch != Nobjects[SUBCATCH]
162
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 || nLandUses != Nobjects[LANDUSE]
163
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 || nNodes != Nobjects[NODE]
164
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 || nLinks != Nobjects[LINK]
165
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 || nPollut != Nobjects[POLLUT]
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 || flowUnits != FlowUnits )
167 {
168 report_writeErrorMsg(ERR_HOTSTART_FILE_FORMAT, "");
169 return FALSE;
170 }
171
172 // --- read contents of the file and close it
173
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if ( fileVersion >= 3 ) readRunoff();
174 1 readRouting();
175 1 fclose(Fhotstart1.file);
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( ErrorCode ) return FALSE;
177 1 else return TRUE;
178 }
179
180 //=============================================================================
181
182 58 int openHotstartFile2()
183 //
184 // Input: none
185 // Output: none
186 // Purpose: opens a new routing hotstart file to save results to.
187 //
188 {
189 int nSubcatch;
190 int nLandUses;
191 int nNodes;
192 int nLinks;
193 int nPollut;
194 int flowUnits;
195 58 char fileStamp[] = "SWMM5-HOTSTART4";
196
197 // --- try to open file
198
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 1 time.
58 if ( Fhotstart2.mode != SAVE_FILE ) return TRUE;
199
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if ( (Fhotstart2.file = fopen(Fhotstart2.name, "w+b")) == NULL)
200 {
201 report_writeErrorMsg(ERR_HOTSTART_FILE_OPEN, Fhotstart2.name);
202 return FALSE;
203 }
204
205 // --- write file stamp & number of objects to file
206 1 nSubcatch = Nobjects[SUBCATCH];
207 1 nLandUses = Nobjects[LANDUSE];
208 1 nNodes = Nobjects[NODE];
209 1 nLinks = Nobjects[LINK];
210 1 nPollut = Nobjects[POLLUT];
211 1 flowUnits = FlowUnits;
212 1 fwrite(fileStamp, sizeof(char), strlen(fileStamp), Fhotstart2.file);
213 1 fwrite(&nSubcatch, sizeof(int), 1, Fhotstart2.file);
214 1 fwrite(&nLandUses, sizeof(int), 1, Fhotstart2.file);
215 1 fwrite(&nNodes, sizeof(int), 1, Fhotstart2.file);
216 1 fwrite(&nLinks, sizeof(int), 1, Fhotstart2.file);
217 1 fwrite(&nPollut, sizeof(int), 1, Fhotstart2.file);
218 1 fwrite(&flowUnits, sizeof(int), 1, Fhotstart2.file);
219 1 return TRUE;
220 }
221
222 //=============================================================================
223
224 1 void saveRouting()
225 //
226 // Input: none
227 // Output: none
228 // Purpose: saves current state of all nodes and links to hotstart file.
229 //
230 {
231 int i, j;
232 float x[3];
233
234
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 1 time.
917 for (i = 0; i < Nobjects[NODE]; i++)
235 {
236 916 x[0] = (float)Node[i].newDepth;
237 916 x[1] = (float)Node[i].newLatFlow;
238 916 fwrite(x, sizeof(float), 2, Fhotstart2.file);
239
240
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 904 times.
916 if ( Node[i].type == STORAGE )
241 {
242 12 j = Node[i].subIndex;
243 12 x[0] = (float)Storage[j].hrt;
244 12 fwrite(&x[0], sizeof(float), 1, Fhotstart2.file);
245 }
246
247
2/2
✓ Branch 0 taken 3664 times.
✓ Branch 1 taken 916 times.
4580 for (j = 0; j < Nobjects[POLLUT]; j++)
248 {
249 3664 x[0] = (float)Node[i].newQual[j];
250 3664 fwrite(&x[0], sizeof(float), 1, Fhotstart2.file);
251 }
252 }
253
2/2
✓ Branch 0 taken 967 times.
✓ Branch 1 taken 1 time.
968 for (i = 0; i < Nobjects[LINK]; i++)
254 {
255 967 x[0] = (float)Link[i].newFlow;
256 967 x[1] = (float)Link[i].newDepth;
257 967 x[2] = (float)Link[i].setting;
258 967 fwrite(x, sizeof(float), 3, Fhotstart2.file);
259
2/2
✓ Branch 0 taken 3868 times.
✓ Branch 1 taken 967 times.
4835 for (j = 0; j < Nobjects[POLLUT]; j++)
260 {
261 3868 x[0] = (float)Link[i].newQual[j];
262 3868 fwrite(&x[0], sizeof(float), 1, Fhotstart2.file);
263 }
264 }
265 1 }
266
267 //=============================================================================
268
269 1 void readRouting()
270 //
271 // Input: none
272 // Output: none
273 // Purpose: reads initial state of all nodes, links and groundwater objects
274 // from hotstart file.
275 //
276 {
277 int i, j;
278 float x;
279 double xgw[4];
280 1 FILE* f = Fhotstart1.file;
281
282 // --- for file format 2, assign GW moisture content and lower depth
283
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if ( fileVersion == 2 )
284 {
285 // --- flow and available upper zone volume not used
286 xgw[2] = 0.0;
287 xgw[3] = MISSING;
288 for (i = 0; i < Nobjects[SUBCATCH]; i++)
289 {
290 // --- read moisture content and water table elevation as floats
291 if ( !readFloat(&x, f) ) return;
292 xgw[0] = x;
293 if ( !readFloat(&x, f) ) return;
294 xgw[1] = x;
295
296 // --- set GW state
297 if ( Subcatch[i].groundwater != NULL ) gwater_setState(i, xgw);
298 }
299 }
300
301 // --- read node states
302
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 1 time.
917 for (i = 0; i < Nobjects[NODE]; i++)
303 {
304
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 916 times.
916 if ( !readFloat(&x, f) ) return;
305 916 Node[i].newDepth = x;
306
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 916 times.
916 if ( !readFloat(&x, f) ) return;
307 916 Node[i].newLatFlow = x;
308
309
3/4
✓ Branch 0 taken 916 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 904 times.
916 if ( fileVersion >= 4 && Node[i].type == STORAGE )
310 {
311
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if ( !readFloat(&x, f) ) return;
312 12 j = Node[i].subIndex;
313 12 Storage[j].hrt = x;
314 }
315
316
2/2
✓ Branch 0 taken 3664 times.
✓ Branch 1 taken 916 times.
4580 for (j = 0; j < Nobjects[POLLUT]; j++)
317 {
318
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3664 times.
3664 if ( !readFloat(&x, f) ) return;
319 3664 Node[i].newQual[j] = x;
320 }
321
322 // --- read in zeros here for backwards compatibility
323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 916 times.
916 if ( fileVersion <= 2 )
324 {
325 for (j = 0; j < Nobjects[POLLUT]; j++)
326 {
327 if ( !readFloat(&x, f) ) return;
328 }
329 }
330 }
331
332 // --- read link states
333
2/2
✓ Branch 0 taken 967 times.
✓ Branch 1 taken 1 time.
968 for (i = 0; i < Nobjects[LINK]; i++)
334 {
335
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 967 times.
967 if ( !readFloat(&x, f) ) return;
336 967 Link[i].newFlow = x;
337
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 967 times.
967 if ( !readFloat(&x, f) ) return;
338 967 Link[i].newDepth = x;
339
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 967 times.
967 if ( !readFloat(&x, f) ) return;
340 967 Link[i].setting = x;
341
342 // --- set link's target setting to saved setting
343 967 Link[i].targetSetting = x;
344 967 link_setTargetSetting(i);
345 967 link_setSetting(i, 0.0);
346
347
2/2
✓ Branch 0 taken 3868 times.
✓ Branch 1 taken 967 times.
4835 for (j = 0; j < Nobjects[POLLUT]; j++)
348 {
349
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3868 times.
3868 if ( !readFloat(&x, f) ) return;
350 3868 Link[i].newQual[j] = x;
351 }
352
353 }
354 }
355
356 //=============================================================================
357
358 1 void saveRunoff(void)
359 //
360 // Input: none
361 // Output: none
362 // Purpose: saves current state of all subcatchments to hotstart file.
363 //
364 {
365 int i, j, k;
366 double x[6];
367 1 FILE* f = Fhotstart2.file;
368
369
2/2
✓ Branch 0 taken 329 times.
✓ Branch 1 taken 1 time.
330 for (i = 0; i < Nobjects[SUBCATCH]; i++)
370 {
371 // Ponded depths for each sub-area & total runoff (4 elements)
372
2/2
✓ Branch 0 taken 987 times.
✓ Branch 1 taken 329 times.
1316 for (j = 0; j < 3; j++) x[j] = Subcatch[i].subArea[j].depth;
373 329 x[3] = Subcatch[i].newRunoff;
374 329 fwrite(x, sizeof(double), 4, f);
375
376 // Infiltration state (max. of 6 elements)
377
2/2
✓ Branch 0 taken 1974 times.
✓ Branch 1 taken 329 times.
2303 for (j=0; j<6; j++) x[j] = 0.0;
378 329 infil_getState(i, x);
379 329 fwrite(x, sizeof(double), 6, f);
380
381 // Groundwater state (4 elements)
382
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 10 times.
329 if ( Subcatch[i].groundwater != NULL )
383 {
384 319 gwater_getState(i, x);
385 319 fwrite(x, sizeof(double), 4, f);
386 }
387
388 // Snowpack state (5 elements for each of 3 snow surfaces)
389
1/2
✓ Branch 0 taken 329 times.
✗ Branch 1 not taken.
329 if ( Subcatch[i].snowpack != NULL )
390 {
391
2/2
✓ Branch 0 taken 987 times.
✓ Branch 1 taken 329 times.
1316 for (j=0; j<3; j++)
392 {
393 987 snow_getState(i, j, x);
394 987 fwrite(x, sizeof(double), 5, f);
395 }
396 }
397
398 // Water quality
399
1/2
✓ Branch 0 taken 329 times.
✗ Branch 1 not taken.
329 if ( Nobjects[POLLUT] > 0 )
400 {
401 // Runoff quality
402
2/2
✓ Branch 0 taken 1316 times.
✓ Branch 1 taken 329 times.
1645 for (j=0; j<Nobjects[POLLUT]; j++)
403 {
404 1316 x[0] = Subcatch[i].newQual[j];
405 1316 fwrite(x, sizeof(double), 1, f);
406 }
407
408 // Ponded quality
409
2/2
✓ Branch 0 taken 1316 times.
✓ Branch 1 taken 329 times.
1645 for (j=0; j<Nobjects[POLLUT]; j++)
410 {
411 1316 x[0] = Subcatch[i].pondedQual[j];
412 1316 fwrite(x, sizeof(double), 1, f);
413 }
414
415 // Buildup and when streets were last swept
416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 329 times.
329 for (k=0; k<Nobjects[LANDUSE]; k++)
417 {
418 for (j=0; j<Nobjects[POLLUT]; j++)
419 {
420 x[0] = Subcatch[i].landFactor[k].buildup[j];
421 fwrite(x, sizeof(double), 1, f);
422 }
423 x[0] = Subcatch[i].landFactor[k].lastSwept;
424 fwrite(x, sizeof(double), 1, f);
425 }
426 }
427 }
428 1 }
429
430 //=============================================================================
431
432 1 void readRunoff()
433 //
434 // Input: none
435 // Output: none
436 // Purpose: reads saved state of all subcatchments from a hot start file.
437 //
438 {
439 int i, j, k;
440 double x[6];
441 1 FILE* f = Fhotstart1.file;
442
443
2/2
✓ Branch 0 taken 329 times.
✓ Branch 1 taken 1 time.
330 for (i = 0; i < Nobjects[SUBCATCH]; i++)
444 {
445 // Ponded depths & runoff (4 elements)
446
2/2
✓ Branch 0 taken 987 times.
✓ Branch 1 taken 329 times.
1316 for (j = 0; j < 3; j++)
447 {
448
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 987 times.
987 if ( !readDouble(&Subcatch[i].subArea[j].depth, f) ) return;
449 }
450
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 329 times.
329 if ( !readDouble(&Subcatch[i].newRunoff, f) ) return;
451
452 // Infiltration state (max. of 6 elements)
453
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1974 times.
✓ Branch 3 taken 1974 times.
✓ Branch 4 taken 329 times.
2303 for (j=0; j<6; j++) if ( !readDouble(&x[j], f) ) return;
454 329 infil_setState(i, x);
455
456 // Groundwater state (4 elements)
457
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 10 times.
329 if ( Subcatch[i].groundwater != NULL )
458 {
459
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1276 times.
✓ Branch 3 taken 1276 times.
✓ Branch 4 taken 319 times.
1595 for (j=0; j<4; j++) if ( !readDouble(&x[j], f) ) return;
460 319 gwater_setState(i, x);
461 }
462
463 // Snowpack state (5 elements for each of 3 snow surfaces)
464
1/2
✓ Branch 0 taken 329 times.
✗ Branch 1 not taken.
329 if ( Subcatch[i].snowpack != NULL )
465 {
466
2/2
✓ Branch 0 taken 987 times.
✓ Branch 1 taken 329 times.
1316 for (j=0; j<3; j++)
467 {
468
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4935 times.
✓ Branch 3 taken 4935 times.
✓ Branch 4 taken 987 times.
5922 for (k=0; k<5; k++) if ( !readDouble(&x[k], f) ) return;
469 987 snow_setState(i, j, x);
470 }
471 }
472
473 // Water quality
474
1/2
✓ Branch 0 taken 329 times.
✗ Branch 1 not taken.
329 if ( Nobjects[POLLUT] > 0 )
475 {
476 // Runoff quality
477
2/2
✓ Branch 0 taken 1316 times.
✓ Branch 1 taken 329 times.
1645 for (j=0; j<Nobjects[POLLUT]; j++)
478
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1316 times.
1316 if ( ! readDouble(&Subcatch[i].newQual[j], f) ) return;
479
480 // Ponded quality
481
2/2
✓ Branch 0 taken 1316 times.
✓ Branch 1 taken 329 times.
1645 for (j=0; j<Nobjects[POLLUT]; j++)
482
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1316 times.
1316 if ( !readDouble(&Subcatch[i].pondedQual[j], f) ) return;
483
484 // Buildup and when streets were last swept
485
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 329 times.
329 for (k=0; k<Nobjects[LANDUSE]; k++)
486 {
487 for (j=0; j<Nobjects[POLLUT]; j++)
488 {
489 if ( !readDouble(
490 &Subcatch[i].landFactor[k].buildup[j], f) ) return;
491 }
492 if ( !readDouble(&Subcatch[i].landFactor[k].lastSwept, f) )
493 return;
494 }
495 }
496 }
497 }
498
499 //=============================================================================
500
501 12277 int readFloat(float *x, FILE* f)
502 //
503 // Input: none
504 // Output: x = pointer to a float variable
505 // Purpose: reads a floating point value from a hot start file
506 //
507 {
508 // --- read a value from the file
509 12277 fread(x, sizeof(float), 1, f);
510
511 // --- test if the value is NaN (not a number)
512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12277 times.
12277 if ( *(x) != *(x) )
513 {
514 report_writeErrorMsg(ERR_HOTSTART_FILE_READ, "");
515 *(x) = 0.0;
516 return FALSE;
517 }
518 12277 return TRUE;
519 }
520
521 //=============================================================================
522
523 12133 int readDouble(double* x, FILE* f)
524 //
525 // Input: none
526 // Output: x = pointer to a double variable
527 // Purpose: reads a floating point value from a hot start file
528 //
529 {
530 // --- read a value from the file
531
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12133 times.
12133 if ( feof(f) )
532 {
533 *(x) = 0.0;
534 report_writeErrorMsg(ERR_HOTSTART_FILE_READ, "");
535 return FALSE;
536 }
537 12133 fread(x, sizeof(double), 1, f);
538
539 // --- test if the value is NaN (not a number)
540
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12133 times.
12133 if ( *(x) != *(x) )
541 {
542 *(x) = 0.0;
543 return FALSE;
544 }
545 12133 return TRUE;
546 }
547