Swarm-NG  1.1
hermite_propagator.hpp
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2011 by Saleh Dindar 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 
26 #include "swarm/swarmplugin.h"
27 
28 namespace swarm {
29 
30 namespace gpu {
31 namespace bppt {
32 
38  double time_step;
41  time_step = cfg.require("time_step", 0.0);
42  }
43 };
44 
53 template<class T,class Gravitation>
56  const static int nbod = T::n;
57 
58  params _params;
59 
61  ensemble::SystemRef& sys;
62  Gravitation& calcForces;
63  int b;
64  int c;
65  int ij;
66  double acc0, jerk0;
67  bool body_component_grid;
68  bool first_thread_in_system;
69  double max_timestep;
70 
72  GPUAPI HermitePropagator(const params& p,ensemble::SystemRef& s,
73  Gravitation& calc)
74  :_params(p),sys(s),calcForces(calc){}
75 
77  GPUAPI void init() {
78  double pos,vel;
79  if( is_in_body_component_grid() )
80  pos = sys[b][c].pos() , vel = sys[b][c].vel();
81  calcForces(ij,b,c,pos,vel,acc0,jerk0);
82  }
83 
84  GPUAPI void shutdown() { }
85 
88  GPUAPI void convert_std_to_internal_coord() {}
89 
90  static GENERIC int thread_per_system(){
91  return nbod * 3;
92  }
93 
94  static GENERIC int shmem_per_system() {
95  return 0;
96  }
97 
98  __device__ bool is_in_body_component_grid()
99  { return ((b < nbod) && (c < 3)); }
100 
101  __device__ bool is_in_body_component_grid_no_star()
102  { return ( (b!=0) && (b < nbod) && (c < 3) ); }
103 
104  __device__ bool is_first_thread_in_system()
105  { return (thread_in_system()==0); }
106 
108  GPUAPI void advance(){
109  double h = min(_params.time_step, max_timestep);
110  double pos = 0.0, vel = 0.0;
111  double acc = 0.0, jerk = 0.0;
112  const double third = 1.0/3.0;
113 
114  if( is_in_body_component_grid() )
115  pos = sys[b][c].pos() , vel = sys[b][c].vel();
116 
117 
119  pos = pos + h*(vel+(h*0.5)*(acc0+(h/3.0)*jerk0));
120  vel = vel + h*(acc0+(h*0.5)*jerk0);
121 
122  double pre_pos = pos, pre_vel = vel;
123 
124  double acc1,jerk1;
125 #pragma unroll
126  for(int i = 0; i < 2 ; i++){
128  calcForces(ij,b,c,pos,vel,acc1,jerk1);
129 
131  pos = pre_pos + ( (0.1-0.25) * (acc0 - acc1) - 1.0/60.0 * ( 7.0 * jerk0 + 2.0 * jerk1 ) * h) * h * h;
132  vel = pre_vel + (( -0.5 ) * (acc0 - acc1 ) - 1.0/12.0 * ( 5.0 * jerk0 + jerk1 ) * h )* h ;
133  }
134  acc0 = acc1, jerk0 = jerk1;
135 
136 
138  if( is_in_body_component_grid() )
139  sys[b][c].pos() = pos , sys[b][c].vel() = vel;
140  if( is_first_thread_in_system() )
141  sys.time() += h;
142  }
143 };
144 
145 }
146 }
147 }
148