Swarm-NG  1.1
stop_on_any_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 
28 #pragma once
29 
30 #include <limits>
31 
32 namespace swarm {
33  namespace monitors {
34 
47  double rmax;
48  bool deactivate_on, log_on, verbose_on;
52  {
53  rmax = cfg.optional("rmax",std::numeric_limits<float>::max());
54  deactivate_on = cfg.optional("deactivate_on_any_large_distance",false);
55  log_on = cfg.optional("log_on_any_large_distance",false);
56  verbose_on = cfg.optional("verbose_on_any_large_distance",false);
57  }
58 
59 
60 };
61 
72 template<class log_t>
74  public:
76 
77  private:
78  params _params;
79  bool need_full_test, condition_met;
80 
81  ensemble::SystemRef& _sys;
82  log_t& _log;
83 
84  public:
85  template<class T>
86  static GENERIC int thread_per_system(T compile_time_param){
87  return 1;
88  }
89 
90  template<class T>
91  static GENERIC int shmem_per_system(T compile_time_param) {
92  return 0;
93  }
94  GPUAPI bool is_deactivate_on() { return _params.deactivate_on; };
95  GPUAPI bool is_log_on() { return _params.log_on; };
96  GPUAPI bool is_verbose_on() { return _params.verbose_on; };
97  GPUAPI bool is_any_on() { return is_deactivate_on() || is_log_on() || is_verbose_on() ; }
98  GPUAPI bool is_condition_met () { return ( condition_met ); }
99  GPUAPI bool need_to_log_system ()
100  { return (is_log_on() && is_condition_met() ); }
101  GPUAPI bool need_to_deactivate ()
102  { return ( is_deactivate_on() && is_condition_met() ); }
103 
104  GPUAPI void log_system() { log::system(_log, _sys); }
105 
107  GPUAPI bool pass_one (int thread_in_system)
108  {
109  need_full_test = false;
110  condition_met = false;
111  if(is_any_on()&&(thread_in_system==0))
112  {
113  bool is_any_body_far_from_origin = false;
114  for(int b = 0 ; b < _sys.nbod(); b ++ )
115  {
116  if(_sys.distance_to_origin_squared(b) > _params.rmax * _params.rmax )
117  is_any_body_far_from_origin = true;
118  }
119  if(!is_any_body_far_from_origin) break;
120  bool need_to_log = false;
121  for(int b = 0 ; b < _sys.nbod(); b ++ )
122  {
123  if(_sys.distance_to_origin_squared(b) >= _params.rmax * _params.rmax )
124  {
125  bool is_far_from_every_body = true;
126  for(int bb = 0 ; bb < _sys.nbod(); bb ++ )
127  if(b != bb)
128  {
129  double r2 = _sys.distance_squared_between(b,bb);
130  if(r2 < _params.rmax*_params.rmax )
131  is_far_from_every_body = false;
132  }
133  if(is_far_from_every_body)
134  {
135  condition_met = true;
136  if( is_log_on() )
137  need_full_test = true;
138  if(is_verbose_on() )
139  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);
140  }
141  } // if far from origin
142  } // for bodies
143  }
144  return need_full_test;
145  }
146 
148  GPUAPI int pass_two (int thread_in_system)
149  {
150  if(is_condition_met() && is_deactivate_on() &&(thread_in_system==0) )
151  { _sys.set_disabled(); }
152  return _sys.state();
153  }
154 
155 
156  GPUAPI void operator () (const int thread_in_system)
157  {
158  pass_one(thread_in_system);
159  pass_two(thread_in_system);
160  if(need_to_log_system() && (thread_in_system()==0) )
161  log::system(_log, _sys);
162  }
163 
164 #if 0
165  // GPUAPI void operator () () {
166  GPUAPI void operator () (int thread_in_system) {
167  if(!is_any_on()) return;
168 
169  if(thread_in_system==0)
170  {
171 
172  bool is_any_body_far_from_origin = false;
173  for(int b = 0 ; b < _sys.nbod(); b ++ ){
174  if(_sys.distance_to_origin_squared(b) > _params.rmax * _params.rmax )
175  is_any_body_far_from_origin = true;
176  }
177  if(!is_any_body_far_from_origin) return;
178  bool need_to_log = false;
179  for(int b = 0 ; b < _sys.nbod(); b ++ ){
180  if(_sys.distance_to_origin_squared(b) >= _params.rmax * _params.rmax ) {
181  bool is_far_from_every_body = true;
182  for(int bb = 0 ; bb < _sys.nbod(); bb ++ )
183  if(b != bb) {
184  double r2 = _sys.distance_squared_between(b,bb);
185  if(r2 < _params.rmax*_params.rmax )
186  is_far_from_every_body = false;
187  }
188  if(is_far_from_every_body) {
189  if(is_verbose_on() )
190  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);
191  if(is_log_on() )
192  need_to_log = true;
193 
194  if(is_deactivate_on() )
195  a_sys.set_disabled();
196  }
197  }
198  }
199  if(need_to_log)
200  log::system(_log, _sys);
201  }
202  }
203 #endif
204 
205  GPUAPI stop_on_any_large_distance(const params& p,ensemble::SystemRef& s,log_t& l)
206  :_params(p),_sys(s),_log(l)
207 #if 0
208  ,_counter(0)
209 #endif
210  {}
211 
212 };
213 
214 }
215 }