00001
00002
00003
00004 #include <stdio.h>
00005 #include <math.h>
00006
00007
00008
00009
00010
00011 static double ALPHA = 0.1;
00012 static double BETA = 0.0;
00013
00014 static double AMPL = 9.8;
00015 static double OMEGA_D = 1.0;
00016 static double PHASE = 0.0;
00017
00018
00019
00020
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)
00038 {
00039 return -0.25*x*x*x*x;
00040 }
00041
00042
00043
00044
00045
00046 static int init = 0;
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
00055
00056 *v += 0.5*dt*accx(*x, *v, *t);
00057 init = 1;
00058 }
00059
00060
00061
00062 *x += (*v)*dt;
00063 *t += dt;
00064
00065
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
00074
00075 v -= -0.5*dt*accx(x, v, t);
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
00085
00086 return x0 + (x1 - x0) * (t - t0) / (t1 - t0);
00087 }
00088
00089 main()
00090 {
00091
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
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", &L);
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
00123
00124 printf("%s\n", command);
00125
00126
00127
00128 if (strcmp(command, "-e") && (!poincare || t_max > t_start)) {
00129
00130 if (poincare) printf("-pp\n");
00131
00132
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
00143
00144 w = 0.0;
00145
00146
00147
00148 printf("%f %f %f\n", t, x, v);
00149
00150
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;
00174
00175
00176 }
00177 }
00178 }
00179
00180
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 }