Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

demo.c

Go to the documentation of this file.
00001 
00002 /* Duffing oscillator in ONE dimension -- Leapfrog integrator. */
00003 
00004 #include <stdio.h>
00005 #include <math.h>
00006 
00007 /*======================================================================*/
00008 
00009 /* Global constants: */
00010 
00011 static double ALPHA = 0.1;      /* Damping */
00012 static double BETA = 0.0;
00013 
00014 static double AMPL = 9.8;       /* Forcing amplitude */
00015 static double OMEGA_D = 1.0;    /* Forcing frequency */
00016 static double PHASE = 0.0;      /* Forcing phase */
00017 
00018 
00019 /* Define accelerations and potential (1-D ONLY).
00020    Allow t as an argument in case of time-dependent forces. */
00021 
00022 double accx_cons(double x, double v, double t)
00023 {
00024     return -x*x*x + AMPL*cos(OMEGA_D*t + PHASE);
00025 }
00026 
00027 double accx_diss(double x, double v, double t)
00028 {
00029     return -v * (ALPHA + BETA * abs(v));
00030 }
00031 
00032 double accx(double x, double v, double t)
00033 {
00034     return accx_cons(x, v, t) + accx_diss(x, v, t);
00035 }
00036 
00037 double potential(double x)      /* Must be CONSISTENT with accx_cons()! */
00038 {
00039     return -0.25*x*x*x*x;
00040 }
00041 
00042 /*======================================================================*/
00043 
00044 /* Take a single time step, NEGLECTING the work integral (for now). */
00045 
00046 static int init = 0;    /* Initialization flag. */
00047 
00048 void step(double* t, double* x, double* v, double* w, double dt)
00049 {
00050     double vv;
00051 
00052     if (init == 0) {
00053 
00054         /* Offset the velocity by half a step the first time through. */
00055 
00056         *v += 0.5*dt*accx(*x, *v, *t);
00057         init = 1;
00058     }
00059 
00060     /* Update all quantities using the Leapfrog scheme. */
00061 
00062     *x += (*v)*dt;
00063     *t += dt;
00064 
00065     /* Temporarily synchronize v with x (call it vv) for use with accx. */
00066 
00067     vv = *v + 0.5*dt*accx(*x, *v, *t);
00068     *v += accx(*x, vv, *t)*dt;
00069 }
00070 
00071 double energy(double x, double v, double t, double dt)
00072 {
00073     /* Must synchronize v in this case (==> dt and t needed)... */
00074 
00075     v -= -0.5*dt*accx(x, v, t);         /* (Using a local copy of v, note.) */
00076 
00077     return 0.5*v*v + potential(x);
00078 }
00079 
00080 /*======================================================================*/
00081 
00082 double interp(double t0, double t1, double x0, double x1, double t)
00083 {
00084     /* Linearly interpolate x to its value at time t */
00085 
00086     return x0 + (x1 - x0) * (t - t0) / (t1 - t0);
00087 }
00088 
00089 main()
00090 {
00091     /* Declare and initialize variables. */
00092 
00093     double x, v;
00094     double t, dt = 0.025, t_max = 500.0;
00095     char command[40] = "                    ";
00096     double w;
00097     char poincare = 0;
00098     double t_next;
00099     double t_start = 100.0;
00100     double x0 = 1.0, v0 = 0.0;
00101     char clear = 1;
00102 
00103     /* Use dialog boxes to set essential parameters. */
00104 
00105     create_double_dialog_entry("x0", &x0), set_dialog_width(16);
00106     create_double_dialog_entry("v0", &v0), set_dialog_width(16);
00107     create_double_dialog_entry("ALPHA", &ALPHA);
00108     create_double_dialog_entry("AMPL", &AMPL);
00109     create_double_dialog_entry("OMEGA_D", &OMEGA_D);
00110     create_double_dialog_entry("PHASE", &PHASE);
00111     create_double_dialog_entry("dt", &dt);
00112     create_double_dialog_entry("t_max", &t_max);
00113     create_double_dialog_entry("t_start", &t_start);
00114     create_button_dialog_entry("Poincare", &poincare);
00115     create_string_dialog_entry("command", command);
00116     create_button_dialog_entry("clear command", &clear);
00117 
00118     set_up_dialog("Duffing Oscillator", 0, 0);
00119 
00120     while (read_dialog_window()) {
00121 
00122         /* Output graphics control command(s), if any. */
00123 
00124         printf("%s\n", command);
00125 
00126         /* Treat "-e" as a special case */
00127 
00128         if (strcmp(command, "-e") && (!poincare || t_max > t_start)) {
00129 
00130             if (poincare) printf("-pp\n");
00131 
00132             /* Set initial conditions (start at rest at x = 0): */
00133 
00134             init = 0;
00135             t = 0.0;
00136             x = x0;
00137             if (AMPL == 0 && x == 0.0) x = 1.0;
00138             v = v0;
00139 
00140             t_next = 0.0;
00141 
00142             /* Note that w is never updated in this version of the program. */
00143 
00144             w = 0.0;
00145 
00146             /* Initial output */
00147 
00148             printf("%f %f %f\n", t, x, v);
00149 
00150             /* Calculate and print out the trajectory. */
00151 
00152             while (t < t_max) {
00153 
00154                 double t_last = t;
00155                 double x_last = x;
00156                 double v_last = v;
00157 
00158                 step(&t, &x, &v, &w, dt);
00159 
00160                 if (!poincare)
00161 
00162                     printf("%f %f %f\n", t, x, v);
00163 
00164                 else {
00165 
00166                     if (t > t_next) {
00167 
00168                         if (t >= t_start) 
00169                             printf("%f %f %f\n", t_next,
00170                                    interp(t_last, t, x_last, x, t_next),
00171                                    interp(t_last, t, v_last, v, t_next));
00172 
00173                         t_next += 2*M_PI/OMEGA_D;    /* Sample at the forcing
00174                                                         frequency */
00175 
00176                     }
00177                 }               
00178             }
00179 
00180             /* Signify end-of-data to force plot_data to plot the points. */
00181 
00182             printf("end of data\n");
00183         }
00184 
00185         fflush(stdout);
00186 
00187         if (clear) command[0] = '\0';
00188         reset_dialog_window();
00189 
00190     }
00191 }

Generated at Sun Feb 24 09:56:57 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001