Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

scatter_MPI.C

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #ifdef USE_MPI
00021 #include "mpi++.h"
00022 #else
00023 #include "localmpi++.h"
00024 #endif
00025 //#include "sdyn.h"
00026 #include "scatter.h"
00027 #include "sigma.h"
00028 
00029 
00030 
00031 
00032 #ifndef TOOLBOX
00033 
00034 
00035 ostream& operator<<(ostream& s, scatter_input& i) {
00036  
00037   s << "Scatter_input: " << endl;
00038   s << "Input string: " << i.init_string << endl;
00039   s << " i.dt = " << i.delta_t << " " << i.dt_out << " " << i.dt_snap << endl;
00040   s << " eta= " << i.eta << endl;
00041   s << " tol= " << i.tidal_tol_factor  << endl;
00042   s << " Cs= " << i.snap_cube_size << " dt cpu= " << i.cpu_time_check << endl;
00043   s << " e_exp= " << i.n_experiments << endl;
00044   s << " rnd= " << i.seed << " "<< i.n_rand <<" "<<i.n_rand_inc<<" "
00045     << i.pipe  << " "<< i.debug;
00046 
00047   return s;
00048 
00049 }
00050 
00051 void ppn(sdyn* b, ostream & s, int level) {
00052 
00053   s.precision(3);
00054 
00055   for (int i = 0; i < 2*level; i++) s << " ";
00056 
00057   if(b != b->get_root()) {
00058     b->pretty_print_node(s);
00059     cerr << endl;
00060     s << "   "<< b->get_mass() << "  "
00061       << b->get_pos() << " (r= " << abs(b->get_pos()) << ")  " 
00062       << b->get_vel() << " (v= " << abs(b->get_vel()) << ")" << endl;
00063     //  << "r= " << abs(b->get_pos()) << "  " 
00064     //  << "v= " << abs(b->get_vel()) << endl;
00065   }
00066 
00067   for (sdyn * daughter = b->get_oldest_daughter();
00068        daughter != NULL;
00069        daughter = daughter->get_younger_sister())
00070     ppn(daughter, s, level + 1);        
00071 }
00072 
00073 
00074 #define DT_CHECK        20
00075 
00076 // scatter: Take the system with root node b and integrate it forward
00077 //          in time up to time delta_t.  Check the state of the system
00078 //          every DT_CHECK time units.
00079 
00080 void scatter(sdyn* b, scatter_input input, 
00081              scatter_exp &experiment) {
00082 
00083   scatter(b, input.eta,
00084              input.delta_t, input.dt_out, input.cpu_time_check,
00085              input.dt_snap, input.tidal_tol_factor, input.snap_cube_size,
00086              input.debug,
00087              experiment);
00088 
00089 }
00090 
00091 void scatter(sdyn* b, real eta,
00092              real delta_t, real dt_out, real cpu_time_check,
00093              real dt_snap, real ttf, real snap_cube_size,
00094              int debug,
00095              scatter_exp &experiment) {
00096 
00097   experiment.init_scatter_exp(b); 
00098 
00099   real de_merge = 0;
00100   int stop_at_cpu = 0;
00101   real cpu_save = cpu_time();
00102   bool terminate = false;
00103 
00104   real t_out = b->get_time_offset();
00105   real t_end = delta_t + (real)b->get_time_offset();
00106 
00107   char previous_form[255];
00108   char current_form[255];
00109   strcpy(current_form, get_normal_form(b));
00110 
00111   real kin=0, pot=0;
00112   b->flatten_node();
00113   real etot_init = calculate_energy_from_scratch(b, kin, pot); 
00114   make_tree(b, DYNAMICS, STABILITY, K_MAX, debug);
00115 
00116   // loop continues for ever or unit termination time is reached or
00117   // system is unbound (see extend_or_end.C)
00118   for (real t = 0; t <= VERY_LARGE_NUMBER; t += DT_CHECK) {
00119 
00120     terminate = tree_evolve(b,  DT_CHECK, dt_out, dt_snap, 
00121                             snap_cube_size, 
00122                             eta, cpu_time_check);
00123 
00124     calculate_energy(b, kin, pot);
00125     if (debug) {
00126       cerr.precision(6), cerr << "\nStatus at time " << b->get_time();
00127       cerr.precision(9), cerr << " (energy = " << kin + pot << "):\n";
00128       cerr.precision(6);
00129     }
00130 
00131     
00132     // Check to see if the scattering is over.
00133     
00134     if (cpu_time_check < 0
00135         && cpu_time() - cpu_save > abs(cpu_time_check)) {
00136       cerr <<" tcpu>tcpu_check"<<endl;
00137       return;
00138     }
00139     
00140     if(t>=dt_out) {
00141 
00142       real ekin, epot;
00143       calculate_energy(b, ekin, epot);
00144       if(debug==1) {
00145         cerr << "Time = " << b->get_time() 
00146              << "  Etot = " << ekin + epot 
00147              << "  Tinf = " << ekin/epot << endl;
00148       }
00149       put_sdyn(cout, *b);
00150       t_out += dt_out;
00151     }
00152     
00153     if(t>=t_end) {
00154       cerr << "Early termination"<<endl;
00155 
00156       experiment.set_scatter_discriptor(stopped);
00157       experiment.set_stop(true);
00158       real ekin, epot;
00159       calculate_energy(b, ekin, epot);
00160       cerr << "Time = " << b->get_time() 
00161            << "  Etot = " << ekin + epot << endl;
00162       break;
00163     }
00164     
00165     int coll_flag = 2;
00166     de_merge += merge_collisions(b, coll_flag);
00167     
00168     make_tree(b, DYNAMICS, STABILITY, K_MAX, false);
00169     
00170     int unbound = extend_or_end_scatter(b, ttf, false);
00171     if(unbound==2) {   // two body system is bound but we stop anyway
00172       experiment.set_final_bound(true);
00173       unbound = 1;   // but stop anyway
00174     }
00175     //bool unbound = tree_is_unbound(b, ttf, false);
00176     //make_tree(b, DYNAMICS, STABILITY, K_MAX, debug);
00177     if (unbound || terminate) break;
00178     
00179     //  if(experiment.get_form_changes()>1) 
00180     //    cerr << "Resonant encounter: " << get_normal_form(b) << endl;
00181     strcpy(previous_form, current_form);
00182     strcpy(current_form, get_normal_form(b));
00183     if(strcmp(previous_form, current_form))
00184       experiment.inc_form_changes();
00185     
00186     //  print_normal_form(b, cerr);
00187   }
00188   
00189   b->flatten_node();
00190   real etot_error = calculate_energy_from_scratch(b, kin, pot) 
00191     - etot_init - de_merge;
00192   experiment.set_energy_error(etot_error);
00193   //PRL(etot_error);
00194 
00195   make_tree(b, DYNAMICS, STABILITY, K_MAX, debug);
00196   
00197   // add final report
00198   experiment.final_scatter_exp(b);
00199   //PRL(experiment.get_final_form());
00200 
00201 }
00202 
00203 
00204 #else
00205 
00206 void slave_part_of_experiment(scatter_input input,
00207                               scatter_exp &experiment) {
00208 
00209   int random_seed = srandinter(input.seed, input.n_rand);
00210 
00211   cerr << "Random seed = " << get_initial_seed()
00212        << "  n_rand = " << get_n_rand() << flush << "\n";
00213     
00214   sdyn *b = mkscat(input.init_string);
00215     
00216   b->flatten_node();
00217     
00218   real kin, pot;
00219   real etot_init = calculate_energy_from_scratch(b, kin, pot);
00220   cerr << "Time = " << 0 
00221        << "  Etot = " << kin + pot 
00222        << " (" << kin << ", " << pot
00223        << ")  Tinf = " << kin/pot << endl;
00224   make_tree(b, !DYNAMICS, STABILITY, K_MAX, input.debug);
00225   
00226   // Initial output:
00227   b->set_name("root");
00228   
00229 #if 0  
00230   cerr << "*** Initial configuration (random seed = "
00231        << get_initial_seed() << "):\n";
00232   print_normal_form(b, cerr);
00233     
00234   vector center = b->get_pos();
00235   print_structure_recursive(b, 0., center, true, true, 4);
00236 #endif
00237     
00238   // Integrate the system to completion:
00239   scatter(b, input, experiment);
00240 
00241   cerr.precision(6);
00242   if (input.debug) cerr << endl;
00243 
00244 #if 0
00245   cerr << "*** Final system configuration (time = " 
00246        << b->get_time() << "):\n";
00247   print_normal_form(b, cerr);
00248 
00249   ppn(b, cerr);
00250   //    vector center = b->get_pos();
00251   print_structure_recursive(b, 0., center, true, true, 4);
00252 
00253   cerr << "Energy error = " << experiment.get_energy_error() << endl;
00254 
00255   cerr << "Final Normal form:  ";
00256   print_normal_form(b, cerr);
00257 #endif
00258 
00259   delete b;
00260 
00261 }
00262 
00263 void slave_process(int master, 
00264                    scatter_input &input, MPI_Datatype inputtype,
00265                    scatter_exp &experiment, MPI_Datatype scatter_exp_type) {
00266 
00267   int myid = MPI::COMM_WORLD.Get_rank();
00268 
00269   int length = 1;
00270 
00271   int request_for_data = 1;
00272   int data_available;
00273   int sending_data;
00274 
00275     do {
00276 
00277       request_for_data = myid;
00278       MPI::COMM_WORLD.Send(&request_for_data, length, MPI::INT, master, 
00279                            DATA_REQUEST_TAG);
00280       MPI::COMM_WORLD.Recv(&data_available, length, MPI::INT, master, 
00281                            DATA_REQUEST_TAG); 
00282 
00283       if(data_available<=0) {
00284         cerr << "Terminate slave "<< myid<<endl;
00285         return;
00286       }
00287 
00288       MPI::COMM_WORLD.Recv(&input, length, inputtype, master, 
00289                            DATA_COMING_TAG);
00290       MPI::COMM_WORLD.Recv(&experiment, length, scatter_exp_type, master, 
00291                            DATA_COMING_TAG);
00292 
00293       slave_part_of_experiment(input, experiment);
00294         
00295       cerr << "Send by slave "<<flush;
00296       PRL(experiment.get_final_form());
00297       
00298       sending_data = myid;
00299       MPI::COMM_WORLD.Send(&sending_data, length, MPI::INT, master, 
00300                            DATA_COMING_TAG);
00301       MPI::COMM_WORLD.Send(&experiment, length, scatter_exp_type, 
00302                              master, DATA_COMING_TAG);
00303     }
00304     while(true);
00305 
00306 }
00307 
00308 void master_process(scatter_input &input, MPI_Datatype inputtype,
00309                     scatter_exp &experiment, MPI_Datatype scatter_exp_type) {
00310 
00311   int myid = MPI::COMM_WORLD.Get_rank();
00312   int nproc = MPI::COMM_WORLD.Get_size();
00313 
00314   int accept_all_senders = MPI::ANY_SOURCE;
00315 
00316   // Initialize random number generator
00317   int random_seed = srandinter(input.seed, input.n_rand);
00318   input.n_rand_inc = get_n_rand() - input.n_rand; 
00319   
00320   // initialize scatter_hist
00321   sdyn *b = mkscat(input.init_string);
00322   scatter_hist *hi = initialize_scatter_hist(b);
00323   delete b;
00324   b = NULL;
00325 
00326   input.n_rand_inc = get_n_rand() - input.n_rand; 
00327 
00328   int length = 1;
00329   int nsend = 0;
00330   int i;
00331 
00332   int n_exp = 0;
00333 
00334   int slave;
00335   int request_for_data;
00336   int data_available = 1;
00337   int slave_sends_data;
00338 
00339   do {
00340 
00341     MPI::COMM_WORLD.Recv(&request_for_data, length, MPI::INT,
00342                          accept_all_senders, DATA_REQUEST_TAG);
00343     slave = request_for_data;
00344     MPI::COMM_WORLD.Send(&data_available, length, MPI::INT, slave, 
00345                          DATA_REQUEST_TAG);
00346 
00347     if (input.n_experiments > 1) cerr << "Experiment #" << n_exp
00348                                       << ": " << "\n";
00349 
00350     input.n_rand += input.n_rand_inc;
00351     PRC(input.n_rand);PRL(input.n_rand_inc);
00352 
00353     MPI::COMM_WORLD.Send(&input, length, inputtype, slave, 
00354                          DATA_COMING_TAG);
00355     MPI::COMM_WORLD.Send(&experiment, length, scatter_exp_type, slave, 
00356                          DATA_COMING_TAG);
00357     nsend++;
00358 
00359     MPI::COMM_WORLD.Recv(&slave_sends_data, length, MPI::INT,
00360                          accept_all_senders,  DATA_COMING_TAG);
00361     slave = slave_sends_data;
00362     MPI::COMM_WORLD.Recv(&experiment, length, scatter_exp_type, 
00363                          slave,  DATA_COMING_TAG);
00364 
00365     //    PRL(experiment.get_final_form());
00366     //    cerr << experiment << endl;
00367     hi->add_scatter_hist(experiment, 0);
00368     //cerr << "scatter history" << flush << endl;
00369     //hi->put_scatter_hist(cerr, false);
00370     //cerr << " N done = " << n_exp+1 << endl;
00371 
00372     n_exp++;
00373   }
00374   while(n_exp < input.n_experiments);
00375 
00376   cerr << "Start terminating all processes"<<endl;
00377 
00378   data_available = 0;
00379   for(i=1; i<nproc; i++) {
00380 
00381       nsend++;
00382 
00383       MPI::COMM_WORLD.Recv(&request_for_data, length, MPI::INT,
00384                            accept_all_senders, DATA_REQUEST_TAG);
00385     
00386       slave = request_for_data;
00387       cerr << "Send termination signal to slave " << slave << endl;
00388       MPI::COMM_WORLD.Send(&data_available, length, MPI::INT, slave, 
00389                            DATA_REQUEST_TAG);
00390   }
00391 
00392   cerr << "scatter history" << flush << endl;
00393   hi->put_scatter_hist(cerr, false);
00394   cerr << "Master ends"<<endl;
00395 }
00396 
00397 void execute_scatter_experiment(scatter_input input) {
00398 
00399   int argc = 0;
00400   char ** argv = NULL;
00401   MPI::Init(argc, argv);
00402   int myid = MPI::COMM_WORLD.Get_rank();
00403   int nproc = MPI::COMM_WORLD.Get_size();
00404 
00405   // MPI definition of datatype input_type
00406   int inputblockcounts[3] = {255, 7, 6};
00407   MPI_Datatype ntypes[3];
00408   MPI::Aint displs[3];
00409   MPI_Datatype inputtype;
00410 
00411   MPI_Address(&input.init_string, &displs[0]);
00412   MPI_Address(&input.delta_t, &displs[1]);
00413   MPI_Address(&input.n_experiments, &displs[2]);
00414   ntypes[0] = MPI::CHAR;
00415   ntypes[1] = MPI::DOUBLE;
00416   ntypes[2] = MPI::INT;
00417   displs[1] -= displs[0];
00418   displs[2] -= displs[0];
00419   displs[0] = 0;
00420 
00421   MPI_Type_struct(3, inputblockcounts, displs, ntypes, &inputtype);
00422   MPI_Type_commit(&inputtype);
00423 
00424   scatter_exp experiment; 
00425 
00426   // MPI definition of datatype scatter_exp
00427   int charlength = 255 + 255;
00428   int reallength = 4;
00429   int intlength = 10 + 2*N_RHO_ZONE_MAX + N_STEP_BIN + N_OSC_BIN;
00430   int boolength = 3 + intlength;
00431   int blockcounts[3] = {charlength, reallength, boolength};
00432   MPI::Aint exp_displs[3];
00433   MPI_Datatype scatter_exp_type;
00434 
00435   MPI_Address(experiment.get_initial_form(), &exp_displs[0]);
00436   MPI_Address(experiment.get_time_ptr(), &exp_displs[1]);
00437   MPI_Address(experiment.get_scatter_discriptor_ptr(), &exp_displs[2]);
00438   MPI_Datatype nexp_types[3] = {MPI::CHAR, MPI::DOUBLE, MPI::INT};
00439   exp_displs[1] -= exp_displs[0];
00440 
00441   exp_displs[2] -= exp_displs[0];
00442   exp_displs[0] = 0;
00443 
00444   MPI_Type_struct(3, blockcounts, exp_displs, nexp_types, &scatter_exp_type);
00445   MPI_Type_commit(&scatter_exp_type);
00446 
00447   int master = 0;
00448   if(myid==master) {
00449     master_process(input, inputtype, 
00450                    experiment, scatter_exp_type);
00451   }
00452   else {
00453     slave_process(master, 
00454                   input, inputtype, 
00455                   experiment, scatter_exp_type);
00456   }
00457 
00458   MPI::Finalize();
00459 
00460 }
00461 
00462 main(int argc, char **argv) {
00463 
00464   scatter_input input;
00465   char* default_init  
00466     = "-M 0.879 -rm 3 -v 2 -r 1 -t -r1 0.0508 -r2 0.0348 -e 0 -q 0.567 -p -a 1 -q 1 -r1 0.0394 -r2 0.0394";        // Iota Ori Probleem 
00467 
00468   strcpy(&input.init_string[0], default_init);
00469 //  input.init_string = default_init;   
00470 
00471   bool D_flag = false;
00472   check_help();
00473 
00474   extern char *poptarg;
00475   int c;
00476   char* param_string = "A:c:C:d:D:g:i:n:N:ps:t:v";
00477 
00478   while ((c = pgetopt(argc, argv, param_string)) != -1)
00479     switch(c) {
00480 
00481     case 'A': input.eta = atof(poptarg);
00482       break;
00483     case 'c': input.cpu_time_check = atof(poptarg);
00484       break;
00485     case 'C': input.snap_cube_size = atof(poptarg);
00486       break;
00487     case 'd': input.dt_out = atof(poptarg);
00488       break;
00489     case 'D': D_flag = TRUE;
00490       input.dt_snap = atof(poptarg);
00491       break;
00492     case 'g': input.tidal_tol_factor = atof(poptarg);
00493       break;
00494     case 'i': strcpy(&input.init_string[0], poptarg);
00495       break;
00496     case 'n': input.n_experiments = atoi(poptarg);
00497       break;   
00498     case 'N': input.n_rand = atoi(poptarg);
00499       break;
00500     case 'p': input.pipe = 1 - input.pipe;
00501       break;
00502     case 't': input.delta_t = atof(poptarg);
00503       break;
00504     case 'v': input.debug = 1 - input.debug;
00505       break;
00506     case 's': input.seed = atoi(poptarg);
00507       break;
00508     case '?': params_to_usage(cerr, argv[0], param_string);
00509       get_help();
00510     }            
00511 
00512   cerr << input << endl;
00513 
00514   if (!D_flag) input.dt_snap = input.delta_t; // Guarantee output at end
00515 
00516   execute_scatter_experiment(input);
00517 
00518 }
00519 #endif
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 

Generated at Sun Feb 24 09:57:14 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001