Next: , Previous: , Up: odepack   [Contents][Index]

77.1.1 Getting Started with ODEPACK

Of the eight variants of the solver, Maxima currently only has an interface to dlsode.

Let’s say we have this system of equations to solve:

  f1 = -.04d0*y1 + 1d4*y2*y3
  f3 = 3d7*y2*y2
  dy1/dt = f1
  dy2/dt = -f1 - f3
  dy3/dt = f3

The independent variable is \(t\); the dependent variables are \(y1\), \(y2\), and \(y3\),

To start the solution, set up the differential equations to solved:

load("dlsode");
f1: -.04d0*y1 + 1d4*y2*y3$
f3: 3d7*y2*y2$
f2: -f1 - f3$
fex: [f1, f2, f3];

Initialize the solver, where we have selected method 21:

(%i6) state : dlsode_init(fex, ['t,y1,y2,y3], 21);
(%o6) [[f, #<Function "LAMBDA ($T $Y1 $Y2 $Y3)" {49DAC061}>], 
[vars, [t, y1, y2, y3]], [mf, 21], [neq, 3], [lrw, 58], [liw, 23], [rwork, {Li\
sp Array: #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
               0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
               0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
               0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)}], 
[iwork, {Lisp Array: #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)}], 
[fjac, #<Function "LAMBDA ($T $Y1 $Y2 $Y3)" {49D52AC9}>]]

The arrays rwork and iwork carry state between calls to dlsode_step, so they should not be modified by the user. In fact, this state should not be modified by the user at all.

Now that the algorithm has been initialized we can compute solutions to the differential equation, using the state returned above.

For this example, we want to compute the solution at times 0.4*10^k for \(k\) from 0 to 11, with the initial values of 1, 0, 0 for the dependent variables and with a relative tolerance of 1d-4 and absolute tolerances of 1e-6, 1e-10, and 1d-6 for the dependent variables.

Then

y: [1d0, 0d0, 0d0];
t: 0d0;
rtol : 1d-4;
atol: [1d-6, 1d-10, 1d-6];
istate: 1;
t:0d0;
tout:.4d0;

for k : 1 thru 12 do
  block([],
    result: dlsode_step(y, t, tout, rtol, atol, istate, state),
    printf(true, "At t = ~12,4,2e   y = ~{~14,6,2e~}~%", result[1], result[2]),
    istate : result[3],
    tout : tout * 10);

This produces the output:

At t =   4.0000e-01   y =   9.851726e-01  3.386406e-05  1.479357e-02
At t =   4.0000e+00   y =   9.055142e-01  2.240418e-05  9.446344e-02
At t =   4.0000e+01   y =   7.158050e-01  9.184616e-06  2.841858e-01
At t =   4.0000e+02   y =   4.504846e-01  3.222434e-06  5.495122e-01
At t =   4.0000e+03   y =   1.831701e-01  8.940379e-07  8.168290e-01
At t =   4.0000e+04   y =   3.897016e-02  1.621193e-07  9.610297e-01
At t =   4.0000e+05   y =   4.935213e-03  1.983756e-08  9.950648e-01
At t =   4.0000e+06   y =   5.159269e-04  2.064759e-09  9.994841e-01
At t =   4.0000e+07   y =   5.306413e-05  2.122677e-10  9.999469e-01
At t =   4.0000e+08   y =   5.494530e-06  2.197824e-11  9.999945e-01
At t =   4.0000e+09   y =   5.129458e-07  2.051784e-12  9.999995e-01
At t =   4.0000e+10   y =  -7.170563e-08 -2.868225e-13  1.000000e+00

Next: , Previous: , Up: odepack   [Contents][Index]

JavaScript license information