OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
main_vl.cpp
1 
2 #include "Vector/vector_dist.hpp"
3 #include "Decomposition/CartDecomposition.hpp"
4 #include "data_type/aggregate.hpp"
5 #include "Plot/GoogleChart.hpp"
6 #include "Plot/util.hpp"
7 #include "timer.hpp"
8 
28 
30 constexpr int velocity = 0;
31 constexpr int force = 1;
32 
34 
61 
64 
65 void calc_forces(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, VerletList<3, double, Mem_fast<>, shift<3, double> > & NN, double sigma12, double sigma6, double r_cut)
66 {
68 
69  // Get an iterator over particles
70  auto it2 = vd.getDomainIterator();
71 
72  // For each particle p ...
73  while (it2.isNext())
74  {
75  // ... get the particle p
76  auto p = it2.get();
77 
78  // Get the position xp of the particle
79  Point<3,double> xp = vd.getPos(p);
80 
81  // Reset the forice counter
82  vd.template getProp<force>(p)[0] = 0.0;
83  vd.template getProp<force>(p)[1] = 0.0;
84  vd.template getProp<force>(p)[2] = 0.0;
85 
87 
88  // Get an iterator over the neighborhood particles of p
89  auto Np = NN.template getNNIterator<NO_CHECK>(p.getKey());
90 
92 
93  // For each neighborhood particle ...
94  while (Np.isNext())
95  {
96  // ... q
97  auto q = Np.get();
98 
99  // if (p == q) skip this particle
100  if (q == p.getKey()) {++Np; continue;};
101 
102  // Get the position of p
103  Point<3,double> xq = vd.getPos(q);
104 
105  // Get the distance between p and q
106  Point<3,double> r = xp - xq;
107 
108  // take the norm of this vector
109  double rn = norm2(r);
110 
111  if (rn > r_cut * r_cut) {++Np;continue;}
112 
113  // Calculate the force, using pow is slower
114  Point<3,double> f = 24.0*(2.0 *sigma12 / (rn*rn*rn*rn*rn*rn*rn) - sigma6 / (rn*rn*rn*rn)) * r;
115 
116  // we sum the force produced by q on p
117  vd.template getProp<force>(p)[0] += f.get(0);
118  vd.template getProp<force>(p)[1] += f.get(1);
119  vd.template getProp<force>(p)[2] += f.get(2);
120 
121  // Next neighborhood
122  ++Np;
123  }
124 
125  // Next particle
126  ++it2;
127  }
128 }
129 
131 
151 
153 double calc_energy(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, VerletList<3, double, Mem_fast<>, shift<3, double> > & NN, double sigma12, double sigma6, double r_cut)
154 {
155  double E = 0.0;
156 
157  double rc = r_cut*r_cut;
158  double shift = 2.0 * ( sigma12 / (rc*rc*rc*rc*rc*rc) - sigma6 / ( rc*rc*rc) );
159 
160  // Get the iterator
161  auto it2 = vd.getDomainIterator();
162 
163  // For each particle ...
164  while (it2.isNext())
165  {
166  // ... p
167  auto p = it2.get();
168 
169  // Get the position of the particle p
170  Point<3,double> xp = vd.getPos(p);
171 
172  // Get an iterator over the neighborhood of the particle p
173  auto Np = NN.template getNNIterator<NO_CHECK>(p.getKey());
174 
175  // For each neighborhood of the particle p
176  while (Np.isNext())
177  {
178  // Neighborhood particle q
179  auto q = Np.get();
180 
181  // if p == q skip this particle
182  if (q == p.getKey()) {++Np; continue;};
183 
184  // Get position of the particle q
185  Point<3,double> xq = vd.getPos(q);
186 
187  // take the normalized direction
188  double rn = norm2(xp - xq);
189 
190  if (rn >= r_cut*r_cut)
191  {++Np;continue;}
192 
193  // potential energy (using pow is slower)
194  E += 2.0 * ( sigma12 / (rn*rn*rn*rn*rn*rn) - sigma6 / ( rn*rn*rn) ) - shift;
195 
196  // Next neighborhood
197  ++Np;
198  }
199 
200  // Kinetic energy of the particle given by its actual speed
201  E += (vd.template getProp<velocity>(p)[0]*vd.template getProp<velocity>(p)[0] +
202  vd.template getProp<velocity>(p)[1]*vd.template getProp<velocity>(p)[1] +
203  vd.template getProp<velocity>(p)[2]*vd.template getProp<velocity>(p)[2]) / 2;
204 
205  // Next Particle
206  ++it2;
207  }
208 
209  // Calculated energy
210  return E;
211 }
212 
214 
215 int main(int argc, char* argv[])
216 {
262 
264  double dt = 0.00025;
265  double sigma = 0.1;
266  double r_cut = 3.0*sigma;
267  double r_gskin = 1.3*r_cut;
268  double sigma12 = pow(sigma,12);
269  double sigma6 = pow(sigma,6);
270 
273 
274  openfpm_init(&argc,&argv);
275  Vcluster & v_cl = create_vcluster();
276 
277  // we will use it do place particles on a 10x10x10 Grid like
278  size_t sz[3] = {10,10,10};
279 
280  // domain
281  Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
282 
283  // Boundary conditions
284  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
285 
286  // ghost, big enough to contain the interaction radius
287  Ghost<3,float> ghost(r_gskin);
288 
290 
291  auto it = vd.getGridIterator(sz);
292 
293  while (it.isNext())
294  {
295  vd.add();
296 
297  auto key = it.get();
298 
299  vd.getLastPos()[0] = key.get(0) * it.getSpacing(0);
300  vd.getLastPos()[1] = key.get(1) * it.getSpacing(1);
301  vd.getLastPos()[2] = key.get(2) * it.getSpacing(2);
302 
303  vd.template getLastProp<velocity>()[0] = 0.0;
304  vd.template getLastProp<velocity>()[1] = 0.0;
305  vd.template getLastProp<velocity>()[2] = 0.0;
306 
307  vd.template getLastProp<force>()[0] = 0.0;
308  vd.template getLastProp<force>()[1] = 0.0;
309  vd.template getLastProp<force>()[2] = 0.0;
310 
311  ++it;
312  }
313 
314  timer tsim;
315  tsim.start();
316 
318 
319  // Get the Cell list structure
320  auto NN = vd.getVerlet(r_gskin);
321 
323 
324  // calculate forces
325  calc_forces(vd,NN,sigma12,sigma6,r_cut);
326  unsigned long int f = 0;
327 
328  int cnt = 0;
329  double max_disp = 0.0;
330 
331  // MD time stepping
332  for (size_t i = 0; i < 10000 ; i++)
333  {
334  // Get the iterator
335  auto it3 = vd.getDomainIterator();
336 
337  double max_displ = 0.0;
338 
339  // integrate velicity and space based on the calculated forces (Step1)
340  while (it3.isNext())
341  {
342  auto p = it3.get();
343 
344  // here we calculate v(tn + 0.5)
345  vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
346  vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
347  vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
348 
349  Point<3,double> disp({vd.template getProp<velocity>(p)[0]*dt,vd.template getProp<velocity>(p)[1]*dt,vd.template getProp<velocity>(p)[2]*dt});
350 
351  // here we calculate x(tn + 1)
352  vd.getPos(p)[0] += disp.get(0);
353  vd.getPos(p)[1] += disp.get(1);
354  vd.getPos(p)[2] += disp.get(2);
355 
356  if (disp.norm() > max_displ)
357  max_displ = disp.norm();
358 
359  ++it3;
360  }
361 
362  if (max_disp < max_displ)
363  max_disp = max_displ;
364 
366 
367  // Because we moved the particles in space we have to map them and re-sync the ghost
368  if (cnt % 10 == 0)
369  {
370  vd.map();
371  vd.template ghost_get<>();
372  // Get the Cell list structure
373  vd.updateVerlet(NN,r_gskin);
374  }
375  else
376  {
377  vd.template ghost_get<>(SKIP_LABELLING);
378  }
379 
381 
382  cnt++;
383 
384  // calculate forces or a(tn + 1) Step 2
385  calc_forces(vd,NN,sigma12,sigma6,r_cut);
386 
387  // Integrate the velocity Step 3
388  auto it4 = vd.getDomainIterator();
389 
390  while (it4.isNext())
391  {
392  auto p = it4.get();
393 
394  // here we calculate v(tn + 1)
395  vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
396  vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
397  vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
398 
399  ++it4;
400  }
401 
402  // After every iteration collect some statistic about the confoguration
403  if (i % 100 == 0)
404  {
405  // We write the particle position for visualization (Without ghost)
406  vd.deleteGhost();
407  vd.write("particles_",f);
408 
409  // we resync the ghost
410  vd.ghost_get<>(SKIP_LABELLING);
411 
412  // We calculate the energy
413  double energy = calc_energy(vd,NN,sigma12,sigma6,r_cut);
414  auto & vcl = create_vcluster();
415  vcl.sum(energy);
416  vcl.max(max_disp);
417  vcl.execute();
418 
419  // we save the energy calculated at time step i c contain the time-step y contain the energy
420  x.add(i);
421  y.add({energy});
422 
423  // We also print on terminal the value of the energy
424  // only one processor (master) write on terminal
425  if (vcl.getProcessUnitID() == 0)
426  std::cout << "Energy: " << energy << " " << max_disp << " " << std::endl;
427 
428  max_disp = 0.0;
429 
430  f++;
431  }
432  }
433 
434  tsim.stop();
435  std::cout << "Time: " << tsim.getwct() << std::endl;
436 
438 
439  // Google charts options, it store the options to draw the X Y graph
440  GCoptions options;
441 
442  // Title of the graph
443  options.title = std::string("Energy with time");
444 
445  // Y axis name
446  options.yAxis = std::string("Energy");
447 
448  // X axis name
449  options.xAxis = std::string("iteration");
450 
451  // width of the line
452  options.lineWidth = 1.0;
453 
454  // Object that draw the X Y graph
455  GoogleChart cg;
456 
457  // Add the graph
458  // The graph that it produce is in svg format that can be opened on browser
459  cg.AddLinesGraph(x,y,options);
460 
461  // Write into html format
462  cg.write("gc_plot2_out.html");
463 
465 
477 
479  openfpm_finalize();
480 
482 }
void AddLinesGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, const GCoptions &opt)
Add a simple lines graph.
Class for Verlet list implementation.
std::string title
Title of the chart.
Definition: GoogleChart.hpp:27
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
double getwct()
Return the elapsed real time.
Definition: timer.hpp:108
Definition: Ghost.hpp:39
Implementation of VCluster class.
Definition: VCluster.hpp:36
std::string yAxis
Y axis name.
Definition: GoogleChart.hpp:29
Small class to produce graph with Google chart in HTML.
void start()
Start the timer.
Definition: timer.hpp:73
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
size_t lineWidth
Width of the line.
Definition: GoogleChart.hpp:55
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
void write(std::string file)
It write the graphs on file in html format using Google charts.
Distributed vector.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:81
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
std::string xAxis
X axis name.
Definition: GoogleChart.hpp:31
Google chart options.
Definition: GoogleChart.hpp:24
Class for cpu time benchmarking.
Definition: timer.hpp:25
void stop()
Stop the timer.
Definition: timer.hpp:97