Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

scatter_merge.C

Go to the documentation of this file.
00001 
00002 //#include "sdyn.h"
00003 #include "scatter.h"
00004 
00005 // set_merger_mass_and_radius: determine mass and radius of merger product
00006 
00007 local void set_merger_mass_and_radius(sdyn * bn, sdyn * bi, sdyn * bj)
00008 {
00009   bn->set_mass(bi->get_mass() + bj->get_mass());       // No mass loss
00010   bn->set_radius(bi->get_radius() + bj->get_radius()); // R \propto M
00011 }
00012 
00013 
00014 // set_merger_dyn: determine pos, vel, acc and jerk of merger product,
00015 //                 and determine energy dissipation
00016 
00017 local void set_merger_dyn(sdyn * bn, sdyn * bi, sdyn * bj)
00018 {
00019     real  mi = bi->get_mass();
00020     real  mj = bj->get_mass();
00021     real  m_inv = 1/(mi + mj);
00022     
00023     bn->set_pos((mi*bi->get_pos() + mj*bj->get_pos())*m_inv);
00024     bn->set_vel((mi*bi->get_vel() + mj*bj->get_vel())*m_inv);
00025     bn->set_acc((mi*bi->get_acc() + mj*bj->get_acc())*m_inv);
00026     bn->set_jerk((mi*bi->get_jerk() + mj*bj->get_jerk())*m_inv);
00027 
00028     vector d_pos = bi->get_pos() - bj->get_pos();
00029     real rij = sqrt(d_pos*d_pos);
00030 
00031     vector d_vel = bi->get_vel() - bj->get_vel();
00032     real vij2 = d_vel*d_vel;
00033 
00034     real eij_pot = -mi * mj / rij;
00035     real eij_kin = 0.5 * mi * mj * m_inv * vij2;
00036 
00037     // Include tidal term from spectator star, if any:
00038 
00039     sdyn * b = bi->get_parent();
00040     sdyn * bk = NULL;
00041 
00042     for_all_daughters(sdyn, b, bb)
00043         if (bb != bi && bb != bj) bk = bb;
00044 
00045     real tidal_pot = 0;
00046     if (bk) {
00047         real mn = mi + mj;
00048         real mk = bk->get_mass();
00049         tidal_pot = -mn * mk / abs(bn->get_pos() - bk->get_pos())
00050                     + mi * mk / abs(bi->get_pos() - bk->get_pos())
00051                     + mj * mk / abs(bj->get_pos() - bk->get_pos());
00052     }
00053 
00054     bn->set_energy_dissipation(bi->get_energy_dissipation()
00055                                + bj->get_energy_dissipation()
00056                                + eij_pot + eij_kin
00057                                - tidal_pot);
00058 
00059 }
00060 
00061 local char * string_index_of_node(node * n)
00062 {
00063     char * tmp;
00064     tmp = n->get_name();
00065     if (tmp != NULL) {
00066         return tmp;
00067     } else {
00068         static char integer_id[20];
00069         sprintf(integer_id, "%d", n->get_index());
00070         n->set_label(integer_id);
00071         return n->get_name();
00072     }
00073 }
00074 
00075 local char * construct_merger_label(node * ni, node * nj)
00076 {
00077     static char new_name[1024];
00078     sprintf(new_name, "%s+%s",
00079             string_index_of_node(ni),
00080             string_index_of_node(nj));
00081     return new_name;
00082 }
00083 
00084 // merge: replace two particles by their center of mass.
00085 
00086 void merge(sdyn * bi, sdyn * bj) {
00087 
00088     sdyn * b = bi->get_parent();
00089     if (b != bj->get_parent()) err_exit("merge: parent conflict...");
00090 
00091     // Note: any stories attached to the particles are lost.
00092 
00093     sdyn * bn = new sdyn();
00094 
00095 #if 0
00096 cerr.precision(6);
00097 cerr << "entering merge(" << bi->get_index() << ", " << bj->get_index()
00098      << ") at dist = " << abs(bi->get_pos()-bj->get_pos()) 
00099      << " with r1 = "<<bi->get_radius() << " r2 = " << bi->get_radius() << endl
00100      << " with v1 = " << bi->get_vel() << "\n"
00101      << "  and v2 = " << bj->get_vel() << endl
00102      << "         at t = " << b->get_time() << endl;
00103 #endif
00104 
00105     set_merger_mass_and_radius(bn, bi, bj);
00106     set_merger_dyn(bn, bi, bj);
00107     bn->set_time(bi->get_time());
00108 
00109     if(bi->get_mass()>bj->get_mass())
00110       bn->set_label(construct_merger_label(bi, bj));
00111     else
00112       bn->set_label(construct_merger_label(bj, bi));
00113 
00114     detach_node_from_general_tree(*bi);
00115     detach_node_from_general_tree(*bj);
00116   
00117     add_node(*bn, *b);
00118 }
00119 
00120 // merge_collisions: recursively merge any stars in contact.
00121 
00122 real merge_collisions(sdyn * b, int ci)
00123 {
00124 
00125   real de = 0;
00126     int coll = 1;
00127     while (coll) {
00128 
00129         coll = 0;
00130         for_all_daughters(sdyn, b, bi)
00131             {
00132             if (coll) break;
00133             for (sdyn * bj = bi->get_younger_sister(); bj != NULL; 
00134                  bj = bj->get_younger_sister()) {
00135 
00136                 if ( abs(bi->get_pos() - bj->get_pos())
00137                       < (bi->get_radius() + bj->get_radius()) ) {
00138 
00139                   b->flatten_node();
00140                   real kin, pot;
00141                   real etot_init = calculate_energy_from_scratch(b, kin, pot);
00142                   make_tree(b, 1, 1, 2, false);
00143 
00144                   merge(bi, bj);
00145                   b->flatten_node();
00146                   real etot_final = calculate_energy_from_scratch(b, kin, pot);
00147                   make_tree(b, 1, 1, 2, false);
00148                   real merger_de = etot_final - etot_init;
00149                   de = merger_de;
00150 
00151                   coll = 1;
00152                   break;
00153                 }
00154             }
00155         }
00156     }
00157 
00158     return de;
00159 }

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