OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
main_cpu.cpp
1#include "Vector/vector_dist.hpp"
2#include "Plot/GoogleChart.hpp"
3#include "Plot/util.hpp"
4#include "timer.hpp"
5
6#ifdef TEST_RUN
7size_t nstep = 100;
8#else
9size_t nstep = 1000;
10#endif
11
12typedef float real_number;
13
14constexpr int velocity = 0;
15constexpr int force = 1;
16
17
18template<typename CellList> void calc_forces(vector_dist<3,real_number, aggregate<real_number[3],real_number[3]> > & vd, CellList & NN, real_number sigma12, real_number sigma6, real_number r_cut2)
19{
20 vd.updateCellList(NN);
21
22 // Get an iterator over particles
23 auto it2 = vd.getDomainIterator();
24
25 // For each particle p ...
26 while (it2.isNext())
27 {
28 // ... get the particle p
29 auto p = it2.get();
30
31 // Get the position xp of the particle
32 Point<3,real_number> xp = vd.getPos(p);
33
34 // Reset the force counter
35 vd.template getProp<force>(p)[0] = 0.0;
36 vd.template getProp<force>(p)[1] = 0.0;
37 vd.template getProp<force>(p)[2] = 0.0;
38
39 // Get an iterator over the neighborhood particles of p
40 auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
41
42 // For each neighborhood particle ...
43 while (Np.isNext())
44 {
45 // ... q
46 auto q = Np.get();
47
48 // if (p == q) skip this particle
49 if (q == p.getKey()) {++Np; continue;};
50
51 // Get the position of p
52 Point<3,real_number> xq = vd.getPos(q);
53
54 // Get the distance between p and q
55 Point<3,real_number> r = xp - xq;
56
57 // take the norm of this vector
58 real_number rn = norm2(r);
59
60 if (rn > r_cut2)
61 {++Np; continue;};
62
63 // Calculate the force, using pow is slower
64 Point<3,real_number> f = 24.0*(2.0 *sigma12 / (rn*rn*rn*rn*rn*rn*rn) - sigma6 / (rn*rn*rn*rn)) * r;
65
66 // we sum the force produced by q on p
67 vd.template getProp<force>(p)[0] += f.get(0);
68 vd.template getProp<force>(p)[1] += f.get(1);
69 vd.template getProp<force>(p)[2] += f.get(2);
70
71 // Next neighborhood
72 ++Np;
73 }
74
75 // Next particle
76 ++it2;
77 }
78}
79
80template<typename CellList> real_number calc_energy(vector_dist<3,real_number, aggregate<real_number[3],real_number[3]> > & vd, CellList & NN, real_number sigma12, real_number sigma6, real_number r_cut2)
81{
82 real_number rc = r_cut2;
83 real_number shift = 2.0 * ( sigma12 / (rc*rc*rc*rc*rc*rc) - sigma6 / ( rc*rc*rc) );
84
85 real_number E = 0.0;
86
87 // Get the iterator
88 auto it2 = vd.getDomainIterator();
89
90 // For each particle ...
91 while (it2.isNext())
92 {
93 // ... p
94 auto p = it2.get();
95
96 // Get the position of the particle p
97 Point<3,real_number> xp = vd.getPos(p);
98
99 // Get an iterator over the neighborhood of the particle p
100 auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p)));
101
102 // For each neighborhood of the particle p
103 while (Np.isNext())
104 {
105 // Neighborhood particle q
106 auto q = Np.get();
107
108 // if p == q skip this particle
109 if (q == p.getKey()) {++Np; continue;};
110
111 // Get position of the particle q
112 Point<3,real_number> xq = vd.getPos(q);
113
114 // take the normalized direction
115 real_number rn = norm2(xp - xq);
116
117 if (rn > r_cut2)
118 {++Np;continue;}
119
120 // potential energy (using pow is slower)
121 E += 2.0 * ( sigma12 / (rn*rn*rn*rn*rn*rn) - sigma6 / ( rn*rn*rn) ) - shift;
122
123 // Next neighborhood
124 ++Np;
125 }
126
127 // Kinetic energy of the particle given by its actual speed
128 E += (vd.template getProp<velocity>(p)[0]*vd.template getProp<velocity>(p)[0] +
129 vd.template getProp<velocity>(p)[1]*vd.template getProp<velocity>(p)[1] +
130 vd.template getProp<velocity>(p)[2]*vd.template getProp<velocity>(p)[2]) / 2;
131
132 // Next Particle
133 ++it2;
134 }
135
136 return E;
137}
138
140
141int main(int argc, char* argv[])
142{
143 openfpm_init(&argc,&argv);
144
145 real_number sigma = 0.01;
146 real_number r_cut = 3.0*sigma;
147
148 // we will use it do place particles on a 10x10x10 Grid like
149 size_t sz[3] = {100,100,100};
150
151 // domain
152 Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
153
154 // Boundary conditions
155 size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
156
157 // ghost, big enough to contain the interaction radius
158 Ghost<3,float> ghost(r_cut);
159
160 real_number dt = 0.00005;
161 real_number sigma12 = pow(sigma,12);
162 real_number sigma6 = pow(sigma,6);
163
166
168
169 // We create the grid iterator
170 auto it = vd.getGridIterator(sz);
171
172 while (it.isNext())
173 {
174 // Create a new particle
175 vd.add();
176
177 // key contain (i,j,k) index of the grid
178 auto key = it.get();
179
180 // The index of the grid can be accessed with key.get(0) == i, key.get(1) == j ...
181 // We use getLastPos to set the position of the last particle added
182 vd.getLastPos()[0] = key.get(0) * it.getSpacing(0);
183 vd.getLastPos()[1] = key.get(1) * it.getSpacing(1);
184 vd.getLastPos()[2] = key.get(2) * it.getSpacing(2);
185
186 // We use getLastProp to set the property value of the last particle we added
187 vd.template getLastProp<velocity>()[0] = 0.0;
188 vd.template getLastProp<velocity>()[1] = 0.0;
189 vd.template getLastProp<velocity>()[2] = 0.0;
190
191 vd.template getLastProp<force>()[0] = 0.0;
192 vd.template getLastProp<force>()[1] = 0.0;
193 vd.template getLastProp<force>()[2] = 0.0;
194
195 ++it;
196 }
197
198 vd.map();
199 vd.ghost_get<>();
200
201 timer tsim;
202 tsim.start();
203
205
206 // Get the Cell list structure
207 auto NN = vd.getCellList(r_cut);
208
209 // The standard
210 // auto NN = vd.getCellList(r_cut);
211
212 // calculate forces
213 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
214 unsigned long int f = 0;
215
216 // MD time stepping
217 for (size_t i = 0; i < nstep ; i++)
218 {
219 timer t_s;
220 t_s.start();
221
222 // Get the iterator
223 auto it3 = vd.getDomainIterator();
224
225 // integrate velicity and space based on the calculated forces (Step1)
226 while (it3.isNext())
227 {
228 auto p = it3.get();
229
230 // here we calculate v(tn + 0.5)
231 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
232 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
233 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
234
235 // here we calculate x(tn + 1)
236 vd.getPos(p)[0] += vd.template getProp<velocity>(p)[0]*dt;
237 vd.getPos(p)[1] += vd.template getProp<velocity>(p)[1]*dt;
238 vd.getPos(p)[2] += vd.template getProp<velocity>(p)[2]*dt;
239
240 ++it3;
241 }
242
243 // Because we moved the particles in space we have to map them and re-sync the ghost
244 vd.map();
245 vd.template ghost_get<>();
246
247 // calculate forces or a(tn + 1) Step 2
248 calc_forces(vd,NN,sigma12,sigma6,r_cut*r_cut);
249
250
251 // Integrate the velocity Step 3
252 auto it4 = vd.getDomainIterator();
253
254 while (it4.isNext())
255 {
256 auto p = it4.get();
257
258 // here we calculate v(tn + 1)
259 vd.template getProp<velocity>(p)[0] += 0.5*dt*vd.template getProp<force>(p)[0];
260 vd.template getProp<velocity>(p)[1] += 0.5*dt*vd.template getProp<force>(p)[1];
261 vd.template getProp<velocity>(p)[2] += 0.5*dt*vd.template getProp<force>(p)[2];
262
263 ++it4;
264 }
265
266 // After every iteration collect some statistic about the configuration
267 if (i % 500 == 0)
268 {
269 // We write the particle position for visualization (Without ghost)
270 vd.deleteGhost();
271 vd.write("particles_",f);
272
273 // we resync the ghost
274 vd.ghost_get<>();
275
276 // We calculate the energy
277 real_number energy = calc_energy(vd,NN,sigma12,sigma6,r_cut*r_cut);
278 auto & vcl = create_vcluster();
279 vcl.sum(energy);
280 vcl.execute();
281
282 // we save the energy calculated at time step i c contain the time-step y contain the energy
283 x.add(i);
284 y.add({energy});
285
286 // We also print on terminal the value of the energy
287 // only one processor (master) write on terminal
288 if (vcl.getProcessUnitID() == 0)
289 std::cout << "Energy: " << energy << std::endl;
290
291 f++;
292 }
293
294 t_s.stop();
295
296 if (i % 100 == 0)
297 {
298 // resort the particle for better cache efficency
299 vd.reorder(5,reorder_opt::LINEAR);
300 }
301 }
302
303 tsim.stop();
304 std::cout << "Time: " << tsim.getwct() << std::endl;
305
306 // Google charts options, it store the options to draw the X Y graph
307 GCoptions options;
308
309 // Title of the graph
310 options.title = std::string("Energy with time");
311
312 // Y axis name
313 options.yAxis = std::string("Energy");
314
315 // X axis name
316 options.xAxis = std::string("iteration");
317
318 // width of the line
319 options.lineWidth = 1.0;
320
321 // Resolution in x
322 options.width = 1280;
323
324 // Resolution in y
325 options.heigh = 720;
326
327 // Add zoom capability
328 options.more = GC_ZOOM;
329
330 // Object that draw the X Y graph
331 GoogleChart cg;
332
333 // Add the graph
334 // The graph that it produce is in svg format that can be opened on browser
335 cg.AddLinesGraph(x,y,options);
336
337 // Write into html format
338 cg.write("gc_plot2_out.html");
339
340 openfpm_finalize();
341}
342
343
344
345
This class represent an N-dimensional box.
Definition Box.hpp:61
Class for FAST cell list implementation.
Definition CellList.hpp:357
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.
Definition Point.hpp:28
Implementation of 1-D std::vector like structure.
Class for cpu time benchmarking.
Definition timer.hpp:28
void stop()
Stop the timer.
Definition timer.hpp:119
void start()
Start the timer.
Definition timer.hpp:90
double getwct()
Return the elapsed real time.
Definition timer.hpp:130
Distributed vector.
Google chart options.
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 more
more
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...