OpenFPM  5.2.0
Project that contain the implementation of distributed structures
main.cpp
1 
59 //#define SE_CLASS1
60 //#define STOP_ON_ERROR
61 
63 #include "Vector/vector_dist.hpp"
64 #include "Operators/Vector/vector_dist_operators.hpp"
65 #include "Draw/DrawParticles.hpp"
66 
67 #include <math.h>
69 
114 // A constant to indicate boundary particles
115 #define BOUNDARY 0
116 
117 // A constant to indicate fluid particles
118 #define FLUID 1
119 
120 // initial spacing between particles dp in the formulas
121 const double dp = 0.0085;
122 // Maximum height of the fluid water
123 // is going to be calculated and filled later on
124 double h_swl = 0.0;
125 
126 // c_s in the formulas (constant used to calculate the sound speed)
127 const double coeff_sound = 20.0;
128 
129 // gamma in the formulas
130 const double gamma_ = 7.0;
131 
132 // sqrt(3.0*dp*dp) support of the kernel
133 const double H = 0.0147224318643;
134 
135 // Eta in the formulas
136 const double Eta2 = 0.01 * H*H;
137 
138 // alpha in the formula
139 const double visco = 0.1;
140 
141 // cbar in the formula (calculated later)
142 double cbar = 0.0;
143 
144 // Mass of the fluid particles
145 const double MassFluid = 0.000614125;
146 
147 // Mass of the boundary particles
148 const double MassBound = 0.000614125;
149 
150 // End simulation time
151 #ifdef TEST_RUN
152 const double t_end = 0.001;
153 #else
154 const double t_end = 1.5;
155 #endif
156 
157 // Gravity acceleration
158 const double gravity = 9.81;
159 
160 // Reference densitu 1000Kg/m^3
161 const double RhoZero = 1000.0;
162 
163 // Filled later require h_swl, it is b in the formulas
164 double B = 0.0;
165 
166 // Constant used to define time integration
167 const double CFLnumber = 0.2;
168 
169 // Minimum T
170 const double DtMin = 0.00001;
171 
172 // Minimum Rho allowed
173 const double RhoMin = 700.0;
174 
175 // Maximum Rho allowed
176 const double RhoMax = 1300.0;
177 
178 // Filled in initialization
179 double max_fluid_height = 0.0;
180 
181 // Properties
182 
183 // FLUID or BOUNDARY
184 const size_t TYPE = 0;
185 
186 // Density
187 const int RHO = 1;
188 
189 // Density at step n-1
190 const int RHO_PREV = 2;
191 
192 // Density temporal variable
193 // needed for template expression
194 const int RHO_TMP = 8;
195 
196 // Pressure
197 const int PRESSURE = 3;
198 
199 // Delta rho calculated in the force calculation
200 const int DRHO = 4;
201 
202 // calculated force
203 const int FORCE = 5;
204 
205 // velocity
206 const int VELOCITY = 6;
207 
208 // velocity at previous step
209 const int VELOCITY_PREV = 7;
210 
211 // velocity temporal variable
212 // needed for template expression
213 const int VELOCITY_TMP = 9;
214 
219 // Type of the vector containing particles
221 // | | | | | | | | | |
222 // | | | | | | | | | |
223 // type density density Pressure delta force velocity velocity density velocity
224 // at n-1 density at n - 1
226 
232 {
233  template<typename Decomposition, typename vector> inline void addComputation(Decomposition & dec,
234  vector & vectorDist,
235  size_t v,
236  size_t p)
237  {
238  if (vectorDist.template getProp<TYPE>(p) == FLUID)
239  dec.addComputationCost(v,4);
240  else
241  dec.addComputationCost(v,3);
242  }
243 
244  template<typename Decomposition> inline void applyModel(Decomposition & dec, size_t v)
245  {
246  dec.setSubSubDomainComputationCost(v, dec.getSubSubDomainComputationCost(v) * dec.getSubSubDomainComputationCost(v));
247  }
248 
249  double distributionTol()
250  {
251  return 1.01;
252  }
253 };
254 
272 inline void EqState(vector_dist_type & vectorDist)
273 {
274  auto it = vectorDist.getDomainIterator();
275 
276  while (it.isNext())
277  {
278  auto a = it.get();
279 
280  double rho_a = vectorDist.template getProp<RHO>(a);
281  double rho_frac = rho_a / RhoZero;
282 
283  vectorDist.template getProp<PRESSURE>(a) = B*( rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac - 1.0);
284 
285  ++it;
286  }
287 }
288 
307 const double a2 = 1.0/M_PI/H/H/H;
308 
309 inline double Wab(double r)
310 {
311  r /= H;
312 
313  if (r < 1.0)
314  return (1.0 - 3.0/2.0*r*r + 3.0/4.0*r*r*r)*a2;
315  else if (r < 2.0)
316  return (1.0/4.0*(2.0 - r)*(2.0 - r)*(2.0 - r))*a2;
317  else
318  return 0.0;
319 }
320 
338 const double c1 = -3.0/M_PI/H/H/H/H;
339 const double d1 = 9.0/4.0/M_PI/H/H/H/H;
340 const double c2 = -3.0/4.0/M_PI/H/H/H/H;
341 const double a2_4 = 0.25*a2;
342 // Filled later
343 double W_dap = 0.0;
344 
345 inline void DWab(Point<3,double> & dx, Point<3,double> & DW, double r, bool print)
346 {
347  const double qq=r/H;
348 
349  double qq2 = qq * qq;
350  double fac1 = (c1*qq + d1*qq2)/r;
351  double b1 = (qq < 1.0)?1.0f:0.0f;
352 
353  double wqq = (2.0 - qq);
354  double fac2 = c2 * wqq * wqq / r;
355  double b2 = (qq >= 1.0 && qq < 2.0)?1.0f:0.0f;
356 
357  double factor = (b1*fac1 + b2*fac2);
358 
359  DW.get(0) = factor * dx.get(0);
360  DW.get(1) = factor * dx.get(1);
361  DW.get(2) = factor * dx.get(2);
362 }
363 
384 // Tensile correction
385 inline double Tensile(double r, double rhoa, double rhob, double prs1, double prs2)
386 {
387  const double qq=r/H;
388  //-Cubic Spline kernel
389  double wab;
390  if(r>H)
391  {
392  double wqq1=2.0f-qq;
393  double wqq2=wqq1*wqq1;
394 
395  wab=a2_4*(wqq2*wqq1);
396  }
397  else
398  {
399  double wqq2=qq*qq;
400  double wqq3=wqq2*qq;
401 
402  wab=a2*(1.0f-1.5f*wqq2+0.75f*wqq3);
403  }
404 
405  //-Tensile correction.
406  double fab=wab*W_dap;
407  fab*=fab; fab*=fab; //fab=fab^4
408  const double tensilp1=(prs1/(rhoa*rhoa))*(prs1>0? 0.01: -0.2);
409  const double tensilp2=(prs2/(rhob*rhob))*(prs2>0? 0.01: -0.2);
410 
411  return (fab*(tensilp1+tensilp2));
412 }
413 
432 inline double Pi(const Point<3,double> & dr, double rr2, Point<3,double> & dv, double rhoa, double rhob, double massb, double & visc)
433 {
434  const double dot = dr.get(0)*dv.get(0) + dr.get(1)*dv.get(1) + dr.get(2)*dv.get(2);
435  const double dot_rr2 = dot/(rr2+Eta2);
436  visc=std::max(dot_rr2,visc);
437 
438  if(dot < 0)
439  {
440  const float amubar=H*dot_rr2;
441  const float robar=(rhoa+rhob)*0.5f;
442  const float pi_visc=(-visco*cbar*amubar/robar);
443 
444  return pi_visc;
445  }
446  else
447  return 0.0;
448 }
449 
467 template<typename CellList> inline void calc_forces(vector_dist_type & vectorDist, CellList & NN, double & max_visc)
468 {
469  auto part = vectorDist.getDomainIterator();
470 
471  // Update the cell-list
472  vectorDist.updateCellList(NN);
473 
474  // For each particle ...
475  while (part.isNext())
476  {
477  // ... a
478  auto a = part.get();
479 
480  // Get the position xp of the particle
481  Point<3,double> xa = vectorDist.getPos(a);
482 
483  // Take the mass of the particle dependently if it is FLUID or BOUNDARY
484  double massa = (vectorDist.getProp<TYPE>(a) == FLUID)?MassFluid:MassBound;
485 
486  // Get the density of the of the particle a
487  double rhoa = vectorDist.getProp<RHO>(a);
488 
489  // Get the pressure of the particle a
490  double Pa = vectorDist.getProp<PRESSURE>(a);
491 
492  // Get the Velocity of the particle a
493  Point<3,double> va = vectorDist.getProp<VELOCITY>(a);
494 
495  // Reset the force counter (- gravity on zeta direction)
496  vectorDist.template getProp<FORCE>(a)[0] = 0.0;
497  vectorDist.template getProp<FORCE>(a)[1] = 0.0;
498  vectorDist.template getProp<FORCE>(a)[2] = -gravity;
499  vectorDist.template getProp<DRHO>(a) = 0.0;
500 
501  // We threat FLUID particle differently from BOUNDARY PARTICLES ...
502  if (vectorDist.getProp<TYPE>(a) != FLUID)
503  {
504  // If it is a boundary particle calculate the delta rho based on equation 2
505  // This require to run across the neighborhoods particles of a
506  auto Np = NN.getNNIteratorBox(NN.getCell(vectorDist.getPos(a)));
507 
508  // For each neighborhood particle
509  while (Np.isNext() == true)
510  {
511  // ... q
512  auto b = Np.get();
513 
514  // Get the position xp of the particle
515  Point<3,double> xb = vectorDist.getPos(b);
516 
517  // if (p == q) skip this particle
518  if (a.getKey() == b) {++Np; continue;};
519 
520  // get the mass of the particle
521  double massb = (vectorDist.getProp<TYPE>(b) == FLUID)?MassFluid:MassBound;
522 
523  // Get the velocity of the particle b
524  Point<3,double> vb = vectorDist.getProp<VELOCITY>(b);
525 
526  // Get the pressure and density of particle b
527  double Pb = vectorDist.getProp<PRESSURE>(b);
528  double rhob = vectorDist.getProp<RHO>(b);
529 
530  // Get the distance between p and q
531  Point<3,double> dr = xa - xb;
532  // take the norm of this vector
533  double r2 = norm2(dr);
534 
535  // If the particles interact ...
536  if (r2 < 4.0*H*H)
537  {
538  // ... calculate delta rho
539  double r = sqrt(r2);
540 
541  Point<3,double> dv = va - vb;
542 
543  Point<3,double> DW;
544  DWab(dr,DW,r,false);
545 
546  const double dot = dr.get(0)*dv.get(0) + dr.get(1)*dv.get(1) + dr.get(2)*dv.get(2);
547  const double dot_rr2 = dot/(r2+Eta2);
548  max_visc=std::max(dot_rr2,max_visc);
549 
550  vectorDist.getProp<DRHO>(a) += massb*(dv.get(0)*DW.get(0)+dv.get(1)*DW.get(1)+dv.get(2)*DW.get(2));
551  }
552 
553  ++Np;
554  }
555  }
556  else
557  {
558  // If it is a fluid particle calculate based on equation 1 and 2
559 
560  // Get an iterator over the neighborhood particles of p
561  auto Np = NN.getNNIteratorBox(NN.getCell(vectorDist.getPos(a)));
562 
563  // For each neighborhood particle
564  while (Np.isNext() == true)
565  {
566  // ... q
567  auto b = Np.get();
568 
569  // Get the position xp of the particle
570  Point<3,double> xb = vectorDist.getPos(b);
571 
572  // if (p == q) skip this particle
573  if (a.getKey() == b) {++Np; continue;};
574 
575  double massb = (vectorDist.getProp<TYPE>(b) == FLUID)?MassFluid:MassBound;
576  Point<3,double> vb = vectorDist.getProp<VELOCITY>(b);
577  double Pb = vectorDist.getProp<PRESSURE>(b);
578  double rhob = vectorDist.getProp<RHO>(b);
579 
580  // Get the distance between p and q
581  Point<3,double> dr = xa - xb;
582  // take the norm of this vector
583  double r2 = norm2(dr);
584 
585  // if they interact
586  if (r2 < 4.0*H*H)
587  {
588  double r = sqrt(r2);
589 
590  Point<3,double> v_rel = va - vb;
591 
592  Point<3,double> DW;
593  DWab(dr,DW,r,false);
594 
595  double factor = - massb*((vectorDist.getProp<PRESSURE>(a) + vectorDist.getProp<PRESSURE>(b)) / (rhoa * rhob) + Tensile(r,rhoa,rhob,Pa,Pb) + Pi(dr,r2,v_rel,rhoa,rhob,massb,max_visc));
596 
597  vectorDist.getProp<FORCE>(a)[0] += factor * DW.get(0);
598  vectorDist.getProp<FORCE>(a)[1] += factor * DW.get(1);
599  vectorDist.getProp<FORCE>(a)[2] += factor * DW.get(2);
600 
601  vectorDist.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));
602  }
603 
604  ++Np;
605  }
606  }
607 
608  ++part;
609  }
610 }
611 
630 void max_acceleration_and_velocity(vector_dist_type & vectorDist, double & max_acc, double & max_vel)
631 {
632  // Calculate the maximum acceleration
633  auto part = vectorDist.getDomainIterator();
634 
635  while (part.isNext())
636  {
637  auto a = part.get();
638 
639  Point<3,double> acc(vectorDist.getProp<FORCE>(a));
640  double acc2 = norm2(acc);
641 
642  Point<3,double> vel(vectorDist.getProp<VELOCITY>(a));
643  double vel2 = norm2(vel);
644 
645  if (vel2 >= max_vel)
646  max_vel = vel2;
647 
648  if (acc2 >= max_acc)
649  max_acc = acc2;
650 
651  ++part;
652  }
653  max_acc = sqrt(max_acc);
654  max_vel = sqrt(max_vel);
655 
656  Vcluster<> & v_cl = create_vcluster();
657  v_cl.max(max_acc);
658  v_cl.max(max_vel);
659  v_cl.execute();
660 }
661 
687 double calc_deltaT(vector_dist_type & vectorDist, double ViscDtMax)
688 {
689  double Maxacc = 0.0;
690  double Maxvel = 0.0;
691  max_acceleration_and_velocity(vectorDist,Maxacc,Maxvel);
692 
693  //-dt1 depends on force per unit mass.
694  const double dt_f = (Maxacc)?sqrt(H/Maxacc):std::numeric_limits<int>::max();
695 
696  //-dt2 combines the Courant and the viscous time-step controls.
697  const double dt_cv = H/(std::max(cbar,Maxvel*10.) + H*ViscDtMax);
698 
699  //-dt new value of time step.
700  double dt=double(CFLnumber)*std::min(dt_f,dt_cv);
701  if(dt<double(DtMin))
702  dt=double(DtMin);
703 
704  return dt;
705 }
706 
740 openfpm::vector<size_t> to_remove;
741 
742 size_t cnt = 0;
743 
744 void verlet_int(vector_dist_type & vectorDist, double dt)
745 {
746  // list of the particle to remove
747  to_remove.clear();
748 
749  double dt205 = dt*dt*0.5;
750  double dt2 = dt*2.0;
751 
752  auto posExpression = getV<POS_PROP>(vectorDist);
753  auto forceExpression = getV<FORCE>(vectorDist);
754  auto drhoExpression = getV<DRHO>(vectorDist);
755  auto typeExpression = getV<TYPE>(vectorDist);
756 
757  auto rhoExpression = getV<RHO>(vectorDist);
758  auto rho_tmpExpression = getV<RHO_TMP>(vectorDist);
759  auto rho_prevExpression = getV<RHO_PREV>(vectorDist);
760 
761  auto velocityExpression = getV<VELOCITY>(vectorDist);
762  auto velocity_tmpExpression = getV<VELOCITY_TMP>(vectorDist);
763  auto velocity_prevExpression = getV<VELOCITY_PREV>(vectorDist);
764 
765  rho_tmpExpression = rhoExpression;
766  rhoExpression = rho_prevExpression + dt2*drhoExpression;
767  rho_prevExpression = rho_tmpExpression;
768 
769  posExpression[0] = posExpression[0] + velocityExpression[0]*dt + forceExpression[0]*dt205 * typeExpression;
770  posExpression[1] = posExpression[1] + velocityExpression[1]*dt + forceExpression[1]*dt205 * typeExpression;
771  posExpression[2] = posExpression[2] + velocityExpression[2]*dt + forceExpression[2]*dt205 * typeExpression;
772 
773  velocity_tmpExpression[0] = velocityExpression[0];
774  velocity_tmpExpression[1] = velocityExpression[1];
775  velocity_tmpExpression[2] = velocityExpression[2];
776 
777  velocityExpression[0] = velocity_prevExpression[0] + forceExpression[0]*dt2 * typeExpression;
778  velocityExpression[1] = velocity_prevExpression[1] + forceExpression[1]*dt2 * typeExpression;
779  velocityExpression[2] = velocity_prevExpression[2] + forceExpression[2]*dt2 * typeExpression;
780 
781  velocity_prevExpression[0] = velocity_tmpExpression[0];
782  velocity_prevExpression[1] = velocity_tmpExpression[1];
783  velocity_prevExpression[2] = velocity_tmpExpression[2];
784 
785  // particle iterator
786  auto part = vectorDist.getDomainIterator();
787 
788  // For each particle ...
789  while (part.isNext())
790  {
791  // ... a
792  auto a = part.get();
793 
794  // if the particle is boundary
795  if (vectorDist.template getProp<TYPE>(a) == BOUNDARY)
796  {
797  double rho = vectorDist.template getProp<RHO>(a);
798 
799  if (rho < RhoZero)
800  vectorDist.template getProp<RHO>(a) = RhoZero;
801 
802  ++part;
803  continue;
804  }
805 
806  // Check if the particle go out of range in space and in density
807  if (vectorDist.getPos(a)[0] < 0.000263878 || vectorDist.getPos(a)[1] < 0.000263878 || vectorDist.getPos(a)[2] < 0.000263878 ||
808  vectorDist.getPos(a)[0] > 0.000263878+1.59947 || vectorDist.getPos(a)[1] > 0.000263878+0.672972 || vectorDist.getPos(a)[2] > 0.000263878+0.903944 ||
809  vectorDist.template getProp<RHO>(a) < RhoMin || vectorDist.template getProp<RHO>(a) > RhoMax)
810  {
811  to_remove.add(a.getKey());
812  }
813 
814  ++part;
815  }
816 
817  // remove the particles
818  vectorDist.remove(to_remove,0);
819 
820  // increment the iteration counter
821  cnt++;
822 }
823 
824 void euler_int(vector_dist_type & vectorDist, double dt)
825 {
826  // list of the particle to remove
827  to_remove.clear();
828 
829  double dt205 = dt*dt*0.5;
830  double dt2 = dt*2.0;
831 
832  auto posExpression = getV<POS_PROP>(vectorDist);
833  auto forceExpression = getV<FORCE>(vectorDist);
834  auto drhoExpression = getV<DRHO>(vectorDist);
835  auto typeExpression = getV<TYPE>(vectorDist);
836 
837  auto rhoExpression = getV<RHO>(vectorDist);
838  auto rho_prevExpression = getV<RHO_PREV>(vectorDist);
839 
840  auto velocityExpression = getV<VELOCITY>(vectorDist);
841  auto velocity_prevExpression = getV<VELOCITY_PREV>(vectorDist);
842 
843  rho_prevExpression = rhoExpression;
844  rhoExpression = rhoExpression + dt*drhoExpression;
845 
846  posExpression[0] = posExpression[0] + velocityExpression[0]*dt + forceExpression[0]*dt205 * typeExpression;
847  posExpression[1] = posExpression[1] + velocityExpression[1]*dt + forceExpression[1]*dt205 * typeExpression;
848  posExpression[2] = posExpression[2] + velocityExpression[2]*dt + forceExpression[2]*dt205 * typeExpression;
849 
850  velocity_prevExpression[0] = velocityExpression[0];
851  velocity_prevExpression[1] = velocityExpression[1];
852  velocity_prevExpression[2] = velocityExpression[2];
853 
854  velocityExpression[0] = velocityExpression[0] + forceExpression[0]*dt * typeExpression;
855  velocityExpression[1] = velocityExpression[1] + forceExpression[1]*dt * typeExpression;
856  velocityExpression[2] = velocityExpression[2] + forceExpression[2]*dt * typeExpression;
857 
858  // particle iterator
859  auto part = vectorDist.getDomainIterator();
860 
861  // For each particle ...
862  while (part.isNext())
863  {
864  // ... a
865  auto a = part.get();
866 
867  // if the particle is boundary
868  if (vectorDist.template getProp<TYPE>(a) == BOUNDARY)
869  {
870  double rho = vectorDist.template getProp<RHO>(a);
871 
872  if (rho < RhoZero)
873  vectorDist.template getProp<RHO>(a) = RhoZero;
874 
875  ++part;
876  continue;
877  }
878 
879  // Check if the particle go out of range in space and in density
880  if (vectorDist.getPos(a)[0] < 0.000263878 || vectorDist.getPos(a)[1] < 0.000263878 || vectorDist.getPos(a)[2] < 0.000263878 ||
881  vectorDist.getPos(a)[0] > 0.000263878+1.59947 || vectorDist.getPos(a)[1] > 0.000263878+0.672972 || vectorDist.getPos(a)[2] > 0.000263878+0.903944 ||
882  vectorDist.template getProp<RHO>(a) < RhoMin || vectorDist.template getProp<RHO>(a) > RhoMax)
883  {
884  to_remove.add(a.getKey());
885  }
886 
887  ++part;
888  }
889 
890  // remove the particles
891  vectorDist.remove(to_remove,0);
892 
893  // increment the iteration counter
894  cnt++;
895 }
896 
924 template<typename Vector, typename CellList>
925 inline void sensor_pressure(Vector & vectorDist,
926  CellList & NN,
929 {
930  Vcluster<> & v_cl = create_vcluster();
931 
932  press_t.add();
933 
934  for (size_t i = 0 ; i < probes.size() ; i++)
935  {
936  float press_tmp = 0.0f;
937  float tot_ker = 0.0;
938 
939  // if the probe is inside the processor domain
940  if (vectorDist.getDecomposition().isLocal(probes.get(i)) == true)
941  {
942  // Get the position of the probe i
943  Point<3,double> xp = probes.get(i);
944 
945  // get the iterator over the neighbohood particles of the probes position
946  auto itg = NN.getNNIteratorBox(NN.getCell(probes.get(i)));
947  while (itg.isNext())
948  {
949  auto q = itg.get();
950 
951  // Only the fluid particles are importants
952  if (vectorDist.template getProp<TYPE>(q) != FLUID)
953  {
954  ++itg;
955  continue;
956  }
957 
958  // Get the position of the neighborhood particle q
959  Point<3,double> xq = vectorDist.getPos(q);
960 
961  // Calculate the contribution of the particle to the pressure
962  // of the probe
963  double r = sqrt(norm2(xp - xq));
964 
965  double ker = Wab(r) * (MassFluid / RhoZero);
966 
967  // Also keep track of the calculation of the summed
968  // kernel
969  tot_ker += ker;
970 
971  // Add the total pressure contribution
972  press_tmp += vectorDist.template getProp<PRESSURE>(q) * ker;
973 
974  // next neighborhood particle
975  ++itg;
976  }
977 
978  // We calculate the pressure normalizing the
979  // sum over all kernels
980  if (tot_ker == 0.0)
981  press_tmp = 0.0;
982  else
983  press_tmp = 1.0 / tot_ker * press_tmp;
984 
985  }
986 
987  // This is not necessary in principle, but if you
988  // want to make all processor aware of the history of the calculated
989  // pressure we have to execute this
990  v_cl.sum(press_tmp);
991  v_cl.execute();
992 
993  // We add the calculated pressure into the history
994  press_t.last().add(press_tmp);
995  }
996 }
997 
1000 int main(int argc, char* argv[])
1001 {
1018 
1019  // initialize the library
1020  openfpm_init(&argc,&argv);
1021 
1022  // It contain for each time-step the value detected by the probes
1025 
1026  probes.add({0.8779,0.3,0.02});
1027  probes.add({0.754,0.31,0.02});
1028 
1029  // Here we define our domain a 2D box with internals from 0 to 1.0 for x and y
1030  Box<3,double> domain({-0.05,-0.05,-0.05},{1.7010,0.7065,0.5025});
1031  size_t sz[3] = {207,90,66};
1032 
1033  // Fill W_dap
1034  W_dap = 1.0/Wab(H/1.5);
1035 
1036  // Here we define the boundary conditions of our problem
1037  size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
1038 
1039  // extended boundary around the domain, and the processor domain
1040  Ghost<3,double> g(2*H);
1041 
1043 
1080 
1081  vector_dist_type vectorDist(0,domain,bc,g,DEC_GRAN(512));
1082 
1084 
1120 
1121  // You can ignore all these dp/2.0 is a trick to reach the same initialization
1122  // of Dual-SPH that use a different criteria to draw particles
1123  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});
1124 
1125  // return an iterator to the fluid particles to add to vectorDist
1126  auto fluid_it = DrawParticles::DrawBox(vectorDist,sz,domain,fluid_box);
1127 
1128  // here we fill some of the constants needed by the simulation
1129  max_fluid_height = fluid_it.getBoxMargins().getHigh(2);
1130  h_swl = fluid_it.getBoxMargins().getHigh(2) - fluid_it.getBoxMargins().getLow(2);
1131  B = (coeff_sound)*(coeff_sound)*gravity*h_swl*RhoZero / gamma_;
1132  cbar = coeff_sound * sqrt(gravity * h_swl);
1133 
1134  // for each particle inside the fluid box ...
1135  while (fluid_it.isNext())
1136  {
1137  // ... add a particle ...
1138  vectorDist.add();
1139 
1140  // ... and set it position ...
1141  vectorDist.getLastPos()[0] = fluid_it.get().get(0);
1142  vectorDist.getLastPos()[1] = fluid_it.get().get(1);
1143  vectorDist.getLastPos()[2] = fluid_it.get().get(2);
1144 
1145  // and its type.
1146  vectorDist.template getLastProp<TYPE>() = FLUID;
1147 
1148  // We also initialize the density of the particle and the hydro-static pressure given by
1149  //
1150  // RhoZero*g*h = P
1151  //
1152  // rho_p = (P/B + 1)^(1/Gamma) * RhoZero
1153  //
1154 
1155  vectorDist.template getLastProp<PRESSURE>() = RhoZero * gravity * (max_fluid_height - fluid_it.get().get(2));
1156 
1157  vectorDist.template getLastProp<RHO>() = pow(vectorDist.template getLastProp<PRESSURE>() / B + 1, 1.0/gamma_) * RhoZero;
1158  vectorDist.template getLastProp<RHO_PREV>() = vectorDist.template getLastProp<RHO>();
1159  vectorDist.template getLastProp<VELOCITY>()[0] = 0.0;
1160  vectorDist.template getLastProp<VELOCITY>()[1] = 0.0;
1161  vectorDist.template getLastProp<VELOCITY>()[2] = 0.0;
1162 
1163  vectorDist.template getLastProp<VELOCITY_PREV>()[0] = 0.0;
1164  vectorDist.template getLastProp<VELOCITY_PREV>()[1] = 0.0;
1165  vectorDist.template getLastProp<VELOCITY_PREV>()[2] = 0.0;
1166 
1167  // next fluid particle
1168  ++fluid_it;
1169  }
1170 
1172 
1197 
1198  // Recipient
1199  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});
1200  Box<3,double> recipient2({dp,dp,dp},{1.6-dp/2.0,0.67-dp/2.0,0.4+dp/2.0});
1201 
1202  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});
1203  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});
1204  Box<3,double> obstacle3({0.9+dp,0.24,0.0},{1.02,0.36,0.45});
1205 
1207  holes.add(recipient2);
1208  holes.add(obstacle1);
1209  auto bound_box = DrawParticles::DrawSkin(vectorDist,sz,domain,holes,recipient1);
1210 
1211  while (bound_box.isNext())
1212  {
1213  vectorDist.add();
1214 
1215  vectorDist.getLastPos()[0] = bound_box.get().get(0);
1216  vectorDist.getLastPos()[1] = bound_box.get().get(1);
1217  vectorDist.getLastPos()[2] = bound_box.get().get(2);
1218 
1219  vectorDist.template getLastProp<TYPE>() = BOUNDARY;
1220  vectorDist.template getLastProp<RHO>() = RhoZero;
1221  vectorDist.template getLastProp<RHO_PREV>() = RhoZero;
1222  vectorDist.template getLastProp<VELOCITY>()[0] = 0.0;
1223  vectorDist.template getLastProp<VELOCITY>()[1] = 0.0;
1224  vectorDist.template getLastProp<VELOCITY>()[2] = 0.0;
1225 
1226  vectorDist.template getLastProp<VELOCITY_PREV>()[0] = 0.0;
1227  vectorDist.template getLastProp<VELOCITY_PREV>()[1] = 0.0;
1228  vectorDist.template getLastProp<VELOCITY_PREV>()[2] = 0.0;
1229 
1230  ++bound_box;
1231  }
1232 
1234 
1252 
1253  auto obstacle_box = DrawParticles::DrawSkin(vectorDist,sz,domain,obstacle2,obstacle1);
1254 
1255  while (obstacle_box.isNext())
1256  {
1257  vectorDist.add();
1258 
1259  vectorDist.getLastPos()[0] = obstacle_box.get().get(0);
1260  vectorDist.getLastPos()[1] = obstacle_box.get().get(1);
1261  vectorDist.getLastPos()[2] = obstacle_box.get().get(2);
1262 
1263  vectorDist.template getLastProp<TYPE>() = BOUNDARY;
1264  vectorDist.template getLastProp<RHO>() = RhoZero;
1265  vectorDist.template getLastProp<RHO_PREV>() = RhoZero;
1266  vectorDist.template getLastProp<VELOCITY>()[0] = 0.0;
1267  vectorDist.template getLastProp<VELOCITY>()[1] = 0.0;
1268  vectorDist.template getLastProp<VELOCITY>()[2] = 0.0;
1269 
1270  vectorDist.template getLastProp<VELOCITY_PREV>()[0] = 0.0;
1271  vectorDist.template getLastProp<VELOCITY_PREV>()[1] = 0.0;
1272  vectorDist.template getLastProp<VELOCITY_PREV>()[2] = 0.0;
1273 
1274  ++obstacle_box;
1275  }
1276 
1277  vectorDist.map();
1278 
1280 
1363 
1364  // Now that we fill the vector with particles
1365  ModelCustom md;
1366 
1367  vectorDist.addComputationCosts(md);
1368  vectorDist.getDecomposition().decompose();
1369  vectorDist.map();
1370 
1372 
1373  vectorDist.ghost_get<TYPE,RHO,PRESSURE,VELOCITY>();
1374 
1375  auto NN = vectorDist.getCellList(2*H);
1376 
1377  // Evolve
1378 
1394 
1395  size_t write = 0;
1396  size_t it = 0;
1397  size_t it_reb = 0;
1398  double t = 0.0;
1399  while (t <= t_end)
1400  {
1401  Vcluster<> & v_cl = create_vcluster();
1402  timer it_time;
1403 
1405  it_reb++;
1406  if (it_reb == 200)
1407  {
1408  vectorDist.map();
1409 
1410  it_reb = 0;
1411  ModelCustom md;
1412  vectorDist.addComputationCosts(md);
1413  vectorDist.getDecomposition().decompose();
1414 
1415  if (v_cl.getProcessUnitID() == 0)
1416  std::cout << "REBALANCED " << std::endl;
1417  }
1418 
1419  vectorDist.map();
1420 
1421  // Calculate pressure from the density
1422  EqState(vectorDist);
1423 
1424  double max_visc = 0.0;
1425 
1426  vectorDist.ghost_get<TYPE,RHO,PRESSURE,VELOCITY>();
1427 
1428  // Calc forces
1429  calc_forces(vectorDist,NN,max_visc);
1430 
1431  // Get the maximum viscosity term across processors
1432  v_cl.max(max_visc);
1433  v_cl.execute();
1434 
1435  // Calculate delta t integration
1436  double dt = calc_deltaT(vectorDist,max_visc);
1437 
1438  // VerletStep or euler step
1439  it++;
1440  if (it < 40)
1441  verlet_int(vectorDist,dt);
1442  else
1443  {
1444  euler_int(vectorDist,dt);
1445  it = 0;
1446  }
1447 
1448  t += dt;
1449 
1450  if (write < t*100)
1451  {
1452  // sensor_pressure calculation require ghost and update cell-list
1453  vectorDist.map();
1454  vectorDist.ghost_get<TYPE,RHO,PRESSURE,VELOCITY>();
1455  vectorDist.updateCellList(NN);
1456 
1457  // calculate the pressure at the sensor points
1458  sensor_pressure(vectorDist,NN,press_t,probes);
1459 
1460  vectorDist.write_frame("Geometry",write);
1461  write++;
1462 
1463  if (v_cl.getProcessUnitID() == 0)
1464  {std::cout << "TIME: " << t << " write " << it_time.getwct() << " " << v_cl.getProcessUnitID() << " " << cnt << " Max visc: " << max_visc << std::endl;}
1465  }
1466  else
1467  {
1468  if (v_cl.getProcessUnitID() == 0)
1469  {std::cout << "TIME: " << t << " " << it_time.getwct() << " " << v_cl.getProcessUnitID() << " " << cnt << " Max visc: " << max_visc << std::endl;}
1470  }
1471  }
1472 
1474 
1489 
1490  openfpm_finalize();
1491 
1493 
1502 }
This class represent an N-dimensional box.
Definition: Box.hpp:60
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:555
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:566
Class for FAST cell list implementation.
Definition: CellList.hpp:558
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.
Definition: Ghost.hpp:40
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
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Definition: Vector.hpp:40
Class for cpu time benchmarking.
Definition: timer.hpp:28
double getwct()
Return the elapsed real time.
Definition: timer.hpp:130
Distributed vector.
auto getProp(vect_dist_key_dx vec_key) -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
void updateCellList(CellL &cellList, bool no_se3=false)
Update a cell list using the stored particles.
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void remove(std::set< size_t > &keys)
Remove a set of elements from the distributed vector.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
Model for Dynamic load balancing.
Definition: main.cpp:232
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:221