00001
00002
00003
00004
00005
00006
00007
00008 #include "dyn.h"
00009
00010 #ifdef TOOLBOX
00011
00012
00013
00014
00015
00016
00017 local bool split_particle(dyn* bi, real ecc, real sma, real mass_ratio)
00018 {
00019 if (bi->get_oldest_daughter() != NULL) {
00020 cerr << "Can't split a binary node!\n";
00021 return false;
00022 } else if (sma <= 0) {
00023 cerr << "Must specify semi-major axis > 0.\n";
00024 return false;
00025 } else if (ecc < 0 || ecc >= 1) {
00026 cerr << "Must specify eccentricity in [0,1).\n";
00027 return false;
00028 } else if (mass_ratio <= 0 || mass_ratio > 1) {
00029 cerr << "Must specify mass ratio in (0,1]!\n";
00030 return false;
00031 }
00032
00033
00034
00035 dyn* d1 = new dyn;
00036 dyn* d2 = new dyn;
00037
00038 bi->set_oldest_daughter(d1);
00039
00040 d1->set_parent(bi);
00041 d2->set_parent(bi);
00042
00043 d1->set_younger_sister(d2);
00044 d2->set_elder_sister(d1);
00045
00046
00047
00048 real m_total = bi->get_mass();
00049 real m1 = m_total / (1 + mass_ratio);
00050 real m2 = m1 * mass_ratio;
00051
00052
00053
00054 if (m1 < m2) {
00055 real temp = m1;
00056 m1 = m2;
00057 m2 = temp;
00058 }
00059
00060 d1->set_mass(m1);
00061 d2->set_mass(m2);
00062
00063
00064
00065 kepler k;
00066
00067 real peri = 1;
00068 if (ecc == 1) peri = 0;
00069
00070
00071
00072 real mean_anomaly = randinter(-PI, PI);
00073
00074 make_standard_kepler(k, 0, m_total, -0.5 * m_total / sma, ecc,
00075 peri, mean_anomaly);
00076
00077 set_random_orientation(k);
00078
00079 d1->set_pos(-m2 * k.get_rel_pos() / m_total);
00080 d1->set_vel(-m2 * k.get_rel_vel() / m_total);
00081
00082 d2->set_pos(m1 * k.get_rel_pos() / m_total);
00083 d2->set_vel(m1 * k.get_rel_vel() / m_total);
00084
00085
00086
00087 if (bi->get_name() == NULL)
00088 if (bi->get_index() >= 0) {
00089 char tmp[64];
00090 sprintf(tmp, "%d", bi->get_index());
00091 bi->set_name(tmp);
00092 }
00093
00094 d1->set_name(bi->get_name());
00095 d2->set_name(bi->get_name());
00096 strcat(d1->get_name(), "a");
00097 strcat(d2->get_name(), "b");
00098
00099 return true;
00100 }
00101
00102
00103
00104 #include <string.h>
00105
00106 local dyn* leaf_with_label(dyn* b, char* label)
00107 {
00108 for_all_leaves(dyn, b, bi) {
00109 if (bi->get_name() != NULL) {
00110 if (strcmp(bi->get_name(), label) == 0)
00111 return bi;
00112 } else if (bi->get_index() >= 0) {
00113 char id[64];
00114 sprintf(id, "%d", bi->get_index());
00115 if (strcmp(id, label) == 0)
00116 return bi;
00117 }
00118 }
00119 return NULL;
00120 }
00121
00122 local void scale_energy(real energy, int N, real M, real E)
00123 {
00124
00125
00126 energy *= (-E / (1.5*N));
00127 }
00128
00129
00130
00131 void main(int argc, char ** argv)
00132 {
00133 real energy = 0.0;
00134 real eccentricity = -1;
00135 real semi_major_axis = 0.1;
00136 real mass_ratio = 1.0;
00137 int random_seed = 0;
00138 char seedlog[64];
00139 char label[64];
00140
00141 label[0] = '\0';
00142
00143 extern char *poptarg;
00144 int c;
00145 char* param_string = "a:e:E:l:s:o:";
00146
00147 while ((c = pgetopt(argc, argv, param_string)) != -1)
00148 switch(c) {
00149
00150 case 'a': semi_major_axis = atof(poptarg);
00151 break;
00152 case 'e': eccentricity = atof(poptarg);
00153 break;
00154 case 'E': energy = atof(poptarg);
00155 break;
00156 case 'l': strcpy(label, poptarg);
00157 break;
00158 case 'q': mass_ratio = atof(poptarg);
00159 break;
00160 case 's': random_seed = atoi(poptarg);
00161 break;
00162 case '?': params_to_usage(cerr, argv[0], param_string);
00163 exit(1);
00164 }
00165
00166 if (label[0] == '\0')
00167 err_exit("must specify a particle label");
00168
00169 dyn* b;
00170 b = get_dyn(cin);
00171
00172
00173
00174 b->log_history(argc, argv);
00175
00176 int actual_seed = srandinter(random_seed);
00177
00178 sprintf(seedlog,
00179 " random number generator seed = %d",actual_seed);
00180 b->log_comment(seedlog);
00181
00182 if (eccentricity < 0)
00183 eccentricity = sqrt(randinter(0,1));
00184
00185 if (energy < 0) {
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 char* energy_string = "initial_total_energy";
00196
00197 if (find_qmatch(b->get_dyn_story(), energy_string))
00198 scale_energy(energy, b->n_daughters(), b->get_mass(),
00199 getrq(b->get_dyn_story(), energy_string));
00200 else
00201 cerr << "split_particle: Using unscaled energy limits.\n";
00202
00203 }
00204
00205
00206
00207 dyn* bi = leaf_with_label(b, label);
00208
00209 if (bi == NULL) {
00210
00211
00212
00213 cerr << "Warning: particle " << label << " not found.\n";
00214 put_dyn(cout, *b);
00215
00216 } else {
00217
00218
00219
00220 if (energy < 0)
00221 semi_major_axis = (1 - mass_ratio) * bi->get_mass()
00222 * mass_ratio * bi->get_mass()
00223 / (-2 * energy);
00224
00225
00226
00227 if (split_particle(bi, eccentricity, semi_major_axis, mass_ratio))
00228 put_dyn(cout, *b);
00229 }
00230 }
00231
00232 #endif