00001 
00002        
00003       
00004      
00005     
00006    
00007   
00008  
00009 
00010 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 #include "dyn.h"
00054 
00055 #ifdef TOOLBOX
00056 
00057 #define  SEED_STRING_LENGTH  256
00058 char  tmp_string[SEED_STRING_LENGTH];
00059 
00060 #ifdef FORTRAN_TRAILING_UNDERSCORE
00061 #   define AKING aking_
00062 #   define RAND ran2_ 
00063 #else
00064 #   define AKING aking
00065 #   define RAND ran2
00066 #endif
00067 
00068 
00069 
00070 extern "C" void AKING(real*, real*, real*, real*, real*, real*, real*,
00071                       real*, real*, int*, int*, real*, int*,
00072                       real*, real*, real*, real*);
00073 
00074 extern "C" real RAND(int &seed)
00075 {
00076     return randinter(0, 1);
00077 }
00078 
00079 local void mk_aniso_king(dyn * b, int n, real w0, real alpha1, real alpha3,
00080                          bool u_flag, int test, int seed)
00081 
00082 
00083 
00084 
00085 
00086 {
00087     
00088     
00089 
00090     if (alpha3 != 0 && alpha1 >= 0)
00091         err_exit("mk_aniso_king: must specify alpha1 < 0");
00092     if (w0 < 1)
00093         err_exit("mk_aniso_king: must specify w0 > 1");
00094     if (w0 > 12)
00095         err_exit("mk_aniso_king: must specify w0 < 12");
00096 
00097     
00098 
00099     real* m = new real[n];
00100     real* x = new real[n];
00101     real* y = new real[n];
00102     real* z = new real[n];
00103     real* vx = new real[n];
00104     real* vy = new real[n];
00105     real* vz = new real[n];
00106 
00107     
00108     
00109 
00110     seed %= 150999;
00111 
00112     real potential, kinetic, tidal_energy;      
00113                                                 
00114 
00115     real* coord = new real[3*n];                
00116                                                 
00117                                                 
00118 
00119     AKING(m, x, y, z, vx, vy, vz,                       
00120           &alpha1, &alpha3, &seed, &n, &w0, &test,      
00121           &potential, &kinetic, &tidal_energy, coord);
00122 
00123     if (b == NULL || n < 1) return;
00124 
00125     
00126 
00127     sprintf(tmp_string,
00128     "       Anisotropic King model, w0 = %.2f, alpha1 = %f, alpha3 = %f",
00129             w0, alpha1, alpha3);
00130     b->log_comment(tmp_string);
00131 
00132     
00133 
00134     int i = 0;
00135     for_all_daughters(dyn, b, bi) {
00136 
00137         bi->set_mass(m[i]);
00138         bi->set_pos(vector(x[i], y[i], z[i]));
00139         bi->set_vel(vector(vx[i], vy[i], vz[i]));
00140 
00141         i++;
00142     }
00143 
00144     delete m, x, y, z, vx, vy, vz;
00145 
00146     
00147     
00148     
00149     
00150 
00151     
00152     
00153 
00154     b->to_com();        
00155 
00156     kinetic = get_kinetic_energy(b);
00157     tidal_energy = get_tidal_pot(b);
00158 
00159     
00160     
00161 
00162     
00163     real r_virial = -0.5/potential;
00164 
00165     
00166     
00167     
00168 
00169     real r_jacobi = pow(-alpha1, -1.0/3);
00170 
00171     
00172     
00173 
00174     if (!u_flag && n > 1) {
00175 
00176         
00177         
00178 
00179         scale_virial(b, -0.5, potential, kinetic);  
00180 
00181         real energy = kinetic + potential + tidal_energy;
00182 
00183         
00184         
00185         
00186 
00187         real fac = scale_energy(b, -0.25, energy);
00188 
00189         
00190         
00191 
00192         alpha1 /= pow(fac,3);
00193         alpha3 /= pow(fac,3);
00194 
00195         sprintf(tmp_string,
00196                 "       Rescaled alpha1 = %f, alpha3 = %f", alpha1, alpha3);
00197         b->log_comment(tmp_string);
00198 
00199         
00200 
00201         r_virial *= fac;                
00202         kinetic /= fac;                 
00203         potential /= fac;               
00204         tidal_energy /= fac;
00205         r_jacobi *= fac;
00206 
00207         
00208 
00209         putrq(b->get_dyn_story(), "initial_total_energy", -0.25);
00210     }
00211 
00212     
00213     
00214 
00215     putrq(b->get_log_story(), "initial_mass", 1.0);
00216     putrq(b->get_log_story(), "initial_rvirial", r_virial);
00217     putrq(b->get_log_story(), "initial_rtidal_over_rvirial",
00218           r_jacobi/r_virial, 10);
00219 
00220     cerr << " mk_aniso_king: "; PRL(r_jacobi/r_virial);
00221 
00222     
00223     
00224 
00225     
00226 
00227     putrq(b->get_log_story(), "alpha3_over_alpha1", alpha3/alpha1, 10);
00228 }
00229 
00230 #define OMEGA_2 3.e-4
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 #define OORT_A  (0.0144)        // km/s/pc
00242 #define OORT_B  (-0.012)        // km/s/pc
00243 #define RHO_G   (0.11/232)      // (232 Msun)/pc^3
00244 
00245 #define OORT_ALPHA_RATIO \
00246         ((4*M_PI*RHO_G + 2*(OORT_A*OORT_A - OORT_B*OORT_B)) \
00247                          / (-4*OORT_A*(OORT_A-OORT_B)))
00248 
00249 main(int argc, char ** argv)
00250 {
00251     real w0;
00252     int  n = 0;
00253 
00254     real Oort_A = OORT_A;       
00255     real Oort_B = OORT_B;       
00256     real rho_G  = RHO_G;        
00257 
00258     
00259     
00260     
00261     
00262     
00263     
00264         
00265     real alpha1 = -3 * OMEGA_2;
00266     real alpha3 = OMEGA_2;
00267     real alpha3_over_alpha1 = alpha3/alpha1;
00268     bool a_flag = false;
00269     bool b_flag = false;
00270 
00271     int  input_seed, actual_seed;
00272 
00273     bool A_flag = false;
00274     bool B_flag = false;
00275     bool G_flag = false;
00276 
00277     bool c_flag = false;
00278     bool i_flag = false;
00279     bool n_flag = false;
00280     bool o_flag = false;
00281     bool s_flag = false; 
00282     bool w_flag = false;
00283     bool u_flag = false;
00284 
00285     int tidal_type = 1;
00286     bool F_flag = false;
00287 
00288     int test = 0;
00289     char  *comment;
00290 
00291     check_help();
00292 
00293     extern char *poptarg;
00294     int c;
00295     char* param_string = "A:a:B:b:c:F:G:in:os:T:uw:";
00296 
00297     while ((c = pgetopt(argc, argv, param_string)) != -1)
00298         switch(c) {
00299             case 'A': Oort_A = atof(poptarg);
00300                       A_flag = true;
00301                       break;
00302             case 'B': Oort_B = atof(poptarg);
00303                       B_flag = true;
00304                       break;
00305             case 'G': rho_G = atof(poptarg);
00306                       G_flag = true;
00307                       break;
00308             case 'a': alpha1 = atof(poptarg);
00309                       a_flag = true;
00310                       break;
00311             case 'b': alpha3_over_alpha1 = atof(poptarg);
00312                       b_flag = true;
00313                       F_flag = false;
00314                       break;
00315             case 'c': c_flag = true; 
00316                       comment = poptarg;
00317                       break;
00318             case 'F': tidal_type = atoi(poptarg);
00319                       b_flag = false;
00320                       F_flag = true;
00321                       break;
00322             case 'i': i_flag = true;
00323                       break;
00324             case 'n': n_flag = true;
00325                       n = atoi(poptarg);
00326                       break;
00327             case 'o': o_flag = true;
00328                       break;
00329             case 's': s_flag = true;
00330                       input_seed = atoi(poptarg);
00331                       break;
00332             case 'T': test = atoi(poptarg);
00333                       break;
00334             case 'u': u_flag = true;
00335                       break;
00336             case 'w': w_flag = true;
00337                       w0 = atof(poptarg);
00338                       break;
00339             case '?': params_to_usage(cerr, argv[0], param_string);
00340                       get_help();
00341         }
00342 
00343     if (!w_flag) {
00344         cerr << "mk_aniso_king: please specify the dimensionless depth";
00345         cerr << " with -w #\n";
00346         exit(1);
00347     }
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355     if (n < 0)
00356         err_exit("mk_aniso_king: n > 0 required");
00357 
00358     if (A_flag && B_flag && G_flag) {
00359 
00360       cerr << " mk_aniso_king: Custom tidal field with Oort constants" 
00361            << endl;
00362       PRI(4);PRC(Oort_A);PRC(Oort_B);PRL(rho_G);
00363       tidal_type = 4;
00364       F_flag = true;
00365 
00366     }
00367 
00368     if (F_flag) {
00369 
00370         if (tidal_type == 1)
00371 
00372             alpha3_over_alpha1 = -1.0/3;
00373 
00374         else if (tidal_type == 2)
00375 
00376             alpha3_over_alpha1 = -0.5;
00377 
00378         else if (tidal_type == 3) {
00379 
00380             
00381 
00382             alpha1 = -4*OORT_A*(OORT_A-OORT_B);
00383             alpha3_over_alpha1 = OORT_ALPHA_RATIO;
00384             a_flag = true;
00385 
00386         } else if(tidal_type == 4) {
00387           
00388             alpha1 = -4*Oort_A*(Oort_A-Oort_B);
00389             alpha3_over_alpha1 = ((4*M_PI*rho_G 
00390                                    + 2*(Oort_A*Oort_A - Oort_B*Oort_B)) \
00391                                / (-4*Oort_A*(Oort_A-Oort_B)));
00392 
00393             a_flag = true;
00394         }
00395         else
00396             F_flag = false;
00397 
00398         if (F_flag) {
00399             cerr << " mk_aniso_king: tidal_type = " << tidal_type;
00400             if (tidal_type >= 3) cerr << ", alpha1 = " << alpha1;
00401             cerr << ", alpha3/alpha1 = " << alpha3_over_alpha1
00402                  << endl;
00403             b_flag = true;
00404         }
00405     }
00406 
00407     if (!b_flag && !F_flag)
00408         cerr << " mk_aniso_king: using default alpha3/alpha1 = "
00409              << alpha3_over_alpha1 << endl;
00410 
00411     alpha3 = alpha3_over_alpha1 * alpha1;
00412 
00413     if (!a_flag) {
00414         cerr << " mk_aniso_king: using default "; PR(alpha1);
00415         if (!b_flag) {
00416             cerr << ", "; PR(alpha3);
00417         }
00418         cerr << endl;
00419     }
00420 
00421     dyn *b = NULL;
00422 
00423     if (!n_flag) {
00424 
00425         b = get_dyn(cin);
00426         n = b->n_leaves();
00427     }
00428     else {
00429 
00430         b = new dyn();
00431         dyn *by, *bo;
00432 
00433         bo = new dyn();
00434         if (i_flag)
00435             bo->set_label(1);
00436         b->set_oldest_daughter(bo); 
00437         bo->set_parent(b);
00438 
00439         for (int i = 1; i < n; i++) {
00440             by = new dyn();
00441             if (i_flag)
00442                 by->set_label(i+1);
00443             by->set_parent(b);
00444             bo->set_younger_sister(by);
00445             by->set_elder_sister(bo);
00446             bo = by;
00447         }
00448     }
00449 
00450     if (c_flag)
00451         b->log_comment(comment);                
00452     b->log_history(argc, argv);
00453 
00454     if (s_flag == false) input_seed = 0;        
00455     actual_seed = srandinter(input_seed);
00456 
00457     if (o_flag)
00458         cerr << "mk_aniso_king: random seed = " << actual_seed << endl;
00459 
00460     sprintf(tmp_string,
00461             "       random number generator seed = %d",
00462             actual_seed);
00463     b->log_comment(tmp_string);
00464 
00465     mk_aniso_king(b, n, w0, alpha1, alpha3, u_flag, test, actual_seed);
00466 
00467     b->set_tidal_field(alpha1, alpha3);
00468     putiq(b->get_log_story(), "kira_tidal_field_type", tidal_type);
00469 
00470     if(tidal_type == 4) {
00471         if (A_flag) putrq(b->get_log_story(), "Oort_A_constant", Oort_A, 10);
00472         if (B_flag) putrq(b->get_log_story(), "Oort_B_constant", Oort_B, 10);
00473         if (G_flag) putrq(b->get_log_story(), "local_mass_density", rho_G, 10);
00474     }
00475 
00476     if (n_flag)
00477         put_node(cout, *b);
00478 }
00479 
00480 #endif
00481 
00482