The main driving routine produced by the -main flag of taylor is rather simple, it just keeps on integrating the system and print out the solution along the way. This may be enough for some tasks, but it is definitely too primitive for real applications. In this section, we provide two sample driving routines. These examples demonstrate what you need to do to write your own driving routes. The input files are provided in the doc subdirectory in the taylor distribution.
We first ask taylor to generate a integrator and a header file for us.
taylor -o lorenz.c -jet -step -name lorenz lorenz.eq1 taylor -o taylor.h -headerThe first command will produce a file
lorenz.c
with no driving routine in it. This file will be
compiled and linked with our main driving routine.
The second command generates the header file
taylor.h
. It is needed in lorenz.c
and
our main driving function.
Using the Supplied Integrator
Our first example is very similar to the driving routine generated by taylor. It uses the one step integrator provided by taylor.
/* save as main1.c */ #include <stdio.h> #include <math.h> #include "taylor.h" int main(int argc, char **argv) { MY_FLOAT xx[3], t; double h, abs_err, rel_err, h_return, log10abs_err; double log10rel_err, endtime; int nsteps = 100, step_ctrl_method = 2, direction = 1; int order = 10; /* set initial conditions */ xx[0] = 0.1; xx[1] = 0.2; xx[2] = 0.3; t = 0.0; /* control parameters */ h= 0.001; abs_err = 1.0e-16; rel_err = 1.0e-16; log10abs_err = log10(abs_err); log10rel_err = log10(rel_err); endtime = 10.0; /* integrate 100 steps */ while( -- nsteps > 0 && h_return != 0) { /* do something with xx and t. We just print it */ printf("%f %f %f %f\n", xx[0],xx[1],xx[2],t); taylor_step_lorenz(&t, &xx[0], direction, step_ctrl_method,log10abs_err, log10rel_err, &endtime, &h_return, &order); } }
After saving the code in main1.c
, you can compile
them using the command
gcc lorenz.c main1.c -lmand run the executable
a.out
as before.
Write Your Own Driver
This example provides a skeleton for writing your own one step integrator.
/* save as main2.c */ #include <stdio.h> #include <math.h> #include "taylor.h" MY_FLOAT **taylor_coefficients_lorenz(MY_FLOAT, MY_FLOAT *, int); int main(int argc, char **argv) { MY_FLOAT xx[3], tmp[3], t, **coef; int j, order=20, nsteps = 100; double step_size; /* set initiaial conditions */ xx[0] = 0.1; xx[1] = 0.2; xx[2] = 0.3; t = 0.0; /* control parameters */ step_size= 0.1; /* integrate 100 steps */ while( -- nsteps > 0) { /* do something with xx and t. We just print it */ printf("%f %f %f %f\n", xx[0], xx[1], xx[2], t); /* compute the taylor coefficients */ coef = taylor_coefficients_lorenz(t, xx, order); /* now we have the taylor coefficients in coef, * we can analyze them and choose a best step size. * Here we just integrate use the given stepsize. */ tmp[0] = tmp[1] = tmp[2] = 0.0; for(j=order; j>0; j--) /* sum up the taylor polynomial */ { tmp[0] = (tmp[0] + coef[0][j])* step_size; tmp[1] = (tmp[1] + coef[1][j])* step_size; tmp[2] = (tmp[2] + coef[2][j])* step_size; } /* advance one step */ xx[0] = xx[0] + tmp[0]; xx[1] = xx[1] + tmp[1]; xx[2] = xx[2] + tmp[2]; t += step_size; /* advance time */ } }