Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

_dyn_.h

Go to the documentation of this file.
00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00012 //                 Base class for hdyn, sdyn3, and sdyn.
00013 //
00014 //  version 1:  Aug 1998   Steve McMillan, Simon Portegies Zwart
00015 //  version 2:
00016 //
00017 //  This file includes:
00018 //  1) definition of class _dyn_
00019 
00020 #ifndef  STARLAB__DYN__H
00021 #  define  STARLAB__DYN__H
00022 
00023 #include "dyn.h"
00024 #include "slow_binary.h"
00025 
00029 
00030 class  _dyn_ : public dyn
00031 {
00032     protected:
00033 
00034         xreal time;             
00035         real  timestep;         
00036 
00037         real pot;               
00038         vec jerk;               
00039         vec old_acc;            
00040         vec old_jerk;           
00041 
00042         vec k_over_18;          
00043 
00044         // Relocated radius to try to reduce cache misses in
00045         // critical functions.  Would like to make it private to force
00046         // use of the accessor function, since the actual value may need
00047         // processing before use (e.g. black holes).  However, this
00048         // apparently also changes the data layout of the class and
00049         // worsens the caching problem.  For now, discourage use of the
00050         // raw class data by general functions, and return something
00051         // usable (e.g. not negative) in the accessor function.
00052         //                                              (Steve, 1/05)
00053 
00054         real radius;            
00055         vec pred_pos;           
00056         vec pred_vel;           
00057         xreal t_pred;           
00058 
00059         slow_binary * slow;     
00060                                 // -- affects all time, prediction, and
00061                                 //    correction functions
00062                                 // -- actually used in kira, but all relevant
00063                                 //    member functions are defined here...
00064 
00066         //  (Also used in kira only).
00067 
00068         slow_perturbed * sp;
00069 
00070         // Note: "time" is always time, and "timestep" is always timestep,
00071         // regardless of the "slow" settings.  However, dtau is actually
00072         // used during the integration of slow binary motion.
00073 
00074     public:
00075 
00076         _dyn_(hbpfp the_hbpfp = new_hydrobase, sbpfp the_sbpfp = new_starbase)
00077            : dyn(the_hbpfp, the_sbpfp, true) {
00078 
00079             time = timestep = pot = 0;
00080             k_over_18 = jerk = old_acc = old_jerk = pred_pos = pred_vel = 0;
00081             t_pred = -VERY_LARGE_NUMBER;
00082             radius = 0;
00083             slow = NULL;
00084             sp = NULL;
00085         }
00086 
00087         virtual ~_dyn_() {
00088 
00089             // Some care is required when deleting the slow structure,
00090             // as binary components share it.  See the note on keplers
00091             // in the dyn destructor.
00092 
00093             if (slow) {
00094                 _dyn_ *s = get_binary_sister();
00095                 if (s) {
00096                     if (s->slow == slow) s->slow = NULL;
00097                 }
00098                 delete slow;
00099                 slow = NULL;
00100             }
00101 
00102             if (sp) {
00103                 delete sp;      // deletes the entire chain
00104                 sp = NULL;
00105             }
00106 
00107         }
00108 
00110 
00111         void set_timestep(real dt) {            // dt is always timestep
00112             timestep = dt;
00113             if (slow) slow->set_dtau(dt/slow->get_kappa());
00114         }
00115 
00116         inline void set_time(xreal t) {         // t is always time
00117             time = t;
00118             if (slow) slow->set_tau(slow->time_to_tau(time));
00119         }
00120 
00121         // The "get_time" accessors should be OK given the above "set"
00122         // functions.
00123 
00124         inline real get_timestep()      const   {return timestep;}
00125         inline xreal get_time()         const   {return time;}
00126 
00128 
00129         void  clear_interaction()         {acc = jerk = 0;
00130                                            pot = 0;}
00131 
00132         void  set_acc_and_jerk_and_pot(const vec& a,
00133                                        const vec& j, real p)
00134            {acc = a; jerk = j; pot = p;}
00135 
00137 
00138         inline vec  get_pred_pos()     {predict_loworder(get_system_time());
00139                                            return pred_pos;}
00140 
00142 
00143         inline vec  get_pred_vel()     {predict_loworder(get_system_time());
00144                                            return pred_vel;}
00145 
00147 
00148         inline vec  get_nopred_pos()    const   {return pred_pos;}
00149 
00151 
00152         inline vec  get_nopred_vel()    const   {return pred_vel;}
00153 
00154         inline void set_pred_pos(vec p)   {pred_pos = p;}
00155         inline void set_pred_vel(vec v)   {pred_vel = v;}
00156 
00157         void  clear_t_pred()              {t_pred = -VERY_LARGE_NUMBER;
00158                                            if (slow) slow->clear_tau_pred();}
00159         inline xreal get_t_pred()         {return t_pred;}
00160         inline void  set_t_pred(xreal t)  {t_pred = t;}
00161         
00162         real  get_pot()         const     {return pot;}
00163         void  set_pot(const real p)       {pot = p;}
00164         void  clear_pot()                 {pot = 0;}
00165         void  inc_pot(const real& d_pot)  {pot += d_pot;}
00166 
00167         inline void set_jerk(const vec& new_jerk)     {jerk = new_jerk;}
00168         inline void set_old_acc(const vec& new_acc)   {old_acc = new_acc;}
00169         inline void set_old_jerk(const vec& new_jerk) {old_jerk = new_jerk;}
00170 
00171         inline void clear_jerk()                         {jerk = 0;}
00172 
00173         inline void scale_jerk(const real scale_factor)
00174             {jerk *= scale_factor;}
00175         inline void scale_old_acc(const real scale_factor)
00176             {old_acc *= scale_factor;}
00177         inline void scale_old_jerk(const real scale_factor)
00178             {old_jerk *= scale_factor;}
00179 
00180         inline void inc_jerk(const vec& d_jerk)       {jerk += d_jerk; }
00181         inline void inc_old_acc(const vec& d_acc)     {old_acc += d_acc; }
00182         inline void inc_old_jerk(const vec& d_jerk)   {old_jerk += d_jerk; }
00183 
00184         inline vec get_jerk()           const   {return jerk;}
00185         inline vec get_old_acc()        const   {return old_acc;}
00186         inline vec get_old_jerk()       const   {return old_jerk;}
00187         inline vec get_k_over_18()      const   {return k_over_18;}
00188 
00189         inline real get_radius()        const   {return abs(radius);}
00190         void set_radius(real r)                 {radius = r;}
00191 
00192         // Slow-binary manipulation functions defined in _dyn_slow.C:
00193 
00194         void create_slow(int k = 1);    
00195         void delete_slow();             
00196         void extend_slow(int k);        
00197 
00198         slow_binary* get_slow()         const   {return slow;}
00199         slow_perturbed* get_sp()        const   {return sp;}
00200 
00201         inline int get_kappa()          const   {if (slow)
00202                                                      return slow->get_kappa();
00203                                                  else
00204                                                      return 1;
00205                                                 }
00206 
00207         inline _dyn_ * get_parent() const
00208             {return (_dyn_*) node::get_parent();}
00209         inline _dyn_ * get_oldest_daughter() const
00210             {return (_dyn_*)node::get_oldest_daughter();}
00211         inline _dyn_ * get_younger_sister() const
00212             {return (_dyn_*) node::get_younger_sister();}
00213         inline _dyn_ * get_elder_sister() const
00214             {return (_dyn_*) node::get_elder_sister();}
00215 
00217 
00218         inline _dyn_ * get_root() const
00219             {return (_dyn_*) node::get_root();}
00220 
00222 
00223         inline _dyn_ * get_top_level_node() const
00224             {return (_dyn_*) node::get_top_level_node();}
00225 
00227 
00228         inline _dyn_ * get_binary_sister()
00229             {return (_dyn_*) node::get_binary_sister();}
00230 
00231         void  init_pred() {
00232             pred_pos = pos;
00233             pred_vel = vel;
00234             t_pred = get_time();
00235             if (slow) slow->init_tau_pred();
00236         }
00237 
00238         void  store_old_force() {
00239             old_acc = acc;
00240             old_jerk = jerk;
00241 
00242             // Save the perturbative forces separately for slow binaries
00243             // and their perturbers.  Note that old_acc and old_jerk must
00244             // *include* the perturbative pieces.
00245 
00246             _dyn_ *od = get_oldest_daughter();
00247 
00248             if (od && od->slow)
00249                 od->slow->store_old_force();
00250 
00251             if (sp)
00252                 sp->store_old_force();                  // store entire chain
00253         }
00254 
00255         inline void predict_loworder(xreal t) {         // t is always time
00256 
00257             if (kep) {
00258 
00259                 init_pred();
00260 
00261             } else {
00262 
00263                 if (t_pred < t) {
00264 
00265                     real dt;
00266 
00267                     // Note that prediction actually occurs in tau if
00268                     // slow is set.
00269 
00270                     if (slow)
00271                         dt = slow->time_to_tau(t) - slow->get_tau();
00272                     else
00273                         dt = t - get_time();
00274 
00275                     // Note that this prediction makes *no* assumptions
00276                     // about the prediction of binary sisters -- this
00277                     // may be quite inefficient if no special precautions
00278                     // are taken when many nodes are predicted.
00279 
00280                     real dt3 = dt * ONE_THIRD;
00281                     real dt2 = dt * 0.5;
00282                     pred_pos = ((old_jerk * dt3
00283                                         + old_acc) * dt2 + vel) * dt + pos;
00284                     pred_vel = (old_jerk * dt2
00285                                         + old_acc) * dt + vel;
00286 
00287                     t_pred = t;
00288                     if (slow)
00289                         slow->set_tau_pred(slow->time_to_tau(t_pred));
00290                 }
00291             }
00292         }
00293 
00294         inline void predict_loworder5(xreal t) {        // t is always time
00295 
00296             // 5th-order prediction of a top-level node (not checked)
00297 
00298             if (t_pred < t) {
00299 
00300                 real dt = t - get_time();
00301 
00302                 real dt3 = dt * ONE_THIRD;
00303                 real dt2 = dt * 0.5;
00304                 pred_pos = (((4.5 * k_over_18 * dt + old_jerk) * dt3
00305                                 + old_acc) * dt2 + vel) * dt + pos;
00306                 pred_vel = ((6 * k_over_18 + old_jerk) * dt2
00307                                 + old_acc) * dt + vel;
00308 
00309                 t_pred = t;
00310             }
00311         }
00312 
00313         inline void predict_from_elder_sister() {
00314 
00315             // For low-level binary nodes only -- NOT checked here.
00316 
00317             _dyn_ *s = get_elder_sister();
00318 
00319             real factor = -s->mass / mass;
00320             pred_pos = factor * s->pred_pos;
00321             pred_vel = factor * s->pred_vel;
00322             t_pred = s->t_pred;
00323         }
00324 
00325         // Handling the slow_perturbed lists (_dyn_slow.C):
00326 
00327         void clear_slow_perturbed() {if (sp) delete sp; sp = NULL;}
00328         void check_slow_perturbed(bool verbose = false);
00329         slow_perturbed *find_slow_perturbed(_dyn_ *n, bool verbose = false);
00330         slow_perturbed *add_slow_perturbed(_dyn_ *n, bool verbose = false);
00331         bool copy_slow_perturbed(_dyn_ *to,
00332                                  bool overwrite = false,
00333                                  bool verbose = false);
00334         void remove_slow_perturbed(_dyn_ *n, bool verbose = false);
00335         void dump_slow_perturbed(char *string = "");
00336         void print_slow_perturbed();
00337         int count_slow_perturbed();
00338             
00339         virtual void null_pointers();
00340         virtual void print_static(ostream &s = cerr);
00341 
00342         virtual  istream& scan_dyn_story(istream&);
00343         virtual  ostream& print_dyn_story(ostream &s,
00344                                           bool print_xreal = true,
00345                                           int short_output = 0);
00346 
00347         // Potentially slow function -- avoid wherever possible!
00348 
00349         inline xreal get_next_time() const {return get_time()
00350                                                  + (xreal)timestep;}
00351 
00352         // Flat-specific member functions defined in _dyn_/evolve/_dyn_ev.C:
00353         
00354         void flat_accumulate_acc_and_jerk(_dyn_ *, real);
00355         void flat_calculate_acc_and_jerk(_dyn_ *, real);
00356         void flat_set_first_timestep(real, real);
00357         void flat_update(const real, const real);
00358         bool flat_correct();
00359 };
00360 
00361 // Also defined in _dyn_ev.C:
00362 
00363 void predict_loworder_all(_dyn_* b, xreal t);
00364 
00365 // In _dyn_slow.C:
00366 
00367 bool is_valid_slow(_dyn_ *pert_node);
00368 
00369 typedef _dyn_ * _dyn_ptr;  // to enable dynamic array declarations such as
00370                            //    _dyn_** _dyn__ptr_array = new _dyn_ptr[n];
00371                            // (note that the following expression is illegal:
00372                            //    _dyn_** _dyn__ptr_array = new (_dyn_ *)[n];)
00373 
00374 // Third argument below is present because get_node expects it...
00375 
00376 inline  node * new__dyn_(hbpfp the_hbpfp, sbpfp the_sbpfp,
00377                          bool use_stories = true)
00378     {return (node *) new _dyn_(the_hbpfp, the_sbpfp);}   // ignore 3rd argument
00379 
00380 // "True" below means "use stories".
00381 
00382 inline  _dyn_ * get__dyn_(istream & s = cin,
00383                           hbpfp the_hbpfp = new_hydrobase,
00384                           sbpfp the_sbpfp = new_starbase)
00385     {return  (_dyn_ *) get_node(s, new__dyn_, the_hbpfp, the_sbpfp, true);}
00386 
00387 #define  put__dyn_  put_node
00388 
00389 #endif
00390 
00391 //=======================================================================//
00392 //  +---------------+        _\|/_        +------------------------------\\ ~
00393 //  |  the end of:  |         /|\         |  inc/_dyn_.h
00394 //  +---------------+                     +------------------------------//
00395 //========================= STARLAB =====================================

Generated on Wed Jul 20 12:43:35 2005 for Starlab by  doxygen 1.4.3