31 #include <thrust/device_vector.h>
32 #include <thrust/sort.h>
39 #if __CUDA_ARCH__ >= 200
47 struct log_rvs_params {
51 thrust::device_ptr<double> rv_times_dev;
53 __host__ log_rvs_params(
const config &cfg)
58 tol = cfg.optional(
"log_rvs_tol", 2.e-8);
60 nbod = cfg.require<
int>(
"nbod");
61 dt = cfg.require(
"time_step", 0.0);
65 filename = cfg.optional(
"rv_filename",std::string(
"rv.in"));
66 std::ifstream rv_file(filename.c_str());
69 std::cerr <<
"# Can't open >" << rv_file <<
"<.\n";
73 thrust::host_vector<double> rv_times_host;
77 std::getline(rv_file,line);
78 if(rv_file.eof())
continue;
79 std::stringstream line_stream(line);
82 try { rv_times_host.push_back(time); }
83 catch(thrust::system_error e)
84 { std::cerr <<
"Error push_back: " << e.what() << std::endl; }
87 std::cerr <<
"# Read " << rv_times_host.size() <<
" RV observation times from " << filename <<
"\n";
90 { thrust::sort(rv_times_host.begin(),rv_times_host.end()); }
91 catch(thrust::system_error e)
92 { std::cerr <<
"Error sort: " << e.what() << std::endl; }
97 num_times = rv_times_host.size();
98 rv_times_dev = thrust::device_malloc<double>(num_times);
100 catch(thrust::system_error e)
101 { std::cerr <<
"Error: device_malloc: " << e.what() << std::endl; }
109 thrust::copy(rv_times_host.begin(),rv_times_host.end(),rv_times_dev);
111 catch(thrust::system_error e)
112 { std::cerr <<
"Error copy: " << e.what() << std::endl; }
121 __host__
void deallocate_device_data()
123 thrust::device_free(rv_times_dev);
148 template<
class log_t>
151 typedef log_rvs_params params;
157 ensemble::SystemRef& _sys;
163 static GENERIC int thread_per_system(T compile_time_param){
168 static GENERIC int shmem_per_system(T compile_time_param) {
171 GPUAPI
bool is_deactivate_on() {
return false; };
172 GPUAPI
bool is_log_on() {
return _params.tol!=0.; };
173 GPUAPI
bool is_verbose_on() {
return false; };
174 GPUAPI
bool is_any_on() {
return is_deactivate_on() || is_log_on() || is_verbose_on() ; }
175 GPUAPI
bool is_condition_met () {
return ( condition_met ); }
176 GPUAPI
bool need_to_log_system ()
177 {
return (is_log_on() && is_condition_met() ); }
178 GPUAPI
bool need_to_deactivate ()
179 {
return ( is_deactivate_on() && is_condition_met() ); }
181 GPUAPI
void log_system() {
log::system(_log, _sys); }
185 if(pass_one(thread_in_system))
186 pass_two(thread_in_system);
189 GPUAPI
bool pass_one (
const int thread_in_system)
191 condition_met =
false;
192 double t = _sys.time();
193 if(_params.next_time_idx>=_params.num_times)
return false;
194 while(_params.rv_times_dev[_params.next_time_idx]<t)
196 _params.next_time_idx++;
197 if(_params.next_time_idx>=_params.num_times)
return false;
199 double log_time = _params.rv_times_dev[_params.next_time_idx];
200 if( (log_time>=t) && (log_time<t+_params.dt) )
208 GPUAPI
double calc_star_vz(
const int& thread_in_system,
const double& dt)
210 extern __shared__
char shared_mem[];
213 typedef typename calcForces_t::shared_data grav_t;
217 #if USING_INTEGRATOR_THAT_OVER_WRITES_SHARED_DATA || 1
220 double pos = _sys[bid][cid].pos(), vel = _sys[bid][cid].vel();
222 calcForces(thread_in_system,bid,cid,pos,vel,acc,jerk);
225 if(thread_in_system < calcForces_t::pair_count)
226 calcForces.calc_pair(thread_in_system);
230 if(thread_in_system==0)
233 calcForces.sum(0,2,acc,jerk);
234 double star_vz = _sys[0][2].vel()+dt*(acc+0.5*dt*jerk);
243 GPUAPI
int pass_two (
const int thread_in_system)
247 double t_log = _params.rv_times_dev[_params.next_time_idx];
248 double dt = t_log-_sys.time();
249 const int nbod = _params.nbod;
251 if((nbod==3) && (nbod<MAX_NBODIES))
254 else if((nbod==4) && (nbod<MAX_NBODIES))
256 else if((nbod==5) && (nbod<MAX_NBODIES))
258 else if((nbod==6) && (nbod<MAX_NBODIES))
260 else if((nbod==7) && (nbod<MAX_NBODIES))
262 else if((nbod==8) && (nbod<MAX_NBODIES))
265 if(thread_in_system==0)
269 _params.next_time_idx++;
270 condition_met =
true;
272 return condition_met;
276 GPUAPI log_rvs(
const params& p,ensemble::SystemRef& s,log_t& l)
277 :_params(p),_sys(s),_log(l) {}