27 namespace swarm {
namespace gpu {
namespace bppt {
34 double max_timestep, max_timestep_global, timestep_scale;
37 max_timestep_global = cfg.
require(
"max_timestep", 0.0);
38 timestep_scale = cfg.
require(
"timestep_scale", 0.0);
50 template<
class T,
class Gravitation>
53 const static int nbod = T::n;
57 ensemble::SystemRef& sys;
58 Gravitation& calcForces;
62 bool body_component_grid;
63 bool first_thread_in_system;
64 double max_timestep, timestep;
69 :_params(p),sys(s),calcForces(calc){}
71 static GENERIC int thread_per_system(){
75 static GENERIC int shmem_per_system() {
84 if( is_in_body_component_grid() )
86 double pos = sys[b][c].pos() , vel = sys[b][c].vel();
87 double acc = calcForces.acc(ij,b,c,pos,vel);
90 max_timestep = _params.max_timestep_global;
93 GPUAPI
void shutdown() { }
95 GPUAPI
void convert_internal_to_std_coord() {}
96 GPUAPI
void convert_std_to_internal_coord() {}
98 __device__
bool is_in_body_component_grid()
100 {
return ((b < T::n) && (c < 3)); }
102 __device__
bool is_in_body_component_grid_no_star()
104 {
return ( (b!=0) && (b < T::n) && (c < 3) ); }
106 __device__
bool is_first_thread_in_system()
118 for(
int i=0;i<nbod;++i)
120 double mi = sys[i].mass();
122 for(
int j=1;j<nbod;++j)
124 if(i==j) {
continue; }
125 double mj = sys[j].mass();
126 double oor = calcForces.one_over_r(i,j);
127 factor += (mi+mj)*oor*oor*oor;
130 factor *= _params.timestep_scale*_params.timestep_scale;
132 factor = rsqrt(factor);
133 factor *= _params.max_timestep_global;
140 double pos = 0.0, vel = 0.0;
142 if( is_in_body_component_grid() )
143 pos = sys[b][c].pos() , vel = sys[b][c].vel();
147 double h_first_half = 0.5 * h;
150 pos = pos + h_first_half * vel;
153 double acc = calcForces.acc(ij,b,c,pos,vel);
156 vel = vel + h_first_half * acc;
162 double h_second_half = 0.5*timestep;
165 vel = vel + h_second_half * acc;
166 pos = pos + h_second_half * vel;
171 if( is_in_body_component_grid() )
172 sys[b][c].pos() = pos , sys[b][c].vel() = vel;
173 if( is_first_thread_in_system() )
174 sys.time() += h_first_half + h_second_half;