00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "hdyn.h"
00021
00022
00023
00024
00025
00026
00027 void calculate_acc_and_jerk_for_list(hdyn *b,
00028 hdyn **next_nodes,
00029 int n_next,
00030 xreal time,
00031 bool exact,
00032 bool tree_changed,
00033 bool &reset_force_correction,
00034
00035 bool &restart_grape)
00036 {
00037
00038
00039
00040
00041
00042
00043 bool ignore_internal = next_nodes[0]->get_ignore_internal();
00044
00045 #ifdef TIME_INTERNAL
00046
00047
00048
00049 real cpu0, cpu1, cpu2, cpu3, cpu4;
00050 int kmax = 1;
00051
00052 for (int k = 0; k < n_next; k++) {
00053 hdyn* bi = next_nodes[k];
00054
00055 if (bi->name_is("13a")
00056 && bi->get_kepler() == NULL
00057 && bi->get_time() > 6.6
00058 && bi->find_perturber_node()
00059 && bi->find_perturber_node()->get_n_perturbers() > 0
00060 ) {
00061
00062
00063
00064 for (int kk = 0; kk < n_next; kk++)
00065 if (kk != k)
00066 next_nodes[kk]->set_timestep(VERY_LARGE_NUMBER);
00067 n_next = 1;
00068 next_nodes[0] = bi;
00069
00070 int p = cerr.precision(HIGH_PRECISION);
00071 cerr << endl << "timing " << bi->format_label()
00072 << " at time " << bi->get_system_time() << endl;
00073 if (bi->is_low_level_node()) {
00074 PRL(bi->get_top_level_node()->format_label());
00075 if (bi->find_perturber_node()) {
00076 PRL(bi->find_perturber_node()->format_label());
00077 PRL(bi->find_perturber_node()->get_n_perturbers());
00078 }
00079 }
00080 cerr.precision(p);
00081
00082 kmax = 25000;
00083 cpu0 = cpu_time();
00084 }
00085 }
00086 }
00087
00088 for (int k = 0; k < kmax; k++) {
00089
00090 #endif
00091
00092 xreal sys_t = next_nodes[0]->get_system_time();
00093
00094 for (int i = 0; i < n_next; i++) {
00095
00096 hdyn *bi = next_nodes[i];
00097
00098
00099
00100 predict_loworder_all(bi->get_top_level_node(), sys_t);
00101
00102 if (bi->is_top_level_node()) {
00103 bi->clear_interaction();
00104 bi->top_level_node_prologue_for_force_calculation(exact);
00105 }
00106 }
00107
00108 #ifdef TIME_INTERNAL
00109 }
00110 if (kmax > 1) cpu1 = cpu_time();
00111 #endif
00112
00113 if (tree_changed)
00114 restart_grape = true;
00115
00116 #ifdef TIME_INTERNAL
00117 for (int k = 0; k < kmax; k++) {
00118 #endif
00119
00120 if (!exact) {
00121
00122 if (!ignore_internal)
00123 kira_calculate_top_level_acc_and_jerk(next_nodes, n_next,
00124 time, restart_grape);
00125
00126
00127
00128
00129 int n = get_n_top_level();
00130
00131 for (int i = 0; i < n_next; i++) {
00132 hdyn *bi = next_nodes[i];
00133
00134 if (ignore_internal) {
00135 bi->set_nn(bi);
00136 bi->set_coll(bi);
00137 bi->set_d_nn_sq(VERY_LARGE_NUMBER);
00138 }
00139
00140 if (bi->is_top_level_node()) {
00141
00142 bi->inc_direct_force(n-1);
00143
00144 bi->top_level_node_epilogue_force_calculation();
00145 }
00146 }
00147 }
00148
00149 #ifdef TIME_INTERNAL
00150 }
00151 if (kmax > 1) cpu2 = cpu_time();
00152 #endif
00153
00154 kira_diag *kd = next_nodes[0]->get_kira_diag();
00155
00156 #ifdef TIME_INTERNAL
00157 for (int k = 0; k < kmax; k++) {
00158 #endif
00159
00160 for (int i = 0; i < n_next; i++) {
00161 hdyn *bi = next_nodes[i];
00162
00163
00164
00165 if (bi->is_low_level_node() && bi->get_kepler() == NULL) {
00166
00167 if (kd->kira_ev) {
00168 cerr << "\nComputing force on low-level node "
00169 << bi->format_label() << endl;
00170 }
00171
00172 bi->clear_interaction();
00173 bi->calculate_acc_and_jerk(exact);
00174
00175 if (kd->kira_ev) {
00176 PRL(bi->get_acc());
00177 PRL(bi->get_binary_sister()->get_acc());
00178 PRL(bi->get_pos());
00179 PRL(bi->get_binary_sister()->get_pos());
00180 }
00181 }
00182
00183
00184
00185
00186
00187 #ifdef TIME_INTERNAL
00188 if (k == 0)
00189 #endif
00190
00191 bi->inc_steps();
00192 }
00193
00194 #ifdef TIME_INTERNAL
00195 }
00196 if (kmax > 1) cpu3 = cpu_time();
00197 #endif
00198
00199
00200
00201
00202 kira_options *ko = next_nodes[0]->get_kira_options();
00203
00204 #ifdef TIME_INTERNAL
00205 for (int k = 0; k < kmax; k++) {
00206 #endif
00207
00208 if (!exact) {
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 for (int i = 0; i < n_next; i++)
00223 next_nodes[i]->set_on_integration_list();
00224
00225 if (ko->use_old_correct_acc_and_jerk || !ko->use_perturbed_list)
00226
00227 correct_acc_and_jerk(b,
00228 reset_force_correction);
00229 else
00230
00231 correct_acc_and_jerk(next_nodes, n_next);
00232
00233
00234
00235 for (int i = 0; i < n_next; i++) {
00236 hdyn *n = next_nodes[i];
00237 if (n && n->is_valid())
00238 n->clear_on_integration_list();
00239 }
00240
00241 }
00242
00243 #ifdef TIME_INTERNAL
00244 }
00245 if (kmax > 1) cpu4 = cpu_time();
00246
00247 for (int k = 0; k < kmax; k++) {
00248 #endif
00249
00250 if (b->get_external_field() > 0) {
00251
00252
00253
00254 for (int i = 0; i < n_next; i++)
00255 if (next_nodes[i]->is_top_level_node()) {
00256 hdyn *bb = next_nodes[i];
00257 real pot;
00258 vector acc, jerk;
00259 get_external_acc(bb, bb->get_pred_pos(), bb->get_pred_vel(),
00260 pot, acc, jerk);
00261 bb->inc_pot(pot);
00262 bb->inc_acc(acc);
00263 bb->inc_jerk(jerk);
00264 }
00265 }
00266
00267 #ifdef TIME_INTERNAL
00268 }
00269 if (kmax > 1) {
00270 cerr << "CPU times: "
00271 << (cpu1-cpu0)/kmax << " "
00272 << (cpu2-cpu1)/kmax << " "
00273 << (cpu3-cpu2)/kmax << " "
00274 << (cpu4-cpu3)/kmax << " "
00275 << (cpu_time()-cpu4)/kmax << endl;
00276 exit(0);
00277 }
00278 #endif
00279 }
00280
00281 void calculate_acc_and_jerk_on_all_top_level_nodes(hdyn * b)
00282 {
00283 int n_top = b->n_daughters();
00284 hdynptr * list = new hdynptr[n_top];
00285
00286 int i_top = 0;
00287 for_all_daughters(hdyn, b, bb)
00288 list[i_top++] = bb;
00289
00290 bool reset_force_correction = true;
00291 bool restart_grape = true;
00292
00293 calculate_acc_and_jerk_for_list(b, list, n_top,
00294 b->get_system_time(),
00295 false,
00296 false,
00297 reset_force_correction,
00298 restart_grape);
00299
00300 delete [] list;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 static int work_size = 0;
00312 static hdyn ** nodes = NULL;
00313 static int nnodes = -1;
00314
00315
00316
00317 void clean_up_kira_ev() {if (nodes) delete [] nodes;}
00318
00319 void initialize_system_phase2(hdyn * b,
00320 int call_id,
00321 bool set_dt)
00322 {
00323
00324
00325 dbg_message("initialize_system_phase2", b);
00326
00327 if (!b->is_root()) {
00328 err_exit("initialize_system_phase2 called with non-root");
00329 }
00330
00331 int n = 0;
00332 for_all_nodes(hdyn, b, b1) n++ ;
00333
00334 if (work_size < n) {
00335 if (!nodes) delete [] nodes;
00336 work_size = n + 10;
00337 nodes = new hdynptr[work_size];
00338 }
00339
00340
00341
00342 for_all_nodes(hdyn, b, b2) {
00343 if (!b2->get_kepler() && (b2->get_unperturbed_timestep() > 0)) {
00344
00345
00346
00347 int p = cerr.precision(HIGH_PRECISION);
00348 cerr << endl
00349 << "initialize_system_phase2: "
00350 << "creating kepler for unperturbed binary"
00351 << endl
00352 << " " << b2->get_parent()->format_label()
00353 << " at system time " << b->get_system_time()
00354 << " call_id = " << call_id
00355 << endl;
00356 cerr.precision(p);
00357
00358 b2->update_kepler_from_hdyn();
00359
00360 }
00361 }
00362
00363
00364
00365 n = 0;
00366 for_all_nodes(hdyn, b, b3) {
00367 if ((b3 != b) && (!b3->get_kepler())) {
00368 nodes[n] = b3;
00369 n++ ;
00370 }
00371 }
00372
00373 xreal time = nodes[0]->get_system_time();
00374
00375 bool tree_changed = true;
00376 bool reset_force_correction = true;
00377 bool restart_grape = true;
00378 bool exact = false;
00379
00380 calculate_acc_and_jerk_for_list(b, nodes, n, time,
00381 exact,
00382 tree_changed,
00383 reset_force_correction,
00384 restart_grape);
00385
00386
00387
00388 real min_dt = VERY_LARGE_NUMBER;
00389
00390 for_all_nodes(hdyn, b, b4) {
00391 if ((b4 != b) && (!b4->get_kepler())) {
00392 b4->store_old_force();
00393 if (set_dt || (b4->get_time() <= 0 || b4->get_timestep() <= 0) ) {
00394 b4->set_first_timestep();
00395
00396 if (b4->get_time() + b4->get_timestep()
00397 < b->get_system_time()) {
00398
00399
00400
00401
00402
00403
00404 cerr << endl << "warning: initialize_system_phase2: "
00405 << "time will go backwards!" << endl;
00406 cerr << "function should not be called with "
00407 << "unsynchronized system." << endl << endl;
00408 pp3(b4);
00409
00410
00411
00412
00413
00414
00415
00416 }
00417
00418 }
00419
00420 min_dt = min(min_dt, b4->get_timestep());
00421 }
00422 }
00423
00424
00425
00426 if (set_dt && b->get_system_time() <= 0) {
00427 for_all_nodes(hdyn, b, b5) {
00428 if ((b5 != b) && (!b5->get_kepler())) {
00429 if (b5->is_parent()
00430 && b5->get_oldest_daughter()
00431 ->get_perturbation_squared() > 1)
00432 b5->set_timestep(min_dt);
00433 }
00434 }
00435 }
00436
00437
00438 }