Swarm-NG  1.1
stop_on_collision.hpp
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2011 by Eric Ford and the Swarm-NG Development Team *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 3 of the License. *
7  * *
8  * This program is distributed in the hope that it will be useful, *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11  * GNU General Public License for more details. *
12  * *
13  * You should have received a copy of the GNU General Public License *
14  * along with this program; if not, write to the *
15  * Free Software Foundation, Inc., *
16  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17  ************************************************************************/
18 
28 #pragma once
29 
30 namespace swarm { namespace monitors {
31 
41  double dmin_squared;
42  bool deactivate_on, log_on, verbose_on;
43 
47  {
48  dmin_squared = cfg.optional("collision_distance_to_origin",0.);
49  dmin_squared *= dmin_squared;
50 
51  deactivate_on = cfg.optional("deactivate_on_collision",false);
52  log_on = cfg.optional("log_on_collision",false);
53  verbose_on = cfg.optional("verbose_on_collision",false);
54  }
55 };
56 
66 template<class log_t>
68  public:
70 
71  private:
72  params _params;
73  bool need_full_test, condition_met;
74  ensemble::SystemRef& _sys;
75  log_t& _log;
76 
77  int _counter;
78 
79  public:
80 
81  template<class T>
82  static GENERIC int thread_per_system(T compile_time_param){
83  return 1;
84  }
85 
86  template<class T>
87  static GENERIC int shmem_per_system(T compile_time_param) {
88  return 0;
89  }
90  GPUAPI bool is_deactivate_on() { return _params.deactivate_on; };
91  GPUAPI bool is_log_on() { return _params.log_on; };
92  GPUAPI bool is_verbose_on() { return _params.verbose_on; };
93  GPUAPI bool is_any_on() { return is_deactivate_on() || is_log_on() || is_verbose_on() ; }
94  GPUAPI bool is_condition_met () { return ( condition_met ); }
95  GPUAPI bool need_to_log_system ()
96  { return (is_log_on() && is_condition_met() ); }
97  GPUAPI bool need_to_deactivate ()
98  { return ( is_deactivate_on() && is_condition_met() ); }
99 
100  GPUAPI void log_system() { log::system(_log, _sys); }
101 
103  GPUAPI bool pass_one (int thread_in_system)
104  {
105  need_full_test = false;
106  condition_met = false;
107  if(is_any_on()&&(thread_in_system==0))
108  {
109  // Chcek for close encounters
110  for(int b = 1; b < _sys.nbod(); b++)
111  for(int d = 0; d < b; d++)
112  condition_met = condition_met || check_close_encounters(b,d);
113  if(condition_met && is_log_on() )
114  { need_full_test = true; }
115 
116  }
117  return need_full_test;
118  }
119 
121  GPUAPI int pass_two (int thread_in_system)
122  {
123  if (need_to_deactivate() && (thread_in_system()==0) )
124  { _sys.set_disabled(); }
125  return _sys.state();
126  }
127 
128 
129 #if 0 // still under development
130  GPUAPI bool check_close_encounter_possible(const int& i, const int& j, double dt){
131 
132  // double hill_distance_to_origin_sq_upper_limit = pow(((_sys.mass(i)+_sys.mass(j))/(3.0*_sys.mass(0))),2.0/3.0)*(std::max(_sys.distance_to_origin_squared(i),_sys.distance_to_origin_squared(j)));
133  double target_distance_to_origin_sq = (NUM_ATTRIBUTES>=1) ? attribute(i)*attribute(i) : _params.dmin_squared;
134  double vesc_sq = 2.0*_sys.mass(0)/std::min(_sys.distance_to_origin(i),_sys.distance_to_origin(j));
135  double d_squared = _sys.distance_squared_between(i,j);
136  bool close_encounter = (d_squared < vesc_sq*dt*dt + target_distance_to_origin_sq);
137  return close_encounter;
138  }
139 #endif
140 
141 #if 0 // still under development
142  GPUAPI double min_encounter_distance(const int& i, const int& j){
143  const Body& b1 = _body[i], & b2 = _body[j];
144  double d = sqrt( square(b1[0].pos()-b2[0].pos())
145  + square(b1[1].pos()-b2[1].pos())
146  + square(b1[2].pos()-b2[2].pos()) );
147  return d;
148  }
149 #endif
150 
152  GPUAPI bool check_close_encounters(const int& i, const int& j){
153 
154  double d_squared = _sys.distance_squared_between(i,j);
155  double target_distance_to_origin_sq = (NUM_ATTRIBUTES>=1) ? attribute(i)*attribute(i) : _params.dmin_squared;
156  bool close_encounter = d_squared < target_distance_to_origin_sq;
157 
158  if( close_encounter )
159  if(is_verbose_on() )
160  lprintf(_log, "Collision detected: "
161  "sys=%d, T=%f j=%d i=%d d=%lg.\n"
162  , _sys.number(), _sys.time(), j, i,sqrt(d_squared));
163  return close_encounter;
164  }
165 
166 
167 
168  GPUAPI void operator () (const int thread_in_system)
169  {
170  pass_one(thread_in_system);
171  pass_two(thread_in_system);
172  if(need_to_log_system() && (thread_in_system()==0) )
173  log::system(_log, _sys);
174  }
175 
176 #if 0
177  // GPUAPI void operator () () {
178  GPUAPI void operator () (int thread_in_system)
179  if(!is_any_on()) return;
180  bool stopit = false;
181 
182  if(thread_in_system==0)
183  {
184 
185  // Chcek for close encounters
186  for(int b = 1; b < _sys.nbod(); b++)
187  for(int d = 0; d < b; d++)
188  stopit = stopit || check_close_encounters(b,d);
189 
190  if(stopit) {
191  if(is_log_on())
192  log::system(_log, _sys);
193  if(is_deactivate_on())
194  _sys.set_disabled();
195  }
196  }
197  }
198 #endif
199 
201  GPUAPI stop_on_collision(const params& p,ensemble::SystemRef& s,log_t& l)
202  :_params(p),_sys(s),_log(l),_counter(0){}
203 
204 };
205 
206 } } // end namespace monitors :: swarm