00001
00002
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,
00009 bool long_binary_output,
00010 int init_indent,
00011 int indent)
00012
00013
00014
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
00042
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,
00141 vector center,
00142 bool verbose,
00143 bool long_binary_output)
00144 {
00145
00146
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
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
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
00202
00203
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);
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
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);
00284 }
00285
00286
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
00293 compute_max_cod(b, center, vel);
00294
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;
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