epanet-plus 0.0.1__cp39-cp39-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of epanet-plus might be problematic. Click here for more details.

Files changed (105) hide show
  1. docs/conf.py +67 -0
  2. epanet-msx-src/dispersion.h +27 -0
  3. epanet-msx-src/hash.c +107 -0
  4. epanet-msx-src/hash.h +28 -0
  5. epanet-msx-src/include/epanetmsx.h +104 -0
  6. epanet-msx-src/include/epanetmsx_export.h +42 -0
  7. epanet-msx-src/mathexpr.c +937 -0
  8. epanet-msx-src/mathexpr.h +39 -0
  9. epanet-msx-src/mempool.c +204 -0
  10. epanet-msx-src/mempool.h +24 -0
  11. epanet-msx-src/msxchem.c +1285 -0
  12. epanet-msx-src/msxcompiler.c +368 -0
  13. epanet-msx-src/msxdict.h +42 -0
  14. epanet-msx-src/msxdispersion.c +586 -0
  15. epanet-msx-src/msxerr.c +116 -0
  16. epanet-msx-src/msxfile.c +260 -0
  17. epanet-msx-src/msxfuncs.c +175 -0
  18. epanet-msx-src/msxfuncs.h +35 -0
  19. epanet-msx-src/msxinp.c +1504 -0
  20. epanet-msx-src/msxout.c +398 -0
  21. epanet-msx-src/msxproj.c +791 -0
  22. epanet-msx-src/msxqual.c +2011 -0
  23. epanet-msx-src/msxrpt.c +400 -0
  24. epanet-msx-src/msxtank.c +422 -0
  25. epanet-msx-src/msxtoolkit.c +1164 -0
  26. epanet-msx-src/msxtypes.h +551 -0
  27. epanet-msx-src/msxutils.c +524 -0
  28. epanet-msx-src/msxutils.h +56 -0
  29. epanet-msx-src/newton.c +158 -0
  30. epanet-msx-src/newton.h +34 -0
  31. epanet-msx-src/rk5.c +287 -0
  32. epanet-msx-src/rk5.h +39 -0
  33. epanet-msx-src/ros2.c +293 -0
  34. epanet-msx-src/ros2.h +35 -0
  35. epanet-msx-src/smatrix.c +816 -0
  36. epanet-msx-src/smatrix.h +29 -0
  37. epanet-src/AUTHORS +60 -0
  38. epanet-src/LICENSE +21 -0
  39. epanet-src/enumstxt.h +151 -0
  40. epanet-src/epanet.c +5937 -0
  41. epanet-src/epanet2.c +961 -0
  42. epanet-src/epanet2.def +131 -0
  43. epanet-src/errors.dat +79 -0
  44. epanet-src/flowbalance.c +186 -0
  45. epanet-src/funcs.h +219 -0
  46. epanet-src/genmmd.c +1000 -0
  47. epanet-src/hash.c +177 -0
  48. epanet-src/hash.h +28 -0
  49. epanet-src/hydcoeffs.c +1303 -0
  50. epanet-src/hydraul.c +1164 -0
  51. epanet-src/hydsolver.c +781 -0
  52. epanet-src/hydstatus.c +442 -0
  53. epanet-src/include/epanet2.h +466 -0
  54. epanet-src/include/epanet2_2.h +1962 -0
  55. epanet-src/include/epanet2_enums.h +518 -0
  56. epanet-src/inpfile.c +884 -0
  57. epanet-src/input1.c +672 -0
  58. epanet-src/input2.c +970 -0
  59. epanet-src/input3.c +2265 -0
  60. epanet-src/leakage.c +527 -0
  61. epanet-src/mempool.c +146 -0
  62. epanet-src/mempool.h +24 -0
  63. epanet-src/output.c +853 -0
  64. epanet-src/project.c +1691 -0
  65. epanet-src/quality.c +695 -0
  66. epanet-src/qualreact.c +800 -0
  67. epanet-src/qualroute.c +696 -0
  68. epanet-src/report.c +1559 -0
  69. epanet-src/rules.c +1500 -0
  70. epanet-src/smatrix.c +871 -0
  71. epanet-src/text.h +508 -0
  72. epanet-src/types.h +928 -0
  73. epanet-src/util/cstr_helper.c +59 -0
  74. epanet-src/util/cstr_helper.h +38 -0
  75. epanet-src/util/errormanager.c +92 -0
  76. epanet-src/util/errormanager.h +39 -0
  77. epanet-src/util/filemanager.c +212 -0
  78. epanet-src/util/filemanager.h +81 -0
  79. epanet-src/validate.c +408 -0
  80. epanet.cp39-win_amd64.pyd +0 -0
  81. epanet_plus/VERSION +1 -0
  82. epanet_plus/__init__.py +8 -0
  83. epanet_plus/epanet_plus.c +118 -0
  84. epanet_plus/epanet_toolkit.py +2730 -0
  85. epanet_plus/epanet_wrapper.py +2414 -0
  86. epanet_plus/include/epanet_plus.h +9 -0
  87. epanet_plus-0.0.1.dist-info/METADATA +152 -0
  88. epanet_plus-0.0.1.dist-info/RECORD +105 -0
  89. epanet_plus-0.0.1.dist-info/WHEEL +5 -0
  90. epanet_plus-0.0.1.dist-info/licenses/LICENSE +21 -0
  91. epanet_plus-0.0.1.dist-info/top_level.txt +11 -0
  92. examples/basic_usage.py +35 -0
  93. python-extension/ext.c +344 -0
  94. python-extension/pyepanet.c +2133 -0
  95. python-extension/pyepanet.h +143 -0
  96. python-extension/pyepanet2.c +1823 -0
  97. python-extension/pyepanet2.h +141 -0
  98. python-extension/pyepanet_plus.c +37 -0
  99. python-extension/pyepanet_plus.h +4 -0
  100. python-extension/pyepanetmsx.c +388 -0
  101. python-extension/pyepanetmsx.h +35 -0
  102. tests/test_epanet.py +16 -0
  103. tests/test_epanetmsx.py +36 -0
  104. tests/test_epyt.py +114 -0
  105. tests/test_load_inp_from_buffer.py +18 -0
@@ -0,0 +1,791 @@
1
+ /******************************************************************************
2
+ ** MODULE: MSXPROJ.C
3
+ ** PROJECT: EPANET-MSX
4
+ ** DESCRIPTION: project data manager used by the EPANET Multi-Species
5
+ ** Extension toolkit.
6
+ ** AUTHORS: see AUTHORS
7
+ ** Copyright: see AUTHORS
8
+ ** License: see LICENSE
9
+ ** VERSION: 2.0.00
10
+ ** LAST UPDATE: 08/30/2022
11
+ ******************************************************************************/
12
+
13
+ #include <stdio.h>
14
+ #include <string.h>
15
+ #include <math.h>
16
+ #include <stdlib.h>
17
+
18
+ #include "msxtypes.h"
19
+ #include "msxutils.h"
20
+ //#include "mempool.h"
21
+ #include "hash.h"
22
+ #include "smatrix.h"
23
+ #include "epanet2.h"
24
+ #include "dispersion.h"
25
+ // Exported variables
26
+ //--------------------
27
+ MSXproject MSX; // MSX project data
28
+
29
+ // Local variables
30
+ //-----------------
31
+ static alloc_handle_t *HashPool; // Memory pool for hash tables
32
+ static HTtable *Htable[MAX_OBJECTS]; // Hash tables for object ID names
33
+
34
+ static char * Errmsg[] =
35
+ {"unknown error code.",
36
+ "Error 501 - insufficient memory available.",
37
+ "Error 502 - no EPANET data file supplied.",
38
+ "Error 503 - could not open MSX input file.",
39
+ "Error 504 - could not open hydraulic results file.",
40
+ "Error 505 - could not read hydraulic results file.",
41
+ "Error 506 - could not read MSX input file.",
42
+ "Error 507 - too few pipe reaction expressions.",
43
+ "Error 508 - too few tank reaction expressions.",
44
+ "Error 509 - could not open differential equation solver.",
45
+ "Error 510 - could not open algebraic equation solver.",
46
+ "Error 511 - could not open binary results file.",
47
+ "Error 512 - read/write error on binary results file.",
48
+ "Error 513 - could not integrate reaction rate expressions.",
49
+ "Error 514 - could not solve reaction equilibrium expressions.",
50
+ "Error 515 - reference made to an unknown type of object.",
51
+ "Error 516 - reference made to an illegal object index.",
52
+ "Error 517 - reference made to an undefined object ID.",
53
+ "Error 518 - invalid property values were specified.",
54
+ "Error 519 - an MSX project was not opened.",
55
+ "Error 520 - an MSX project is already opened.",
56
+ "Error 521 - could not open MSX report file.", //(LR-11/20/07)
57
+
58
+ "Error 522 - could not compile chemistry functions.",
59
+ "Error 523 - could not load functions from compiled chemistry file.",
60
+ "Error 524 - illegal math operation."};
61
+
62
+ // Imported functions
63
+ //--------------------
64
+ int MSXinp_countMsxObjects(void);
65
+ int MSXinp_countNetObjects(void);
66
+ int MSXinp_readNetData(void);
67
+ int MSXinp_readMsxData(void);
68
+
69
+ // Exported functions
70
+ //--------------------
71
+ int MSXproj_open(char *fname);
72
+ int MSXproj_addObject(int type, char *id, int n);
73
+ int MSXproj_findObject(int type, char *id);
74
+ char * MSXproj_findID(int type, char *id);
75
+ char * MSXproj_getErrmsg(int errcode);
76
+
77
+ // Local functions
78
+ //-----------------
79
+ static void setDefaults(void);
80
+ static int convertUnits(void);
81
+ static int createObjects(void);
82
+ static void deleteObjects(void);
83
+ static int createHashTables(void);
84
+ static void deleteHashTables(void);
85
+
86
+ static int openRptFile(void); //(LR-11/20/07)
87
+
88
+ static int buildadjlists();
89
+ static void freeadjlists();
90
+
91
+
92
+ //=============================================================================
93
+
94
+ int MSXproj_open(char *fname)
95
+ /*
96
+ ** Purpose:
97
+ ** opens an EPANET-MSX project.
98
+ **
99
+ ** Input:
100
+ ** fname = name of EPANET-MSX input file
101
+ **
102
+ ** Returns:
103
+ ** an error code (0 if no error)
104
+ */
105
+ {
106
+ // --- initialize data to default values
107
+
108
+ int errcode = 0;
109
+ MSX.ProjectOpened = FALSE;
110
+ MSX.QualityOpened = FALSE;
111
+ setDefaults();
112
+
113
+ // --- open the MSX input file
114
+
115
+ strcpy(MSX.MsxFile.name, fname);
116
+ if ((MSX.MsxFile.file = fopen(fname,"rt")) == NULL) return ERR_OPEN_MSX_FILE;
117
+
118
+ // --- create hash tables to look up object ID names
119
+
120
+ CALL(errcode, createHashTables());
121
+
122
+ // --- allocate memory for the required number of objects
123
+
124
+ CALL(errcode, MSXinp_countMsxObjects());
125
+ CALL(errcode, MSXinp_countNetObjects());
126
+ CALL(errcode, createObjects());
127
+
128
+ MSX.DispersionFlag = 0; //no dispersion by default, unless yes in msx file
129
+
130
+ // --- read in the EPANET and MSX object data
131
+
132
+ CALL(errcode, MSXinp_readNetData());
133
+ CALL(errcode, MSXinp_readMsxData());
134
+
135
+ if (strcmp(MSX.RptFile.name, ""))
136
+ CALL(errcode, openRptFile());
137
+
138
+ // --- convert user's units to internal units
139
+
140
+ CALL(errcode, convertUnits());
141
+
142
+ if (MSX.DispersionFlag != 0)
143
+ {
144
+ float relvis;
145
+ ENgetoption(13, &relvis);
146
+ MSX.Dispersion.viscosity = relvis * 1.1E-5;
147
+
148
+ msx_createsparse(); //symmetric matrix
149
+ }
150
+
151
+ // Build nodal adjacency lists
152
+ if (errcode == 0 && MSX.Adjlist == NULL)
153
+ {
154
+ errcode = buildadjlists(); //parallel links are included
155
+ if (errcode) return errcode;
156
+ }
157
+
158
+ // --- close input file
159
+
160
+ if ( MSX.MsxFile.file ) fclose(MSX.MsxFile.file);
161
+ MSX.MsxFile.file = NULL;
162
+ if ( !errcode ) MSX.ProjectOpened = TRUE;
163
+ return errcode;
164
+ }
165
+
166
+ //=============================================================================
167
+
168
+ void MSXproj_close()
169
+ /*
170
+ ** Purpose:
171
+ ** closes the current EPANET-MSX project.
172
+ **
173
+ ** Input:
174
+ ** none
175
+ */
176
+ {
177
+ // --- close all files
178
+
179
+ if ( MSX.RptFile.file ) fclose(MSX.RptFile.file); //(LR-11/20/07, to fix bug 08)
180
+ if ( MSX.HydFile.file ) fclose(MSX.HydFile.file);
181
+ if ( MSX.TmpOutFile.file && MSX.TmpOutFile.file != MSX.OutFile.file )
182
+ fclose(MSX.TmpOutFile.file);
183
+ if ( MSX.OutFile.file ) fclose(MSX.OutFile.file);
184
+
185
+ // --- delete all temporary files
186
+
187
+ if ( MSX.HydFile.mode == SCRATCH_FILE ) remove(MSX.HydFile.name);
188
+ if ( MSX.OutFile.mode == SCRATCH_FILE ) remove(MSX.OutFile.name);
189
+ remove(MSX.TmpOutFile.name);
190
+
191
+ // --- free all allocated memory
192
+
193
+ MSX.RptFile.file = NULL; //(LR-11/20/07, to fix bug 08)
194
+ MSX.HydFile.file = NULL;
195
+ MSX.OutFile.file = NULL;
196
+ MSX.TmpOutFile.file = NULL;
197
+ deleteObjects();
198
+ deleteHashTables();
199
+ MSX.ProjectOpened = FALSE;
200
+ }
201
+
202
+ //=============================================================================
203
+
204
+ int MSXproj_addObject(int type, char *id, int n)
205
+ /*
206
+ ** Purpose:
207
+ ** adds an object ID to the project's hash tables.
208
+ **
209
+ ** Input:
210
+ ** type = object type
211
+ ** id = object ID string
212
+ ** n = object index.
213
+ **
214
+ ** Returns:
215
+ ** 0 if object already added, 1 if not, -1 if hashing fails.
216
+ */
217
+ {
218
+ int result;
219
+ int len;
220
+ char *newID;
221
+
222
+ // --- do nothing if object already exists in a hash table
223
+
224
+ if ( MSXproj_findObject(type, id) > 0 ) return 0;
225
+
226
+ // --- use memory from the hash tables' common memory pool to store
227
+ // a copy of the object's ID string
228
+
229
+ len = (int)strlen(id) + 1;
230
+ newID = (char *) Alloc(len*sizeof(char));
231
+ strcpy(newID, id);
232
+
233
+ // --- insert object's ID into the hash table for that type of object
234
+
235
+ result = HTinsert(Htable[type], newID, n);
236
+ if ( result == 0 ) result = -1;
237
+ return result;
238
+ }
239
+
240
+ //=============================================================================
241
+
242
+ int MSXproj_findObject(int type, char *id)
243
+ /*
244
+ ** Purpose:
245
+ ** uses hash table to find index of an object with a given ID.
246
+ **
247
+ ** Input:
248
+ ** type = object type
249
+ ** id = object ID.
250
+ **
251
+ ** Returns:
252
+ ** index of object with given ID, or -1 if ID not found.
253
+ */
254
+ {
255
+ return HTfind(Htable[type], id);
256
+ }
257
+
258
+ //=============================================================================
259
+
260
+ char * MSXproj_findID(int type, char *id)
261
+ /*
262
+ ** Purpose:
263
+ ** uses hash table to find address of given string entry.
264
+ **
265
+ ** Input:
266
+ ** type = object type
267
+ ** id = ID name being sought.
268
+ **
269
+ ** Returns:
270
+ ** pointer to location where object's ID string is stored.
271
+ */
272
+ {
273
+ return HTfindKey(Htable[type], id);
274
+ }
275
+
276
+ //=============================================================================
277
+
278
+ char * MSXproj_getErrmsg(int errcode)
279
+ /*
280
+ ** Purpose:
281
+ ** gets the text of an error message.
282
+ **
283
+ ** Input:
284
+ ** errcode = error code.
285
+ **
286
+ ** Returns:
287
+ ** text of error message.
288
+ */
289
+ {
290
+ if ( errcode <= ERR_FIRST || errcode >= ERR_MAX ) return Errmsg[0];
291
+ else return Errmsg[errcode - ERR_FIRST];
292
+ }
293
+
294
+ //=============================================================================
295
+
296
+ void setDefaults()
297
+ /*
298
+ ** Purpose:
299
+ ** assigns default values to project variables.
300
+ **
301
+ ** Input:
302
+ ** none.
303
+ */
304
+ {
305
+ int i;
306
+ MSX.RptFile.file = NULL; //(LR-11/20/07)
307
+ MSX.HydFile.file = NULL;
308
+ MSX.HydFile.mode = USED_FILE;
309
+ MSX.OutFile.file = NULL;
310
+ MSX.OutFile.mode = SCRATCH_FILE;
311
+ MSX.TmpOutFile.file = NULL;
312
+ MSXutils_getTempName(MSX.OutFile.name);
313
+ MSXutils_getTempName(MSX.TmpOutFile.name);
314
+ strcpy(MSX.RptFile.name, "");
315
+ strcpy(MSX.Title, "");
316
+ MSX.Rptflag = 0;
317
+ for (i=0; i<MAX_OBJECTS; i++) MSX.Nobjects[i] = 0;
318
+ MSX.Unitsflag = US;
319
+ MSX.Flowflag = GPM;
320
+ MSX.Statflag = SERIES;
321
+ MSX.DefRtol = 0.001;
322
+ MSX.DefAtol = 0.01;
323
+ MSX.Solver = EUL;
324
+ MSX.Coupling = NO_COUPLING;
325
+ MSX.Compiler = NO_COMPILER;
326
+ MSX.ErrCode = 0;
327
+ MSX.AreaUnits = FT2;
328
+ MSX.RateUnits = DAYS;
329
+ MSX.Qstep = 300*1000; // 300,000 millisec = 5 minutes
330
+ MSX.Rstep = 3600;
331
+ MSX.Rstart = 0;
332
+ MSX.Dur = 0;
333
+ MSX.Node = NULL;
334
+ MSX.Link = NULL;
335
+ MSX.Tank = NULL;
336
+ MSX.D = NULL;
337
+ MSX.Q = NULL;
338
+ MSX.H = NULL;
339
+ MSX.S = NULL;
340
+ MSX.Species = NULL;
341
+ MSX.Term = NULL;
342
+ MSX.Const = NULL;
343
+ MSX.Pattern = NULL;
344
+ MSX.K = NULL;
345
+ }
346
+
347
+ //=============================================================================
348
+
349
+ int convertUnits()
350
+ /*
351
+ ** Purpose:
352
+ ** converts user's units to internal EPANET units.
353
+ **
354
+ ** Input:
355
+ ** none.
356
+ **
357
+ ** Returns:
358
+ ** an error code (0 if no error).
359
+ */
360
+ {
361
+ // --- flow conversion factors (to cfs)
362
+ double fcf[] = {1.0, GPMperCFS, MGDperCFS, IMGDperCFS, AFDperCFS,
363
+ LPSperCFS, LPMperCFS, MLDperCFS, CMHperCFS, CMDperCFS};
364
+
365
+ // --- rate time units conversion factors (to sec)
366
+ double rcf[] = {1.0, 60.0, 3600.0, 86400.0};
367
+
368
+ int i, m, errcode = 0;
369
+
370
+ // --- conversions for length & tank volume
371
+
372
+ if ( MSX.Unitsflag == US )
373
+ {
374
+ MSX.Ucf[LENGTH_UNITS] = 1.0;
375
+ MSX.Ucf[DIAM_UNITS] = 12.0;
376
+ MSX.Ucf[VOL_UNITS] = 1.0;
377
+ }
378
+ else
379
+ {
380
+ MSX.Ucf[LENGTH_UNITS] = MperFT;
381
+ MSX.Ucf[DIAM_UNITS] = 1000.0*MperFT;
382
+ MSX.Ucf[VOL_UNITS] = M3perFT3;
383
+ }
384
+
385
+ // --- conversion for surface area
386
+
387
+ MSX.Ucf[AREA_UNITS] = 1.0;
388
+ switch (MSX.AreaUnits)
389
+ {
390
+ case M2: MSX.Ucf[AREA_UNITS] = M2perFT2; break;
391
+ case CM2: MSX.Ucf[AREA_UNITS] = CM2perFT2; break;
392
+ }
393
+
394
+ // --- conversion for flow rate
395
+
396
+ MSX.Ucf[FLOW_UNITS] = fcf[MSX.Flowflag];
397
+ MSX.Ucf[CONC_UNITS] = LperFT3;
398
+
399
+ // --- conversion for reaction rate time
400
+
401
+ MSX.Ucf[RATE_UNITS] = rcf[MSX.RateUnits];
402
+
403
+ // --- convert pipe diameter & length
404
+
405
+ for (i=1; i<=MSX.Nobjects[LINK]; i++)
406
+ {
407
+ MSX.Link[i].diam /= MSX.Ucf[DIAM_UNITS];
408
+ MSX.Link[i].len /= MSX.Ucf[LENGTH_UNITS];
409
+ }
410
+
411
+ // --- convert initial tank volumes
412
+
413
+ for (i=1; i<=MSX.Nobjects[TANK]; i++)
414
+ {
415
+ MSX.Tank[i].v0 /= MSX.Ucf[VOL_UNITS];
416
+ MSX.Tank[i].vMix /= MSX.Ucf[VOL_UNITS];
417
+ }
418
+
419
+ // --- assign default tolerances to species
420
+
421
+ for (m=1; m<=MSX.Nobjects[SPECIES]; m++)
422
+ {
423
+ if ( MSX.Species[m].rTol == 0.0 ) MSX.Species[m].rTol = MSX.DefRtol;
424
+ if ( MSX.Species[m].aTol == 0.0 ) MSX.Species[m].aTol = MSX.DefAtol;
425
+ }
426
+ return errcode;
427
+ }
428
+
429
+
430
+ //=============================================================================
431
+
432
+ int createObjects()
433
+ /*
434
+ ** Purpose:
435
+ ** creates multi-species data objects.
436
+ **
437
+ ** Input:
438
+ ** none.
439
+ **
440
+ ** Returns:
441
+ ** an error code (0 if no error).
442
+ */
443
+ {
444
+ int i;
445
+
446
+ // --- create nodes, links, & tanks
447
+
448
+ MSX.Node = (Snode *) calloc(MSX.Nobjects[NODE]+1, sizeof(Snode));
449
+ MSX.Link = (Slink *) calloc(MSX.Nobjects[LINK]+1, sizeof(Slink));
450
+ MSX.Tank = (Stank *) calloc(MSX.Nobjects[TANK]+1, sizeof(Stank));
451
+
452
+ // --- create species, terms, parameters, constants & time patterns
453
+
454
+ MSX.Species = (Sspecies *) calloc(MSX.Nobjects[SPECIES]+1, sizeof(Sspecies));
455
+ MSX.Term = (Sterm *) calloc(MSX.Nobjects[TERM]+1, sizeof(Sterm));
456
+ MSX.Param = (Sparam *) calloc(MSX.Nobjects[PARAMETER]+1, sizeof(Sparam));
457
+ MSX.Const = (Sconst *) calloc(MSX.Nobjects[CONSTANT]+1, sizeof(Sconst));
458
+ MSX.Pattern = (Spattern *) calloc(MSX.Nobjects[PATTERN]+1, sizeof(Spattern));
459
+ MSX.K = (double *) calloc(MSX.Nobjects[CONSTANT]+1, sizeof(double));
460
+
461
+ // --- create arrays for demands, heads, & flows
462
+
463
+ MSX.D = (float *) calloc(MSX.Nobjects[NODE]+1, sizeof(float));
464
+ MSX.H = (float *) calloc(MSX.Nobjects[NODE]+1, sizeof(float));
465
+ MSX.Q = (float *) calloc(MSX.Nobjects[LINK]+1, sizeof(float));
466
+ MSX.S = (float *) calloc(MSX.Nobjects[LINK] + 1, sizeof(float));
467
+
468
+ // --- create arrays for current & initial concen. of each species for each node
469
+
470
+ MSX.C0 = (double *) calloc(MSX.Nobjects[SPECIES]+1, sizeof(double));
471
+ for (i=1; i<=MSX.Nobjects[NODE]; i++)
472
+ {
473
+ MSX.Node[i].c = (double *) calloc(MSX.Nobjects[SPECIES]+1, sizeof(double));
474
+ MSX.Node[i].c0 = (double *) calloc(MSX.Nobjects[SPECIES]+1, sizeof(double));
475
+ MSX.Node[i].rpt = 0;
476
+ }
477
+
478
+ // --- create arrays for init. concen. & kinetic parameter values for each link
479
+
480
+ for (i=1; i<=MSX.Nobjects[LINK]; i++)
481
+ {
482
+ MSX.Link[i].c0 = (double *)
483
+ calloc(MSX.Nobjects[SPECIES]+1, sizeof(double));
484
+ MSX.Link[i].reacted = (double *)
485
+ calloc(MSX.Nobjects[SPECIES] + 1, sizeof(double));
486
+ MSX.Link[i].param = (double *)
487
+ calloc(MSX.Nobjects[PARAMETER]+1, sizeof(double));
488
+ MSX.Link[i].rpt = 0;
489
+ }
490
+
491
+ // --- create arrays for kinetic parameter values & current concen. for each tank
492
+
493
+ for (i=1; i<=MSX.Nobjects[TANK]; i++)
494
+ {
495
+ MSX.Tank[i].param = (double *)
496
+ calloc(MSX.Nobjects[PARAMETER]+1, sizeof(double));
497
+ MSX.Tank[i].c = (double *)
498
+ calloc(MSX.Nobjects[SPECIES]+1, sizeof(double));
499
+ MSX.Tank[i].reacted = (double*)
500
+ calloc(MSX.Nobjects[SPECIES] + 1, sizeof(double));
501
+ }
502
+
503
+ // --- initialize contents of each time pattern object
504
+
505
+ for (i=1; i<=MSX.Nobjects[PATTERN]; i++)
506
+ {
507
+ MSX.Pattern[i].length = 0;
508
+ MSX.Pattern[i].first = NULL;
509
+ MSX.Pattern[i].current = NULL;
510
+ }
511
+
512
+ // --- initialize reaction rate & equil. formulas for each species
513
+
514
+ for (i=1; i<=MSX.Nobjects[SPECIES]; i++)
515
+ {
516
+ MSX.Species[i].pipeExpr = NULL;
517
+ MSX.Species[i].tankExpr = NULL;
518
+ MSX.Species[i].pipeExprType = NO_EXPR;
519
+ MSX.Species[i].tankExprType = NO_EXPR;
520
+ MSX.Species[i].precision = 2;
521
+ MSX.Species[i].rpt = 0;
522
+ }
523
+
524
+ // --- initialize math expressions for each intermediate term
525
+
526
+ for (i=1; i<=MSX.Nobjects[TERM]; i++) MSX.Term[i].expr = NULL;
527
+
528
+ MSX.MaxSegments = MAXSEGMENTS;
529
+ MSX.Dispersion.PecletLimit = 1000.00;
530
+ MSX.Dispersion.DIFFUS = 1.29E-8;
531
+ MSX.Dispersion.md = (double*)
532
+ calloc(MSX.Nobjects[SPECIES] + 1, sizeof(double));
533
+ MSX.Dispersion.ld = (double*)
534
+ calloc(MSX.Nobjects[SPECIES] + 1, sizeof(double));
535
+
536
+ for (int m = 1; m <= MSX.Nobjects[SPECIES]; m++)
537
+ {
538
+ MSX.Dispersion.md[m] = -1.0;
539
+ MSX.Dispersion.ld[m] = -1.0;
540
+ }
541
+ return 0;
542
+ }
543
+
544
+ //=============================================================================
545
+
546
+ void deleteObjects()
547
+ /*
548
+ ** Purpose:
549
+ ** deletes multi-species data objects.
550
+ **
551
+ ** Input:
552
+ ** none.
553
+ */
554
+ {
555
+ int i;
556
+ SnumList *listItem;
557
+
558
+ // --- free memory used by nodes, links, and tanks
559
+
560
+ if (MSX.Node) for (i=1; i<=MSX.Nobjects[NODE]; i++)
561
+ {
562
+ FREE(MSX.Node[i].c);
563
+ FREE(MSX.Node[i].c0);
564
+ if(MSX.Node[i].sources)
565
+ {
566
+ struct Ssource *p=MSX.Node[i].sources;
567
+ while(p != NULL)
568
+ {
569
+ MSX.Node[i].sources=p->next;
570
+ FREE(p);
571
+ p=MSX.Node[i].sources;
572
+ }
573
+ }
574
+ }
575
+ if (MSX.Link) for (i=1; i<=MSX.Nobjects[LINK]; i++)
576
+ {
577
+ FREE(MSX.Link[i].c0);
578
+ FREE(MSX.Link[i].param);
579
+ FREE(MSX.Link[i].reacted);
580
+ }
581
+ if (MSX.Tank) for (i=1; i<=MSX.Nobjects[TANK]; i++)
582
+ {
583
+ FREE(MSX.Tank[i].param);
584
+ FREE(MSX.Tank[i].c);
585
+ FREE(MSX.Tank[i].reacted);
586
+ }
587
+
588
+ freeadjlists();
589
+
590
+ // --- free memory used by time patterns
591
+ if (MSX.Pattern) for (i=1; i<=MSX.Nobjects[PATTERN]; i++)
592
+ {
593
+ listItem = MSX.Pattern[i].first;
594
+ while (listItem)
595
+ {
596
+ MSX.Pattern[i].first = listItem->next;
597
+ free(listItem);
598
+ listItem = MSX.Pattern[i].first;
599
+ }
600
+ }
601
+ FREE(MSX.Pattern);
602
+
603
+ // --- free memory used for hydraulics results
604
+
605
+ FREE(MSX.D);
606
+ FREE(MSX.H);
607
+ FREE(MSX.Q);
608
+ FREE(MSX.S);
609
+ FREE(MSX.C0);
610
+
611
+ // --- delete all nodes, links, and tanks
612
+
613
+ FREE(MSX.Node);
614
+ FREE(MSX.Link);
615
+ FREE(MSX.Tank);
616
+
617
+ // --- free memory used by reaction rate & equilibrium expressions
618
+
619
+ if (MSX.Species) for (i=1; i<=MSX.Nobjects[SPECIES]; i++)
620
+ {
621
+ // --- free the species tank expression only if it doesn't
622
+ // already point to the species pipe expression
623
+ if ( MSX.Species[i].tankExpr != MSX.Species[i].pipeExpr )
624
+ {
625
+ mathexpr_delete(MSX.Species[i].tankExpr);
626
+ }
627
+ mathexpr_delete(MSX.Species[i].pipeExpr);
628
+ }
629
+
630
+ // --- delete all species, parameters, and constants
631
+
632
+ FREE(MSX.Species);
633
+ FREE(MSX.Param);
634
+ FREE(MSX.Const);
635
+ FREE(MSX.K);
636
+
637
+ // --- free memory used by intermediate terms
638
+
639
+ if (MSX.Term) for (i=1; i<=MSX.Nobjects[TERM]; i++)
640
+ mathexpr_delete(MSX.Term[i].expr);
641
+ FREE(MSX.Term);
642
+ }
643
+
644
+ //=============================================================================
645
+
646
+ int createHashTables()
647
+ /*
648
+ ** Purpose:
649
+ ** allocates memory for object ID hash tables.
650
+ **
651
+ ** Input:
652
+ ** none.
653
+ **
654
+ ** Returns:
655
+ ** an error code (0 if no error).
656
+ */
657
+ { int j;
658
+
659
+ // --- create a hash table for each type of object
660
+
661
+ for (j = 0; j < MAX_OBJECTS ; j++)
662
+ {
663
+ Htable[j] = HTcreate();
664
+ if ( Htable[j] == NULL ) return ERR_MEMORY;
665
+ }
666
+
667
+ // --- initialize the memory pool used to store object ID's
668
+
669
+ HashPool = AllocInit();
670
+ if ( HashPool == NULL ) return ERR_MEMORY;
671
+ return 0;
672
+ }
673
+
674
+ //=============================================================================
675
+
676
+ void deleteHashTables()
677
+ /*
678
+ ** Purpose:
679
+ ** frees memory allocated for object ID hash tables.
680
+ **
681
+ ** Input:
682
+ ** none.
683
+ */
684
+ {
685
+ int j;
686
+
687
+ // --- free the hash tables
688
+
689
+ for (j = 0; j < MAX_OBJECTS; j++)
690
+ {
691
+ if ( Htable[j] != NULL ) HTfree(Htable[j]);
692
+ }
693
+
694
+ // --- free the object ID memory pool
695
+
696
+ if ( HashPool )
697
+ {
698
+ AllocSetPool(HashPool);
699
+ AllocFreePool();
700
+ }
701
+ }
702
+
703
+ // New function added (LR-11/20/07, to fix bug 08)
704
+ int openRptFile()
705
+ {
706
+ if ( MSX.RptFile.file ) fclose(MSX.RptFile.file);
707
+ MSX.RptFile.file = fopen(MSX.RptFile.name, "wt");
708
+ if ( MSX.RptFile.file == NULL ) return ERR_OPEN_RPT_FILE;
709
+ return 0;
710
+ }
711
+
712
+ int buildadjlists() //from epanet for node sorting in WQ routing
713
+ /*
714
+ **--------------------------------------------------------------
715
+ ** Input: none
716
+ ** Output: returns error code
717
+ ** Purpose: builds linked list of links adjacent to each node
718
+ **--------------------------------------------------------------
719
+ */
720
+ {
721
+ int i, j, k;
722
+ int errcode = 0;
723
+ Padjlist alink;
724
+
725
+ // Create an array of adjacency lists
726
+ freeadjlists();
727
+ MSX.Adjlist = (Padjlist*)calloc(MSX.Nobjects[NODE]+1, sizeof(Padjlist));
728
+ if (MSX.Adjlist == NULL) return 101;
729
+ for (i = 0; i <= MSX.Nobjects[NODE]; i++)
730
+ MSX.Adjlist[i] = NULL;
731
+
732
+ // For each link, update adjacency lists of its end nodes
733
+ for (k = 1; k <= MSX.Nobjects[LINK]; k++)
734
+ {
735
+ i = MSX.Link[k].n1;
736
+ j = MSX.Link[k].n2;
737
+
738
+ // Include link in start node i's list
739
+ alink = (struct Sadjlist*) malloc(sizeof(struct Sadjlist));
740
+ if (alink == NULL)
741
+ {
742
+ errcode = 101;
743
+ break;
744
+ }
745
+ alink->node = j;
746
+ alink->link = k;
747
+ alink->next = MSX.Adjlist[i];
748
+ MSX.Adjlist[i] = alink;
749
+
750
+ // Include link in end node j's list
751
+ alink = (struct Sadjlist*) malloc(sizeof(struct Sadjlist));
752
+ if (alink == NULL)
753
+ {
754
+ errcode = 101;
755
+ break;
756
+ }
757
+ alink->node = i;
758
+ alink->link = k;
759
+ alink->next = MSX.Adjlist[j];
760
+ MSX.Adjlist[j] = alink;
761
+ }
762
+ if (errcode) freeadjlists();
763
+ return errcode;
764
+ }
765
+
766
+
767
+ void freeadjlists() //from epanet for node sorting in WQ routing
768
+ /*
769
+ **--------------------------------------------------------------
770
+ ** Input: none
771
+ ** Output: none
772
+ ** Purpose: frees memory used for nodal adjacency lists
773
+ **--------------------------------------------------------------
774
+ */
775
+ {
776
+ int i;
777
+ Padjlist alink;
778
+
779
+ if (MSX.Adjlist == NULL) return;
780
+ for (i = 0; i <= MSX.Nobjects[NODE]; i++)
781
+ {
782
+ for (alink = MSX.Adjlist[i]; alink != NULL; alink = MSX.Adjlist[i])
783
+ {
784
+ MSX.Adjlist[i] = alink->next;
785
+ free(alink);
786
+ }
787
+ }
788
+ free(MSX.Adjlist);
789
+ MSX.Adjlist = NULL;
790
+ }
791
+