Пример #1
0
  /*! \param cfg Configuration Paramaters
   */
	stop_on_ejection_params(const config &cfg)
	{
		rmax = cfg.optional("rmax",std::numeric_limits<float>::max());
		deactivate_on = cfg.optional("deactivate_on_ejection",false);
		log_on = cfg.optional("log_on_ejection",false);
		verbose_on = cfg.optional("verbose_on_ejection",false);
	}
Пример #2
0
bool validate_configuration(config& cfg){
  bool valid = true;                 // Indicates whether cfg parameters are valid
  int nsystems = cfg.optional("nsys",1000);
  int nbodypersystem = cfg.optional("nbod",3);
  // WARNING: blocksize isn't being used as the block size.  Trying to remove this.
//  int bs = cfg.optional("blocksize",16);

  // Check that parameters from command line are ok
//  if((bs<ENSEMBLE_CHUNK_SIZE)||(bs>64)) valid =false;
//  if( bs % ENSEMBLE_CHUNK_SIZE != 0 ) valid = false;
  if(!(nsystems>=1)||!(nsystems<=256000)) valid = false;
  if(!(nbodypersystem>=3)||!(nbodypersystem<=MAX_NBODIES)) valid = false;

  return valid;
}
Пример #3
0
void stability_test() {

	defaultEnsemble &ens = current_ens;

	double begin_time = ens.time_ranges().median;
	double destination_time = cfg.optional("destination_time", begin_time + 10 * M_PI );
	double interval = cfg.optional("interval", (destination_time-begin_time) ) ; 
	double logarithmic = cfg.optional("logarithmic", 0 ) ; 
	double allowed_deltaE =  cfg.optional("allowed_deltaE", 0.01 );

	if(destination_time < begin_time ) ERROR("Destination time should be larger than begin time");
	if(interval < 0) ERROR("Interval cannot be negative");
	if(interval < 0.001) ERROR("Interval too small");
	if(logarithmic != 0 && logarithmic <= 1) ERROR("logarithm base should be greater than 1");


	std::cout << "Time, Energy Conservation Factor (delta E/E), Active Systems" << std::endl;
	for(double time = begin_time; time < destination_time; ) {

		if(logarithmic > 1)
			time = (time > 0) ? time * logarithmic : interval;
		else
			time += interval;

		double effective_time = min(time,destination_time);
		integ->set_destination_time ( effective_time );

		DEBUG_OUTPUT(2, "Integrator ensemble" );
		integ->integrate();

		SYNC;
		DEBUG_OUTPUT(2, "Check energy conservation" );
                ensemble::range_t deltaE_range = energy_conservation_error_range(ens, initial_ens );

		int active_systems = ens.nsys() - number_of_disabled_systems( ens );
		std::cout << effective_time << ", " << deltaE_range.max << ", " << deltaE_range.median << ", " << active_systems << std::endl;
		
		if(deltaE_range.median > allowed_deltaE){
			INFO_OUTPUT(0, "At least half of systems are too unstable to conserve energy. dE/E: " << deltaE_range.median << std::endl );
			exit(1);
		}

	}

}
Пример #4
0
void prepare_integrator () {
	// Initialize Integrator
	DEBUG_OUTPUT(2, "Initializing integrator" );
	double begin_time = initial_ens.time_ranges().average;
	double destination_time = cfg.optional("destination_time", begin_time + 10 * M_PI );
	integ = integrator::create(cfg);
	integ->set_ensemble(current_ens);
	integ->set_destination_time ( destination_time );
	SYNC;
}
Пример #5
0
/**
 * This procedure was copied from the other Monte Carlo simulation code
 *
 * I had to change all the floats to double because in the new swarm we
 * use double for masses. Also, our ensemble classes now use reference
 * counted pointers and we create them in a functional way than old 
 * fill-this-for-me-please pointers(references). The generate name
 * makes more sense that the set_initial_conditions. I only added
 * one line for generating the ensemble. In the other monte carlo, 
 * the ensemble is generated first and then passed to this function
 * to fill it in.
 *
 *
 */
defaultEnsemble generate_ensemble_with_randomized_initial_conditions(const config& cfg) 
{
  defaultEnsemble ens = defaultEnsemble::create( cfg.require("nbod",0), cfg.require("nsys",0) );
  std::cerr << "# nsystems = " << ens.nsys() << " nbodies/system = " << ens.nbod() << "\n";

  //  std::cerr << "# Set initial time for all systems = ";
  double time_init = cfg.optional("time_init", 0.0);
  //  std::cerr << time_init << ".\n";

  const bool use_jacobi = cfg.optional("use_jacobi", 0);
  bool keplerian_ephemeris = cfg.optional("use_keplerian", 1);
  bool transit_ephemeris = cfg.optional("use_transit", 0);
  if(transit_ephemeris) keplerian_ephemeris = 0;
  assert(!(keplerian_ephemeris && transit_ephemeris));  // find a better way

  for(unsigned int sys=0;sys<ens.nsys();++sys)
    {
      generate_initial_conditions_for_system(cfg,ens,sys,sys);
    } // end loop over systems
  return ens;
}
Пример #6
0
void write_stable_systems(defaultEnsemble &ens, defaultEnsemble &ens_init) 
{
  // find the stable ones and output the initial conditions for the stable
  // ones in keplerian coordinates
  //  std::cerr << "# Finding stable system ids\n";
  std::vector<unsigned int> stable_system_indices, unstable_system_indices;
  for(int i = 0; i < ens.nsys() ; i++ )
    {
      if(ens[i].is_disabled())
	unstable_system_indices.push_back(i);
      else
	stable_system_indices.push_back(i);
    }
  
  //  std::cerr << "# Writing stable system ids\n";
  if(cfg.count("stable_init_output"))
    {
      ofstream stable_init_output( cfg.optional("stable_init_output", string("stable_init_output.txt")).c_str() ); 
      print_selected_systems(ens_init,stable_system_indices, stable_init_output);
    }

  if(cfg.count("stable_final_output"))
    {
      ofstream stable_final_output( cfg.optional("stable_final_output", string("stable_final_output.txt")).c_str() ); 
      print_selected_systems(ens,stable_system_indices, stable_final_output);
    }

  if(cfg.count("unstable_init_output"))
    {
      ofstream unstable_init_output( cfg.optional("unstable_init_output", string("unstable_init_output.txt")).c_str() ); 
      print_selected_systems(ens_init,unstable_system_indices, unstable_init_output);
    }

  if(cfg.count("unstable_final_output"))
    {
      ofstream unstable_final_output( cfg.optional("unstable_final_output", string("unstable_final_output.txt")).c_str() ); 
      print_selected_systems(ens,unstable_system_indices, unstable_final_output);
    }

}
Пример #7
0
Pwriter writer::create(const config& cfg)
{
        Pwriter w;

	std::string name = cfg.optional(std::string("log_writer") , std::string("null") );
	std::string plugin_name = "writer_" + name;

	try {
	  w.reset( (writer*) (plugin::instance(plugin_name,cfg)) );
	}catch(plugin_not_found& e){
			ERROR("Log writer " + name + " not found.");
	}

        return w;
}
Пример #8
0
void generate_initial_conditions_for_system(const config& cfg, defaultEnsemble &ens, const int sysidx, const int sysid) 
{
  double time_init = cfg.optional("time_init", 0.0);
  const bool use_jacobi = cfg.optional("use_jacobi", 0);
  bool keplerian_ephemeris = cfg.optional("use_keplerian", 1);
  bool transit_ephemeris = cfg.optional("use_transit", 0);
  if(transit_ephemeris) keplerian_ephemeris = 0;
  assert(!(keplerian_ephemeris && transit_ephemeris));  // find a better way

  ens[sysidx].id() = sysid;
  ens[sysidx].time() = time_init;
  ens[sysidx].set_active();
  if(sysid>maxsysid) maxsysid = sysid;

  // set sun to unit mass and at origin
  double mass_star = draw_value_from_config(cfg,"mass_star",0.00003,100.);
  double x=0, y=0, z=0, vx=0, vy=0, vz=0;
  ens.set_body(sysidx, 0, mass_star, x, y, z, vx, vy, vz);

  // If omitted or value of zero, then default to cycling through body id to make eccentric
  int ecc_body = cfg.optional("ecc_body", 0);
  if(ecc_body==0)
    {      ecc_body = 1+(sysid*(ens.nbod()-1))/ens.nsys();    }
  double mass_enclosed = mass_star;
  for(unsigned int bod=1;bod<ens.nbod();++bod)
    {
      double mass_planet = draw_value_from_config(cfg,"mass",bod,0.,mass_star);
      mass_enclosed += mass_planet;
      
      double a, e, i, O, w, M;
      if(transit_ephemeris)
	{
	  double period = draw_value_from_config(cfg,"period",bod,0.2,365250.);
	  double epoch = draw_value_from_config(cfg,"epoch",bod,0.2,365250.);
	  a = pow((period/365.25)*(period/365.25)*mass_enclosed,1.0/3.0);
	  if(bod==ecc_body)
	    e = draw_value_from_config(cfg,"ecc",bod,0.,1.);
	  else
	    e = 0.;
	  i = draw_value_from_config(cfg,"inc",bod,-180.,180.);
	  O = draw_value_from_config(cfg,"node",bod,-720.,720.);
	  w = draw_value_from_config(cfg,"omega",bod,-720.,720.);
	  
	  i *= M_PI/180.;
	  O *= M_PI/180.;
	  w *= M_PI/180.;
	  
	  double T = (0.5*M_PI-w)+2.0*M_PI*((epoch/period)-floor(epoch/period));
	  double E = atan2(sqrt(1.-e)*(1.+e)*sin(T),e+cos(T));
	  M = E-e*sin(E);
	}
      else if (keplerian_ephemeris)
	{
	  a = draw_value_from_config(cfg,"a",bod,0.001,10000.);
	  if(bod==ecc_body)
	    e = draw_value_from_config(cfg,"ecc",bod,0.,1.);
	  else
	    e = 0.;
	  i = draw_value_from_config(cfg,"inc",bod,-180.,180.);
	  O = draw_value_from_config(cfg,"node",bod,-720.,720.);
	  w = draw_value_from_config(cfg,"omega",bod,-720.,720.);
	  M = draw_value_from_config(cfg,"meananom",bod,-720.,720.);
	  
	  i *= M_PI/180.;
	  O *= M_PI/180.;
	  w *= M_PI/180.;
	  M *= M_PI/180.;
	}
      
      double mass = use_jacobi ? mass_enclosed : mass_star+mass_planet;
      if(cfg.count("verbose")&&(sysid<10))
	std::cout << "# Drawing sysid= " << sysid << " bod= " << bod << ' ' << mass_planet << "  " << a << ' ' << e << ' ' << i*180./M_PI << ' ' << O*180./M_PI << ' ' << w*180./M_PI << ' ' << M*180./M_PI << '\n';
      
      calc_cartesian_for_ellipse(x,y,z,vx,vy,vz, a, e, i, O, w, M, mass);
      
      //  printf("%d %d: %lg (%lg %lg %lg) (%lg %lg %lg) \n", sysidx, bod, mass_planet, x,y,z,vx,vy,vz);
      
      if(use_jacobi)
	{
	  double bx, by, bz, bvx, bvy, bvz;
	  ens.get_barycenter(sysidx,bx,by,bz,bvx,bvy,bvz,bod-1);
	  x  += bx;	  y  += by;	  z  += bz;
	  vx += bvx;	  vy += bvy;	  vz += bvz;
	}
      
      // assign body a mass, position and velocity
      ens.set_body(sysidx, bod, mass_planet, x, y, z, vx, vy, vz);
      
      if(cfg.count("verbose")&&(sysid<10))
	{
	  double x_t = ens.x(sysidx,bod);
	  double y_t = ens.y(sysidx,bod);
	  double z_t = ens.z(sysidx,bod);
	  double vx_t = ens.vx(sysidx,bod);
	  double vy_t = ens.vy(sysidx,bod);
	  double vz_t = ens.vz(sysidx,bod);
	  
	  std::cout << " x= " << x << "=" << x_t << " ";
	  std::cout << " y= " << y << "=" << y_t << " ";
	  std::cout << " z= " << z << "=" << z_t << " ";
	  std::cout << "vx= " << vx << "=" << vx_t << " ";
	  std::cout << "vy= " << vy << "=" << vy_t << " ";
	  std::cout << "vz= " << vz << "=" << vz_t << "\n";
	}
      
    }  // end loop over bodies
  
  // Shift into barycentric frame
  ens.get_barycenter(sysidx,x,y,z,vx,vy,vz);
  for(unsigned int bod=0;bod<ens.nbod();++bod)
    {
      ens.set_body(sysidx, bod, ens.mass(sysidx,bod), 
		   ens.x(sysidx,bod)-x, ens.y(sysidx,bod)-y, ens.z(sysidx,bod)-z, 
		   ens.vx(sysidx,bod)-vx, ens.vy(sysidx,bod)-vy, ens.vz(sysidx,bod)-vz);	  
    }  // end loop over bodies
}
Пример #9
0
void print_system(const swarm::ensemble& ens, const int systemid, std::ostream &os = std::cout)
{
  enum {
    JACOBI, BARYCENTRIC, ASTROCENTRIC
  } COORDINATE_SYSTEM = BARYCENTRIC;
  const bool use_jacobi = cfg.optional("use_jacobi", 0);  
  if(use_jacobi) COORDINATE_SYSTEM = JACOBI;

  

  std::streamsize cout_precision_old = os.precision();
  os.precision(10);
  os << "sys_idx= " << systemid << " sys_id= " << ens[systemid].id() << " time= " << ens.time(systemid) << "\n";
      double star_mass = ens.mass(systemid,0);
      double mass_effective = star_mass;
      double bx, by, bz, bvx, bvy, bvz;
      switch(COORDINATE_SYSTEM) 
	{
	case JACOBI:
	  ens.get_barycenter(systemid,bx,by,bz,bvx,bvy,bvz,0);
	  break;
	  
	case BARYCENTRIC:
	  ens.get_barycenter(systemid,bx,by,bz,bvx,bvy,bvz);
	  break;
	  
	case ASTROCENTRIC:
	  ens.get_body(systemid,0,star_mass,bx,by,bz,bvx,bvy,bvz);
	  break;
	}
      
      for(unsigned int bod=1;bod<ens.nbod();++bod) // Skip star since printing orbits
	{
	  //	  std::cout << "pos= (" << ens.x(systemid, bod) << ", " <<  ens.y(systemid, bod) << ", " << ens.z(systemid, bod) << ") vel= (" << ens.vx(systemid, bod) << ", " <<  ens.vy(systemid, bod) << ", " << ens.vz(systemid, bod) << ").\n";
	  double mass = ens.mass(systemid,bod);
	  
	  switch(COORDINATE_SYSTEM) 
	    {
	    case JACOBI:
	      ens.get_barycenter(systemid,bx,by,bz,bvx,bvy,bvz,bod-1);
	      mass_effective += mass;
	      break;
	      
	    case BARYCENTRIC:
	      mass_effective = star_mass + mass;
	      break;
	      
	    case ASTROCENTRIC:
	      mass_effective = star_mass + mass;
	      break;
	    }
	  double x = ens.x(systemid,bod)-bx;
	  double y = ens.y(systemid,bod)-by;
	  double z = ens.z(systemid,bod)-bz;
	  double vx = ens.vx(systemid,bod)-bvx;
	  double vy = ens.vy(systemid,bod)-bvy;
	  double vz = ens.vz(systemid,bod)-bvz;
	  
	  double a, e, i, O, w, M;
	  calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
	  i *= 180/M_PI;
	  O *= 180/M_PI;
	  w *= 180/M_PI;
	  M *= 180/M_PI;
	  //	  os << " b= " << bod << " m= " << mass << " a= " << a << " e= " << e << " i= " << i << " Omega= " << O << " omega= " << w << " M= " << M << "\n";
	  os << ens[systemid].id() << " " << bod << " " << mass << " " << a << " " << e << " " << i << " " << O << " " << w << " " << M << "\n";
	}

  os.precision(cout_precision_old);
  os << std::flush;
}
Пример #10
0
int main(int argc, char* argv[]){

	// Command line and Config file
	parse_commandline_and_config(argc,argv);
//	outputConfigSummary(std::cout,cfg);
	base_cfg = cfg;
	command = argvars_map["command"].as< string >();


	// Set some variables
	pos_threshold = cfg.optional("pos_threshold", 1e-10);
	vel_threshold = cfg.optional("vel_threshold", 1e-10);
	time_threshold = cfg.optional("time_threshold", 1e-10);

	// Branch based on COMMAND
	if(command == "integrate"){
		init_cuda();
		run_integration();

	}else if(command == "test-cpu"){
//		init_cuda();  // removed so CPU tests would work, but then broke GPU tests when needed to set cuda device
		output_test();
	}else if(command == "test"){
		init_cuda();  
		output_test();
	}else if(command == "benchmark" || command == "verify") {
		init_cuda();
		if(command == "verify") 
			verify_mode = true;

		if(argvars_map.count("range") > 0) {
			parameter_range pr = argvars_map["range"].as<parameter_range>();
			benchmark(pr);
		}else
			cerr << "A parameter-value range is missing" << endl;

		if(command == "verify")  {
			cout << (verification_results ? "Verify success" : "Verify failed") << endl;
			return verification_results ? 0 : 1;
		}
	}


	else if(command == "query" ) {
		if (!argvars_map.count("logfile")) { cerr << "Name of input log file is missing \n"; return 1; }

		time_range_t T;
		sys_range_t sys, body_range;
		if (argvars_map.count("time")) { T = argvars_map["time"].as<time_range_t>(); }
		if (argvars_map.count("system")) { sys = argvars_map["system"].as<sys_range_t>(); }
		if (argvars_map.count("body")) { body_range = argvars_map["body"].as<sys_range_t>(); }
		if (argvars_map.count("keplerian")) { query::set_keplerian_output(); }
		if (argvars_map.count("origin")) { query::set_coordinate_system(query::origin); }
		if (argvars_map.count("astrocentric")) { query::set_coordinate_system(query::astrocentric); }
		if (argvars_map.count("barycentric")) { query::set_coordinate_system(query::barycentric); }
		if (argvars_map.count("jacobi")) { query::set_coordinate_system(query::jacobi); }


        std::cout.flush(); 
	cerr << "# Systems: " << sys << " Bodies: " << body_range << " Times: " << T << endl;
	if (argvars_map.count("keplerian")) 
	  { std::cerr << "# Output in Keplerian coordinates  "; }
	else { std::cerr << "# Output in Cartesian coordinates  "; }
#if 0
	switch(query::planets_coordinate_system)
	  {
		case astrocentric:
		  std::cerr << "(astrocentric)";
		  break;
		case barycentric:
		  std::cerr << "(barycentric)";
		  break;
		case jacobi:
		  std::cerr << "(jacobi)";
		  break;
		case origin:
		  std::cerr << "(origin)";
		  break;
	  }
#endif
	std::cerr << "\n";


		std::string datafile(argvars_map["logfile"].as<std::string>());

		query::execute(datafile, T, sys, body_range);
	}

	else if(command == "generate" ) {
		srand(time(NULL));
		INFO_OUTPUT(1, "Generating new ensemble:  " << cfg["nsys"] << ", " << cfg["nbod"] << endl);
		current_ens = generate_ensemble(cfg);
		save_ensemble();
	} 
	
	else if(command == "convert" ) {
		if( read_input_file(current_ens,cfg) && save_ensemble() ) {
			INFO_OUTPUT(1,"Converted!");
		}else{
			INFO_OUTPUT(1,"Convertion failed");
			exit(1);
		}
	} 
	
	else
		std::cerr << "Valid commands are: integrate, benchmark, verify, test, test-cpu, query, generate " << std::endl;

	return 0;
}
Пример #11
0
 stop_on_collision_param(const config &cfg)
 {
     dmin_squared = cfg.optional("collision_radius",0.);
     dmin_squared *= dmin_squared;
 }
Пример #12
0
/**
 * Read in Keplerian coordinates from a text file
 *
 */
defaultEnsemble generate_ensemble_with_initial_conditions_keplerian_from_file(const config& cfg) 
{
  defaultEnsemble ens = defaultEnsemble::create( cfg.require("nbod",0), cfg.require("nsys",0) );
  std::cerr << "# nsystems = " << ens.nsys() << " nbodies/system = " << ens.nbod() << "\n";

  //  std::cerr << "# Set initial time for all systems = ";
  double time_init = cfg.optional("time_init", 0.0);
  //  std::cerr << time_init << ".\n";

  const bool use_jacobi = cfg.optional("use_jacobi", 0);

  //  std::cerr << "# Writing stable system ids\n";
  ifstream jacobi_input( cfg.optional("input_mcmc_keplerian", string("mcmc.out")).c_str() ); 

  for(unsigned int sysid=0;sysid<ens.nsys();++sysid)
    {
      assert(jacobi_input.good());
      string id;
      double mass_star;
      jacobi_input >> id >> mass_star;
      ens[sysid].id() = sysid;
      ens[sysid].time() = time_init;
      ens[sysid].set_active();
      double x=0, y=0, z=0, vx=0, vy=0, vz=0;
      ens.set_body(sysid, 0, mass_star, x, y, z, vx, vy, vz);
      double mass_enclosed = mass_star;
      for(unsigned int bod=1;bod<ens.nbod();++bod)
	{

	  double mass_planet, a, e, i, O, w, M;
	  jacobi_input >> mass_planet >> a >> e >> i >> w >> O >> M;
	  //	  a = pow((period/365.25)*(period/365.25)*mass_enclosed,1.0/3.0);
	  i *= M_PI/180.;
	  O *= M_PI/180.;
	  w *= M_PI/180.;
	  M *= M_PI/180.;

	  mass_enclosed += mass_planet;	  
	  double mass = use_jacobi ? mass_enclosed : mass_star+mass_planet;
	  if(cfg.count("verbose")&&(sysid<10))
	    std::cout << "# Drawing sysid= " << sysid << " bod= " << bod << ' ' << mass_planet << "  " << a << ' ' << e << ' ' << i*180./M_PI << ' ' << O*180./M_PI << ' ' << w*180./M_PI << ' ' << M*180./M_PI << '\n';
	  
	  calc_cartesian_for_ellipse(x,y,z,vx,vy,vz, a, e, i, O, w, M, mass);
      //  printf("%d %d: %lg (%lg %lg %lg) (%lg %lg %lg) \n", sysid, bod, mass_planet, x,y,z,vx,vy,vz);

	  if(use_jacobi)
	    {
	      double bx, by, bz, bvx, bvy, bvz;
	      ens.get_barycenter(sysid,bx,by,bz,bvx,bvy,bvz,bod-1);
	      x  += bx;	  y  += by;	  z  += bz;
	      vx += bvx;  vy += bvy;	  vz += bvz;
	    }
	  
	  // assign body a mass, position and velocity
	  ens.set_body(sysid, bod, mass_planet, x, y, z, vx, vy, vz);

	  if(cfg.count("verbose")&&(sysid<10))
	    {
	      double x_t = ens.x(sysid,bod);
	      double y_t = ens.y(sysid,bod);
	      double z_t = ens.z(sysid,bod);
	      double vx_t = ens.vx(sysid,bod);
	      double vy_t = ens.vy(sysid,bod);
	      double vz_t = ens.vz(sysid,bod);
	      
	      std::cout << " x= " << x << "=" << x_t << " ";
	      std::cout << " y= " << y << "=" << y_t << " ";
	      std::cout << " z= " << z << "=" << z_t << " ";
	      std::cout << "vx= " << vx << "=" << vx_t << " ";
	      std::cout << "vy= " << vy << "=" << vy_t << " ";
	      std::cout << "vz= " << vz << "=" << vz_t << "\n";
	    }
      
	}  // end loop over bodies
  
      // Shift into barycentric frame
      ens.get_barycenter(sysid,x,y,z,vx,vy,vz);
      for(unsigned int bod=0;bod<ens.nbod();++bod)
	{
	  ens.set_body(sysid, bod, ens.mass(sysid,bod), 
		       ens.x(sysid,bod)-x, ens.y(sysid,bod)-y, ens.z(sysid,bod)-z, 
		       ens.vx(sysid,bod)-vx, ens.vy(sysid,bod)-vy, ens.vz(sysid,bod)-vz);	  
	}  // end loop over bodies

    } // end loop over systems
  return ens;
}
Пример #13
0
/**
 * Read in Cartesian coordinates from a text file
 *
 */
defaultEnsemble generate_ensemble_with_initial_conditions_cartesian_from_file(const config& cfg) 
{
  defaultEnsemble ens = defaultEnsemble::create( cfg.require("nbod",0), cfg.require("nsys",0) );
  std::cerr << "# nsystems = " << ens.nsys() << " nbodies/system = " << ens.nbod() << "\n";

  //  std::cerr << "# Set initial time for all systems = ";
  double time_init = cfg.optional("time_init", 0.0);
  //  std::cerr << time_init << ".\n";

  const bool use_jacobi = cfg.optional("use_jacobi", 0);

  //  std::cerr << "# Writing stable system ids\n";
  ifstream mcmc_input( cfg.optional("input_mcmc_cartesian", string("mcmc.out")).c_str() ); 

  assert(mcmc_input.good());

  const int lines_to_skip = cfg.optional("lines_to_skip", 0);
  for(int i=0;i<lines_to_skip;++i)
    {
      assert(mcmc_input.good());
      char junk[1024];
      mcmc_input.getline(junk,1024);
    }

  for(unsigned int sysid=0;sysid<ens.nsys();++sysid)
    {
      assert(mcmc_input.good());
#if 1
      std::vector<double> masses(ens.nbod(),0.0);
      for(unsigned int bod=0;bod<ens.nbod();++bod)
	{
	  mcmc_input >> masses[bod];
	}  // end loop over bodies

      ens[sysid].id() = sysid;
      ens[sysid].time() = time_init;
      ens[sysid].set_active();
      double x=0, y=0, z=0, vx=0, vy=0, vz=0;
      ens.set_body(sysid, 0, masses[0], x, y, z, vx, vy, vz);
      double mass_enclosed = masses[0];
      for(unsigned int bod=1;bod<ens.nbod();++bod)
	{
	  mcmc_input >> x >> y >> z >> vx >> vy >> vz;

	  mass_enclosed += masses[bod];
	  double mass = use_jacobi ? mass_enclosed : masses[0]+masses[bod];
	  if(cfg.count("verbose")&&(sysid<10))
	    std::cout << "# Drawing sysid= " << sysid << " bod= " << bod << ' ' << masses[bod] << "  " << x << ' ' << y << ' ' << z << ' ' << vx << ' ' << vy << ' ' << vz << '\n';
	  
	  if(use_jacobi)
	    {
	      double bx, by, bz, bvx, bvy, bvz;
	      ens.get_barycenter(sysid,bx,by,bz,bvx,bvy,bvz,bod-1);
	      x  += bx;	  y  += by;	  z  += bz;
	      vx += bvx;  vy += bvy;	  vz += bvz;
	    }
	  
	  // assign body a mass, position and velocity
	  ens.set_body(sysid, bod, masses[bod], x, y, z, vx, vy, vz);

	  if(cfg.count("verbose")&&(sysid<10))
	    {
	      double x_t = ens.x(sysid,bod);
	      double y_t = ens.y(sysid,bod);
	      double z_t = ens.z(sysid,bod);
	      double vx_t = ens.vx(sysid,bod);
	      double vy_t = ens.vy(sysid,bod);
	      double vz_t = ens.vz(sysid,bod);
	      
	      std::cout << " x= " << x << "=" << x_t << " ";
	      std::cout << " y= " << y << "=" << y_t << " ";
	      std::cout << " z= " << z << "=" << z_t << " ";
	      std::cout << "vx= " << vx << "=" << vx_t << " ";
	      std::cout << "vy= " << vy << "=" << vy_t << " ";
	      std::cout << "vz= " << vz << "=" << vz_t << "\n";
	    }
#else
      std::vector<double> masses(ens.nbod(),0.0);
      double x=0, y=0, z=0, vx=0, vy=0, vz=0;
      double mass_enclosed = 0.0;
      ens[sysid].id() = sysid;
      ens[sysid].time() = time_init;
      ens[sysid].set_active();
      for(unsigned int bod=0;bod<ens.nbod();++bod)
	{
	  mcmc_input >> masses[bod];
	  mcmc_input >> x >> y >> z >> vx >> vy >> vz;

	  mass_enclosed += masses[bod];
	  double mass = use_jacobi ? mass_enclosed : masses[0]+masses[bod];
	  if(cfg.count("verbose")&&(sysid<10))
	    std::cout << "# Drawing sysid= " << sysid << " bod= " << bod << ' ' << masses[bod] << "  " << x << ' ' << y << ' ' << z << ' ' << vx << ' ' << vy << ' ' << vz << '\n';
	  
	  if(use_jacobi)
	    {
	      double bx, by, bz, bvx, bvy, bvz;
	      ens.get_barycenter(sysid,bx,by,bz,bvx,bvy,bvz,bod-1);
	      x  += bx;	  y  += by;	  z  += bz;
	      vx += bvx;  vy += bvy;	  vz += bvz;
	    }
	  
	  // assign body a mass, position and velocity
	  ens.set_body(sysid, bod, masses[bod], x, y, z, vx, vy, vz);

	  if(cfg.count("verbose")&&(sysid<10))
	    {
	      double x_t = ens.x(sysid,bod);
	      double y_t = ens.y(sysid,bod);
	      double z_t = ens.z(sysid,bod);
	      double vx_t = ens.vx(sysid,bod);
	      double vy_t = ens.vy(sysid,bod);
	      double vz_t = ens.vz(sysid,bod);
	      
	      std::cout << " x= " << x << "=" << x_t << " ";
	      std::cout << " y= " << y << "=" << y_t << " ";
	      std::cout << " z= " << z << "=" << z_t << " ";
	      std::cout << "vx= " << vx << "=" << vx_t << " ";
	      std::cout << "vy= " << vy << "=" << vy_t << " ";
	      std::cout << "vz= " << vz << "=" << vz_t << "\n";
	    }
#endif      
	}  // end loop over bodies
  
      // Shift into barycentric frame
      ens.get_barycenter(sysid,x,y,z,vx,vy,vz);
      for(unsigned int bod=0;bod<ens.nbod();++bod)
	{
	  ens.set_body(sysid, bod, ens.mass(sysid,bod), 
		       ens.x(sysid,bod)-x, ens.y(sysid,bod)-y, ens.z(sysid,bod)-z, 
		       ens.vx(sysid,bod)-vx, ens.vy(sysid,bod)-vy, ens.vz(sysid,bod)-vz);	  
	}  // end loop over bodies

    } // end loop over systems
  return ens;
}


void print_system(const swarm::ensemble& ens, const int systemid, std::ostream &os = std::cout)
{
  enum {
    JACOBI, BARYCENTRIC, ASTROCENTRIC
  } COORDINATE_SYSTEM = BARYCENTRIC;
  const bool use_jacobi = cfg.optional("use_jacobi_output", 0);  
  if(use_jacobi) COORDINATE_SYSTEM = JACOBI;

  std::streamsize cout_precision_old = os.precision();
  os.precision(10);
  os << "sys_idx= " << systemid << " sys_id= " << ens[systemid].id() << " time= " << ens.time(systemid) << "\n";
      double star_mass = ens.mass(systemid,0);
      double mass_effective = star_mass;
      double bx, by, bz, bvx, bvy, bvz;
      switch(COORDINATE_SYSTEM) 
	{
	case JACOBI:
	  ens.get_barycenter(systemid,bx,by,bz,bvx,bvy,bvz,0);
	  break;
	  
	case BARYCENTRIC:
	  ens.get_barycenter(systemid,bx,by,bz,bvx,bvy,bvz);
	  break;
	  
	case ASTROCENTRIC:
	  ens.get_body(systemid,0,star_mass,bx,by,bz,bvx,bvy,bvz);
	  break;
	}
      
      for(unsigned int bod=1;bod<ens.nbod();++bod) // Skip star since printing orbits
	{
	  //	  std::cout << "pos= (" << ens.x(systemid, bod) << ", " <<  ens.y(systemid, bod) << ", " << ens.z(systemid, bod) << ") vel= (" << ens.vx(systemid, bod) << ", " <<  ens.vy(systemid, bod) << ", " << ens.vz(systemid, bod) << ").\n";
	  double mass = ens.mass(systemid,bod);
	  
	  switch(COORDINATE_SYSTEM) 
	    {
	    case JACOBI:
	      ens.get_barycenter(systemid,bx,by,bz,bvx,bvy,bvz,bod-1);
	      mass_effective += mass;
	      break;
	      
	    case BARYCENTRIC:
	      mass_effective = star_mass + mass;
	      break;
	      
	    case ASTROCENTRIC:
	      mass_effective = star_mass + mass;
	      break;
	    }
	  double x = ens.x(systemid,bod)-bx;
	  double y = ens.y(systemid,bod)-by;
	  double z = ens.z(systemid,bod)-bz;
	  double vx = ens.vx(systemid,bod)-bvx;
	  double vy = ens.vy(systemid,bod)-bvy;
	  double vz = ens.vz(systemid,bod)-bvz;
	  
	  double a, e, i, O, w, M;
	  calc_keplerian_for_cartesian(a,e,i,O,w,M, x,y,z,vx,vy,vz, mass_effective);
	  i *= 180/M_PI;
	  O *= 180/M_PI;
	  w *= 180/M_PI;
	  M *= 180/M_PI;
	  //	  os << " b= " << bod << " m= " << mass << " a= " << a << " e= " << e << " i= " << i << " Omega= " << O << " omega= " << w << " M= " << M << "\n";
	  os << ens[systemid].id() << " " << bod << " " << mass << " " << a << " " << e << " " << i << " " << O << " " << w << " " << M << "\n";
	}

  os.precision(cout_precision_old);
  os << std::flush;
}


void print_selected_systems(swarm::ensemble& ens, std::vector<unsigned int> systemindices, std::ostream &os = std::cout)
{
  for(unsigned int i=0; i<systemindices.size(); ++i)
      print_system(ens,systemindices[i], os);
}

void print_selected_systems_for_demo(swarm::ensemble& ens, unsigned int nprint, std::ostream &os = std::cout)
{
  if(nprint>ens.nsys()) nprint = ens.nsys();
  for(unsigned int systemid = 0; systemid< nprint; ++systemid)
      print_system(ens,systemid,os);
}


void write_stable_systems(defaultEnsemble &ens, defaultEnsemble &ens_init) 
{
  // find the stable ones and output the initial conditions for the stable
  // ones in keplerian coordinates
  //  std::cerr << "# Finding stable system ids\n";
  std::vector<unsigned int> stable_system_indices, unstable_system_indices;
  for(int i = 0; i < ens.nsys() ; i++ )
    {
      if(ens[i].is_disabled())
	unstable_system_indices.push_back(i);
      else
	stable_system_indices.push_back(i);
    }
  
  //  std::cerr << "# Writing stable system ids\n";
  if(cfg.count("stable_init_output"))
    {
      ofstream stable_init_output( cfg.optional("stable_init_output", string("stable_init_output.txt")).c_str() ); 
      print_selected_systems(ens_init,stable_system_indices, stable_init_output);
    }

  if(cfg.count("stable_final_output"))
    {
      ofstream stable_final_output( cfg.optional("stable_final_output", string("stable_final_output.txt")).c_str() ); 
      print_selected_systems(ens,stable_system_indices, stable_final_output);
    }

  if(cfg.count("unstable_init_output"))
    {
      ofstream unstable_init_output( cfg.optional("unstable_init_output", string("unstable_init_output.txt")).c_str() ); 
      print_selected_systems(ens_init,unstable_system_indices, unstable_init_output);
    }

  if(cfg.count("unstable_final_output"))
    {
      ofstream unstable_final_output( cfg.optional("unstable_final_output", string("unstable_final_output.txt")).c_str() ); 
      print_selected_systems(ens,unstable_system_indices, unstable_final_output);
    }

}
Пример #14
0
	stop_on_ejection_params(const config &cfg)
	{
		rmax = cfg.optional("rmax",std::numeric_limits<float>::max());
	}
Пример #15
0
int main(int argc, char* argv[] ) 
{
  // We keep it simple, later on one can use boost::program_options to 
  // have more options
  // but now we only use two configuration files. It is because the 
  // initial conditions configuration file can get really big and 
  // it has very little to do with other configuration options.
  if(argc < 3) cout << "Usage: montecarlo_ecclimit <integration configuration> <initial conditions configuration>" << endl;

  // First one is the configuration for integration
  string integ_configfile = argv[1];
  // the second one is the configuration for generating
  //  initial conditions it is used by \ref generate_ensemble_with_randomized_initial_conditions
  string initc_configfile = argv[2];
  
  cfg = config::load(integ_configfile);
  
  // 1.read keplerian coordinates from a file
  // 2.generate guesses based on the keplerian coordinates
  // 3.convert keplerian coordinates to an ensemble
  // The following line that is taken from swarm_tutorial_montecarlo.cpp
  // does the first three steps. Its pretty amazing.
  defaultEnsemble ens ; 
  if( cfg.count("input") ) 
    {    ens = snapshot::load(cfg["input"]);  }
  else
    {    ens = generate_ensemble_with_randomized_initial_conditions( config::load(initc_configfile) );  }
	
  // save the ensemble as a snapshot
  if(cfg.count("initial_snapshot"))
    {    snapshot::save( ens, cfg["initial_snapshot"] );	}

  defaultEnsemble ens_init = ens.clone() ;
  std::vector<std::vector<double> > semimajor_axes_init = calc_semimajor_axes(ens);

  // We want to find the ones that are really stable, so we integrate for
  // a really long time and over time we get rid of unstable ones. 
  double destination_time = cfg.optional("destination_time", 1.0E6);
  
  
  swarm::init(cfg);
  Pintegrator integ = integrator::create(cfg);
  integ->set_ensemble(ens);
  integ->set_destination_time ( destination_time );
  // We can set the following two items if we really need
  // longer integrations before we stop for checking the
  // ensemble and saving snapshots.
  // one kernel call to allow for prompt CPU pruning of unstable systems
  int max_kernel_calls_per_integrate = cfg.optional("max_kernel_calls_per_integrate",1);
  // 10^2 inner orbits at 200 time steps per inner orbit
  int max_itterations_per_kernel_call = cfg.optional("max_itterations_per_kernel_call",20000);
  integ->set_max_attempts( max_kernel_calls_per_integrate ); 
  integ->set_max_iterations ( max_itterations_per_kernel_call ); 
  SYNC;

  // integrate ensemble
  //  - drop the unstable ones as you go
  //  - redistribute the systems for better efficiency
  //  - save the results periodically
  //  This can be an infitie loop. but we can always get out of this
  //  the best way to do it is to use Ctrl-C. Further wecan
  //  define Ctrl-C signal handler to get out
  //  of this loop in a safe way. But we really want this loop
  //  to run for a long time
  reactivate_systems(ens);
  // EBF Experiment trying to expose host log.
  swarm::log::ensemble(*(swarm::log::manager::default_log()->get_hostlog()),ens);
  integ->flush_log();

  catch_ctrl_c();
  while( number_of_active_systems(ens) > 0 && integration_loop_not_aborted_yet ) {

    // 1. Integrate, we could use core_integrate but the general integrate
    // saves all the headache. We should only use core_integrate if we are
    // going to do everything on GPU, but since we are saving a snapshot in 
    // the middle, there's no point. It also has a nice for loop and can
    // to several kernel calls.
    integ->integrate();
    
    // 2. CPU-based tests to identify systems that can be terminated
    int active_ones = number_of_active_systems(ens);
    const double deltaa_frac_threshold = cfg.optional("deltaa_frac_threshold", 0.5);
    disable_unstable_systems( ens, semimajor_axes_init, deltaa_frac_threshold );
    //    double med_deltaE = find_median_energy_conservation_error(ens, ens_init );
    double max_deltaE = find_max_energy_conservation_error(ens, ens_init );
    std::cerr << "# Time: " << ens.time_ranges().min << " " << ens.time_ranges().median << " " << ens.time_ranges().max << " Systems: " << ens.nsys() << ", " << active_ones << ", ";
    active_ones = number_of_active_systems(ens);    
    std::cerr << active_ones << "  max|dE/E|= " << max_deltaE << "\n";

    // EBF Experiment trying to expose host log.  
    swarm::log::ensemble_enabled(*(swarm::log::manager::default_log()->get_hostlog()),ens);
    integ->flush_log();

    if (!cfg.count("input") && cfg.count("replace_unstable") )
      {
	int nsys_to_replace = number_of_disabled_systems( ens ) ;
	if( nsys_to_replace >0 ) 
	  {
	    replace_disabled_systems( ens );
	    integ->set_ensemble( ens );
	  }
      }
    else
      {
    // 3. Now we need to get rid of the inactive ones. There 
    // should be some criteria, whatever it is we are
    // going to put it in a function and call it \ref needs_shrinking
    if ( needs_shrinking( ens ) ) 
      {
	// Now this function will take care of trimming for us
	// We need to create a new ensemble of a smaller size
	// thats why we need to call set_ensemble again. because
	// the GPU ensemble should get recreated for us.
	//  we need better memory management to safely allow
	//  the following statement. Right now we don't have a
	//  very good automatic memory management
	//	std::cerr << "# Removing disabled systems\n";
	ens = trim_disabled_systems( ens );
	//	std::cerr << "# Testing if ens has any systems left.\n";
	if(ens.nsys()>0)
	  {
	    // std::cerr << "# Setting ensemble for integrator\n";
	    // WARNING: This appears to be the cause of SEGFAULT
	    //          if the ensemble is empty.  
	    integ->set_ensemble( ens );
	  }
	//	std::cerr << "# Time: " << ens.time_ranges() << " Total Systems: " << ens.nsys() << " Active Systems: " << active_ones << ", ";
	//	active_ones = number_of_active_systems(ens);    
	//	std::cerr << active_ones << "\n";
      }
      }
    //    std::cerr << std::endl;

    // 4. We need to save a snapshot in case system crashes or someone
    // gets tired of it and hits Ctrl-C
    //    std::cerr << "# Saving snapshot\n";
    save_snapshot( ens );
    write_stable_systems(ens,ens_init);    
  }

  // Now we are at the end of the system, before we examine
  // the output we need to 
  //  std::cerr << "# Removing disabled systems\n";
  if(number_of_active_systems(ens)>0)
    {
      ens = trim_disabled_systems( ens );
      //  std::cerr << "# Saving snapshot\n";
      save_snapshot( ens );
    }

  write_stable_systems(ens,ens_init);
}
	stop_on_all_but_two_at_large_distance_params(const config &cfg)
	{
		double rmax = cfg.optional("rmax",std::numeric_limits<float>::max());
	}
	stop_on_any_large_distance_params(const config &cfg)
	{
		rmax = cfg.optional("rmax",std::numeric_limits<float>::max());
		stop = cfg.optional("stop_on_rmax",false);
	}