00001 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 #include "dyn.h"
00037 
00038 #ifdef TOOLBOX
00039 
00040 
00041 
00042 
00043 
00044 
00045 local bool split_particle(dyn* bi, real ecc, real sma, real mass_ratio)
00046 {
00047     if (bi->get_oldest_daughter() != NULL) {
00048         cerr << "Can't split a binary node!\n";
00049         return false;
00050     } else if (sma <= 0) {
00051         cerr << "Must specify semi-major axis > 0.\n";
00052         return false;
00053     } else if (ecc < 0 || ecc >= 1) {
00054         cerr << "Must specify eccentricity in [0,1).\n";
00055         return false;
00056     } else if (mass_ratio <= 0 || mass_ratio > 1) {
00057         cerr << "Must specify mass ratio in (0,1]!\n";
00058         return false;
00059     }
00060 
00061     
00062 
00063     dyn* d1 = new dyn;
00064     dyn* d2 = new dyn;
00065 
00066     bi->set_oldest_daughter(d1);
00067 
00068     d1->set_parent(bi);
00069     d2->set_parent(bi);
00070 
00071     d1->set_younger_sister(d2);
00072     d2->set_elder_sister(d1);
00073 
00074     
00075 
00076     real m_total = bi->get_mass();
00077     real m1 = m_total / (1 + mass_ratio);
00078     real m2 = m1 * mass_ratio;
00079 
00080     
00081 
00082     if (m1 < m2) {
00083         real temp = m1;
00084         m1 = m2;
00085         m2 = temp;
00086     }
00087 
00088     d1->set_mass(m1);
00089     d2->set_mass(m2);
00090 
00091     
00092 
00093     kepler k;
00094 
00095     real peri = 1; 
00096     if (ecc == 1) peri = 0;
00097 
00098     
00099 
00100     real mean_anomaly = randinter(-PI, PI);
00101 
00102     make_standard_kepler(k, 0, m_total, -0.5 * m_total / sma, ecc,
00103                          peri, mean_anomaly);
00104 
00105     set_random_orientation(k);
00106 
00107     d1->set_pos(-m2 * k.get_rel_pos() / m_total);
00108     d1->set_vel(-m2 * k.get_rel_vel() / m_total);
00109 
00110     d2->set_pos(m1 * k.get_rel_pos() / m_total);
00111     d2->set_vel(m1 * k.get_rel_vel() / m_total);
00112 
00113     
00114 
00115     if (bi->get_name() == NULL)
00116         if (bi->get_index() >= 0) {
00117             char tmp[64];
00118             sprintf(tmp, "%d", bi->get_index());
00119             bi->set_name(tmp);
00120         }
00121 
00122     d1->set_name(bi->get_name());
00123     d2->set_name(bi->get_name());
00124     strcat(d1->get_name(), "a");
00125     strcat(d2->get_name(), "b");
00126 
00127     return true;
00128 }
00129 
00130 
00131 
00132 #include <string.h>
00133 
00134 local dyn* leaf_with_label(dyn* b, char* label)
00135 {
00136     for_all_leaves(dyn, b, bi) {
00137         if (bi->get_name() != NULL) {
00138             if (strcmp(bi->get_name(), label) == 0)
00139                 return bi;
00140         } else if (bi->get_index() >= 0) {
00141             char id[64];
00142             sprintf(id, "%d", bi->get_index());
00143             if (strcmp(id, label) == 0)
00144                 return bi;
00145         }
00146     }
00147     return NULL;
00148 }
00149 
00150 local void scale_energy(real energy, int N, real M, real E)
00151 {
00152     
00153 
00154     energy *= (-E / (1.5*N));
00155 }
00156 
00157 
00158 
00159 local void check_and_initialize(dyn* b, char* label,
00160                                 real eccentricity, real energy,
00161                                 real semi_major_axis, real mass_ratio)
00162 {
00163     if (eccentricity < 0)
00164         eccentricity = sqrt(randinter(0,1));    
00165 
00166     if (energy < 0) {
00167 
00168         
00169 
00170         
00171         
00172 
00173         
00174         
00175 
00176         char* energy_string = "initial_total_energy";
00177 
00178         if (find_qmatch(b->get_dyn_story(), energy_string))
00179             scale_energy(energy, b->n_daughters(), b->get_mass(),
00180                          getrq(b->get_dyn_story(), energy_string));
00181         else
00182             cerr << "split_particle: Using unscaled energy limits.\n";
00183 
00184     }
00185 
00186     
00187 
00188     dyn* bi = leaf_with_label(b, label);
00189 
00190     if (bi == NULL) {
00191 
00192         cerr << "Warning: particle \"" << label << "\" not found.\n";
00193 
00194     } else {
00195 
00196         
00197 
00198         if (energy < 0)
00199             semi_major_axis = (1 - mass_ratio) * bi->get_mass()
00200                                 * mass_ratio * bi->get_mass()
00201                                         / (-2 * energy);
00202 
00203         
00204 
00205         if (!split_particle(bi, eccentricity, semi_major_axis, mass_ratio))
00206             err_exit("fatal error");
00207     }
00208 }
00209 
00210 #define DEFAULT_ENERGY           0.0
00211 #define DEFAULT_ECC             -1.0
00212 #define DEFAULT_SMA              0.1
00213 #define DEFAULT_Q                1.0
00214 
00215 void main(int argc, char ** argv)
00216 {
00217     real energy = DEFAULT_ENERGY;
00218     real eccentricity = DEFAULT_ECC;
00219     real semi_major_axis = DEFAULT_SMA;
00220     real mass_ratio = DEFAULT_Q;
00221 
00222     char label[64];
00223     label[0] = '\0';
00224     bool previous_label = false;
00225 
00226     int random_seed = 0;
00227     char seedlog[64];
00228 
00229     check_help();
00230 
00231     dyn* b;
00232     b = get_dyn(cin);
00233 
00234     b->log_history(argc, argv);
00235 
00236     
00237 
00238     int i = 0;
00239     while (++i < argc)
00240         if (argv[i][0] == '-')
00241             switch (argv[i][1]) {
00242 
00243                 case 'a': semi_major_axis = atof(argv[++i]);
00244                           break;
00245 
00246                 case 'e': eccentricity = atof(argv[++i]);
00247                           break;
00248 
00249                 case 'E': energy = atof(argv[++i]);
00250                           break;
00251 
00252                 case 'l': if (previous_label)
00253 
00254                               
00255                               
00256 
00257                               check_and_initialize(b, label,
00258                                                    eccentricity, energy,
00259                                                    semi_major_axis, mass_ratio);
00260 
00261                           strcpy(label, argv[++i]);
00262 
00263                           
00264                           
00265                           
00266 
00267                           energy = DEFAULT_ENERGY;
00268                           eccentricity = DEFAULT_ECC;
00269                           semi_major_axis = DEFAULT_SMA;
00270                           mass_ratio = DEFAULT_Q;
00271 
00272                           previous_label = true;
00273                           break;
00274 
00275                 case 'q': mass_ratio = atof(argv[++i]);
00276                           break;
00277 
00278                 case 's': {
00279                           random_seed = atoi(argv[++i]);
00280                           int actual_seed = srandinter(random_seed);
00281                           sprintf(seedlog,
00282                                   "       random number generator seed = %d",
00283                                   actual_seed);
00284                           b->log_comment(seedlog);
00285                           }
00286                           break;
00287 
00288                 default:  get_help();
00289                           exit(1);
00290             }
00291 
00292     if (previous_label)
00293         check_and_initialize(b, label,
00294                              eccentricity, energy,
00295                              semi_major_axis, mass_ratio);
00296 
00297     put_dyn(cout, *b);
00298 }
00299 
00300 #endif