OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
main.cpp
1 
8 #include "Vector/vector_dist.hpp"
9 #include "Plot/GoogleChart.hpp"
10 #include "Plot/util.hpp"
11 #include "timer.hpp"
12 
33 
35 constexpr int velocity = 0;
36 constexpr int force = 1;
37 
39 
57 
59 template<typename CellList> void calc_forces(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, CellList & NN, double sigma12, double sigma6, double r_cut2)
60 {
61 
63 
77 
79  vd.updateCellList(NN);
80 
82 
98 
100  // Get an iterator over particles
101  auto it2 = vd.getDomainIterator();
102 
103  // For each particle p ...
104  while (it2.isNext())
105  {
106  // ... get the particle p
107  auto p = it2.get();
108 
109  // Get the position xp of the particle
110  Point<3,double> xp = vd.getPos(p);
111 
112  // Reset the force counter
113  vd.template getProp<force>(p)[0] = 0.0;
114  vd.template getProp<force>(p)[1] = 0.0;
115  vd.template getProp<force>(p)[2] = 0.0;
116 
117  // Get an iterator over the neighborhood particles of p
118  auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
119 
120  // For each neighborhood particle ...
121  while (Np.isNext())
122  {
123  // ... q
124  auto q = Np.get();
125 
126  // if (p == q) skip this particle
127  if (q == p.getKey()) {++Np; continue;};
128 
129  // Get the position of p
130  Point<3,double> xq = vd.getPos(q);
131 
132  // Get the distance between p and q
133  Point<3,double> r = xp - xq;
134 
135  // take the norm of this vector
136  double rn = norm2(r);
137 
138  if (rn > r_cut2)
139  {++Np; continue;};
140 
141  // Calculate the force, using pow is slower
142  Point<3,double> f = 24.0*(2.0 *sigma12 / (rn*rn*rn*rn*rn*rn*rn) - sigma6 / (rn*rn*rn*rn)) * r;
143 
144  // we sum the force produced by q on p
145  vd.template getProp<force>(p)[0] += f.get(0);
146  vd.template getProp<force>(p)[1] += f.get(1);
147  vd.template getProp<force>(p)[2] += f.get(2);
148 
149  // Next neighborhood
150  ++Np;
151  }
152 
153  // Next particle
154  ++it2;
155  }
156 
158 
160 
161 }
162 
164 
177 
179 template<typename CellList> double calc_energy(vector_dist<3,double, aggregate<double[3],double[3]> > & vd, CellList & NN, double sigma12, double sigma6, double r_cut2)
180 {
181  double rc = r_cut2;
182  double shift = 2.0 * ( sigma12 / (rc*rc*rc*rc*rc*rc) - sigma6 / ( rc*rc*rc) );
183 
185 
198 
200  double E = 0.0;
201 // vd.updateCellList(NN);
202 
204 
220 
222  // Get the iterator
223  auto it2 = vd.getDomainIterator();
224 
225  // For each particle ...
226  while (it2.isNext())
227  {
228  // ... p
229  auto p = it2.get();
230 
231  // Get the position of the particle p
232  Point<3,double> xp = vd.getPos(p);
233 
234  // Get an iterator over the neighborhood of the particle p
235  auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
236 
237  // For each neighborhood of the particle p
238  while (Np.isNext())
239  {
240  // Neighborhood particle q
241  auto q = Np.get();
242 
243  // if p == q skip this particle
244  if (q == p.getKey()) {++Np; continue;};
245 
246  // Get position of the particle q
247  Point<3,double> xq = vd.getPos(q);
248 
249  // take the normalized direction
250  double rn = norm2(xp - xq);
251 
252  if (rn > r_cut2)
253  {++Np;continue;}
254 
255  // potential energy (using pow is slower)
256  E += 2.0 * ( sigma12 / (rn*rn*rn*rn*rn*rn) - sigma6 / ( rn*rn*rn) ) - shift;
257 
258  // Next neighborhood
259  ++Np;
260  }
261 
262  // Kinetic energy of the particle given by its actual speed
263  E += (vd.template getProp<velocity>(p)[0]*vd.template getProp<velocity>(p)[0] +
264  vd.template getProp<velocity>(p)[1]*vd.template getProp<velocity>(p)[1] +
265  vd.template getProp<velocity>(p)[2]*vd.template getProp<velocity>(p)[2]) / 2;
266 
267  // Next Particle
268  ++it2;
269  }
270 
272 
274 
275  // Calculated energy
276  return E;
277 }
278 
280 
281 int main(int argc, char* argv[])
282 {
300 
302  openfpm_init(&argc,&argv);
303 
304  double sigma = 0.1;
305  double r_cut = 3.0*sigma;
306 
307  // we will use it do place particles on a 10x10x10 Grid like
308  size_t sz[3] = {10,10,10};
309 
310  // domain
311  Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
312 
313  // Boundary conditions
314  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
315 
316  // ghost, big enough to contain the interaction radius
317  Ghost<3,float> ghost(r_cut);
318 
319  double dt = 0.0005;
320  double sigma12 = pow(sigma,12);
321  double sigma6 = pow(sigma,6);
322 
325 
327 
340 
343 
345 
360 
362  // We create the grid iterator
363  auto it = vd.getGridIterator(sz);
364 
365  while (it.isNext())
366  {
367  // Create a new particle
368  vd.add();
369 
370  // key contain (i,j,k) index of the grid
371  auto key = it.get();
372 
373  // The index of the grid can be accessed with key.get(0) == i, key.get(1) == j ...
374  // We use getLastPos to set the position of the last particle added
375  vd.getLastPos()[0] = key.get(0) * it.getSpacing(0);
376  vd.getLastPos()[1] = key.get(1) * it.getSpacing(1);
377  vd.getLastPos()[2] = key.get(2) * it.getSpacing(2);
378 
379  // We use getLastProp to set the property value of the last particle we added
380  vd.template getLastProp<velocity>()[0] = 0.0;
381  vd.template getLastProp<velocity>()[1] = 0.0;
382  vd.template getLastProp<velocity>()[2] = 0.0;
383 
384  vd.template getLastProp<force>()[0] = 0.0;
385  vd.template getLastProp<force>()[1] = 0.0;
386  vd.template getLastProp<force>()[2] = 0.0;
387 
388  ++it;
389  }
390 
392 
432  timer tsim;
433  tsim.start();
434 
436 
437  // Get the Cell list structure
438  auto NN = vd.getCellList<CELL_MEMBAL(3,double)>(r_cut);
439 
440  // The standard
441  // auto NN = vd.getCellList(r_cut);
442 
443  // calculate forces
444  calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
445  unsigned long int f = 0;
446 
447  // MD time stepping
448  for (size_t i = 0; i < 10000 ; i++)
449  {
450  // Get the iterator
451  auto it3 = vd.getDomainIterator();
452 
453  // integrate velicity and space based on the calculated forces (Step1)
454  while (it3.isNext())
455  {
456  auto p = it3.get();
457 
458  // here we calculate v(tn + 0.5)
459  vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
460  vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
461  vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
462 
463  // here we calculate x(tn + 1)
464  vd.getPos(p)[0] += vd.template getProp<velocity>(p)[0]*dt;
465  vd.getPos(p)[1] += vd.template getProp<velocity>(p)[1]*dt;
466  vd.getPos(p)[2] += vd.template getProp<velocity>(p)[2]*dt;
467 
468  ++it3;
469  }
470 
471  // Because we moved the particles in space we have to map them and re-sync the ghost
472  vd.map();
473  vd.template ghost_get<>();
474 
475  // calculate forces or a(tn + 1) Step 2
476  calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
477 
478 
479  // Integrate the velocity Step 3
480  auto it4 = vd.getDomainIterator();
481 
482  while (it4.isNext())
483  {
484  auto p = it4.get();
485 
486  // here we calculate v(tn + 1)
487  vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
488  vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
489  vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
490 
491  ++it4;
492  }
493 
494  // After every iteration collect some statistic about the configuration
495  if (i % 100 == 0)
496  {
497  // We write the particle position for visualization (Without ghost)
498  vd.deleteGhost();
499  vd.write("particles_",f);
500 
501  // we resync the ghost
502  vd.ghost_get<>();
503 
504  // We calculate the energy
505  double energy = calc_energy(vd,NN,sigma12,sigma6,r_cut*r_cut);
506  auto & vcl = create_vcluster();
507  vcl.sum(energy);
508  vcl.execute();
509 
510  // we save the energy calculated at time step i c contain the time-step y contain the energy
511  x.add(i);
512  y.add({energy});
513 
514  // We also print on terminal the value of the energy
515  // only one processor (master) write on terminal
516  if (vcl.getProcessUnitID() == 0)
517  std::cout << "Energy: " << energy << std::endl;
518 
519  f++;
520  }
521  }
522 
524 
525  tsim.stop();
526  std::cout << "Time: " << tsim.getwct() << std::endl;
527 
543 
545  // Google charts options, it store the options to draw the X Y graph
546  GCoptions options;
547 
548  // Title of the graph
549  options.title = std::string("Energy with time");
550 
551  // Y axis name
552  options.yAxis = std::string("Energy");
553 
554  // X axis name
555  options.xAxis = std::string("iteration");
556 
557  // width of the line
558  options.lineWidth = 1.0;
559 
560  // Resolution in x
561  options.width = 1280;
562 
563  // Resolution in y
564  options.heigh = 720;
565 
566  // Add zoom capability
567  options.more = GC_ZOOM;
568 
569  // Object that draw the X Y graph
570  GoogleChart cg;
571 
572  // Add the graph
573  // The graph that it produce is in svg format that can be opened on browser
574  cg.AddLinesGraph(x,y,options);
575 
576  // Write into html format
577  cg.write("gc_plot2_out.html");
578 
580 
592 
594  openfpm_finalize();
595 
597 
619 }
620 
621 
622 
623 
size_t heigh
height of the graph in pixels
Definition: GoogleChart.hpp:48
void AddLinesGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, const GCoptions &opt)
Add a simple lines graph.
std::string title
Title of the chart.
Definition: GoogleChart.hpp:27
std::string more
more
Definition: GoogleChart.hpp:66
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
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.
size_t width
width of the graph in pixels
Definition: GoogleChart.hpp:45
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
Class for FAST cell list implementation.
Definition: CellList.hpp:269
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