00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "scatter.h"
00021
00022 #include "sigma.h"
00023
00024 #ifndef TOOLBOX
00025
00026
00027 ostream& operator<<(ostream& s, scatter_input& i) {
00028
00029 s << "Scatter_input: " << endl;
00030 s << "Input string: " << i.init_string << endl;
00031 s << " i.dt = " << i.delta_t << " " << i.dt_out << " " << i.dt_snap << endl;
00032 s << " eta= " << i.eta << endl;
00033 s << " tol= " << i.tidal_tol_factor << endl;
00034 s << " Cs= " << i.snap_cube_size << " dt cpu= " << i.cpu_time_check << endl;
00035 s << " e_exp= " << i.n_experiments << endl;
00036 s << " rnd= " << i.seed << " "<< i.n_rand <<" "<< i.pipe << " "<< i.debug;
00037
00038 return s;
00039
00040 }
00041
00042 void ppn(sdyn* b, ostream & s, int level) {
00043
00044 s.precision(3);
00045
00046 for (int i = 0; i < 2*level; i++) s << " ";
00047
00048 if(b != b->get_root()) {
00049 b->pretty_print_node(s);
00050 cerr << endl;
00051 s << " "<< b->get_mass() << " "
00052 << b->get_pos() << " (r= " << abs(b->get_pos()) << ") "
00053 << b->get_vel() << " (v= " << abs(b->get_vel()) << ")" << endl;
00054
00055
00056 }
00057
00058 for (sdyn * daughter = b->get_oldest_daughter();
00059 daughter != NULL;
00060 daughter = daughter->get_younger_sister())
00061 ppn(daughter, s, level + 1);
00062 }
00063
00064
00065 #define DT_CHECK 20
00066
00067
00068
00069
00070
00071 void scatter(sdyn* b, scatter_input input,
00072 scatter_exp &experiment) {
00073
00074 real eta = input.eta;
00075 real delta_t = input.delta_t;
00076 real dt_out = input.dt_out;
00077 real cpu_time_check = input.cpu_time_check;
00078 real dt_snap = input.dt_snap;
00079 real ttf = input.tidal_tol_factor;
00080 real snap_cube_size = input.snap_cube_size;
00081 int debug = input.debug;
00082
00083 experiment.init_scatter_exp(b);
00084
00085 real de_merge = 0;
00086 int stop_at_cpu = 0;
00087 real cpu_save = cpu_time();
00088 bool terminate = false;
00089
00090 real t_out = b->get_time_offset();
00091 real t_end = delta_t + b->get_time_offset();
00092 PRC(t_out);PRL(t_end);
00093
00094 char previous_form[255];
00095 char current_form[255];
00096 strcpy(current_form, get_normal_form(b));
00097
00098 real kin=0, pot=0;
00099 b->flatten_node();
00100 real etot_init = calculate_energy_from_scratch(b, kin, pot);
00101 make_tree(b, DYNAMICS, STABILITY, K_MAX, debug);
00102
00103 for (real t = 0; t <= delta_t; t += DT_CHECK) {
00104 PRC(t);
00105 terminate = tree_evolve(b, DT_CHECK, dt_out, dt_snap,
00106 snap_cube_size,
00107 eta, cpu_time_check);
00108
00109 calculate_energy(b, kin, pot);
00110 if (debug) {
00111 cerr.precision(6), cerr << "\nStatus at time " << b->get_time();
00112 cerr.precision(9), cerr << " (energy = " << kin + pot << "):\n";
00113 cerr.precision(6);
00114 }
00115
00116
00117
00118
00119 if (cpu_time_check < 0
00120 && cpu_time() - cpu_save > abs(cpu_time_check)) return;
00121
00122 if(b->get_time()>=t_out) {
00123 cerr<< " terminate on t_out" << b->get_teim()<<endl;
00124 real ekin, epot;
00125 calculate_energy(b, ekin, epot);
00126 if(input.verbose==1) {
00127
00128 cerr << "Time = " << b->get_time()
00129 << " Etot = " << ekin + epot
00130 << " Tinf = " << ekin/epot << endl;
00131 }
00132 t_out += dt_out;
00133 }
00134
00135 if(b->get_time()>=t_end) {
00136 cerr << "Early termination"<<endl;
00137 experiment.set_scatter_discriptor(stopped);
00138 experiment.set_stop(true);
00139 real ekin, epot;
00140 calculate_energy(b, ekin, epot);
00141 cerr << "Time = " << b->get_time()
00142 << " Etot = " << ekin + epot << endl;
00143 break;
00144 }
00145
00146 int coll_flag = 2;
00147 de_merge += merge_collisions(b, coll_flag);
00148
00149 make_tree(b, DYNAMICS, STABILITY, K_MAX, false);
00150
00151 int unbound = extend_or_end_scatter(b, ttf, false);
00152 if(unbound==2) {
00153 experiment.set_final_bound(true);
00154 unbound = 1;
00155 }
00156
00157
00158 if (unbound || terminate) break;
00159
00160
00161
00162 strcpy(previous_form, current_form);
00163 strcpy(current_form, get_normal_form(b));
00164 if(strcmp(previous_form, current_form))
00165 experiment.inc_form_changes();
00166
00167
00168 }
00169
00170 b->flatten_node();
00171 real etot_error = calculate_energy_from_scratch(b, kin, pot)
00172 - etot_init - de_merge;
00173 experiment.set_energy_error(etot_error);
00174
00175 make_tree(b, DYNAMICS, STABILITY, K_MAX, debug);
00176
00177
00178 experiment.final_scatter_exp(b);
00179
00180 }
00181
00182
00183 #else
00184
00185 void slave_part_of_experiment(scatter_input input,
00186 scatter_exp &experiment) {
00187
00188 cerr << "Random seed = " << get_initial_seed()
00189 << " n_rand = " << get_n_rand() << flush << "\n";
00190
00191 sdyn *b = mkscat(input.init_string);
00192
00193
00194 b->flatten_node();
00195
00196 real kin, pot;
00197 real etot_init = calculate_energy_from_scratch(b, kin, pot);
00198 if(input.verbose==1) {
00199 cerr << "Time = " << 0 << " Etot = " << kin + pot
00200 << " (" << kin << ", " << pot
00201 << ") Tinf = " << kin/pot << endl;
00202 }
00203 make_tree(b, !DYNAMICS, STABILITY, K_MAX, input.debug);
00204
00205
00206
00207 cerr << "*** Initial configuration (random seed = "
00208 << get_initial_seed() << "):\n";
00209 print_normal_form(b, cerr);
00210 b->set_name("root");
00211
00212
00213 vector center = b->get_pos();
00214 print_structure_recursive(b, 0., center, true, true, 4);
00215
00216
00217
00218 scatter(b, input, experiment);
00219
00220
00221 cerr.precision(6);
00222 if (input.debug) cerr << endl;
00223
00224 cerr << "*** Final system configuration (time = "
00225 << b->get_time() << "):\n";
00226 print_normal_form(b, cerr);
00227 b->set_name("root");
00228 ppn(b, cerr);
00229
00230 print_structure_recursive(b, 0., center, true, true, 4);
00231
00232 cerr << "Energy error = " << experiment.get_energy_error() << endl;
00233
00234 cerr << "Final Normal form: ";
00235 print_normal_form(b, cerr);
00236 cerr << "\n\n";
00237
00238 }
00239
00240
00241 void master_part_of_experiment(scatter_input input,
00242 scatter_exp &experiment) {
00243
00244 int random_seed = srandinter(input.seed, input.n_rand);
00245
00246
00247 sdyn *b = mkscat(input.init_string);
00248 scatter_hist *hi = initialize_scatter_hist(b);
00249 delete b;
00250 b = NULL;
00251
00252 int n_exp = 0;
00253 real de = 0;
00254 for (n_exp = 0; n_exp < input.n_experiments; n_exp++) {
00255
00256
00257 if (input.n_experiments > 1) cerr << "Experiment #" << n_exp+1
00258 << ": " << "\n";
00259
00260 slave_part_of_experiment(input, experiment);
00261
00262 hi->add_scatter_hist(experiment, 0);
00263 cerr << "scatter history" << flush << endl;
00264 hi->put_scatter_hist(cerr, false);
00265 cerr << " N done = " << n_exp+1 << endl;
00266 }
00267
00268 }
00269
00270 void execute_scatter_experiment(scatter_input input) {
00271
00272
00273 scatter_exp experiment;
00274
00275 int myid = 0;
00276 int master = 0;
00277
00278 if(myid==master) {
00279 master_part_of_experiment(input, experiment);
00280 }
00281 else {
00282 slave_part_of_experiment(input, experiment);
00283 }
00284
00285 }
00286
00287 main(int argc, char **argv)
00288 {
00289
00290 scatter_input input;
00291
00292
00293
00294
00295 char* default_init
00296 = "-M 1 -rm 3 -v 1 -t -r1 0 -r2 0 -q 1 -p -a 1 -q 1 -r1 0 -r2 0";
00297
00298 strcpy(&input.init_string[0], default_init);
00299
00300 bool D_flag = false;
00301 check_help();
00302
00303 extern char *poptarg;
00304 int c;
00305 char* param_string = "A:c:C:d:D:g:i:n:N:ps:t:v";
00306
00307 while ((c = pgetopt(argc, argv, param_string)) != -1)
00308 switch(c) {
00309
00310 case 'A': input.eta = atof(poptarg);
00311 break;
00312 case 'c': input.cpu_time_check = atof(poptarg);
00313 break;
00314 case 'C': input.snap_cube_size = atof(poptarg);
00315 break;
00316 case 'd': input.dt_out = atof(poptarg);
00317 break;
00318 case 'D': D_flag = TRUE;
00319 input.dt_snap = atof(poptarg);
00320 break;
00321 case 'g': input.tidal_tol_factor = atof(poptarg);
00322 break;
00323 case 'i': strcpy(&input.init_string[0], poptarg);
00324 break;
00325 case 'n': input.n_experiments = atoi(poptarg);
00326 break;
00327 case 'N': input.n_rand = atoi(poptarg);
00328 break;
00329 case 'p': input.pipe = 1 - input.pipe;
00330 break;
00331 case 't': input.delta_t = atof(poptarg);
00332 break;
00333 case 'v': input.debug = 1 - input.debug;
00334 break;
00335 case 's': input.seed = atoi(poptarg);
00336 break;
00337 case '?': params_to_usage(cerr, argv[0], param_string);
00338 get_help();
00339 }
00340
00341 cerr << input << endl;
00342
00343 if (!D_flag) input.dt_snap = input.delta_t;
00344
00345 execute_scatter_experiment(input);
00346
00347
00348
00349
00350 }
00351 #endif
00352
00353
00354
00355
00356
00357
00358
00359