00001
00012
00013 #include "dyn.h"
00014
00015 #ifdef TOOLBOX
00016
00017 local void predict_step(dyn * b,
00018 real dt)
00019 {
00020 if (b->get_oldest_daughter() !=NULL) {
00021 for (dyn * bb = b->get_oldest_daughter(); bb != NULL;
00022 bb = bb->get_younger_sister()) {
00023 predict_step(bb, dt);
00024 }
00025 } else {
00026 b->inc_vel( 0.5 * dt * b->get_acc() );
00027 b->inc_pos( dt * b->get_vel() );
00028 }
00029 }
00030
00031 local void correct_step(dyn * b,
00032 real dt)
00033 {
00034 if (b->get_oldest_daughter() !=NULL) {
00035 for (dyn * bb = b->get_oldest_daughter(); bb != NULL;
00036 bb = bb->get_younger_sister()) {
00037 correct_step(bb,dt);
00038 }
00039 } else {
00040 b->inc_vel( 0.5 * dt * b->get_acc() );
00041 }
00042 }
00043
00044 local void step(real& t,
00045 dyn* b,
00046 real dt,
00047 real eps)
00048 {
00049 t += dt;
00050
00051 predict_step(b, dt);
00052 b->calculate_acceleration(b, eps*eps);
00053 correct_step(b, dt);
00054 }
00055
00056 local void evolve(real& t,
00057 dyn* b,
00058 real delta_t,
00059 real dt,
00060 real dt_out,
00061 real dt_snap,
00062 real eps,
00063 int x_flag)
00064 {
00065 real t_end = t + delta_t;
00066 real t_out = t + dt_out;
00067 real t_snap = t + dt_snap;
00068 int steps = 0;
00069
00070
00071 b->calculate_acceleration(b, eps*eps);
00072
00073 print_recalculated_energies(b, 0, eps*eps, 0);
00074
00075 while (t < t_end) {
00076
00077 int termination_flag;
00078
00079 if (t + dt < t_end)
00080 termination_flag = 0;
00081 else
00082 {
00083 termination_flag = 1;
00084 if (x_flag)
00085 dt = t_end - t;
00086 }
00087
00088 step(t, b, dt, eps);
00089 steps++;
00090
00091
00092
00093 if (t >= t_out) {
00094 cerr << "Time = " << t << " steps = " << steps << endl;
00095 print_recalculated_energies(b, 1, eps*eps, 0);
00096 t_out += dt_out;
00097 }
00098
00099
00100
00101 if (termination_flag == 1) {
00102 put_node(cout, *b);
00103 cout << flush;
00104 break;
00105 }
00106
00107 if (t >= t_snap) {
00108 put_node(cout, *b);
00109 cout << flush;
00110 t_snap += dt_snap;
00111 }
00112 }
00113 }
00114
00115 main(int argc, char **argv)
00116 {
00117 dyn* b;
00118 real t = 0;
00119
00120 real delta_t = 1;
00121 real dt_out = .25;
00122 real dt = 0.02;
00123 real dt_snap;
00124 real eps = 0.05;
00125 char *comment;
00126
00127 bool a_flag = FALSE;
00128 bool c_flag = FALSE;
00129 bool d_flag = FALSE;
00130 bool D_flag = FALSE;
00131 bool e_flag = FALSE;
00132 bool q_flag = FALSE;
00133 bool t_flag = FALSE;
00134 bool x_flag = FALSE;
00135
00136
00137
00138
00139
00140
00141
00142 check_help();
00143
00144 extern char *poptarg;
00145 int c;
00146 char* param_string = "a:c:d:D:e:qt:x";
00147
00148 while ((c = pgetopt(argc, argv, param_string)) != -1)
00149 switch(c)
00150 {
00151 case 'a': a_flag = TRUE;
00152 dt = atof(poptarg);
00153 break;
00154 case 'c': c_flag = TRUE;
00155 comment = poptarg;
00156 break;
00157 case 'd': d_flag = TRUE;
00158 dt_out = atof(poptarg);
00159 break;
00160 case 'D': D_flag = TRUE;
00161 dt_snap = atof(poptarg);
00162 break;
00163 case 'e': e_flag = TRUE;
00164 eps = atof(poptarg);
00165 break;
00166 case 'q': q_flag = TRUE;
00167 break;
00168 case 't': t_flag = TRUE;
00169 delta_t = atof(poptarg);
00170 break;
00171 case 'x': x_flag = TRUE;
00172 break;
00173 case '?': params_to_usage(cerr, argv[0], param_string);
00174 get_help();
00175 exit(1);
00176 }
00177
00178 if (!q_flag) {
00179
00180
00181
00182 if (!t_flag) cerr << "default delta_t = " << delta_t << "\n";
00183 if (!a_flag) cerr << "default dt = " << dt << "\n";
00184 if (!d_flag) cerr << "default dt_out = " << dt_out << "\n";
00185 if (!e_flag) cerr << "default eps = " << eps << "\n";
00186 if (!x_flag) cerr << "default termination: not at exact t_end" << "\n";
00187 }
00188
00189 if (!D_flag) dt_snap = delta_t;
00190
00191 b = get_dyn(cin);
00192
00193 if (c_flag == TRUE) b->log_comment(comment);
00194 b->log_history(argc, argv);
00195
00196 evolve(t, b, delta_t, dt, dt_out, dt_snap, eps, x_flag);
00197 rmtree(b);
00198 }
00199
00200 #endif