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