Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

leapfrog.C

Go to the documentation of this file.
00001 
00012 
00013 #include "dyn.h"
00014 
00015 #ifdef TOOLBOX
00016 
00017 local void predict_step(dyn * b,          // n-body system pointer
00018                         real dt)          // timestep
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,          // n-body system pointer
00032                         real dt)          // timestep
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,        // time                         
00045                 dyn* b,         // dyn array                   
00046                 real dt,        // time step of the integration 
00047                 real eps)       // softening length             
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,        // time                         
00057                   dyn* b,         // dyn array                   
00058                   real delta_t,   // time span of the integration 
00059                   real dt,        // (fixed) integration time step
00060                   real dt_out,    // output time interval
00061                   real dt_snap,   // snapshot output interval
00062                   real eps,       // softening length             
00063                   int x_flag)     // exact-time termination flag
00064 {
00065     real t_end = t + delta_t;      // final time, at the end of the integration
00066     real t_out = t + dt_out;       // time of next diagnostic output
00067     real t_snap = t + dt_snap;     // time of next snapshot;
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         // Check for (trivial) output to cerr.
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         // Output a snapshot to cout at the scheduled time, or at end of run.
00100 
00101         if (termination_flag == 1) {
00102             put_node(cout, *b);
00103             cout << flush;
00104             break;                          // end the run
00105         }
00106 
00107         if (t >= t_snap) {
00108             put_node(cout, *b);             // do not synchronize all particles
00109             cout << flush;
00110             t_snap += dt_snap;              // and continue the run
00111         }
00112     }
00113 }
00114 
00115 main(int argc, char **argv)
00116 {
00117     dyn* b;              // pointer to the nbody system
00118     real  t = 0;         // time
00119 
00120     real  delta_t = 1;   // time span of the integration
00121     real  dt_out = .25;  // output time interval
00122     real  dt = 0.02;     // time step of the integration
00123     real  dt_snap;       // snap output interval
00124     real  eps = 0.05;    // softening length               
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;   // if true: termination at the exact time of
00135                             //          of the final output, by
00136                             //          adjustment of the last time step;
00137                             // if false: no adjustment of the last time step,
00138                             //           as a consequence the time of final
00139                             //           output might be slightly later than
00140                             //           the time specified.
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         // Check input arguments and echo defaults.
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

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