00001
00044
00045 #include "dyn.h"
00046
00047 #ifdef TOOLBOX
00048
00049 local void makepowerlaw(dyn * root, int n,
00050 real A, real a, real x,
00051 real cutoff, real mass,
00052 real r_min, real r_max)
00053 {
00054 real xi = 1/x, pmass = 1./n, armax = 0, vc;
00055 root->set_mass(1);
00056
00057 if (a > 0) {
00058 armax = pow(a/r_max, x);
00059 vc =sqrt(3*A*pow(a, x-1)/(3-x));
00060 } else
00061 vc = sqrt(3*A*pow(cutoff, x-1)/(3-x));
00062
00063 for_all_daughters(dyn, root, bi) {
00064
00065 bi->set_mass(pmass);
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 real radius = 0;
00077 while (radius < r_min) {
00078 if (randinter(0, 1) < armax)
00079 radius = a*pow(randinter(0, 1), 1./3);
00080 else
00081 radius = r_max*pow(randinter(armax, 1), xi);
00082 }
00083
00084 real costheta;
00085
00086
00087
00088
00089 if (radius > cutoff)
00090
00091
00092
00093 costheta = randinter(-1, 1);
00094
00095 else {
00096
00097
00098
00099 real lim = radius/cutoff;
00100 costheta = randinter(-lim, lim);
00101 }
00102
00103 real sintheta = 1 - costheta*costheta;
00104 if (sintheta > 0) sintheta = sqrt(sintheta);
00105 real phi = randinter(0.0, TWO_PI);
00106
00107 bi->set_pos(radius*vector(sintheta * cos(phi),
00108 sintheta * sin(phi),
00109 costheta));
00110
00111
00112
00113
00114
00115 real vrms;
00116
00117 if (a > 0) {
00118
00119
00120
00121 vrms = vc;
00122 if (radius > a) vrms *= pow(radius/a, (x-1)/2);
00123
00124 } else {
00125
00126 if (radius > cutoff)
00127 vrms = sqrt(3*A*pow(radius, x-1)/(3-x));
00128 else
00129
00130 vrms = max(sqrt(mass/radius), vc);
00131 }
00132
00133
00134
00135
00136 if (radius > cutoff) {
00137
00138
00139
00140 bi->set_vel(vrms*vector(randinter(-1,1),
00141 randinter(-1,1),
00142 randinter(-1,1)));
00143 } else {
00144
00145
00146
00147 vector rhat = bi->get_pos()/radius;
00148 vector zhat = vector(0,0,1);
00149
00150 vector xyhat = rhat^zhat;
00151 xyhat /= abs(xyhat);
00152
00153 real lim = sqrt(radius/cutoff);
00154 real rfrac = randinter(-lim, lim);
00155 real zfrac = randinter(-lim, lim);
00156 real tfrac = sqrt(max(0.0, 1-rfrac*rfrac-zfrac*zfrac));
00157
00158 bi->set_vel(vrms*(rfrac*rhat+tfrac*xyhat+zfrac*zhat));
00159 }
00160 }
00161
00162 putrq(root->get_log_story(), "initial_mass", 1.0);
00163 }
00164
00165 #define SEED_STRING_LENGTH 60
00166
00167 main(int argc, char ** argv) {
00168 int i;
00169 int n;
00170 int input_seed, actual_seed;
00171 int a_flag = false;
00172 int c_flag = false;
00173 int e_flag = false;
00174 int i_flag = false;
00175 int m_flag = false;
00176 int n_flag = false;
00177 int o_flag = false;
00178 int s_flag = false;
00179
00180 char *comment;
00181 char seedlog[SEED_STRING_LENGTH];
00182
00183 real coeff = 1, scale = 1, exponent = 1;
00184 vector center = 0;
00185
00186 real cutoff = 0, mass = 0, softening = 0;
00187
00188 real r_max = 10, r_min = 0.1;
00189
00190 check_help();
00191
00192 extern char *poptarg;
00193 int c;
00194 char* param_string = "A:a:b:c:e:il:M:m:n:oR:r:s:x:";
00195
00196 while ((c = pgetopt(argc, argv, param_string)) != -1)
00197 switch(c) {
00198 case 'A': coeff = atof(poptarg);
00199 break;
00200 case 'a':
00201 case 'R':
00202 a_flag = true;
00203 scale = atof(poptarg);
00204 break;
00205 case 'b': cutoff = atof(poptarg);
00206 break;
00207 case 'c': c_flag = true;
00208 comment = poptarg;
00209 break;
00210 case 'e': e_flag = true;
00211 softening = atof(poptarg);
00212 break;
00213 case 'i': i_flag = true;
00214 break;
00215 case 'l': r_min = atof(poptarg);
00216 break;
00217 case 'M':
00218 case 'm': m_flag = true;
00219 mass = atof(poptarg);
00220 break;
00221 case 'n': n_flag = true;
00222 n = atoi(poptarg);
00223 break;
00224 case 'o': o_flag = true;
00225 break;
00226 case 'r': r_max = atof(poptarg);
00227 break;
00228 case 's': s_flag = true;
00229 input_seed = atoi(poptarg);
00230 break;
00231 case 'x': exponent = atof(poptarg);
00232 break;
00233 case '?': params_to_usage(cerr, argv[0], param_string);
00234 get_help();
00235 exit(1);
00236 }
00237
00238 if (!n_flag) {
00239 cerr << "makepowerlaw: must specify the number # of";
00240 cerr << " particles with -n#" << endl;
00241 exit(1);
00242 }
00243
00244 if (n < 1) {
00245 cerr << "makepowerlaw: n < 1 not allowed" << endl;
00246 exit(1);
00247 }
00248
00249 if (exponent <= 0 || exponent >= 3) {
00250 cerr << "makepowerlaw: 0 < x < 3 required" << endl;
00251 exit(1);
00252 }
00253
00254 if (cutoff > 0) {
00255 if (!m_flag) mass = coeff*pow(cutoff, exponent);
00256 if (!e_flag) softening = cutoff/1000;
00257 if (a_flag)
00258 cerr << "makepowerlaw: scale = " << scale
00259 << " inconsistent with cutoff = " << cutoff
00260 << "; setting scale = 0" << endl;
00261 scale = 0;
00262 }
00263
00264
00265
00266 dyn *b, *by, *bo;
00267
00268 b = new dyn();
00269 if (i_flag) b->set_label("root");
00270
00271 bo = new dyn();
00272 if (i_flag) bo->set_label(1);
00273 b->set_oldest_daughter(bo);
00274 bo->set_parent(b);
00275
00276 for (i = 1; i < n; i++) {
00277 by = new dyn();
00278 if (i_flag) by->set_label(i+1);
00279 bo->set_younger_sister(by);
00280 by->set_elder_sister(bo);
00281 bo = by;
00282 }
00283
00284
00285
00286 if (c_flag) b->log_comment(comment);
00287
00288 b->log_history(argc, argv);
00289
00290 if (!s_flag) input_seed = 0;
00291 actual_seed = srandinter(input_seed);
00292
00293 if (o_flag) cerr << "makepowerlaw: random seed = " << actual_seed << endl;
00294
00295 sprintf(seedlog, " random number generator seed = %d",actual_seed);
00296 b->log_comment(seedlog);
00297
00298
00299
00300 makepowerlaw(b, n, coeff, scale, exponent, cutoff, mass, r_min, r_max);
00301
00302
00303
00304 putrq(b->get_log_story(), "kira_pl_coeff", coeff);
00305 putrq(b->get_log_story(), "kira_pl_exponent", exponent);
00306 putrq(b->get_log_story(), "kira_pl_scale", scale);
00307 putvq(b->get_log_story(), "kira_pl_center", center);
00308
00309 putrq(b->get_log_story(), "kira_pl_cutoff", cutoff);
00310 putrq(b->get_log_story(), "kira_pl_mass", mass);
00311 putrq(b->get_log_story(), "kira_pl_softening", softening);
00312
00313 putiq(b->get_log_story(), "ignore_internal", 1);
00314 putrq(b->get_log_story(), "r_reflect", r_max);
00315
00316 put_node(cout, *b);
00317 }
00318
00319 #endif
00320
00321