next up previous contents
Next: A Few Remarks on Up: User-Defined Dynamical Systems Previous: Installing a Defined Dynamical   Contents


A Vector Field Example

In this section we present an example of installing a user-defined vector field into dstool. It is assumed that the reader is familiar with the material in Section 3.2.

Our task is to install the vector field defined by the equations
42#42
This system is known as Duffing's equations and we direct the reader to [1] and references therein for an exposition of the dynamics of this system.

To define and install this system, change to your local models directory and copy the file GENERIC.c to the file duffing_def.c. Use any text editor to edit duffing_def.c.

The segment of code which defines the equations of motion (Equation 3.5) will be called duffing(). This function is defined as follows:

/* ------------------------------------------------------------------------
   function used to define the vector field 
   ------------------------------------------------------------------------ */
int duffing(f,x,p)
double *f,*x,*p;
{
   double  cos();

   f[0] = x[1];
   f[1] = x[0] - x[0]*x[0]*x[0] - p[0]*x[1] - p[1]*cos( p[2]*x[2] );
}
Here we have defined the variables and parameters as x &=& { x[0], x[1] } = { u, v },
p &=& { p[0], p[1], p[2] } = { , , }. As usual, the independent variable is stored after the spatial variables so that x[2] is time. The function duffing() returns in the array f the strength of the vector field with parameters p, evaluated at the point x.

We now define the Jacobian of Equation 3.5 by writing the function duffing_jac():

/* ------------------------------------------------------------------------
   function used to define the Jacobian
   ------------------------------------------------------------------------ */
int duffing_jac(m,x,p)
double  **m, *x, *p;
{
   double    sin();

   m[0][0] = 0.0;
   m[0][1] = 1.0;
   m[1][0] = 1.0 - 3.0 * x[0] * x[0];
   m[1][1] = -p[0];
}

Since our equations are for a vector field, we do not need to define an inverse function. Our vector field is time-dependent, so we can define a function which returns the temporal derivatives of the vector field. This function is not yet used by dstool, and there is no template for such a function in GENERIC.c, but it is easy enough to write:

/* ------------------------------------------------------------------------
   function used to define temporal derivatives
   ------------------------------------------------------------------------ */
int duffing_dfdt(m,x,p)
double  *f, *x, *p;
{
   double    sin();

   f[0] = 0.0;
   f[1] = -p[1] * p[2] * sin( p[2] * x[2] ); 
}

Since our vector field is Hamiltonian for 43#43, we choose

44#44

as an auxiliary function. We will also define a second auxiliary function. Since our vector field is periodic in time (with period 45#45), it is a common technique to look at the time- 45#45 map in order to better understand the dynamics. This ``stroboscopic map'' can also be thought of as a Poincaré map for the extended phase space. We are thus interested in the times t for which 46#46. Choosing t0 = 0 we define the procedure duffing_aux() by
/* ------------------------------------------------------------------------
   function used to define aux functions of the varbs, time, or params
   ------------------------------------------------------------------------ */
int duffing_aux(f,x,p)
double *f,*x,*p;
{
   double   temp, sin();

   temp = 0.5 * x[0] * x[0];
   f[0] = 0.5 * x[1] * x[1] - temp + temp * temp;
   f[1] = sin( p[2] * x[2] );
}

We are now ready to define the labels and initial conditions for Duffing's equations by writing the function duffing_init(). We choose [-2, 2] as default plotting ranges for both u and v. Initializing the variables is straightforward:

int duffing_init()
{
/* ------------ define the dynamical system in this segment --------------- */

static int     n_varb=2;                  /* dim of phase space           */
static char    *variable_names[]={"u","v"}; /* list of phase varb names   */
static double  variables[]={0.5,0.5};     /* default varb initial values  */
static double  variable_min[]={-2.,-2.};  /* default varb min for display */
static double  variable_max[]={2.,2.};    /* default varb max for display */

static char    *indep_varb_name="time";   /* name of indep variable             */
static double  indep_varb_min=0.;         /* default indep varb min for display */
static double  indep_varb_max=1000;       /* default indep varb max for display */

Defining the parameter ranges is somewhat arbitrary. Sometimes it is difficult to tell a priori what range of parameters will provide interesting bifurcations. This is not a big problem since it is a trivial matter to change the range upon which a function (or parameter) is plotted once within dstool. We choose [0,1] as a range for each parameter. We choose 47#47:

static int    n_param=3;                  /* dim of parameter space        */
static char   *parameter_names[]={"delta","gamma", "w"}; /* list of param names */
static double parameters[]={0.25,0.4,1.}; /* initial parameter values      */
static double parameter_min[]={0.,0.,0.}; /* default param min for display */
static double parameter_max[]={1.,1.,1.}; /* default param max for display */

The initialization of our two auxiliary functions is accomplished by the code segment:

static int     n_funct=2;               /* number of user-defined functions */
static char    *funct_names[]={"H", "P_Section"}; /* list of funct names; {""} if none */
static double  funct_min[]={-4.,-1.};   /* default funct min for display    */
static double  funct_max[]={4.,1.};     /* default funct max for display    */
As in the case with parameters, it is sometimes difficult to choose a priori what appropriate ranges for the functions should be.

The manifold type for Duffing's equations is EUCLIDEAN since we do not have any periodic spatial variables. Thus we do not need to modify the following segment of code:

static int    manifold_type=EUCLIDEAN; /* EUCLIDEAN or PERIODIC                 */
static int    periodic_varb[]={FALSE, FALSE}; /* if PERIODIC, which varbs periodic? */
static double period_start[]={0.,0.};  /* if PERIODIC, begin fundamental domain */
static double period_end[]={1., 1.};   /* if PERIODIC, end of fundamental domain*/

The last segment of code we need to modify is the segment which tells dstool which numerical algorithms may be used on the Duffing's equations. We complete the definition of duffing_init() with the code segment

static int  mapping_toggle=FALSE;       /* this is a map? TRUE or FALSE         */
static int  inverse_toggle=FALSE;       /* if so, is inverse FALSE, APPROX_INV, */
                                        /* or EXPLICIT_INV? FALSE for vec field */ 

/*  In this section, input NULL or the name of the function which contains...   */
int     (*def_name)()=duffing;          /* the eqns of motion                   */
int     (*jac_name)()=duffing_jac;      /* the jacobian (deriv w.r.t. space)    */
int     (*aux_func_name)()=duffing_aux; /* the auxiliary functions              */
int     (*inv_name)()=NULL;             /* the inverse or approx inverse        */
int     (*dfdt_name)()=duffing_dfdt;    /* the deriv w.r.t time                 */
int     (*dfdparam_name)()=NULL;        /* the derivs w.r.t. parameters         */

As in Section 3.2, we now need to edit two other files found in the models directory. We edit Makefile and add duffing_def.c to the list of files to compile. We also edit the file modellib_ds_def.h and add the lines

extern int  duffing_init();
and
{1, "Duffing's Eqns", duffing_init},
to the second and third blocks of code, respectively.

Changing directories to your local dstool directory and typing make dstool_u will create a local executable of dstool which includes Duffing's equations among its installed dynamical systems.




next up previous contents
Next: A Few Remarks on Up: User-Defined Dynamical Systems Previous: Installing a Defined Dynamical   Contents
root
1998-11-02