Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

makescat.C

Go to the documentation of this file.
00001 
00071 
00072 #include "scatter.h"
00073 
00074 #ifndef TOOLBOX
00075 
00076 #define DEFAULT_MASS_RATIO 1
00077 #define DEFAULT_ECC 0
00078 #define DEFAULT_SMA 1
00079 #define SMA_REDUCE 10
00080 #define DEFAULT_R1 0
00081 #define DEFAULT_R2 0
00082 
00083 #define TIDAL_TOL_FACTOR 1e-6
00084 
00085 local void pp(sdyn* b, ostream & s, int level = 0) {
00086 
00087     s.precision(4);
00088 
00089     for (int i = 0; i < 2*level; i++) s << " ";
00090 
00091     b->pretty_print_node(s);
00092     s << " \t"<< b->get_mass() << " \t"
00093       << b->get_pos() << "   "
00094       << b->get_vel() <<endl;
00095 
00096     for (sdyn * daughter = b->get_oldest_daughter();
00097          daughter != NULL;
00098          daughter = daughter->get_younger_sister())
00099         pp(daughter, s, level + 1);     
00100 }
00101 
00102 // initialize_root: Set up the outermost (scattering) trajectory.
00103 //                  The plane and orientation of the trajectory define the
00104 //                  coordinate system used.  Assume a target semi-major
00105 //                  axis of 1 in determining the initial separation.
00106 
00107 local void initialize_root(sdyn* root, real v_inf, 
00108                            real rho_sq_min, real rho_sq_max, real peri,
00109                            real r_init,
00110                            real projectile_mass, real projectile_radius) {
00111 
00112     // Explicitly state target mass and radius:
00113 
00114     // NOTE that this will give unit radius to the target star in
00115     // a two-body encounter!
00116 
00117     real target_mass = 1;
00118     real target_sma = 1;
00119 
00120     real m_total = target_mass + projectile_mass;
00121     root->set_mass(m_total);
00122     root->set_pos(vector(0,0,0));
00123     root->set_vel(vector(0,0,0));
00124 
00125     sdyn* target = root->get_oldest_daughter();
00126     target->set_mass(target_mass);
00127     target->set_radius(target_sma);
00128 
00129     sdyn* projectile = target->get_younger_sister();
00130     projectile->set_mass(projectile_mass);
00131     projectile->set_radius(projectile_radius);
00132 
00133     // Establish the orbital elements of the scattering:
00134 
00135     v_inf *= sqrt(0.5*m_total);
00136     // Exactly one of rho_sq_max and peri should be < 0.
00137 
00138     if (rho_sq_max*peri > 0) err_exit("Inconsistent initial conditions.");
00139     
00140     real rho_max = -1;
00141     if(rho_sq_max>0)
00142       rho_max = sqrt(rho_sq_max);
00143 
00144     if (peri > 0) {
00145         if (v_inf > 0)
00146             rho_max = peri * sqrt(1 + 2*m_total/(peri*v_inf*v_inf));
00147         else
00148             rho_max = peri;
00149     }
00150     // Adjusted by (SPZ: 11 Oct 2000)
00151     // randomize rho \propto \sqrt{rho_max^2}
00152     real rho = sqrt(randinter(rho_sq_min, pow(rho_max, 2)));
00153     //    PRL(rho);
00154 
00155     // Note: Unit of velocity is v_g, not v_crit (identical for equal masses)
00156 
00157     real energy = .5 * v_inf * v_inf;
00158     real ang_mom = rho * v_inf;
00159 
00160     real ecc = (energy == 0 ? 1 : sqrt( 1 + 2 * energy
00161                                               * pow(ang_mom/m_total, 2)));
00162 
00163     // Special case: if v_inf = 0, assume rho is periastron.
00164 
00165     real virial_ratio = rho;
00166 
00167     kepler k;
00168 
00169     // Don't use mean_anomaly = 0 here (see scatter3.C):
00170 
00171     make_standard_kepler(k, 0, m_total, energy, ecc, virial_ratio, -0.001, 1);
00172 
00173     // Radius for "unperturbed" inner binary:
00174 
00175     real r_unp = (target_sma + projectile_radius)
00176                      * pow(TIDAL_TOL_FACTOR / m_total, -1/3.0);
00177 
00178     real r_start = min(r_init, r_unp);
00179     if (k.get_separation() < r_start)
00180         k.return_to_radius(r_start);
00181     else
00182         k.advance_to_radius(r_start);
00183 
00184     // Initialize the dynamics.
00185 
00186     root->set_time(k.get_time());
00187     target->set_time(k.get_time());
00188     projectile->set_time(k.get_time());
00189     
00190     target->set_pos(-projectile_mass * k.get_rel_pos() / m_total);
00191     target->set_vel(-projectile_mass * k.get_rel_vel() / m_total);
00192 
00193     projectile->set_pos(target_mass * k.get_rel_pos() / m_total);
00194     projectile->set_vel(target_mass * k.get_rel_vel() / m_total);
00195 
00196 //    cerr << "Initialized root...\n";
00197 //    pp(root, cerr);
00198 
00199 //    cerr << "t: " << target->get_index()
00200 //       <<" " << target->get_name() << endl;
00201 //    cerr << "p: " << projectile->get_index()
00202 //       << " "   << projectile->get_name() << endl;
00203 }
00204 
00205 // split_particle: Split the specified node into a binary with the specified
00206 //                 parameters.  All unspecified orbit elements are chosen
00207 //                 randomly.  Newly created nodes have names "n1" and "n2",
00208 //                 where "n" is the name of the node being split.
00209 
00210 local void split_particle(sdyn* current, real ecc, real sma, int planar,
00211                           real mass_ratio, real r1, real r2) {
00212 
00213     if (current->get_oldest_daughter() != NULL)
00214         err_exit("Can't split a binary node!");
00215 
00216     // Update the binary tree structure:
00217 
00218     sdyn* d1 = new sdyn;
00219     sdyn* d2 = new sdyn;
00220 
00221     current->set_oldest_daughter(d1);
00222 
00223     d1->set_parent(current);
00224     d2->set_parent(current);
00225 
00226     d1->set_younger_sister(d2);
00227     d2->set_elder_sister(d1);
00228 
00229     // Set new masses and radii:
00230 
00231     real m_total = current->get_mass();
00232     real m1 = m_total / (1 + mass_ratio);
00233     real m2 = m1 * mass_ratio;
00234 
00235     // By convention, first component has larger mass.
00236 
00237     if (m1 < m2) {
00238         real temp = m1;
00239         m1 = m2;
00240         m2 = temp;
00241     }
00242 
00243     d1->set_mass(m1);
00244     d2->set_mass(m2);
00245     
00246     //    PRC(m1);PRC(r1);PRC(m2);PRL(r2);
00247     d1->set_radius(r1);
00248     d2->set_radius(r2);
00249     
00250     // Sets parent radius (center of mass) to zero
00251     d2->get_parent()->set_radius(0);
00252 
00253     // Set internal orbital elements:
00254 
00255     kepler k;
00256 
00257     if (sma < 0) {
00258         sma = DEFAULT_SMA;
00259         for (int i = 1; i < strlen(current->get_name()); i++)
00260             sma /= SMA_REDUCE;
00261     }
00262 
00263     if (ecc < 0 || ecc >= 1) {
00264 
00265       // factor 2 for MIN_PERI_FACTOR see sdyn/util/make_tree.C
00266       real peri_min = 2*max(d1->get_radius(), d2->get_radius());
00267       real e_max = 1 - peri_min/sma;
00268 
00269       if(e_max<0) 
00270         err_exit("initial eccentricity out of bounds in split_particle(...)"); 
00271 
00272       // Thermal distribution in eccentricity
00273       if(STABILITY)
00274         ecc = sqrt(randinter(0, e_max*e_max));  
00275       else
00276         ecc = sqrt(randinter(0,1));     
00277     }
00278 
00279     //    cerr << "Splitting " << current->get_name();
00280     //    cerr << ",  planar flag = " << planar << endl;
00281     //    cerr << "ecc, sma = " << ecc << " " << sma << endl;
00282 
00283     real peri = 1; // Default value (unimportant unless ecc = 1).
00284     if (ecc == 1) peri = 0;
00285 
00286     // For now, binary phase is random.
00287 
00288     real mean_anomaly = randinter(-PI, PI);
00289 
00290     make_standard_kepler(k, 0, m_total, -0.5 * m_total / sma, ecc,
00291                          peri, mean_anomaly);
00292 
00293     set_random_orientation(k, planar);
00294 
00295     d1->set_time(current->get_time());
00296     d2->set_time(current->get_time());
00297 
00298     d1->set_pos(-m2 * k.get_rel_pos() / m_total);
00299     d1->set_vel(-m2 * k.get_rel_vel() / m_total);
00300 
00301     d2->set_pos(m1 * k.get_rel_pos() / m_total);
00302     d2->set_vel(m1 * k.get_rel_vel() / m_total);
00303 
00304     // Naming convention:
00305 
00306     d1->set_name(current->get_name());
00307     d2->set_name(current->get_name());
00308     strcat(d1->get_name(), "1");
00309     strcat(d2->get_name(), "2");
00310 
00311 //    cerr << "Pretty-print " << current->get_name() << endl;
00312 //    pp(current, cerr);
00313 }
00314 
00315 // locate_label_and_set_defaults: Return a pointer to the node with the
00316 //                                specified name, creating the binary tree
00317 //                                above it if necessary and establishing
00318 //                                default parameters at each level.
00319 
00320 // Note that the node name is strictly defined and the number of characters in
00321 // the name is the level in the binary tree: "t", "t1", "t11", "t112", etc.
00322 
00323 #include <string.h>
00324 local sdyn* locate_label_and_set_defaults(sdyn* root, char* label, int planar) {
00325 
00326     sdyn* b = root;
00327 
00328     for (int i = 0; i < strlen(label); i++) {
00329 
00330         char* name = strdup(label);
00331         name[i+1] = '\0';               // Truncate name to current level
00332 
00333         sdyn* node = NULL;
00334 
00335 //      cerr << "Looking for " << name<<endl;
00336 
00337         while (node == NULL) {
00338             for_all_daughters(sdyn, b, bb)
00339                 if (strcmp(bb->get_name(), name) == 0) node = bb;
00340             if (node == NULL) {
00341                 if (b->get_oldest_daughter() != NULL) return NULL;
00342 
00343 //              cerr << "Not found, making default daughters\n";
00344 
00345                 split_particle(b, DEFAULT_ECC, -1, planar,
00346                                DEFAULT_MASS_RATIO, DEFAULT_R1, DEFAULT_R2);
00347             } 
00348 //          else
00349 //              cerr << "Found " << node->get_name()<<endl;
00350         }
00351         b = node;
00352     }
00353     return b;
00354 }
00355 
00356 // first_leaf: return a pointer to the first leaf descended from the
00357 //             specified node.
00358 
00359 sdyn* first_leaf(sdyn* b)
00360 {
00361     while (b->get_oldest_daughter()) b = b->get_oldest_daughter();
00362     return b;
00363 }
00364 
00365 // next_leaf: return a pointer to the next leaf after the present node.
00366 
00367 sdyn* next_leaf(sdyn* b)
00368 {
00369     if (b == NULL)
00370 
00371         return NULL;
00372 
00373     else if (b->get_oldest_daughter())
00374 
00375         return first_leaf(b);
00376 
00377     else // Ascend the tree looking for a younger sister.
00378 
00379         while (b != NULL && b->get_younger_sister() == NULL)
00380             b = b->get_parent();
00381 
00382     return (b == NULL ? (sdyn*)NULL : first_leaf(b->get_younger_sister()));
00383 }
00384 
00385 sdyn* mkscat(int argc, char **argv) {
00386 
00387     // Establish standard configuration and names:
00388 
00389     sdyn* root = mksdyn(2);     // Top-level (unbound) scattering orbit.
00390     root->set_name("r");
00391     root->set_index(-1);        // Undo indexing effect of mksdyn...
00392 
00393     sdyn* target = root->get_oldest_daughter();
00394     target->set_name("t");
00395     target->set_index(-1);
00396 
00397     sdyn* projectile = target->get_younger_sister();
00398     projectile->set_name("p");
00399     projectile->set_index(-1);
00400 
00401     sdyn* current = root;       // Node currently under consideration.
00402 
00403     // Establish defaults for the top level:
00404 
00405     real projectile_mass = 1;   // Note convention: projectile and target have
00406     real projectile_radius = 0; //                  EQUAL masses by default.
00407     real v_inf = 1;
00408     real rho = 0;
00409     real rho_sq = 0;
00410     real peri = -1;
00411     real initial_separation = VERY_LARGE_NUMBER;
00412 
00413     real mass_ratio = DEFAULT_MASS_RATIO;   // Parameters to use when the
00414     real ecc = DEFAULT_ECC;                 // next binary is built
00415     real sma = DEFAULT_SMA;
00416     real r1 = DEFAULT_R1;
00417     real r2 = DEFAULT_R2;
00418 
00419     int  planar = 0;
00420     bool debug = FALSE;
00421 
00422     // First scan the argument list to get the actual random seed used:
00423 
00424     int  seed = 0;
00425     int i = 0;
00426     int random_seed;
00427     while (++i < argc)
00428         if (argv[i][0] == '-' && argv[i][1] == 's') {
00429           seed = atoi(argv[++i]);
00430           if(seed!=0) 
00431             random_seed = srandinter(seed);
00432           else
00433             cerr << "Seed not re-initialized" << endl;
00434           seed = -1;
00435         }
00436     if(seed>0) 
00437       random_seed = srandinter(seed);
00438 
00439     // Now parse the rest of the command line and initialize the system.
00440 
00441     i = 0;
00442     while (++i < argc) if (argv[i][0] == '-')
00443         switch (argv[i][1]) {
00444 
00445             // Top-level parameters:
00446 
00447             case 'M': if (current != root) cerr <<
00448                         "Too late to initialize projectile mass!\n";
00449                       projectile_mass = atof(argv[++i]);
00450                       break;
00451             case 'R': projectile_radius = atof(argv[++i]);
00452                       break;
00453             case 'r': switch(argv[i][2]) {
00454                           case '\0':    if (current != root) cerr <<
00455                               "Too late to initialize impact parameter!\n";
00456                                         rho = atof(argv[++i]);
00457                                         rho_sq = rho*rho;
00458                                         peri = -1;
00459                                         break;
00460                           case 'm':    if (current != root) cerr <<
00461                               "Too late to initialize pericenter!\n";
00462                                         peri = atof(argv[++i]);
00463                                         rho = -1;
00464                                         rho_sq = -1;
00465                                         break;
00466                           case '1':     r1 = atof(argv[++i]);
00467                                         break;
00468                           case '2':     r2 = atof(argv[++i]);
00469                                         break;
00470                           default:      cerr << "Incorrect 'r' flag ignored\n";
00471                                         break;
00472                       }
00473                       break;
00474             case 'S': initial_separation = atof(argv[++i]);
00475                       break;
00476             case 'v': if (current != root) cerr <<
00477                         "Too late to initialize velocity at infinity!\n";
00478                       v_inf = atof(argv[++i]);
00479                       break;
00480 
00481             // Begin accumulating parameters on a new node:
00482 
00483             case 'p':
00484             case 't': if (current == root)
00485                           initialize_root(root, v_inf, rho_sq, rho_sq, peri,
00486                                           initial_separation,
00487                                           projectile_mass, projectile_radius);
00488                       else
00489                           split_particle(current, ecc, sma, planar,
00490                                          mass_ratio, r1, r2);
00491 
00492                       current = locate_label_and_set_defaults(root,
00493                                                               &argv[i][1],
00494                                                               planar);
00495                       if (current == NULL) err_exit("Illegal node name.");
00496 
00497                       // Reset the defaults (note that planar isn't reset):
00498 
00499                       mass_ratio = DEFAULT_MASS_RATIO;
00500                       //                      ecc = DEFAULT_ECC;
00501                       ecc = sqrt(randinter(0, 1));
00502                       sma = -1;         // Impossible value
00503                       r1 = DEFAULT_R1;
00504                       r2 = DEFAULT_R2;
00505 
00506                       break;
00507 
00508             // Binary parameters:
00509 
00510             case 'a': sma = atof(argv[++i]);
00511                       break;
00512             case 'e': ecc = atof(argv[++i]);
00513                       break;
00514             case 'q': mass_ratio = atof(argv[++i]);
00515                       break;
00516 
00517             case 'P': switch(argv[i][2]) {
00518                           case '-':     planar = -1;
00519                                         break;
00520                           case '0':     planar = 0;
00521                                         break;
00522                           case '+':     planar = 1;
00523                                         break;
00524                           case '\0':    if (planar == 0)
00525                                             planar = 1;
00526                                         else
00527                                           planar = 0;
00528                                         break;
00529                           default:      cerr << "Incorrect 'P' flag ignored\n";
00530                                         break;
00531                       }
00532                         break;
00533 
00534             case 'd': debug = 1 - debug;
00535                       break;
00536             case 's': break;
00537 
00538             default:  cerr << "usage: mkscat [-d] [-s #]"
00539                            << " [-M #] [-r #] [-rm #] [-v #] [-R #] [-S #]"
00540                            << " [ -t/p... [-a #] [-e #] [-q #] [-P[+/-]"
00541                            << " [-r1 #] [-r2 #] ] [-t/p... ...]"
00542                            << endl;
00543                       exit(1);
00544         }
00545 
00546     // Initialize the last piece:
00547 
00548     if (current == root)
00549         initialize_root(root, v_inf, rho_sq, rho_sq, peri, initial_separation,
00550                         projectile_mass, projectile_radius);
00551     else
00552         split_particle(current, ecc, sma, planar,
00553                        mass_ratio, r1, r2);
00554 
00555     // Finally, assign sequential indices to the particles, for the
00556     // convenience of xstarplot and other display/reduction programs.
00557 
00558     int id = 0;
00559     sdyn* b = first_leaf(root);
00560     while (b) {
00561         b->set_index(++id);
00562         b = next_leaf(b);
00563     }
00564 
00565 //----------------------------------------------------------------------------
00566 
00567     root->log_history(argc, argv);
00568 
00569     char seedlog[80];
00570     sprintf(seedlog, "           random seed = %d",
00571             random_seed);
00572     root->log_comment(seedlog);
00573 
00574     if (0) {
00575         cerr << "mkscat: pretty-print system (seed = "
00576              << random_seed << "):\n";
00577         pp(root, cerr);
00578     }
00579 
00580     return root;
00581 }
00582 
00583 sdyn* mkscat(int argc, char **argv, scatter_profile &prof) {
00584 
00585 
00586     // Establish standard configuration and names:
00587 
00588     sdyn* root = mksdyn(2);     // Top-level (unbound) scattering orbit.
00589     root->set_name("r");
00590     root->set_index(-1);        // Undo indexing effect of mksdyn...
00591 
00592     sdyn* target = root->get_oldest_daughter();
00593     target->set_name("t");
00594     target->set_index(-1);
00595 
00596     sdyn* projectile = target->get_younger_sister();
00597     projectile->set_name("p");
00598     projectile->set_index(-1);
00599 
00600     sdyn* current = root;       // Node currently under consideration.
00601 
00602     // Establish defaults for the top level:
00603 
00604     real projectile_mass = 1;   // Note convention: projectile and target have
00605     real projectile_radius = 0; //                  EQUAL masses by default.
00606     real v_inf = 1;
00607     real rho = 0;
00608     real peri = -1;
00609     real initial_separation = VERY_LARGE_NUMBER;
00610 
00611     real mass_ratio = DEFAULT_MASS_RATIO;   // Parameters to use when the
00612     real ecc = DEFAULT_ECC;                 // next binary is built
00613     real sma = DEFAULT_SMA;
00614     real r1 = DEFAULT_R1;
00615     real r2 = DEFAULT_R2;
00616 
00617     int  planar = 0;
00618     bool debug = FALSE;
00619 
00620     // First scan the argument list to get the actual random seed used:
00621 
00622     int  seed = 0;
00623     int i = 0;
00624     int random_seed;
00625     while (++i < argc)
00626         if (argv[i][0] == '-' && argv[i][1] == 's') {
00627           seed = atoi(argv[++i]);
00628           if(seed!=0) 
00629             random_seed = srandinter(seed);
00630           else
00631             cerr << "Seed not re-initialized" << endl;
00632           seed = -1;
00633         }
00634     if(seed>0) 
00635       random_seed = srandinter(seed);
00636 
00637     // Now parse the rest of the command line and initialize the system.
00638 
00639     i = 0;
00640     while (++i < argc) if (argv[i][0] == '-')
00641         switch (argv[i][1]) {
00642 
00643             // Top-level parameters:
00644 
00645             case 'M': if (current != root) cerr <<
00646                         "Too late to initialize projectile mass!\n";
00647                       projectile_mass = atof(argv[++i]);
00648                       prof.mp = projectile_mass;
00649                       break;
00650             case 'R': projectile_radius = atof(argv[++i]);
00651                       prof.ap = projectile_radius;
00652                       break;
00653             case 'r': switch(argv[i][2]) {
00654                           case '\0':    if (current != root) cerr <<
00655                               "Too late to initialize impact parameter!\n";
00656                                         if(prof.rho_sq_max<0 && prof.peri<0) {
00657                                           rho = atof(argv[++i]);
00658                                           peri = -1;
00659                                           prof.rho_sq_max = rho*rho;
00660                                           prof.peri = -1;
00661                                         }
00662                                         break;
00663                           case 'm':    if (current != root) cerr <<
00664                               "Too late to initialize pericenter!\n";
00665                                         if(prof.rho_sq_max<0 && prof.peri<0) {
00666                                           peri = atof(argv[++i]);
00667                                           rho = -1;
00668                                           prof.peri = peri;
00669                                           prof.rho_sq_max = rho;
00670                                         }
00671                                         break;
00672                           case '1':     r1 = atof(argv[++i]);
00673                                         break;
00674                           case '2':     r2 = atof(argv[++i]);
00675                                         break;
00676                           default:      cerr << "Incorrect 'r' flag ignored\n";
00677                                         break;
00678                       }
00679                       break;
00680             case 'S': initial_separation = atof(argv[++i]);
00681                       break;
00682             case 'v': if (current != root) cerr <<
00683                         "Too late to initialize velocity at infinity!\n";
00684                       if(prof.rho_sq_max<0 && prof.peri<0) {
00685                         v_inf = atof(argv[++i]);
00686                         prof.v_inf = v_inf;
00687                       }
00688                       break;
00689 
00690             // Begin accumulating parameters on a new node:
00691 
00692             case 'p':
00693             case 't': if (current == root)
00694                           initialize_root(root, prof.v_inf, 
00695                                           prof.rho_sq_min, prof.rho_sq_max, 
00696                                           prof.peri,
00697                                           initial_separation,
00698                                           projectile_mass, projectile_radius);
00699                       else
00700                           split_particle(current, ecc, sma, planar,
00701                                          mass_ratio, r1, r2);
00702 
00703                       current = locate_label_and_set_defaults(root,
00704                                                               &argv[i][1],
00705                                                               planar);
00706                       if (current == NULL) err_exit("Illegal node name.");
00707 
00708                       // Reset the defaults (note that planar isn't reset):
00709 
00710                       mass_ratio = DEFAULT_MASS_RATIO;
00711                       //                      ecc = DEFAULT_ECC;
00712                       ecc = sqrt(randinter(0, 1));
00713                       sma = -1;         // Impossible value
00714                       r1 = DEFAULT_R1;
00715                       r2 = DEFAULT_R2;
00716 
00717                       break;
00718 
00719             // Binary parameters:
00720 
00721             case 'a': sma = atof(argv[++i]);
00722                       break;
00723             case 'e': ecc = atof(argv[++i]);
00724                       break;
00725             case 'q': mass_ratio = atof(argv[++i]);
00726                       break;
00727 
00728             case 'P': switch(argv[i][2]) {
00729                           case '-':     planar = -1;
00730                                         break;
00731                           case '0':     planar = 0;
00732                                         break;
00733                           case '+':     planar = 1;
00734                                         break;
00735                           case '\0':    if (planar == 0)
00736                                             planar = 1;
00737                                         else
00738                                           planar = 0;
00739                                         break;
00740                           default:      cerr << "Incorrect 'P' flag ignored\n";
00741                                         break;
00742                       }
00743                         break;
00744 
00745             case 'd': debug = 1 - debug;
00746                       break;
00747             case 's': break;
00748 
00749             default:  cerr << "usage: mkscat [-d] [-s #]"
00750                            << " [-M #] [-r #] [-rm #] [-v #] [-R #] [-S #]"
00751                            << " [ -t/p... [-a #] [-e #] [-q #] [-P[+/-]"
00752                            << " [-r1 #] [-r2 #] ] [-t/p... ...]"
00753                            << endl;
00754                       exit(1);
00755         }
00756 
00757     // Initialize the last piece:
00758 
00759     if (current == root)
00760         initialize_root(root, prof.v_inf, prof.rho_sq_min, prof.rho_sq_max, 
00761                         prof.peri, 
00762                         initial_separation,
00763                         projectile_mass, projectile_radius);
00764     else
00765         split_particle(current, ecc, sma, planar,
00766                        mass_ratio, r1, r2);
00767 
00768     // Finally, assign sequential indices to the particles, for the
00769     // convenience of xstarplot and other display/reduction programs.
00770 
00771     int id = 0;
00772     sdyn* b = first_leaf(root);
00773     while (b) {
00774         b->set_index(++id);
00775         b = next_leaf(b);
00776     }
00777 
00778 //----------------------------------------------------------------------------
00779 
00780     root->log_history(argc, argv);
00781 
00782     char seedlog[80];
00783     sprintf(seedlog, "           random seed = %d",
00784             random_seed);
00785     root->log_comment(seedlog);
00786 
00787     if (0) {
00788         cerr << "mkscat: pretty-print system (seed = "
00789              << random_seed << "):\n";
00790         pp(root, cerr);
00791     }
00792 
00793     return root;
00794 }
00795 
00796 #define TEXT_BUFFER_SIZE 1024
00797 
00798 static char temp[TEXT_BUFFER_SIZE];     // argv will point into this array
00799 static char* name = "parse_string";     // Any name will do...
00800 
00801 // parse_string: Split a character string into words.  Return a list of
00802 //               substrings, using the same conventions as argc and argv
00803 //               in UNIX (0 --> "parse_string").
00804 
00805 void parse_string(char* s, int& argc, char* argv[]) {
00806 
00807     int length = strlen(s);
00808     if (length >= TEXT_BUFFER_SIZE) err_exit("String too long.");
00809 
00810     argv[0] = name;
00811     argc = 1;
00812 
00813     int first = 0, last = -1;  // First and last characters of the current word
00814 
00815     for (int i = 0; i <= length; i++) {
00816         temp[i] = s[i];
00817         if (temp[i] == ' ' || i == length) {
00818             if (last >= 0) {                            // End of word
00819                 temp[i] = '\0';
00820                 argv[argc++] = temp + first;            // *No* check on argc
00821             }
00822             last = -1;
00823         } else {
00824             if (last < 0) first = i;                    // Start of word
00825             last = i;
00826         }
00827     }
00828 }
00829 
00830 
00831 #define MAX_ARGS 256
00832 
00833 sdyn* mkscat(char* s, scatter_profile &prof) {  
00834                                     // Character string interface to mkscat
00835     int argc;
00836     char* argv[MAX_ARGS];
00837 
00838     parse_string(s, argc, argv);
00839     if (argc > MAX_ARGS) err_exit("Too many arguments.");
00840 
00841     return mkscat(argc, argv, prof);
00842 }    
00843 
00844 sdyn* mkscat(char* s) {   // Character string interface to mkscat
00845 
00846     int argc;
00847     char* argv[MAX_ARGS];
00848 
00849     parse_string(s, argc, argv);
00850     if (argc > MAX_ARGS) err_exit("Too many arguments.");
00851 
00852     return mkscat(argc, argv);
00853 }    
00854 
00855 #else
00856 
00857 main(int argc, char** argv) {
00858     check_help();
00859     //    sdyn * root = mkscat(argc, argv);
00860     //    put_sdyn(cout, *root);
00861 }
00862 
00863 #endif

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