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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use libc::{c_double, c_int};
use std::slice;
use libffi::high::ClosureMut4;
#[link(name = "gfortran")]
extern {
pub fn dlsode_(f: extern fn(*const c_int, *const c_double, *mut c_double, *mut c_double),
neq: &c_int,
y: *mut c_double,
t: &mut c_double,
tout: &c_double,
itol: &c_int,
rtol: &c_double,
atol: &c_double,
itask: &c_int,
istate: &mut c_int,
iopt: &c_int,
rwork: *mut c_double,
lrw: &c_int,
iwork: *mut c_int,
liw: &c_int,
jac: extern fn(&mut c_int,&mut c_double,&mut c_double,&mut c_int,&mut c_int,&mut c_double,&mut c_int),
mf: &c_int
);
}
pub extern fn fake_jacobian(
_x1: &mut c_int,
_x2: &mut c_double,
_x3: &mut c_double,
_x4: &mut c_int,
_x5: &mut c_int,
_x6: &mut c_double,
_x7: &mut c_int,
) {
}
pub fn solve_ode(
rhs: fn(&[f64], &f64) -> Vec<f64>,
y0: &[f64],
t_dense: Vec<f64>,
atol: f64,
rtol :f64,
) -> Vec<Vec<f64>> {
let mut f = | n: *const c_int, t: *const c_double, y_ptr: *mut c_double, dy_ptr: *mut c_double | {
let dy = unsafe { slice::from_raw_parts_mut(dy_ptr, n as usize) };
let y = unsafe { slice::from_raw_parts(y_ptr, n as usize) };
let dy_new = unsafe {rhs(y, &*t) };
for (i, deriv) in dy_new.iter().enumerate() {
dy[i] = *deriv
}
};
let closure = ClosureMut4::new(&mut f);
let call = closure.code_ptr();
let mut y: Vec<f64> = y0.to_vec();
let n = y0.len();
let mut t = t_dense[0];
let itol = 1;
let itask = 1;
let iopt = 0;
let mut istate = 1;
let mf = 22;
let lrw = 22 + 9*n + n*n;
let liw = 20 + n;
let mut rwork: Vec<f64> = (0..lrw).map(|_i| 0.0 as c_double).collect();
let mut iwork: Vec<i32> = (0..liw).map(|_i| 0 as c_int).collect();
let mut result = Vec::new();
for tout in t_dense {
unsafe { dlsode_(
*call,
&(n as i32),
y.as_mut_ptr(),
&mut t,
&tout,
&itol,
&rtol,
&atol,
&itask,
&mut istate,
&iopt,
rwork.as_mut_ptr(),
&(lrw as i32),
iwork.as_mut_ptr(),
&(liw as i32),
fake_jacobian,
&mf
); }
result.push(y.clone());
}
result
}