OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
170int 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 represent an N-dimensional box.
Definition Box.hpp:61
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.
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition Point.hpp:172
void execute()
Execute all the requests.
size_t rank()
Get the process unit id.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
Implementation of VCluster class.
Definition VCluster.hpp:59
Distributed vector.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
Linear model.
Definition LB_Model.hpp:48
Definition ids.hpp:149