epyt-flow 0.14.1__py3-none-any.whl → 0.15.0__py3-none-any.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.
Files changed (108) hide show
  1. epyt_flow/VERSION +1 -1
  2. epyt_flow/__init__.py +0 -37
  3. epyt_flow/data/benchmarks/battledim.py +2 -2
  4. epyt_flow/data/benchmarks/leakdb.py +12 -9
  5. epyt_flow/gym/scenario_control_env.py +32 -33
  6. epyt_flow/simulation/events/actuator_events.py +24 -18
  7. epyt_flow/simulation/events/leakages.py +59 -57
  8. epyt_flow/simulation/events/quality_events.py +21 -30
  9. epyt_flow/simulation/events/system_event.py +3 -3
  10. epyt_flow/simulation/scada/complex_control.py +14 -12
  11. epyt_flow/simulation/scada/custom_control.py +22 -21
  12. epyt_flow/simulation/scada/scada_data.py +108 -105
  13. epyt_flow/simulation/scada/simple_control.py +38 -31
  14. epyt_flow/simulation/scenario_simulator.py +368 -395
  15. epyt_flow/simulation/sensor_config.py +31 -32
  16. epyt_flow/topology.py +11 -10
  17. epyt_flow/uncertainty/model_uncertainty.py +146 -122
  18. epyt_flow/utils.py +66 -0
  19. epyt_flow/visualization/visualization_utils.py +4 -2
  20. {epyt_flow-0.14.1.dist-info → epyt_flow-0.15.0.dist-info}/METADATA +14 -19
  21. epyt_flow-0.15.0.dist-info/RECORD +65 -0
  22. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +0 -60
  23. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +0 -21
  24. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +0 -151
  25. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +0 -5930
  26. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +0 -961
  27. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +0 -79
  28. epyt_flow/EPANET/EPANET/SRC_engines/flowbalance.c +0 -186
  29. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +0 -219
  30. epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +0 -1000
  31. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +0 -177
  32. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +0 -28
  33. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +0 -1303
  34. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +0 -1172
  35. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +0 -781
  36. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +0 -442
  37. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +0 -464
  38. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +0 -1960
  39. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +0 -518
  40. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +0 -884
  41. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +0 -672
  42. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +0 -735
  43. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +0 -2265
  44. epyt_flow/EPANET/EPANET/SRC_engines/leakage.c +0 -527
  45. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +0 -146
  46. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +0 -24
  47. epyt_flow/EPANET/EPANET/SRC_engines/output.c +0 -853
  48. epyt_flow/EPANET/EPANET/SRC_engines/project.c +0 -1691
  49. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +0 -695
  50. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +0 -800
  51. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +0 -696
  52. epyt_flow/EPANET/EPANET/SRC_engines/report.c +0 -1557
  53. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +0 -1500
  54. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +0 -871
  55. epyt_flow/EPANET/EPANET/SRC_engines/text.h +0 -508
  56. epyt_flow/EPANET/EPANET/SRC_engines/types.h +0 -928
  57. epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.c +0 -59
  58. epyt_flow/EPANET/EPANET/SRC_engines/util/cstr_helper.h +0 -38
  59. epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.c +0 -92
  60. epyt_flow/EPANET/EPANET/SRC_engines/util/errormanager.h +0 -39
  61. epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.c +0 -212
  62. epyt_flow/EPANET/EPANET/SRC_engines/util/filemanager.h +0 -81
  63. epyt_flow/EPANET/EPANET/SRC_engines/validate.c +0 -408
  64. epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +0 -53
  65. epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +0 -27
  66. epyt_flow/EPANET/EPANET-MSX/Src/hash.c +0 -107
  67. epyt_flow/EPANET/EPANET-MSX/Src/hash.h +0 -28
  68. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +0 -102
  69. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +0 -42
  70. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +0 -937
  71. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +0 -39
  72. epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +0 -204
  73. epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +0 -24
  74. epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +0 -1285
  75. epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +0 -368
  76. epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +0 -42
  77. epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +0 -586
  78. epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +0 -116
  79. epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +0 -260
  80. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +0 -175
  81. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +0 -35
  82. epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +0 -1504
  83. epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +0 -401
  84. epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +0 -791
  85. epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +0 -2010
  86. epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +0 -400
  87. epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +0 -422
  88. epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +0 -1164
  89. epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +0 -551
  90. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +0 -524
  91. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +0 -56
  92. epyt_flow/EPANET/EPANET-MSX/Src/newton.c +0 -158
  93. epyt_flow/EPANET/EPANET-MSX/Src/newton.h +0 -34
  94. epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +0 -287
  95. epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +0 -39
  96. epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +0 -293
  97. epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +0 -35
  98. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +0 -816
  99. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +0 -29
  100. epyt_flow/EPANET/EPANET-MSX/readme.txt +0 -14
  101. epyt_flow/EPANET/compile_linux.sh +0 -4
  102. epyt_flow/EPANET/compile_macos.sh +0 -4
  103. epyt_flow/simulation/backend/__init__.py +0 -1
  104. epyt_flow/simulation/backend/my_epyt.py +0 -1101
  105. epyt_flow-0.14.1.dist-info/RECORD +0 -148
  106. {epyt_flow-0.14.1.dist-info → epyt_flow-0.15.0.dist-info}/WHEEL +0 -0
  107. {epyt_flow-0.14.1.dist-info → epyt_flow-0.15.0.dist-info}/licenses/LICENSE +0 -0
  108. {epyt_flow-0.14.1.dist-info → epyt_flow-0.15.0.dist-info}/top_level.txt +0 -0
@@ -1,586 +0,0 @@
1
- /******************************************************************************
2
- ** MODULE: MSXDISPERSION.C
3
- ** PROJECT: EPANET-MSX
4
- ** DESCRIPTION: Dispersion solver for Lagrangian ADR
5
- ******************************************************************************/
6
-
7
- #include <stdio.h>
8
- #include <stdlib.h>
9
- #include <string.h>
10
- #include <math.h>
11
- #include <omp.h>
12
-
13
- #include "msxtypes.h"
14
- #include "dispersion.h"
15
- #include "smatrix.h"
16
-
17
- #define ERRCODE(x) (errcode = ((errcode>100) ? (errcode) : (x)))
18
- // External variables
19
- //--------------------
20
- extern MSXproject MSX; // MSX project data
21
-
22
- static double* al; //vector helping solve tridaigonal system of eqns.
23
- static double* bl; //vector helping solve tridaigonal system of eqns.
24
- static double* cl; //vector helping solve tridaigonal system of eqns.
25
- static double* rl; //vector helping solve tridaigonal system of eqns.
26
- static double* sol; //vector helping solve tridaigonal system of eqns.
27
-
28
- static double* gam;
29
-
30
- #pragma omp threadprivate(al, bl, cl, rl, sol, gam)
31
-
32
- int dispersion_open()
33
- {
34
- int errcode=0;
35
- #pragma omp parallel
36
- {
37
- al = (double*)calloc(MSX.MaxSegments + 2, sizeof(double));
38
- bl = (double*)calloc(MSX.MaxSegments + 2, sizeof(double));
39
- cl = (double*)calloc(MSX.MaxSegments + 2, sizeof(double));
40
- rl = (double*)calloc(MSX.MaxSegments + 2, sizeof(double));
41
- sol = (double*)calloc(MSX.MaxSegments + 2, sizeof(double));
42
- gam = (double*)calloc(MSX.MaxSegments + 2, sizeof(double));
43
- #pragma omp critical
44
- {
45
- ERRCODE(MEMCHECK(al));
46
- ERRCODE(MEMCHECK(bl));
47
- ERRCODE(MEMCHECK(cl));
48
- ERRCODE(MEMCHECK(rl));
49
- ERRCODE(MEMCHECK(sol));
50
- ERRCODE(MEMCHECK(gam));
51
- }
52
- }
53
- return errcode;
54
-
55
- }
56
-
57
- int dispersion_close()
58
- {
59
- int errcode = 0;
60
- #pragma omp parallel
61
- {
62
- FREE(al);
63
- FREE(bl);
64
- FREE(cl);
65
- FREE(rl);
66
- FREE(sol);
67
- FREE(gam);
68
- }
69
- return errcode;
70
- }
71
-
72
- void dispersion_pipe(int m, double tstep)
73
- {
74
-
75
- double cons = 0.0;
76
- double ldispersion = 0.0;
77
- double flowrate = 0.0, velocity = 0.0, area = 0.0;
78
- int nseg = 0, k;
79
- double diam = 0.0;
80
- double vd = 0.0, vu = 0.0, vself = 0.0, asquare = 0.0, dh = 0.0, frictionfactor = 0.0;
81
- double reynolds=0, shearvelocity=0;
82
- Pseg seg = NULL;
83
-
84
- double elpt = 0.0;
85
- double d0 = 1.292e-8; //molecular diffusivity 1.292e-8 ft^2/s 1.2e-9 m^2/s
86
-
87
- d0 = MSX.Dispersion.md[m];
88
- #pragma omp parallel
89
- {
90
- #pragma omp for private(seg, cons, vd, vu, vself, k, nseg, asquare, velocity, diam, area, flowrate, reynolds, dh, frictionfactor, shearvelocity, ldispersion, elpt)
91
- for (k = 1; k <= MSX.Nobjects[LINK]; k++)
92
- {
93
-
94
- velocity = 0;
95
- if (MSX.FirstSeg[k] == NULL)
96
- continue;
97
- diam = MSX.Link[k].diam;
98
- // Compute Reynolds No.
99
- flowrate = (MSX.S[k] <= CLOSED) ? 0.0 : MSX.Q[k];
100
- area = PI * diam * diam / 4.0; // pipe area
101
- if (area > 0.0 && MSX.Link[k].len > 0.0 && ABS(flowrate) > 0.0)
102
- {
103
- velocity = fabs(flowrate) / area; // flow velocity
104
- reynolds = velocity * diam / MSX.Dispersion.viscosity; // Reynolds number //#define VISCOS 1.1E-5 // Kinematic viscosity of water // @ 20 deg C (sq ft/sec)
105
- dh = ABS(MSX.H[MSX.Link[k].n1] - MSX.H[MSX.Link[k].n2]);
106
- if (dh > 0.00001)
107
- frictionfactor = 39.725 * dh * pow(diam, 5) / (MSX.Link[k].len * SQR(flowrate));
108
- else
109
- frictionfactor = 0.0;
110
- shearvelocity = velocity * sqrt(frictionfactor / 8);
111
-
112
- if (d0 < 0)
113
- {
114
- ldispersion = MSX.Dispersion.ld[m];
115
- }
116
- else if (reynolds > 2300) //Basha 2007
117
- {
118
- ldispersion = 0.5 * diam * shearvelocity * (10.1 + 577 * pow(reynolds / 1000.0, -2.2));
119
-
120
- }
121
- /* else //Basha 2007
122
- {
123
- ldispersion = SQR(0.5 * diam * velocity) / (48 * d0);
124
- elpt = MSX.Link[k].len / velocity;
125
- ldispersion = ldispersion * (1 - exp(-12.425 * d0 * elpt / SQR(0.5 * diam)));
126
- ldispersion += d0;
127
- }*/
128
- else //Lee 2004 averaged
129
- {
130
- ldispersion = SQR(0.5 * diam * velocity) / (48 * d0);
131
- elpt = MSX.Link[k].len / velocity;
132
- double interv = 16.0 * d0 * elpt / (0.25 * diam * diam);
133
- ldispersion = ldispersion * (1 - (1 - exp(-interv))/interv);
134
- ldispersion += d0;
135
-
136
- }
137
-
138
- }
139
- else
140
- {
141
- ldispersion = 0;
142
- }
143
-
144
- if (ldispersion < 0.0)
145
- {
146
- ldispersion = 0;
147
- MSX.Dispersion.pipeDispersionCoeff[k] = 0;
148
- continue;
149
- }
150
-
151
- double domi;
152
-
153
- if (velocity > 0)
154
- domi = ldispersion / (velocity * velocity * tstep);
155
- else
156
- domi = 1000;
157
- if (domi >= 0.000 && MSX.Link[k].len*velocity/ldispersion < MSX.Dispersion.PecletLimit) //Peclet numer
158
- {
159
- MSX.Dispersion.pipeDispersionCoeff[k] = ldispersion;
160
- }
161
- else
162
- {
163
- MSX.Dispersion.pipeDispersionCoeff[k] = 0;
164
- continue;
165
- }
166
- asquare = area * area;
167
- seg = MSX.FirstSeg[k]; //downstream
168
- cons = 2.0 * ldispersion * asquare * tstep;
169
- vd = 0.0;
170
- bl[0] = 1.0;
171
- cl[0] = 0.0;
172
- rl[0] = 0.0;
173
- nseg = 0;
174
-
175
- while (seg != NULL)
176
- {
177
- nseg++;
178
- vself = seg->v;
179
- rl[nseg] = seg->c[m];
180
- seg = seg->prev;
181
- if (seg)
182
- vu = seg->v;
183
- else
184
- vu = 0.0;
185
- al[nseg] = -cons / (vself * vself + vself * vd);
186
- cl[nseg] = -cons / (vself * vself + vself * vu);
187
- bl[nseg] = 1 - al[nseg] - cl[nseg];
188
-
189
- vd = vself;
190
- }
191
- if (nseg == 0)
192
- continue;
193
-
194
-
195
- al[nseg + 1] = 0.0;
196
- bl[nseg + 1] = 1.0;
197
- rl[nseg + 1] = 0.0;
198
-
199
- if (reynolds >= 0)
200
- tridiag(nseg + 2, al, bl, cl, rl, sol); //nseg+2 <= 1000 here
201
- else
202
- {
203
- for (int p = 0; p <= nseg + 1; p++)
204
- sol[p] = rl[p];
205
- }
206
-
207
- seg = MSX.FirstSeg[k]; //downstream segment
208
- int segindex = 1;
209
- while (seg != NULL)
210
- {
211
- seg->hresponse = sol[segindex];
212
- seg = seg->prev;
213
- segindex++;
214
- }
215
- /*clear initial condition*/
216
- for (int p = 1; p < nseg + 1; p++)
217
- rl[p] = 0.0;
218
-
219
- /*downstream unit boundary condition*/
220
- rl[0] = 1.0;
221
- if (reynolds >= 0)
222
- tridiag(nseg + 2, al, bl, cl, rl, sol);
223
- else
224
- {
225
- for (int p = 0; p <= nseg + 1; p++)
226
- sol[p] = rl[p];
227
- }
228
-
229
- seg = MSX.FirstSeg[k]; //downstream
230
- segindex = 1;
231
- while (seg != NULL)
232
- {
233
- seg->dresponse = sol[segindex];
234
- seg = seg->prev;
235
- segindex++;
236
- }
237
-
238
- /*upstream unit boundary condition*/
239
- rl[0] = 0.0;
240
- rl[nseg + 1] = 1.0;
241
- if (reynolds >= 0)
242
- tridiag(nseg + 2, al, bl, cl, rl, sol); //nseg+2 <= 100 here
243
- else
244
- {
245
- for (int p = 0; p <= nseg + 1; p++)
246
- sol[p] = rl[p];
247
- }
248
-
249
- seg = MSX.FirstSeg[k]; //downstream
250
- segindex = 1;
251
- while (seg != NULL)
252
- {
253
- seg->uresponse = sol[segindex];
254
- seg = seg->prev;
255
- segindex++;
256
- }
257
- }
258
- }
259
- }
260
-
261
- void solve_nodequal(int m, double tstep)
262
- {
263
-
264
- Pseg firstseg;
265
- Pseg lastseg;
266
- Psource source;
267
- int n1, n2;
268
- double diam, area, asquare;
269
-
270
- // double dispersion = 147.25;
271
- double ldispersion;
272
- double coelastseg, coefirstseg;
273
-
274
- int njuncs = MSX.Nobjects[NODE] - MSX.Nobjects[TANK];
275
- int found = 0;
276
-
277
-
278
- //let's take a look of the matrix
279
-
280
- memset(MSX.Dispersion.Aii, 0, (MSX.Nobjects[NODE] + 1) * sizeof(double));
281
- memset(MSX.Dispersion.Aij, 0, (MSX.Dispersion.Ncoeffs + 1) * sizeof(double));
282
- memset(MSX.Dispersion.F, 0, (MSX.Nobjects[NODE] + 1) * sizeof(double));
283
- for (int k = 1; k <= MSX.Nobjects[LINK]; k++)
284
- {
285
- ldispersion = MSX.Dispersion.pipeDispersionCoeff[k];
286
- if (ldispersion <= 0)
287
- continue;
288
- n1 = MSX.Link[k].n1; //upstream
289
- n2 = MSX.Link[k].n2; //downstream
290
- if (MSX.FlowDir[k] < 0)
291
- {
292
- n1 = MSX.Link[k].n2; //upstream
293
- n2 = MSX.Link[k].n1; //downstream
294
- }
295
- diam = MSX.Link[k].diam;
296
- area = 0.25 * PI * diam * diam;
297
- asquare = area * area;
298
- firstseg = MSX.FirstSeg[k]; //downstream
299
- lastseg = MSX.LastSeg[k]; //upstream
300
-
301
-
302
- if (firstseg == NULL)
303
- continue;
304
-
305
- coefirstseg = ldispersion * asquare / firstseg->v; //dispersion should be pipe by pipe
306
- coelastseg = ldispersion * asquare / lastseg->v; //dispersion should be pipe by pipe
307
- MSX.Dispersion.Aij[MSX.Dispersion.Ndx[k]] -= coefirstseg * firstseg->uresponse; //coefirstseg*firstseg->greenu = coelastseg*lastseg->greend
308
-
309
- found = 0;
310
- source = MSX.Node[n2].sources;
311
- while(source != NULL)
312
- {
313
- if (source->species == m)
314
- {
315
- found = 1;
316
- break;
317
- }
318
- else
319
- source = source->next;
320
- }
321
-
322
- if (n2 <= njuncs)
323
- {
324
- if (source == NULL || source->c0 <= 0.0)
325
- {
326
- MSX.Dispersion.Aii[MSX.Dispersion.Row[n2]] += coefirstseg * (1.0 - firstseg->dresponse);
327
-
328
- MSX.Dispersion.F[MSX.Dispersion.Row[n2]] += coefirstseg * firstseg->hresponse;
329
- }
330
- else
331
- {
332
- MSX.Dispersion.Aij[MSX.Dispersion.Ndx[k]] = 0;
333
- MSX.Dispersion.F[MSX.Dispersion.Row[n1]] += coelastseg * MSX.LastSeg[k]->dresponse * MSX.Node[n2].c[m];
334
- }
335
- }
336
- else
337
- {
338
- MSX.Dispersion.F[MSX.Dispersion.Row[n1]] += coelastseg * MSX.LastSeg[k]->dresponse * MSX.Node[n2].c[m];
339
- }
340
-
341
-
342
- found = 0;
343
- source = MSX.Node[n1].sources;
344
- while (source != NULL)
345
- {
346
- if (source->species == m)
347
- {
348
- found = 1;
349
- break;
350
- }
351
- else
352
- source = source->next;
353
- }
354
-
355
- if (n1 <= njuncs)
356
- {
357
- source = MSX.Node[n1].sources;
358
- if (source == NULL || source->c0 <= 0.0)
359
- {
360
- MSX.Dispersion.Aii[MSX.Dispersion.Row[n1]] += coelastseg * (1.0 - lastseg->uresponse);
361
- MSX.Dispersion.F[MSX.Dispersion.Row[n1]] += coelastseg * lastseg->hresponse;
362
- }
363
- else
364
- {
365
- MSX.Dispersion.Aij[MSX.Dispersion.Ndx[k]] = 0; //sure
366
- MSX.Dispersion.F[MSX.Dispersion.Row[n2]] += coefirstseg * firstseg->uresponse * MSX.Node[n1].c[m];
367
- }
368
-
369
- }
370
- else
371
- {
372
- MSX.Dispersion.F[MSX.Dispersion.Row[n2]] += coefirstseg * firstseg->uresponse * MSX.Node[n1].c[m];
373
- }
374
- }
375
- for (int i = 1; i <= njuncs; i++)
376
- {
377
- if (MSX.Dispersion.Aii[MSX.Dispersion.Row[i]] == 0.0) //no dispersion around the junction at all
378
- {
379
- MSX.Dispersion.Aii[MSX.Dispersion.Row[i]] = 1.0;
380
-
381
- MSX.Dispersion.F[MSX.Dispersion.Row[i]] = 1.0 * MSX.Node[i].c[m];
382
- }
383
- }
384
-
385
- int errcode = msx_linsolve(njuncs, MSX.Dispersion.Aii, MSX.Dispersion.Aij, MSX.Dispersion.F);
386
-
387
- for (int i = 1; i <= njuncs; i++)
388
- {
389
- MSX.Node[i].c[m] = MSX.Dispersion.F[MSX.Dispersion.Row[i]];
390
- }
391
-
392
- }
393
-
394
-
395
- void segqual_update(int m, double tstep)
396
- {
397
-
398
- Pseg seg = NULL;
399
- Psource source = NULL;
400
- int n1 = 0, n2 = 0, k;
401
- double mass1 = 0;
402
- double mass2 = 0;
403
- double dispersedin = 0;
404
- double ldispersion = 0, massin = 0;
405
- double area = 0.0;
406
- int njuncs = MSX.Nobjects[NODE] - MSX.Nobjects[TANK];
407
- #pragma omp parallel
408
- {
409
- #pragma omp for private(k, n1, n2, seg, source, mass1, mass2, ldispersion, massin, area)
410
- for (k = 1; k <= MSX.Nobjects[LINK]; k++)
411
- {
412
- mass1 = 0;
413
- mass2 = 0;
414
- ldispersion = MSX.Dispersion.pipeDispersionCoeff[k];
415
- if (ldispersion <= 0.0)
416
- continue;
417
- area = 0.25 * PI * MSX.Link[k].diam * MSX.Link[k].diam;
418
- n1 = MSX.Link[k].n1;
419
- n2 = MSX.Link[k].n2;
420
- if (MSX.FlowDir[k] < 0.0)
421
- {
422
- n1 = MSX.Link[k].n2;
423
- n2 = MSX.Link[k].n1;
424
- }
425
- seg = MSX.FirstSeg[k];
426
- while (seg != NULL) //update segment concentration based on new up/down node quality
427
- {
428
- mass1 += seg->c[m] * seg->v;
429
- seg->c[m] = seg->hresponse + MSX.Node[n2].c[m] * seg->dresponse + MSX.Node[n1].c[m] * seg->uresponse;
430
-
431
- mass2 += seg->c[m] * seg->v;
432
- seg = seg->prev;
433
- }
434
- if (MSX.FirstSeg[k] == NULL)
435
- continue;
436
-
437
- source = MSX.Node[n2].sources;
438
- while (source != NULL)
439
- {
440
- if (source->species == m)
441
- break;
442
- source = source->next;
443
- }
444
- massin = 0;
445
- if (source != NULL && source->c0 > 0)
446
- {
447
- massin = 2.0 * ldispersion * tstep * area * area * (MSX.Node[n2].c[m] - MSX.FirstSeg[k]->c[m]) * LperFT3 / MSX.FirstSeg[k]->v;
448
- }
449
- else if (n2 > njuncs && MSX.Tank[n2 - njuncs].a == 0) //we assume constant tank and reservoir concentration during dispersion which may not be true for small tanks
450
- {
451
- massin = 2.0 * ldispersion * tstep * area * area * (MSX.Node[n2].c[m] - MSX.FirstSeg[k]->c[m]) * LperFT3 / MSX.FirstSeg[k]->v;
452
- }
453
- else if (n2 > njuncs && MSX.Tank[n2 - njuncs].a > 0.0)
454
- {
455
- massin = 2.0 * ldispersion * tstep * area * area * (MSX.Node[n2].c[m] - MSX.FirstSeg[k]->c[m]) * LperFT3 / MSX.FirstSeg[k]->v;
456
-
457
- }
458
- #pragma omp critical
459
- {
460
- dispersedin += massin;
461
- }
462
- source = MSX.Node[n1].sources;
463
- while (source != NULL)
464
- {
465
- if (source->species == m)
466
- break;
467
- source = source->next;
468
- }
469
- massin = 0;
470
- if (source != NULL && source->c0 > 0)
471
- {
472
- massin = 2.0 * ldispersion * tstep * area * area * (MSX.Node[n1].c[m] - MSX.LastSeg[k]->c[m]) * LperFT3 / MSX.LastSeg[k]->v;
473
- }
474
- else if (n1 > njuncs && MSX.Tank[n1 - njuncs].a == 0)
475
- {
476
- massin = 2.0 * ldispersion * tstep * area * area * (MSX.Node[n1].c[m] - MSX.LastSeg[k]->c[m]) * LperFT3 / MSX.LastSeg[k]->v;
477
- }
478
- else if (n1 > njuncs && MSX.Tank[n1 - njuncs].a > 0.0)
479
- {
480
-
481
- massin = 2.0 * ldispersion * tstep * area * area * (MSX.Node[n1].c[m] - MSX.LastSeg[k]->c[m]) * LperFT3 / MSX.LastSeg[k]->v;
482
-
483
- }
484
- #pragma omp critical
485
- {
486
- dispersedin += massin;
487
- }
488
- }
489
- }
490
- MSX.MassBalance.indisperse[m] += dispersedin;
491
-
492
-
493
- }
494
-
495
-
496
- void disperse_tankqual(int n, int m, double massin)
497
- {
498
- int j, tm, k;
499
- Pseg seg;
500
- double c, v;
501
-
502
- j = MSX.Node[n].tank;
503
- if (j < 0)
504
- return;
505
- else if (MSX.Tank[j].a == 0)
506
- return;
507
-
508
- k = MSX.Nobjects[LINK] + j;
509
- tm = MSX.Tank[j].mixModel;
510
-
511
- if (tm == MIX1|| tm == MIX2)
512
- {
513
- seg = MSX.LastSeg[k];
514
- if (seg)
515
- {
516
- v = seg->v;
517
- c = seg->c[m];
518
- if (v > 0)
519
- c = (c * v * LperFT3 + massin) / (v * LperFT3);
520
-
521
- c = MAX(0, c);
522
- seg->c[m] = c;
523
- MSX.Tank[j].c[m] = c;
524
- MSX.Node[n].c[m] = c;
525
- }
526
- }
527
- else if (tm == FIFO)
528
- {
529
- seg = MSX.FirstSeg[k];
530
- if (seg)
531
- {
532
- v = seg->v;
533
- c = seg->c[m];
534
- if (v > 0)
535
- c = (c * v * LperFT3 + massin) / (v * LperFT3);
536
-
537
- if( c < 0)
538
- c = MAX(0, c);
539
- seg->c[m] = c;
540
-
541
- }
542
- }
543
- else if (tm == LIFO)
544
- {
545
- seg = MSX.FirstSeg[k];
546
- if (seg)
547
- {
548
- v = seg->v;
549
- c = seg->c[m];
550
- if (v > 0)
551
- c = (c * v * LperFT3 + massin) / (v * LperFT3);
552
-
553
- c = MAX(0, c);
554
- seg->c[m] = c;
555
-
556
- }
557
-
558
- }
559
-
560
-
561
- }
562
-
563
-
564
-
565
-
566
-
567
- // Solve tri-daigonal system of eqns. using Thomas' algorithm
568
-
569
- void tridiag(int n, double *a, double *b, double *c, double *r, double *y)
570
- {
571
- int j;
572
- double bet;
573
-
574
- bet = b[0];
575
- y[0] = r[0] / bet;
576
- for (j = 1; j < n; j++)
577
- {
578
- gam[j] = c[j - 1] / bet;
579
- bet = b[j] - a[j] * gam[j];
580
- y[j] = (r[j] - a[j] * y[j - 1]) / bet;
581
- }
582
- for (j = n - 2; j >= 0; j--)
583
- {
584
- y[j] -= gam[j + 1] * y[j + 1];
585
- }
586
- }
@@ -1,116 +0,0 @@
1
- /******************************************************************************
2
- ** MODULE: MSXERR.C
3
- ** PROJECT: EPANET-MSX
4
- ** DESCRIPTION: Math error reporting routines.
5
- ** AUTHORS: see AUTHORS
6
- ** Copyright: see AUTHORS
7
- ** License: see LICENSE
8
- ** VERSION: 2.0.00
9
- ** LAST UPDATE: 04/14/2021
10
- ******************************************************************************/
11
-
12
- #include <stdio.h>
13
- #include <string.h>
14
-
15
- #include "msxtypes.h"
16
- #include "epanet2.h"
17
-
18
- // External variables
19
- //--------------------
20
- extern MSXproject MSX; // MSX project data
21
-
22
- // Local variables
23
- //-----------------
24
- static int mathError; // math error flag
25
- static char mathErrorMsg[1024]; // math error message
26
- static char* elementTxt[] = // see ObjectType in msxtypes.h
27
- {"", "pipe", "tank"};
28
- static char* exprTypeTxt[] = // see ExpressionType in msxtypes.h
29
- {"", "rate", "formula", "equilibrium"};
30
-
31
- // Exported functions
32
- //--------------------
33
- void MSXerr_clearMathError(void);
34
- int MSXerr_mathError(void);
35
- double MSXerr_validate(double x, int index, int element, int exprType);
36
- void MSXerr_writeMathErrorMsg(void);
37
-
38
-
39
- //=============================================================================
40
-
41
- void MSXerr_clearMathError()
42
- /*
43
- ** Purpose:
44
- ** clears the math error flag.
45
- */
46
- {
47
- mathError = 0;
48
- strcpy(mathErrorMsg, "");
49
- }
50
-
51
- //=============================================================================
52
-
53
- int MSXerr_mathError()
54
- /*
55
- ** Purpose:
56
- ** returns the current state of the math error flag.
57
- */
58
- {
59
- return mathError;
60
- }
61
-
62
- //=============================================================================
63
-
64
- void MSXerr_writeMathErrorMsg()
65
- /*
66
- ** Purpose:
67
- ** writes math error message to EPANET report file.
68
- */
69
- {
70
- ENwriteline(mathErrorMsg);
71
- ENwriteline("");
72
- }
73
-
74
- //=============================================================================
75
-
76
- double MSXerr_validate(double x, int index, int element, int exprType)
77
- /*
78
- ** Purpose:
79
- ** checks if a number is valid or not.
80
- **
81
- ** Input:
82
- ** x = the number to check
83
- ** index = array index of species or term that x was computed for
84
- ** element = LINK for a pipe element or TANK for a tank element
85
- ** exprType = type of expression that produced x
86
- **
87
- ** Returns:
88
- ** the value of x if it's a valid number or 0 otherwise.
89
- */
90
- {
91
- // return x if it's a valid number
92
- if (x == x) return x;
93
-
94
- // return 0 if the math error flag has previously been set
95
- // (we only want the first math error identified since others
96
- // may have propagated from it)
97
- if (mathError) return 0.0;
98
-
99
- // construct a math error message
100
- if ( exprType == TERM )
101
- {
102
- sprintf(mathErrorMsg,
103
- "Ilegal math operation occurred for term:\n %s",
104
- MSX.Term[index].id);
105
- }
106
- else
107
- {
108
- sprintf(mathErrorMsg,
109
- "Ilegal math operation occurred in %s %s expression for species:\n %s",
110
- elementTxt[element], exprTypeTxt[exprType], MSX.Species[index].id);
111
- }
112
-
113
- // set the math error flag and return 0
114
- mathError = 1;
115
- return 0.0;
116
- }