forked from N-BodyShop/gasoline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrunge.c
83 lines (73 loc) · 1.91 KB
/
runge.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <math.h>
#include <assert.h>
#include "runge.h"
#define MAXDEP 10
/*
* Make one R-K step
*/
void
RungeStep(void *CTX, /* context for extra parameters */
/* derivative function takes independent and array of
dependent variables, last argument is returned derivates */
void (*deriv)(void *, double, double *, double*),
int nDep, /* number of dependent variables */
double t, /* independent variable */
double *xin, /* array of input */
double *xout, /* array of output */
double dDelta) /* step size */
{
double k1[MAXDEP];
double k2[MAXDEP];
double k3[MAXDEP];
double k4[MAXDEP];
double xtemp[MAXDEP];
const double onesixth = 1.0/6.0;
const double onethird = 1.0/3.0;
int i;
assert(nDep <= MAXDEP);
deriv(CTX, t, xin, k1);
for(i = 0; i < nDep; i++) {
k1[i] *= dDelta;
xtemp[i] = xin[i] + 0.5*k1[i];
}
deriv(CTX, t + 0.5*dDelta, xtemp, k2);
for(i = 0; i < nDep; i++) {
k2[i] *= dDelta;
xtemp[i] = xin[i] + 0.5*k2[i];
}
deriv(CTX, t + 0.5*dDelta, xtemp, k3);
for(i = 0; i < nDep; i++) {
k3[i] *= dDelta;
xtemp[i] = xin[i] + k3[i];
}
deriv(CTX, t + dDelta, xtemp, k4);
for(i = 0; i < nDep; i++) {
k4[i] *= dDelta;
xout[i] = xin[i] + onesixth*(k1[i] + k4[i]) + onethird*(k2[i] + k3[i]);
}
}
void
RungeKutta(void *CTX,
void (*deriv)(void *, double, double *, double*),
int nDep, /* number of dependent variables */
double tin, /* independent variable */
double *xin, /* array of input */
double tout,
double *xout, /* array of output */
int nSteps)
{
double dDelta = (tout - tin)/nSteps;
int i;
double xtemp[MAXDEP];
assert(nDep <= MAXDEP);
for(i = 0; i < nDep; i++) {
xtemp[i] = xin[i];
}
for(i = 0; i < nSteps; i++) {
RungeStep(CTX, deriv, nDep, tin, xtemp, xtemp, dDelta);
tin += dDelta;
}
for(i = 0; i < nDep; i++) {
xout[i] = xtemp[i];
}
}