OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
main.cpp
1 //#define CHECKFOR_POSNAN
2 //#define CHECKFOR_PROPNAN
3 
156 //#define SE_CLASS3
157 //#define CHECKFOR_POSNAN
158 //#define STOP_ON_ERROR
159 //#define PRINT_STACKTRACE
160 
161 #ifdef TEST_RUN
162 
163 #else
164 
165 #endif
166 
167 #include "Vector/vector_dist.hpp"
168 #include "Draw/DrawParticles.hpp"
169 
170 int main(int argc, char* argv[])
171 {
172  // initialize the library
173  openfpm_init(&argc,&argv);
174 
176 
177  double m = 1;
178  double R = 0.06;
179  double cutoff = 2 * R;
180  double skin = 0.1 * cutoff;
181  constexpr int max_contacts = 36;
182  constexpr int max_contacts_def = max_contacts * 3;
183  double dt = 0.0001;
184  double Im = 2.0 * R * R * m / 5.0;
185  double k_n = 7849;
186  double k_t = 7849;
187  double gamma_n = 3401;
188  double gamma_t = 3401;
189  double m_eff = 0.5;
190 #ifdef TEST_RUN
191  double t_stop = 0.001;
192 #else
193  double t_stop = 16.0000;
194 #endif
195  double mu = 0.5;
196  double max_vel;
197  Vcluster<> & v_cl = create_vcluster();
198 
199  Box<3,double> domain({0.0,0.0,0.0},{17.04,6.0,6.6});
200  Ghost<3,double> g(cutoff + skin);
201 
203 
204  constexpr int velocity = 0;
205  constexpr int force = 1;
206  constexpr int omega = 2;
207  constexpr int tau = 3;
208  constexpr int cpd = 4;
209  constexpr int cpi = 5;
210  constexpr int ncp = 6;
211  constexpr int tt = 7;
212  constexpr int gid = 8;
213 
214  size_t bc[3] = {NON_PERIODIC,PERIODIC,NON_PERIODIC};
215 
217  double[max_contacts_def],int[max_contacts],
218  int,int,int>> parts(0,domain,bc,g);
219 
221 
222  // virtual grid
223  size_t sz[3] = {143,51,56};
224 
225  Box<3,double> sand_box({1.8,0.0,0.18},{8.58,5.9999,2.7});
226 
227  // we draw the initialization
228  auto sand_it = DrawParticles::DrawBox(parts,sz,domain,sand_box);
229 
230  while (sand_it.isNext())
231  {
232  // ... add a particle ...
233  parts.add();
234 
235  // ... and set it position ...
236  parts.getLastPos()[0] = sand_it.get().get(0);
237  parts.getLastPos()[1] = sand_it.get().get(1);
238  parts.getLastPos()[2] = sand_it.get().get(2);
239 
240  parts.getLastProp<velocity>()[0] = 0.0;
241  parts.getLastProp<velocity>()[1] = 0.0;
242  parts.getLastProp<velocity>()[2] = 0.0;
243 
244  parts.getLastProp<omega>()[0] = 0.0;
245  parts.getLastProp<omega>()[1] = 0.0;
246  parts.getLastProp<omega>()[2] = 0.0;
247 
248  parts.getLastProp<tau>()[0] = 0.0;
249  parts.getLastProp<tau>()[1] = 0.0;
250  parts.getLastProp<tau>()[2] = 0.0;
251 
252  parts.getLastProp<force>()[0] = 0.0;
253  parts.getLastProp<force>()[1] = 0.0;
254  parts.getLastProp<force>()[2] = 0.0;
255 
256  parts.getLastProp<ncp>() = 0;
257 
258  parts.getLastProp<tt>() = 0;
259 
260  ++sand_it;
261  }
262 
263  Box<3,double> base_box({0.06,0.0,0.06},{16.98,5.9999,0.18});
264 
265  // we draw the initialization
266  auto base_it = DrawParticles::DrawBox(parts,sz,domain,base_box);
267 
268  while (base_it.isNext())
269  {
270  // ... add a particle ...
271  parts.add();
272 
273  // ... and set it position ...
274  parts.getLastPos()[0] = base_it.get().get(0);
275  parts.getLastPos()[1] = base_it.get().get(1);
276  parts.getLastPos()[2] = base_it.get().get(2);
277 
278  parts.getLastProp<tt>() = 1;
279 
280  ++base_it;
281  }
282 
283  Box<3,double> wall_front({16.86,0.0,0.06},{16.98,5.9999,6.54});
284 
285  // we draw the initialization
286  auto wall_f_it = DrawParticles::DrawBox(parts,sz,domain,wall_front);
287 
288  while (wall_f_it.isNext())
289  {
290  // ... add a particle ...
291  parts.add();
292 
293  // ... and set it position ...
294  parts.getLastPos()[0] = wall_f_it.get().get(0);
295  parts.getLastPos()[1] = wall_f_it.get().get(1);
296  parts.getLastPos()[2] = wall_f_it.get().get(2);
297 
298  parts.getLastProp<tt>() = 1;
299 
300  ++wall_f_it;
301  }
302 
303  Box<3,double> wall_back({0.06,0.0,0.06},{0.18,5.9999,6.54});
304 
305  // we draw the initialization
306  auto wall_b_it = DrawParticles::DrawBox(parts,sz,domain,wall_back);
307 
308  while (wall_b_it.isNext())
309  {
310  // ... add a particle ...
311  parts.add();
312 
313  // ... and set it position ...
314  parts.getLastPos()[0] = wall_b_it.get().get(0);
315  parts.getLastPos()[1] = wall_b_it.get().get(1);
316  parts.getLastPos()[2] = wall_b_it.get().get(2);
317 
318  parts.getLastProp<tt>() = 1;
319 
320  ++wall_b_it;
321  }
322 
324 
325  parts.map();
326  parts.addComputationCosts(ModelSquare());
327  parts.getDecomposition().decompose();
328  parts.map();
329 
330  // Fill the gid
331 
332  auto it_p = parts.getDomainIterator();
333  size_t accu = parts.accum();
334 
335  while (it_p.isNext())
336  {
337  auto p = it_p.get();
338 
339  parts.getProp<gid>(p) = accu;
340 
341  ++accu;
342  ++it_p;
343  }
344 
345  parts.ghost_get<>();
346 
347 
348  size_t cnt = 0;
349  size_t cnt_reb = 0;
350  auto nlist = parts.getVerlet<VERLETLIST_BAL(3,double)>(cutoff + skin);
351 
352  double tot_sp = 0.0;
353 
354  double t = 0.0;
355  while (t < t_stop)
356  {
357  auto pit = parts.getDomainIterator();
358 
359  max_vel = 0.0;
360 
362 
363  // Update
364  while (pit.isNext())
365  {
366  auto p = pit.get();
367 
368  if (parts.getProp<tt>(p) == 1) {++pit;continue;}
369 
370  parts.getProp<velocity>(p)[0] = parts.getProp<velocity>(p)[0] + parts.getProp<force>(p)[0]*dt;
371  parts.getProp<velocity>(p)[1] = parts.getProp<velocity>(p)[1] + parts.getProp<force>(p)[1]*dt;
372  parts.getProp<velocity>(p)[2] = parts.getProp<velocity>(p)[2] + parts.getProp<force>(p)[2]*dt;
373 
374  double norm2 = parts.getProp<velocity>(p)[0]*parts.getProp<velocity>(p)[0] +
375  parts.getProp<velocity>(p)[1]*parts.getProp<velocity>(p)[1] +
376  parts.getProp<velocity>(p)[2]*parts.getProp<velocity>(p)[2];
377  if (max_vel < norm2)
378  {max_vel = norm2;}
379 
380  parts.getPos(p)[0] = parts.getPos(p)[0] + parts.getProp<velocity>(p)[0]*dt;
381  parts.getPos(p)[1] = parts.getPos(p)[1] + parts.getProp<velocity>(p)[1]*dt;
382  parts.getPos(p)[2] = parts.getPos(p)[2] + parts.getProp<velocity>(p)[2]*dt;
383 
384  if (parts.getPos(p)[0] < domain.getLow(0) || parts.getPos(p)[0] > domain.getHigh(0) ||
385  parts.getPos(p)[2] < domain.getLow(2) || parts.getPos(p)[2] > domain.getHigh(2) )
386  {parts.getProp<tt>(p) = 1;}
387 
388  parts.getProp<omega>(p)[0] = parts.getProp<omega>(p)[0] + parts.getProp<tau>(p)[0]/Im*dt;
389  parts.getProp<omega>(p)[1] = parts.getProp<omega>(p)[1] + parts.getProp<tau>(p)[1]/Im*dt;
390  parts.getProp<omega>(p)[2] = parts.getProp<omega>(p)[2] + parts.getProp<tau>(p)[2]/Im*dt;
391 
392  ++pit;
393  }
394  tot_sp += sqrt(max_vel)*dt;
395  v_cl.max(tot_sp);
396  v_cl.execute();
397 
399 
401 
402  if (tot_sp >= skin / 2.0)
403  {
404  parts.map();
405 
406  // Check if it is time to rebalance
407 
408  if (cnt_reb >= 200)
409  {
410  if (v_cl.rank() == 0)
411  {std::cout << "Redecomposing" << std::endl;}
412  cnt_reb = 0;
413  parts.addComputationCosts(ModelSquare());
414  parts.getDecomposition().redecompose(200);
415  parts.map();
416  }
417 
418  if (v_cl.rank() == 0)
419  {std::cout << "Reconstruct Verlet" << std::endl;}
420 
421  parts.ghost_get<velocity,omega,gid>();
422  parts.updateVerlet(nlist,cutoff+skin);
423 
424  tot_sp = 0.0;
425  }
426  else
427  {
428  parts.ghost_get<velocity,omega,gid>();
429  }
430 
432 
434 
435  auto pit2 = parts.getDomainIterator();
436 
437  while (pit2.isNext())
438  {
439  auto p = pit2.get();
440  Point<3,double> xp = parts.getPos(p);
441  Point<3,double> v_p = parts.getProp<velocity>(p);
442  Point<3,double> omega_p = parts.getProp<omega>(p);
443 
444  if (parts.getProp<tt>(p) == 1) {++pit2;continue;}
445 
446  Point<3,double> dF_n({0.0,0.0,0.0});
447  Point<3,double> dF_t({0.0,0.0,0.0});
448  Point<3,double> dTau({0.0,0.0,0.0});
449 
450  int contact_ok[max_contacts];
451  for (size_t i = 0; i < max_contacts ; i++) {contact_ok[i] = 0;}
452 
453  auto NN = nlist.getNNIterator(p.getKey());
454 
455  while (NN.isNext())
456  {
457  auto q = NN.get();
458 
459  if (q == p.getKey()) {++NN;continue;}
460 
461  Point<3,double> xq = parts.getPos(q);
462  Point<3,double> v_q = parts.getProp<velocity>(q);
463  Point<3,double> omega_q = parts.getProp<omega>(q);
464 
465  Point<3,double> r_pq = xp - xq;
466  double r_s_pq2 = norm2(r_pq);
467 
468  // Norm is not defined, next particle
469  if (r_s_pq2 == 0)
470  {continue;}
471 
472  double delta_ij = 2.0*R - sqrt(r_s_pq2);
473 
474  if (delta_ij < 0.0) {++NN;continue;}
475 
476  size_t cnt_end = parts.getProp<ncp>(p);
477  int this_contact = cnt_end;
478 
479  for (size_t k = 0 ; k < cnt_end ; k++)
480  {
481  if (parts.getProp<cpi>(p)[k] == parts.getProp<gid>(q))
482  {
483  this_contact = k;
484  }
485  }
486 
487  int cidx;
488  if (this_contact == cnt_end)
489  {
490  parts.getProp<ncp>(p) += 1;
491  this_contact = parts.getProp<ncp>(p) - 1;
492 
493  cidx = 3 * this_contact;
494 
495  if (this_contact >= max_contacts)
496  {std::cout << "Error reached maximum nunber of contacts points" << std::endl;}
497 
498  parts.getProp<cpi>(p)[this_contact] = parts.getProp<gid>(q);
499 
500  parts.getProp<cpd>(p)[cidx] = 0.0;
501  parts.getProp<cpd>(p)[cidx + 1] = 0.0;
502  parts.getProp<cpd>(p)[cidx + 2] = 0.0;
503 
504  }
505  else
506  {
507  cidx = 3 * this_contact;
508  }
509 
510  Point<3,double> n_ij = r_pq / sqrt(r_s_pq2);
511  Point<3,double> v_rel = v_p - v_q;
512  Point<3,double> v_nij = (v_rel * n_ij) * n_ij;
513  Point<3,double> v_omega = (omega_p + omega_q)*R;
514  Point<3,double> v_cross;
515 
516  v_cross.get(0) = v_omega.get(1) * n_ij.get(2) - v_omega.get(2) * n_ij.get(1);
517  v_cross.get(1) = v_omega.get(2) * n_ij.get(0) - v_omega.get(0) * n_ij.get(2);
518  v_cross.get(2) = v_omega.get(0) * n_ij.get(1) - v_omega.get(1) * n_ij.get(0);
519 
520  Point<3,double> v_tij = v_rel - v_nij - v_cross;
521  Point<3,double> v_dtij = dt * v_tij;
522 
523  parts.getProp<cpd>(p)[cidx] += v_dtij.get(0);
524  parts.getProp<cpd>(p)[cidx + 1] += v_dtij.get(1);
525  parts.getProp<cpd>(p)[cidx + 2] += v_dtij.get(2);
526 
527  Point<3,double> u_ij;
528 
529  u_ij.get(0) = parts.getProp<cpd>(p)[cidx];
530  u_ij.get(1) = parts.getProp<cpd>(p)[cidx + 1];
531  u_ij.get(2) = parts.getProp<cpd>(p)[cidx + 2];
532 
533  Point<3,double> F_nij = sqrt(delta_ij/2/R) * (k_n*delta_ij*n_ij - gamma_n*m_eff*v_nij);
534  dF_n = dF_n + F_nij;
535 
536  Point<3,double> F_tij = sqrt(delta_ij/2/R) * (-k_t*u_ij - gamma_t*m_eff*v_tij);
537  double F_tij_sq = norm2(F_tij);
538  double F_nij_sq = mu * mu * norm2(F_nij);
539  if (F_tij_sq > F_nij_sq)
540  {
541  F_tij = F_tij * (F_nij_sq / F_tij_sq);
542 
543  parts.getProp<cpd>(p)[cidx] = -1.0 / k_t * (F_tij.get(0) * sqrt(2*R/delta_ij) + gamma_t*m_eff*v_tij.get(0));
544  parts.getProp<cpd>(p)[cidx+1] = -1.0 / k_t * (F_tij.get(1) * sqrt(2*R/delta_ij) + gamma_t*m_eff*v_tij.get(1));
545  parts.getProp<cpd>(p)[cidx+2] = -1.0 / k_t * (F_tij.get(2) * sqrt(2*R/delta_ij) + gamma_t*m_eff*v_tij.get(2));
546  }
547 
548 
549  dF_t = dF_t + F_tij;
550  dTau.get(0) = dTau.get(0) - R * (n_ij.get(1) * F_tij.get(2) - n_ij.get(2) * F_tij.get(1));
551  dTau.get(1) = dTau.get(1) - R * (n_ij.get(2) * F_tij.get(0) - n_ij.get(0) * F_tij.get(2));
552  dTau.get(2) = dTau.get(2) - R * (n_ij.get(0) * F_tij.get(1) - n_ij.get(1) * F_tij.get(0));
553 
554  contact_ok[this_contact] = 1;
555 
556  ++NN;
557  }
558 
559  int cnt_end = parts.getProp<ncp>(p);
560  int i = 0;
561  for (int iread = 0; iread < cnt_end ; iread++)
562  {
563  if (contact_ok[iread] == 1)
564  {
565  i = i + 1;
566  int j = 3*(i - 1);
567  int k = 3*iread;
568 
569  parts.getProp<cpd>(p)[j] = parts.getProp<cpd>(p)[k];
570  parts.getProp<cpd>(p)[j+1] = parts.getProp<cpd>(p)[k+1];
571  parts.getProp<cpd>(p)[j+2] = parts.getProp<cpd>(p)[k+2];
572  }
573  }
574 
575  parts.getProp<ncp>(p) = i;
576 
577  if (parts.getProp<tt>(p) == 0)
578  {
579  parts.getProp<force>(p).get(0) = m * 4.905 + dF_n.get(0) + dF_t.get(0);
580  parts.getProp<force>(p).get(1) = 0.0 + dF_n.get(1) + dF_t.get(1);
581  parts.getProp<force>(p).get(2) = m * -8.49570921 + dF_n.get(2) + dF_t.get(2);
582 
583  parts.getProp<tau>(p) = dTau;
584  }
585 
586  if (parts.getProp<tt>(p) == 1)
587  {
588  parts.getProp<force>(p) = 0;
589  parts.getProp<tau>(p) = 0;
590  }
591 
592  ++pit2;
593  }
594 
596 
597  if (v_cl.rank() == 0)
598  {std::cout << "Time step" << std::endl;}
599 
600  if (cnt % 300 == 0)
601  {
602  std::cout << "Write " << cnt << std::endl;
603  parts.write_frame("output",cnt);
604  }
605 
606  cnt_reb++;
607  cnt++;
608  t += dt;
609  }
610 
611  openfpm_finalize();
612 }
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
Definition: Ghost.hpp:39
Implementation of VCluster class.
Definition: VCluster.hpp:58
void execute()
Execute all the requests.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
size_t rank()
Get the process unit id.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
This class represent an N-dimensional box.
Definition: Box.hpp:60
Linear model.
Definition: LB_Model.hpp:47
static PointIterator< dim, T, typename vd_type::Decomposition_type > DrawBox(vd_type &vd, size_t(&sz)[dim], Box< dim, T > &domain, Box< dim, T > &sub)
Draw particles in a box.
Distributed vector.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
Definition: ids.hpp:148