00001 
00002        
00003       
00004      
00005     
00006    
00007   
00008  
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 #include "_dyn_.h"
00037 
00038 void _dyn_::create_slow(int k)          
00039 {
00040     if (!is_low_level_node()) {
00041         warning("create_slow: not a low-level node");
00042         return;
00043     }
00044 
00045     slow = new slow_binary(k);
00046 
00047     slow->set_t_init(get_time());
00048     slow->set_t_apo(get_time());
00049 
00050     
00051 
00052     slow->set_dtau(timestep);
00053     timestep *= k;
00054 
00055     
00056     
00057 
00058     _dyn_ *s = get_younger_sister();
00059 
00060     if (!s) {
00061 
00062         warning("create_slow: no younger sister");
00063 
00064     } else {
00065 
00066         real m2 = get_binary_sister()->mass;
00067         vector sep = pos * (1 + mass/m2);
00068         real r2 = sep*sep;
00069         vector a2 = -m2*sep / (r2*sqrt(r2));
00070 
00071         acc = a2 + (acc - a2) * k;
00072         old_acc = acc;                  
00073 
00074         
00075 
00076         s->slow = slow;
00077         real factor = -s->mass / mass;
00078         s->acc = factor * acc;
00079         s->old_acc = s->acc;
00080 
00081     }
00082 }
00083 
00084 void _dyn_::delete_slow()
00085 {
00086     if (!slow) {
00087 
00088         cerr << "warning: delete_slow: " << format_label()
00089              << " is not a slow binary" << endl;
00090         return;
00091 
00092     } else {
00093 
00094         int k = get_kappa();
00095 
00096         timestep /= k;
00097 
00098         
00099         
00100 
00101         
00102         
00103 
00104         _dyn_ *s = get_younger_sister();
00105 
00106         if (!s) {
00107 
00108             warning("delete_slow: no younger sister...");
00109 
00110         } else {
00111 
00112             real m2 = s->mass;
00113             vector sep = pos * (1 + mass/m2);
00114             real r2 = sep*sep;
00115             vector a2 = -m2*sep / (r2*sqrt(r2));
00116 
00117             acc = a2 + (acc - a2) / k;
00118             old_acc = acc;              
00119 
00120             
00121 
00122             real factor = -s->mass / mass;
00123             s->acc = factor * acc;
00124             s->old_acc = s->acc;
00125 
00126         }
00127 
00128         delete slow;
00129 
00130         slow = NULL;
00131         if (s) s->slow = NULL;
00132     }
00133 }
00134 
00135 void _dyn_::extend_slow(int k)          
00136 {
00137     if (!slow) {
00138 
00139         cerr << "warning: extend_slow: " << format_label()
00140              << " is not a slow binary" << endl;
00141         return;
00142 
00143     } else {
00144 
00145         real k_fac = ((real)k) / get_kappa();
00146         slow->set_kappa(k);
00147 
00148         slow->set_t_init(get_time());
00149         slow->set_t_apo(get_time());
00150 
00151         
00152 
00153         slow->set_tau(0);
00154         slow->init_tau_pred();
00155 
00156         timestep *= k_fac;
00157 
00158         
00159         
00160 
00161         _dyn_ *s = get_younger_sister();
00162 
00163         if (!s) {
00164 
00165             warning("extend_slow: no younger sister");
00166 
00167         } else {
00168 
00169             real m2 = get_binary_sister()->mass;
00170             vector sep = pos * (1 + mass/m2);
00171             real r2 = sep*sep;
00172             vector a2 = -m2*sep / (r2*sqrt(r2));
00173 
00174             acc = a2 + (acc - a2) * k_fac;
00175             old_acc = acc;              
00176 
00177             
00178 
00179             real factor = -s->mass / mass;
00180             s->acc = factor * acc;
00181             s->old_acc = s->acc;
00182 
00183         }
00184     }
00185 }
00186 
00187 
00188 
00189 bool is_valid_slow(_dyn_ *pert_node)
00190 {
00191     if (!pert_node
00192         || !pert_node->is_valid()
00193         || !pert_node->get_oldest_daughter()
00194         || !pert_node->get_oldest_daughter()->get_slow())
00195         return false;
00196     else
00197         return true;
00198 }
00199 
00200 typedef slow_perturbed* sp_ptr;
00201 
00202 local void delete_slow_perturbed(_dyn_ *b,
00203                                  sp_ptr &s,
00204                                  slow_perturbed *prev,
00205                                  sp_ptr &sp,
00206                                  bool verbose)
00207 {
00208     
00209 
00210     slow_perturbed *next = s->get_next();
00211 
00212     if (prev)
00213         prev->set_next(next);
00214     else
00215         sp = next;
00216 
00217     if (verbose) {
00218         cerr << "deleted " << s->get_node()->format_label();
00219         cerr << " from slow_perturbed list of " << b->format_label()
00220              << " at time " << b->get_system_time()
00221              << endl;
00222     }
00223 
00224     s->set_next(NULL);          
00225     delete s;
00226     s = next;
00227 }
00228 
00229 void _dyn_::check_slow_perturbed(bool verbose)          
00230 {
00231     slow_perturbed *s = sp, *prev = NULL;
00232     while (s) {
00233         _dyn_ *pert_node = s->get_node();
00234 
00235         
00236 
00237         if (!is_valid_slow(pert_node))
00238 
00239             delete_slow_perturbed(this, s, prev, sp, verbose);
00240 
00241         else {
00242 
00243             prev = s;
00244             s = s->get_next();
00245 
00246         }
00247     }
00248 }
00249 
00250 slow_perturbed* _dyn_::find_slow_perturbed(_dyn_ *n,      
00251                                            bool verbose)  
00252 {
00253     slow_perturbed *s = sp, *prev = NULL;
00254     while (s) {
00255         _dyn_ *pert_node = s->get_node();
00256 
00257         
00258 
00259         if (!is_valid_slow(pert_node))
00260 
00261             delete_slow_perturbed(this, s, prev, sp, verbose);
00262 
00263         else {
00264 
00265             if (pert_node == n) return s;
00266 
00267             prev = s;
00268             s = s->get_next();
00269 
00270         }
00271     }
00272     return NULL;
00273 }
00274 
00275 slow_perturbed* _dyn_::add_slow_perturbed(_dyn_ *n,
00276                                           bool verbose)   
00277 {
00278     if (!is_valid_slow(n)) return NULL;
00279 
00280     slow_perturbed *s = sp, *prev = NULL;
00281     while (s) {
00282         if (s->get_node() == n) return s;
00283         prev = s;
00284         s = s->get_next();
00285     }
00286 
00287     s = new slow_perturbed();
00288     s->set_node(n);
00289     s->set_kappa(n->get_oldest_daughter()->get_kappa());
00290 
00291     if (prev)
00292         prev->set_next(s);
00293     else
00294         sp = s;
00295 
00296     if (verbose) {
00297         cerr << "added " << n->format_label();
00298         cerr << " to slow_perturbed list of " << format_label()
00299              << " at time " << get_system_time()
00300              << endl;
00301     }
00302 
00303     return s;
00304 }
00305         
00306 void _dyn_::remove_slow_perturbed(_dyn_ *n,
00307                                   bool verbose)         
00308 {
00309     slow_perturbed *s = sp, *prev = NULL;
00310     while (s) {
00311 
00312         if (s->get_node() == n) {
00313             delete_slow_perturbed(this, s, prev, sp, verbose);
00314             return;
00315         }
00316 
00317         prev = s;
00318         s = s->get_next();
00319     }
00320 }
00321 
00322 bool _dyn_::copy_slow_perturbed(_dyn_ *to,
00323                                 bool overwrite,         
00324                                 bool verbose)           
00325 {
00326     
00327     
00328 
00329     if (!sp) return false;
00330 
00331     if (to->get_sp()) {
00332         if (overwrite) {
00333             if (verbose) cerr << "copy_slow_perturbed: "
00334                               << "deleting existing slow_perturbed list"
00335                               << endl;
00336             delete to->get_sp();
00337         } else {
00338             if (verbose) cerr << "copy_slow_perturbed: "
00339                               << "adding to existing slow_perturbed list"
00340                               << endl;
00341         }
00342     }
00343 
00344     slow_perturbed *s = sp;
00345     while (s) {
00346         to->add_slow_perturbed(s->get_node(), verbose);
00347         s = s->get_next();
00348     }
00349 
00350     return true;
00351 }
00352 
00353 void _dyn_::dump_slow_perturbed(char *string)           
00354 {
00355     
00356 
00357     if (!sp) return;
00358 
00359     cerr << string
00360          << "dump slow_perturbed list for "
00361          << format_label() << " at time " << get_system_time() << ":"
00362          << endl;
00363 
00364     slow_perturbed *s = sp;
00365     int n = 0;
00366     while (s) {
00367         n++;
00368 
00369         cerr << string; PRC(n); PRL(s);
00370         cerr << string; PRI(4); PRC(s->get_node());
00371                         PRL(s->get_node()->format_label());
00372         cerr << string; PRI(4); PRL(s->get_kappa());
00373         cerr << string; PRI(4); PRL(s->get_next());
00374 
00375         s = s->get_next();
00376     }
00377 }
00378 
00379 void _dyn_::print_slow_perturbed()      
00380 {
00381     if (!sp) return;
00382 
00383     cerr << "slow_perturbed list of " << format_label() << ":"
00384          << endl;
00385 
00386     slow_perturbed *s = sp;
00387     while (s) {
00388         cerr << " " << s->get_node()->format_label();
00389         s = s->get_next();
00390     }
00391     cerr << endl;
00392 }
00393 
00394 int _dyn_::count_slow_perturbed()
00395 {
00396     slow_perturbed *s = sp;
00397     int n = 0;
00398     while (s) {
00399         n++;
00400         s = s->get_next();
00401     }
00402     return n;
00403 }
00404