epanet-plus 0.0.1__cp310-cp310-macosx_10_9_x86_64.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.cpython-310-darwin.so +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 +6 -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,158 @@
1
+ /******************************************************************************
2
+ ** MODULE: NEWTON.C
3
+ ** PROJECT: EPANET-MSX
4
+ ** DESCRIPTION: Newton-Raphson algorithm used to solve a set of nonlinear
5
+ ** algebraic equations.
6
+ ** AUTHORS: see AUTHORS
7
+ ** Copyright: see AUTHORS
8
+ ** License: see LICENSE
9
+ ** VERSION: 2.0.00
10
+ ** LAST UPDATE: 04/14/2021
11
+ ******************************************************************************/
12
+
13
+ #include <stdio.h>
14
+ #include <stdlib.h>
15
+ #include <string.h>
16
+ #include <math.h>
17
+ #include "msxutils.h"
18
+ #include "newton.h"
19
+
20
+ // Local declarations
21
+ //-------------------
22
+ MSXNewton MSXNewtonSolver;
23
+
24
+ #pragma omp threadprivate(MSXNewtonSolver)
25
+
26
+ //=============================================================================
27
+
28
+ int newton_open(int n)
29
+ /*
30
+ ** Purpose:
31
+ ** opens the algebraic solver to handle a system of n equations.
32
+ **
33
+ ** Input:
34
+ ** n = number of equations
35
+ **
36
+ ** Returns:
37
+ ** 1 if successful, 0 if not.
38
+ **
39
+ ** Note:
40
+ ** All arrays are 1-based so an extra memory location
41
+ ** must be allocated for the unused 0-th position.
42
+ */
43
+ {
44
+ int errorcode = 1;
45
+
46
+ #pragma omp parallel
47
+ {
48
+ MSXNewtonSolver.Nmax = 0;
49
+ MSXNewtonSolver.Indx = NULL;
50
+ MSXNewtonSolver.F = NULL;
51
+ MSXNewtonSolver.W = NULL;
52
+ MSXNewtonSolver.Indx = (int*)calloc(n + 1, sizeof(int));
53
+ MSXNewtonSolver.F = (double*)calloc(n + 1, sizeof(double));
54
+ MSXNewtonSolver.W = (double*)calloc(n + 1, sizeof(double));
55
+ MSXNewtonSolver.J = createMatrix(n + 1, n + 1);
56
+ #pragma omp critical
57
+ {
58
+ if (!MSXNewtonSolver.Indx || !MSXNewtonSolver.F || !MSXNewtonSolver.W || !MSXNewtonSolver.J)
59
+ errorcode = 0;
60
+ }
61
+ MSXNewtonSolver.Nmax = n;
62
+ }
63
+
64
+ return errorcode;
65
+ }
66
+
67
+ //=============================================================================
68
+
69
+ void newton_close()
70
+ /*
71
+ ** Purpose:
72
+ ** closes the algebraic solver.
73
+ **
74
+ ** Input:
75
+ ** none
76
+ */
77
+ {
78
+
79
+ #pragma omp parallel
80
+ {
81
+ if (MSXNewtonSolver.Indx) { free(MSXNewtonSolver.Indx); MSXNewtonSolver.Indx = NULL; }
82
+ if (MSXNewtonSolver.F) { free(MSXNewtonSolver.F); MSXNewtonSolver.F = NULL; }
83
+ if (MSXNewtonSolver.W) { free(MSXNewtonSolver.W); MSXNewtonSolver.W = NULL; }
84
+ freeMatrix(MSXNewtonSolver.J);
85
+ MSXNewtonSolver.J = NULL;
86
+ }
87
+
88
+ }
89
+
90
+ //=============================================================================
91
+
92
+ int newton_solve(double x[], int n, int maxit, int numsig,
93
+ void (*func)(double, double*, int, double*))
94
+ /*
95
+ ** Purpose:
96
+ ** uses newton-raphson iterations to solve n nonlinear eqns.
97
+ **
98
+ ** Input:
99
+ ** x[] = solution vector
100
+ ** n = number of equations
101
+ ** maxit = max. number of iterations allowed
102
+ ** numsig = number of significant digits in error
103
+ ** func = pointer to the function that returns the function values at x.
104
+ **
105
+ ** Returns:
106
+ ** number of iterations if successful, -1 if Jacobian is singular,
107
+ ** -2 if it didn't converge, or -3 if n exceeds allowable size.
108
+ **
109
+ ** Note:
110
+ ** the arguments to the function func are:
111
+ ** t = a time value (not used here)
112
+ ** x = vector of unknowns being solved for
113
+ ** n = number of unknowns
114
+ ** f = vector of function values evaluated at x.
115
+ */
116
+ {
117
+ int i, k;
118
+ double errx, errmax, cscal, relconvg = pow(10.0, -numsig);
119
+
120
+ // --- check that system was sized adequetely
121
+
122
+ if ( n > MSXNewtonSolver.Nmax ) return -3;
123
+
124
+ // --- use up to maxit iterations to find a solution
125
+
126
+ for (k=1; k<=maxit; k++)
127
+ {
128
+ // --- evaluate the Jacobian matrix
129
+
130
+ jacobian(x, n, MSXNewtonSolver.F, MSXNewtonSolver.W, MSXNewtonSolver.J, func);
131
+
132
+ // --- factorize the Jacobian
133
+
134
+ if ( !factorize(MSXNewtonSolver.J, n, MSXNewtonSolver.W, MSXNewtonSolver.Indx) ) return -1;
135
+
136
+ // --- solve for the updates to x (returned in F)
137
+
138
+ for (i=1; i<=n; i++) MSXNewtonSolver.F[i] = -MSXNewtonSolver.F[i];
139
+ solve(MSXNewtonSolver.J, n, MSXNewtonSolver.Indx, MSXNewtonSolver.F);
140
+
141
+ // --- update solution x & check for convergence
142
+
143
+ errmax = 0.0;
144
+ for (i=1; i<=n; i++)
145
+ {
146
+ cscal = x[i];
147
+ if (cscal < relconvg) cscal = relconvg;
148
+ x[i] += MSXNewtonSolver.F[i];
149
+ errx = fabs(MSXNewtonSolver.F[i]/cscal);
150
+ if (errx > errmax) errmax = errx;
151
+ }
152
+ if (errmax <= relconvg) return k;
153
+ }
154
+
155
+ // --- return error code if no convergence
156
+
157
+ return -2;
158
+ }
@@ -0,0 +1,34 @@
1
+ /******************************************************************************
2
+ ** MODULE: NEWTON.H
3
+ ** PROJECT: EPANET-MSX
4
+ ** DESCRIPTION: header file for the equation solver contained in newton.c.
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
+ #ifndef NEWTON_H
13
+ #define NEWTON_H
14
+
15
+ typedef struct
16
+ {
17
+ int Nmax; // max. number of equations
18
+ int* Indx; // permutation vector of row indexes
19
+ double* F; // function & adjustment vector
20
+ double* W; // work vector
21
+ double** J; // Jacobian matrix
22
+ }MSXNewton;
23
+
24
+ // Opens the equation solver system
25
+ int newton_open(int n);
26
+
27
+ // Closes the equation solver system
28
+ void newton_close(void);
29
+
30
+ // Applies the solver to a specific system of equations
31
+ int newton_solve(double x[], int n, int maxit, int numsig,
32
+ void (*func)(double, double*, int, double*));
33
+
34
+ #endif
epanet-msx-src/rk5.c ADDED
@@ -0,0 +1,287 @@
1
+ /************************************************************************
2
+ ** MODULE: RK5.C
3
+ ** PROJECT: EPANET-MSX
4
+ ** DESCRIPTION: Numerical solution of a system of first order
5
+ ** ordinary differential equations dY/dt = F(t,Y).
6
+ ** AUTHOR: L. Rossman, US EPA - NRMRL
7
+ ** VERSION: 2.0.00
8
+ ** LAST UPDATE: 04/14/2021
9
+ **
10
+ ** This is an explicit Runge-Kutta method of order (4)5
11
+ ** due to Dormand & Prince (with optional stepsize control).
12
+ ** The code was adapted from the DOPRI5 code of E. Hairer
13
+ ** and G. Wanner as described in:
14
+ ** E. HAIRER, S.P. NORSETT AND G. WANNER, SOLVING ORDINARY
15
+ ** DIFFERENTIAL EQUATIONS I. NONSTIFF PROBLEMS. 2ND EDITION.
16
+ ** SPRINGER SERIES IN COMPUTATIONAL MATHEMATICS,
17
+ ** SPRINGER-VERLAG (1993)
18
+ ***********************************************************************/
19
+
20
+ #include <stdlib.h>
21
+ #include <math.h>
22
+ #include "rk5.h"
23
+
24
+ #define fmin(x,y) (((x)<=(y)) ? (x) : (y)) /* minimum of x and y */
25
+ #define fmax(x,y) (((x)>=(y)) ? (x) : (y)) /* maximum of x and y */
26
+
27
+ // Local variables
28
+ //-----------------
29
+ MSXRungeKutta MSXRungeKuttaSolver;
30
+
31
+ #pragma omp threadprivate(MSXRungeKuttaSolver)
32
+ //=============================================================================
33
+
34
+ int rk5_open(int n, int itmax, int adjust)
35
+ /*
36
+ ** Purpose:
37
+ ** Opens the RK5 solver to solve system of n equations
38
+ **
39
+ ** Input:
40
+ ** n = number of equtions
41
+ ** itmax = maximum iterations allowed
42
+ ** adjust = 1 if time step adjustment used, 0 if not
43
+ **
44
+ ** Returns:
45
+ ** 1 if successful and 0 if not.
46
+ */
47
+ {
48
+ int n1 = n+1;
49
+ int errorcode = 1;
50
+ MSXRungeKuttaSolver.Report = NULL;
51
+
52
+ #pragma omp parallel
53
+ {
54
+ MSXRungeKuttaSolver.Nmax = 0;
55
+ MSXRungeKuttaSolver.Itmax = itmax;
56
+ MSXRungeKuttaSolver.Adjust = adjust;
57
+ MSXRungeKuttaSolver.Ynew = (double*)calloc(n1, sizeof(double));
58
+ MSXRungeKuttaSolver.Ak = (double*)calloc(6 * n1, sizeof(double));
59
+ #pragma omp critical
60
+ {
61
+ if (!MSXRungeKuttaSolver.Ynew || !MSXRungeKuttaSolver.Ak) errorcode = 0;
62
+ }
63
+
64
+ MSXRungeKuttaSolver.Nmax = n;
65
+ MSXRungeKuttaSolver.K1 = (MSXRungeKuttaSolver.Ak);
66
+ MSXRungeKuttaSolver.K2 = ((MSXRungeKuttaSolver.Ak)+(n1));
67
+ MSXRungeKuttaSolver.K3 = ((MSXRungeKuttaSolver.Ak)+(2 * n1));
68
+ MSXRungeKuttaSolver.K4 = ((MSXRungeKuttaSolver.Ak)+(3 * n1));
69
+ MSXRungeKuttaSolver.K5 = ((MSXRungeKuttaSolver.Ak)+(4 * n1));
70
+ MSXRungeKuttaSolver.K6 = ((MSXRungeKuttaSolver.Ak)+(5 * n1));
71
+ }
72
+
73
+ return errorcode;
74
+ }
75
+
76
+ //=============================================================================
77
+
78
+ void rk5_close()
79
+ /*
80
+ ** Purpose:
81
+ ** Closes the RK5 solver.
82
+ */
83
+ {
84
+
85
+ #pragma omp parallel
86
+ {
87
+ if (MSXRungeKuttaSolver.Ynew) free(MSXRungeKuttaSolver.Ynew);
88
+ MSXRungeKuttaSolver.Ynew = NULL;
89
+ if (MSXRungeKuttaSolver.Ak) free(MSXRungeKuttaSolver.Ak);
90
+ MSXRungeKuttaSolver.Ak = NULL;
91
+ MSXRungeKuttaSolver.Nmax = 0;
92
+ MSXRungeKuttaSolver.Report = NULL;
93
+ }
94
+
95
+ }
96
+
97
+ //=============================================================================
98
+
99
+ int rk5_integrate(double y[], int n, double t, double tnext,
100
+ double* htry, double atol[], double rtol[],
101
+ void (*func)(double, double*, int, double*))
102
+ /*
103
+ ** Purpose:
104
+ ** Integrates system of equations dY/dt = F(t,Y) over a
105
+ ** given interval.
106
+ **
107
+ ** Input:
108
+ ** y[] = values of dependent variables at start of interval
109
+ ** n = number of dependent variables
110
+ ** t = value of independent variable at start of interval
111
+ ** tnext = value of independent variable at end of interval
112
+ ** htry = initial step size
113
+ ** atol[] = absolute error tolerance on each dependent variable
114
+ ** rtol[] = relative error tolerance on each dependent variable
115
+ ** func = pointer to function that evaluates dY/dt at given
116
+ ** values of t and Y.
117
+ **
118
+ ** Output:
119
+ ** y[] = values of dependent variables at end of interval
120
+ ** htry = last step size used
121
+ **
122
+ ** Returns:
123
+ ** number of function evaluations if successful, -1 if not
124
+ ** successful within Itmax iterations or -2 if step size
125
+ ** shrinks to 0.
126
+ */
127
+ {
128
+ double c2=0.20, c3=0.30, c4=0.80, c5=8.0/9.0;
129
+ double a21=0.20, a31=3.0/40.0, a32=9.0/40.0,
130
+ a41=44.0/45.0, a42=-56.0/15.0, a43=32.0/9.0,
131
+ a51=19372.0/6561.0, a52=-25360.0/2187.0, a53=64448.0/6561.0,
132
+ a54=-212.0/729.0, a61=9017.0/3168.0, a62=-355.0/33.0,
133
+ a63=46732.0/5247.0, a64=49.0/176.0, a65=-5103.0/18656.0,
134
+ a71=35.0/384.0, a73=500.0/1113.0, a74=125.0/192.0,
135
+ a75=-2187.0/6784.0, a76=11.0/84.0;
136
+ double e1=71.0/57600.0, e3=-71.0/16695.0, e4=71.0/1920.0,
137
+ e5=-17253.0/339200.0, e6=22.0/525.0, e7=-1.0/40.0;
138
+
139
+ double tnew, h, hmax, hnew, ytol, err, sk, fac, fac11 = 1.0;
140
+ int i;
141
+
142
+ // --- parameters for step size control
143
+
144
+ double UROUND = 2.3e-16;
145
+ double SAFE = 0.90;
146
+ double fac1 = 0.2;
147
+ double fac2 = 10.0;
148
+ double beta = 0.04;
149
+ double facold = 1.e-4;
150
+ double expo1 = 0.2 - beta*0.75;
151
+ double facc1 = 1.0/fac1;
152
+ double facc2 = 1.0/fac2;
153
+
154
+ // --- various counters
155
+
156
+ int nstep = 1;
157
+ int nfcn = 0;
158
+ int naccpt = 0;
159
+ int nrejct = 0;
160
+ int reject = 0;
161
+ int adjust = MSXRungeKuttaSolver.Adjust;
162
+
163
+ // --- initial function evaluation
164
+
165
+ func(t, y, n, MSXRungeKuttaSolver.K1);
166
+ nfcn++;
167
+
168
+ // --- initial step size
169
+ h = *htry;
170
+ hmax = tnext - t;
171
+ if (h == 0.0)
172
+ {
173
+ adjust = 1;
174
+ h = tnext - t;
175
+ for (i=1; i<=n; i++)
176
+ {
177
+ ytol = atol[i] + rtol[i]*fabs(y[i]);
178
+ if (MSXRungeKuttaSolver.K1[i] != 0.0)
179
+ h = fmin(h, (ytol/fabs(MSXRungeKuttaSolver.K1[i])));
180
+ }
181
+ }
182
+ h = fmax(1.e-8, h);
183
+
184
+ // --- while not at end of time interval
185
+
186
+ while (t < tnext)
187
+ {
188
+ // --- check for zero step size
189
+ if (0.10*fabs(h) <= fabs(t)*UROUND) return -2;
190
+
191
+ // --- adjust step size if interval exceeded
192
+ if ((t + 1.01*h - tnext) > 0.0) h = tnext - t;
193
+
194
+ tnew = t + c2*h;
195
+ for (i=1; i<=n; i++)
196
+ MSXRungeKuttaSolver.Ynew[i] = y[i] + h*a21* MSXRungeKuttaSolver.K1[i];
197
+ func(tnew, MSXRungeKuttaSolver.Ynew, n, MSXRungeKuttaSolver.K2);
198
+
199
+ tnew = t + c3*h;
200
+ for (i=1; i<=n; i++)
201
+ MSXRungeKuttaSolver.Ynew[i] = y[i] + h*(a31* MSXRungeKuttaSolver.K1[i] + a32* MSXRungeKuttaSolver.K2[i]);
202
+ func(tnew, MSXRungeKuttaSolver.Ynew, n, MSXRungeKuttaSolver.K3);
203
+
204
+ tnew = t + c4*h;
205
+ for (i=1; i<=n; i++)
206
+ MSXRungeKuttaSolver.Ynew[i]=y[i] + h*(a41* MSXRungeKuttaSolver.K1[i] + a42* MSXRungeKuttaSolver.K2[i] + a43* MSXRungeKuttaSolver.K3[i]);
207
+ func(tnew, MSXRungeKuttaSolver.Ynew, n, MSXRungeKuttaSolver.K4);
208
+
209
+ tnew = t + c5*h;
210
+ for (i=1; i<=n; i++)
211
+ MSXRungeKuttaSolver.Ynew[i] = y[i] + h*(a51* MSXRungeKuttaSolver.K1[i] + a52* MSXRungeKuttaSolver.K2[i] + a53* MSXRungeKuttaSolver.K3[i]+a54* MSXRungeKuttaSolver.K4[i]);
212
+ func(tnew, MSXRungeKuttaSolver.Ynew, n, MSXRungeKuttaSolver.K5);
213
+
214
+ tnew = t + h;
215
+ for (i=1; i<=n; i++)
216
+ MSXRungeKuttaSolver.Ynew[i] = y[i] + h*(a61* MSXRungeKuttaSolver.K1[i] + a62* MSXRungeKuttaSolver.K2[i] +
217
+ a63* MSXRungeKuttaSolver.K3[i] + a64* MSXRungeKuttaSolver.K4[i] + a65* MSXRungeKuttaSolver.K5[i]);
218
+ func(tnew, MSXRungeKuttaSolver.Ynew, n, MSXRungeKuttaSolver.K6);
219
+
220
+ for (i=1; i<=n; i++)
221
+ MSXRungeKuttaSolver.Ynew[i] = y[i] + h*(a71* MSXRungeKuttaSolver.K1[i] + a73* MSXRungeKuttaSolver.K3[i] +
222
+ a74* MSXRungeKuttaSolver.K4[i] + a75* MSXRungeKuttaSolver.K5[i] + a76* MSXRungeKuttaSolver.K6[i]);
223
+ func(tnew, MSXRungeKuttaSolver.Ynew, n, MSXRungeKuttaSolver.K2);
224
+ nfcn += 6;
225
+
226
+ // --- step size adjustment
227
+
228
+ err = 0.0;
229
+ hnew = h;
230
+ if (adjust)
231
+ {
232
+ for (i=1; i<=n; i++)
233
+ MSXRungeKuttaSolver.K4[i] = (e1* MSXRungeKuttaSolver.K1[i] + e3* MSXRungeKuttaSolver.K3[i] + e4* MSXRungeKuttaSolver.K4[i] + e5* MSXRungeKuttaSolver.K5[i] +
234
+ e6* MSXRungeKuttaSolver.K6[i] + e7* MSXRungeKuttaSolver.K2[i])*h;
235
+
236
+ for (i=1; i<=n; i++)
237
+ {
238
+ sk = atol[i] + rtol[i]*fmax(fabs(y[i]), fabs(MSXRungeKuttaSolver.Ynew[i]));
239
+ sk = MSXRungeKuttaSolver.K4[i]/sk;
240
+ err = err + (sk*sk);
241
+ }
242
+ err = sqrt(err/n);
243
+
244
+ // --- computation of hnew
245
+ fac11 = pow(err, expo1);
246
+ fac = fac11/pow(facold, beta); // LUND-stabilization
247
+ fac = fmax(facc2, fmin(facc1, (fac/SAFE))); // must have FAC1 <= HNEW/H <= FAC2
248
+ hnew = h/fac;
249
+ }
250
+
251
+ // --- step is accepted
252
+
253
+ if( err <= 1.0 )
254
+ {
255
+ facold = fmax(err, 1.0e-4);
256
+ naccpt++;
257
+ for (i=1; i<=n; i++)
258
+ {
259
+ MSXRungeKuttaSolver.K1[i] = MSXRungeKuttaSolver.K2[i];
260
+ y[i] = MSXRungeKuttaSolver.Ynew[i];
261
+ }
262
+ t = t + h;
263
+ if ( adjust && t <= tnext ) *htry = h;
264
+ if (fabs(hnew) > hmax) hnew = hmax;
265
+ if (reject) hnew = fmin(fabs(hnew), fabs(h));
266
+ reject = 0;
267
+ if (MSXRungeKuttaSolver.Report) MSXRungeKuttaSolver.Report(t, y, n);
268
+ }
269
+
270
+ // --- step is rejected
271
+
272
+ else
273
+ {
274
+ if ( adjust ) hnew = h/fmin(facc1, (fac11/SAFE));
275
+ reject = 1;
276
+ if (naccpt >= 1) nrejct++;
277
+ }
278
+
279
+ // --- take another step
280
+
281
+ h = hnew;
282
+ if ( adjust ) *htry = h;
283
+ nstep++;
284
+ if (nstep >= MSXRungeKuttaSolver.Itmax) return -1;
285
+ }
286
+ return nfcn;
287
+ }
epanet-msx-src/rk5.h ADDED
@@ -0,0 +1,39 @@
1
+ /************************************************************************
2
+ ** MODULE: RK5.H
3
+ ** PROJECT: EPANET-MSX
4
+ ** DESCRIPTION: Header file for the ODE solver contained in RK5.C.
5
+ ** AUTHOR: L. Rossman, US EPA - NRMRL
6
+ ** VERSION: 2.0.00
7
+ ** LAST UPDATE: 04/14/2021
8
+ ***********************************************************************/
9
+
10
+ #ifndef RK5_H
11
+ #define RK5_H
12
+
13
+ typedef struct
14
+ {
15
+ int Nmax; // max. number of equations
16
+ int Itmax; // max. number of integration steps
17
+ int Adjust; // use adjustable step size
18
+ double* Ak; // work arrays
19
+ double* K1;
20
+ double* K2;
21
+ double* K3;
22
+ double* K4;
23
+ double* K5;
24
+ double* K6;
25
+ double* Ynew; // updated solution
26
+ void (*Report) (double, double*, int);
27
+ }MSXRungeKutta;
28
+ // Opens the ODE solver system
29
+ int rk5_open(int n, int itmax, int adjust);
30
+
31
+ // Closes the ODE solver system
32
+ void rk5_close(void);
33
+
34
+ // Applies the solver to integrate a specific system of ODEs
35
+ int rk5_integrate(double y[], int n, double t, double tnext,
36
+ double* htry, double atol[], double rtol[],
37
+ void (*func)(double, double*, int, double*));
38
+
39
+ #endif