00001
00008
00009
00010
00011 #include "dyn.h"
00012
00013 #define SEED_STRING_LENGTH 256
00014 char tmp_string[SEED_STRING_LENGTH];
00015
00016 #ifdef TOOLBOX
00017
00018 typedef struct
00019 {
00020 real radius;
00021 real mass;
00022 } rm_pair, *rm_pair_ptr;
00023
00024
00025
00026
00027
00028 local int compare_radii(const void * pi, const void * pj)
00029 {
00030 if (((rm_pair_ptr) pi)->radius > ((rm_pair_ptr) pj)->radius)
00031 return +1;
00032 else if (((rm_pair_ptr)pi)->radius < ((rm_pair_ptr)pj)->radius)
00033 return -1;
00034 else
00035 return 0;
00036 }
00037
00038
00039
00040
00041
00042 real radius_containting_mass(dyn * b, real mass) {
00043
00044 char lagr_string[64] = "central black hole";
00045
00046 int n = b->n_daughters();
00047
00048
00049
00050
00051
00052 vector lagr_pos = 0, lagr_vel = 0;
00053 bool try_com = true;
00054 bool modify_com = false;
00055
00056 #if 0
00057 if (find_qmatch(b->get_dyn_story(), "density_center_pos")) {
00058
00059 if (getrq(b->get_dyn_story(), "density_center_time")
00060 != b->get_system_time())
00061 warning("lagrad: neglecting out-of-date density center");
00062 else {
00063 lagr_pos = getvq(b->get_dyn_story(), "density_center_pos");
00064 strcpy(lagr_string, "density center");
00065 try_com = false;
00066
00067
00068
00069
00070 lagr_vel = getvq(b->get_dyn_story(), "density_center_vel");
00071 }
00072 }
00073
00074 if (try_com && find_qmatch(b->get_dyn_story(), "com_pos")) {
00075
00076 if (getrq(b->get_dyn_story(), "com_time")
00077 != b->get_system_time()) {
00078 warning("lagrad: neglecting out-of-date center of mass");
00079 } else {
00080 lagr_pos = getvq(b->get_dyn_story(), "com_pos");
00081 lagr_vel = getvq(b->get_dyn_story(), "com_vel");
00082 strcpy(lagr_string, "center of mass");
00083 modify_com = true;
00084 }
00085 }
00086 #endif
00087
00088 rm_pair_ptr rm_table = new rm_pair[n];
00089
00090 if (rm_table == NULL) {
00091 cerr << "radius_containing_mass: "
00092 << "not enough memory left for rm_table\n";
00093 return -1;
00094 }
00095
00096
00097
00098
00099 real total_mass = 0;
00100 int i = 0;
00101
00102 for_all_daughters(dyn, b, bi) {
00103 total_mass += bi->get_mass();
00104 rm_table[i].radius = abs(bi->get_pos() - lagr_pos);
00105 rm_table[i].mass = bi->get_mass();
00106 i++;
00107 }
00108
00109
00110 qsort((void *)rm_table, (size_t)i, sizeof(rm_pair), compare_radii);
00111
00112 real rlagr = 0;
00113 real cumulative_mass = 0.0;
00114
00115
00116
00117 i=0;
00118 while (cumulative_mass < mass)
00119 cumulative_mass += rm_table[i++].mass;
00120
00121 rlagr = rm_table[i-1].radius;
00122
00123 delete [] rm_table;
00124
00125 PRL(rlagr);
00126 return rlagr;
00127 }
00128
00129 void merge_bh_with_coll(dyn * bh, dyn * bcoll) {
00130
00131 detach_node_from_general_tree(*bcoll);
00132 bcoll->set_younger_sister(NULL);
00133 bcoll->set_elder_sister(NULL);
00134
00135 real mass = bh->get_mass() + bcoll->get_mass();
00136
00137 real f1 = bh->get_mass() / mass;
00138 real f2 = bcoll->get_mass() / mass;
00139 vector pos = f1 * bh->get_pos() + f2 * bcoll->get_pos();
00140 vector vel = f1 * bh->get_vel() + f2 * bcoll->get_vel();
00141 vector acc = f1 * bh->get_acc() + f2 * bcoll->get_acc();
00142
00143
00144
00145 bh->set_mass(mass);
00146 bh->set_pos(bh->get_pos() - pos);
00147 bh->set_vel(bh->get_vel() - vel);
00148 bh->set_acc(bh->get_acc() - acc);
00149
00150 bcoll->set_pos(bcoll->get_pos() - pos);
00151 bcoll->set_vel(bcoll->get_vel() - vel);
00152 bcoll->set_acc(bcoll->get_acc() - acc);
00153 }
00154
00155
00156 local void grow_black_hole(dyn* b, real m_bh) {
00157
00158 PRL(m_bh);
00159 if(m_bh<=1) {
00160 cerr << "fractional bh mass" << endl;
00161 m_bh *= b->get_mass();
00162 PRL(m_bh);
00163 }
00164
00165 real bh_radius = radius_containting_mass(b, m_bh);
00166 PRL(bh_radius);
00167
00168
00169 real sum = 0;
00170
00171 int ibh = 0;
00172 dyn *bh = NULL;
00173 int n = b->n_daughters();
00174 do {
00175 for_all_daughters(dyn, b, bi) {
00176 if(abs(bi->get_pos())<=bh_radius) {
00177 ibh++;
00178 if (bh==NULL)
00179 bh = bi;
00180 else if(bh!=bi) {
00181
00182 merge_bh_with_coll(bh, bi);
00183
00184
00185 break;
00186 }
00187 }
00188 }
00189 }
00190 while(bh->get_mass()<m_bh);
00191
00192 putiq(bh->get_log_story(), "black_hole", 1);
00193 }
00194
00195 void main(int argc, char ** argv) {
00196
00197 real m_bh = 0;
00198
00199 check_help();
00200
00201 extern char *poptarg;
00202 int c;
00203 char* param_string = "M:";
00204
00205 while ((c = pgetopt(argc, argv, param_string)) != -1)
00206 switch(c) {
00207 case 'M': m_bh = atof(poptarg);
00208 break;
00209 case '?': params_to_usage(cerr, argv[0], param_string);
00210 exit(1);
00211 }
00212
00213
00214 dyn* b;
00215 b = get_dyn(cin);
00216 b->log_history(argc, argv);
00217
00218 grow_black_hole(b, m_bh);
00219
00220 put_dyn(cout, *b);
00221 rmtree(b);
00222
00223 }
00224 #endif