00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "_dyn_.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028 void _dyn_::flat_accumulate_acc_and_jerk(_dyn_ * leaf,
00029 real eps2)
00030 {
00031 vector d_pos = leaf->get_pred_pos() - get_pred_pos();
00032 vector d_vel = leaf->get_pred_vel() - get_pred_vel();
00033 real r2inv = 1.0 / (d_pos * d_pos + eps2);
00034 real a3 = -3.0 * (d_pos * d_vel) * r2inv;
00035 real mrinv = leaf->get_mass() * sqrt(r2inv);
00036 pot -= mrinv;
00037 real mr3inv = mrinv * r2inv;
00038 acc += mr3inv * d_pos;
00039 jerk += mr3inv * (d_vel + a3 * d_pos);
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #ifdef RECURSIVE_LOOP
00052
00053 void _dyn_::flat_calculate_acc_and_jerk(_dyn_ * p,
00054 real eps2)
00055 {
00056 if (p->is_root()) {
00057
00058 for_all_daughters(_dyn_, p, d)
00059 flat_calculate_acc_and_jerk(d, eps2);
00060
00061 } else {
00062
00063 if (p != this)
00064 flat_accumulate_acc_and_jerk(p, eps2);
00065
00066 }
00067 }
00068
00069 #else
00070
00071
00072
00073
00074
00075 void _dyn_::flat_calculate_acc_and_jerk(_dyn_ * p,
00076 real eps2)
00077 {
00078 if (p->is_root()) {
00079
00080 for_all_daughters(_dyn_, p, d)
00081 if (d != this)
00082 flat_accumulate_acc_and_jerk(d, eps2);
00083
00084 } else {
00085
00086 if (p != this)
00087 flat_accumulate_acc_and_jerk(p, eps2);
00088
00089 }
00090 }
00091
00092 #endif
00093
00094 #define SAFETY_FACTOR 16
00095
00096 void _dyn_::flat_set_first_timestep(real eta_for_firststep,
00097 real max_step_size)
00098 {
00099
00100
00101
00102 real a1scaled2 = jerk * jerk;
00103 real a2 = acc * acc;
00104 real newstep;
00105
00106 if (a1scaled2 > 0.0)
00107 newstep = eta_for_firststep * sqrt(a2 / a1scaled2);
00108 else
00109 newstep = eta_for_firststep / SAFETY_FACTOR;
00110
00111 newstep = adjust_number_to_power(newstep, max_step_size);
00112 timestep = newstep;
00113 }
00114
00115 local real flat_new_timestep(vector & at3,
00116 vector & bt2,
00117 vector & jerk,
00118 vector & acc,
00119 real timestep,
00120 real time,
00121 real eta,
00122 real dtmax)
00123 {
00124 real a3scaled2 = 36 * at3 * at3;
00125 real a2scaled2 = 4 * bt2 * bt2;
00126 real a1scaled2 = timestep * jerk * jerk;
00127 real a2 = acc * acc;
00128
00129
00130
00131 real newstep = eta * sqrt(sqrt(a2 / a2scaled2)) * timestep;
00132
00133
00134
00135
00136
00137
00138
00139 if (newstep < timestep)
00140 return timestep * 0.5;
00141 else if (newstep < 2 * timestep)
00142 return timestep;
00143 else if (fmod(time, 2 * timestep) != 0.0 || 2 * timestep > dtmax)
00144 return timestep;
00145 else
00146 return timestep * 2;
00147 }
00148
00149 void _dyn_::flat_update(const real eta, const real dtmax)
00150 {
00151 vector at3 = 2 * (old_acc - acc) + timestep * (old_jerk + jerk);
00152 vector bt2 = -3 * (old_acc - acc) - timestep * (2 * old_jerk + jerk);
00153 time = time + timestep;
00154 timestep = flat_new_timestep(at3, bt2, jerk, acc,
00155 timestep, time, eta, dtmax);
00156 }
00157
00158
00159
00160
00161
00162
00163 #define ONE12 0.0833333333333333333333
00164 #define ONE3 0.3333333333333333333333
00165
00166 bool _dyn_::flat_correct()
00167 {
00168 vector at3 = 2 * (old_acc - acc) + timestep * (old_jerk + jerk);
00169 vector bt2 = -3 * (old_acc - acc) - timestep * (2 * old_jerk + jerk);
00170 real dt2 = timestep * timestep;
00171
00172
00173
00174
00175 vector new_pos = pred_pos + (0.05 * at3 + ONE12 * bt2) * dt2;
00176 vector new_vel = pred_vel + (0.25 * at3 + ONE3 * bt2) * timestep;
00177
00178 pos = new_pos;
00179 vel = new_vel;
00180
00181 return true;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 void predict_loworder_all(_dyn_ * b,
00191 xreal t)
00192 {
00193 if (!b) return;
00194
00195
00196
00197 if (b->is_parent())
00198 for_all_daughters(_dyn_, b, d)
00199 predict_loworder_all(d, t);
00200
00201 if (b->is_top_level_node()) {
00202
00203 #ifdef FIFTH_ORDER_PRED
00204 real dt = b->get_timestep();
00205 vector kdt = 18*dt*b->get_k_over_18();
00206 PRL(b->get_jerk());
00207 PRC(dt); PRL(kdt);
00208 b->predict_loworder5(t);
00209
00210 #else
00211 b->predict_loworder(t);
00212 #endif
00213
00214 } else {
00215
00216
00217
00218
00219 _dyn_ *s = b->get_elder_sister();
00220 if (s && s->get_t_pred() == t)
00221
00222
00223
00224
00225 b->predict_from_elder_sister();
00226
00227 else
00228
00229
00230
00231
00232 b->predict_loworder(t);
00233
00234 }
00235 }
00236
00237
00238
00239
00240