Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

dyn_stats.C

Go to the documentation of this file.
00001 
00002 // dyn_stats.C:  Helper functions used mainly by sys_stats.
00003 
00004 #include "dyn.h"
00005 
00006 real print_binary_params(kepler* k, real m1, real kT,
00007                          real dist_from_center,
00008                          bool verbose,                  // default = true
00009                          bool long_binary_output,       // default = true
00010                          int init_indent,               // default = 0
00011                          int indent)                    // default = BIN_INDENT
00012 
00013 // Print out the orbital parameters of a binary, regardless of energy.
00014 // Return the total energy of the binary system.
00015 
00016 {
00017     real m = k->get_total_mass();
00018     real m2 = m - m1;
00019     real mu = m1 * m2 / m;
00020     real mu_kT;
00021 
00022     if (kT > 0) mu_kT = mu / kT;
00023 
00024     if (verbose) {
00025 
00026         for (int i = 0; i < init_indent-2; i++) cerr << " ";
00027         cerr << "  ";
00028 
00029         if (!long_binary_output) {
00030 
00031             int p = cerr.precision(LOW_PRECISION);
00032 
00033             cerr << "a= " << k->get_semi_major_axis()
00034                  << " e= " << k->get_eccentricity()
00035                  << " r= " << k->get_separation();
00036 
00037             if (kT > 0) cerr << " E/kT= " << mu_kT*k->get_energy();
00038 
00039             cerr << " D= " << dist_from_center;
00040 
00041             // cerr << endl;    // newline should be added by calling
00042                                 // function (e.g. print_pert)
00043 
00044             cerr.precision(p);
00045 
00046         } else {
00047 
00048             cerr << "a = " << k->get_semi_major_axis()
00049                  << "  e = " << k->get_eccentricity()
00050                  << endl;
00051 
00052             PRI(indent); cerr << "r = " << k->get_separation()
00053                               << "  D = " << dist_from_center
00054                               << endl;
00055 
00056             PRI(indent); cerr << "P = " << k->get_period()
00057                               << "  peri = " <<  k->get_periastron();
00058             if (k->get_energy() < 0)
00059                 cerr << "  apo = " <<  k->get_semi_major_axis()
00060                                         * (1 + k->get_eccentricity());
00061             cerr << endl;
00062 
00063             PRI(indent); cerr << "E = " << mu*k->get_energy()
00064                               << "  E/mu = " << k->get_energy();
00065             if (kT > 0) cerr << "  E/kT = " << mu_kT*k->get_energy();
00066             cerr << endl;
00067 
00068             PRI(indent); cerr << "masses  " << m1 << "  " << m2
00069                               << "  (total = " << m << ")" << endl;
00070         }
00071 
00072     } else {
00073 
00074         cerr << "  "  << m << "  " << m1 << "  " << m2
00075              << "  "  << k->get_semi_major_axis()
00076              << "  " << k->get_eccentricity()
00077              << "  " << mu*k->get_energy()
00078              << "  " << k->get_energy();
00079         if (kT > 0) cerr << "  " << -mu_kT*k->get_energy();
00080         cerr << "  " << dist_from_center
00081              << endl;
00082     }
00083 
00084     return mu*k->get_energy();
00085 }
00086 
00087 real get_total_energy(dyn* bi, dyn* bj)
00088 {
00089     real M = bi->get_mass() + bj->get_mass();
00090     vector dx = bj->get_pos() - bi->get_pos();
00091     vector dv = bj->get_vel() - bi->get_vel();
00092     real mu = (bi->get_mass() * bj->get_mass()) / M;
00093     return mu*(0.5*dv*dv - M / abs(dx));
00094 }
00095 
00096 real get_period(dyn* bi, dyn* bj)
00097 {
00098     real M = bi->get_mass() + bj->get_mass();
00099     real E = -M / abs(bi->get_pos() - bj->get_pos())
00100                         + 0.5 * square(bi->get_vel() - bj->get_vel());
00101     if (E < 0) {
00102 
00103         real a = -0.5 * M / E;
00104         real P = TWO_PI * sqrt(a*a*a/M);
00105 
00106         return P;
00107 
00108     } else
00109 
00110         return VERY_LARGE_NUMBER;
00111 }
00112 
00113 void get_total_energy_and_period(dyn* bi, dyn* bj, real& E, real& P)
00114 {
00115     real M = bi->get_mass() + bj->get_mass();
00116 
00117     E = -M / abs(bi->get_pos() - bj->get_pos())
00118                         + 0.5 * square(bi->get_vel() - bj->get_vel());
00119     if (E < 0) {
00120 
00121         real a = -0.5 * M / E;
00122         P = TWO_PI * sqrt(a*a*a/M);
00123 
00124     } else
00125 
00126         P = VERY_LARGE_NUMBER;
00127 }
00128 
00129 void initialize_kepler_from_dyn_pair(kepler& k, dyn* bi, dyn* bj,
00130                                      bool minimal)
00131 {
00132     k.set_time(bi->get_system_time());
00133     k.set_total_mass(bi->get_mass()+bj->get_mass());
00134     k.set_rel_pos(bj->get_pos()-bi->get_pos());
00135     k.set_rel_vel(bj->get_vel()-bi->get_vel());
00136     k.initialize_from_pos_and_vel(minimal, false);
00137 }
00138 
00139 void print_binary_from_dyn_pair(dyn* bi, dyn* bj,
00140                                 real kT,                // default = 0
00141                                 vector center,          // default = (0,0,0)
00142                                 bool verbose,           // default = true
00143                                 bool long_binary_output) // default = true
00144 {
00145     // Print out the relative orbital parameters of a dyn pair,
00146     // regardless of their relative energy.
00147 
00148     kepler k;
00149     initialize_kepler_from_dyn_pair(k, bi, bj);
00150 
00151     dyn *primary = bi, *secondary = bj;
00152     if (bj->get_mass() > bi->get_mass()) {
00153         primary = bj;
00154         secondary = bi;
00155     }
00156 
00157     if (verbose) PRI(4);
00158     cerr << "(";
00159     primary->pretty_print_node(cerr);
00160     cerr << ",";
00161     secondary->pretty_print_node(cerr);
00162     cerr << "):  ";
00163 
00164     real dist_from_center = abs(primary->get_pos() - center);
00165 
00166     int init_indent = 11 - strlen(bi->format_label());
00167     init_indent -= strlen(bj->format_label()) ;
00168 
00169     print_binary_params(&k, primary->get_mass(), kT,
00170                         dist_from_center, verbose, long_binary_output,
00171                         init_indent);
00172 
00173     // No newline -- should be added by calling function.
00174 }
00175 
00176 real print_structure_recursive(dyn* bi,
00177                                real kT,
00178                                vector center,
00179                                bool verbose,
00180                                bool long_binary_output,
00181                                int indent)
00182 {
00183     // Simpler interface onto print_structure_recursive()
00184 
00185     int idum = 0;
00186     real edum = 0;
00187 
00188     return print_structure_recursive(bi, NULL, idum, edum, kT, center,
00189                                      verbose, long_binary_output, indent);
00190 }
00191 
00192 real print_structure_recursive(dyn* bi,
00193                                void (*dstar_params)(dyn*),
00194                                int& n_unp, real& e_unp,
00195                                real kT,
00196                                vector center,
00197                                bool verbose,
00198                                bool long_binary_output,
00199                                int indent)
00200 
00201 // Recursively print out the orbital parameters of a hierarchical system,
00202 // regardless of energy.  Update some unperturbed counters and return the
00203 // total energy of the system.  On entry, bi is the top-level CM.
00204 
00205 {
00206       
00207     real eb = 0;
00208     if (bi->get_oldest_daughter()) {
00209 
00210 
00211         dyn* od = bi->get_oldest_daughter();
00212         dyn* yd = od->get_younger_sister();
00213 
00214         kepler k;
00215         k.set_time(0);
00216         k.set_total_mass(bi->get_mass());
00217         k.set_rel_pos(od->get_pos()-yd->get_pos());
00218         k.set_rel_vel(od->get_vel()-yd->get_vel());
00219         k.initialize_from_pos_and_vel(true, false);  // minimal, non-verbose
00220 
00221         dyn* primary = od;
00222         if (yd->get_mass() > od->get_mass()) primary = yd;
00223 
00224         int init_indent = 21;
00225         if (indent > 0) {
00226             for (int i = 0; i < indent; i++) cerr << " ";
00227             if (!od->get_kepler())
00228                 cerr << "    ";
00229             else
00230                 cerr << "  U ";
00231             bi->pretty_print_node(cerr); cerr << "   ";
00232             init_indent = 14 - strlen(bi->format_label()) - indent;
00233         }
00234 
00235         real dist_from_center = abs(primary->get_pos() - center);
00236 
00237         eb += print_binary_params(&k, primary->get_mass(), kT,
00238                                   dist_from_center, verbose,
00239                                   long_binary_output, init_indent);
00240 
00241         if (dstar_params != NULL && od->is_leaf() && yd->is_leaf())
00242             dstar_params(bi);
00243                     
00244         real e = od->print_pert(long_binary_output);
00245         if (e != 0) {
00246             n_unp++;
00247             e_unp += e;
00248         }
00249 
00250         for_all_daughters(dyn, bi, bb) {
00251             eb += print_structure_recursive(bb, dstar_params,
00252                                             n_unp, e_unp,
00253                                             kT, center,
00254                                             verbose, long_binary_output,
00255                                             indent+2);
00256         }
00257     }
00258 
00259     return eb;
00260 }
00261 
00262 void compute_core_parameters(dyn* b, int k,
00263                              bool allow_n_sq_ops,
00264                              vector& center,
00265                              real& rcore, int& ncore, real& mcore)
00266 {
00267     vector vel;
00268 
00269     // Write densities to particle dyn stories, if necessary.
00270 
00271     if (getrq(b->get_dyn_story(), "density_time")
00272                 != b->get_system_time()) {
00273 
00274         if (!allow_n_sq_ops) {
00275             cerr << "compute_core_parameters:  no densities available "
00276                  << "and allow_n_sq_ops set false" << endl;
00277             ncore = 0;
00278             rcore = mcore = 0;
00279             return;
00280         }
00281 
00282         cerr << "\n  compute_core_parameters:  computing densities\n";
00283         compute_density(b, k);          // (N^2 ops on the front end...)
00284     }
00285 
00286     // Compute mean (not max) density center, if necessary.
00287 
00288     if (getrq(b->get_dyn_story(), "density_center_time")
00289                 != b->get_system_time()
00290         || !strcmp(getsq(b->get_dyn_story(), "density_center_type"), "mean"))
00291       {
00292         // Find point with maximum density (changed by SM&SPZ Oct 11, 2001)
00293         compute_max_cod(b, center, vel);
00294         //      compute_mean_cod(b, center, vel);
00295       }
00296 
00297     real total_weight = 0;
00298     real sum = 0;
00299     for_all_daughters(dyn, b, bi) {
00300         real density = getrq(bi->get_dyn_story(), "density");
00301 
00302         if (density > 0) {
00303             real dens2 = density * density;             // weight factor
00304 
00305             total_weight += dens2;
00306             sum += dens2 * square(bi->get_pos() - center);
00307         }
00308     }
00309 
00310     real rcore2 = 0;
00311     if (total_weight > 0 && sum > 0)
00312         rcore2 = sum/total_weight;
00313 
00314     rcore = sqrt(rcore2);
00315     ncore = 0;
00316     mcore = 0;
00317 
00318     if (rcore2 > 0) {
00319         for_all_daughters(dyn, b, bj)
00320             if (square(bj->get_pos() - center) <= rcore2) {
00321                 ncore++;
00322                 mcore += bj->get_mass();
00323             }
00324     }
00325 }
00326 

Generated at Sun Feb 24 09:56:59 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001