30 namespace swarm {
namespace gpu {
namespace bppt {
41 const static int nbod = T::n;
42 const static int pair_count = (nbod*(nbod-1))/2;
43 const static int CHUNK_SIZE = SHMEM_CHUNK_SIZE;
48 ensemble::SystemRef& sys;
53 GPUAPI
GravitationAcc(ensemble::SystemRef& sys,shared_data &shared):sys(sys),shared(shared){ }
57 GPUAPI
void calc_pair(
int ij)
const{
58 int i = first<nbod>( ij );
59 int j = second<nbod>( ij );
62 double dx[3] = { sys[j][0].pos()- sys[i][0].pos(),sys[j][1].pos()- sys[i][1].pos(), sys[j][2].pos()- sys[i][2].pos() };
63 double dv[3] = { sys[j][0].vel()- sys[i][0].vel(),sys[j][1].vel()- sys[i][1].vel(), sys[j][2].vel()- sys[i][2].vel() };
64 double r2 = dx[0]*dx[0]+dx[1]*dx[1]+dx[2]*dx[2];
65 double acc_mag = rsqrt(r2) / r2;
68 for(
int c = 0;
c < 3;
c ++)
70 shared[ij][
c].acc() = dx[
c]* acc_mag;
78 GPUAPI
double one_over_r(
const int b1,
const int b2)
const
82 for(
int d = 0; d < pair_count; d++)
84 int x = first<nbod>(d), y= second<nbod>(d);
85 if( ((x==b1) && (y==b2)) || (x==b2) && (y==b1))
87 sum += shared[d][0].acc()*shared[d][0].acc();
88 sum += shared[d][1].acc()*shared[d][1].acc();
89 sum += shared[d][2].acc()*shared[d][2].acc();
96 GPUAPI
double sum_acc_planets(
int b,
int c)
const{
101 for(
int d = 0; d < pair_count; d++){
102 int x = first<nbod>(d), y= second<nbod>(d);
106 acc_sum += shared[d][
c].acc() * sys[y].mass();
109 acc_sum -= shared[d][
c].acc() * sys[
x].mass();
116 GPUAPI
double sum_acc(
int b,
int c)
const{
117 double acc_from_planets = 0;
118 double acc_from_sun = 0;
122 for(
int d = 0; d < pair_count; d++){
123 int x = first<nbod>(d), y= second<nbod>(d);
127 acc_from_sun += shared[d][
c].acc() * sys[y].mass();
129 acc_from_planets += shared[d][
c].acc() * sys[y].mass();
132 acc_from_sun -= shared[d][
c].acc() * sys[
x].mass();
134 acc_from_planets -= shared[d][
c].acc() * sys[
x].mass();
138 return acc_from_sun + acc_from_planets;
143 GPUAPI
void operator() (
int ij,
int b,
int c,
double& pos,
double& vel,
double&
acc)
const{
145 if(b < nbod && c < 3)
146 sys[b][
c].pos() = pos , sys[b][
c].vel() = vel;
151 if(b < nbod && c < 3){
175 if(b < nbod && c < 3){
176 return sum_acc_planets(b,c);
193 GPUAPI
double acc (
int ij,
int b,
int c,
double& pos,
double& vel)
const{
195 if(b < nbod && c < 3)
196 sys[b][
c].pos() = pos , sys[b][
c].vel() = vel;
201 if(b < nbod && c < 3){
209 return ( 3*nbod > (nbod-1)*nbod/2 ) ? nbod*3 : (nbod-1)*nbod/2;
214 return sizeof(shared_data)/CHUNK_SIZE;