project.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | //----------------------------------------------------------------------------- | ||
| 2 | // project.c | ||
| 3 | // | ||
| 4 | // Project: EPA SWMM5 | ||
| 5 | // Version: 5.2 | ||
| 6 | // Date: 07/17/23 (Build 5.2.4) | ||
| 7 | // Author: L. Rossman | ||
| 8 | // | ||
| 9 | // Project management functions. | ||
| 10 | // | ||
| 11 | // This module provides project-related services such as: | ||
| 12 | // o opening a new project and reading its input data | ||
| 13 | // o allocating and freeing memory for project objects | ||
| 14 | // o setting default values for object properties and options | ||
| 15 | // o initializing the internal state of all objects | ||
| 16 | // o managing hash tables for identifying objects by ID name | ||
| 17 | // | ||
| 18 | // Update History | ||
| 19 | // ============== | ||
| 20 | // Build 5.1.004: | ||
| 21 | // - Ignore RDII option added. | ||
| 22 | // Build 5.1.007: | ||
| 23 | // - Default monthly adjustments for climate variables included. | ||
| 24 | // - User-supplied GW flow equations initialized to NULL. | ||
| 25 | // - Storage node exfiltration object initialized to NULL. | ||
| 26 | // - Freeing of memory used for storage node exfiltration included. | ||
| 27 | // Build 5.1.008: | ||
| 28 | // - Constants used for dynamic wave routing moved to dynwave.c. | ||
| 29 | // - Input processing of minimum time step & number of | ||
| 30 | // parallel threads for dynamic wave routing added. | ||
| 31 | // - Default values of hyd. conductivity adjustments added. | ||
| 32 | // - Freeing of memory used for outfall pollutant load added. | ||
| 33 | // Build 5.1.009: | ||
| 34 | // - Fixed bug in computing total duration introduced in 5.1.008. | ||
| 35 | // Build 5.1.011: | ||
| 36 | // - Memory management of hydraulic event dates array added. | ||
| 37 | // Build 5.1.012: | ||
| 38 | // - Minimum conduit slope option initialized to 0 (none). | ||
| 39 | // - NO/YES no longer accepted as options for NORMAL_FLOW_LIMITED. | ||
| 40 | // Build 5.1.013: | ||
| 41 | // - omp_get_num_threads function protected against lack of compiler | ||
| 42 | // support for OpenMP. | ||
| 43 | // - Rain gage validation now performed after subcatchment validation. | ||
| 44 | // - More robust parsing of MinSurfarea option provided. | ||
| 45 | // - Support added for new RuleStep analysis option. | ||
| 46 | // Build 5.1.015: | ||
| 47 | // - Support added for multiple infiltration methods within a project. | ||
| 48 | // Build 5.2.0: | ||
| 49 | // - Support added for Streets and Inlets. | ||
| 50 | // - Support added for RptFlags.disabled option. | ||
| 51 | // - Object's rptFlag changed to record its index in output file. | ||
| 52 | // Build 5.2.2: | ||
| 53 | // - Default number of threads changed from OMP max. number to 1 | ||
| 54 | // to be consistent with User Manual. | ||
| 55 | // Build 5.2.4: | ||
| 56 | // - Default Inertial Damping changed from SOME to PARTIAL_DAMPING. | ||
| 57 | // - Default CourantFactor changed from 0 (fixed routing time step) | ||
| 58 | // - to 0.75 (variable time step) | ||
| 59 | //----------------------------------------------------------------------------- | ||
| 60 | #define _CRT_SECURE_NO_DEPRECATE | ||
| 61 | |||
| 62 | #include <stdlib.h> | ||
| 63 | #include <string.h> | ||
| 64 | #include <math.h> | ||
| 65 | |||
| 66 | // Protect against lack of compiler support for OpenMP | ||
| 67 | #if defined(_OPENMP) | ||
| 68 | #include <omp.h> | ||
| 69 | #else | ||
| 70 | int omp_get_max_threads(void) { return 1;} | ||
| 71 | #endif | ||
| 72 | |||
| 73 | #include "headers.h" | ||
| 74 | #include "lid.h" | ||
| 75 | #include "hash.h" | ||
| 76 | #include "mempool.h" | ||
| 77 | |||
| 78 | //----------------------------------------------------------------------------- | ||
| 79 | // Shared variables | ||
| 80 | //----------------------------------------------------------------------------- | ||
| 81 | static HTtable* Htable[MAX_OBJ_TYPES]; // Hash tables for object ID names | ||
| 82 | static char MemPoolAllocated; // TRUE if memory pool allocated | ||
| 83 | |||
| 84 | //----------------------------------------------------------------------------- | ||
| 85 | // External Functions (declared in funcs.h) | ||
| 86 | //----------------------------------------------------------------------------- | ||
| 87 | // project_open (called from swmm_open in swmm5.c) | ||
| 88 | // project_close (called from swmm_close in swmm5.c) | ||
| 89 | // project_readInput (called from swmm_open in swmm5.c) | ||
| 90 | // project_readOption (called from readOption in input.c) | ||
| 91 | // project_validate (called from swmm_open in swmm5.c) | ||
| 92 | // project_init (called from swmm_start in swmm5.c) | ||
| 93 | // project_addObject (called from addObject in input.c) | ||
| 94 | // project_createMatrix (called from openFileForInput in iface.c) | ||
| 95 | // project_freeMatrix (called from iface_closeRoutingFiles) | ||
| 96 | // project_findObject | ||
| 97 | // project_findID | ||
| 98 | |||
| 99 | //----------------------------------------------------------------------------- | ||
| 100 | // Function declarations | ||
| 101 | //----------------------------------------------------------------------------- | ||
| 102 | static void initPointers(void); | ||
| 103 | static void setDefaults(void); | ||
| 104 | static void openFiles(const char *f1, const char *f2, const char *f3); | ||
| 105 | static void createObjects(void); | ||
| 106 | static void deleteObjects(void); | ||
| 107 | static void createHashTables(void); | ||
| 108 | static void deleteHashTables(void); | ||
| 109 | |||
| 110 | |||
| 111 | //============================================================================= | ||
| 112 | |||
| 113 | 58 | void project_open(const char *f1, const char *f2, const char *f3) | |
| 114 | // | ||
| 115 | // Input: f1 = pointer to name of input file | ||
| 116 | // f2 = pointer to name of report file | ||
| 117 | // f3 = pointer to name of binary output file | ||
| 118 | // Output: none | ||
| 119 | // Purpose: opens a new SWMM project. | ||
| 120 | // | ||
| 121 | { | ||
| 122 | 58 | initPointers(); | |
| 123 | 58 | setDefaults(); | |
| 124 | 58 | openFiles(f1, f2, f3); | |
| 125 | 58 | } | |
| 126 | |||
| 127 | //============================================================================= | ||
| 128 | |||
| 129 | 58 | void project_readInput() | |
| 130 | // | ||
| 131 | // Input: none | ||
| 132 | // Output: none | ||
| 133 | // Purpose: retrieves project data from input file. | ||
| 134 | // | ||
| 135 | { | ||
| 136 | // --- create hash tables for fast retrieval of objects by ID names | ||
| 137 | 58 | createHashTables(); | |
| 138 | |||
| 139 | // --- count number of objects in input file and create them | ||
| 140 | 58 | input_countObjects(); | |
| 141 | 58 | createObjects(); | |
| 142 | |||
| 143 | // --- read project data from input file | ||
| 144 | 58 | input_readData(); | |
| 145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( ErrorCode ) return; |
| 146 | |||
| 147 | // --- establish starting & ending date/time | ||
| 148 | 58 | StartDateTime = StartDate + StartTime; | |
| 149 | 58 | EndDateTime = EndDate + EndTime; | |
| 150 | 58 | ReportStart = ReportStartDate + ReportStartTime; | |
| 151 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | ReportStart = MAX(ReportStart, StartDateTime); |
| 152 | |||
| 153 | // --- check for valid starting & ending date/times | ||
| 154 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( EndDateTime <= StartDateTime ) |
| 155 | { | ||
| 156 | ✗ | report_writeErrorMsg(ERR_START_DATE, ""); | |
| 157 | } | ||
| 158 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | else if ( EndDateTime <= ReportStart ) |
| 159 | { | ||
| 160 | ✗ | report_writeErrorMsg(ERR_REPORT_DATE, ""); | |
| 161 | } | ||
| 162 | else | ||
| 163 | { | ||
| 164 | // --- compute total duration of simulation in seconds | ||
| 165 | 58 | TotalDuration = floor((EndDateTime - StartDateTime) * SECperDAY); | |
| 166 | |||
| 167 | // --- reporting step must be <= total duration | ||
| 168 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( (double)ReportStep > TotalDuration ) |
| 169 | { | ||
| 170 | ✗ | ReportStep = (int)(TotalDuration); | |
| 171 | } | ||
| 172 | |||
| 173 | // --- reporting step can't be < routing step | ||
| 174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( (double)ReportStep < RouteStep ) |
| 175 | { | ||
| 176 | ✗ | report_writeErrorMsg(ERR_REPORT_STEP, ""); | |
| 177 | } | ||
| 178 | |||
| 179 | // --- convert total duration to milliseconds | ||
| 180 | 58 | TotalDuration *= 1000.0; | |
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | //============================================================================= | ||
| 185 | |||
| 186 | 58 | void project_validate() | |
| 187 | // | ||
| 188 | // Input: none | ||
| 189 | // Output: none | ||
| 190 | // Purpose: checks validity of project data. | ||
| 191 | // | ||
| 192 | { | ||
| 193 | int i; | ||
| 194 | int j; | ||
| 195 | int err; | ||
| 196 | |||
| 197 | // --- validate Curves and TimeSeries | ||
| 198 |
2/2✓ Branch 0 taken 221 times.
✓ Branch 1 taken 58 times.
|
279 | for ( i=0; i<Nobjects[CURVE]; i++ ) |
| 199 | { | ||
| 200 | 221 | err = table_validate(&Curve[i]); | |
| 201 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
|
221 | if ( err ) report_writeErrorMsg(ERR_CURVE_SEQUENCE, Curve[i].ID); |
| 202 | } | ||
| 203 |
2/2✓ Branch 0 taken 102 times.
✓ Branch 1 taken 58 times.
|
160 | for ( i=0; i<Nobjects[TSERIES]; i++ ) |
| 204 | { | ||
| 205 | 102 | err = table_validate(&Tseries[i]); | |
| 206 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
|
102 | if ( err ) report_writeTseriesErrorMsg(err, &Tseries[i]); |
| 207 | } | ||
| 208 | |||
| 209 | // --- validate hydrology objects | ||
| 210 | // (NOTE: order is important !!!!) | ||
| 211 | 58 | climate_validate(); | |
| 212 | 58 | lid_validate(); | |
| 213 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 8 times.
|
58 | if ( Nobjects[SNOWMELT] == 0 ) IgnoreSnowmelt = TRUE; |
| 214 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 9 times.
|
58 | if ( Nobjects[AQUIFER] == 0 ) IgnoreGwater = TRUE; |
| 215 |
2/2✓ Branch 1 taken 2186 times.
✓ Branch 2 taken 58 times.
|
2244 | for ( i=0; i<Nobjects[AQUIFER]; i++ ) gwater_validateAquifer(i); |
| 216 |
2/2✓ Branch 1 taken 2393 times.
✓ Branch 2 taken 58 times.
|
2451 | for ( i=0; i<Nobjects[SUBCATCH]; i++ ) subcatch_validate(i); |
| 217 |
2/2✓ Branch 1 taken 52 times.
✓ Branch 2 taken 58 times.
|
110 | for ( i=0; i<Nobjects[GAGE]; i++ ) gage_validate(i); |
| 218 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 58 times.
|
66 | for ( i=0; i<Nobjects[SNOWMELT]; i++ ) snow_validateSnowmelt(i); |
| 219 | |||
| 220 | // --- compute geometry tables for each shape curve | ||
| 221 | 58 | j = 0; | |
| 222 |
2/2✓ Branch 0 taken 221 times.
✓ Branch 1 taken 58 times.
|
279 | for ( i=0; i<Nobjects[CURVE]; i++ ) |
| 223 | { | ||
| 224 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 190 times.
|
221 | if ( Curve[i].curveType == SHAPE_CURVE ) |
| 225 | { | ||
| 226 | 31 | Curve[i].refersTo = j; | |
| 227 | 31 | Shape[j].curve = i; | |
| 228 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
|
31 | if ( !shape_validate(&Shape[j], &Curve[i]) ) |
| 229 | ✗ | report_writeErrorMsg(ERR_CURVE_SEQUENCE, Curve[i].ID); | |
| 230 | 31 | j++; | |
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | // --- validate links before nodes, since the latter can | ||
| 235 | // result in adjustment of node depths | ||
| 236 |
2/2✓ Branch 0 taken 10183 times.
✓ Branch 1 taken 58 times.
|
10241 | for ( i=0; i<Nobjects[NODE]; i++) Node[i].oldDepth = Node[i].fullDepth; |
| 237 |
2/2✓ Branch 1 taken 10508 times.
✓ Branch 2 taken 58 times.
|
10566 | for ( i=0; i<Nobjects[LINK]; i++) link_validate(i); |
| 238 |
2/2✓ Branch 1 taken 10183 times.
✓ Branch 2 taken 58 times.
|
10241 | for ( i=0; i<Nobjects[NODE]; i++) node_validate(i); |
| 239 | |||
| 240 | // --- adjust time steps if necessary | ||
| 241 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( DryStep < WetStep ) |
| 242 | { | ||
| 243 | ✗ | report_writeWarningMsg(WARN06, ""); | |
| 244 | ✗ | DryStep = WetStep; | |
| 245 | } | ||
| 246 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( RouteStep > (double)WetStep ) |
| 247 | { | ||
| 248 | ✗ | report_writeWarningMsg(WARN07, ""); | |
| 249 | ✗ | RouteStep = WetStep; | |
| 250 | } | ||
| 251 | |||
| 252 | // --- adjust individual reporting flags to match global reporting flag | ||
| 253 |
2/2✓ Branch 0 taken 46 times.
✓ Branch 1 taken 12 times.
|
58 | if ( RptFlags.subcatchments == ALL ) |
| 254 |
2/2✓ Branch 0 taken 2393 times.
✓ Branch 1 taken 46 times.
|
2439 | for (i=0; i<Nobjects[SUBCATCH]; i++) Subcatch[i].rptFlag = 1; |
| 255 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 10 times.
|
58 | if (RptFlags.nodes == ALL) |
| 256 |
2/2✓ Branch 0 taken 318 times.
✓ Branch 1 taken 48 times.
|
366 | for (i = 0; i < Nobjects[NODE]; i++) Node[i].rptFlag = 1; |
| 257 |
2/2✓ Branch 0 taken 47 times.
✓ Branch 1 taken 11 times.
|
58 | if ( RptFlags.links == ALL ) |
| 258 |
2/2✓ Branch 0 taken 238 times.
✓ Branch 1 taken 47 times.
|
285 | for (i=0; i<Nobjects[LINK]; i++) Link[i].rptFlag = 1; |
| 259 | |||
| 260 | // --- validate dynamic wave options | ||
| 261 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 17 times.
|
58 | if ( RouteModel == DW ) dynwave_validate(); |
| 262 | |||
| 263 | // --- validate street/channel inlets | ||
| 264 | 58 | inlet_validate(); | |
| 265 | |||
| 266 | // --- adjust number of parallel threads to be used | ||
| 267 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( NumThreads == 0 ) NumThreads = omp_get_max_threads(); |
| 268 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | else NumThreads = MIN(NumThreads, omp_get_max_threads()); |
| 269 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 32 times.
|
58 | if ( Nobjects[LINK] < 4 * NumThreads ) NumThreads = 1; |
| 270 | 58 | } | |
| 271 | |||
| 272 | //============================================================================= | ||
| 273 | |||
| 274 | 58 | void project_close() | |
| 275 | // | ||
| 276 | // Input: none | ||
| 277 | // Output: none | ||
| 278 | // Purpose: closes a SWMM project. | ||
| 279 | // | ||
| 280 | { | ||
| 281 | 58 | deleteObjects(); | |
| 282 | 58 | deleteHashTables(); | |
| 283 | 58 | } | |
| 284 | |||
| 285 | //============================================================================= | ||
| 286 | |||
| 287 | 58 | int project_init(void) | |
| 288 | // | ||
| 289 | // Input: none | ||
| 290 | // Output: returns an error code | ||
| 291 | // Purpose: initializes the internal state of all objects. | ||
| 292 | // | ||
| 293 | { | ||
| 294 | int j, k; | ||
| 295 | 58 | climate_initState(); | |
| 296 | 58 | lid_initState(); | |
| 297 |
2/2✓ Branch 1 taken 102 times.
✓ Branch 2 taken 58 times.
|
160 | for (j=0; j<Nobjects[TSERIES]; j++) table_tseriesInit(&Tseries[j]); |
| 298 |
2/2✓ Branch 1 taken 52 times.
✓ Branch 2 taken 58 times.
|
110 | for (j=0; j<Nobjects[GAGE]; j++) gage_initState(j); |
| 299 | 58 | k = 1; | |
| 300 |
2/2✓ Branch 0 taken 2393 times.
✓ Branch 1 taken 58 times.
|
2451 | for (j=0; j<Nobjects[SUBCATCH]; j++) |
| 301 | { | ||
| 302 | 2393 | subcatch_initState(j); | |
| 303 |
1/2✓ Branch 0 taken 2393 times.
✗ Branch 1 not taken.
|
2393 | if (Subcatch[j].rptFlag > 0) |
| 304 | { | ||
| 305 | 2393 | Subcatch[j].rptFlag = k; | |
| 306 | 2393 | k++; | |
| 307 | } | ||
| 308 | } | ||
| 309 | 58 | k = 1; | |
| 310 |
2/2✓ Branch 0 taken 10183 times.
✓ Branch 1 taken 58 times.
|
10241 | for (j=0; j<Nobjects[NODE]; j++) |
| 311 | { | ||
| 312 | 10183 | node_initState(j); | |
| 313 |
2/2✓ Branch 0 taken 817 times.
✓ Branch 1 taken 9366 times.
|
10183 | if (Node[j].rptFlag > 0) |
| 314 | { | ||
| 315 | 817 | Node[j].rptFlag = k; | |
| 316 | 817 | k++; | |
| 317 | } | ||
| 318 | } | ||
| 319 | 58 | k = 1; | |
| 320 |
2/2✓ Branch 0 taken 10508 times.
✓ Branch 1 taken 58 times.
|
10566 | for (j=0; j<Nobjects[LINK]; j++) |
| 321 | { | ||
| 322 | 10508 | link_initState(j); | |
| 323 |
2/2✓ Branch 0 taken 1220 times.
✓ Branch 1 taken 9288 times.
|
10508 | if (Link[j].rptFlag > 0) |
| 324 | { | ||
| 325 | 1220 | Link[j].rptFlag = k; | |
| 326 | 1220 | k++; | |
| 327 | } | ||
| 328 | } | ||
| 329 | 58 | return ErrorCode; | |
| 330 | } | ||
| 331 | |||
| 332 | //============================================================================= | ||
| 333 | |||
| 334 | 26489 | int project_addObject(int type, char *id, int n) | |
| 335 | // | ||
| 336 | // Input: type = object type | ||
| 337 | // id = object ID string | ||
| 338 | // n = object index | ||
| 339 | // Output: returns 0 if object already added, 1 if not, -1 if hashing fails | ||
| 340 | // Purpose: adds an object ID to a hash table | ||
| 341 | // | ||
| 342 | { | ||
| 343 | int result; | ||
| 344 | long len; | ||
| 345 | char *newID; | ||
| 346 | |||
| 347 | // --- do nothing if object already placed in hash table | ||
| 348 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 26489 times.
|
26489 | if ( project_findObject(type, id) >= 0 ) return 0; |
| 349 | |||
| 350 | // --- use memory from the hash tables' common memory pool to store | ||
| 351 | // a copy of the object's ID string | ||
| 352 | 26489 | len = (long)strlen(id); | |
| 353 | 26489 | newID = (char *) Alloc((len+1)*sizeof(char)); | |
| 354 | 26489 | sstrncpy(newID, id, len); | |
| 355 | |||
| 356 | // --- insert object's ID into the hash table for that type of object | ||
| 357 | 26489 | result = HTinsert(Htable[type], newID, n); | |
| 358 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 26489 times.
|
26489 | if ( result == 0 ) result = -1; |
| 359 | 26489 | return result; | |
| 360 | } | ||
| 361 | |||
| 362 | //============================================================================= | ||
| 363 | |||
| 364 | 208645 | int project_findObject(int type, const char *id) | |
| 365 | // | ||
| 366 | // Input: type = object type | ||
| 367 | // id = object ID | ||
| 368 | // Output: returns index of object with given ID, or -1 if ID not found | ||
| 369 | // Purpose: uses hash table to find index of an object with a given ID. | ||
| 370 | // | ||
| 371 | { | ||
| 372 | 208645 | return HTfind(Htable[type], id); | |
| 373 | } | ||
| 374 | |||
| 375 | //============================================================================= | ||
| 376 | |||
| 377 | 26490 | char *project_findID(int type, char *id) | |
| 378 | // | ||
| 379 | // Input: type = object type | ||
| 380 | // id = ID name being sought | ||
| 381 | // Output: returns pointer to location where object's ID string is stored | ||
| 382 | // Purpose: uses hash table to find address of given string entry. | ||
| 383 | // | ||
| 384 | { | ||
| 385 | 26490 | return HTfindKey(Htable[type], id); | |
| 386 | } | ||
| 387 | |||
| 388 | //============================================================================= | ||
| 389 | |||
| 390 | 2 | double ** project_createMatrix(int nrows, int ncols) | |
| 391 | // | ||
| 392 | // Input: nrows = number of rows (0-based) | ||
| 393 | // ncols = number of columns (0-based) | ||
| 394 | // Output: returns a pointer to a matrix | ||
| 395 | // Purpose: allocates memory for a matrix of doubles. | ||
| 396 | // | ||
| 397 | { | ||
| 398 | int i; | ||
| 399 | double **a; | ||
| 400 | |||
| 401 | 2 | size_t size = (size_t)nrows * (size_t)ncols; | |
| 402 | |||
| 403 | // --- allocate pointers to rows | ||
| 404 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (nrows < 1 || ncols < 1) |
| 405 | ✗ | return NULL; | |
| 406 | 2 | a = (double **) malloc(nrows * sizeof(double *)); | |
| 407 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if ( !a ) |
| 408 | ✗ | return NULL; | |
| 409 | |||
| 410 | // --- allocate rows and set pointers to them | ||
| 411 | 2 | a[0] = (double *) malloc (size * sizeof(double)); | |
| 412 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if ( !a[0] ) |
| 413 | { | ||
| 414 | ✗ | free(a); | |
| 415 | ✗ | return NULL; | |
| 416 | } | ||
| 417 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | for ( i = 1; i < nrows; i++ ) |
| 418 | ✗ | a[i] = a[i-1] + ncols; | |
| 419 | |||
| 420 | // --- fill matrix with zeroes | ||
| 421 | 2 | memset(a[0], 0, size); | |
| 422 | |||
| 423 | // --- return pointer to array of pointers to rows | ||
| 424 | 2 | return a; | |
| 425 | } | ||
| 426 | |||
| 427 | //============================================================================= | ||
| 428 | |||
| 429 | 2 | void project_freeMatrix(double **a) | |
| 430 | // | ||
| 431 | // Input: a = matrix of floats | ||
| 432 | // Output: none | ||
| 433 | // Purpose: frees memory allocated for a matrix of doubles. | ||
| 434 | // | ||
| 435 | { | ||
| 436 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if ( a != NULL ) |
| 437 | { | ||
| 438 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if ( a[0] != NULL ) free( a[0] ); |
| 439 | 2 | free( a ); | |
| 440 | } | ||
| 441 | 2 | } | |
| 442 | |||
| 443 | //============================================================================= | ||
| 444 | |||
| 445 | 1588 | int project_readOption(char* s1, char* s2) | |
| 446 | // | ||
| 447 | // Input: s1 = option keyword | ||
| 448 | // s2 = string representation of option's value | ||
| 449 | // Output: returns error code | ||
| 450 | // Purpose: reads a project option from a pair of string tokens. | ||
| 451 | // | ||
| 452 | // NOTE: all project options have default values assigned in setDefaults(). | ||
| 453 | // | ||
| 454 | { | ||
| 455 | int k, m, h, s; | ||
| 456 | double tStep; | ||
| 457 | char strDate[25]; | ||
| 458 | DateTime aTime; | ||
| 459 | DateTime aDate; | ||
| 460 | |||
| 461 | // --- determine which option is being read | ||
| 462 | 1588 | k = findmatch(s1, OptionWords); | |
| 463 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1588 times.
|
1588 | if ( k < 0 ) return error_setInpError(ERR_KEYWORD, s1); |
| 464 |
28/31✓ Branch 0 taken 58 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 58 times.
✓ Branch 3 taken 58 times.
✓ Branch 4 taken 58 times.
✓ Branch 5 taken 58 times.
✓ Branch 6 taken 58 times.
✓ Branch 7 taken 58 times.
✓ Branch 8 taken 58 times.
✓ Branch 9 taken 78 times.
✓ Branch 10 taken 52 times.
✓ Branch 11 taken 194 times.
✓ Branch 12 taken 39 times.
✓ Branch 13 taken 110 times.
✓ Branch 14 taken 40 times.
✓ Branch 15 taken 39 times.
✓ Branch 16 taken 56 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 96 times.
✓ Branch 19 taken 40 times.
✓ Branch 20 taken 58 times.
✓ Branch 21 taken 44 times.
✓ Branch 22 taken 41 times.
✓ Branch 23 taken 38 times.
✓ Branch 24 taken 37 times.
✓ Branch 25 taken 37 times.
✓ Branch 26 taken 33 times.
✓ Branch 27 taken 33 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 time.
✗ Branch 30 not taken.
|
1588 | switch ( k ) |
| 465 | { | ||
| 466 | // --- choice of flow units | ||
| 467 | 58 | case FLOW_UNITS: | |
| 468 | 58 | m = findmatch(s2, FlowUnitWords); | |
| 469 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 470 | 58 | FlowUnits = m; | |
| 471 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 3 times.
|
58 | if ( FlowUnits <= MGD ) UnitSystem = US; |
| 472 | 3 | else UnitSystem = SI; | |
| 473 | 58 | break; | |
| 474 | |||
| 475 | // --- choice of infiltration modeling method | ||
| 476 | 58 | case INFIL_MODEL: | |
| 477 | 58 | m = findmatch(s2, InfilModelWords); | |
| 478 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 479 | 58 | InfilModel = m; | |
| 480 | 58 | break; | |
| 481 | |||
| 482 | // --- choice of flow routing method | ||
| 483 | 58 | case ROUTE_MODEL: | |
| 484 | 58 | m = findmatch(s2, RouteModelWords); | |
| 485 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( m < 0 ) m = findmatch(s2, OldRouteModelWords); |
| 486 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 487 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( m == NO_ROUTING ) IgnoreRouting = TRUE; |
| 488 | 58 | else RouteModel = m; | |
| 489 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( RouteModel == EKW ) RouteModel = KW; |
| 490 | 58 | break; | |
| 491 | |||
| 492 | // --- simulation start date | ||
| 493 | 58 | case START_DATE: | |
| 494 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ( !datetime_strToDate(s2, &StartDate) ) |
| 495 | { | ||
| 496 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 497 | } | ||
| 498 | 58 | break; | |
| 499 | |||
| 500 | // --- simulation start time of day | ||
| 501 | 58 | case START_TIME: | |
| 502 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ( !datetime_strToTime(s2, &StartTime) ) |
| 503 | { | ||
| 504 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 505 | } | ||
| 506 | 58 | break; | |
| 507 | |||
| 508 | // --- simulation ending date | ||
| 509 | 58 | case END_DATE: | |
| 510 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ( !datetime_strToDate(s2, &EndDate) ) |
| 511 | { | ||
| 512 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 513 | } | ||
| 514 | 58 | break; | |
| 515 | |||
| 516 | // --- simulation ending time of day | ||
| 517 | 58 | case END_TIME: | |
| 518 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ( !datetime_strToTime(s2, &EndTime) ) |
| 519 | { | ||
| 520 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 521 | } | ||
| 522 | 58 | break; | |
| 523 | |||
| 524 | // --- reporting start date | ||
| 525 | 58 | case REPORT_START_DATE: | |
| 526 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ( !datetime_strToDate(s2, &ReportStartDate) ) |
| 527 | { | ||
| 528 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 529 | } | ||
| 530 | 58 | break; | |
| 531 | |||
| 532 | // --- reporting start time of day | ||
| 533 | 58 | case REPORT_START_TIME: | |
| 534 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ( !datetime_strToTime(s2, &ReportStartTime) ) |
| 535 | { | ||
| 536 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 537 | } | ||
| 538 | 58 | break; | |
| 539 | |||
| 540 | // --- day of year when street sweeping begins or when it ends | ||
| 541 | // (year is arbitrarily set to 1947 so that the dayOfYear | ||
| 542 | // function can be applied) | ||
| 543 | 78 | case SWEEP_START: | |
| 544 | case SWEEP_END: | ||
| 545 | 78 | sstrncpy(strDate, s2, 24); | |
| 546 | 78 | sstrcat(strDate, "/1947", 25); | |
| 547 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 78 times.
|
78 | if ( !datetime_strToDate(strDate, &aDate) ) |
| 548 | { | ||
| 549 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 550 | } | ||
| 551 | 78 | m = datetime_dayOfYear(aDate); | |
| 552 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 39 times.
|
78 | if ( k == SWEEP_START ) SweepStart = m; |
| 553 | 39 | else SweepEnd = m; | |
| 554 | 78 | break; | |
| 555 | |||
| 556 | // --- number of antecedent dry days | ||
| 557 | 52 | case START_DRY_DAYS: | |
| 558 | 52 | StartDryDays = atof(s2); | |
| 559 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
|
52 | if ( StartDryDays < 0.0 ) |
| 560 | { | ||
| 561 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 562 | } | ||
| 563 | 52 | break; | |
| 564 | |||
| 565 | // --- runoff or reporting time steps | ||
| 566 | // (input is in hrs:min:sec format, time step saved as seconds) | ||
| 567 | 194 | case WET_STEP: | |
| 568 | case DRY_STEP: | ||
| 569 | case REPORT_STEP: | ||
| 570 | case RULE_STEP: | ||
| 571 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 194 times.
|
194 | if ( !datetime_strToTime(s2, &aTime) ) |
| 572 | { | ||
| 573 | ✗ | return error_setInpError(ERR_DATETIME, s2); | |
| 574 | } | ||
| 575 | 194 | datetime_decodeTime(aTime, &h, &m, &s); | |
| 576 | 194 | h += 24*(int)aTime; | |
| 577 | 194 | s = s + 60*m + 3600*h; | |
| 578 | |||
| 579 | // --- RuleStep allowed to be 0 while other time steps must be > 0 | ||
| 580 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 174 times.
|
194 | if (k == RULE_STEP) |
| 581 | { | ||
| 582 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | if (s < 0) return error_setInpError(ERR_NUMBER, s2); |
| 583 | } | ||
| 584 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 174 times.
|
174 | else if ( s <= 0 ) return error_setInpError(ERR_NUMBER, s2); |
| 585 | |||
| 586 |
4/5✓ Branch 0 taken 58 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 58 times.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
|
194 | switch ( k ) |
| 587 | { | ||
| 588 | 58 | case WET_STEP: WetStep = s; break; | |
| 589 | 58 | case DRY_STEP: DryStep = s; break; | |
| 590 | 58 | case REPORT_STEP: ReportStep = s; break; | |
| 591 | 20 | case RULE_STEP: RuleStep = s; break; | |
| 592 | } | ||
| 593 | 194 | break; | |
| 594 | |||
| 595 | // --- type of damping applied to inertial terms of dynamic wave routing | ||
| 596 | 39 | case INERT_DAMPING: | |
| 597 | 39 | m = findmatch(s2, InertDampingWords); | |
| 598 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 599 | 39 | else InertDamping = m; | |
| 600 | 39 | break; | |
| 601 | |||
| 602 | // --- Yes/No options (NO = 0, YES = 1) | ||
| 603 | 110 | case ALLOW_PONDING: | |
| 604 | case SLOPE_WEIGHTING: | ||
| 605 | case SKIP_STEADY_STATE: | ||
| 606 | case IGNORE_RAINFALL: | ||
| 607 | case IGNORE_SNOWMELT: | ||
| 608 | case IGNORE_GWATER: | ||
| 609 | case IGNORE_ROUTING: | ||
| 610 | case IGNORE_QUALITY: | ||
| 611 | case IGNORE_RDII: | ||
| 612 | 110 | m = findmatch(s2, NoYesWords); | |
| 613 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 110 times.
|
110 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 614 |
6/10✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
110 | switch ( k ) |
| 615 | { | ||
| 616 | 41 | case ALLOW_PONDING: AllowPonding = m; break; | |
| 617 | ✗ | case SLOPE_WEIGHTING: SlopeWeighting = m; break; | |
| 618 | 41 | case SKIP_STEADY_STATE: SkipSteadyState = m; break; | |
| 619 | 7 | case IGNORE_RAINFALL: IgnoreRainfall = m; break; | |
| 620 | 7 | case IGNORE_SNOWMELT: IgnoreSnowmelt = m; break; | |
| 621 | 7 | case IGNORE_GWATER: IgnoreGwater = m; break; | |
| 622 | ✗ | case IGNORE_ROUTING: IgnoreRouting = m; break; | |
| 623 | 7 | case IGNORE_QUALITY: IgnoreQuality = m; break; | |
| 624 | ✗ | case IGNORE_RDII: IgnoreRDII = m; break; | |
| 625 | } | ||
| 626 | 110 | break; | |
| 627 | |||
| 628 | 40 | case NORMAL_FLOW_LTD: | |
| 629 | 40 | m = findmatch(s2, NormalFlowWords); | |
| 630 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 631 | 40 | NormalFlowLtd = m; | |
| 632 | 40 | break; | |
| 633 | |||
| 634 | 39 | case FORCE_MAIN_EQN: | |
| 635 | 39 | m = findmatch(s2, ForceMainEqnWords); | |
| 636 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 637 | 39 | ForceMainEqn = m; | |
| 638 | 39 | break; | |
| 639 | |||
| 640 | 56 | case LINK_OFFSETS: | |
| 641 | 56 | m = findmatch(s2, LinkOffsetWords); | |
| 642 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
|
56 | if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); |
| 643 | 56 | LinkOffsets = m; | |
| 644 | 56 | break; | |
| 645 | |||
| 646 | // --- compatibility option for selecting solution method for | ||
| 647 | // dynamic wave flow routing (NOT CURRENTLY USED) | ||
| 648 | ✗ | case COMPATIBILITY: | |
| 649 | ✗ | if ( strcomp(s2, "3") ) Compatibility = SWMM3; | |
| 650 | ✗ | else if ( strcomp(s2, "4") ) Compatibility = SWMM4; | |
| 651 | ✗ | else if ( strcomp(s2, "5") ) Compatibility = SWMM5; | |
| 652 | ✗ | else return error_setInpError(ERR_KEYWORD, s2); | |
| 653 | ✗ | break; | |
| 654 | |||
| 655 | // --- routing or lengthening time step (in decimal seconds) | ||
| 656 | // (lengthening time step is used in Courant stability formula | ||
| 657 | // to artificially lengthen conduits for dynamic wave flow routing | ||
| 658 | // (a value of 0 means that no lengthening is used)) | ||
| 659 | 96 | case ROUTE_STEP: | |
| 660 | case LENGTHENING_STEP: | ||
| 661 |
2/2✓ Branch 1 taken 39 times.
✓ Branch 2 taken 57 times.
|
96 | if ( !getDouble(s2, &tStep) ) |
| 662 | { | ||
| 663 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
|
39 | if ( !datetime_strToTime(s2, &aTime) ) |
| 664 | { | ||
| 665 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 666 | } | ||
| 667 | else | ||
| 668 | { | ||
| 669 | 39 | datetime_decodeTime(aTime, &h, &m, &s); | |
| 670 | 39 | h += 24*(int)aTime; | |
| 671 | 39 | s = s + 60*m + 3600*h; | |
| 672 | 39 | tStep = s; | |
| 673 | } | ||
| 674 | } | ||
| 675 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 38 times.
|
96 | if ( k == ROUTE_STEP ) |
| 676 | { | ||
| 677 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( tStep <= 0.0 ) return error_setInpError(ERR_NUMBER, s2); |
| 678 | 58 | RouteStep = tStep; | |
| 679 | } | ||
| 680 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 12 times.
|
38 | else LengtheningStep = MAX(0.0, tStep); |
| 681 | 96 | break; | |
| 682 | |||
| 683 | // --- minimum variable time step for dynamic wave routing | ||
| 684 | 40 | case MIN_ROUTE_STEP: | |
| 685 |
2/4✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
|
40 | if ( !getDouble(s2, &MinRouteStep) || MinRouteStep < 0.0 ) |
| 686 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 687 | 40 | break; | |
| 688 | |||
| 689 | 58 | case NUM_THREADS: | |
| 690 | 58 | m = atoi(s2); | |
| 691 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( m < 0 ) return error_setInpError(ERR_NUMBER, s2); |
| 692 | 58 | NumThreads = m; | |
| 693 | 58 | break; | |
| 694 | |||
| 695 | // --- safety factor applied to variable time step estimates under | ||
| 696 | // dynamic wave flow routing (value of 0 indicates that variable | ||
| 697 | // time step option not used) | ||
| 698 | 44 | case VARIABLE_STEP: | |
| 699 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
|
44 | if ( !getDouble(s2, &CourantFactor) ) |
| 700 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 701 |
2/4✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 44 times.
|
44 | if ( CourantFactor < 0.0 || CourantFactor > 2.0 ) |
| 702 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 703 | 44 | break; | |
| 704 | |||
| 705 | // --- minimum surface area (ft2 or sq. meters) associated with nodes | ||
| 706 | // under dynamic wave flow routing | ||
| 707 | 41 | case MIN_SURFAREA: | |
| 708 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
|
41 | if (!getDouble(s2, &MinSurfArea)) |
| 709 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 710 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
|
41 | if (MinSurfArea < 0.0) |
| 711 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 712 | 41 | break; | |
| 713 | |||
| 714 | // --- minimum conduit slope (%) | ||
| 715 | 38 | case MIN_SLOPE: | |
| 716 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
|
38 | if ( !getDouble(s2, &MinSlope) ) |
| 717 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 718 |
2/4✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
|
38 | if ( MinSlope < 0.0 || MinSlope >= 100 ) |
| 719 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 720 | 38 | MinSlope /= 100.0; | |
| 721 | 38 | break; | |
| 722 | |||
| 723 | // --- maximum trials / time step for dynamic wave routing | ||
| 724 | 37 | case MAX_TRIALS: | |
| 725 | 37 | m = atoi(s2); | |
| 726 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
|
37 | if ( m < 0 ) return error_setInpError(ERR_NUMBER, s2); |
| 727 | 37 | MaxTrials = m; | |
| 728 | 37 | break; | |
| 729 | |||
| 730 | // --- head convergence tolerance for dynamic wave routing | ||
| 731 | 37 | case HEAD_TOL: | |
| 732 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
|
37 | if ( !getDouble(s2, &HeadTol) ) |
| 733 | { | ||
| 734 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 735 | } | ||
| 736 | 37 | break; | |
| 737 | |||
| 738 | // --- steady state tolerance on system inflow - outflow | ||
| 739 | 33 | case SYS_FLOW_TOL: | |
| 740 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
|
33 | if ( !getDouble(s2, &SysFlowTol) ) |
| 741 | { | ||
| 742 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 743 | } | ||
| 744 | 33 | SysFlowTol /= 100.0; | |
| 745 | 33 | break; | |
| 746 | |||
| 747 | // --- steady state tolerance on nodal lateral inflow | ||
| 748 | 33 | case LAT_FLOW_TOL: | |
| 749 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
|
33 | if ( !getDouble(s2, &LatFlowTol) ) |
| 750 | { | ||
| 751 | ✗ | return error_setInpError(ERR_NUMBER, s2); | |
| 752 | } | ||
| 753 | 33 | LatFlowTol /= 100.0; | |
| 754 | 33 | break; | |
| 755 | |||
| 756 | // --- method used for surcharging in dynamic wave flow routing | ||
| 757 | ✗ | case SURCHARGE_METHOD: | |
| 758 | ✗ | m = findmatch(s2, SurchargeWords); | |
| 759 | ✗ | if (m < 0) return error_setInpError(ERR_KEYWORD, s2); | |
| 760 | ✗ | SurchargeMethod = m; | |
| 761 | ✗ | break; | |
| 762 | |||
| 763 | 1 | case TEMPDIR: // Temporary Directory | |
| 764 | 1 | sstrncpy(TempDir, s2, MAXFNAME); | |
| 765 | 1 | break; | |
| 766 | |||
| 767 | } | ||
| 768 | 1588 | return 0; | |
| 769 | } | ||
| 770 | |||
| 771 | //============================================================================= | ||
| 772 | |||
| 773 | 58 | void initPointers() | |
| 774 | // | ||
| 775 | // Input: none | ||
| 776 | // Output: none | ||
| 777 | // Purpose: assigns NULL to all dynamic arrays for a new project. | ||
| 778 | // | ||
| 779 | { | ||
| 780 | 58 | Gage = NULL; | |
| 781 | 58 | Subcatch = NULL; | |
| 782 | 58 | Node = NULL; | |
| 783 | 58 | Outfall = NULL; | |
| 784 | 58 | Divider = NULL; | |
| 785 | 58 | Storage = NULL; | |
| 786 | 58 | Link = NULL; | |
| 787 | 58 | Conduit = NULL; | |
| 788 | 58 | Pump = NULL; | |
| 789 | 58 | Orifice = NULL; | |
| 790 | 58 | Weir = NULL; | |
| 791 | 58 | Outlet = NULL; | |
| 792 | 58 | Pollut = NULL; | |
| 793 | 58 | Landuse = NULL; | |
| 794 | 58 | Pattern = NULL; | |
| 795 | 58 | Curve = NULL; | |
| 796 | 58 | Tseries = NULL; | |
| 797 | 58 | Transect = NULL; | |
| 798 | 58 | Shape = NULL; | |
| 799 | 58 | Aquifer = NULL; | |
| 800 | 58 | UnitHyd = NULL; | |
| 801 | 58 | Snowmelt = NULL; | |
| 802 | 58 | Event = NULL; | |
| 803 | 58 | MemPoolAllocated = FALSE; | |
| 804 | 58 | } | |
| 805 | |||
| 806 | //============================================================================= | ||
| 807 | |||
| 808 | 58 | void setDefaults() | |
| 809 | // | ||
| 810 | // Input: none | ||
| 811 | // Output: none | ||
| 812 | // Purpose: assigns default values to project variables. | ||
| 813 | // | ||
| 814 | { | ||
| 815 | int i, j; | ||
| 816 | |||
| 817 | // Project title & temp. file path | ||
| 818 |
2/2✓ Branch 1 taken 174 times.
✓ Branch 2 taken 58 times.
|
232 | for (i = 0; i < MAXTITLE; i++) sstrncpy(Title[i], "", 0); |
| 819 | 58 | sstrncpy(TempDir, "", 0); | |
| 820 | |||
| 821 | // Interface files | ||
| 822 | 58 | Frain.mode = SCRATCH_FILE; // Use scratch rainfall file | |
| 823 | 58 | Fclimate.mode = NO_FILE; | |
| 824 | 58 | Frunoff.mode = NO_FILE; | |
| 825 | 58 | Frdii.mode = NO_FILE; | |
| 826 | 58 | Fhotstart1.mode = NO_FILE; | |
| 827 | 58 | Fhotstart2.mode = NO_FILE; | |
| 828 | 58 | Finflows.mode = NO_FILE; | |
| 829 | 58 | Foutflows.mode = NO_FILE; | |
| 830 | 58 | Frain.file = NULL; | |
| 831 | 58 | Fclimate.file = NULL; | |
| 832 | 58 | Frunoff.file = NULL; | |
| 833 | 58 | Frdii.file = NULL; | |
| 834 | 58 | Fhotstart1.file = NULL; | |
| 835 | 58 | Fhotstart2.file = NULL; | |
| 836 | 58 | Finflows.file = NULL; | |
| 837 | 58 | Foutflows.file = NULL; | |
| 838 | 58 | Fout.file = NULL; | |
| 839 | 58 | Fout.mode = NO_FILE; | |
| 840 | |||
| 841 | // Analysis options | ||
| 842 | 58 | UnitSystem = US; // US unit system | |
| 843 | 58 | FlowUnits = CFS; // CFS flow units | |
| 844 | 58 | InfilModel = HORTON; // Horton infiltration method | |
| 845 | 58 | RouteModel = DW; // Dynamic wave flow routing method | |
| 846 | 58 | SurchargeMethod = EXTRAN; // Use EXTRAN method for surcharging | |
| 847 | 58 | CrownCutoff = 0.96; // Fractional pipe crown cutoff | |
| 848 | 58 | AllowPonding = FALSE; // No ponding at nodes | |
| 849 | 58 | InertDamping = PARTIAL_DAMPING; // Partial inertial damping | |
| 850 | 58 | NormalFlowLtd = BOTH; // Default normal flow limitation | |
| 851 | 58 | ForceMainEqn = H_W; // Hazen-Williams eqn. for force mains | |
| 852 | 58 | LinkOffsets = DEPTH_OFFSET; // Use depth for link offsets | |
| 853 | 58 | LengtheningStep = 0; // No lengthening of conduits | |
| 854 | 58 | CourantFactor = 0.75; // Variable time step reduced to 75% | |
| 855 | 58 | MinSurfArea = 0.0; // Force use of default min. surface area | |
| 856 | 58 | MinSlope = 0.0; // No user supplied minimum conduit slope | |
| 857 | 58 | SkipSteadyState = FALSE; // Do flow routing in steady state periods | |
| 858 | 58 | IgnoreRainfall = FALSE; // Analyze rainfall/runoff | |
| 859 | 58 | IgnoreRDII = FALSE; // Analyze RDII | |
| 860 | 58 | IgnoreSnowmelt = FALSE; // Analyze snowmelt | |
| 861 | 58 | IgnoreGwater = FALSE; // Analyze groundwater | |
| 862 | 58 | IgnoreRouting = FALSE; // Analyze flow routing | |
| 863 | 58 | IgnoreQuality = FALSE; // Analyze water quality | |
| 864 | 58 | WetStep = 300; // Runoff wet time step (secs) | |
| 865 | 58 | DryStep = 3600; // Runoff dry time step (secs) | |
| 866 | 58 | RuleStep = 0; // Rules evaluated at each routing step | |
| 867 | 58 | RouteStep = 20; // Routing time step (secs) | |
| 868 | 58 | MinRouteStep = 0.5; // Minimum variable time step (sec) | |
| 869 | 58 | ReportStep = 900; // Reporting time step (secs) | |
| 870 | 58 | StartDryDays = 0.0; // Antecedent dry days | |
| 871 | 58 | MaxTrials = 0; // Force use of default max. trials | |
| 872 | 58 | HeadTol = 0.0; // Force use of default head tolerance | |
| 873 | 58 | SysFlowTol = 0.05; // System flow tolerance for steady state | |
| 874 | 58 | LatFlowTol = 0.05; // Lateral flow tolerance for steady state | |
| 875 | 58 | NumThreads = 1; // Number of parallel threads to use | |
| 876 | 58 | NumEvents = 0; // Number of detailed routing events | |
| 877 | |||
| 878 | // Deprecated options | ||
| 879 | 58 | SlopeWeighting = TRUE; // Use slope weighting | |
| 880 | 58 | Compatibility = SWMM4; // Use SWMM 4 up/dn weighting method | |
| 881 | |||
| 882 | // Starting & ending date/time | ||
| 883 | 58 | StartDate = datetime_encodeDate(2004, 1, 1); | |
| 884 | 58 | StartTime = datetime_encodeTime(0,0,0); | |
| 885 | 58 | StartDateTime = StartDate + StartTime; | |
| 886 | 58 | EndDate = StartDate; | |
| 887 | 58 | EndTime = 0.0; | |
| 888 | 58 | ReportStartDate = NO_DATE; | |
| 889 | 58 | ReportStartTime = NO_DATE; | |
| 890 | 58 | SweepStart = 1; | |
| 891 | 58 | SweepEnd = 365; | |
| 892 | |||
| 893 | // Reporting options | ||
| 894 | 58 | RptFlags.disabled = FALSE; | |
| 895 | 58 | RptFlags.input = FALSE; | |
| 896 | 58 | RptFlags.continuity = TRUE; | |
| 897 | 58 | RptFlags.flowStats = TRUE; | |
| 898 | 58 | RptFlags.controls = FALSE; | |
| 899 | 58 | RptFlags.subcatchments = FALSE; | |
| 900 | 58 | RptFlags.nodes = FALSE; | |
| 901 | 58 | RptFlags.links = FALSE; | |
| 902 | 58 | RptFlags.averages = FALSE; | |
| 903 | |||
| 904 | // Temperature data | ||
| 905 | 58 | Temp.dataSource = NO_TEMP; | |
| 906 | 58 | Temp.tSeries = -1; | |
| 907 | 58 | Temp.ta = 70.0; | |
| 908 | 58 | Temp.elev = 0.0; | |
| 909 | 58 | Temp.anglat = 40.0; | |
| 910 | 58 | Temp.dtlong = 0.0; | |
| 911 | 58 | Temp.tmax = MISSING; | |
| 912 | |||
| 913 | // Wind speed data | ||
| 914 | 58 | Wind.type = MONTHLY_WIND; | |
| 915 |
2/2✓ Branch 0 taken 696 times.
✓ Branch 1 taken 58 times.
|
754 | for ( i=0; i<12; i++ ) Wind.aws[i] = 0.0; |
| 916 | |||
| 917 | // Snowmelt parameters | ||
| 918 | 58 | Snow.snotmp = 34.0; | |
| 919 | 58 | Snow.tipm = 0.5; | |
| 920 | 58 | Snow.rnm = 0.6; | |
| 921 | |||
| 922 | // Snow areal depletion curves for pervious and impervious surfaces | ||
| 923 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 58 times.
|
174 | for ( i=0; i<2; i++ ) |
| 924 | { | ||
| 925 |
2/2✓ Branch 0 taken 1160 times.
✓ Branch 1 taken 116 times.
|
1276 | for ( j=0; j<10; j++) Snow.adc[i][j] = 1.0; |
| 926 | } | ||
| 927 | |||
| 928 | // Evaporation rates | ||
| 929 | 58 | Evap.type = CONSTANT_EVAP; | |
| 930 |
2/2✓ Branch 0 taken 696 times.
✓ Branch 1 taken 58 times.
|
754 | for (i=0; i<12; i++) |
| 931 | { | ||
| 932 | 696 | Evap.monthlyEvap[i] = 0.0; | |
| 933 | 696 | Evap.panCoeff[i] = 1.0; | |
| 934 | } | ||
| 935 | 58 | Evap.recoveryPattern = -1; | |
| 936 | 58 | Evap.recoveryFactor = 1.0; | |
| 937 | 58 | Evap.tSeries = -1; | |
| 938 | 58 | Evap.dryOnly = FALSE; | |
| 939 | |||
| 940 | // Climate adjustments | ||
| 941 |
2/2✓ Branch 0 taken 696 times.
✓ Branch 1 taken 58 times.
|
754 | for (i = 0; i < 12; i++) |
| 942 | { | ||
| 943 | 696 | Adjust.temp[i] = 0.0; // additive adjustments | |
| 944 | 696 | Adjust.evap[i] = 0.0; // additive adjustments | |
| 945 | 696 | Adjust.rain[i] = 1.0; // multiplicative adjustments | |
| 946 | 696 | Adjust.hydcon[i] = 1.0; // hyd. conductivity adjustments | |
| 947 | } | ||
| 948 | 58 | Adjust.rainFactor = 1.0; | |
| 949 | 58 | Adjust.hydconFactor = 1.0; | |
| 950 | 58 | } | |
| 951 | |||
| 952 | //============================================================================= | ||
| 953 | |||
| 954 | 58 | void openFiles(const char *f1, const char *f2, const char *f3) | |
| 955 | // | ||
| 956 | // Input: f1 = name of input file | ||
| 957 | // f2 = name of report file | ||
| 958 | // f3 = name of binary output file | ||
| 959 | // Output: none | ||
| 960 | // Purpose: opens a project's input and report files. | ||
| 961 | // | ||
| 962 | { | ||
| 963 | // --- initialize file pointers to NULL | ||
| 964 | 58 | Finp.file = NULL; | |
| 965 | 58 | Frpt.file = NULL; | |
| 966 | 58 | Fout.file = NULL; | |
| 967 | |||
| 968 | // --- save file names | ||
| 969 | 58 | sstrncpy(Finp.name, f1, MAXFNAME); | |
| 970 | 58 | sstrncpy(Frpt.name, f2, MAXFNAME); | |
| 971 | 58 | sstrncpy(Fout.name, f3, MAXFNAME); | |
| 972 | |||
| 973 | // --- check that file names are not identical | ||
| 974 |
3/6✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 58 times.
|
58 | if (strcomp(f1, f2) || strcomp(f1, f3) || strcomp(f2, f3)) |
| 975 | { | ||
| 976 | ✗ | writecon(FMT11); | |
| 977 | ✗ | ErrorCode = ERR_FILE_NAME; | |
| 978 | ✗ | return; | |
| 979 | } | ||
| 980 | |||
| 981 | // --- open input and report files | ||
| 982 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ((Finp.file = fopen(f1,"rt")) == NULL) |
| 983 | { | ||
| 984 | ✗ | writecon(FMT12); | |
| 985 | ✗ | writecon(f1); | |
| 986 | ✗ | ErrorCode = ERR_INP_FILE; | |
| 987 | ✗ | return; | |
| 988 | } | ||
| 989 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ((Frpt.file = fopen(f2,"wt")) == NULL) |
| 990 | { | ||
| 991 | ✗ | writecon(FMT13); | |
| 992 | ✗ | ErrorCode = ERR_RPT_FILE; | |
| 993 | ✗ | return; | |
| 994 | } | ||
| 995 | } | ||
| 996 | |||
| 997 | //============================================================================= | ||
| 998 | |||
| 999 | 58 | void createObjects() | |
| 1000 | // | ||
| 1001 | // Input: none | ||
| 1002 | // Output: none | ||
| 1003 | // Purpose: allocates memory for project's objects. | ||
| 1004 | // | ||
| 1005 | // NOTE: number of each type of object has already been determined in | ||
| 1006 | // project_readInput(). | ||
| 1007 | // | ||
| 1008 | { | ||
| 1009 | int j, k; | ||
| 1010 | |||
| 1011 | // --- allocate memory for each category of object | ||
| 1012 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( ErrorCode ) return; |
| 1013 | 58 | Gage = (TGage *) calloc(Nobjects[GAGE], sizeof(TGage)); | |
| 1014 | 58 | Subcatch = (TSubcatch *) calloc(Nobjects[SUBCATCH], sizeof(TSubcatch)); | |
| 1015 | 58 | Node = (TNode *) calloc(Nobjects[NODE], sizeof(TNode)); | |
| 1016 | 58 | Outfall = (TOutfall *) calloc(Nnodes[OUTFALL], sizeof(TOutfall)); | |
| 1017 | 58 | Divider = (TDivider *) calloc(Nnodes[DIVIDER], sizeof(TDivider)); | |
| 1018 | 58 | Storage = (TStorage *) calloc(Nnodes[STORAGE], sizeof(TStorage)); | |
| 1019 | 58 | Link = (TLink *) calloc(Nobjects[LINK], sizeof(TLink)); | |
| 1020 | 58 | Conduit = (TConduit *) calloc(Nlinks[CONDUIT], sizeof(TConduit)); | |
| 1021 | 58 | Pump = (TPump *) calloc(Nlinks[PUMP], sizeof(TPump)); | |
| 1022 | 58 | Orifice = (TOrifice *) calloc(Nlinks[ORIFICE], sizeof(TOrifice)); | |
| 1023 | 58 | Weir = (TWeir *) calloc(Nlinks[WEIR], sizeof(TWeir)); | |
| 1024 | 58 | Outlet = (TOutlet *) calloc(Nlinks[OUTLET], sizeof(TOutlet)); | |
| 1025 | 58 | Pollut = (TPollut *) calloc(Nobjects[POLLUT], sizeof(TPollut)); | |
| 1026 | 58 | Landuse = (TLanduse *) calloc(Nobjects[LANDUSE], sizeof(TLanduse)); | |
| 1027 | 58 | Pattern = (TPattern *) calloc(Nobjects[TIMEPATTERN], sizeof(TPattern)); | |
| 1028 | 58 | Curve = (TTable *) calloc(Nobjects[CURVE], sizeof(TTable)); | |
| 1029 | 58 | Tseries = (TTable *) calloc(Nobjects[TSERIES], sizeof(TTable)); | |
| 1030 | 58 | Aquifer = (TAquifer *) calloc(Nobjects[AQUIFER], sizeof(TAquifer)); | |
| 1031 | 58 | UnitHyd = (TUnitHyd *) calloc(Nobjects[UNITHYD], sizeof(TUnitHyd)); | |
| 1032 | 58 | Snowmelt = (TSnowmelt *) calloc(Nobjects[SNOWMELT], sizeof(TSnowmelt)); | |
| 1033 | 58 | Shape = (TShape *) calloc(Nobjects[SHAPE], sizeof(TShape)); | |
| 1034 | |||
| 1035 | // --- create array of detailed routing event periods | ||
| 1036 | 58 | Event = (TEvent *) calloc((size_t)NumEvents+1, sizeof(TEvent)); | |
| 1037 | 58 | Event[NumEvents].start = BIG; | |
| 1038 | 58 | Event[NumEvents].end = BIG + 1.0; | |
| 1039 | |||
| 1040 | // --- create LID objects | ||
| 1041 | 58 | lid_create(Nobjects[LID], Nobjects[SUBCATCH]); | |
| 1042 | |||
| 1043 | // --- create control rules | ||
| 1044 | 58 | ErrorCode = controls_create(Nobjects[CONTROL]); | |
| 1045 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( ErrorCode ) return; |
| 1046 | |||
| 1047 | // --- create cross section transects | ||
| 1048 | 58 | ErrorCode = transect_create(Nobjects[TRANSECT]); | |
| 1049 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( ErrorCode ) return; |
| 1050 | |||
| 1051 | // --- create street cross sections & inlet designs | ||
| 1052 | 58 | ErrorCode = street_create(Nobjects[STREET]); | |
| 1053 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( ErrorCode ) return; |
| 1054 | 58 | ErrorCode = inlet_create(Nobjects[INLET]); | |
| 1055 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if ( ErrorCode ) return; |
| 1056 | |||
| 1057 | // --- allocate memory for infiltration data | ||
| 1058 | 58 | infil_create(Nobjects[SUBCATCH]); | |
| 1059 | |||
| 1060 | // --- allocate memory for water quality state variables | ||
| 1061 |
2/2✓ Branch 0 taken 2393 times.
✓ Branch 1 taken 58 times.
|
2451 | for (j = 0; j < Nobjects[SUBCATCH]; j++) |
| 1062 | { | ||
| 1063 | 2393 | Subcatch[j].initBuildup = | |
| 1064 | 2393 | (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1065 | 2393 | Subcatch[j].oldQual = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1066 | 2393 | Subcatch[j].newQual = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1067 | 2393 | Subcatch[j].pondedQual = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1068 | 2393 | Subcatch[j].totalLoad = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1069 | } | ||
| 1070 |
2/2✓ Branch 0 taken 10183 times.
✓ Branch 1 taken 58 times.
|
10241 | for (j = 0; j < Nobjects[NODE]; j++) |
| 1071 | { | ||
| 1072 | 10183 | Node[j].oldQual = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1073 | 10183 | Node[j].newQual = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1074 | 10183 | Node[j].extInflow = NULL; | |
| 1075 | 10183 | Node[j].dwfInflow = NULL; | |
| 1076 | 10183 | Node[j].rdiiInflow = NULL; | |
| 1077 | 10183 | Node[j].treatment = NULL; | |
| 1078 | } | ||
| 1079 |
2/2✓ Branch 0 taken 10508 times.
✓ Branch 1 taken 58 times.
|
10566 | for (j = 0; j < Nobjects[LINK]; j++) |
| 1080 | { | ||
| 1081 | 10508 | Link[j].inlet = NULL; | |
| 1082 | 10508 | Link[j].oldQual = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1083 | 10508 | Link[j].newQual = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1084 | 10508 | Link[j].totalLoad = (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1085 | } | ||
| 1086 | |||
| 1087 | // --- allocate memory for land use buildup/washoff functions | ||
| 1088 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 58 times.
|
68 | for (j = 0; j < Nobjects[LANDUSE]; j++) |
| 1089 | { | ||
| 1090 | 10 | Landuse[j].buildupFunc = | |
| 1091 | 10 | (TBuildup *) calloc(Nobjects[POLLUT], sizeof(TBuildup)); | |
| 1092 | 10 | Landuse[j].washoffFunc = | |
| 1093 | 10 | (TWashoff *) calloc(Nobjects[POLLUT], sizeof(TWashoff)); | |
| 1094 | } | ||
| 1095 | |||
| 1096 | // --- allocate memory for subcatchment landuse factors | ||
| 1097 |
2/2✓ Branch 0 taken 2393 times.
✓ Branch 1 taken 58 times.
|
2451 | for (j = 0; j < Nobjects[SUBCATCH]; j++) |
| 1098 | { | ||
| 1099 | 2393 | Subcatch[j].landFactor = | |
| 1100 | 2393 | (TLandFactor *) calloc(Nobjects[LANDUSE], sizeof(TLandFactor)); | |
| 1101 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 2393 times.
|
2444 | for (k = 0; k < Nobjects[LANDUSE]; k++) |
| 1102 | { | ||
| 1103 | 51 | Subcatch[j].landFactor[k].buildup = | |
| 1104 | 51 | (double *) calloc(Nobjects[POLLUT], sizeof(double)); | |
| 1105 | } | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | // --- initialize buildup & washoff functions | ||
| 1109 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 58 times.
|
68 | for (j = 0; j < Nobjects[LANDUSE]; j++) |
| 1110 | { | ||
| 1111 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 10 times.
|
35 | for (k = 0; k < Nobjects[POLLUT]; k++) |
| 1112 | { | ||
| 1113 | 25 | Landuse[j].buildupFunc[k].funcType = NO_BUILDUP; | |
| 1114 | 25 | Landuse[j].buildupFunc[k].normalizer = PER_AREA; | |
| 1115 | 25 | Landuse[j].washoffFunc[k].funcType = NO_WASHOFF; | |
| 1116 | } | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | // --- initialize rain gage properties | ||
| 1120 |
2/2✓ Branch 0 taken 52 times.
✓ Branch 1 taken 58 times.
|
110 | for (j = 0; j < Nobjects[GAGE]; j++) |
| 1121 | { | ||
| 1122 | 52 | Gage[j].tSeries = -1; | |
| 1123 | 52 | sstrncpy(Gage[j].fname, "", 0); | |
| 1124 | } | ||
| 1125 | |||
| 1126 | // --- initialize subcatchment properties | ||
| 1127 |
2/2✓ Branch 0 taken 2393 times.
✓ Branch 1 taken 58 times.
|
2451 | for (j = 0; j < Nobjects[SUBCATCH]; j++) |
| 1128 | { | ||
| 1129 | 2393 | Subcatch[j].outSubcatch = -1; | |
| 1130 | 2393 | Subcatch[j].outNode = -1; | |
| 1131 | 2393 | Subcatch[j].infil = -1; | |
| 1132 | 2393 | Subcatch[j].groundwater = NULL; | |
| 1133 | 2393 | Subcatch[j].gwLatFlowExpr = NULL; | |
| 1134 | 2393 | Subcatch[j].gwDeepFlowExpr = NULL; | |
| 1135 | 2393 | Subcatch[j].snowpack = NULL; | |
| 1136 | 2393 | Subcatch[j].lidArea = 0.0; | |
| 1137 |
2/2✓ Branch 0 taken 9294 times.
✓ Branch 1 taken 2393 times.
|
11687 | for (k = 0; k < Nobjects[POLLUT]; k++) |
| 1138 | { | ||
| 1139 | 9294 | Subcatch[j].initBuildup[k] = 0.0; | |
| 1140 | } | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | // --- initialize RDII unit hydrograph properties | ||
| 1144 |
2/2✓ Branch 1 taken 220 times.
✓ Branch 2 taken 58 times.
|
278 | for ( j = 0; j < Nobjects[UNITHYD]; j++ ) rdii_initUnitHyd(j); |
| 1145 | |||
| 1146 | // --- initialize snowmelt properties | ||
| 1147 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 58 times.
|
66 | for ( j = 0; j < Nobjects[SNOWMELT]; j++ ) snow_initSnowmelt(j); |
| 1148 | |||
| 1149 | // --- initialize storage node exfiltration | ||
| 1150 |
2/2✓ Branch 0 taken 117 times.
✓ Branch 1 taken 58 times.
|
175 | for (j = 0; j < Nnodes[STORAGE]; j++) Storage[j].exfil = NULL; |
| 1151 | |||
| 1152 | // --- initialize link properties | ||
| 1153 |
2/2✓ Branch 0 taken 10508 times.
✓ Branch 1 taken 58 times.
|
10566 | for (j = 0; j < Nobjects[LINK]; j++) |
| 1154 | { | ||
| 1155 | 10508 | Link[j].xsect.type = -1; | |
| 1156 | 10508 | Link[j].cLossInlet = 0.0; | |
| 1157 | 10508 | Link[j].cLossOutlet = 0.0; | |
| 1158 | 10508 | Link[j].cLossAvg = 0.0; | |
| 1159 | 10508 | Link[j].hasFlapGate = FALSE; | |
| 1160 | } | ||
| 1161 |
2/2✓ Branch 0 taken 106 times.
✓ Branch 1 taken 58 times.
|
164 | for (j = 0; j < Nlinks[PUMP]; j++) Pump[j].pumpCurve = -1; |
| 1162 | |||
| 1163 | // --- initialize reporting flags | ||
| 1164 |
2/2✓ Branch 0 taken 2393 times.
✓ Branch 1 taken 58 times.
|
2451 | for (j = 0; j < Nobjects[SUBCATCH]; j++) Subcatch[j].rptFlag = FALSE; |
| 1165 |
2/2✓ Branch 0 taken 10183 times.
✓ Branch 1 taken 58 times.
|
10241 | for (j = 0; j < Nobjects[NODE]; j++) Node[j].rptFlag = FALSE; |
| 1166 |
2/2✓ Branch 0 taken 10508 times.
✓ Branch 1 taken 58 times.
|
10566 | for (j = 0; j < Nobjects[LINK]; j++) Link[j].rptFlag = FALSE; |
| 1167 | |||
| 1168 | // --- initialize curves, time series, and time patterns | ||
| 1169 |
2/2✓ Branch 1 taken 221 times.
✓ Branch 2 taken 58 times.
|
279 | for (j = 0; j < Nobjects[CURVE]; j++) table_init(&Curve[j]); |
| 1170 |
2/2✓ Branch 1 taken 102 times.
✓ Branch 2 taken 58 times.
|
160 | for (j = 0; j < Nobjects[TSERIES]; j++) table_init(&Tseries[j]); |
| 1171 |
2/2✓ Branch 1 taken 452 times.
✓ Branch 2 taken 58 times.
|
510 | for (j = 0; j < Nobjects[TIMEPATTERN]; j++) inflow_initDwfPattern(j); |
| 1172 | } | ||
| 1173 | |||
| 1174 | //============================================================================= | ||
| 1175 | |||
| 1176 | 58 | void deleteObjects() | |
| 1177 | // | ||
| 1178 | // Input: none | ||
| 1179 | // Output: none | ||
| 1180 | // Purpose: frees memory allocated for a project's objects. | ||
| 1181 | // | ||
| 1182 | // NOTE: care is taken to first free objects that are properties of another | ||
| 1183 | // object before the latter is freed (e.g., we must free a | ||
| 1184 | // subcatchment's land use factors before freeing the subcatchment). | ||
| 1185 | // | ||
| 1186 | { | ||
| 1187 | int j, k; | ||
| 1188 | |||
| 1189 | // --- free memory for landuse factors & groundwater | ||
| 1190 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2393 times.
✓ Branch 3 taken 58 times.
|
2451 | if ( Subcatch ) for (j = 0; j < Nobjects[SUBCATCH]; j++) |
| 1191 | { | ||
| 1192 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 2393 times.
|
2444 | for (k = 0; k < Nobjects[LANDUSE]; k++) |
| 1193 | { | ||
| 1194 |
1/2✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
|
51 | FREE(Subcatch[j].landFactor[k].buildup); |
| 1195 | } | ||
| 1196 |
1/2✓ Branch 0 taken 2393 times.
✗ Branch 1 not taken.
|
2393 | FREE(Subcatch[j].landFactor); |
| 1197 |
2/2✓ Branch 0 taken 2241 times.
✓ Branch 1 taken 152 times.
|
2393 | FREE(Subcatch[j].groundwater); |
| 1198 | 2393 | gwater_deleteFlowExpression(j); | |
| 1199 |
2/2✓ Branch 0 taken 2304 times.
✓ Branch 1 taken 89 times.
|
2393 | FREE(Subcatch[j].snowpack); |
| 1200 | } | ||
| 1201 | |||
| 1202 | // --- free memory for buildup/washoff functions | ||
| 1203 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 58 times.
|
68 | if ( Landuse ) for (j = 0; j < Nobjects[LANDUSE]; j++) |
| 1204 | { | ||
| 1205 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | FREE(Landuse[j].buildupFunc); |
| 1206 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | FREE(Landuse[j].washoffFunc) |
| 1207 | } | ||
| 1208 | |||
| 1209 | // --- free memory for water quality state variables | ||
| 1210 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2393 times.
✓ Branch 3 taken 58 times.
|
2451 | if ( Subcatch ) for (j = 0; j < Nobjects[SUBCATCH]; j++) |
| 1211 | { | ||
| 1212 |
1/2✓ Branch 0 taken 2393 times.
✗ Branch 1 not taken.
|
2393 | FREE(Subcatch[j].initBuildup); |
| 1213 |
1/2✓ Branch 0 taken 2393 times.
✗ Branch 1 not taken.
|
2393 | FREE(Subcatch[j].oldQual); |
| 1214 |
1/2✓ Branch 0 taken 2393 times.
✗ Branch 1 not taken.
|
2393 | FREE(Subcatch[j].newQual); |
| 1215 |
1/2✓ Branch 0 taken 2393 times.
✗ Branch 1 not taken.
|
2393 | FREE(Subcatch[j].pondedQual); |
| 1216 |
1/2✓ Branch 0 taken 2393 times.
✗ Branch 1 not taken.
|
2393 | FREE(Subcatch[j].totalLoad); |
| 1217 | } | ||
| 1218 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10183 times.
✓ Branch 3 taken 58 times.
|
10241 | if ( Node ) for (j = 0; j < Nobjects[NODE]; j++) |
| 1219 | { | ||
| 1220 |
1/2✓ Branch 0 taken 10183 times.
✗ Branch 1 not taken.
|
10183 | FREE(Node[j].oldQual); |
| 1221 |
1/2✓ Branch 0 taken 10183 times.
✗ Branch 1 not taken.
|
10183 | FREE(Node[j].newQual); |
| 1222 | } | ||
| 1223 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10508 times.
✓ Branch 3 taken 58 times.
|
10566 | if ( Link ) for (j = 0; j < Nobjects[LINK]; j++) |
| 1224 | { | ||
| 1225 |
1/2✓ Branch 0 taken 10508 times.
✗ Branch 1 not taken.
|
10508 | FREE(Link[j].oldQual); |
| 1226 |
1/2✓ Branch 0 taken 10508 times.
✗ Branch 1 not taken.
|
10508 | FREE(Link[j].newQual); |
| 1227 |
1/2✓ Branch 0 taken 10508 times.
✗ Branch 1 not taken.
|
10508 | FREE(Link[j].totalLoad); |
| 1228 | // Any inlet assigned to Link[j].inlet is freed in inlet_delete(). | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | // --- free memory used for rainfall infiltration | ||
| 1232 | 58 | infil_delete(); | |
| 1233 | |||
| 1234 | // --- free memory used for storage exfiltration | ||
| 1235 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 58 times.
|
175 | if ( Node ) for (j = 0; j < Nnodes[STORAGE]; j++) |
| 1236 | { | ||
| 1237 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 114 times.
|
117 | if ( Storage[j].exfil ) |
| 1238 | { | ||
| 1239 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | FREE(Storage[j].exfil->btmExfil); |
| 1240 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | FREE(Storage[j].exfil->bankExfil); |
| 1241 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | FREE(Storage[j].exfil); |
| 1242 | } | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | // --- free memory used for outfall pollutants loads | ||
| 1246 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 348 times.
✓ Branch 3 taken 58 times.
|
406 | if ( Node ) for (j = 0; j < Nnodes[OUTFALL]; j++) |
| 1247 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 347 times.
|
348 | FREE(Outfall[j].wRouted); |
| 1248 | |||
| 1249 | // --- free memory used for nodal inflows & treatment functions | ||
| 1250 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10183 times.
✓ Branch 3 taken 58 times.
|
10241 | if ( Node ) for (j = 0; j < Nobjects[NODE]; j++) |
| 1251 | { | ||
| 1252 | 10183 | inflow_deleteExtInflows(j); | |
| 1253 | 10183 | inflow_deleteDwfInflows(j); | |
| 1254 | 10183 | rdii_deleteRdiiInflow(j); | |
| 1255 | 10183 | treatmnt_delete(j); | |
| 1256 | } | ||
| 1257 | |||
| 1258 | // --- delete table entries for curves and time series | ||
| 1259 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102 times.
✓ Branch 3 taken 58 times.
|
160 | if ( Tseries ) for (j = 0; j < Nobjects[TSERIES]; j++) |
| 1260 | 102 | table_deleteEntries(&Tseries[j]); | |
| 1261 |
3/4✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
✓ Branch 3 taken 58 times.
|
279 | if ( Curve ) for (j = 0; j < Nobjects[CURVE]; j++) |
| 1262 | 221 | table_deleteEntries(&Curve[j]); | |
| 1263 | |||
| 1264 | // --- delete cross section transects | ||
| 1265 | 58 | transect_delete(); | |
| 1266 | |||
| 1267 | // --- delete street and inlet design objects | ||
| 1268 | 58 | street_delete(); | |
| 1269 | 58 | inlet_delete(); | |
| 1270 | |||
| 1271 | // --- delete control rules | ||
| 1272 | 58 | controls_delete(); | |
| 1273 | |||
| 1274 | // --- delete LIDs | ||
| 1275 | 58 | lid_delete(); | |
| 1276 | |||
| 1277 | // --- now free each major category of object | ||
| 1278 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Gage); |
| 1279 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Subcatch); |
| 1280 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Node); |
| 1281 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Outfall); |
| 1282 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Divider); |
| 1283 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Storage); |
| 1284 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Link); |
| 1285 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Conduit); |
| 1286 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Pump); |
| 1287 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Orifice); |
| 1288 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Weir); |
| 1289 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Outlet); |
| 1290 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Pollut); |
| 1291 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Landuse); |
| 1292 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Pattern); |
| 1293 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Curve); |
| 1294 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Tseries); |
| 1295 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Aquifer); |
| 1296 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(UnitHyd); |
| 1297 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Snowmelt); |
| 1298 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Shape); |
| 1299 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | FREE(Event); |
| 1300 | 58 | } | |
| 1301 | |||
| 1302 | //============================================================================= | ||
| 1303 | |||
| 1304 | 58 | void createHashTables() | |
| 1305 | // | ||
| 1306 | // Input: none | ||
| 1307 | // Output: returns error code | ||
| 1308 | // Purpose: allocates memory for object ID hash tables | ||
| 1309 | // | ||
| 1310 | { int j; | ||
| 1311 | 58 | MemPoolAllocated = FALSE; | |
| 1312 |
2/2✓ Branch 0 taken 1044 times.
✓ Branch 1 taken 58 times.
|
1102 | for (j = 0; j < MAX_OBJ_TYPES ; j++) |
| 1313 | { | ||
| 1314 | 1044 | Htable[j] = HTcreate(); | |
| 1315 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1044 times.
|
1044 | if ( Htable[j] == NULL ) report_writeErrorMsg(ERR_MEMORY, ""); |
| 1316 | } | ||
| 1317 | |||
| 1318 | // --- initialize memory pool used to store object ID's | ||
| 1319 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | if ( AllocInit() == NULL ) report_writeErrorMsg(ERR_MEMORY, ""); |
| 1320 | 58 | else MemPoolAllocated = TRUE; | |
| 1321 | 58 | } | |
| 1322 | |||
| 1323 | //============================================================================= | ||
| 1324 | |||
| 1325 | 58 | void deleteHashTables() | |
| 1326 | // | ||
| 1327 | // Input: none | ||
| 1328 | // Output: none | ||
| 1329 | // Purpose: frees memory allocated for object ID hash tables | ||
| 1330 | // | ||
| 1331 | { | ||
| 1332 | int j; | ||
| 1333 |
2/2✓ Branch 0 taken 1044 times.
✓ Branch 1 taken 58 times.
|
1102 | for (j = 0; j < MAX_OBJ_TYPES; j++) |
| 1334 | { | ||
| 1335 |
1/2✓ Branch 0 taken 1044 times.
✗ Branch 1 not taken.
|
1044 | if ( Htable[j] != NULL ) HTfree(Htable[j]); |
| 1336 | } | ||
| 1337 | |||
| 1338 | // --- free object ID memory pool | ||
| 1339 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | if ( MemPoolAllocated ) AllocFreePool(); |
| 1340 | 58 | } | |
| 1341 | |||
| 1342 | //============================================================================= | ||
| 1343 |