105 #include "Vector/vector_dist.hpp"
106 #include "Plot/GoogleChart.hpp"
107 #include "Plot/util.hpp"
116 typedef float real_number;
118 constexpr
int velocity = 0;
119 constexpr
int force = 1;
120 constexpr
int energy = 2;
122 template<
typename vector_dist_type,
typename NN_type>
123 __global__
void calc_force_gpu(
vector_dist_type vd, NN_type NN, real_number sigma12, real_number sigma6, real_number r_cut2)
126 GET_PARTICLE_SORT(p,NN);
132 vd.template getProp<force>(p)[0] = 0.0;
133 vd.template getProp<force>(p)[1] = 0.0;
134 vd.template getProp<force>(p)[2] = 0.0;
142 auto Np = NN.getNNIteratorBox(NN.getCell(vd.
getPos(p)));
150 auto q = Np.get_sort();
155 if (q == p) {++Np;
continue;};
164 real_number rn = norm2(r);
170 Point<3,real_number> f = 24.0*(2.0 *sigma12 / (rn*rn*rn*rn*rn*rn*rn) - sigma6 / (rn*rn*rn*rn)) * r;
178 vd.template getProp<force>(p)[0] = force_.
get(0);
179 vd.template getProp<force>(p)[1] = force_.
get(1);
180 vd.template getProp<force>(p)[2] = force_.
get(2);
183 template<
typename vector_dist_type>
184 __global__
void update_velocity_position(
vector_dist_type vd, real_number dt)
186 auto p = GET_PARTICLE(vd);
189 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
190 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
191 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
194 vd.
getPos(p)[0] += vd.template getProp<velocity>(p)[0]*dt;
195 vd.
getPos(p)[1] += vd.template getProp<velocity>(p)[1]*dt;
196 vd.
getPos(p)[2] += vd.template getProp<velocity>(p)[2]*dt;
199 template<
typename vector_dist_type>
202 auto p = GET_PARTICLE(vd);
205 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
206 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
207 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
210 template<
typename vector_dist_type,
typename NN_type>
211 __global__
void particle_energy(
vector_dist_type vd, NN_type NN, real_number sigma12, real_number sigma6, real_number
shift, real_number r_cut2)
214 GET_PARTICLE_SORT(p,NN);
220 auto Np = NN.getNNIteratorBox(NN.getCell(vd.
getPos(p)));
228 auto q = Np.get_sort();
231 if (q == p) {++Np;
continue;};
237 real_number rn = norm2(xp - xq);
243 E += 2.0 * ( sigma12 / (rn*rn*rn*rn*rn*rn) - sigma6 / ( rn*rn*rn) ) -
shift;
250 vd.template getProp<energy>(p) = E + (vd.template getProp<velocity>(p)[0]*vd.template getProp<velocity>(p)[0] +
251 vd.template getProp<velocity>(p)[1]*vd.template getProp<velocity>(p)[1] +
252 vd.template getProp<velocity>(p)[2]*vd.template getProp<velocity>(p)[2]) / 2;
255 template<
typename CellList>
void calc_forces(
vector_dist_gpu<3,real_number,
aggregate<real_number[3],real_number[3],real_number> > & vd,
CellList & NN, real_number sigma12, real_number sigma6, real_number r_cut2)
258 auto it2 = vd.getDomainIteratorGPU();
264 vd.template updateCellListGPU<>(NN);
266 CUDA_LAUNCH(calc_force_gpu,it2,vd.toKernel(),NN.toKernel(),sigma12,sigma6,r_cut2);
269 vd.template restoreOrder<force>(NN);
272 template<
typename CellList> real_number calc_energy(
vector_dist_gpu<3,real_number,
aggregate<real_number[3],real_number[3],real_number> > & vd,
CellList & NN, real_number sigma12, real_number sigma6, real_number r_cut2)
274 real_number rc = r_cut2;
275 real_number
shift = 2.0 * ( sigma12 / (rc*rc*rc*rc*rc*rc) - sigma6 / ( rc*rc*rc) );
277 vd.template updateCellListGPU<velocity>(NN);
279 auto it2 = vd.getDomainIteratorGPU();
281 CUDA_LAUNCH(particle_energy,it2,vd.toKernel(),NN.toKernel(),sigma12,sigma6,
shift,r_cut2);
283 vd.template restoreOrder<energy>(NN);
286 return reduce_local<energy,_add_>(vd);
289 int main(
int argc,
char* argv[])
291 openfpm_init(&argc,&argv);
293 real_number sigma = 0.01;
294 real_number r_cut =3.0*sigma;
297 size_t sz[3] = {100,100,100};
303 size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
308 real_number dt = 0.00005;
309 real_number sigma12 = pow(sigma,12);
310 real_number sigma6 = pow(sigma,6);
330 vd.
getLastPos()[0] = key.get(0) * it.getSpacing(0);
331 vd.
getLastPos()[1] = key.get(1) * it.getSpacing(1);
332 vd.
getLastPos()[2] = key.get(2) * it.getSpacing(2);
335 vd.template getLastProp<velocity>()[0] = 0.0;
336 vd.template getLastProp<velocity>()[1] = 0.0;
337 vd.template getLastProp<velocity>()[2] = 0.0;
339 vd.template getLastProp<force>()[0] = 0.0;
340 vd.template getLastProp<force>()[1] = 0.0;
341 vd.template getLastProp<force>()[2] = 0.0;
349 vd.
map(RUN_ON_DEVICE);
360 auto NN = vd.getCellListGPU(r_cut / 2.0, CL_NON_SYMMETRIC | CL_GPU_REORDER, 2);
368 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
369 unsigned long int f = 0;
372 for (
size_t i = 0; i < nstep ; i++)
375 auto it3 = vd.getDomainIteratorGPU();
376 CUDA_LAUNCH(update_velocity_position,it3,vd.toKernel(),dt);
379 vd.
map(RUN_ON_DEVICE);
380 vd.template ghost_get<>(RUN_ON_DEVICE);
383 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
386 auto it4 = vd.getDomainIteratorGPU();
388 CUDA_LAUNCH(update_velocity,it4,vd.toKernel(),dt);
404 real_number energy = calc_energy(vd,NN,sigma12,sigma6,r_cut*r_cut);
405 auto & vcl = create_vcluster();
415 if (vcl.getProcessUnitID() == 0)
416 std::cout <<
"Energy: " << energy << std::endl;
423 std::cout <<
"Time: " << tsim.
getwct() << std::endl;
429 options.
title = std::string(
"Energy with time");
432 options.
yAxis = std::string(
"Energy");
435 options.
xAxis = std::string(
"iteration");
441 options.
width = 1280;
447 options.
more = GC_ZOOM;
457 cg.
write(
"gc_plot2_out.html");
464 int main(
int argc,
char* argv[])
Class for FAST cell list implementation.
Small class to produce graph with Google chart in HTML.
void write(std::string file)
It write the graphs on file in html format using Google charts.
void AddLinesGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, const GCoptions &opt)
Add a simple lines graph.
This class implement the point shape in an N-dimensional space.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Implementation of 1-D std::vector like structure.
Class for cpu time benchmarking.
void stop()
Stop the timer.
void start()
Start the timer.
double getwct()
Return the elapsed real time.
bool write_frame(std::string out, size_t iteration, int opt=VTK_WRITER)
Output particle position and properties.
void deviceToHostPos()
Move the memory from the device to host memory.
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const size_t(&sz)[dim])
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
void hostToDevicePos()
Move the memory from the device to host memory.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
void deviceToHostProp()
Move the memory from the device to host memory.
void add()
Add local particle.
void hostToDeviceProp()
Move the memory from the device to host memory.
void deleteGhost()
Delete the particles on the ghost.
auto getLastPos() -> decltype(vPos.template get< 0 >(0))
Get the position of the last element.
size_t width
width of the graph in pixels
size_t heigh
height of the graph in pixels
std::string xAxis
X axis name.
size_t lineWidth
Width of the line.
std::string title
Title of the chart.
std::string yAxis
Y axis name.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...