Our task is to install the vector field defined by the equations
86#86
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 DsTool directory and copy the file GENERIC.c to the file userduffing_def.c. Use any text editor to edit userduffing_def.c.
The segment of code which defines the equations of motion (Equation )
will be called userduffing(). This function is defined as follows:
/* ------------------------------------------------------------------------ function used to define the vector field ------------------------------------------------------------------------ */ int userduffing(f,x,p) double *f,*x,*p; { 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 by writing the function userduffing_jac():
/* ------------------------------------------------------------------------ function used to define the Jacobian ------------------------------------------------------------------------ */ int userduffing_jac(m,x,p) double **m, *x, *p; { 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 userduffing_dfdt(f,x,p) double *f, *x, *p; { f[0] = 0.0; f[1] = -p[1] * p[2] * sin( p[2] * x[2] ); }
Since our vector field is Hamiltonian for
87#87,
we choose
/* ------------------------------------------------------------------------ function used to define aux functions of the varbs, time, or params ------------------------------------------------------------------------ */ int userduffing_aux(f,x,p) double *f,*x,*p; { double temp; 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 userduffing_init(). We choose [-2, 2] as default plotting ranges for both u and v. Initializing the variables is straightforward:
int userduffing_init() { /* ------------ define the dynamical system in this segment --------------- */ 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 91#91:
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:
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:
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 userduffing_init() with the code segment:
int mapping_toggle=FALSE; /* this is a map? TRUE or FALSE */ 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)()=userduffing; /* the eqns of motion */ int (*jac_name)()=userduffing_jac; /* the jacobian (deriv w.r.t. space) */ int (*aux_func_name)()=userduffing_aux; /* the auxiliary functions */ int (*inv_name)()=NULL; /* the inverse or approx inverse */ int (*dfdt_name)()=userduffing_dfdt; /* the deriv w.r.t time */ int (*dfdparam_name)()=NULL; /* the derivs w.r.t. parameters */
As in Section , we now need to edit two other files.
We edit Makefile and add userduffing_def.c
to the USER_SRCS list, and add userduffing_def.o to the
USER_OBJS list. We also edit the file
user.c and add the lines
extern int userduffing_init();and
{0, "Duffing's Eqns", userduffing_init},to the second and third blocks of code, respectively.
Typing make will create a local executable of DsTool which includes Duffing's equations among its installed dynamical systems.