75 #include "Vector/vector_dist.hpp"
76 #include "Plot/GoogleChart.hpp"
77 #include "Plot/util.hpp"
86 typedef float real_number;
90 constexpr
int velocity = 0;
91 constexpr
int force = 1;
92 constexpr
int energy = 2;
96 template<
typename vector_dist_type,
typename NN_type>
97 __global__
void calc_force_gpu(
vector_dist_type vd, NN_type NN, real_number sigma12, real_number sigma6, real_number r_cut2)
99 auto p = GET_PARTICLE(vd);
105 vd.template getProp<force>(p)[0] = 0.0;
106 vd.template getProp<force>(p)[1] = 0.0;
107 vd.template getProp<force>(p)[2] = 0.0;
112 auto Np = NN.getNNIteratorBox(NN.getCell(vd.
getPos(p)));
121 if (q == p) {++Np;
continue;};
130 real_number rn = norm2(r);
136 Point<3,real_number> f = 24.0*(2.0 *sigma12 / (rn*rn*rn*rn*rn*rn*rn) - sigma6 / (rn*rn*rn*rn)) * r;
139 vd.template getProp<force>(p)[0] += f.get(0);
140 vd.template getProp<force>(p)[1] += f.get(1);
141 vd.template getProp<force>(p)[2] += f.get(2);
150 template<
typename vector_dist_type>
151 __global__
void update_velocity_position(
vector_dist_type vd, real_number dt)
153 auto p = GET_PARTICLE(vd);
156 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
157 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
158 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
161 vd.
getPos(p)[0] += vd.template getProp<velocity>(p)[0]*dt;
162 vd.
getPos(p)[1] += vd.template getProp<velocity>(p)[1]*dt;
163 vd.
getPos(p)[2] += vd.template getProp<velocity>(p)[2]*dt;
166 template<
typename vector_dist_type>
169 auto p = GET_PARTICLE(vd);
172 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
173 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
174 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
181 template<
typename vector_dist_type,
typename NN_type>
182 __global__
void particle_energy(
vector_dist_type vd, NN_type NN, real_number sigma12, real_number sigma6, real_number
shift, real_number r_cut2)
184 auto p = GET_PARTICLE(vd);
190 auto Np = NN.getNNIteratorBox(NN.getCell(vd.
getPos(p)));
201 if (q == p) {++Np;
continue;};
207 real_number rn = norm2(xp - xq);
213 E += 2.0 * ( sigma12 / (rn*rn*rn*rn*rn*rn) - sigma6 / ( rn*rn*rn) ) -
shift;
220 vd.template getProp<energy>(p) = E + (vd.template getProp<velocity>(p)[0]*vd.template getProp<velocity>(p)[0] +
221 vd.template getProp<velocity>(p)[1]*vd.template getProp<velocity>(p)[1] +
222 vd.template getProp<velocity>(p)[2]*vd.template getProp<velocity>(p)[2]) / 2;
229 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)
231 vd.updateCellListGPU(NN);
234 auto it2 = vd.getDomainIteratorGPU();
236 CUDA_LAUNCH(calc_force_gpu,it2,vd.toKernel(),NN.toKernel(),sigma12,sigma6,r_cut2);
241 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)
243 real_number rc = r_cut2;
244 real_number
shift = 2.0 * ( sigma12 / (rc*rc*rc*rc*rc*rc) - sigma6 / ( rc*rc*rc) );
246 vd.updateCellListGPU(NN);
248 auto it2 = vd.getDomainIteratorGPU();
250 CUDA_LAUNCH(particle_energy,it2,vd.toKernel(),NN.toKernel(),sigma12,sigma6,
shift,r_cut2);
255 return reduce_local<energy,_add_>(vd);
260 int main(
int argc,
char* argv[])
262 openfpm_init(&argc,&argv);
264 real_number sigma = 0.01;
265 real_number r_cut = 3.0*sigma;
268 size_t sz[3] = {100,100,100};
274 size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
279 real_number dt = 0.00005;
280 real_number sigma12 = pow(sigma,12);
281 real_number sigma6 = pow(sigma,6);
301 vd.
getLastPos()[0] = key.get(0) * it.getSpacing(0);
302 vd.
getLastPos()[1] = key.get(1) * it.getSpacing(1);
303 vd.
getLastPos()[2] = key.get(2) * it.getSpacing(2);
306 vd.template getLastProp<velocity>()[0] = 0.0;
307 vd.template getLastProp<velocity>()[1] = 0.0;
308 vd.template getLastProp<velocity>()[2] = 0.0;
310 vd.template getLastProp<force>()[0] = 0.0;
311 vd.template getLastProp<force>()[1] = 0.0;
312 vd.template getLastProp<force>()[2] = 0.0;
320 vd.
map(RUN_ON_DEVICE);
329 auto NN = vd.getCellListGPU(r_cut, CL_NON_SYMMETRIC, 2);
335 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
336 unsigned long int f = 0;
339 for (
size_t i = 0; i < nstep ; i++)
342 auto it3 = vd.getDomainIteratorGPU();
344 CUDA_LAUNCH(update_velocity_position,it3,vd.toKernel(),dt);
349 vd.
map(RUN_ON_DEVICE);
350 vd.template ghost_get<>(RUN_ON_DEVICE);
355 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
359 auto it4 = vd.getDomainIteratorGPU();
361 CUDA_LAUNCH(update_velocity,it4,vd.toKernel(),dt);
381 real_number energy = calc_energy(vd,NN,sigma12,sigma6,r_cut*r_cut);
382 auto & vcl = create_vcluster();
392 if (vcl.getProcessUnitID() == 0)
393 std::cout <<
"Energy: " << energy << std::endl;
402 std::cout <<
"Time: " << tsim.
getwct() << std::endl;
408 options.
title = std::string(
"Energy with time");
411 options.
yAxis = std::string(
"Energy");
414 options.
xAxis = std::string(
"iteration");
420 options.
width = 1280;
426 options.
more = GC_ZOOM;
436 cg.
write(
"gc_plot2_out.html");
443 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.
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...