コード例 #1
0
ファイル: swarm.cpp プロジェクト: yingz/swarm
bool read_output_file(defaultEnsemble& ens, config& cfg){

	if(cfg.valid("output") ) {
		INFO_OUTPUT(1, "Loading from binary file " << cfg["output"]);
		ens = swarm::snapshot::load(cfg["output"]);	
		INFO_OUTPUT(1,", time = " << ens.time_ranges() << endl);
		return true;

	}else if(cfg.valid("text_output")) {
		INFO_OUTPUT(1, "Loading from text file " << cfg["text_output"]);
		ens = swarm::snapshot::load_text(cfg["text_output"]);	
		INFO_OUTPUT(1,", time = " << ens.time_ranges() << endl);
		return true;

	}else
		return false;
		
}
コード例 #2
0
ファイル: swarm.cpp プロジェクト: yingz/swarm
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;
}
コード例 #3
0
ファイル: montecarlo_ecclimit.cpp プロジェクト: yingz/swarm
/**
 *  ***************TODO***********
 */
void replace_disabled_systems( defaultEnsemble& ens ) 
{
  int nsys = ens.nsys();
  // Replace the systems that have been disabled
  for(int i = 0; i < nsys; i++)
    {
      if( ens[i].is_disabled() )
	{
	  generate_initial_conditions_for_system(cfg,ens,i,maxsysid+1);
	}
    }
}
コード例 #4
0
ファイル: montecarlo_ecclimit.cpp プロジェクト: yingz/swarm
bool needs_shrinking( const defaultEnsemble& ens ) 
{
  // This is the ratio we use when we are shrinking
  // if the ratio of active ones to all is less 
  // than this number then we trim the fat
  const double critical_ratio = 0.75;
  
  int count_disabled = number_of_disabled_systems( ens ) ;
  double ratio = double(count_disabled) / double( ens.nsys() );
  
  return ratio > critical_ratio;
}
コード例 #5
0
ファイル: montecarlo_ecclimit.cpp プロジェクト: yingz/swarm
/**
 *  This is a very crucial part of the Monte Carlo simulation
 *  We remove the disabled ones and make a smaller ensemble.
 *  We don't really need to make another ensemble. But keeping
 *  the same ensemble is a lot of trouble.
 *
 */
defaultEnsemble trim_disabled_systems( const defaultEnsemble& ens ) 
{
  int nsys = ens.nsys();
  int active_nsys = nsys - number_of_disabled_systems( ens ) ;
  // WARNING: Needed to add this to prevent segfaults.  TODO: Figure out why.
  if(active_nsys==0) return ens;  
  int nbod = ens.nbod();

  defaultEnsemble active_ens = defaultEnsemble::create( nbod, active_nsys );

  // Copy the active ones to the new ensemble
  for(int i = 0, j = 0; (i < nsys) && (j < active_nsys); i++)
    {
      if( !ens[i].is_disabled() )
	{
	  ens[i].copyTo( active_ens[j] );
	  j++;
	}
    }
  
  return active_ens;
}
コード例 #6
0
ファイル: swarm.cpp プロジェクト: yingz/swarm
void benchmark_item(const string& param, const string& value) {
	//outputConfigSummary(std::cout,cfg);
	if(!validate_configuration(cfg) ) ERROR( "Invalid configuration" );

	if(param == "input" || param == "nsys" || param == "nbod" || cfg.count("reinitialize"))
		load_generate_ensemble();

	DEBUG_OUTPUT(2, "Make a copy of ensemble for energy conservation test" );
	current_ens = initial_ens.clone();

	double init_time = watch_time( prepare_integrator );

	double integration_time = watch_time( generic_integrate );

	double max_deltaE = find_max_energy_conservation_error(current_ens, initial_ens );

	// Compare with reneference ensemble for integrator verification
	double pos_diff = 0, vel_diff = 0, time_diff = 0;
	bool comparison =  compare_ensembles( current_ens, reference_ens , pos_diff, vel_diff, time_diff );

	/// CSV output for use in spreadsheet software 
	std::cout << param << ", "
	          << value << ",  "   
			  << current_ens.time_ranges() << ",  "
	          << max_deltaE << ",    " 
			  << pos_diff << ",    "
			  << vel_diff << ",   "
			  << time_diff << ",   "
	          << integration_time << ",    "
	          << init_time 
	          << std::endl;

	if( !comparison || pos_diff > pos_threshold || vel_diff > vel_threshold || time_diff > time_threshold ){
		fail_verify();
	}

}
コード例 #7
0
ファイル: swarm.cpp プロジェクト: yingz/swarm
void run_integration(){
	if(!validate_configuration(cfg) ) ERROR( "Invalid configuration" );

	load_generate_ensemble();

	DEBUG_OUTPUT(2, "Make a copy of ensemble for energy conservation test" );
	current_ens = initial_ens.clone();

	prepare_integrator();

	double integration_time = watch_time ( cfg.valid("interval") ? stability_test : generic_integrate );

	save_ensemble();

	INFO_OUTPUT( 1, "Integration time: " << integration_time << " ms " << std::endl);
}
コード例 #8
0
ファイル: montecarlo_ecclimit.cpp プロジェクト: yingz/swarm
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);
    }

}
コード例 #9
0
ファイル: swarm.cpp プロジェクト: yingz/swarm
void output_test() {
	if(!validate_configuration(cfg) ) ERROR( "Invalid configuration" );

	if(!read_input_file(initial_ens, cfg) ) {
		ERROR("you should have a tested input file");
	}

	DEBUG_OUTPUT(2, "Make a copy of ensemble for energy conservation test" );
	current_ens = initial_ens.clone();

	prepare_integrator();

	double integration_time = watch_time ( cfg.valid("interval") ? stability_test : generic_integrate );

	if(read_output_file(reference_ens,cfg)){

		// Compare with reneference ensemble for integrator verification
		double pos_diff = 0, vel_diff = 0, time_diff = 0;
		bool comparison =  compare_ensembles( current_ens, reference_ens , pos_diff, vel_diff, time_diff );

		INFO_OUTPUT(1,"\tPosition difference: " << pos_diff  << endl
			 << "\tVelocity difference: " << vel_diff  << endl
			 << "\tTime     difference: " << time_diff << endl );

		if( !comparison || pos_diff > pos_threshold || vel_diff > vel_threshold || time_diff > time_threshold ){
			INFO_OUTPUT(0, "Test failed" << endl);
			exit(1);
		}else {
			INFO_OUTPUT(0, "Test success" << endl);
		}


	}else{
		ERROR("You should provide a test output file");
	}

	INFO_OUTPUT( 1, "Integration time: " << integration_time << " ms " << std::endl);
}
コード例 #10
0
ファイル: montecarlo_ecclimit.cpp プロジェクト: yingz/swarm
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
}
コード例 #11
0
ファイル: montecarlo_ecclimit.cpp プロジェクト: yingz/swarm
void disable_unstable_systems(defaultEnsemble& ens, const std::vector<std::vector<double> >& semimajor_axes_init, const double deltaa_threshold )
{
  for(int sys_idx = 0; sys_idx < ens.nsys() ; sys_idx++)
    {
      if(ens[sys_idx].is_disabled() ) continue;
      bool disable = false;
      int sys_id = ens[sys_idx].id();
      double star_mass = ens.mass(sys_idx,0);      
      double mass_effective = star_mass;
      double bx, by, bz, bvx, bvy, bvz;
      ens.get_barycenter(sys_idx,bx,by,bz,bvx,bvy,bvz,0);
      for(unsigned int bod=1;bod<ens.nbod();++bod) // Skip star since calculating orbits
	{
	  //	  std::cout << "body= " << bod << ": ";
	  //	  std::cout << "pos= (" << ens.x(sys_idx, bod) << ", " <<  ens.y(sys_idx, bod) << ", " << ens.z(sys_idx, bod) << ") vel= (" << ens.vx(sys_idx, bod) << ", " <<  ens.vy(sys_idx, bod) << ", " << ens.vz(sys_idx, bod) << ").\n";
	  double mass = ens.mass(sys_idx,bod);
	  mass_effective += mass;
	  ens.get_barycenter(sys_idx,bx,by,bz,bvx,bvy,bvz,bod-1);
	  double x = ens.x(sys_idx,bod)-bx;
	  double y = ens.y(sys_idx,bod)-by;
	  double z = ens.z(sys_idx,bod)-bz;
	  double vx = ens.vx(sys_idx,bod)-bvx;
	  double vy = ens.vy(sys_idx,bod)-bvy;
	  double vz = ens.vz(sys_idx,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;

	  if(!((e>=0.)&&(e<1.0)))	{ disable = true; }
	  if(!((a>0.)&&(a<10.0)))	{ disable = true; }
	  assert(sys_id>=0);
	  assert(sys_id<semimajor_axes_init.size());
	  assert(bod-1>=0);
	  assert(bod-1<semimajor_axes_init[sys_id].size());
	  double da = a - semimajor_axes_init[sys_id][bod-1];
	  if(fabs(da) >= deltaa_threshold * semimajor_axes_init[sys_id][bod-1])
	    { disable = true; }

	  if(disable)
	    {
	      if(cfg.count("verbose"))
		std::cout << "# Disabling idx=" << sys_idx << " id=" << sys_id << " b=" << bod << " a= " << a << " e= " << e << " i= " << i << " Omega= " << O << " omega= " << w << " M= " << M << "\n";	  	
	      break;
	    }
	}
      if(disable) ens[sys_idx].set_disabled();
    }
}
コード例 #12
0
ファイル: montecarlo_ecclimit.cpp プロジェクト: yingz/swarm
std::vector<std::vector<double> > calc_semimajor_axes(defaultEnsemble& ens)
{
  std::vector<std::vector<double> > semimajor_axes(ens.nsys(),std::vector<double>(ens.nbod(),0.));

  for(int sys_idx = 0; sys_idx < ens.nsys() ; sys_idx++)
    {
      int sys_id = ens[sys_idx].id();
      assert(sys_id>=0);
      assert(sys_id<ens.nsys());
      double star_mass = ens.mass(sys_idx,0);      
      double mass_effective = star_mass;
      double bx, by, bz, bvx, bvy, bvz;
      ens.get_barycenter(sys_idx,bx,by,bz,bvx,bvy,bvz,0);
      for(unsigned int bod=1;bod<ens.nbod();++bod) // Skip star since calculating orbits
	{
	  double mass = ens.mass(sys_idx,bod);
	  mass_effective += mass;
	  ens.get_barycenter(sys_idx,bx,by,bz,bvx,bvy,bvz,bod-1);
	  double x = ens.x(sys_idx,bod)-bx;
	  double y = ens.y(sys_idx,bod)-by;
	  double z = ens.z(sys_idx,bod)-bz;
	  double vx = ens.vx(sys_idx,bod)-bvx;
	  double vy = ens.vy(sys_idx,bod)-bvy;
	  double vz = ens.vz(sys_idx,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);
	  semimajor_axes[sys_id][bod-1] = a;
	}
    }
  return semimajor_axes;
}
コード例 #13
0
ファイル: utils.cpp プロジェクト: AstroGPU/swarm
int number_of_disabled_systems(defaultEnsemble ens) {
	int count_running = 0;
	for(int i = 0; i < ens.nsys() ; i++)
		if( ens[i].is_disabled() ) count_running++;
	return count_running;
}