OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
main.cpp
1
53//#define SE_CLASS1
54//#define STOP_ON_ERROR
55
56#include "Vector/vector_dist.hpp"
57#include <math.h>
58#include "Draw/DrawParticles.hpp"
59
211// A constant to indicate boundary particles
212#define BOUNDARY 1
213
214// A constant to indicate fluid particles
215#define FLUID 0
216
217// initial spacing between particles dp in the formulas
218const double dp = 0.0085;
219// Maximum height of the fluid water
220// is going to be calculated and filled later on
221double h_swl = 0.0;
222
223// c_s in the formulas (constant used to calculate the sound speed)
224const double coeff_sound = 20.0;
225
226// gamma in the formulas
227const double gamma_ = 7.0;
228
229// sqrt(3.0*dp*dp) support of the kernel
230const double H = 0.0147224318643;
231
232const double FourH2 = 4.0 * H*H;
233
234// Eta in the formulas
235const double Eta2 = 0.01 * H*H;
236
237// alpha in the formula
238const double visco = 0.1;
239
240// cbar in the formula (calculated later)
241double cbar = 0.0;
242
243// Mass of the fluid particles
244const double MassFluid = 0.000614125;
245
246// Mass of the boundary particles
247const double MassBound = 0.000614125;
248
249// End simulation time
250#ifndef TEST_RUN
251const double t_end = 1.5;
252#else
253const double t_end = 0.001;
254#endif
255
256// Gravity acceleration
257const double gravity = 9.81;
258
259// Reference densitu 1000Kg/m^3
260const double rho_zero = 1000.0;
261
262// Filled later require h_swl, it is b in the formulas
263double B = 0.0;
264
265// Constant used to define time integration
266const double CFLnumber = 0.2;
267
268// Minimum T
269const double DtMin = 0.00001;
270
271// Minimum Rho allowed
272const double RhoMin = 700.0;
273
274// Maximum Rho allowed
275const double RhoMax = 1300.0;
276
277// Filled in initialization
278double max_fluid_height = 0.0;
279
280// Properties
281
282// FLUID or BOUNDARY
283const size_t type = 0;
284
285// FLUID or BOUNDARY
286const size_t nn_num = 1;
287
288// Density
289const int rho = 2;
290
291// Density at step n-1
292const int rho_prev = 3;
293
294// Pressure
295const int Pressure = 4;
296
297// Delta rho calculated in the force calculation
298const int drho = 5;
299
300// calculated force
301const int force = 6;
302
303// velocity
304const int velocity = 7;
305
306// velocity at previous step
307const int velocity_prev = 8;
308
313// Type of the vector containing particles
315// | | | | | | | | |
316// | | | | | | | | |
317// type | density density Pressure delta force velocity velocity
318// | at n-1 density at n - 1
319// |
320// Number of neighborhood
321
323struct ModelCustom
324{
325 template<typename Decomposition, typename vector> inline void addComputation(Decomposition & dec, vector & vd, size_t v, size_t p)
326 {
327 if (vd.template getProp<type>(p) == FLUID )
328 {dec.addComputationCost(v,4);}
329 else
330 {dec.addComputationCost(v,3);}
331 }
332
333 template<typename Decomposition> inline void applyModel(Decomposition & dec, size_t v)
334 {
335 dec.setSubSubDomainComputationCost(v, dec.getSubSubDomainComputationCost(v) * dec.getSubSubDomainComputationCost(v));
336 }
337
338 float distributionTol()
339 {
340 return 1.01;
341 }
342};
343
346{
347 template<typename Decomposition, typename vector> inline void addComputation(Decomposition & dec, vector & vd, size_t v, size_t p)
348 {
349 dec.addComputationCost(v,vd.template getProp<nn_num>(p) + 4);
350 }
351
352 template<typename Decomposition> inline void applyModel(Decomposition & dec, size_t v)
353 {
354 }
355
356 float distributionTol()
357 {
358 return 1.01;
359 }
360};
361
362inline void EqState(particles & vd)
363{
364 auto it = vd.getDomainIterator();
365
366 while (it.isNext())
367 {
368 auto a = it.get();
369
370 double rho_a = vd.template getProp<rho>(a);
371 double rho_frac = rho_a / rho_zero;
372
373 vd.template getProp<Pressure>(a) = B*( rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac - 1.0);
374
375 ++it;
376 }
377}
378
379const double a2 = 1.0/M_PI/H/H/H;
380
381inline double Wab(double r)
382{
383 r /= H;
384
385 if (r < 1.0)
386 {return (1.0 - 3.0/2.0*r*r + 3.0/4.0*r*r*r)*a2;}
387 else if (r < 2.0)
388 {return (1.0/4.0*(2.0 - r*r)*(2.0 - r*r)*(2.0 - r*r))*a2;}
389 else
390 {return 0.0;}
391}
392
393const double c1 = -3.0/M_PI/H/H/H/H;
394const double d1 = 9.0/4.0/M_PI/H/H/H/H;
395const double c2 = -3.0/4.0/M_PI/H/H/H/H;
396const double a2_4 = 0.25*a2;
397// Filled later
398double W_dap = 0.0;
399
400inline void DWab(Point<3,double> & dx, Point<3,double> & DW, double r)
401{
402 const double qq=r/H;
403
404 double qq2 = qq * qq;
405 double fac1 = (c1*qq + d1*qq2)/r;
406 double b1 = (qq < 1.0)?1.0f:0.0f;
407
408 double wqq = (2.0 - qq);
409 double fac2 = c2 * wqq * wqq / r;
410 double b2 = (qq >= 1.0 && qq < 2.0)?1.0f:0.0f;
411
412 double factor = (b1*fac1 + b2*fac2);
413
414 DW.get(0) = factor * dx.get(0);
415 DW.get(1) = factor * dx.get(1);
416 DW.get(2) = factor * dx.get(2);
417}
418
419inline double Tensile(double r, double rhoa, double rhob, double prs1, double prs2)
420{
421 const double qq=r/H;
422 //-Cubic Spline kernel
423 double wab;
424 if(r>H)
425 {
426 double wqq1=2.0f-qq;
427 double wqq2=wqq1*wqq1;
428
429 wab=a2_4*(wqq2*wqq1);
430 }
431 else
432 {
433 double wqq2=qq*qq;
434 double wqq3=wqq2*qq;
435
436 wab=a2*(1.0f-1.5f*wqq2+0.75f*wqq3);
437 }
438
439 //-Tensile correction.
440 double fab=wab*W_dap;
441 fab*=fab; fab*=fab; //fab=fab^4
442 const double tensilp1=(prs1/(rhoa*rhoa))*(prs1>0? 0.01: -0.2);
443 const double tensilp2=(prs2/(rhob*rhob))*(prs2>0? 0.01: -0.2);
444
445 return (fab*(tensilp1+tensilp2));
446}
447
448
449inline double Pi(const Point<3,double> & dr, double rr2, Point<3,double> & dv, double rhoa, double rhob, double massb, double & visc)
450{
451 const double dot = dr.get(0)*dv.get(0) + dr.get(1)*dv.get(1) + dr.get(2)*dv.get(2);
452 const double dot_rr2 = dot/(rr2+Eta2);
453 visc=std::max(dot_rr2,visc);
454
455 if(dot < 0)
456 {
457 const float amubar=H*dot_rr2;
458 const float robar=(rhoa+rhob)*0.5f;
459 const float pi_visc=(-visco*cbar*amubar/robar);
460
461 return pi_visc;
462 }
463 else
464 return 0.0;
465}
466
467
468template<typename VerletList> inline void calc_forces(particles & vd, VerletList & NN, double & max_visc)
469{
472 // Reset the ghost
473 auto itg = vd.getDomainIterator();
474 while (itg.isNext())
475 {
476 auto p = itg.get();
477 // Reset force
478
479 // Reset the force counter (- gravity on zeta direction)
480 vd.template getProp<force>(p)[0] = 0.0;
481 vd.template getProp<force>(p)[1] = 0.0;
482 vd.template getProp<force>(p)[2] = -gravity;
483 vd.template getProp<drho>(p) = 0.0;
484
485
486 ++itg;
487 }
488
493 auto itg2 = vd.getGhostIterator();
494 while (itg2.isNext())
495 {
496 auto p = itg2.get();
497 // Reset force
498
499 // Reset the force counter (- gravity on zeta direction)
500 vd.template getProp<force>(p)[0] = 0.0;
501 vd.template getProp<force>(p)[1] = 0.0;
502 vd.template getProp<force>(p)[2] = 0.0;
503 vd.template getProp<drho>(p) = 0.0;
504
505 ++itg2;
506 }
507
510 // Get an iterator over particles
511 auto part = vd.getParticleIteratorCRS(NN);
512
513 double visc = 0;
514
515 // For each particle ...
516 while (part.isNext())
517 {
518 // ... a
519 auto a = part.get();
520
521 // Get the position xp of the particle
522 Point<3,double> xa = vd.getPos(a);
523
524 // Type of the particle
525 size_t typea = vd.getProp<type>(a);
526
527 // Take the mass of the particle dependently if it is FLUID or BOUNDARY
528 double massa = (vd.getProp<type>(a) == FLUID)?MassFluid:MassBound;
529
530 // Get the density of the of the particle a
531 double rhoa = vd.getProp<rho>(a);
532
533 // Get the pressure of the particle a
534 double Pa = vd.getProp<Pressure>(a);
535
536 // Get the Velocity of the particle a
537 Point<3,double> va = vd.getProp<velocity>(a);
538
539 // Get an iterator over the neighborhood particles of p
540 auto Np = NN.template getNNIterator<NO_CHECK>(a);
541
542 size_t nn = 0;
543
544 // For each neighborhood particle
545 while (Np.isNext() == true)
546 {
547 // ... q
548 auto b = Np.get();
549
550 // Get the position xp of the particle
551 Point<3,double> xb = vd.getPos(b);
552
553 // Get the distance between p and q
554 Point<3,double> dr = xa - xb;
555 // take the norm of this vector
556 float r2 = norm2(dr);
557
558 // if they interact
559 if (r2 < FourH2 && r2 > 1e-18)
560 {
561 double r = sqrt(r2);
562
563 unsigned int typeb = vd.getProp<type>(b);
564
565 double massb = (typeb == FLUID)?MassFluid:MassBound;
566 Point<3,double> vb = vd.getProp<velocity>(b);
567 double Pb = vd.getProp<Pressure>(b);
568 double rhob = vd.getProp<rho>(b);
569
570 Point<3,double> v_rel = va - vb;
571
573 DWab(dr,DW,r);
574
576
577 double factor = - ((Pa + Pb) / (rhoa * rhob) + Tensile(r,rhoa,rhob,Pa,Pb) + Pi(dr,r2,v_rel,rhoa,rhob,massb,visc));
578
579 // Bound - Bound does not produce any change
580 factor = (typea == BOUNDARY && typeb == BOUNDARY)?0.0f:factor;
581
582 vd.getProp<force>(a)[0] += massb * factor * DW.get(0);
583 vd.getProp<force>(a)[1] += massb * factor * DW.get(1);
584 vd.getProp<force>(a)[2] += massb * factor * DW.get(2);
585
586 vd.getProp<force>(b)[0] -= massa * factor * DW.get(0);
587 vd.getProp<force>(b)[1] -= massa * factor * DW.get(1);
588 vd.getProp<force>(b)[2] -= massa * factor * DW.get(2);
589
590 double scal = (v_rel.get(0)*DW.get(0)+v_rel.get(1)*DW.get(1)+v_rel.get(2)*DW.get(2));
591
592 // Bound - Bound does not produce any change
593 scal = (typea == BOUNDARY && typeb == BOUNDARY)?0.0f:scal;
594
595 vd.getProp<drho>(a) += massb*scal;
596 vd.getProp<drho>(b) += massa*scal;
597
599 }
600
601 nn++;
602 ++Np;
603 }
604
605 // Number of particles here
606 vd.getProp<nn_num>(a) = nn;
607
608 ++part;
609 }
610
612
613 vd.template ghost_put<add_,drho,force>();
614
616}
617
618void max_acceleration_and_velocity(particles & vd, double & max_acc, double & max_vel)
619{
620 // Calculate the maximum acceleration
621 auto part = vd.getDomainIterator();
622
623 while (part.isNext())
624 {
625 auto a = part.get();
626
627 Point<3,double> acc(vd.getProp<force>(a));
628 double acc2 = norm2(acc);
629
630 Point<3,double> vel(vd.getProp<velocity>(a));
631 double vel2 = norm2(vel);
632
633 if (vel2 >= max_vel)
634 max_vel = vel2;
635
636 if (acc2 >= max_acc)
637 max_acc = acc2;
638
639 ++part;
640 }
641 max_acc = sqrt(max_acc);
642 max_vel = sqrt(max_vel);
643
644 Vcluster<> & v_cl = create_vcluster();
645 v_cl.max(max_acc);
646 v_cl.max(max_vel);
647 v_cl.execute();
648}
649
650double calc_deltaT(particles & vd, double ViscDtMax)
651{
652 double Maxacc = 0.0;
653 double Maxvel = 0.0;
654 max_acceleration_and_velocity(vd,Maxacc,Maxvel);
655
656 //-dt1 depends on force per unit mass.
657 const double dt_f = (Maxacc)?sqrt(H/Maxacc):std::numeric_limits<int>::max();
658
659 //-dt2 combines the Courant and the viscous time-step controls.
660 const double dt_cv = H/(std::max(cbar,Maxvel*10.) + H*ViscDtMax);
661
662 //-dt new value of time step.
663 double dt=double(CFLnumber)*std::min(dt_f,dt_cv);
664 if(dt<double(DtMin))
665 {dt=double(DtMin);}
666
667 return dt;
668}
669
670
672
673size_t cnt = 0;
674
676void verlet_int(particles & vd, double dt, double & max_disp)
678{
679 // list of the particle to remove
680 to_remove.clear();
681
682 // particle iterator
683 auto part = vd.getDomainIterator();
684
685 double dt205 = dt*dt*0.5;
686 double dt2 = dt*2.0;
687
689 max_disp = 0;
692 // For each particle ...
693 while (part.isNext())
694 {
695 // ... a
696 auto a = part.get();
697
698 // if the particle is boundary
699 if (vd.template getProp<type>(a) == BOUNDARY)
700 {
701 // Update rho
702 double rhop = vd.template getProp<rho>(a);
703
704 // Update only the density
705 vd.template getProp<velocity>(a)[0] = 0.0;
706 vd.template getProp<velocity>(a)[1] = 0.0;
707 vd.template getProp<velocity>(a)[2] = 0.0;
708 double rhonew = vd.template getProp<rho_prev>(a) + dt2*vd.template getProp<drho>(a);
709 vd.template getProp<rho>(a) = (rhonew < rho_zero)?rho_zero:rhonew;
710
711 vd.template getProp<rho_prev>(a) = rhop;
712
713 ++part;
714 continue;
715 }
716
717 //-Calculate displacement and update position / Calcula desplazamiento y actualiza posicion.
718 double dx = vd.template getProp<velocity>(a)[0]*dt + vd.template getProp<force>(a)[0]*dt205;
719 double dy = vd.template getProp<velocity>(a)[1]*dt + vd.template getProp<force>(a)[1]*dt205;
720 double dz = vd.template getProp<velocity>(a)[2]*dt + vd.template getProp<force>(a)[2]*dt205;
721
722 vd.getPos(a)[0] += dx;
723 vd.getPos(a)[1] += dy;
724 vd.getPos(a)[2] += dz;
725
727 double d2 = dx*dx + dy*dy + dz*dz;
728
729 max_disp = (max_disp > d2)?max_disp:d2;
732 double velX = vd.template getProp<velocity>(a)[0];
733 double velY = vd.template getProp<velocity>(a)[1];
734 double velZ = vd.template getProp<velocity>(a)[2];
735 double rhop = vd.template getProp<rho>(a);
736
737 vd.template getProp<velocity>(a)[0] = vd.template getProp<velocity_prev>(a)[0] + vd.template getProp<force>(a)[0]*dt2;
738 vd.template getProp<velocity>(a)[1] = vd.template getProp<velocity_prev>(a)[1] + vd.template getProp<force>(a)[1]*dt2;
739 vd.template getProp<velocity>(a)[2] = vd.template getProp<velocity_prev>(a)[2] + vd.template getProp<force>(a)[2]*dt2;
740 vd.template getProp<rho>(a) = vd.template getProp<rho_prev>(a) + dt2*vd.template getProp<drho>(a);
741
742 // Check if the particle go out of range in space and in density
743 if (vd.getPos(a)[0] < 0.000263878 || vd.getPos(a)[1] < 0.000263878 || vd.getPos(a)[2] < 0.000263878 ||
744 vd.getPos(a)[0] > 0.000263878+1.59947 || vd.getPos(a)[1] > 0.000263878+0.672972 || vd.getPos(a)[2] > 0.000263878+0.903944 ||
745 vd.template getProp<rho>(a) < RhoMin || vd.template getProp<rho>(a) > RhoMax)
746 {
747 to_remove.add(a.getKey());
748 }
749
750 vd.template getProp<velocity_prev>(a)[0] = velX;
751 vd.template getProp<velocity_prev>(a)[1] = velY;
752 vd.template getProp<velocity_prev>(a)[2] = velZ;
753 vd.template getProp<rho_prev>(a) = rhop;
754
755 ++part;
756 }
757
760 Vcluster<> & v_cl = create_vcluster();
761 v_cl.max(max_disp);
762 v_cl.execute();
763
764 max_disp = sqrt(max_disp);
765
768 // increment the iteration counter
769 cnt++;
770}
771
773void euler_int(particles & vd, double dt, double & max_disp)
775{
776 // list of the particle to remove
777 to_remove.clear();
778
779 // particle iterator
780 auto part = vd.getDomainIterator();
781
782 double dt205 = dt*dt*0.5;
783 double dt2 = dt*2.0;
784
785 max_disp = 0;
786
787 // For each particle ...
788 while (part.isNext())
789 {
790 // ... a
791 auto a = part.get();
792
793 // if the particle is boundary
794 if (vd.template getProp<type>(a) == BOUNDARY)
795 {
796 // Update rho
797 double rhop = vd.template getProp<rho>(a);
798
799 // Update only the density
800 vd.template getProp<velocity>(a)[0] = 0.0;
801 vd.template getProp<velocity>(a)[1] = 0.0;
802 vd.template getProp<velocity>(a)[2] = 0.0;
803 double rhonew = vd.template getProp<rho>(a) + dt*vd.template getProp<drho>(a);
804 vd.template getProp<rho>(a) = (rhonew < rho_zero)?rho_zero:rhonew;
805
806 vd.template getProp<rho_prev>(a) = rhop;
807
808 ++part;
809 continue;
810 }
811
812 //-Calculate displacement and update position / Calcula desplazamiento y actualiza posicion.
813 double dx = vd.template getProp<velocity>(a)[0]*dt + vd.template getProp<force>(a)[0]*dt205;
814 double dy = vd.template getProp<velocity>(a)[1]*dt + vd.template getProp<force>(a)[1]*dt205;
815 double dz = vd.template getProp<velocity>(a)[2]*dt + vd.template getProp<force>(a)[2]*dt205;
816
817 vd.getPos(a)[0] += dx;
818 vd.getPos(a)[1] += dy;
819 vd.getPos(a)[2] += dz;
820
821 double d2 = dx*dx + dy*dy + dz*dz;
822
823 max_disp = (max_disp > d2)?max_disp:d2;
824
825 double velX = vd.template getProp<velocity>(a)[0];
826 double velY = vd.template getProp<velocity>(a)[1];
827 double velZ = vd.template getProp<velocity>(a)[2];
828 double rhop = vd.template getProp<rho>(a);
829
830 vd.template getProp<velocity>(a)[0] = vd.template getProp<velocity>(a)[0] + vd.template getProp<force>(a)[0]*dt;
831 vd.template getProp<velocity>(a)[1] = vd.template getProp<velocity>(a)[1] + vd.template getProp<force>(a)[1]*dt;
832 vd.template getProp<velocity>(a)[2] = vd.template getProp<velocity>(a)[2] + vd.template getProp<force>(a)[2]*dt;
833 vd.template getProp<rho>(a) = vd.template getProp<rho>(a) + dt*vd.template getProp<drho>(a);
834
835 // Check if the particle go out of range in space and in density
836 if (vd.getPos(a)[0] < 0.000263878 || vd.getPos(a)[1] < 0.000263878 || vd.getPos(a)[2] < 0.000263878 ||
837 vd.getPos(a)[0] > 0.000263878+1.59947 || vd.getPos(a)[1] > 0.000263878+0.672972 || vd.getPos(a)[2] > 0.000263878+0.903944 ||
838 vd.template getProp<rho>(a) < RhoMin || vd.template getProp<rho>(a) > RhoMax)
839 {
840 to_remove.add(a.getKey());
841 }
842
843 vd.template getProp<velocity_prev>(a)[0] = velX;
844 vd.template getProp<velocity_prev>(a)[1] = velY;
845 vd.template getProp<velocity_prev>(a)[2] = velZ;
846 vd.template getProp<rho_prev>(a) = rhop;
847
848 ++part;
849 }
850
851 Vcluster<> & v_cl = create_vcluster();
852 v_cl.max(max_disp);
853 v_cl.execute();
854
855 max_disp = sqrt(max_disp);
856
857 // increment the iteration counter
858 cnt++;
859}
860
861int main(int argc, char* argv[])
862{
863 // initialize the library
864 openfpm_init(&argc,&argv);
865
866 // Here we define our domain a 2D box with internals from 0 to 1.0 for x and y
867 Box<3,double> domain({-0.05,-0.05,-0.05},{1.7010,0.7065,0.5025});
868 size_t sz[3] = {207,90,66};
869
870 // Fill W_dap
871 W_dap = 1.0/Wab(H/1.5);
872
873 // Here we define the boundary conditions of our problem
874 size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
875
878 double skin = 0.25 * 2*H;
879 double r_gskin = 2*H + skin;
880
881 // extended boundary around the domain, and the processor domain
882 // by the support of the cubic kernel
883 Ghost<3,double> g(r_gskin);
884
887 // Eliminating the lower part of the ghost
888 // We are using CRS scheme
889 g.setLow(0,0.0);
890 g.setLow(1,0.0);
891 g.setLow(2,0.0);
892
895 particles vd(0,domain,bc,g,BIND_DEC_TO_GHOST);
896
899 // You can ignore all these dp/2.0 is a trick to reach the same initialization
900 // of Dual-SPH that use a different criteria to draw particles
901 Box<3,double> fluid_box({dp/2.0,dp/2.0,dp/2.0},{0.4+dp/2.0,0.67-dp/2.0,0.3+dp/2.0});
902
903 // return an iterator to the fluid particles to add to vd
904 auto fluid_it = DrawParticles::DrawBox(vd,sz,domain,fluid_box);
905
906 // here we fill some of the constants needed by the simulation
907 max_fluid_height = fluid_it.getBoxMargins().getHigh(2);
908 h_swl = fluid_it.getBoxMargins().getHigh(2) - fluid_it.getBoxMargins().getLow(2);
909 B = (coeff_sound)*(coeff_sound)*gravity*h_swl*rho_zero / gamma_;
910 cbar = coeff_sound * sqrt(gravity * h_swl);
911
912 // for each particle inside the fluid box ...
913 while (fluid_it.isNext())
914 {
915 // ... add a particle ...
916 vd.add();
917
918 // ... and set it position ...
919 vd.getLastPos()[0] = fluid_it.get().get(0);
920 vd.getLastPos()[1] = fluid_it.get().get(1);
921 vd.getLastPos()[2] = fluid_it.get().get(2);
922
923 // and its type.
924 vd.template getLastProp<type>() = FLUID;
925
926 // We also initialize the density of the particle and the hydro-static pressure given by
927 //
928 // rho_zero*g*h = P
929 //
930 // rho_p = (P/B + 1)^(1/Gamma) * rho_zero
931 //
932
933 vd.template getLastProp<Pressure>() = rho_zero * gravity * (max_fluid_height - fluid_it.get().get(2));
934
935 vd.template getLastProp<rho>() = pow(vd.template getLastProp<Pressure>() / B + 1, 1.0/gamma_) * rho_zero;
936 vd.template getLastProp<rho_prev>() = vd.template getLastProp<rho>();
937 vd.template getLastProp<velocity>()[0] = 0.0;
938 vd.template getLastProp<velocity>()[1] = 0.0;
939 vd.template getLastProp<velocity>()[2] = 0.0;
940
941 vd.template getLastProp<velocity_prev>()[0] = 0.0;
942 vd.template getLastProp<velocity_prev>()[1] = 0.0;
943 vd.template getLastProp<velocity_prev>()[2] = 0.0;
944
945 // next fluid particle
946 ++fluid_it;
947 }
948
949 // Recipient
950 Box<3,double> recipient1({0.0,0.0,0.0},{1.6+dp/2.0,0.67+dp/2.0,0.4+dp/2.0});
951 Box<3,double> recipient2({dp,dp,dp},{1.6-dp/2.0,0.67-dp/2.0,0.4+dp/2.0});
952
953 Box<3,double> obstacle1({0.9,0.24-dp/2.0,0.0},{1.02+dp/2.0,0.36,0.45+dp/2.0});
954 Box<3,double> obstacle2({0.9+dp,0.24+dp/2.0,0.0},{1.02-dp/2.0,0.36-dp,0.45-dp/2.0});
955 Box<3,double> obstacle3({0.9+dp,0.24,0.0},{1.02,0.36,0.45});
956
958 holes.add(recipient2);
959 holes.add(obstacle1);
960 auto bound_box = DrawParticles::DrawSkin(vd,sz,domain,holes,recipient1);
961
962 while (bound_box.isNext())
963 {
964 vd.add();
965
966 vd.getLastPos()[0] = bound_box.get().get(0);
967 vd.getLastPos()[1] = bound_box.get().get(1);
968 vd.getLastPos()[2] = bound_box.get().get(2);
969
970 vd.template getLastProp<type>() = BOUNDARY;
971 vd.template getLastProp<rho>() = rho_zero;
972 vd.template getLastProp<rho_prev>() = rho_zero;
973 vd.template getLastProp<velocity>()[0] = 0.0;
974 vd.template getLastProp<velocity>()[1] = 0.0;
975 vd.template getLastProp<velocity>()[2] = 0.0;
976
977 vd.template getLastProp<velocity_prev>()[0] = 0.0;
978 vd.template getLastProp<velocity_prev>()[1] = 0.0;
979 vd.template getLastProp<velocity_prev>()[2] = 0.0;
980
981 ++bound_box;
982 }
983
984 auto obstacle_box = DrawParticles::DrawSkin(vd,sz,domain,obstacle2,obstacle1);
985
986 while (obstacle_box.isNext())
987 {
988 vd.add();
989
990 vd.getLastPos()[0] = obstacle_box.get().get(0);
991 vd.getLastPos()[1] = obstacle_box.get().get(1);
992 vd.getLastPos()[2] = obstacle_box.get().get(2);
993
994 vd.template getLastProp<type>() = BOUNDARY;
995 vd.template getLastProp<rho>() = rho_zero;
996 vd.template getLastProp<rho_prev>() = rho_zero;
997 vd.template getLastProp<velocity>()[0] = 0.0;
998 vd.template getLastProp<velocity>()[1] = 0.0;
999 vd.template getLastProp<velocity>()[2] = 0.0;
1000
1001 vd.template getLastProp<velocity_prev>()[0] = 0.0;
1002 vd.template getLastProp<velocity_prev>()[1] = 0.0;
1003 vd.template getLastProp<velocity_prev>()[2] = 0.0;
1004
1005 ++obstacle_box;
1006 }
1007
1008 vd.map();
1009
1011 //
1012 //
1013 //
1014
1015 size_t tot_part = vd.size_local();
1016
1017 auto & v_cl = create_vcluster();
1018 v_cl.sum(tot_part);
1019 v_cl.execute();
1020 std::cout << "SUM: " << tot_part << std::endl;
1021
1022 // Now that we fill the vector with particles
1023 ModelCustom md;
1024
1025 vd.addComputationCosts(md);
1026 vd.getDecomposition().decompose();
1027 vd.map();
1028
1029 vd.ghost_get<type,rho,Pressure,velocity>();
1030
1032 auto NN = vd.getVerletCrs(r_gskin);
1035 size_t write = 0;
1036 size_t it = 0;
1037 size_t it_reb = 0;
1038 double t = 0.0;
1039 double tot_disp = 0.0;
1040 double max_disp;
1041 while (t <= t_end)
1042 {
1043 Vcluster<> & v_cl = create_vcluster();
1044 timer it_time;
1045
1048 it_reb++;
1049 if (2*tot_disp >= skin)
1050 {
1051 vd.remove(to_remove);
1052
1053 vd.map();
1054
1055 if (it_reb > 200)
1056 {
1057 ModelCustom2 md;
1058 vd.addComputationCosts(md);
1059 vd.getDecomposition().redecompose(200);
1060
1061 vd.map();
1062
1063 it_reb = 0;
1064
1065 if (v_cl.getProcessUnitID() == 0)
1066 std::cout << "REBALANCED " << std::endl;
1067
1068 }
1069
1070 // Calculate pressure from the density
1071 EqState(vd);
1072
1073 vd.ghost_get<type,rho,Pressure,velocity>();
1074
1076 vd.updateVerlet(NN,r_gskin,VL_CRS_SYMMETRIC);
1079 tot_disp = 0.0;
1080
1081 if (v_cl.getProcessUnitID() == 0)
1082 std::cout << "RECONSTRUCT Verlet " << std::endl;
1083 }
1084 else
1085 {
1086 // Calculate pressure from the density
1087 EqState(vd);
1088
1089 vd.ghost_get<type,rho,Pressure,velocity>(SKIP_LABELLING);
1090 }
1091
1094 double max_visc = 0.0;
1095
1096 // Calc forces
1097 calc_forces(vd,NN,max_visc);
1098
1099 // Get the maximum viscosity term across processors
1100 v_cl.max(max_visc);
1101 v_cl.execute();
1102
1103 // Calculate delta t integration
1104 double dt = calc_deltaT(vd,max_visc);
1105
1108 // VerletStep or euler step
1109 it++;
1110 if (it < 40)
1111 verlet_int(vd,dt,max_disp);
1112 else
1113 {
1114 euler_int(vd,dt,max_disp);
1115 it = 0;
1116 }
1117
1118 tot_disp += max_disp;
1119
1122 t += dt;
1123
1124 if (write < t*100)
1125 {
1126 vd.deleteGhost();
1127 vd.write_frame("Geometry",write,VTK_WRITER | FORMAT_BINARY);
1128 vd.getDecomposition().write("dec" + std::to_string(write));
1129 vd.ghost_get<type,rho,Pressure,velocity>(SKIP_LABELLING);
1130 write++;
1131
1132 if (v_cl.getProcessUnitID() == 0)
1133 std::cout << "TIME: " << t << " write " << it_time.getwct() << " " << v_cl.getProcessUnitID() << " TOT disp: " << tot_disp << " " << cnt << std::endl;
1134 }
1135 else
1136 {
1137 if (v_cl.getProcessUnitID() == 0)
1138 std::cout << "TIME: " << t << " " << it_time.getwct() << " " << v_cl.getProcessUnitID() << " TOT disp: " << tot_disp << " " << cnt << std::endl;
1139 }
1140 }
1141
1142 openfpm_finalize();
1143}
1144
This class represent an N-dimensional box.
Definition Box.hpp:61
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition Box.hpp:556
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition Box.hpp:567
This class define the domain decomposition interface.
static PointIteratorSkin< dim, T, typename vd_type::Decomposition_type > DrawSkin(vd_type &vd, size_t(&sz)[dim], Box< dim, T > &domain, Box< dim, T > &sub_A, Box< dim, T > &sub_B)
Draw particles in a box B excluding the area of a second box A (B - A)
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.
void sum(T &num)
Sum the numbers across all processors and get the result.
size_t getProcessUnitID()
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
Class for Verlet list implementation.
Implementation of 1-D std::vector like structure.
Class for cpu time benchmarking.
Definition timer.hpp:28
double getwct()
Return the elapsed real time.
Definition timer.hpp:130
vect_dist_key_dx get()
Get the actual key.
Distributed vector.
void updateVerlet(VerletList< dim, St, Mem_type, shift< dim, St > > &ver, St r_cut, size_t opt=VL_NON_SYMMETRIC)
for each particle get the verlet list
size_t size_local() const
return the local size of the vector
void remove(openfpm::vector< size_t > &keys, size_t start=0)
Remove a set of elements from the distributed vector.
bool write_frame(std::string out, size_t iteration, int opt=VTK_WRITER)
Output particle position and properties.
auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
openfpm::vector_key_iterator_seq< typename vrl::Mem_type_type::local_index_type > getParticleIteratorCRS(vrl &NN)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme.
vector_dist_iterator getGhostIterator() const
Get the iterator across the position of the ghost particles.
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
auto getLastPos() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
VerletL getVerletCrs(St r_cut)
for each particle get the symmetric verlet list
void add()
Add local particle.
void addComputationCosts(const self &vd, Model md=Model())
Add the computation cost on the decomposition coming from the particles.
void deleteGhost()
Delete the particles on the ghost.
Decomposition & getDecomposition()
Get the decomposition.
Second model for dynamic load balancing.
Definition main.cpp:346
Model for Dynamic load balancing.
Definition main.cpp:222