Swarm-NG  1.1
stop_on_all_but_two_at_large_distance.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 
29 #pragma once
30 
31 #include <limits>
32 
33 namespace swarm {
34  namespace monitors {
35 
36 
49  double rmax;
50  bool deactivate_on, log_on, verbose_on;
54  {
55  double rmax = cfg.optional("rmax",std::numeric_limits<float>::max());
56  deactivate_on = cfg.optional("deactivate_on_all_but_two_at_large_distance",false);
57  log_on = cfg.optional("log_on_all_but_two_at_large_distance",false);
58  verbose_on = cfg.optional("verbose_on_all_but_two_at_large_distance",false)
59  }
60 };
61 
67 template<class log_t>
69  public:
71 
72  private:
73  params _params;
74  bool need_full_test, condition_met;
75 
76  ensemble::SystemRef& _sys;
77  log_t& _log;
78  int _counter;
79 
80  public:
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  // Check for distance from origin
110  int num_body_near_origin = 0, id1 = -1, id2 = -2;
111  for(int b = 0 ; b < _sys.nbod(); b ++ ){
112  if(_sys.distance_to_origin_squared(b) <= _params.rmax*_params.rmax ) // WARNING: Confusing function name
113  {
114  if(num_body_near_origin==0) id1 = b;
115  if(num_body_near_origin==1) id2 = b;
116  num_body_near_origin++;
117  }
118  }
119  if( num_body_near_origin <= 2 )
120  { need_full_test = true; }
121  }
122  return need_full_test;
123  }
124 
126  GPUAPI int pass_two (int thread_in_system)
127  {
128  int new_state = _sys.state();
129  if(is_any_on() && need_full_test) // implies thread_in_system==0
130  {
131  // Check for distance from other bodies
132  int num_body_far_from_all = 0;
133  for(int b = 0 ; b < _sys.nbod(); b ++ )
134  {
135  if(_sys.distance_to_origin_squared(b) <= _params.rmax*_params.rmax ) continue; // WARNING: Confusing function name
136  bool is_far_from_every_body = true;
137  for(int bb = 0 ; bb < _sys.nbod(); bb ++ ){
138  if(b == bb) continue;
139  if(_sys.distance_squared_between(b,bb) < _params.rmax*_params.rmax )
140  { is_far_from_every_body = false; break; }
141  }
142  if(is_far_from_every_body)
143  { num_body_far_from_all++; }
144  }
145  if(num_body_far_from_all+2>=_sys.nbod())
146  {
147  condition_met = true;
148  if(is_verbose_on())
149  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"
150  , _sys.number(), id1, id2, _sys.time() , r, _params.rmax);
151  if(is_deactivate_on() && (_sys.state()>=0) )
152  { _sys.set_disabled(); new_state = _sys.state(); }
153  }
154  }
155  return new_state;
156  }
157 
158  GPUAPI void operator () (const int thread_in_system)
159  {
160  pass_one(thread_in_system);
161  pass_two(thread_in_system);
162  if(need_to_log_system() && (thread_in_system()==0) )
163  log::system(_log, _sys);
164  }
165 
166 
167 #if 0
168  // GPUAPI void operator () () {
169  GPUAPI void operator () (int thread_in_system) {
170  if(!is_any_on()) return;
171 
172  if(thread_in_system==0)
173  {
174  // Check for distance from origin
175  int num_body_near_origin = 0, id1 = -1, id2 = -2;
176  for(int b = 0 ; b < _sys.nbod(); b ++ ){
177  if(_sys.distance_to_origin_squared(b) <= _params.rmax*_params.rmax ) // WARNING: Confusing function name
178  {
179  if(num_body_near_origin==0) id1 = b;
180  if(num_body_near_origin==1) id2 = b;
181  num_body_near_origin++;
182  }
183  }
184  if( num_body_near_origin > 2 )
185  return;
186 
187  // Check for distance from other bodies
188  int num_body_far_from_all = 0;
189  for(int b = 0 ; b < _sys.nbod(); b ++ ){
190  if(_sys.distance_to_origin_squared(b) <= _params.rmax*_params.rmax ) continue; // WARNING: Confusing function name
191  bool is_far_from_every_body = true;
192  for(int bb = 0 ; bb < _sys.nbod(); bb ++ ){
193  if(b == bb) continue;
194  if(_sys.distance_squared_between(b,bb) < _params.rmax*_params.rmax )
195  { is_far_from_every_body = false; break; }
196  }
197  if(is_far_from_every_body)
198  {
199  num_body_far_from_all++;
200  }
201  }
202  if(num_body_far_from_all+2>=_sys.nbod())
203  {
204  if(is_verbose_on())
205  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"
206  , _sys.number(), id1, id2, _sys.time() , r, _params.rmax);
207  if(is_log_on())
208  log::system(_log, _sys);
209  if(is_deactivate_on())
210  _sys.set_disabled();
211  }
212  }
213  }
214 #endif
215 
216  GPUAPI stop_on_all_but_two_at_large_distance(const params& p,ensemble::SystemRef& s,log_t& l)
217  :_params(p),_sys(s),_log(l),_counter(0){}
218 
219 };
220 
221  }
222 }
223