00001 00002 //=======================================================// _\|/_ 00003 // __ _____ ___ ___ // /|\ 00004 // / | ^ | \ | ^ | \ // _\|/_ 00005 // \__ | / \ |___/ | / \ |___/ // /|\ 00006 // \ | /___\ | \ | /___\ | \ // _\|/_ 00007 // ___/ | / \ | \ |____ / \ |___/ // /|\ 00008 // // _\|/_ 00009 //=======================================================// /|\ 00010 00011 // 00012 // hdyn_flat.C: functions related to orbit integration within the hdyn class. 00013 // - member functions for FLAT trees only 00014 //............................................................................. 00015 // version 1: Jul 1996 Steve McMillan 00016 // version 2: 00017 //............................................................................. 00018 00019 #include "hdyn.h" 00020 00021 //----------------------------------------------------------------------------- 00022 // flat_accumulate_acc_and_jerk -- calculates the contribution to the 00023 // acceleration & jerk on this node from 00024 // the node leaf. 00025 // note: for flat trees only 00026 //----------------------------------------------------------------------------- 00027 00028 inline void 00029 hdyn::flat_accumulate_acc_and_jerk(hdyn * leaf, // attracting leaf node 00030 real eps2) // softening length squared 00031 { 00032 vector d_pos = leaf->get_pred_pos() - get_pred_pos(); 00033 vector d_vel = leaf->get_pred_vel() - get_pred_vel(); 00034 real r2inv = 1.0 / (d_pos * d_pos + eps2); 00035 real a3 = -3.0 * (d_pos * d_vel) * r2inv; 00036 real mrinv = leaf->get_mass() * sqrt(r2inv); 00037 pot -= mrinv; 00038 real mr3inv = mrinv * r2inv; 00039 acc += mr3inv * d_pos; 00040 jerk += mr3inv * (d_vel + a3 * d_pos); 00041 } 00042 00043 //----------------------------------------------------------------------------- 00044 // flat_calculate_acc_and_jerk -- calculates acceleration & jerk on this node: 00045 // from all nodes under p (if p is root ptr); 00046 // or from the node p (if p is a leaf ptr). 00047 // 00048 // NOTE: for flat trees only 00049 // 00050 //----------------------------------------------------------------------------- 00051 00052 #ifdef RECURSIVE_LOOP 00053 00054 void hdyn::flat_calculate_acc_and_jerk(hdyn * p, // root or leaf 00055 real eps2) // softening length squared 00056 { 00057 if (p->is_root()) { // p is root, so 00058 // invoke for all leaves 00059 for_all_daughters(hdyn, p, d) 00060 flat_calculate_acc_and_jerk(d, eps2); 00061 00062 } else { // p is leaf, but 00063 // not this leaf 00064 if (p != this) 00065 flat_accumulate_acc_and_jerk(p, eps2); 00066 } 00067 } 00068 00069 #else 00070 00071 // Looping by recursion (as above) is relatively expensive on many systems. 00072 // Remove the recursion for the sake of efficiency (and readability?) by 00073 // using an explicit loop. 00074 00075 void hdyn::flat_calculate_acc_and_jerk(hdyn * p, // root or leaf 00076 real eps2) // softening length squared 00077 { 00078 if (p->is_root()) { // p is root, so 00079 // invoke for all leaves 00080 for_all_daughters(hdyn, p, d) 00081 if (d != this) 00082 flat_accumulate_acc_and_jerk(d, eps2); 00083 00084 } else { // NOTE: else clause currently not used 00085 00086 if (p != this) 00087 flat_accumulate_acc_and_jerk(p, eps2); 00088 00089 } 00090 } 00091 00092 #endif