00001
00002 #include "cluster_support.h"
00003
00004
00005
00006
00007
00008
00009
00010 void make_profile(initial_cluster& c_init,
00011 cluster_profile& c_prof, profile prof,
00012 star_type_spec s_prof = Emission) {
00013
00014 double_profile binary;
00015 double_init b_init;
00016
00017 if (!c_init.field) {
00018 real m_to = turn_off_mass(c_init.end_time);
00019 cout << "Turn off mass (" << type_string(get_spectral_class(m_to))
00020 << ") = " << turn_off_mass(c_init.end_time)
00021 << " Solar mass."<< endl;
00022 }
00023
00024 for (int i=0; i<c_init.no_of_binaries; i++) {
00025 b_init = c_init.random_initial_conditions();
00026 make_profile(i+1, c_init.start_time, binary, b_init);
00027 c_prof.enhance_cluster_profile(binary, prof, s_prof);
00028 }
00029
00030 }
00031
00032
00033
00034
00035
00036
00037 cluster_profile::cluster_profile() {
00038
00039 no_of_init_bins=no_of_fin_bins=0;
00040 no_of_runners=no_of_mergers=no_of_singles=0;
00041
00042 for (int s=MIN_TYPE_NUMBER; s<MAX_TYPE_NUMBER; s++) {
00043 for (int p=MIN_TYPE_NUMBER; p<MAX_TYPE_NUMBER; p++) {
00044 init_bins[p][s] = 0;
00045 fin_bins[p][s] = 0;
00046 bins_stt[p][s] = 0;
00047 bins_spt[p][s] = 0;
00048 for (int t = NAC; t<no_of_spec_type; t++)
00049 bins_spa[p][s][t] = 0;
00050 }
00051 singles[s] = 0;
00052 mergers[s] = 0;
00053 single_stt[s] = 0;
00054 single_spt[s] = 0;
00055 merge_stt[s] = 0;
00056 merge_spt[s] = 0;
00057 runner_stt[s] = 0;
00058 runner_spt[s] = 0;
00059 for (int t = NAC; t<no_of_spec_type; t++) {
00060 single_spa[s][t] = 0;
00061 merge_spa[s][t] = 0;
00062 runner_spa[s][t] = 0;
00063 }
00064 }
00065
00066 }
00067
00068
00069
00070
00071
00072 void cluster_profile::enhance_cluster_profile(double_profile& binary,
00073 profile prof,
00074 star_type_spec s_prof = Emission) {
00075
00076 if (prof==star_type)
00077 star_type_cluster_profile(binary);
00078 else if (prof==spectral_type)
00079 spectral_type_cluster_profile(binary);
00080 else if (prof==spectral_addition)
00081 spectral_addition_cluster_profile(binary, s_prof);
00082 else {
00083 cerr << "cluster_profile::enhance_cluster_profile()" <<endl;
00084 cerr << "profile type unknown" << endl;
00085 }
00086 }
00087
00088 void cluster_profile::enhance_cluster_profile(double_profile& binary) {
00089
00090 star_type_cluster_profile(binary);
00091 spectral_type_cluster_profile(binary);
00092 for (int prof = Emission; prof<no_of_spec_type; prof++)
00093 spectral_addition_cluster_profile(binary, (star_type_spec)prof);
00094 }
00095
00096 void cluster_profile::enhance_cluster_profile(star_state& single) {
00097
00098 star_type_cluster_profile(single);
00099 spectral_type_cluster_profile(single);
00100 for (int prof = Emission; prof<no_of_spec_type; prof++)
00101 spectral_addition_cluster_profile(single, (star_type_spec)prof);
00102 }
00103
00104 void cluster_profile::star_type_cluster_profile(double_profile& binary) {
00105
00106 init_bins[binary.init.primary.type][binary.init.secondary.type]++;
00107 no_of_init_bins++;
00108
00109 if (binary.final.type==Merged) {
00110 merge_stt[binary.final.primary.type]++;
00111 }
00112 else if (binary.final.type==Disrupted) {
00113 runner_stt[binary.final.primary.type]++;
00114 runner_stt[binary.final.secondary.type]++;
00115 }
00116 else {
00117 bins_stt[binary.final.primary.type]
00118 [binary.final.secondary.type]++;
00119 }
00120 }
00121
00122 void cluster_profile::star_type_cluster_profile(star_state& single) {
00123
00124 if (single.class_spec[Merger])
00125 merge_stt[single.type]++;
00126 else if (single.class_spec[Runaway])
00127 runner_stt[single.type]++;
00128 else
00129 single_stt[single.type]++;
00130 }
00131
00132 void cluster_profile::spectral_type_cluster_profile(double_profile& binary) {
00133
00134
00135 init_bins[binary.init.primary.class_tpe]
00136 [binary.init.secondary.class_tpe]++;
00137
00138 if (binary.final.type==Merged) {
00139 merge_spt[binary.final.primary.class_tpe]++;
00140 }
00141 else if (binary.final.type==Disrupted) {
00142 runner_spt[binary.final.primary.class_tpe]++;
00143 runner_spt[binary.final.secondary.class_tpe]++;
00144 }
00145 else {
00146 bins_spt[binary.final.primary.class_tpe]
00147 [binary.final.secondary.class_tpe]++;
00148 }
00149 }
00150
00151 void cluster_profile::spectral_type_cluster_profile(star_state& single) {
00152
00153 if (single.class_spec[Merger])
00154 merge_spt[single.class_tpe]++;
00155 else if (single.class_spec[Runaway])
00156 runner_spt[single.class_tpe]++;
00157 else
00158 single_spt[single.class_tpe]++;
00159 no_of_singles++;
00160 }
00161
00162 void cluster_profile::spectral_addition_cluster_profile(double_profile& binary,
00163 star_type_spec s_prof) {
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 if (binary.final.primary.class_spec[s_prof]) {
00174 init_bins[binary.final.primary.class_tpe]
00175 [binary.final.secondary.class_tpe]++;
00176 no_of_init_bins++;
00177 }
00178
00179 if (binary.final.type==Disrupted) {
00180 if (binary.final.primary.class_spec[s_prof]) {
00181 runner_spa[binary.final.primary.class_tpe][s_prof]++;
00182 }
00183 if (binary.final.secondary.class_spec[s_prof]) {
00184 runner_spa[binary.final.secondary.class_tpe][s_prof]++;
00185 }
00186 }
00187 else if (binary.final.type==Merged) {
00188 if (binary.final.primary.class_spec[s_prof]) {
00189 merge_spa[binary.final.primary.class_tpe][s_prof]++;
00190 }
00191 }
00192 else {
00193
00194
00195 if (binary.final.primary.class_spec[s_prof]) {
00196 bins_spa[binary.final.primary.class_tpe]
00197 [binary.final.secondary.class_tpe][s_prof]++;
00198 }
00199 else if (binary.final.secondary.class_spec[s_prof]) {
00200 bins_spa[binary.final.secondary.class_tpe]
00201 [binary.final.primary.class_tpe][s_prof]++;
00202 }
00203 }
00204 }
00205
00206 void cluster_profile::spectral_addition_cluster_profile(star_state& single,
00207 star_type_spec prof) {
00208 if (single.class_spec[prof]) {
00209 if (single.class_spec[Merger])
00210 merge_spa[single.class_tpe][prof]++;
00211 else if (single.class_spec[Runaway])
00212 runner_spa[single.class_tpe][prof]++;
00213 else
00214 single_spa[single.class_tpe][prof]++;
00215 }
00216 }
00217
00218
00219 void cluster_profile::spectral_addition_single_profile(double_profile& binary,
00220 star_type_spec s_prof) {
00221
00222
00223
00224
00225 if (binary.final.primary.class_spec[s_prof])
00226 bins_spa[binary.final.primary.type]
00227 [binary.final.secondary.class_tpe][s_prof]++;
00228 else if (binary.final.secondary.class_spec[s_prof])
00229 bins_spa[binary.final.secondary.type]
00230 [binary.final.primary.class_tpe][s_prof]++;
00231 }
00232
00233 void cluster_profile::print_profile() {
00234
00235
00236 print_profile(Main_Sequence);
00237 print_profile(O5);
00238
00239 for (int type=Emission; type<no_of_spec_type; type++)
00240 print_profile((star_type_spec)type,star_type);
00241
00242 }
00243
00244 void cluster_profile::print_profile(profile prof) {
00245
00246 if (prof==star_type) {
00247 cout << "Stellar type data:" << endl;
00248 print_profile(Main_Sequence);
00249 }
00250 else if (prof==spectral_type) {
00251 cout << "Spectral type data:" << endl;
00252 print_profile(O5);
00253
00254 }
00255 else if (prof==spectral_addition) {
00256 print_profile(Emission, prof);
00257 }
00258 else {
00259 cerr << "cluster_profile::print_profile()" <<endl;
00260 cerr << "profile type unknown" << endl;
00261 }
00262 }
00263
00264 void cluster_profile::print_profile(stellar_type type) {
00265
00266
00267
00268 int s, p;
00269 int v_min = Main_Sequence;
00270 int v_max = no_of_stellar_type;
00271
00272 cout << endl << endl;
00273
00274 cout <<"\t";
00275 for (s=v_min; s<v_max; s++) {
00276
00277 cout << type_short_string((stellar_type)s) <<"\t";
00278 }
00279
00280 cout << endl;
00281 for (s=v_min; s<v_max; s++) {
00282
00283 cout << type_short_string((stellar_type)s) << "\t";
00284 for (p=v_min; p<v_max; p++) {
00285
00286 cout << bins_stt[p][s] << "\t";
00287 }
00288 cout << endl;
00289 }
00290
00291 cout << endl;
00292
00293 cout <<"\t";
00294 for (s=v_min; s<v_max; s++)
00295 cout << type_short_string((stellar_type)s) <<"\t";
00296 cout << endl;
00297 cout << "runaway\t";
00298 for (s=v_min; s<v_max; s++)
00299 cout << runner_stt[s] << "\t";
00300 cout << endl;
00301 cout << "mergers\t";
00302 for (s=v_min; s<v_max; s++)
00303 cout << merge_stt[s] << "\t";
00304 cout << endl;
00305 cout << "singles\t";
00306 for (s=v_min; s<v_max; s++)
00307 cout << single_stt[s] << "\t";
00308 cout << endl;
00309 }
00310
00311
00312
00313 void cluster_profile::print_profile(spectral_class type) {
00314
00315
00316
00317 int s, p;
00318 int v_min = O5;
00319 int v_max = no_spectral_class;
00320
00321
00322 cout << endl;
00323 cout <<"\t";
00324 for (s=v_min; s<v_max; s++)
00325 cout << type_string((spectral_class)s) <<"\t";
00326 cout << endl;
00327 for (s=v_min; s<v_max; s++) {
00328 cout << type_string((spectral_class)s) << "\t";
00329 for (p=v_min; p<v_max; p++)
00330 cout << bins_spt[p][s] << "\t";
00331 cout << endl;
00332 }
00333
00334
00335 cout << endl;
00336
00337 cout <<"\t";
00338 for (s=v_min; s<v_max; s++)
00339 cout << type_string((spectral_class)s) <<"\t";
00340 cout << endl;
00341 cout << "runaway\t";
00342 for (s=v_min; s<v_max; s++)
00343 cout << runner_spt[s] << "\t";
00344 cout << endl;
00345 cout << "mergers\t";
00346 for (s=v_min; s<v_max; s++)
00347 cout << merge_spt[s] << "\t";
00348 cout << endl;
00349 cout << "singles\t";
00350 for (s=v_min; s<v_max; s++)
00351 cout << single_spt[s] << "\t";
00352 cout << endl;
00353 }
00354
00355 void cluster_profile::print_profile(star_type_spec type, profile prof) {
00356
00357 cout << endl;
00358 cout << type_string(type) << ": " << endl;
00359 if (type==Runaway || type==Merger) {
00360
00361 return ;
00362 }
00363
00364
00365
00366 int s, p;
00367 int v_min = O5;
00368 int v_max = no_spectral_class;
00369
00370
00371 cout <<"\t";
00372 for (s=v_min; s<v_max; s++)
00373 cout << type_string((spectral_class)s) <<"\t";
00374 cout << endl;
00375 for (s=v_min; s<v_max; s++) {
00376 cout << type_string((spectral_class)s) << "\t";
00377 for (p=v_min; p<v_max; p++)
00378 cout << bins_spa[p][s][type] << "\t";
00379 cout << endl;
00380 }
00381
00382 if (type!=Rl_filling && type!=Accreting) {
00383 cout << endl;
00384
00385 cout <<"\t";
00386 for (s=v_min; s<v_max; s++)
00387 cout << type_string((spectral_class)s) <<"\t";
00388 cout << endl;
00389 cout << "runaway\t";
00390 for (s=v_min; s<v_max; s++)
00391 cout << runner_spa[s][type] << "\t";
00392 cout << endl;
00393 cout << "mergers\t";
00394 for (s=v_min; s<v_max; s++)
00395 cout << merge_spa[s][type] << "\t";
00396 cout << endl;
00397 cout << "singles\t";
00398 for (s=v_min; s<v_max; s++)
00399 cout << single_spa[s][type] << "\t";
00400 cout << endl;
00401 }
00402 }
00403
00404 void cluster_profile::print_single_profile(star_type_spec type) {
00405
00406
00407
00408
00409 int s, p;
00410 int p_min = O5;
00411 int p_max = no_spectral_class;
00412 int s_min = Main_Sequence;
00413 int s_max = no_of_stellar_type;
00414
00415
00416
00417 cout <<"\t";
00418 for (s=s_min; s<s_max; s++)
00419 cout << type_short_string((stellar_type)s) <<"\t";
00420 cout << endl;
00421 for (p=p_min; p<p_max; p++) {
00422 cout << type_string((spectral_class)p) << "\t";
00423 for (s=s_min; s<s_max; s++)
00424 cout << bins_spa[s][p][type] << "\t";
00425 cout << endl;
00426 }
00427 }
00428
00429
00430
00431
00432
00433 initial_cluster::initial_cluster() {
00434
00435 start_time = 0;
00436 end_time = 12000;
00437 field = FALSE;
00438
00439 start_id = 1;
00440 n_steps = 10;
00441 no_of_singles = 1000;
00442 no_of_binaries = 100;
00443
00444 r_core = 0.5;
00445 r_halfm = 5;
00446 r_tidal = 50;
00447 rho_core = 1.e+5;
00448 v_disp = 30;
00449
00450 m_min = 0.08;
00451 m_max = 100.0;
00452
00453 m_alpha = 2.7;
00454
00455
00456
00457
00458 q_min = 0.3;
00459 q_max = 0.95;
00460 q_alpha = 0.7;
00461
00462 a_min = 0.6;
00463 a_max = 1.e+4;
00464 a_alpha = 0.0;
00465
00466 e_min = 0.035;
00467 e_max = .7;
00468 e_alpha = 1;
00469
00470 }
00471
00472 double_init initial_cluster::random_initial_conditions() {
00473
00474
00475
00476
00477
00478
00479
00480
00481 double_init init;
00482
00483
00484 init.start_time = start_time;
00485 if (!field)
00486 init.end_time = end_time;
00487 else
00488 init.end_time = randinter(start_time, end_time);
00489 init.n_steps = n_steps;
00490
00491
00492 real constant = pow(m_min, 1-m_alpha) - pow(m_max, 1-m_alpha);
00493 real random = randinter(0., 1.);
00494 init.mass_prim = pow(random*constant
00495 + pow(m_max, 1-m_alpha), 1/(1-m_alpha));
00496
00497
00498 random = randinter(0., 1.);
00499 init.eccentricity = sqrt(random);
00500
00501
00502 random = randinter(0.125, 1.);
00503 real q = init.q = 1./pow(random, 1/3.) - 1;
00504
00505
00506 a_min = 0.49*pow(q, 2./3.)/(0.6*pow(q, 2./3.) + log(1 + pow(q, 1/3.)));
00507 a_min = 2*pow(init.mass_prim, 0.7)/a_min;
00508 a_max = 5000*a_min;
00509 constant = log(a_max) - log(a_min);
00510 random = randinter(0., 1.);
00511 init.semi = a_min*exp(random*constant);
00512
00513
00514 return init;
00515 }
00516
00517 double_init random_initial_conditions(initial_cluster& c) {
00518
00519 extern real randinter(real, real);
00520
00521 real random, constant;
00522
00523 double_init init;
00524
00525
00526 if (!c.field)
00527 init.end_time = c.end_time;
00528 else
00529 init.end_time = randinter(c.start_time, c.end_time);
00530 init.n_steps = c.n_steps;
00531
00532
00533 constant = pow(c.m_min, 1-c.m_alpha) - pow(c.m_max, 1-c.m_alpha);
00534 random = randinter(0., 1.);
00535 init.mass_prim = pow(random*constant
00536 + pow(c.m_max, 1-c.m_alpha), 1/(1-c.m_alpha));
00537
00538
00539 random = randinter(0., 1.);
00540 init.eccentricity = sqrt(random);
00541
00542
00543 random = randinter(0.125, 1.);
00544 real q = init.q = 1./pow(random, 1/3.) - 1;
00545
00546
00547 c.a_min = 0.49*pow(q, 2./3.)/(0.6*pow(q, 2./3.) + log(1 + pow(q, 1/3.)));
00548 c.a_min = 2*pow(init.mass_prim, 0.7)/c.a_min;
00549 c.a_max = 5000*c.a_min;
00550 constant = log(c.a_max) - log(c.a_min);
00551 random = randinter(0., 1.);
00552 init.semi = c.a_min*exp(random*constant);
00553
00554 return init;
00555
00556 }
00557
00558 real next_output_time(int n_out, int n_tot, real t1, real t2) {
00559
00560
00561
00562 real m1 = turn_off_mass(t1);
00563 real m2 = turn_off_mass(t2);
00564 real dm = (m1-m2)/n_tot;
00565 real dt = (t2-t1)/n_tot;
00566
00567 real m_out = m1 - dm*(n_out+1);
00568
00569
00570 return main_sequence_time(m_out);
00571
00572 }
00573
00574