00001
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "dyn.h"
00029
00030 #ifdef TOOLBOX
00031
00032 #define MFRAC_DEFAULT 0.999 // radial cutoff
00033 #define RFRAC_DEFAULT 22.8042468 // corresponding radial cutoff
00034
00035 #define SEED_STRING_LENGTH 60
00036
00037 local void mkplummer(dyn * b, int n, real mfrac, real rfrac, bool u_flag)
00038 {
00039 int i;
00040
00041 real partmass;
00042 real radius;
00043 real velocity;
00044 real theta, phi;
00045 real x, y;
00046 real scalefactor;
00047 real inv_scalefactor;
00048 real sqrt_scalefactor;
00049 real mrfrac;
00050 real m_min, m_max;
00051 dyn * bi;
00052
00053 b->set_mass(1.0);
00054 partmass = 1.0 / ((real) n);
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 scalefactor = 16.0 / (3.0 * PI);
00078 inv_scalefactor = 1.0 / scalefactor;
00079 sqrt_scalefactor = sqrt( scalefactor );
00080
00081
00082
00083 if (rfrac < VERY_LARGE_NUMBER) {
00084
00085
00086 rfrac *= scalefactor;
00087 mrfrac = rfrac*rfrac*rfrac / pow(1.0 + rfrac*rfrac, 1.5);
00088 if (mrfrac < mfrac)
00089 mfrac = mrfrac;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099 real xfac = 1/1.695;
00100 real vfac = 1/sqrt(xfac);
00101
00102 for (i = 0, bi = b->get_oldest_daughter(); i < n;
00103 i++, bi = bi->get_younger_sister()) {
00104
00105 bi->set_mass(partmass);
00106
00107
00108
00109
00110
00111 m_min = (i * mfrac)/n;
00112 m_max = ((i+1) * mfrac)/n;
00113 real rrrr = randinter(m_min, m_max);
00114 radius = xfac / sqrt( pow (rrrr, -2.0/3.0) - 1.0);
00115
00116
00117
00118
00119
00120
00121 theta = acos(randinter(-1.0, 1.0));
00122 phi = randinter(0.0, TWO_PI);
00123
00124 bi->set_pos(vector(radius * sin( theta ) * cos( phi ),
00125 radius * sin( theta ) * sin( phi ),
00126 radius * cos( theta )));
00127
00128
00129
00130
00131
00132
00133
00134 x = 0.0;
00135 y = 0.1;
00136
00137
00138
00139
00140
00141
00142
00143
00144 while (y > x*x*pow( 1.0 - x*x, 3.5)) {
00145 x = randinter(0.0,1.0);
00146 y = randinter(0.0,0.1);
00147 }
00148
00149
00150
00151 velocity = vfac* x * sqrt(2.0) * pow( 1.0 + radius*radius, -0.25);
00152 theta = acos(randinter(-1.0, 1.0));
00153 phi = randinter(0.0,TWO_PI);
00154
00155 bi->set_vel(vector(velocity * sin( theta ) * cos( phi ),
00156 velocity * sin( theta ) * sin( phi ),
00157 velocity * cos( theta )));
00158 }
00159
00160
00161
00162
00163 b->to_com();
00164
00165 putrq(b->get_log_story(), "initial_mass", 1.0);
00166
00167 if (!u_flag && n > 1) {
00168
00169 real kinetic, potential;
00170
00171 get_top_level_energies(b, 0.0, potential, kinetic);
00172 scale_virial(b, -0.5, potential, kinetic);
00173 real energy = kinetic + potential;
00174 scale_energy(b, -0.25, energy);
00175
00176 putrq(b->get_log_story(), "initial_rvirial", 1.0);
00177 putrq(b->get_dyn_story(), "initial_total_energy", -0.25);
00178 }
00179 }
00180
00181 local void swap(dyn* bi, dyn* bj)
00182 {
00183 if (bi != bj) {
00184
00185 real mass = bi->get_mass();
00186 vector pos = bi->get_pos();
00187 vector vel = bi->get_vel();
00188
00189 bi->set_mass(bj->get_mass());
00190 bi->set_pos(bj->get_pos());
00191 bi->set_vel(bj->get_vel());
00192
00193 bj->set_mass(mass);
00194 bj->set_pos(pos);
00195 bj->set_vel(vel);
00196 }
00197 }
00198
00199
00200
00201 local void reshuffle_all(dyn* b, int n)
00202 {
00203
00204
00205
00206
00207
00208 int i = 0;
00209 dynptr *list = new dynptr[n];
00210 for_all_daughters(dyn, b, bi)
00211 list[i++] = bi;
00212
00213
00214
00215 for (i = 0; i < n; i++)
00216 swap(list[i], list[(int)randinter(0, n)]);
00217
00218 delete [] list;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 main(int argc, char ** argv)
00249 {
00250 int i;
00251 int n;
00252 int input_seed, actual_seed;
00253 real mfrac;
00254 real rfrac;
00255
00256 bool c_flag = false;
00257 bool i_flag = false;
00258 bool m_flag = false;
00259 bool n_flag = false;
00260 bool o_flag = false;
00261 bool r_flag = false;
00262 bool R_flag = true;
00263 bool s_flag = false;
00264 bool u_flag = false;
00265
00266 char *comment;
00267 char seedlog[SEED_STRING_LENGTH];
00268
00269 check_help();
00270
00271 extern char *poptarg;
00272 int c;
00273 char* param_string = "c:im:n:os:r:Ru";
00274
00275 mfrac = rfrac = VERY_LARGE_NUMBER;
00276
00277 while ((c = pgetopt(argc, argv, param_string)) != -1)
00278 switch(c) {
00279
00280 case 'c': c_flag = TRUE;
00281 comment = poptarg;
00282 break;
00283 case 'i': i_flag = TRUE;
00284 break;
00285 case 'm': m_flag = TRUE;
00286 mfrac = atof(poptarg);
00287 break;
00288 case 'n': n_flag = TRUE;
00289 n = atoi(poptarg);
00290 break;
00291 case 'o': o_flag = TRUE;
00292 break;
00293 case 'r': r_flag = TRUE;
00294 rfrac = atof(poptarg);
00295 break;
00296 case 'R': R_flag = !R_flag;
00297 break;
00298 case 's': s_flag = TRUE;
00299 input_seed = atoi(poptarg);
00300 break;
00301 case 'u': u_flag = TRUE;
00302 break;
00303 case '?': params_to_usage(cerr, argv[0], param_string);
00304 get_help();
00305 exit(1);
00306 }
00307
00308 if (!n_flag) {
00309 cerr << "mkplummer: specify the number # of";
00310 cerr << " particles with -n#\n";
00311 exit(1);
00312 }
00313
00314 dyn *b, *by, *bo;
00315 b = new dyn();
00316
00317 if (n > 0) {
00318 bo = new dyn();
00319 if (i_flag)
00320 bo->set_label(1);
00321 b->set_oldest_daughter(bo);
00322 bo->set_parent(b);
00323 }
00324
00325 for (i = 1; i < n; i++) {
00326 by = new dyn();
00327 if (i_flag)
00328 by->set_label(i+1);
00329 by->set_parent(b);
00330 bo->set_younger_sister(by);
00331 by->set_elder_sister(bo);
00332 bo = by;
00333 }
00334
00335 if (c_flag == TRUE)
00336 b->log_comment(comment);
00337 b->log_history(argc, argv);
00338
00339 if (s_flag == FALSE)
00340 input_seed = 0;
00341 actual_seed = srandinter(input_seed);
00342
00343 if (o_flag) cerr << "mkplummer: random seed = " << actual_seed << endl;
00344
00345 sprintf(seedlog, " random number generator seed = %d",actual_seed);
00346 b->log_comment(seedlog);
00347
00348 if (m_flag == FALSE && r_flag == FALSE)
00349 mfrac = MFRAC_DEFAULT;
00350
00351 if (n != 0) {
00352 mkplummer(b, n, mfrac, rfrac, u_flag);
00353 if (R_flag) reshuffle_all(b, n);
00354 }
00355
00356 put_node(cout, *b);
00357 rmtree(b);
00358 }
00359
00360 #endif
00361
00362