00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 bool kira_use_grape()
00047 {
00048 #if defined(USE_GRAPE)
00049 return true;
00050 #else
00051 return false;
00052 #endif
00053 }
00054
00055 void kira_calculate_internal_energies(hdyn* b,
00056 real& epot, real& ekin, real& etot,
00057 bool cm,
00058 bool use_grape)
00059 {
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #if defined(USE_GRAPE)
00083
00084 if (use_grape)
00085
00086 grape_calculate_energies(b, epot, ekin, etot, cm);
00087
00088 else
00089
00090 calculate_energies(b, b->get_eps2(), epot, ekin, etot, cm);
00091
00092 #else
00093
00094 calculate_energies(b, b->get_eps2(), epot, ekin, etot, cm);
00095
00096 #endif
00097
00098 }
00099
00100 void kira_calculate_energies(dyn* b, real eps2,
00101 real &potential, real &kinetic, real &total,
00102 bool cm)
00103 {
00104
00105
00106
00107
00108
00109
00110
00111
00112 kira_calculate_internal_energies((hdyn*)b, potential, kinetic, total, cm);
00113 }
00114
00115 void kira_top_level_energies(dyn *b, real eps2,
00116 real& potential_energy,
00117 real& kinetic_energy)
00118 {
00119
00120
00121
00122
00123
00124 real energy;
00125 kira_calculate_energies(b, eps2,
00126 potential_energy, kinetic_energy, energy,
00127 true);
00128 }
00129
00130 void kira_calculate_top_level_acc_and_jerk(hdyn ** next_nodes,
00131 int n_next,
00132 xreal time,
00133 bool & restart_grape)
00134 {
00135
00136
00137
00138
00139 #if defined(USE_GRAPE)
00140
00141 grape_calculate_acc_and_jerk(next_nodes, n_next,
00142 time, restart_grape);
00143 restart_grape = false;
00144
00145 #else
00146
00147 for (int i = 0; i < n_next; i++) {
00148 hdyn *bi = next_nodes[i];
00149 if (bi->is_top_level_node())
00150 bi->top_level_node_real_force_calculation();
00151 }
00152
00153 #endif
00154 }
00155
00156 void kira_compute_densities(hdyn* b, vector& cod_pos, vector& cod_vel)
00157 {
00158
00159
00160
00161 #if defined(USE_GRAPE)
00162
00163 cerr << "Computing densities using GRAPE..." << endl;
00164 real cpu0 = cpu_time();
00165
00166
00167
00168
00169
00170
00171 grape_calculate_densities(b, 0.1);
00172
00173 real cpu1 = cpu_time();
00174 compute_mean_cod(b, cod_pos, cod_vel);
00175 real cpu2 = cpu_time();
00176
00177 cerr << "CPU times: density " << cpu1 - cpu0
00178 << " cod " << cpu2 - cpu1
00179 << endl;
00180
00181 #else
00182
00183
00184
00185 cerr << "Skipping density calculation..." << endl;
00186
00187 #endif
00188
00189 }
00190
00191 void kira_synchronize_tree(hdyn *b)
00192 {
00193
00194
00195
00196
00197
00198
00199 #if defined(USE_GRAPE)
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 xreal sys_t = b->get_system_time();
00210
00211 cerr << endl
00212 << "synchronizing tree using GRAPE at time " << sys_t
00213 << endl << flush;
00214
00215 int n_next = 0;
00216 for_all_daughters(hdyn, b, bi)
00217 if (bi->get_time() < sys_t) n_next++;
00218
00219 hdyn **next_nodes = new hdynptr[n_next];
00220 n_next = 0;
00221 for_all_daughters(hdyn, b, bi)
00222 if (bi->get_time() < sys_t) next_nodes[n_next++] = bi;
00223
00224
00225
00226
00227 for (int i = 0; i < n_next; i++) {
00228 hdyn *bi = next_nodes[i];
00229 predict_loworder_all(bi, sys_t);
00230 bi->clear_interaction();
00231 bi->top_level_node_prologue_for_force_calculation(false);
00232 }
00233
00234 bool restart_grape = false;
00235 grape_calculate_acc_and_jerk(next_nodes, n_next, sys_t, restart_grape);
00236
00237 int ntop = get_n_top_level();
00238 for (int i = 0; i < n_next; i++) {
00239 hdyn *bi = next_nodes[i];
00240 bi->inc_direct_force(ntop-1);
00241 bi->top_level_node_epilogue_force_calculation();
00242 bi->inc_steps();
00243 }
00244
00245
00246
00247
00248 kira_options *ko = b->get_kira_options();
00249
00250 for (int i = 0; i < n_next; i++)
00251 next_nodes[i]->set_on_integration_list();
00252
00253 if (ko->use_old_correct_acc_and_jerk || !ko->use_perturbed_list) {
00254 bool reset = false;
00255 correct_acc_and_jerk(b, reset);
00256 } else
00257 correct_acc_and_jerk(next_nodes, n_next);
00258
00259 for (int i = 0; i < n_next; i++)
00260 next_nodes[i]->clear_on_integration_list();
00261
00262 if (b->get_external_field() > 0) {
00263
00264
00265
00266 for (int i = 0; i < n_next; i++) {
00267 hdyn *bi = next_nodes[i];
00268 real pot;
00269 vector acc, jerk;
00270 get_external_acc(bi, bi->get_pred_pos(), bi->get_pred_vel(),
00271 pot, acc, jerk);
00272 bi->inc_pot(pot);
00273 bi->inc_acc(acc);
00274 bi->inc_jerk(jerk);
00275 }
00276 }
00277
00278
00279
00280 for (int i = 0; i < n_next; i++) {
00281 hdyn *bi = next_nodes[i];
00282 bi->correct_and_update();
00283 bi->init_pred();
00284 bi->store_old_force();
00285 }
00286
00287 delete [] next_nodes;
00288
00289 cerr << endl
00290 << "end of synchronization"
00291 << endl << flush;
00292
00293 #else
00294
00295 cerr << endl
00296 << "synchronizing tree without GRAPE at time " << b->get_system_time()
00297 << endl;
00298
00299 synchronize_tree(b);
00300
00301 #endif
00302 }