Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

kira_log.C

Go to the documentation of this file.
00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00011 // Functions associated with log output, snapshots, etc.
00012 //
00013 // Externally visible functions:
00014 //
00015 //      void print_dstar_params
00016 //      bool print_dstar_stats
00017 //      void get_energies_with_external
00018 //      void print_statistics
00019 //      void update_cpu_counters
00020 //      void log_output
00021 //      void snap_output
00022 
00023 #include "hdyn.h"
00024 #include "star/dstar_to_kira.h"
00025 
00026 typedef  struct {
00027     real  dt;
00028     real  dt_a;
00029     hdyn*  b;
00030 } dt_pair, *dt_pair_ptr;
00031 
00032 local int compare_dt(const void * pi, const void * pj)    // increasing dt
00033 {
00034     if (((dt_pair_ptr) pi)->dt < ((dt_pair_ptr) pj)->dt)
00035         return -1;
00036     else if (((dt_pair_ptr)pi)->dt > ((dt_pair_ptr)pj)->dt)
00037         return +1;
00038     else
00039         return 0;
00040 }
00041 
00042 typedef  struct {
00043     real  count;
00044     hdyn*  b;
00045 } count_pair, *count_pair_ptr;
00046 
00047 local int compare_steps(const void * pi, const void * pj) // decreasing count
00048 {
00049     if (((count_pair_ptr) pi)->count > ((count_pair_ptr) pj)->count)
00050         return -1;
00051     else if (((count_pair_ptr)pi)->count < ((count_pair_ptr)pj)->count)
00052         return +1;
00053     else
00054         return 0;
00055 }
00056 
00057 int get_effective_block(real dt)
00058 {
00059     // For general timestep dt, find the effective block it is in, by
00060     // determining the smallest k for which the step can be written as
00061     //
00062     //          dt = n * 2^{-k}
00063     //
00064     // for integral n.
00065 
00066     int k = 0;
00067     real dtb = 1;
00068 
00069     while (fmod(dt, dtb) != 0 && k < 50) {
00070         k++;
00071         dtb /= 2;
00072     }
00073 
00074     return k;
00075 }
00076 
00077 #define NTOP 10
00078 #define NBOT 10
00079 
00080 local void print_timestep_stats(hdyn* b)
00081 {
00082     // Time step statistics.
00083 
00084     real dt_mean = 0, dt_min = VERY_LARGE_NUMBER, dt_max = -dt_min;
00085 
00086     real n_dt = 0;              // actually these are integer counters
00087     real n_dt_p = 0;
00088     real n_dt_u = 0;
00089     real total_steps = 0;
00090     real total_steps_a = 0;
00091     real total_steps_p = 0;
00092 
00093     // Timestep histograms:
00094 
00095     int count[30],              // all nodes, perturbed steps
00096         count_a[30],            // all nodes, actual steps
00097         count_p[30],            // all perturbed nodes
00098         count_u[30],            // all unperturbed nodes, unperturbed steps
00099         count_ue[30],           // all unperturbed nodes, effective blocks
00100         count_next[30];         // next_time distribution
00101 
00102     int i;
00103     for (i = 0; i < 30; i++)
00104         count[i] = count_a[i]
00105                  = count_p[i]
00106                  = count_u[i]
00107                  = count_ue[i]
00108                  = count_next[i]
00109                  = 0;
00110 
00111     // Count the total number of particles/nodes.
00112 
00113     int n = 0;
00114     for_all_nodes(hdyn, b, bb)  n++;
00115     n--;
00116 
00117     dt_pair_ptr list_dt  = new dt_pair[n];
00118     dt_pair_ptr list_dtb = new dt_pair[n];
00119 
00120     // Total timestep counters:
00121 
00122     count_pair_ptr steps_inst  = new count_pair[n];
00123     count_pair_ptr steps_delta = new count_pair[n];
00124     count_pair_ptr f_dir_delta = new count_pair[n];
00125     count_pair_ptr f_ind_delta = new count_pair[n];
00126 
00127     n = 0;
00128     int np = 0, nd = 0, ni = 0;
00129 
00130     real delta_steps_tot = 0;
00131     real delta_f_dir_tot = 0;
00132     real delta_f_ind_tot = 0;
00133 
00134     bool print_dtb = false;
00135 
00136     for_all_nodes(hdyn, b, bb)
00137         if (bb != b) {
00138 
00139             real dt = bb->get_timestep();
00140 
00141             // This dt is the timestep of a top-level or perturbed binary
00142             // node, and the perturbed timestep of an unperturbed binary.
00143 
00144             // Actual timestep:
00145 
00146             real dt_a = dt;
00147             if (bb->get_kepler())
00148                 dt_a = bb->get_unperturbed_timestep();
00149 
00150             // Don't include younger binary sisters in *any* statistic.
00151 
00152             if (bb->is_top_level_node() || bb->get_elder_sister() == NULL) {
00153 
00154                 // Basic stats (all steps):
00155 
00156                 dt_mean += dt_a;
00157                 dt_min = min(dt_min, dt_a);
00158                 dt_max = max(dt_max, dt_a);
00159 
00160                 n_dt += 1;
00161                 real steps = rint(1/dt);
00162                 real steps_a = rint(1/dt_a);
00163                 total_steps += steps;
00164                 total_steps_a += steps_a;
00165 
00166                 // Update perturbed_steps counters.
00167 
00168                 if (!bb->get_kepler()) {
00169 
00170                     list_dt[np].dt = dt;
00171                     list_dt[np].dt_a = dt;
00172                     list_dt[np].b = bb;
00173                     steps_inst[np].count = steps;
00174                     steps_inst[np].b = bb;
00175                     np++;
00176                 }
00177 
00178                 // 1. All perturbed steps, including unperturbed
00179                 //    binaries: count.
00180 
00181                 i = 0;
00182                 real dtbin = 1;
00183                 while (dt < dtbin) {
00184                     i++;
00185                     dtbin *= 0.5;
00186                 }
00187                 if (i > 29) i = 29;
00188                 count[i]++;
00189 
00190                 if (!bb->get_kepler()) {
00191 
00192                     // 2. Perturbed nodes only: count_p.
00193 
00194                     total_steps_p += steps;
00195                     n_dt_p += 1;
00196                     count_p[i]++;
00197 
00198                 }
00199 
00200                 // 3. All actual steps, including unperturbed
00201                 //    binaries: count_a.
00202 
00203                 i = 0;
00204                 dtbin = 1;
00205                 while (dt_a < dtbin) {
00206                     i++;
00207                     dtbin *= 0.5;
00208                 }
00209                 if (i > 29) i = 29;
00210                 count_a[i]++;
00211 
00212                 if (bb->get_kepler()) {
00213 
00214                     // 4a. Unperturbed nodes only, unperturbed steps: count_u.
00215 
00216                     n_dt_u += 1;
00217                     count_u[i]++;
00218 
00219                     // 4b. Unperturbed nodes only, effective blocks: count_ue.
00220 
00221                     int kb = get_effective_block(dt_a);
00222                     if (kb > 29) kb = 29;
00223                     count_ue[kb]++;
00224                 }
00225 
00226                 // 5. Next_time, all nodes, actual steps: count_next.
00227 
00228                 real dt_next = bb->get_next_time() - bb->get_system_time();
00229                 int kb = get_effective_block(dt_next);
00230                 real dtb = pow(2.0, -kb);
00231 
00232                 list_dtb[n].dt = -kb;
00233                 list_dtb[n].dt_a = dt_a;
00234                 list_dtb[n].b = bb;
00235 
00236                 if (bb->get_kepler() || dt_a != dtb) {
00237 
00238                     if (!print_dtb) {
00239                         cerr << endl << "  Actual and block timesteps:"
00240                              << endl;
00241                         print_dtb = true;
00242                     }
00243 
00244                     if (bb->get_kepler())
00245                         cerr << "    unperturbed ";
00246                     else
00247                         cerr << "    ***mismatch ";
00248 
00249                     cerr << bb->format_label() << ":  ";
00250                     PRC(kb), PRC(dt_a); PRL(dtb);
00251                 }
00252 
00253                 if (kb > 29) kb = 29;
00254                 count_next[kb]++;               // next_time
00255 
00256                 // Total timestep/force counters:
00257 
00258                 // Instantaneous:
00259 
00260                 steps_delta[n].count = bb->get_steps();
00261                 if (find_qmatch(bb->get_dyn_story(), "prev_steps"))
00262                     steps_delta[n].count -= getrq(bb->get_dyn_story(),
00263                                                   "prev_steps");
00264                 putrq(bb->get_dyn_story(), "prev_steps", bb->get_steps());
00265                 steps_delta[n].b = bb;
00266                 delta_steps_tot += steps_delta[n].count;
00267 
00268                 n++;
00269 
00270                 // Direct (top-level/GRAPE):
00271 
00272                 f_dir_delta[nd].count = bb->get_direct_force();
00273                 if (find_qmatch(bb->get_dyn_story(), "prev_f_dir"))
00274                     f_dir_delta[nd].count -= getrq(bb->get_dyn_story(),
00275                                                    "prev_f_dir");
00276                 putrq(bb->get_dyn_story(), "prev_f_dir",
00277                       bb->get_direct_force());
00278                 f_dir_delta[nd].b = bb;
00279                 delta_f_dir_tot += f_dir_delta[nd].count;
00280                 nd++;
00281 
00282                 // Indirect (low-level/front-end):
00283 
00284                 f_ind_delta[ni].count = bb->get_indirect_force();
00285                 if (find_qmatch(bb->get_dyn_story(), "prev_f_ind"))
00286                     f_ind_delta[ni].count -= getrq(bb->get_dyn_story(),
00287                                                    "prev_f_ind");
00288                 putrq(bb->get_dyn_story(), "prev_f_ind",
00289                       bb->get_indirect_force());
00290                 f_ind_delta[ni].b = bb;
00291                 delta_f_ind_tot += f_ind_delta[ni].count;
00292                 ni++;
00293             }
00294         }
00295 
00296     //
00297     //----------------------------------------------------------------------
00298     //
00299     // Print out the results:
00300 
00301     // First print the timestep histograms...
00302 
00303     cerr << endl << "  Timesteps (younger binary components excluded,"
00304          << endl << "             mean = " << dt_mean/max((int)rint(n_dt), 1)
00305          << "  min = " << dt_min << "  max = " << dt_max << "):"
00306          << endl;
00307 
00308     if (n_dt_u > 0)
00309         cerr << endl << "  all nodes (perturbed steps, bin #1 = 1, dt /= 2):"
00310              << endl << "        ";
00311     else
00312         cerr << endl << "  all nodes (actual steps, bin #1 = 1, dt /= 2):"
00313              << endl << "        ";
00314 
00315     for (i =  0; i < 10; i++) fprintf(stderr, " %5d", count[i]);
00316     cerr << endl << "        ";
00317     for (i = 10; i < 20; i++) fprintf(stderr, " %5d", count[i]);
00318     cerr << endl << "        ";
00319     for (i = 20; i < 30; i++) fprintf(stderr, " %5d", count[i]);
00320 
00321     cerr << endl << "  total = " << n_dt
00322          << ",  weighted timestep sum = "
00323          << total_steps/n_dt << endl;
00324 
00325     if (n_dt_u > 0) {
00326 
00327         cerr << endl << "  all nodes (actual steps):"
00328              << endl << "        ";
00329         for (i =  0; i < 10; i++) fprintf(stderr, " %5d", count_a[i]);
00330         cerr << endl << "        ";
00331         for (i = 10; i < 20; i++) fprintf(stderr, " %5d", count_a[i]);
00332         cerr << endl << "        ";
00333         for (i = 20; i < 30; i++) fprintf(stderr, " %5d", count_a[i]);
00334 
00335         cerr << endl << "  total = " << n_dt
00336              << ",  weighted timestep sum = "
00337              << total_steps_a/n_dt << endl;
00338 
00339         if (n_dt_p > 0) {
00340             cerr << endl << "  excluding unperturbed systems:"
00341                  << endl << "        ";
00342             for (i =  0; i < 10; i++) fprintf(stderr, " %5d", count_p[i]);
00343             cerr << endl << "        ";
00344             for (i = 10; i < 20; i++) fprintf(stderr, " %5d", count_p[i]);
00345             cerr << endl << "        ";
00346             for (i = 20; i < 30; i++) fprintf(stderr, " %5d", count_p[i]);
00347 
00348             cerr << endl << "  total = " << n_dt_p
00349                  << ",  weighted timestep sum = "
00350                  << total_steps_p/n_dt_p
00351                  << endl;
00352         }
00353 
00354         cerr << endl << "  unperturbed systems only:"
00355              << endl << "        ";
00356         for (i =  0; i < 10; i++) fprintf(stderr, " %5d", count_u[i]);
00357         cerr << endl << "        ";
00358         for (i = 10; i < 20; i++) fprintf(stderr, " %5d", count_u[i]);
00359         cerr << endl << "        ";
00360         for (i = 20; i < 30; i++) fprintf(stderr, " %5d", count_u[i]);
00361 
00362         cerr << endl << "  total = " << n_dt_u << endl;
00363 
00364         cerr << endl << "  unperturbed systems only (effective blocks):"
00365              << endl << "        ";
00366         for (i =  0; i < 10; i++) fprintf(stderr, " %5d", count_ue[i]);
00367         cerr << endl << "        ";
00368         for (i = 10; i < 20; i++) fprintf(stderr, " %5d", count_ue[i]);
00369         cerr << endl << "        ";
00370         for (i = 20; i < 30; i++) fprintf(stderr, " %5d", count_ue[i]);
00371         cerr << endl;
00372     }
00373 
00374     cerr << endl
00375          << "  next_step distribution (all nodes):"
00376          << endl << "        ";
00377     for (i =  0; i < 10; i++) fprintf(stderr, " %5d", count_next[i]);
00378     cerr << endl << "        ";
00379     for (i = 10; i < 20; i++) fprintf(stderr, " %5d", count_next[i]);
00380     cerr << endl << "        ";
00381     for (i = 20; i < 30; i++) fprintf(stderr, " %5d", count_next[i]);
00382     cerr << endl;
00383 
00384     // ...then the list of shortest steps and force counters.
00385 
00386     if (n > NBOT+NTOP) {
00387 
00388         // Print out NBOT shortest perturbed time steps.
00389 
00390         cerr << endl << "  " << NBOT << " shortest perturbed time steps:"
00391              << endl << endl;
00392 
00393         qsort((void *)list_dt, (size_t)np, sizeof(dt_pair), compare_dt);
00394 
00395         for (i = 0; i < NBOT; i++)
00396             fprintf(stderr, "    %3d.     %-15s  %.4e\n",
00397                     i+1,
00398                     list_dt[i].b->format_label(),
00399                     list_dt[i].dt);
00400 
00401         // Print out NBOT shortest effective block steps.
00402 
00403         cerr << endl << "  " << NBOT << " shortest effective block steps:"
00404              << endl << endl;
00405 
00406         qsort((void *)list_dtb, (size_t)n, sizeof(dt_pair), compare_dt);
00407 
00408         for (i = 0; i < NBOT; i++)
00409             fprintf(stderr, "    %3d.     %-15s  %3d   %.4e   %.4e\n",
00410                     i+1,
00411                     list_dtb[i].b->format_label(),
00412                     -(int)list_dtb[i].dt,          // "dt" here is really -kb
00413                     pow(2.0, list_dtb[i].dt),
00414                     list_dtb[i].dt_a);
00415 
00416         // Print out top NTOP particles in (1) instantaneous cost (steps),
00417         //                                 (2) integrated cost since the
00418         //                                     last output.
00419         //                                 (3) direct ("GRAPE") forces
00420         //                                     since the last output
00421         //                                 (4) indirect ("front-end") forces
00422         //                                     since the last output.
00423 
00424         // Sort the arrays in order of decreasing count:
00425 
00426         qsort((void *)steps_inst,  (size_t)np, sizeof(count_pair),
00427               compare_steps);
00428         qsort((void *)steps_delta, (size_t)n,  sizeof(count_pair),
00429               compare_steps);
00430         qsort((void *)f_dir_delta, (size_t)nd, sizeof(count_pair),
00431               compare_steps);
00432         qsort((void *)f_ind_delta, (size_t)ni, sizeof(count_pair),
00433               compare_steps);
00434 
00435         cerr << endl << "  Top " << NTOP
00436              << " nodes by instantaneous (excl. unperturbed)"
00437              << " and delta (all) steps:"
00438              << endl << endl;
00439 
00440         fprintf(stderr, "             %-26s      %-30s\n",
00441                 "--- instantaneous ---",
00442                 "------- delta -------");
00443         fprintf(stderr, "            %-26s      %-30s\n\n",
00444                 "(normalized to dt = 1) ",
00445                 "(since last log output)");
00446 
00447         char tmp[1024];
00448 
00449         for (i = 0; i < NTOP; i++) {
00450 
00451             if (i < np)
00452                 sprintf(tmp, "%3d.     %-10s %10.0f",
00453                         i+1,
00454                         steps_inst[i].b->format_label(),
00455                         steps_inst[i].count);
00456             else
00457                 strcpy(tmp, " ");
00458             fprintf(stderr, "    %-35s", tmp);
00459 
00460             if (i < n)
00461                 sprintf(tmp, "%-10s %10.0f",
00462                         steps_delta[i].b->format_label(),
00463                         steps_delta[i].count);
00464             else
00465                 strcpy(tmp, " ");
00466             fprintf(stderr, "      %-30s\n", tmp);
00467         }
00468         cerr << endl << "  total delta_steps = " << delta_steps_tot << endl;
00469 
00470         cerr << endl << "  Top " << NTOP
00471              << " nodes by delta(force calculations):"
00472              << endl << endl;
00473 
00474         fprintf(stderr, "             %-26s      %-30s\n",
00475                 "------- direct ------",
00476                 "------ indirect -----");
00477 
00478         for (i = 0; i < NTOP; i++) {
00479 
00480             if (i < nd)
00481                 sprintf(tmp, "%3d.     %-10s %10.0f",
00482                         i+1,
00483                         f_dir_delta[i].b->format_label(),
00484                         f_dir_delta[i].count);
00485             else
00486                 strcpy(tmp, " ");
00487             fprintf(stderr, "    %-35s", tmp);
00488 
00489             if (i < ni && f_ind_delta[i].count > 0)
00490                 sprintf(tmp, "%-10s %10.0f",
00491                         f_ind_delta[i].b->format_label(),
00492                         f_ind_delta[i].count);
00493             else
00494                 strcpy(tmp, " ");
00495             fprintf(stderr, "      %-30s\n", tmp);
00496         }
00497         cerr << endl << "  total delta_f_dir = " << delta_f_dir_tot
00498              << "  delta_f_ind = " << delta_f_dir_tot
00499              << endl;
00500     }
00501 
00502     delete [] list_dt;
00503     delete [] steps_inst;
00504     delete [] steps_delta;
00505     delete [] f_dir_delta;
00506     delete [] f_ind_delta;
00507 }
00508 
00509 void print_dstar_params(dyn* b)                 // b is binary center of mass
00510 {
00511     if (((hdyn*)b)->get_use_dstar())
00512         print_binary_dstars(b);
00513 }
00514 
00515 bool print_dstar_stats(dyn* b, bool mass_function,    // b is binary
00516                        vector center, bool verbose)   // center of mass
00517 {
00518     if (((hdyn*)b)->get_use_dstar()) {
00519         dstar_stats(b, mass_function, center, verbose);
00520 
00521         return true;
00522     }
00523 
00524     return false;
00525 }
00526 
00527 void print_statistics(hdyn* b,
00528                       int long_binary_output)           // default = 2
00529 {
00530     // General system statistics (omit time output
00531     // and O(N^2) operations):
00532 
00533     sys_stats(b,
00534               0.5,                      // energy cutoff
00535               true,                     // verbose output
00536               (long_binary_output > 0), // print binaries
00537               (long_binary_output > 1), // full binary_output
00538               2,                        // which lagr
00539               false,                    // don't print time
00540               false,                    // don't compute energy
00541               false,                    // don't allow n^2 ops
00542               kira_calculate_energies,  // energy calculation function
00543               print_dstar_params,       // allow access to dstar_to_kira
00544               print_dstar_stats);       // from dyn sys_stats function
00545 
00546     // Statistics on time steps and bottlenecks:
00547 
00548     print_timestep_stats(b);
00549     print_sort_counters();
00550 }
00551 
00552 local int n_bound(hdyn* b, vector& cod_vel)
00553 {
00554     int nb = 0;
00555     for_all_daughters(hdyn, b, bb)
00556         if (0.5*square(bb->get_vel()-cod_vel) + bb->get_pot() < 0)
00557             nb += bb->n_leaves();
00558     return nb;
00559 }
00560 
00561 local real m_bound(hdyn* b, vector& cod_vel)
00562 {
00563     real mb = 0;
00564     for_all_daughters(hdyn, b, bb)
00565         if (0.5*square(bb->get_vel()-cod_vel) + bb->get_pot() < 0)
00566             mb += bb->get_mass();
00567     return mb;
00568 }
00569 
00570 local void get_n_and_m_bound(hdyn* b, vector& cod_vel, int& nb, real& mb)
00571 {
00572     nb = 0;
00573     mb = 0;
00574     for_all_daughters(hdyn, b, bb)
00575         if (0.5*square(bb->get_vel()-cod_vel) + bb->get_pot() < 0) {
00576             nb += bb->n_leaves();
00577             mb += bb->get_mass();
00578     }
00579 }
00580 
00581 
00582 
00583 void update_cpu_counters(hdyn * b)
00584 {
00585     real last_cpu = b->get_kira_counters()->cpu_time;
00586     b->get_kira_counters()->cpu_time = cpu_time();
00587     b->get_kira_counters()->total_cpu_time += (cpu_time() - last_cpu);
00588     write_counters_to_log(b);
00589 }
00590 
00591 void log_output(hdyn * b, real count, real steps,
00592                 kira_counters* kc_prev,
00593                 int long_binary_output) // default = 2
00594 {
00595     // Standard log output (to stderr, note).
00596 
00597     vector cod_pos, com_vel, cod_vel;
00598     compute_com(b, cod_pos, com_vel);
00599     cod_vel = com_vel;
00600 
00601 //#if 0
00602 
00603     // Suppressed while debugging other parts of
00604     // the GRAPE-6 interface (Steve, 7/00).
00605 
00606     real cpu = cpu_time();
00607     cerr << endl << "Computing densities..." << flush;
00608     kira_compute_densities(b, cod_pos, cod_vel);        // does nothing unless
00609                                                         // GRAPE is present
00610     cpu = cpu_time() - cpu;
00611     if (cpu < 0) cpu = 0;
00612     PRL(cpu);
00613 
00614 //#endif
00615 
00616     int n_bound;
00617     real m_bound;
00618     get_n_and_m_bound(b, cod_vel, n_bound, m_bound);
00619 
00620     cerr << endl;
00621     for (int k = 0 ; k < 40; k++) cerr << '-';
00622     cerr << endl << endl
00623          << "Time = " << b->get_system_time()
00624          << "  N = "    << b->n_leaves() << " (" << n_bound << " bound)"
00625          << "  mass = " << total_mass(b) << " (" << m_bound << " bound)"
00626          << endl
00627          << "          block steps = " << count
00628          << "  total steps = " << steps
00629          << "  steps per block = " << steps/max(1.0, count)
00630          << endl;
00631 
00632     if (b->get_use_sstar())
00633         print_sstar_time_scales(b);
00634 
00635     int p = cerr.precision(INT_PRECISION);
00636     print_recalculated_energies(b, true, true);
00637 
00638     // Extra output on external fields:
00639 
00640     unsigned int ext = b->get_external_field();
00641     if (ext) {
00642         cerr << "          external potential = " << get_external_pot(b)
00643              << " (";
00644         print_external(ext);
00645         cerr << ")" << endl;
00646     }
00647     cerr << "          CM kinetic energy = "
00648          << 0.5*b->get_mass()*square(com_vel) << endl;
00649 
00650     cerr.precision(p);
00651 
00652     // Note: on return from print_recalculated_energies, hdyn::pot
00653     // is properly set, and includes the external field, if any.
00654     // The earlier "bound" quantities may be suspect...
00655 
00656     if (steps > 0) {
00657         update_cpu_counters(b);
00658         print_counters(b->get_kira_counters(), kc_prev);
00659     }
00660 
00661     print_statistics(b, long_binary_output);
00662     cerr << flush;
00663 }
00664 
00665 void snap_output(hdyn * b, real steps, int& snaps,
00666                  bool reg_snap, bool last_snap,
00667                  char * snap_save_file,
00668                  xreal t, xreal ttmp, real t_end,
00669                  real& t_snap, real dt_snap, bool verbose)
00670 {
00671     // Save a snapshot.
00672 
00673     update_cpu_counters(b);
00674     b->set_time(t);
00675 
00676     if (last_snap) {
00677 
00678         // Write (overwrite) snap_save_file.
00679 
00680         ofstream file(snap_save_file);
00681 
00682         if (file) {
00683             set_complete_system_dump(true);
00684             put_node(file, *b, b->get_kira_options()->print_xreal);
00685             set_complete_system_dump(false);
00686             file.close();
00687             cerr << "Snapshot saved in file "
00688                  << snap_save_file
00689                  << " (save CPU = "
00690                  << cpu_time() - b->get_kira_counters()->cpu_time
00691                  << ")\n";
00692         } else {
00693             if (snap_save_file == NULL)
00694                 cerr << "No save file specified.\n";
00695             else
00696                 cerr << "Error opening save file "
00697                      << snap_save_file << "\n";
00698         }
00699     }
00700 
00701     if (reg_snap) {
00702 
00703         if (verbose) cerr << endl;
00704             cerr << "Snapshot output #" << ++snaps
00705                  << " at steps = " << steps
00706                  << ", time = " << b->get_system_time() << endl;
00707         if (verbose) cerr << endl;
00708 
00709         set_complete_system_dump(true);
00710         put_node(cout, *b, b->get_kira_options()->print_xreal);
00711         set_complete_system_dump(false);
00712         cout << flush;
00713 
00714         // if (ttmp > t_end) exit(0);   // do this in kira, not here...
00715     }
00716 }

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