00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013
00014
00015
00016
00017
00018
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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 real radius;
00055 vec pred_pos;
00056 vec pred_vel;
00057 xreal t_pred;
00058
00059 slow_binary * slow;
00060
00061
00062
00063
00064
00066
00067
00068 slow_perturbed * sp;
00069
00070
00071
00072
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
00090
00091
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;
00104 sp = NULL;
00105 }
00106
00107 }
00108
00110
00111 void set_timestep(real dt) {
00112 timestep = dt;
00113 if (slow) slow->set_dtau(dt/slow->get_kappa());
00114 }
00115
00116 inline void set_time(xreal t) {
00117 time = t;
00118 if (slow) slow->set_tau(slow->time_to_tau(time));
00119 }
00120
00121
00122
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
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
00243
00244
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();
00253 }
00254
00255 inline void predict_loworder(xreal t) {
00256
00257 if (kep) {
00258
00259 init_pred();
00260
00261 } else {
00262
00263 if (t_pred < t) {
00264
00265 real dt;
00266
00267
00268
00269
00270 if (slow)
00271 dt = slow->time_to_tau(t) - slow->get_tau();
00272 else
00273 dt = t - get_time();
00274
00275
00276
00277
00278
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) {
00295
00296
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
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
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
00348
00349 inline xreal get_next_time() const {return get_time()
00350 + (xreal)timestep;}
00351
00352
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
00362
00363 void predict_loworder_all(_dyn_* b, xreal t);
00364
00365
00366
00367 bool is_valid_slow(_dyn_ *pert_node);
00368
00369 typedef _dyn_ * _dyn_ptr;
00370
00371
00372
00373
00374
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);}
00379
00380
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
00394
00395