106#include "Vector/vector_dist.hpp"
107#include "Plot/GoogleChart.hpp"
108#include "Plot/util.hpp"
117typedef float real_number;
119constexpr int velocity = 0;
120constexpr int force = 1;
121constexpr int energy = 2;
123template<
typename vector_dist_type,
typename NN_type>
124__global__
void calc_force_gpu(vector_dist_type vd, NN_type NN, real_number sigma12, real_number sigma6, real_number r_cut2)
127 GET_PARTICLE_SORT(p,NN);
133 vd.template getProp<force>(p)[0] = 0.0;
134 vd.template getProp<force>(p)[1] = 0.0;
135 vd.template getProp<force>(p)[2] = 0.0;
143 auto Np = NN.getNNIteratorBox(NN.getCell(vd.getPos(p)));
151 auto q = Np.get_sort();
156 if (q == p) {++Np;
continue;};
165 real_number rn = norm2(r);
171 Point<3,real_number> f = 24.0*(2.0 *sigma12 / (rn*rn*rn*rn*rn*rn*rn) - sigma6 / (rn*rn*rn*rn)) * r;
179 vd.template getProp<force>(p)[0] = force_.
get(0);
180 vd.template getProp<force>(p)[1] = force_.
get(1);
181 vd.template getProp<force>(p)[2] = force_.
get(2);
184template<
typename vector_dist_type>
185__global__
void update_velocity_position(vector_dist_type vd, real_number dt)
187 auto p = GET_PARTICLE(vd);
190 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
191 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
192 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
195 vd.getPos(p)[0] += vd.template getProp<velocity>(p)[0]*dt;
196 vd.getPos(p)[1] += vd.template getProp<velocity>(p)[1]*dt;
197 vd.getPos(p)[2] += vd.template getProp<velocity>(p)[2]*dt;
200template<
typename vector_dist_type>
201__global__
void update_velocity(vector_dist_type vd, real_number dt)
203 auto p = GET_PARTICLE(vd);
206 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
207 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
208 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
211template<
typename vector_dist_type,
typename NN_type>
212__global__
void particle_energy(vector_dist_type vd, NN_type NN, real_number sigma12, real_number sigma6, real_number
shift, real_number r_cut2)
215 GET_PARTICLE_SORT(p,NN);
221 auto Np = NN.getNNIteratorBox(NN.getCell(vd.getPos(p)));
229 auto q = Np.get_sort();
232 if (q == p) {++Np;
continue;};
238 real_number rn = norm2(xp - xq);
244 E += 2.0 * ( sigma12 / (rn*rn*rn*rn*rn*rn) - sigma6 / ( rn*rn*rn) ) -
shift;
251 vd.template getProp<energy>(p) = E + (vd.template getProp<velocity>(p)[0]*vd.template getProp<velocity>(p)[0] +
252 vd.template getProp<velocity>(p)[1]*vd.template getProp<velocity>(p)[1] +
253 vd.template getProp<velocity>(p)[2]*vd.template getProp<velocity>(p)[2]) / 2;
256template<
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 vd.updateCellList(NN);
261 auto it2 = vd.getDomainIteratorGPU();
265 CUDA_LAUNCH(calc_force_gpu,it2,vd.toKernel_sorted(),NN.toKernel(),sigma12,sigma6,r_cut2);
271 vd.merge_sort<force>(NN);
276template<
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)
278 real_number rc = r_cut2;
279 real_number
shift = 2.0 * ( sigma12 / (rc*rc*rc*rc*rc*rc) - sigma6 / ( rc*rc*rc) );
281 vd.updateCellList(NN);
283 auto it2 = vd.getDomainIteratorGPU();
285 CUDA_LAUNCH(particle_energy,it2,vd.toKernel_sorted(),NN.toKernel(),sigma12,sigma6,
shift,r_cut2);
287 vd.merge_sort<energy>(NN);
290 return reduce_local<energy,_add_>(vd);
293int main(
int argc,
char* argv[])
295 openfpm_init(&argc,&argv);
297 real_number sigma = 0.01;
298 real_number r_cut =3.0*sigma;
301 size_t sz[3] = {100,100,100};
307 size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
312 real_number dt = 0.00005;
313 real_number sigma12 = pow(sigma,12);
314 real_number sigma6 = pow(sigma,6);
322 auto it = vd.getGridIterator(sz);
334 vd.getLastPos()[0] = key.get(0) * it.getSpacing(0);
335 vd.getLastPos()[1] = key.get(1) * it.getSpacing(1);
336 vd.getLastPos()[2] = key.get(2) * it.getSpacing(2);
339 vd.template getLastProp<velocity>()[0] = 0.0;
340 vd.template getLastProp<velocity>()[1] = 0.0;
341 vd.template getLastProp<velocity>()[2] = 0.0;
343 vd.template getLastProp<force>()[0] = 0.0;
344 vd.template getLastProp<force>()[1] = 0.0;
345 vd.template getLastProp<force>()[2] = 0.0;
350 vd.hostToDevicePos();
351 vd.hostToDeviceProp<velocity,force>();
353 vd.map(RUN_ON_DEVICE);
354 vd.ghost_get<>(RUN_ON_DEVICE);
364 auto NN = vd.getCellListGPU(r_cut / 2.0);
372 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
373 unsigned long int f = 0;
376 for (
size_t i = 0; i < nstep ; i++)
379 auto it3 = vd.getDomainIteratorGPU();
381 CUDA_LAUNCH(update_velocity_position,it3,vd.toKernel(),dt);
384 vd.map(RUN_ON_DEVICE);
385 vd.template ghost_get<>(RUN_ON_DEVICE);
388 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
391 auto it4 = vd.getDomainIteratorGPU();
393 CUDA_LAUNCH(update_velocity,it4,vd.toKernel(),dt);
398 vd.deviceToHostPos();
399 vd.deviceToHostProp<0,1,2>();
403 vd.write_frame(
"particles_",f);
406 vd.ghost_get<>(RUN_ON_DEVICE);
409 real_number energy = calc_energy(vd,NN,sigma12,sigma6,r_cut*r_cut);
410 auto & vcl = create_vcluster();
420 if (vcl.getProcessUnitID() == 0)
421 std::cout <<
"Energy: " << energy << std::endl;
428 std::cout <<
"Time: " << tsim.
getwct() << std::endl;
434 options.
title = std::string(
"Energy with time");
437 options.
yAxis = std::string(
"Energy");
440 options.
xAxis = std::string(
"iteration");
446 options.
width = 1280;
452 options.
more = GC_ZOOM;
462 cg.
write(
"gc_plot2_out.html");
469int main(
int argc,
char* argv[])
This class represent an N-dimensional box.
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.
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...