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

sdyn3.h

00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00011 /*
00012  *  sdyn3.h: derived class for nbody systems, for scattering experiments
00013  *.............................................................................
00014  *    version 1:  Dec 1993   Piet Hut, Steve McMillan
00015  *    version 2:
00016  *.............................................................................
00017  *     This file includes:
00018  *  1) definition of class sdyn3
00019  *.............................................................................
00020  */
00021 
00022 #ifndef  STARLAB_SDYN3_H
00023 #  define  STARLAB_SDYN3_H
00024 
00025 #define DEFAULT_TIDAL_TOL_FACTOR 1e-6
00026 
00027 #define SSD_HYSTERESIS_FACTOR 2     // multiplicative safety margin:
00028                                     // a minimum in ssd only counts as a 
00029                                     // certified minimum if it is surrounded at
00030                                     // both sides by maxima that are at least
00031                                     // this factor larger than the minimum;
00032                                     // two successive certified minima must
00033                                     // have at least one intermediate point in
00034                                     // time at which ssd is larger than either
00035                                     // minimum by this factor.
00036 
00037 #define MAX_N_STEPS     100000000
00038 
00039 #include  "_dyn_.h"
00040 
00041 /*-----------------------------------------------------------------------------
00042  *  sdyn3  --  a derived class of dynamical particles, with enough information
00043  *            to integrate the equations of motions with a 4th-order
00044  *            generalized Hermite polynomial integrator.
00045  *-----------------------------------------------------------------------------
00046  */
00047 class  sdyn3 : public _dyn_
00048 {
00049     protected:
00050 
00051         xreal  time_offset;
00052     
00053         real  energy_dissipation;          // dissipation associated with this
00054                                            // star due to its merger history
00055 
00056         real  min_encounter_time_sq;       // pair-wise
00057         real  min_free_fall_time_sq;       // pair-wise
00058 
00059         // In the current implementation of sdyn3_ev, the "nn" quantities
00060         // are only set if no_ssd_flag = 0 (i.e. on the final iteration).
00061 
00062         sdyn3* nn;               // pointer to the nearest neighbor
00063         real d_nn_sq;           // distance squared to the nearest neighbor
00064                                                 
00065         real  nn_dr2;         // current nearest neighbor distance squared
00066         int   nn_label;       // identity of current nearest neighbor
00067         real  min_nn_dr2;     // minimum-ever nearest neighbor distance squared
00068         int   min_nn_label;   // identity of nearest-ever neighbor
00069 
00070         int   init_nn_label;  // Identity of initial nearest neighbor
00071         int   nn_change_flag; // While zero, nearest neighbor remains unchanged
00072 
00073         real  new_pot;
00074         vec  new_pos;
00075         vec  new_vel;
00076         vec  new_acc;
00077         vec  new_jerk;
00078 
00079         void  accumulate_new_acc_and_jerk_from_new(sdyn3 *, real, int, int &);
00080 
00081 // the following nine (?) are only used in the root node, but given for all
00082 // particles, to keep the data structure homogeneous.
00083 
00084         real  ssd; // current sum of squares of inter-particle distances
00085 
00086         real  min_ssd;              // minimum sum of squares of all
00087                                     // inter-particle distances, after the
00088                                     // certified maximum
00089         real  max_ssd;              // maximum sum of squares of all
00090                                     // inter-particle distances, after the
00091                                     // certified maximum
00092 
00093         real  min_min_ssd;          // minimum-ever sum of squares of all
00094                                     // inter-particle distances
00095         int   n_ssd_osc;            // number of oscillations in ssd, so far
00096 
00097         int  ssd_ingoing_flag;      // true iff the last certified extremum was
00098                                     // a maximum; false iff the last certified
00099                                     // extremum was a minimum.
00100 
00101 // the following three quantities could be put in the dyn_story.
00102 
00103         real n_steps;       // number of integration steps, to make it easy
00104                            // to store a partially completed experiment, and 
00105                            // complete the run later.
00106         real e_tot_init;       // initial total energy of the system
00107         real de_tot_abs_max;   // maximum error at any previous step in the
00108                                // total energy.
00109 
00110     public:
00111 
00112         sdyn3(hbpfp the_hbpfp = new_hydrobase, sbpfp the_sbpfp = new_starbase)
00113            : _dyn_(the_hbpfp, the_sbpfp)
00114             {
00115             energy_dissipation = 0;
00116             time_offset = 0;
00117             nn = NULL;
00118             d_nn_sq = 0;
00119             min_nn_dr2 = VERY_LARGE_NUMBER;
00120             min_nn_label = -1;   // illegal value; no nearest-ever neighbor set
00121             init_nn_label = -1;  // illegal value; no initial neighbor set
00122             nn_change_flag = 0;
00123             n_steps = 0;
00124             de_tot_abs_max = 0;
00125             max_ssd = min_ssd = min_min_ssd = VERY_LARGE_NUMBER;
00126             n_ssd_osc = 0;
00127             ssd_ingoing_flag = 1;
00128             ssd = VERY_LARGE_NUMBER;
00129             }
00130  
00131         real  get_pot()                         {return pot;}
00132         xreal  get_time_offset()                {return time_offset;}
00133 
00134         real  get_new_pot()                     {return new_pot;}
00135         vec  get_new_pos()                   {return new_pos;}
00136         vec  get_new_vel()                   {return new_vel;}
00137         vec  get_new_acc()                   {return new_acc;}
00138         vec  get_new_jerk()                  {return new_jerk;}
00139 
00140         real  get_min_encounter_time_sq()       {return min_encounter_time_sq;}
00141         real  get_min_free_fall_time_sq()       {return min_free_fall_time_sq;}
00142 
00143         void  set_min_encounter_time_sq(real t) {min_encounter_time_sq = t;}
00144         void  set_min_free_fall_time_sq(real t) {min_free_fall_time_sq = t;}
00145 
00146         real  get_n_steps()                     {return n_steps;}
00147         void  set_n_steps(real n)               {n_steps = n;}
00148 
00149         real  get_e_tot_init()                  {return e_tot_init;}
00150         void  set_e_tot_init(real en)           {e_tot_init = en;}
00151 
00152         void  set_min_nn_dr2(real r)            {min_nn_dr2 = r;}
00153         void  set_min_nn_label(int label)       {min_nn_label = label;}
00154         void  set_nn_dr2(real r)                {nn_dr2 = r;}
00155         void  set_init_nn_label(int label)      {init_nn_label = label;}
00156         void  set_nn_change_flag(int flag)      {nn_change_flag = flag;}
00157 
00158         sdyn3 * get_nn(){return nn;}
00159         void set_nn(sdyn3 * new_nn){nn = new_nn;}
00160         real get_d_nn_sq(){return d_nn_sq;}
00161         void set_d_nn_sq(real d){d_nn_sq = d;}
00162   
00163         real  get_nn_dr2()                      {return nn_dr2;}
00164         real  get_min_nn_dr2()                  {return min_nn_dr2;}
00165         int   get_min_nn_label()                {return min_nn_label;}
00166         int   get_nn_label()                    {return nn_label;}
00167         int   get_init_nn_label()               {return init_nn_label;}
00168         int   get_nn_change_flag()              {return nn_change_flag;}
00169         real  get_min_min_ssd()                 {return min_min_ssd;}
00170         int   get_n_ssd_osc()                   {return n_ssd_osc;}
00171 
00172         real  get_ssd()                         {return ssd;}
00173 
00174         real  get_energy_dissipation()          {return energy_dissipation;}
00175         void  set_energy_dissipation(real d)    {energy_dissipation = d;}
00176 
00177         void  clear_new_interaction()           {new_acc=new_jerk=new_pot = 0;}
00178         void  clear_de_tot_abs_max()            {de_tot_abs_max = 0;}
00179 
00180         void  prepare_root()                  
00181             {
00182             min_nn_dr2 = -1;                   // not a valid number
00183             }
00184 
00185         void  prepare_branch()
00186             {
00187             min_min_ssd = -1;                  // not a valid number
00188             ssd = -1;                          // not a valid number
00189             min_ssd = -1;                      // not a valid number
00190             max_ssd = -1;                      // not a valid number
00191             }
00192 
00193         void  inc_time(real dt)                 {time += dt;}
00194 
00195         void  begin_offset_time(xreal t_off)    {time -= t_off;
00196                                                  time_offset += t_off;}
00197 
00198         void  end_offset_time()                 {time += time_offset;
00199                                                  time_offset = 0;}
00200 
00201         void  inc_new_pot(real dp)              {new_pot += dp;}
00202         void  inc_new_acc(vec da)            {new_acc += da;}
00203         void  inc_new_jerk(vec dj)           {new_jerk += dj;}
00204 
00205         void  inc_ssd(real ds)                  {ssd += ds;}
00206             
00207         void  calculate_new_acc_and_jerk_from_new(sdyn3 *, real, int, int &);
00208 
00209         void  taylor_pred_new_pos_and_vel(const real);
00210 
00211         void  taylor_pred_new_pos(const real dt)
00212             {
00213             new_pos = pos + dt * ( vel + 0.5*dt * acc );
00214             new_pos += (1./6) * dt*dt*dt * jerk;
00215             }
00216 
00217         void  taylor_pred_new_vel(const real dt)
00218             {
00219             new_vel = vel + dt * acc;
00220             new_vel += (1./2) * dt*dt * jerk;
00221             }
00222 
00223         void  correct_new_acc_and_jerk(const real, const real);
00224         void  correct_new_pos_and_vel(const real);
00225 
00226         void  store_old_into_new()
00227             {
00228             new_pot = pot;
00229             new_pos = pos;
00230             new_vel = vel;
00231             new_acc = acc;
00232             new_jerk = jerk;
00233             }
00234 
00235         void  store_new_into_old()
00236             {
00237             pot = new_pot;
00238             pos = new_pos;
00239             vel = new_vel;
00240             acc = new_acc;
00241             jerk = new_jerk;
00242             }
00243 
00244         sdyn3 * get_parent()
00245             {return (sdyn3*) node::get_parent();}
00246         sdyn3 * get_oldest_daughter()
00247             {return (sdyn3*)node::get_oldest_daughter();}
00248         sdyn3 * get_younger_sister()
00249             {return (sdyn3*) node::get_younger_sister();}
00250         sdyn3 * get_elder_sister()
00251             {return (sdyn3*) node::get_elder_sister();}
00252 
00253         virtual  istream& scan_dyn_story(istream&);
00254         virtual  ostream& print_dyn_story(ostream&s,
00255                                           bool print_xreal = true,
00256                                           int short_output = 0);
00257 };
00258 
00259 typedef sdyn3 * sdyn3ptr;  // to enable dynamic array declarations such as
00260                          //    sdyn3** sdyn3_ptr_array = new sdyn3ptr[n];
00261                          // (note that the following expression is illegal:
00262                          //    sdyn3** sdyn3_ptr_array = new (sdyn3 *)[n];)
00263 
00264 // Third argument below is present because get_node expects it...
00265 
00266 inline  node * new_sdyn3(hbpfp the_hbpfp, sbpfp the_sbpfp,
00267                          bool use_stories = true)
00268     {return (node *) new sdyn3(the_hbpfp, the_sbpfp);}   // ignore 3rd argument
00269 
00270 inline sdyn3 * mksdyn3(int n, hbpfp the_hbpfp = new_hydrobase,
00271                             sbpfp the_sbpfp = new_starbase)
00272     {return  (sdyn3 *) mk_flat_tree(n, new_sdyn3, the_hbpfp, the_sbpfp);}
00273 
00274 inline  sdyn3 * get_sdyn3(istream & s = cin,
00275                           hbpfp the_hbpfp = new_hydrobase,
00276                           sbpfp the_sbpfp = new_starbase)
00277     {return  (sdyn3 *) get_node(s, new_sdyn3, the_hbpfp, the_sbpfp);}
00278     
00279 #define  put_sdyn3  put_node
00280 
00281 typedef  void (*sdyn3_print_fp)(sdyn3ptr);      // to extract information
00282                                                 // from the integrator
00283 
00284 // Useful functions:
00285 
00286 void set_kepler_from_sdyn3(kepler&, sdyn3*, sdyn3*);
00287 void kepler_pair_to_triple(kepler&, kepler&, sdyn3*, sdyn3*, sdyn3*);
00288 
00289 int system_in_cube(sdyn3*, real);
00290 
00291 // Standard integrators for scattering problems:
00292 
00293 bool  tree3_evolve(sdyn3*, real, real, real, real, real,
00294                    real cpu_time_check = 3600,
00295                    real dt = VERY_LARGE_NUMBER,
00296                    sdyn3_print_fp p = NULL,
00297                    int snap_limit = -1);
00298 bool  low_n3_evolve(sdyn3*, real, real, real, real, real, real,
00299                     int, char *, int, int, real,
00300                     real cpu_time_check = 3600,
00301                     real dt = VERY_LARGE_NUMBER,
00302                     sdyn3_print_fp p = NULL,
00303                     int snap_limit = -1);
00304 
00305 real energy(sdyn3 * b);
00306 real potential_energy(sdyn3 * b);
00307 real total_angular_momentum(sdyn3 * b);
00308 
00309 #endif
00310 
00311 //=======================================================================//
00312 //  +---------------+        _\|/_        +------------------------------\\ ~
00313 //  |  the end of:  |         /|\         |  inc/sdyn3.h
00314 //  +---------------+                     +------------------------------//
00315 //========================= STARLAB =====================================\\ ~
00316 

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