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 
60 //#define SE_CLASS1
61 //#define STOP_ON_ERROR
62 
64 #include "Vector/vector_dist.hpp"
65 #include <math.h>
66 #include "Draw/DrawParticles.hpp"
68 
113 // A constant to indicate boundary particles
114 #define BOUNDARY 0
115 
116 // A constant to indicate fluid particles
117 #define FLUID 1
118 
119 // initial spacing between particles dp in the formulas
120 const double dp = 0.0085;
121 // Maximum height of the fluid water
122 // is going to be calculated and filled later on
123 double h_swl = 0.0;
124 
125 // c_s in the formulas (constant used to calculate the sound speed)
126 const double coeff_sound = 20.0;
127 
128 // gamma in the formulas
129 const double gamma_ = 7.0;
130 
131 // sqrt(3.0*dp*dp) support of the kernel
132 const double H = 0.0147224318643;
133 
134 // Eta in the formulas
135 const double Eta2 = 0.01 * H*H;
136 
137 // alpha in the formula
138 const double visco = 0.1;
139 
140 // cbar in the formula (calculated later)
141 double cbar = 0.0;
142 
143 // Mass of the fluid particles
144 const double MassFluid = 0.000614125;
145 
146 // Mass of the boundary particles
147 const double MassBound = 0.000614125;
148 
149 // End simulation time
150 #ifdef TEST_RUN
151 const double t_end = 0.001;
152 #else
153 const double t_end = 1.5;
154 #endif
155 
156 // Gravity acceleration
157 const double gravity = 9.81;
158 
159 // Reference densitu 1000Kg/m^3
160 const double rho_zero = 1000.0;
161 
162 // Filled later require h_swl, it is b in the formulas
163 double B = 0.0;
164 
165 // Constant used to define time integration
166 const double CFLnumber = 0.2;
167 
168 // Minimum T
169 const double DtMin = 0.00001;
170 
171 // Minimum Rho allowed
172 const double RhoMin = 700.0;
173 
174 // Maximum Rho allowed
175 const double RhoMax = 1300.0;
176 
177 // Filled in initialization
178 double max_fluid_height = 0.0;
179 
180 // Properties
181 
182 // FLUID or BOUNDARY
183 const size_t type = 0;
184 
185 // Density
186 const int rho = 1;
187 
188 // Density at step n-1
189 const int rho_prev = 2;
190 
191 // Pressure
192 const int Pressure = 3;
193 
194 // Delta rho calculated in the force calculation
195 const int drho = 4;
196 
197 // calculated force
198 const int force = 5;
199 
200 // velocity
201 const int velocity = 6;
202 
203 // velocity at previous step
204 const int velocity_prev = 7;
205 
210 // Type of the vector containing particles
212 // | | | | | | | |
213 // | | | | | | | |
214 // type density density Pressure delta force velocity velocity
215 // at n-1 density at n - 1
216 
222 {
223  template<typename Decomposition, typename vector> inline void addComputation(Decomposition & dec,
224  vector & vd,
225  size_t v,
226  size_t p)
227  {
228  if (vd.template getProp<type>(p) == FLUID)
229  dec.addComputationCost(v,4);
230  else
231  dec.addComputationCost(v,3);
232  }
233 
234  template<typename Decomposition> inline void applyModel(Decomposition & dec, size_t v)
235  {
236  dec.setSubSubDomainComputationCost(v, dec.getSubSubDomainComputationCost(v) * dec.getSubSubDomainComputationCost(v));
237  }
238 
239  double distributionTol()
240  {
241  return 1.01;
242  }
243 };
244 
262 inline void EqState(particles & vd)
263 {
264  auto it = vd.getDomainIterator();
265 
266  while (it.isNext())
267  {
268  auto a = it.get();
269 
270  double rho_a = vd.template getProp<rho>(a);
271  double rho_frac = rho_a / rho_zero;
272 
273  vd.template getProp<Pressure>(a) = B*( rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac - 1.0);
274 
275  ++it;
276  }
277 }
278 
297 const double a2 = 1.0/M_PI/H/H/H;
298 
299 inline double Wab(double r)
300 {
301  r /= H;
302 
303  if (r < 1.0)
304  return (1.0 - 3.0/2.0*r*r + 3.0/4.0*r*r*r)*a2;
305  else if (r < 2.0)
306  return (1.0/4.0*(2.0 - r*r)*(2.0 - r*r)*(2.0 - r*r))*a2;
307  else
308  return 0.0;
309 }
310 
328 const double c1 = -3.0/M_PI/H/H/H/H;
329 const double d1 = 9.0/4.0/M_PI/H/H/H/H;
330 const double c2 = -3.0/4.0/M_PI/H/H/H/H;
331 const double a2_4 = 0.25*a2;
332 // Filled later
333 double W_dap = 0.0;
334 
335 inline void DWab(Point<3,double> & dx, Point<3,double> & DW, double r, bool print)
336 {
337  const double qq=r/H;
338 
339  double qq2 = qq * qq;
340  double fac1 = (c1*qq + d1*qq2)/r;
341  double b1 = (qq < 1.0)?1.0f:0.0f;
342 
343  double wqq = (2.0 - qq);
344  double fac2 = c2 * wqq * wqq / r;
345  double b2 = (qq >= 1.0 && qq < 2.0)?1.0f:0.0f;
346 
347  double factor = (b1*fac1 + b2*fac2);
348 
349  DW.get(0) = factor * dx.get(0);
350  DW.get(1) = factor * dx.get(1);
351  DW.get(2) = factor * dx.get(2);
352 }
353 
374 // Tensile correction
375 inline double Tensile(double r, double rhoa, double rhob, double prs1, double prs2)
376 {
377  const double qq=r/H;
378  //-Cubic Spline kernel
379  double wab;
380  if(r>H)
381  {
382  double wqq1=2.0f-qq;
383  double wqq2=wqq1*wqq1;
384 
385  wab=a2_4*(wqq2*wqq1);
386  }
387  else
388  {
389  double wqq2=qq*qq;
390  double wqq3=wqq2*qq;
391 
392  wab=a2*(1.0f-1.5f*wqq2+0.75f*wqq3);
393  }
394 
395  //-Tensile correction.
396  double fab=wab*W_dap;
397  fab*=fab; fab*=fab; //fab=fab^4
398  const double tensilp1=(prs1/(rhoa*rhoa))*(prs1>0? 0.01: -0.2);
399  const double tensilp2=(prs2/(rhob*rhob))*(prs2>0? 0.01: -0.2);
400 
401  return (fab*(tensilp1+tensilp2));
402 }
403 
422 inline double Pi(const Point<3,double> & dr, double rr2, Point<3,double> & dv, double rhoa, double rhob, double massb, double & visc)
423 {
424  const double dot = dr.get(0)*dv.get(0) + dr.get(1)*dv.get(1) + dr.get(2)*dv.get(2);
425  const double dot_rr2 = dot/(rr2+Eta2);
426  visc=std::max(dot_rr2,visc);
427 
428  if(dot < 0)
429  {
430  const float amubar=H*dot_rr2;
431  const float robar=(rhoa+rhob)*0.5f;
432  const float pi_visc=(-visco*cbar*amubar/robar);
433 
434  return pi_visc;
435  }
436  else
437  return 0.0;
438 }
439 
457 template<typename CellList> inline double calc_forces(particles & vd, CellList & NN, double & max_visc)
458 {
459  auto part = vd.getDomainIterator();
460  double visc = 0;
461 
462  // Update the cell-list
463  vd.updateCellList(NN);
464 
465  // For each particle ...
466  while (part.isNext())
467  {
468  // ... a
469  auto a = part.get();
470 
471  // Get the position xp of the particle
472  Point<3,double> xa = vd.getPos(a);
473 
474  // Take the mass of the particle dependently if it is FLUID or BOUNDARY
475  double massa = (vd.getProp<type>(a) == FLUID)?MassFluid:MassBound;
476 
477  // Get the density of the of the particle a
478  double rhoa = vd.getProp<rho>(a);
479 
480  // Get the pressure of the particle a
481  double Pa = vd.getProp<Pressure>(a);
482 
483  // Get the Velocity of the particle a
484  Point<3,double> va = vd.getProp<velocity>(a);
485 
486  // Reset the force counter (- gravity on zeta direction)
487  vd.template getProp<force>(a)[0] = 0.0;
488  vd.template getProp<force>(a)[1] = 0.0;
489  vd.template getProp<force>(a)[2] = -gravity;
490  vd.template getProp<drho>(a) = 0.0;
491 
492  // We threat FLUID particle differently from BOUNDARY PARTICLES ...
493  if (vd.getProp<type>(a) != FLUID)
494  {
495  // If it is a boundary particle calculate the delta rho based on equation 2
496  // This require to run across the neighborhoods particles of a
497  auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(a)));
498 
499  // For each neighborhood particle
500  while (Np.isNext() == true)
501  {
502  // ... q
503  auto b = Np.get();
504 
505  // Get the position xp of the particle
506  Point<3,double> xb = vd.getPos(b);
507 
508  // if (p == q) skip this particle
509  if (a.getKey() == b) {++Np; continue;};
510 
511  // get the mass of the particle
512  double massb = (vd.getProp<type>(b) == FLUID)?MassFluid:MassBound;
513 
514  // Get the velocity of the particle b
515  Point<3,double> vb = vd.getProp<velocity>(b);
516 
517  // Get the pressure and density of particle b
518  double Pb = vd.getProp<Pressure>(b);
519  double rhob = vd.getProp<rho>(b);
520 
521  // Get the distance between p and q
522  Point<3,double> dr = xa - xb;
523  // take the norm of this vector
524  double r2 = norm2(dr);
525 
526  // If the particles interact ...
527  if (r2 < 4.0*H*H)
528  {
529  // ... calculate delta rho
530  double r = sqrt(r2);
531 
532  Point<3,double> dv = va - vb;
533 
534  Point<3,double> DW;
535  DWab(dr,DW,r,false);
536 
537  const double dot = dr.get(0)*dv.get(0) + dr.get(1)*dv.get(1) + dr.get(2)*dv.get(2);
538  const double dot_rr2 = dot/(r2+Eta2);
539  max_visc=std::max(dot_rr2,max_visc);
540 
541  vd.getProp<drho>(a) += massb*(dv.get(0)*DW.get(0)+dv.get(1)*DW.get(1)+dv.get(2)*DW.get(2));
542  }
543 
544  ++Np;
545  }
546  }
547  else
548  {
549  // If it is a fluid particle calculate based on equation 1 and 2
550 
551  // Get an iterator over the neighborhood particles of p
552  auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(a)));
553 
554  // For each neighborhood particle
555  while (Np.isNext() == true)
556  {
557  // ... q
558  auto b = Np.get();
559 
560  // Get the position xp of the particle
561  Point<3,double> xb = vd.getPos(b);
562 
563  // if (p == q) skip this particle
564  if (a.getKey() == b) {++Np; continue;};
565 
566  double massb = (vd.getProp<type>(b) == FLUID)?MassFluid:MassBound;
567  Point<3,double> vb = vd.getProp<velocity>(b);
568  double Pb = vd.getProp<Pressure>(b);
569  double rhob = vd.getProp<rho>(b);
570 
571  // Get the distance between p and q
572  Point<3,double> dr = xa - xb;
573  // take the norm of this vector
574  double r2 = norm2(dr);
575 
576  // if they interact
577  if (r2 < 4.0*H*H)
578  {
579  double r = sqrt(r2);
580 
581  Point<3,double> v_rel = va - vb;
582 
583  Point<3,double> DW;
584  DWab(dr,DW,r,false);
585 
586  double factor = - massb*((vd.getProp<Pressure>(a) + vd.getProp<Pressure>(b)) / (rhoa * rhob) + Tensile(r,rhoa,rhob,Pa,Pb) + Pi(dr,r2,v_rel,rhoa,rhob,massb,visc));
587 
588  vd.getProp<force>(a)[0] += factor * DW.get(0);
589  vd.getProp<force>(a)[1] += factor * DW.get(1);
590  vd.getProp<force>(a)[2] += factor * DW.get(2);
591 
592  vd.getProp<drho>(a) += massb*(v_rel.get(0)*DW.get(0)+v_rel.get(1)*DW.get(1)+v_rel.get(2)*DW.get(2));
593  }
594 
595  ++Np;
596  }
597  }
598 
599  ++part;
600  }
601 }
602 
621 void max_acceleration_and_velocity(particles & vd, double & max_acc, double & max_vel)
622 {
623  // Calculate the maximum acceleration
624  auto part = vd.getDomainIterator();
625 
626  while (part.isNext())
627  {
628  auto a = part.get();
629 
630  Point<3,double> acc(vd.getProp<force>(a));
631  double acc2 = norm2(acc);
632 
633  Point<3,double> vel(vd.getProp<velocity>(a));
634  double vel2 = norm2(vel);
635 
636  if (vel2 >= max_vel)
637  max_vel = vel2;
638 
639  if (acc2 >= max_acc)
640  max_acc = acc2;
641 
642  ++part;
643  }
644  max_acc = sqrt(max_acc);
645  max_vel = sqrt(max_vel);
646 
647  Vcluster & v_cl = create_vcluster();
648  v_cl.max(max_acc);
649  v_cl.max(max_vel);
650  v_cl.execute();
651 }
652 
678 double calc_deltaT(particles & vd, double ViscDtMax)
679 {
680  double Maxacc = 0.0;
681  double Maxvel = 0.0;
682  max_acceleration_and_velocity(vd,Maxacc,Maxvel);
683 
684  //-dt1 depends on force per unit mass.
685  const double dt_f = (Maxacc)?sqrt(H/Maxacc):std::numeric_limits<int>::max();
686 
687  //-dt2 combines the Courant and the viscous time-step controls.
688  const double dt_cv = H/(std::max(cbar,Maxvel*10.) + H*ViscDtMax);
689 
690  //-dt new value of time step.
691  double dt=double(CFLnumber)*std::min(dt_f,dt_cv);
692  if(dt<double(DtMin))
693  dt=double(DtMin);
694 
695  return dt;
696 }
697 
731 openfpm::vector<size_t> to_remove;
732 
733 size_t cnt = 0;
734 
735 void verlet_int(particles & vd, double dt)
736 {
737  // list of the particle to remove
738  to_remove.clear();
739 
740  // particle iterator
741  auto part = vd.getDomainIterator();
742 
743  double dt205 = dt*dt*0.5;
744  double dt2 = dt*2.0;
745 
746  // For each particle ...
747  while (part.isNext())
748  {
749  // ... a
750  auto a = part.get();
751 
752  // if the particle is boundary
753  if (vd.template getProp<type>(a) == BOUNDARY)
754  {
755  // Update rho
756  double rhop = vd.template getProp<rho>(a);
757 
758  // Update only the density
759  vd.template getProp<velocity>(a)[0] = 0.0;
760  vd.template getProp<velocity>(a)[1] = 0.0;
761  vd.template getProp<velocity>(a)[2] = 0.0;
762  vd.template getProp<rho>(a) = vd.template getProp<rho_prev>(a) + dt2*vd.template getProp<drho>(a);
763 
764  vd.template getProp<rho_prev>(a) = rhop;
765 
766  ++part;
767  continue;
768  }
769 
770  //-Calculate displacement and update position / Calcula desplazamiento y actualiza posicion.
771  double dx = vd.template getProp<velocity>(a)[0]*dt + vd.template getProp<force>(a)[0]*dt205;
772  double dy = vd.template getProp<velocity>(a)[1]*dt + vd.template getProp<force>(a)[1]*dt205;
773  double dz = vd.template getProp<velocity>(a)[2]*dt + vd.template getProp<force>(a)[2]*dt205;
774 
775  vd.getPos(a)[0] += dx;
776  vd.getPos(a)[1] += dy;
777  vd.getPos(a)[2] += dz;
778 
779  double velX = vd.template getProp<velocity>(a)[0];
780  double velY = vd.template getProp<velocity>(a)[1];
781  double velZ = vd.template getProp<velocity>(a)[2];
782  double rhop = vd.template getProp<rho>(a);
783 
784  vd.template getProp<velocity>(a)[0] = vd.template getProp<velocity_prev>(a)[0] + vd.template getProp<force>(a)[0]*dt2;
785  vd.template getProp<velocity>(a)[1] = vd.template getProp<velocity_prev>(a)[1] + vd.template getProp<force>(a)[1]*dt2;
786  vd.template getProp<velocity>(a)[2] = vd.template getProp<velocity_prev>(a)[2] + vd.template getProp<force>(a)[2]*dt2;
787  vd.template getProp<rho>(a) = vd.template getProp<rho_prev>(a) + dt2*vd.template getProp<drho>(a);
788 
789  // Check if the particle go out of range in space and in density
790  if (vd.getPos(a)[0] < 0.000263878 || vd.getPos(a)[1] < 0.000263878 || vd.getPos(a)[2] < 0.000263878 ||
791  vd.getPos(a)[0] > 0.000263878+1.59947 || vd.getPos(a)[1] > 0.000263878+0.672972 || vd.getPos(a)[2] > 0.000263878+0.903944 ||
792  vd.template getProp<rho>(a) < RhoMin || vd.template getProp<rho>(a) > RhoMax)
793  {
794  to_remove.add(a.getKey());
795  }
796 
797  vd.template getProp<velocity_prev>(a)[0] = velX;
798  vd.template getProp<velocity_prev>(a)[1] = velY;
799  vd.template getProp<velocity_prev>(a)[2] = velZ;
800  vd.template getProp<rho_prev>(a) = rhop;
801 
802  ++part;
803  }
804 
805  // remove the particles
806  vd.remove(to_remove,0);
807 
808  // increment the iteration counter
809  cnt++;
810 }
811 
812 void euler_int(particles & vd, double dt)
813 {
814  // list of the particle to remove
815  to_remove.clear();
816 
817  // particle iterator
818  auto part = vd.getDomainIterator();
819 
820  double dt205 = dt*dt*0.5;
821  double dt2 = dt*2.0;
822 
823  // For each particle ...
824  while (part.isNext())
825  {
826  // ... a
827  auto a = part.get();
828 
829  // if the particle is boundary
830  if (vd.template getProp<type>(a) == BOUNDARY)
831  {
832  // Update rho
833  double rhop = vd.template getProp<rho>(a);
834 
835  // Update only the density
836  vd.template getProp<velocity>(a)[0] = 0.0;
837  vd.template getProp<velocity>(a)[1] = 0.0;
838  vd.template getProp<velocity>(a)[2] = 0.0;
839  vd.template getProp<rho>(a) = vd.template getProp<rho>(a) + dt*vd.template getProp<drho>(a);
840 
841  vd.template getProp<rho_prev>(a) = rhop;
842 
843  ++part;
844  continue;
845  }
846 
847  //-Calculate displacement and update position / Calcula desplazamiento y actualiza posicion.
848  double dx = vd.template getProp<velocity>(a)[0]*dt + vd.template getProp<force>(a)[0]*dt205;
849  double dy = vd.template getProp<velocity>(a)[1]*dt + vd.template getProp<force>(a)[1]*dt205;
850  double dz = vd.template getProp<velocity>(a)[2]*dt + vd.template getProp<force>(a)[2]*dt205;
851 
852  vd.getPos(a)[0] += dx;
853  vd.getPos(a)[1] += dy;
854  vd.getPos(a)[2] += dz;
855 
856  double velX = vd.template getProp<velocity>(a)[0];
857  double velY = vd.template getProp<velocity>(a)[1];
858  double velZ = vd.template getProp<velocity>(a)[2];
859  double rhop = vd.template getProp<rho>(a);
860 
861  vd.template getProp<velocity>(a)[0] = vd.template getProp<velocity>(a)[0] + vd.template getProp<force>(a)[0]*dt;
862  vd.template getProp<velocity>(a)[1] = vd.template getProp<velocity>(a)[1] + vd.template getProp<force>(a)[1]*dt;
863  vd.template getProp<velocity>(a)[2] = vd.template getProp<velocity>(a)[2] + vd.template getProp<force>(a)[2]*dt;
864  vd.template getProp<rho>(a) = vd.template getProp<rho>(a) + dt*vd.template getProp<drho>(a);
865 
866  // Check if the particle go out of range in space and in density
867  if (vd.getPos(a)[0] < 0.000263878 || vd.getPos(a)[1] < 0.000263878 || vd.getPos(a)[2] < 0.000263878 ||
868  vd.getPos(a)[0] > 0.000263878+1.59947 || vd.getPos(a)[1] > 0.000263878+0.672972 || vd.getPos(a)[2] > 0.000263878+0.903944 ||
869  vd.template getProp<rho>(a) < RhoMin || vd.template getProp<rho>(a) > RhoMax)
870  {
871  to_remove.add(a.getKey());
872  }
873 
874  vd.template getProp<velocity_prev>(a)[0] = velX;
875  vd.template getProp<velocity_prev>(a)[1] = velY;
876  vd.template getProp<velocity_prev>(a)[2] = velZ;
877  vd.template getProp<rho_prev>(a) = rhop;
878 
879  ++part;
880  }
881 
882  // remove the particles
883  vd.remove(to_remove,0);
884 
885  // increment the iteration counter
886  cnt++;
887 }
888 
916 template<typename Vector, typename CellList>
917 inline void sensor_pressure(Vector & vd,
918  CellList & NN,
921 {
922  Vcluster & v_cl = create_vcluster();
923 
924  press_t.add();
925 
926  for (size_t i = 0 ; i < probes.size() ; i++)
927  {
928  float press_tmp = 0.0f;
929  float tot_ker = 0.0;
930 
931  // if the probe is inside the processor domain
932  if (vd.getDecomposition().isLocal(probes.get(i)) == true)
933  {
934  // Get the position of the probe i
935  Point<3,double> xp = probes.get(i);
936 
937  // get the iterator over the neighbohood particles of the probes position
938  auto itg = NN.template getNNIterator<NO_CHECK>(NN.getCell(probes.get(i)));
939  while (itg.isNext())
940  {
941  auto q = itg.get();
942 
943  // Only the fluid particles are importants
944  if (vd.template getProp<type>(q) != FLUID)
945  {
946  ++itg;
947  continue;
948  }
949 
950  // Get the position of the neighborhood particle q
951  Point<3,double> xq = vd.template getPos(q);
952 
953  // Calculate the contribution of the particle to the pressure
954  // of the probe
955  double r = sqrt(norm2(xp - xq));
956 
957  double ker = Wab(r) * (MassFluid / rho_zero);
958 
959  // Also keep track of the calculation of the summed
960  // kernel
961  tot_ker += ker;
962 
963  // Add the total pressure contribution
964  press_tmp += vd.template getProp<Pressure>(q) * ker;
965 
966  // next neighborhood particle
967  ++itg;
968  }
969 
970  // We calculate the pressure normalizing the
971  // sum over all kernels
972  if (tot_ker == 0.0)
973  press_tmp = 0.0;
974  else
975  press_tmp = 1.0 / tot_ker * press_tmp;
976 
977  }
978 
979  // This is not necessary in principle, but if you
980  // want to make all processor aware of the history of the calculated
981  // pressure we have to execute this
982  v_cl.sum(press_tmp);
983  v_cl.execute();
984 
985  // We add the calculated pressure into the history
986  press_t.last().add(press_tmp);
987  }
988 }
989 
992 int main(int argc, char* argv[])
993 {
1009 
1011  // initialize the library
1012  openfpm_init(&argc,&argv);
1013 
1014  // It contain for each time-step the value detected by the probes
1017 
1018  probes.add({0.8779,0.3,0.02});
1019  probes.add({0.754,0.31,0.02});
1020 
1021  // Here we define our domain a 2D box with internals from 0 to 1.0 for x and y
1022  Box<3,double> domain({-0.05,-0.05,-0.05},{1.7010,0.7065,0.5025});
1023  size_t sz[3] = {207,90,66};
1024 
1025  // Fill W_dap
1026  W_dap = 1.0/Wab(H/1.5);
1027 
1028  // Here we define the boundary conditions of our problem
1029  size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
1030 
1031  // extended boundary around the domain, and the processor domain
1032  Ghost<3,double> g(2*H);
1033 
1035 
1071 
1073  particles vd(0,domain,bc,g,DEC_GRAN(512));
1074 
1076 
1111 
1113  // You can ignore all these dp/2.0 is a trick to reach the same initialization
1114  // of Dual-SPH that use a different criteria to draw particles
1115  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});
1116 
1117  // return an iterator to the fluid particles to add to vd
1118  auto fluid_it = DrawParticles::DrawBox(vd,sz,domain,fluid_box);
1119 
1120  // here we fill some of the constants needed by the simulation
1121  max_fluid_height = fluid_it.getBoxMargins().getHigh(2);
1122  h_swl = fluid_it.getBoxMargins().getHigh(2) - fluid_it.getBoxMargins().getLow(2);
1123  B = (coeff_sound)*(coeff_sound)*gravity*h_swl*rho_zero / gamma_;
1124  cbar = coeff_sound * sqrt(gravity * h_swl);
1125 
1126  // for each particle inside the fluid box ...
1127  while (fluid_it.isNext())
1128  {
1129  // ... add a particle ...
1130  vd.add();
1131 
1132  // ... and set it position ...
1133  vd.getLastPos()[0] = fluid_it.get().get(0);
1134  vd.getLastPos()[1] = fluid_it.get().get(1);
1135  vd.getLastPos()[2] = fluid_it.get().get(2);
1136 
1137  // and its type.
1138  vd.template getLastProp<type>() = FLUID;
1139 
1140  // We also initialize the density of the particle and the hydro-static pressure given by
1141  //
1142  // rho_zero*g*h = P
1143  //
1144  // rho_p = (P/B + 1)^(1/Gamma) * rho_zero
1145  //
1146 
1147  vd.template getLastProp<Pressure>() = rho_zero * gravity * (max_fluid_height - fluid_it.get().get(2));
1148 
1149  vd.template getLastProp<rho>() = pow(vd.template getLastProp<Pressure>() / B + 1, 1.0/gamma_) * rho_zero;
1150  vd.template getLastProp<rho_prev>() = vd.template getLastProp<rho>();
1151  vd.template getLastProp<velocity>()[0] = 0.0;
1152  vd.template getLastProp<velocity>()[1] = 0.0;
1153  vd.template getLastProp<velocity>()[2] = 0.0;
1154 
1155  vd.template getLastProp<velocity_prev>()[0] = 0.0;
1156  vd.template getLastProp<velocity_prev>()[1] = 0.0;
1157  vd.template getLastProp<velocity_prev>()[2] = 0.0;
1158 
1159  // next fluid particle
1160  ++fluid_it;
1161  }
1162 
1164 
1188 
1190  // Recipient
1191  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});
1192  Box<3,double> recipient2({dp,dp,dp},{1.6-dp/2.0,0.67-dp/2.0,0.4+dp/2.0});
1193 
1194  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});
1195  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});
1196  Box<3,double> obstacle3({0.9+dp,0.24,0.0},{1.02,0.36,0.45});
1197 
1199  holes.add(recipient2);
1200  holes.add(obstacle1);
1201  auto bound_box = DrawParticles::DrawSkin(vd,sz,domain,holes,recipient1);
1202 
1203  while (bound_box.isNext())
1204  {
1205  vd.add();
1206 
1207  vd.getLastPos()[0] = bound_box.get().get(0);
1208  vd.getLastPos()[1] = bound_box.get().get(1);
1209  vd.getLastPos()[2] = bound_box.get().get(2);
1210 
1211  vd.template getLastProp<type>() = BOUNDARY;
1212  vd.template getLastProp<rho>() = rho_zero;
1213  vd.template getLastProp<rho_prev>() = rho_zero;
1214  vd.template getLastProp<velocity>()[0] = 0.0;
1215  vd.template getLastProp<velocity>()[1] = 0.0;
1216  vd.template getLastProp<velocity>()[2] = 0.0;
1217 
1218  vd.template getLastProp<velocity_prev>()[0] = 0.0;
1219  vd.template getLastProp<velocity_prev>()[1] = 0.0;
1220  vd.template getLastProp<velocity_prev>()[2] = 0.0;
1221 
1222  ++bound_box;
1223  }
1224 
1226 
1243 
1245  auto obstacle_box = DrawParticles::DrawSkin(vd,sz,domain,obstacle2,obstacle1);
1246 
1247  while (obstacle_box.isNext())
1248  {
1249  vd.add();
1250 
1251  vd.getLastPos()[0] = obstacle_box.get().get(0);
1252  vd.getLastPos()[1] = obstacle_box.get().get(1);
1253  vd.getLastPos()[2] = obstacle_box.get().get(2);
1254 
1255  vd.template getLastProp<type>() = BOUNDARY;
1256  vd.template getLastProp<rho>() = rho_zero;
1257  vd.template getLastProp<rho_prev>() = rho_zero;
1258  vd.template getLastProp<velocity>()[0] = 0.0;
1259  vd.template getLastProp<velocity>()[1] = 0.0;
1260  vd.template getLastProp<velocity>()[2] = 0.0;
1261 
1262  vd.template getLastProp<velocity_prev>()[0] = 0.0;
1263  vd.template getLastProp<velocity_prev>()[1] = 0.0;
1264  vd.template getLastProp<velocity_prev>()[2] = 0.0;
1265 
1266  ++obstacle_box;
1267  }
1268 
1269  vd.map();
1270 
1272 
1354 
1356  // Now that we fill the vector with particles
1357  ModelCustom md;
1358 
1359  vd.addComputationCosts(md);
1360  vd.getDecomposition().decompose();
1361  vd.map();
1362 
1364 
1365  vd.ghost_get<type,rho,Pressure,velocity>();
1366 
1367  auto NN = vd.getCellList(2*H);
1368 
1369  // Evolve
1370 
1385 
1387  size_t write = 0;
1388  size_t it = 0;
1389  size_t it_reb = 0;
1390  double t = 0.0;
1391  while (t <= t_end)
1392  {
1393  Vcluster & v_cl = create_vcluster();
1394  timer it_time;
1395 
1397  it_reb++;
1398  if (it_reb == 200)
1399  {
1400  vd.map();
1401 
1402  it_reb = 0;
1403  ModelCustom md;
1404  vd.addComputationCosts(md);
1405  vd.getDecomposition().decompose();
1406 
1407  if (v_cl.getProcessUnitID() == 0)
1408  std::cout << "REBALANCED " << std::endl;
1409  }
1410 
1411  vd.map();
1412 
1413  // Calculate pressure from the density
1414  EqState(vd);
1415 
1416  double max_visc = 0.0;
1417 
1418  vd.ghost_get<type,rho,Pressure,velocity>();
1419 
1420  // Calc forces
1421  calc_forces(vd,NN,max_visc);
1422 
1423  // Get the maximum viscosity term across processors
1424  v_cl.max(max_visc);
1425  v_cl.execute();
1426 
1427  // Calculate delta t integration
1428  double dt = calc_deltaT(vd,max_visc);
1429 
1430  // VerletStep or euler step
1431  it++;
1432  if (it < 40)
1433  verlet_int(vd,dt);
1434  else
1435  {
1436  euler_int(vd,dt);
1437  it = 0;
1438  }
1439 
1440  t += dt;
1441 
1442  if (write < t*100)
1443  {
1444  // calculate the pressure at the sensor points
1445  sensor_pressure(vd,NN,press_t,probes);
1446 
1447  vd.write("Geometry",write);
1448  write++;
1449 
1450  if (v_cl.getProcessUnitID() == 0)
1451  std::cout << "TIME: " << t << " write " << it_time.getwct() << " " << v_cl.getProcessUnitID() << " " << cnt << std::endl;
1452  }
1453  else
1454  {
1455  if (v_cl.getProcessUnitID() == 0)
1456  std::cout << "TIME: " << t << " " << it_time.getwct() << " " << v_cl.getProcessUnitID() << " " << cnt << std::endl;
1457  }
1458  }
1459 
1461 
1475 
1477  openfpm_finalize();
1478 
1480 
1489 }
1490 
void sum(T &num)
Sum the numbers across all processors and get the result.
auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
size_t getProcessUnitID()
Get the process unit id.
static PointIteratorSkin< dim, T, Decomposition > DrawSkin(vector_dist< dim, T, aggr, layout, layout_base, Decomposition > &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)
void execute()
Execute all the requests.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support...
Definition: Vector.hpp:39
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
double getwct()
Return the elapsed real time.
Definition: timer.hpp:108
Definition: Ghost.hpp:39
void updateCellList(CellL &cell_list, bool no_se3=false)
Update a cell list using the stored particles.
Implementation of VCluster class.
Definition: VCluster.hpp:36
This class define the domain decomposition interface.
void remove(openfpm::vector< size_t > &keys, size_t start=0)
Remove a set of elements from the distributed vector.
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
This class represent an N-dimensional box.
Definition: Box.hpp:56
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
Distributed vector.
vect_dist_key_dx get()
Get the actual key.
Model for Dynamic load balancing.
Definition: main.cpp:221
Class for FAST cell list implementation.
Definition: CellList.hpp:269
Class for cpu time benchmarking.
Definition: timer.hpp:25
static PointIterator< dim, T, Decomposition > DrawBox(vector_dist< dim, T, aggr, layout, layout_base, Decomposition > &vd, size_t(&sz)[dim], Box< dim, T > &domain, Box< dim, T > &sub)
Draw particles in a box.