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 },
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
/* ------------------------------------------------------------------------ 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.