示例#1
0
	/** First, we test whether body b is far from the origin 
	 * (which may be COM or star) and moving farther away.  
	 * If both of those are passed, then we check that the
	 * orbit is parabolic or hyperbolic.
	 *
	 */
	GPUAPI bool test_body(const int& b) {

		double x,y,z,vx,vy,vz; _sys[b].get(x,y,z,vx,vy,vz);
		//		double r = sqrt(_sys[b].radius_squared());  // WARNING: Deceiving function name
		double r = _sys[b].radius();  // WARNING: Deceiving function name
		if( r < _params.rmax ) return false;
		double rdotv = x*vx+y*vy+z*vz;
		if( rdotv <= 0. ) return false;
		
		bool stopit = false;
		double speed_sq = _sys[b].speed_squared();  // WARNING: Deceiving function name
		double epp = 0.5*speed_sq*r/_sys[b].mass()-1.;
		if( fabs(epp) < 1e-4 ) {
			double energy = 0.5*speed_sq-_sys[b].mass()/r;
			if(is_verbose_on() )
			  lprintf(_log, "Orbit is nearly parabolic: _sys=%d, bod=%d, T=%lg r=%lg energy=%lg energy*r/GM=%lg.\n"
					, _sys.number(), b, _sys.time() , r, energy, epp );
			stopit = true;
		}else if ( epp > 0 ){
			double energy = 0.5*speed_sq-_sys[b].mass()/r;
			if(is_verbose_on() )
			  lprintf(_log, "Orbit is hyperbolic: _sys=%d, bod=%d, T=%lg r=%lg energy=%lg energy*r/GM=%lg.\n"
					, _sys.number(), b, _sys.time() , r, energy, epp );
			// TODO: Make sure that planet is not near another body
			// This is very unlikely to be an issue, provided that rmax
			// is set to be well beyond the initial semi-major axes
			stopit = true;
		}

		return stopit;
	}
	GPUAPI int pass_two (int thread_in_system) 
          {
	    int new_state = _sys.state();
	    if(is_any_on() && need_full_test) // implies thread_in_system==0
	      {
		// Check for distance from other bodies
		int num_body_far_from_all = 0;
		for(int b = 0 ; b < _sys.nbod(); b ++ )
		  {
		    if(_sys.radius_squared(b) <= _params.rmax*_params.rmax ) continue; // WARNING: Confusing function name
		    bool is_far_from_every_body = true;
		    for(int bb = 0 ; bb < _sys.nbod(); bb ++ ){		
		      if(b == bb) continue;
		      if(_sys.distance_squared_between(b,bb) < _params.rmax*_params.rmax )
			{ is_far_from_every_body = false;  break; }
		    }
		    if(is_far_from_every_body) 
		      {   num_body_far_from_all++;	  }
		  }
		if(num_body_far_from_all+2>=_sys.nbod())
		  {
		    condition_met = true;
		    if(is_verbose_on())
		      lprintf(_log, "No more than two bodies are within rmax of other bodies: _sys=%d, bod1=%d, bod2=%d, T=%lg r=%lg rmax=%lg.\n"
			      , _sys.number(), id1, id2, _sys.time() , r, _params.rmax);
		    if(is_deactivate_on() && (_sys.state()>=0) )
		      {  _sys.set_disabled();  new_state = _sys.state(); }
		  }
	      }
	    return new_state;
	  }
  //	GPUAPI void operator () () { 
  GPUAPI void operator () (int thread_in_system) {
	  if(!is_any_on()) return;

		if(thread_in_system==0)
		  {
		// Check for distance from origin
		int num_body_near_origin = 0, id1 = -1, id2 = -2;
		for(int b = 0 ; b < _sys.nbod(); b ++ ){
			if(_sys.radius_squared(b) <= _params.rmax*_params.rmax ) // WARNING: Confusing function name
				{
				if(num_body_near_origin==0) id1 = b;
				if(num_body_near_origin==1) id2 = b;
				 num_body_near_origin++;
				}
		}
		if( num_body_near_origin > 2 )
		  return;
 
		// Check for distance from other bodies
		int num_body_far_from_all = 0;
		for(int b = 0 ; b < _sys.nbod(); b ++ ){
			if(_sys.radius_squared(b) <= _params.rmax*_params.rmax ) continue; // WARNING: Confusing function name
			bool is_far_from_every_body = true;
			for(int bb = 0 ; bb < _sys.nbod(); bb ++ ){		
			   if(b == bb) continue;
			   if(_sys.distance_squared_between(b,bb) < _params.rmax*_params.rmax )
					{ is_far_from_every_body = false;  break; }
				}
			if(is_far_from_every_body) 
				{
				num_body_far_from_all++;
				}
		}
		if(num_body_far_from_all+2>=_sys.nbod())
			{
			  if(is_verbose_on())
			lprintf(_log, "No more than two bodies are within rmax of other bodies: _sys=%d, bod1=%d, bod2=%d, T=%lg r=%lg rmax=%lg.\n"
				, _sys.number(), id1, id2, _sys.time() , r, _params.rmax);
			  if(is_log_on())
			log::system(_log, _sys);
			  if(is_deactivate_on())
			  _sys.set_disabled();
			}
		  }
  }
	GPUAPI bool pass_one (int thread_in_system) 
          {
	    need_full_test = false; 
	    condition_met = false;
	    if(is_any_on()&&(thread_in_system==0))
	      {
		bool is_any_body_far_from_origin = false;
		for(int b = 0 ; b < _sys.nbod(); b ++ )
		  {
		    if(_sys.radius_squared(b) > _params.rmax * _params.rmax )
		      is_any_body_far_from_origin = true;
		  }
		if(!is_any_body_far_from_origin) break;
		bool need_to_log = false;
		for(int b = 0 ; b < _sys.nbod(); b ++ )
		  {
		    if(_sys.radius_squared(b) >= _params.rmax * _params.rmax ) 
		      {
			bool is_far_from_every_body = true;
			for(int bb = 0 ; bb < _sys.nbod(); bb ++ )
			  if(b != bb) 
			    {
			      double r2 = _sys.distance_squared_between(b,bb);
			      if(r2 < _params.rmax*_params.rmax )
				is_far_from_every_body = false;
			    }
			if(is_far_from_every_body) 
			  {
			    condition_met = true;
			    if( is_log_on() )
			      need_full_test = true;
			    if(is_verbose_on() )
			      lprintf(_log, "Distance from all bodies exceeds rmax: _sys=%d, bod=%d, T=%lg r=%lg rmax=%lg.\n", _sys.number(), b, _sys.time() , sqrt(r2), _params.rmax);
			  }
		      } // if far from origin
		  } // for bodies
	      }
	    return need_full_test;
	  }
  //	GPUAPI void operator () () { 
  GPUAPI void operator () (int thread_in_system) {
	  if(!is_any_on()) return;

		if(thread_in_system==0)
		  {

		bool is_any_body_far_from_origin = false;
		for(int b = 0 ; b < _sys.nbod(); b ++ ){
			if(_sys.radius_squared(b) > _params.rmax * _params.rmax )
				is_any_body_far_from_origin = true;
		}
		if(!is_any_body_far_from_origin) return;
		bool need_to_log = false;
		for(int b = 0 ; b < _sys.nbod(); b ++ ){
			if(_sys.radius_squared(b) >= _params.rmax * _params.rmax ) {
				bool is_far_from_every_body = true;
				for(int bb = 0 ; bb < _sys.nbod(); bb ++ )
					if(b != bb) {
						double r2 = _sys.distance_squared_between(b,bb);
						if(r2 < _params.rmax*_params.rmax )
							is_far_from_every_body = false;
					}
				if(is_far_from_every_body) {
				  if(is_verbose_on() )
					lprintf(_log, "Distance from all bodies exceeds rmax: _sys=%d, bod=%d, T=%lg r=%lg rmax=%lg.\n", _sys.number(), b, _sys.time() , sqrt(r2), _params.rmax);
				  if(is_log_on() )
				    need_to_log = true;

				  if(is_deactivate_on() )
					a_sys.set_disabled();
				}
			}
		}
		if(need_to_log)
		   log::system(_log, _sys);		  
		  }
  }
示例#6
0
文件: combine.hpp 项目: eford/swarm
 GPUAPI bool is_any_on() { return is_deactivate_on() || is_log_on() || is_verbose_on() ; }