Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

kira_runtime.C

Go to the documentation of this file.
00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00011 // Implement run-time corrections/adjustments to kira.
00012 //
00013 // Externally visible functions:
00014 //
00015 //      void clean_up_files
00016 //      bool check_file
00017 //      bool check_runtime
00018 
00019 #include "hdyn.h"
00020 #include "kira_defaults.h"
00021 #include <unistd.h>
00022 
00023 local void clean_up_file(char* name)
00024 {
00025     char tmp[80];
00026 
00027     // NOTE: this procedure may fail if the system is running
00028     // close to its memory limit.  Files can be opened and read,
00029     // and appropriate action taken, but the system call to delete
00030     // may not work.  This may represent a serious problem for
00031     // options that produce a lot of output. (Steve, 11/99)
00032     //
00033     // Fix is to use the "unlink" system command. (Steve, 6/00)
00034 
00035     // sprintf(tmp, "rm -f %s", name);
00036     // system(tmp);
00037 
00038     cerr << endl;
00039     if (unlink(name) == 0)
00040         cerr << "***** deleted file " << name << endl;
00041     else
00042         cerr << "***** error deleting file " << name << endl;
00043 
00044     ifstream file(name);
00045     if (file) {
00046         cerr << ">>>>> clean_up_file: warning: file " << name
00047              << " NOT deleted" << endl;
00048         file.close();
00049     }
00050 }
00051 
00052 #define N_FILES 13
00053 
00054 void clean_up_files()
00055 {
00056     // List files to be explicitly cleaned up:
00057 
00058     char * files[N_FILES] = {"ALLOW_CHECK",
00059                              "ABORT",
00060                              "DIAG",
00061                              "DUMP",
00062                              "ENERGY",
00063                              "KILL_MULTIPLES",
00064                              "LOG",
00065                              "MULTIPLES",
00066                              "OPTIONS",
00067                              "PARAMS",
00068                              "PP",
00069                              "SCHED",
00070                              "STOP"};
00071 
00072     // Clean up...
00073 
00074     for (int i = 0; i < N_FILES; i++) {
00075         ifstream file(files[i]);
00076         if (file) {
00077             file.close();
00078             clean_up_file(files[i]);
00079         }
00080     }
00081 }
00082 
00083 bool check_file(char* name,
00084                 bool del)       // default = true
00085 {
00086     ifstream file(name);
00087     if (file) {
00088         file.close();
00089         if (del) clean_up_file(name);
00090         return true;
00091     } else
00092         return false;
00093 }
00094 
00095 local void print_multiples(hdyn * b)
00096 {
00097     cerr << endl << "***** In print_multiples:\n";
00098     int n_mult = 0;
00099 
00100     for_all_daughters(hdyn, b, bb)
00101         if (!bb->is_leaf())
00102             if (bb->n_leaves() > 2) {
00103                 n_mult++;
00104                 cerr << "\nFound multiple system " << bb->format_label()
00105                      << endl;
00106                 real eb = print_structure_recursive(bb);
00107                 cerr << "Energy = " << eb << endl;
00108             }
00109 
00110     if (n_mult == 0) cerr << "    (no multiples found)\n";
00111 
00112     cerr << endl;
00113 }
00114 
00115 local void force_step(hdyn * b, real t)
00116 {
00117     real dt = b->get_timestep();
00118     int i = 0;
00119     while (b->get_next_time() > t && i++ < 10)
00120         b->set_timestep((dt /= 2));
00121     b->set_timestep((dt *= 2));
00122 }
00123 
00124 local void force_unperturbed_step(hdyn * b)
00125 {
00126     kepler * kep = b->get_kepler();
00127     if (kep) {
00128         real dt_unp = b->get_unperturbed_timestep();
00129         while (b->get_next_time() > b->get_parent()->get_next_time())
00130             b->set_unperturbed_timestep((dt_unp -= kep->get_period()));
00131         b->set_unperturbed_timestep((dt_unp += kep->get_period()));
00132     } else {
00133         cerr << "Warning: " << b->format_label()
00134              << " has no kepler pointer\n";
00135         force_step(b, b->get_parent()->get_next_time());
00136     }
00137 }
00138 
00139 local void adjust_vel(hdyn * b)
00140 {
00141     real v = abs(b->get_vel());
00142     real r = abs(b->get_pos());
00143 
00144     b->set_vel(-v * b->get_pos() / r);  // Preserve v
00145 
00146     hdyn * s =  b->get_binary_sister();
00147     real mass_fac = -b->get_mass()/s->get_mass();
00148 
00149     s->set_vel(b->get_vel() * mass_fac);
00150 
00151     // Recompute acc and jerk (acc unchanged)...
00152 
00153     vector a_2b, j_2b;
00154     real p_2b;
00155     real d_min_sister = VERY_LARGE_NUMBER;
00156     hdyn * p_nn_sister = NULL;
00157     real eps2 = 0.0;
00158     b->calculate_partial_acc_and_jerk(b->get_parent(), b->get_parent(), b,
00159                                       a_2b, j_2b, p_2b,
00160                                       d_min_sister, p_nn_sister,
00161                                       false, NULL, b);
00162 
00163 //  b->set_acc_and_jerk_and_pot(mass_fac*a_2b, mass_fac*j_2b, -mass_fac*p_2b);
00164 
00165 }
00166 
00167 local bool kill_multiple(hdyn * b)
00168 {
00169     // For now, adjust eccentricity of top-level node b only...
00170 
00171     hdyn * od = b->get_oldest_daughter();
00172     kepler * kep = od->get_kepler();
00173 
00174     if (kep) {
00175 
00176         if (kep->get_eccentricity() < 1) {
00177 
00178             // Unperturbed system.  Reduce timesteps to advance
00179             // system in scheduling, then modify kepler structure.
00180 
00181             // Top-level CM step...
00182 
00183             force_step(b, b->get_system_time());
00184 
00185             // Top-level binary step...
00186 
00187             force_unperturbed_step(od);
00188 
00189             // Lower levels, if any...
00190 
00191             for_all_nodes(hdyn, b, bb) {
00192                 if (bb->get_parent() != b && bb->get_elder_sister() == NULL) {
00193 
00194                     if (bb->get_kepler() == NULL) {
00195 
00196                         cerr << "Warning: " << bb->format_label()
00197                              << " has no kepler pointer\n";
00198 
00199                         force_step(bb, bb->get_parent()->get_next_time());
00200 
00201                     } else
00202 
00203                         force_unperturbed_step(bb);
00204                 }
00205             }
00206 
00207             // Modify top-level orbit....
00208 
00209             kep->set_eccentricity(0.99999);
00210 
00211             // Probably need to do more (reinitialize) here...  <<<<<<
00212 
00213             return true;
00214         }
00215         
00216     } else {
00217 
00218         // Force CM and top-level steps only...
00219 
00220         force_step(b, b->get_system_time());
00221         force_step(b->get_oldest_daughter(), b->get_system_time());
00222 
00223         // Modify relative velocity of components.
00224 
00225         adjust_vel(b->get_oldest_daughter());
00226 
00227         return true;
00228 
00229     }
00230 
00231     return false;
00232 }
00233 
00234 local bool kill_multiples(hdyn * b)
00235 {
00236 
00237     //---------------------------------------------------------------//
00238     cerr << endl << "***** kill_multiples: not yet implemented...\n\n";
00239     return false;
00240     //---------------------------------------------------------------//
00241 
00242     bool killed = false;
00243     for_all_daughters(hdyn, b, bb)
00244         if (!bb->is_leaf())
00245            if (bb->n_leaves() > 2) {
00246                 cerr << "\nFound multiple system " << bb->format_label()
00247                      << endl;
00248                 print_structure_recursive(bb);
00249                 if (kill_multiple(bb)) {
00250                     cerr << "...killed\n";
00251                     killed = true;
00252                 }
00253             }
00254 
00255     return killed;
00256 }
00257 
00258 local void modify_params(hdyn * b, char * name,
00259                          real& t_end, real& new_dt_log, real& new_dt_snap,
00260                          int& long_binary_output, char* new_snap_save_file)
00261 {
00262     // Allow runtime modification of parameters that can be set on
00263     // the kira command line.
00264 
00265     ifstream file(name);
00266     if (file) {
00267 
00268         cerr << endl << "***** Reading parameter changes from file " << name
00269              << "\n\n";
00270 
00271         // File should contain lines of the form:
00272         //
00273         //              -keyword value
00274         //
00275         // where the keywords a, b, C, d, D, f, g, k, K, N, O, and t are
00276         // permitted (meanings are the same as if specified on the command
00277         // line, except that "-t" increments t_end).
00278         //
00279         // Parameter changes take place IMMEDIATELY.
00280 
00281         char *s, line[128];
00282 
00283         while (file.get(line, 128, '\n')) {
00284 
00285             // NOTE: If get() found the terminating '\n', it left it
00286             // in the input stream as the first unread character (a C++
00287             // feature, not a bug).  To avoid an infinite loop, read
00288             // that character now.  Partial reads of lines probably
00289             // mean an error, so we simply read characters until the
00290             // terminator is found.
00291 
00292             char c;
00293             while (file.get(c) && c != '\n') ;
00294 
00295             // Parse the line.
00296 
00297             if (s = strstr(line, "-a")) {
00298 
00299                 real tmp = atof(s+2);
00300                 if (tmp > 0 && tmp < 1) {
00301                     cerr << "Setting eta = " << tmp << endl;
00302                     b->set_eta(tmp);
00303                     putrq(b->get_log_story(), "eta", tmp);
00304                 }
00305 
00306             } else if (s = strstr(line, "-b")) {
00307 
00308                 int tmp = atoi(s+2);
00309                 if (tmp > 0) {
00310                     cerr << "Setting long_binary_output = " << tmp << endl;
00311                     long_binary_output = tmp;
00312                 }
00313 
00314             } else if (s = strstr(line, "-C")) {
00315 
00316                 real tmp = atof(s+2);
00317                 if (tmp > 0 && tmp < 1800) {    // arbitrary upper limit...
00318                     cerr << "Setting grape_max_cpu = " << tmp << endl;
00319                     b->get_kira_options()->grape_max_cpu = tmp;
00320                 }
00321 
00322             } else if (s = strstr(line, "-d")) {
00323 
00324                 real tmp = atof(s+2);
00325                 if (tmp > 0) {
00326                     cerr << "Setting dt_log = " << tmp << endl;
00327                     new_dt_log = tmp;
00328                 }
00329 
00330             } else if (s = strstr(line, "-D")) {
00331 
00332                 real tmp = atof(s+2);
00333                 if (tmp > 0) {
00334                     cerr << "Setting dt_snap = " << tmp << endl;
00335                     new_dt_snap = tmp;
00336                 }
00337 
00338             } else if (s = strstr(line, "-f")) {
00339 
00340                 real tmp = atof(s+2);
00341                 if (tmp > 0 && tmp < 100) {
00342                     cerr << "Setting d_min_fac = " << tmp << endl;
00343                     b->set_d_min_fac(tmp);
00344                     putrq(b->get_log_story(), "d_min_fac", tmp);
00345                 }
00346 
00347             } else if (s = strstr(line, "-g")) {
00348 
00349                 real tmp = atof(s+2);
00350                 if (tmp > 0 && tmp < 100) {
00351                     cerr << "Setting lag_factor = " << tmp << " (squared)\n";
00352                     b->set_lag_factor(tmp*tmp);
00353                     putrq(b->get_log_story(), "lag_factor", tmp);
00354                 }
00355 
00356             } else if (s = strstr(line, "-k")) {
00357 
00358                 real tmp = atof(s+2);
00359                 if (tmp > 0 && tmp < 1) {
00360                     cerr << "Setting gamma = " << tmp << endl;
00361                     b->set_gamma2(tmp*tmp);
00362                     putrq(b->get_log_story(), "gamma", tmp);
00363                 }
00364 
00365             } else if (s = strstr(line, "-K")) {
00366 
00367                 int tmp = atoi(s+2);
00368                 if (tmp > 0) {
00369                     int kappa_max = (int) pow(2, tmp);
00370                     b->set_max_slow_factor(kappa_max);
00371                     cerr << "Setting maximum slowdown factor = "
00372                          << kappa_max << endl;
00373                     putiq(b->get_log_story(), "log_max_slow", tmp);
00374                 }
00375 
00376             } else if (s = strstr(line, "-N")) {
00377 
00378                 int tmp = atoi(s+2);
00379                 if (tmp > 0) {
00380                     cerr << "Setting n_check = " << tmp << endl;
00381                     b->get_kira_diag()->n_check_heartbeat = tmp;
00382                 }
00383 
00384             } else if (s = strstr(line, "-O")) {
00385 
00386                 strcpy(new_snap_save_file, s+3);
00387                 if (new_snap_save_file[0] != '\0') {
00388                     cerr << "Setting snap_save_file = "
00389                          << new_snap_save_file << endl;
00390                 }
00391 
00392             } else if (s = strstr(line, "-t")) {
00393 
00394                 real tmp = atof(s+2);
00395                 t_end += tmp;
00396                 cerr << "Setting t_end = " << t_end << endl;
00397 
00398             } else if (s = strstr(line, "-u")) {
00399 
00400                 toggle_unperturbed(b, 1);
00401                 print_unperturbed_options(b);
00402 
00403             } else if (s = strstr(line, "-U")) {
00404 
00405                 toggle_unperturbed(b, 0);
00406                 print_unperturbed_options(b);
00407 
00408             } else if (s = strstr(line, "-x")) {
00409 
00410                 b->get_kira_options()->print_xreal
00411                     = !b->get_kira_options()->print_xreal;
00412                 cerr << "Setting print_xreal = "
00413                      << b->get_kira_options()->print_xreal << endl;
00414 
00415             }
00416         }
00417 
00418         file.close();
00419         clean_up_file(name);
00420 
00421         cerr << endl;
00422     }
00423 }
00424 
00425 local int get_value(char *s, int default_value)         // overloaded!
00426 {
00427     // Look for an "=" in the line.
00428 
00429     char *ss;
00430     if (ss = strstr(s, "="))
00431         return atoi(ss+1);
00432     else
00433         return default_value;
00434 }
00435 
00436 local real get_value(char *s, real default_value)
00437 {
00438     char *ss;
00439     if (ss = strstr(s, "="))
00440         return atof(ss+1);
00441     else
00442         return default_value;
00443 }
00444 
00445 local bool get_value(char *s, real& v1, real& v2)
00446 {
00447     char *ss;
00448     if (ss = strstr(s, "="))
00449         if (sscanf(ss+1, "%f %f", &v1, &v2) == 2)
00450             return true;
00451 
00452     return false;
00453 }
00454 
00455 local char *get_string(char *s)
00456 {
00457     char *ss;
00458     if (ss = strstr(s, "=")) {
00459         ss++;
00460         while (*ss <= ' ') ss++;
00461         char *s1 = ss;                  // first nonblank character after "="
00462         char *s2 = s1;
00463         while (*s2 > ' ') s2++;         // s2 = next blank character after s1
00464 
00465         // Create permanent data...
00466 
00467         int i;
00468         char *string = new char[s2 - s1 + 1];
00469         for (i = 0; i < s2-s1; i++) string[i] = *(s1+i);
00470         string[i] = '\0';
00471 
00472         return string;
00473     }
00474 
00475     return NULL;
00476 }
00477 
00478 local void modify_options(hdyn * b, char * name, bool del = true)
00479 {
00480     // Modify entries in the hdyn::kira_options class.
00481 
00482     // ***************************************************************
00483     // ****  Note that options/diag names need to be unique       ****
00484     // ****  to accommodate use of combined .kira file.           ****
00485     // ****  Abbreviated names are unhelpful -- reconsider?       ****
00486     // ****  Future option names should be long and descriptive.  ****
00487     // ***************************************************************
00488 
00489     int count = 0;
00490 
00491     ifstream file(name);
00492     if (file) {
00493 
00494         char *s, line[128];
00495 
00496         while (file.get(line, 128, '\n')) {
00497 
00498             char c;
00499             while (file.get(c) && c != '\n') ;  // see note in modify_params
00500 
00501             // Use "keyword [= value]" format (if a value is required),
00502             // with reasonable abbreviations and alternatives allowed...
00503 
00504             // Allow blank/comment lines:
00505 
00506             if (line[0] == '\n' || line[0] == '\0' || line[0] == '#')
00507                 continue;
00508 
00509             if (count++ == 0) cerr << endl;
00510             cerr << "read runtime option " << line << endl;
00511 
00512             // First option is to change the general Starlab "precision"
00513             // setting that controls format of real output from put_node().
00514 
00515             if (s = strstr(line, "precision"))
00516 
00517                 adjust_starlab_precision(get_value(s, -1));  // default = reset
00518         
00519             else if (s = strstr(line, "print"))
00520 
00521                 b->get_kira_options()->print();
00522         
00523             else if (s = strstr(line, "reset")) {
00524 
00525                 // Restore factory settings...
00526 
00527                 delete b->get_kira_options();
00528                 b->set_kira_options(new kira_options);
00529         
00530 
00531                 // *** print_xreal is taken care of in modify_params() ***
00532 
00533 
00534             } else if ((s = strstr(line, "perturber_criterion"))
00535                        || (s = strstr(line, "perturber_c")))
00536 
00537                 b->get_kira_options()->perturber_criterion
00538                     = get_value(s, DEFAULT_PERTURBER_CRITERION);
00539 
00540             else if ((s = strstr(line, "optimize_scheduling"))
00541                        || (s = strstr(line, "optimize_s")))
00542 
00543                 b->get_kira_options()->optimize_scheduling
00544                     = get_value(s, DEFAULT_OPTIMIZE_SCHEDULING);
00545 
00546             else if ((s = strstr(line, "optimize_block"))
00547                      || (s = strstr(line, "optimize_b")))
00548 
00549                 b->get_kira_options()->optimize_block
00550                     = get_value(s, DEFAULT_OPTIMIZE_BLOCK);
00551 
00552 
00553             //  ***  allow_unperturbed and allow_multiples are  ***
00554             //  ***  taken care of in modify_params()...        ***
00555 
00556 
00557             else if ((s = strstr(line, "min_unpert_steps"))
00558                      || (s = strstr(line, "min_unpert")))
00559 
00560                 b->get_kira_options()->min_unpert_steps
00561                     = get_value(s, DEFAULT_MIN_UNPERT_STEPS);
00562 
00563             else if ((s = strstr(line, "full_merge_tol_for_close"))
00564                      || (s = strstr(line, "full_merge_tol_"))
00565                      || (s = strstr(line, "full_merge_close")))
00566 
00567                 b->get_kira_options()->full_merge_tol_for_close_binary
00568                     = get_value(s, DEFAULT_FULL_MERGE_TOL_FOR_CLOSE_BINARY);
00569 
00570             else if ((s = strstr(line, "full_merge_tolerance"))
00571                      || (s = strstr(line, "full_merge")))
00572 
00573                 b->get_kira_options()->full_merge_tolerance
00574                     = get_value(s, DEFAULT_FULL_MERGE_TOLERANCE);
00575 
00576             else if ((s = strstr(line, "relax_factor"))
00577                      || (s = strstr(line, "relax")))
00578 
00579                 b->get_kira_options()->relax_factor
00580                     = get_value(s, DEFAULT_RELAX_FACTOR);
00581 
00582             else if ((s = strstr(line, "partial_merge_factor"))
00583                      || (s = strstr(line, "partial_merge")))
00584 
00585                 b->get_kira_options()->partial_merge_factor
00586                     = get_value(s, DEFAULT_PARTIAL_MERGE_FACTOR);
00587 
00588             else if ((s = strstr(line, "multiple_merge_tolerance"))
00589                      || (s = strstr(line, "multiple_merge")))
00590 
00591                 b->get_kira_options()->multiple_merge_tolerance
00592                     = get_value(s, DEFAULT_MULTIPLE_MERGE_TOLERANCE);
00593 
00594             else if ((s = strstr(line, "unconditional_stable_fac"))
00595                      || (s = strstr(line, "uncond_stable"))
00596                      || (s = strstr(line, "stable")))
00597 
00598                 b->get_kira_options()->unconditional_stable_fac
00599                     = get_value(s, DEFAULT_UNCONDITIONAL_STABLE_FAC);
00600 
00601             else if ((s = strstr(line, "partial_stable_fac"))
00602                      || (s = strstr(line, "partial_stable")))
00603 
00604                 b->get_kira_options()->partial_stable_fac
00605                     = get_value(s, DEFAULT_PARTIAL_STABLE_FAC);
00606 
00607             else if ((s = strstr(line, "aarseth_stable_fac"))
00608                      || (s = strstr(line, "aarseth_stable"))
00609                      || (s = strstr(line, "aarseth_fac")))
00610 
00611                 b->get_kira_options()->aarseth_stable_fac
00612                     = get_value(s, DEFAULT_AARSETH_STABLE_FAC);
00613 
00614             else if ((s = strstr(line, "use_aarseth_criterion"))
00615                      || (s = strstr(line, "use_aarseth"))
00616                      || (s = strstr(line, "aarseth")))
00617 
00618                 b->get_kira_options()->use_aarseth_criterion
00619                     = get_value(s, DEFAULT_USE_AARSETH_CRITERION);
00620 
00621             else if ((s = strstr(line, "close_criterion"))
00622                      || (s = strstr(line, "close")))
00623 
00624                 b->get_kira_options()->close_criterion
00625                     = get_value(s, DEFAULT_CLOSE_CRITERION);
00626 
00627             else if ((s = strstr(line, "allow_keplstep"))
00628                      || (s = strstr(line, "allow_kepl")))
00629 
00630                 b->get_kira_options()->allow_keplstep
00631                     = get_value(s, DEFAULT_ALLOW_KEPLSTEP);
00632 
00633             else if ((s = strstr(line, "use_old_correct_acc_and_jerk"))
00634                      || (s = strstr(line, "use_old_corr")))
00635 
00636                 b->get_kira_options()->use_old_correct_acc_and_jerk
00637                     = get_value(s, DEFAULT_USE_OLD_CORRECT_ACC_AND_JERK);
00638 
00639             else if ((s = strstr(line, "grape_check_count"))
00640                      || (s = strstr(line, "grape_check")))
00641 
00642                 b->get_kira_options()->grape_check_count
00643                     = get_value(s, DEFAULT_GRAPE_CHECK_COUNT);
00644 
00645             else if ((s = strstr(line, "grape_max_cpu"))
00646                      || (s = strstr(line, "grape_max")))
00647 
00648                 b->get_kira_options()->grape_max_cpu
00649                     = get_value(s, DEFAULT_GRAPE_MAX_CPU);
00650 
00651             else if ((s = strstr(line, "use_perturbed_list"))
00652                      || (s = strstr(line, "use_pert")))
00653 
00654                 b->get_kira_options()->use_perturbed_list
00655                     = get_value(s, DEFAULT_USE_PERTURBED_LIST);
00656 
00657             else if ((s = strstr(line, "max_slow_factor"))
00658                      || (s = strstr(line, "max_slow_fac")))
00659 
00660                 b->set_max_slow_factor(get_value(s, DEFAULT_MAX_SLOW_FACTOR));
00661 
00662             else if ((s = strstr(line, "max_slow_perturbation"))
00663                      || (s = strstr(line, "max_slow_pert")))
00664 
00665                 b->set_max_slow_perturbation(get_value(s,
00666                                              DEFAULT_MAX_SLOW_PERTURBATION));
00667 
00668         }
00669 
00670         file.close();
00671         if (del) clean_up_file(name);
00672     }
00673 }
00674 
00675 local void modify_diag(hdyn * b, char * name, bool del = true)
00676 {
00677     // Modify entries in the hdyn::kira_diag class.
00678 
00679     // *************************************************************
00680     // ****  Note that options/diag names need to be unique     ****
00681     // ****  to accommodate use of combined .kira file.         ****
00682     // ****  Abbreviated names are unhelpful -- reconsider?     ****
00683     // ****  Future diag names should be long and descriptive.  ****
00684     // *************************************************************
00685 
00686     int count = 0;
00687 
00688     ifstream file(name);
00689     if (file) {
00690 
00691         char *s, line[128];
00692 
00693         while (file.get(line, 128, '\n')) {
00694 
00695             char c;
00696             while (file.get(c) && c != '\n') ;  // see note in modify_params
00697 
00698             // Use "keyword [= value]" format (if a value is required),
00699             // with reasonable abbreviations and alternatives allowed...
00700             //
00701             // Convention: for true/false switches, 0 = false, 1 = true
00702             //             for levels,   -1 turns off the output,
00703             //                         >= 0 sets the value
00704 
00705             // Allow blank/comment lines:
00706 
00707             if (line[0] == '\n' || line[0] == '\0' || line[0] == '#')
00708                 continue;
00709 
00710             if (count++ == 0) cerr << endl;
00711             cerr << "read runtime diag option " << line << endl;
00712 
00713             if (s = strstr(line, "print"))
00714 
00715                 b->get_kira_diag()->print();
00716         
00717             else if (s = strstr(line, "name")) {
00718 
00719                 if (s = get_string(line))
00720                     b->get_kira_diag()->set_name(s);
00721                 else
00722                     b->get_kira_diag()->clear_name();
00723 
00724             } else if (s = strstr(line, "dt")) {
00725 
00726                 real dt = get_value(s, 0.0);
00727                 if (dt > 0)
00728                     b->get_kira_diag()->set_range(b->get_system_time(),
00729                                                   b->get_system_time() + dt);
00730 
00731             } else if (s = strstr(line, "range")) {
00732 
00733                 real t1, t2;
00734                 if (get_value(line, t1, t2))
00735                     if (t2 > t1 && t2 > b->get_system_time())
00736                         b->get_kira_diag()->set_range(t1, t2);
00737 
00738             } else if (s = strstr(line, "reset")) {
00739 
00740                 // Restore factory settings...
00741 
00742                 delete b->get_kira_diag();
00743                 b->set_kira_diag(new kira_diag);
00744         
00745             } else if (s = strstr(line, "kira_main"))
00746 
00747                 b->get_kira_diag()->kira_main = get_value(s, 1);
00748 
00749             else if (s = strstr(line, "n_check_heartbeat"))
00750 
00751                 b->get_kira_diag()->n_check_heartbeat
00752                     = get_value(s, 50000);
00753 
00754             else if (s = strstr(line, "check_heartbeat"))
00755 
00756                 b->get_kira_diag()->check_heartbeat
00757                     = get_value(s, 1);
00758 
00759             else if (s = strstr(line, "n_check_runtime"))
00760 
00761                 b->get_kira_diag()->n_check_runtime = get_value(s, 2500);
00762 
00763             else if ((s = strstr(line, "unpert_function_id"))
00764                      || (s = strstr(line, "unpert_id")))
00765 
00766                 b->get_kira_diag()->unpert_function_id
00767                     = get_value(s, 1);
00768 
00769             else if ((s = strstr(line, "report_start_unperturbed"))
00770                      || (s = strstr(line, "report_start_unpert"))
00771                      || (s = strstr(line, "unpert_start")))
00772 
00773                 b->get_kira_diag()->report_start_unperturbed
00774                     = get_value(s, 1);
00775 
00776             else if ((s = strstr(line, "report_continue_unperturbed"))
00777                      || (s = strstr(line, "report_cont_unpert"))
00778                      || (s = strstr(line, "unpert_cont")))
00779 
00780                 b->get_kira_diag()->report_continue_unperturbed
00781                     = get_value(s, 1);
00782 
00783             else if ((s = strstr(line, "report_end_unperturbed"))
00784                      || (s = strstr(line, "report_end_unpert"))
00785                      || (s = strstr(line, "unpert_end")))
00786 
00787                 b->get_kira_diag()->report_end_unperturbed
00788                     = get_value(s, 1);
00789 
00790             else if ((s = strstr(line, "report_pericenter_reflection"))
00791                      || (s = strstr(line, "report_peri_unpert"))
00792                      || (s = strstr(line, "unpert_peri")))
00793 
00794                 b->get_kira_diag()->report_pericenter_reflection
00795                     = get_value(s, 1);
00796 
00797             else if ((s = strstr(line, "report_multiple"))
00798                      || (s = strstr(line, "report_mult_unpert"))
00799                      || (s = strstr(line, "unpert_mult")))
00800 
00801                 b->get_kira_diag()->report_multiple
00802                     = get_value(s, 1);
00803 
00804             else if ((s = strstr(line, "unpert_report_level"))
00805                      || (s = strstr(line, "unpert_level")))
00806 
00807                 b->get_kira_diag()->unpert_report_level
00808                     = get_value(s, 0);
00809 
00810             else if ((s = strstr(line, "end_unpert_report_level"))
00811                      || (s = strstr(line, "end_unpert_level")))
00812 
00813                 b->get_kira_diag()->end_unpert_report_level
00814                     = get_value(s, 0);
00815 
00816             else if ((s = strstr(line, "multiple_report_level"))
00817                      || (s = strstr(line, "mult_report_level")))
00818 
00819                 b->get_kira_diag()->multiple_report_level
00820                     = get_value(s, 0);
00821 
00822             else if ((s = strstr(line, "tree_level"))) {
00823 
00824                 b->get_kira_diag()->tree_level
00825                     = get_value(s, 0);
00826                 if (b->get_kira_diag()->tree_level < 0)
00827                     b->get_kira_diag()->tree = false;
00828 
00829             } else if (s = strstr(line, "diag_tree"))
00830 
00831                 b->get_kira_diag()->tree
00832                     = get_value(s, 1);
00833 
00834             else if ((s = strstr(line, "ev_function_id")))
00835 
00836                 b->get_kira_diag()->ev_function_id
00837                     = get_value(s, 1);
00838 
00839             else if ((s = strstr(line, "grape_level"))) {
00840 
00841                 b->get_kira_diag()->grape_level
00842                     = get_value(s, 0);
00843                 if (b->get_kira_diag()->grape_level < 0)
00844                     b->get_kira_diag()->grape = false;
00845 
00846             } else if ((s = strstr(line, "grape_ev")))
00847 
00848                 b->get_kira_diag()->grape
00849                     = get_value(s, 1);
00850 
00851             else if ((s = strstr(line, "timestep_check")))
00852 
00853                 b->get_kira_diag()->timestep_check
00854                     = get_value(s, 1);
00855 
00856             else if (s = strstr(line, "diag_correct"))
00857 
00858                 b->get_kira_diag()->correct
00859                     = get_value(s, 1);
00860 
00861             else if (s = strstr(line, "kira_ev"))
00862 
00863                 b->get_kira_diag()->kira_ev = get_value(s, 1);
00864 
00865             else if ((s = strstr(line, "slow_perturbed"))
00866                      || (s = strstr(line, "slow_pert")))
00867 
00868                 b->get_kira_diag()->slow_perturbed
00869                     = get_value(s, 1);
00870 
00871             else if ((s = strstr(line, "slow_level"))) {
00872 
00873                 b->get_kira_diag()->slow_level
00874                     = get_value(s, 0);
00875                 if (b->get_kira_diag()->slow_level < 0)
00876                     b->get_kira_diag()->slow = false;
00877 
00878             } else if (s = strstr(line, "slow_diag"))
00879 
00880                 b->get_kira_diag()->slow
00881                     = get_value(s, 1);
00882 
00883             else if ((s = strstr(line, "report_stellar_evolution"))
00884                        || (s = strstr(line, "report_stellar_e"))
00885                        || (s = strstr(line, "stellar_e")))
00886 
00887                 b->get_kira_diag()->report_stellar_evolution
00888                     = get_value(s, 1);
00889 
00890             else if ((s = strstr(line, "report_stellar_mass_loss"))
00891                        || (s = strstr(line, "report_stellar_m"))
00892                        || (s = strstr(line, "stellar_m")))
00893 
00894                 b->get_kira_diag()->report_stellar_mass_loss
00895                     = get_value(s, 1);
00896 
00897             else if ((s = strstr(line, "report_binary_mass_loss"))
00898                        || (s = strstr(line, "report_b"))
00899                        || (s = strstr(line, "binary")))
00900 
00901                 b->get_kira_diag()->report_binary_mass_loss
00902                     = get_value(s, 1);
00903 
00904             else if ((s = strstr(line, "report_adjust_perturbed"))
00905                        || (s = strstr(line, "report_adj"))
00906                        || (s = strstr(line, "adjust_pert")))
00907 
00908                 b->get_kira_diag()->report_adjust_perturbed_list
00909                     = get_value(s, 1);
00910 
00911             else if ((s = strstr(line, "report_correct_perturber_list"))
00912                        || (s = strstr(line, "report_corr"))
00913                        || (s = strstr(line, "correct_pert")))
00914 
00915                 b->get_kira_diag()->report_correct_perturber_list
00916                     = get_value(s, 1);
00917 
00918             else if (s = strstr(line, "diag_ev"))    // poor choice of keyword!
00919 
00920                 b->get_kira_diag()->ev
00921                     = get_value(s, 1);
00922 
00923         }
00924 
00925         file.close();
00926         if (del) clean_up_file(name);
00927     }
00928 }
00929 
00930 local void pp(hdyn * b, char * name)
00931 {
00932     ifstream file(name);
00933     if (file) {
00934 
00935         cerr << endl << "***** Running pp3 on particle(s) listed in file "
00936              << name << ":\n\n";
00937 
00938         // File should contain valid particle names, one per line.
00939 
00940         char *s, line[128];
00941 
00942         while (file.get(line, 128, '\n')) {
00943 
00944             // NOTE: If get() found the terminating '\n', it left it
00945             // in the input stream as the first unread character (a C++
00946             // feature, not a bug).  To avoid an infinite loop, read
00947             // that character now.  Partial reads of lines probably
00948             // mean an error, so we simply read characters until the
00949             // terminator is found.
00950 
00951             char c;
00952             while (file.get(c) && c != '\n') ;
00953 
00954             // Add a trailing '\0' to the input line at the first
00955             // non-printing location.
00956 
00957             bool ok = false;
00958             for (int i = 0; i < 128; i++) {
00959                 if (line[i] < ' ') {
00960                     line[i] = '\0';
00961                     ok = true;
00962                     break;
00963                 }
00964             }
00965 
00966             // (Silently ignore unterminated lines.)
00967 
00968             if (ok) {
00969 
00970                 // Parse the line.
00971 
00972                 hdyn* bb = (hdyn*) node_with_name(line, b->get_root());
00973 
00974                 if (!bb)
00975                     cerr << "Unable to find node " << line << endl;
00976                 else
00977                     pp3(bb);
00978             }
00979         }
00980 
00981         file.close();
00982         clean_up_file(name);
00983 
00984         cerr << endl;
00985     }
00986 }
00987 
00988 local void dump_to_file(hdyn* b, char* name)
00989 {
00990     ifstream file(name);
00991     bool written = false;
00992     if (file) {
00993         char dumpfile[128];
00994         if (file.get(dumpfile, 128, '\n')) {
00995             ofstream dump(dumpfile);
00996             if (dump) {
00997                 put_node(dump, *b, b->get_kira_options()->print_xreal);
00998                 dump.close();
00999                 cerr << "Data written to file " << dumpfile << endl;
01000                 written = true;
01001             }
01002         }
01003         file.close();
01004         clean_up_file(name);
01005     }
01006     if (!written)
01007         cerr << "No data written" << endl;
01008 }
01009 
01010 // Check_kira_init:  read and process configuration files if present,
01011 //                   but do *not* delete them.
01012 
01013 void check_kira_init(hdyn *b)
01014 {
01015     // Look in standard places for nonstandard options.  Merge the old
01016     // old "INIT_DIAG" and "INIT_OPTIONS" settings into a single file
01017     // (change made by Steve, 1/02).
01018 
01019     char file[1024];
01020 
01021     // Look first in $HOME/.kira ...
01022 
01023     strcpy(file, getenv("HOME"));
01024     strcat(file, "/.kira");
01025 
01026     if (check_file(file, false)) {
01027         modify_diag(b, file, false);
01028         modify_options(b, file, false);
01029     }
01030 
01031     // ... then allow local setup in ./.kira.
01032 
01033     strcpy(file, "./.kira");
01034 
01035     if (check_file(file, false)) {
01036         modify_diag(b, file, false);
01037         modify_options(b, file, false);
01038     }
01039 }
01040 
01041 // Check_kira_runtime:  read and process files if present, then delete them.
01042 
01043 bool check_kira_runtime(hdyn* b,
01044                         real& t_end, real& new_dt_log, real& new_dt_snap,
01045                         int& long_binary_output, char* new_snap_save_file,
01046                         bool& tree_changed)
01047 {
01048     static bool allow_check = true;
01049     bool status = false;
01050 
01051     if (check_file("ALLOW_CHECK")) {
01052         allow_check = !allow_check;
01053         cerr << endl
01054              << "**** Setting allow_check = " << allow_check
01055              << endl;
01056     }
01057 
01058     if (!allow_check) return false;
01059 
01060     // Note the order in which we check things -- placing ABORT
01061     // at end allows us to get other output before quitting.
01062 
01063     if (check_file("PARAMS", false))
01064         modify_params(b, "PARAMS", t_end,
01065                       new_dt_log, new_dt_snap,
01066                       long_binary_output, new_snap_save_file);
01067 
01068     if (check_file("DIAG", false))
01069         modify_diag(b, "DIAG");
01070 
01071     if (check_file("OPTIONS", false))
01072         modify_options(b, "OPTIONS");
01073 
01074     if (check_file("PP", false))
01075         pp(b, "PP");
01076 
01077     if (check_file("DUMP", false)) {
01078         cerr << endl
01079              << "***** (Unsynchronized system dump forced by user)\n\n";
01080         cerr << "Time = " << b->get_system_time()
01081              << "  N = "    << b->n_leaves()
01082              << "  mass = " << total_mass(b) << endl;
01083         dump_to_file(b, "dump");
01084         cerr << endl;
01085     }
01086 
01087     if (check_file("ENERGY")) {
01088         cerr << endl << "***** (Energy output forced by user)\n\n";
01089         cerr << "Time = " << b->get_system_time()
01090              << "  N = "    << b->n_leaves()
01091              << "  mass = " << total_mass(b) << endl;
01092 
01093         // Note that, as presently coded, the computation of the energy
01094         // also recomputes acc and jerk for all nodes, and therefore
01095         // affects the future evolution, making runs non-reproducible.
01096 
01097         // pp3(b);
01098         print_recalculated_energies(b);
01099         // pp3(b);
01100         cerr << endl;
01101     }
01102 
01103     if (check_file("LOG")) {
01104         cerr << endl << "***** (Log output forced by user)\n\n";
01105         cerr << "Time = " << b->get_system_time()
01106              << "  N = "    << b->n_leaves()
01107              << "  mass = " << total_mass(b) << endl;
01108 
01109         // print_recalculated_energies(b);      // omit because this can
01110                                                 // change the evolution...
01111                                                 // -- doesn't affect evolution
01112                                                 // now, but omit anyway
01113 
01114         print_counters(b->get_kira_counters());
01115         print_statistics(b);
01116         cerr << endl;
01117     }
01118 
01119     if (check_file("MULTIPLES")) {
01120         cerr << endl << "***** (Multiple output forced by user)\n\n";
01121         cerr << "Time = " << b->get_system_time()
01122              << "  N = "    << b->n_leaves()
01123              << "  mass = " << total_mass(b) << endl;
01124         print_multiples(b);
01125         cerr << endl;
01126     }
01127 
01128     if (check_file("KILL_MULTIPLES"))
01129         tree_changed |= kill_multiples(b);
01130 
01131     if (check_file("SCHED")) {
01132         cerr << endl << "***** (Scheduling output forced by user)\n\n";
01133         cerr << "Time = " << b->get_system_time()
01134              << "  N = "    << b->n_leaves()
01135              << "  mass = " << total_mass(b) << endl;
01136         print_counters(b->get_kira_counters());
01137 
01138         cerr << "Particles just advanced:" << endl;
01139         for_all_nodes(hdyn, b, bb)
01140             if (bb->get_time() == bb->get_system_time())
01141                 cerr << "    " << bb->format_label()
01142                      << "  timestep = " << bb->get_timestep()
01143                      << endl;
01144 
01145         cerr << endl;
01146     }
01147 
01148     // Check this last...
01149 
01150     if (check_file("ABORT")) {
01151 
01152         cerr << endl << "***** Abort forced by user at time "
01153              << b->get_system_time() << "\n\n" << flush;
01154         clean_up_files();
01155 
01156         status = true;
01157     }
01158 
01159     return status;      // "true" ==> quit kira on return
01160 }

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