00001
00002
00003 #include "scatter.h"
00004
00005
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());
00010 bn->set_radius(bi->get_radius() + bj->get_radius());
00011 }
00012
00013
00014
00015
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
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
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
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
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 }