56#include "Vector/vector_dist.hpp"
58#include "Draw/DrawParticles.hpp"
218const double dp = 0.0085;
224const double coeff_sound = 20.0;
227const double gamma_ = 7.0;
230const double H = 0.0147224318643;
232const double FourH2 = 4.0 * H*H;
235const double Eta2 = 0.01 * H*H;
238const double visco = 0.1;
244const double MassFluid = 0.000614125;
247const double MassBound = 0.000614125;
251const double t_end = 1.5;
253const double t_end = 0.001;
257const double gravity = 9.81;
260const double rho_zero = 1000.0;
266const double CFLnumber = 0.2;
269const double DtMin = 0.00001;
272const double RhoMin = 700.0;
275const double RhoMax = 1300.0;
278double max_fluid_height = 0.0;
283const size_t type = 0;
286const size_t nn_num = 1;
292const int rho_prev = 3;
295const int Pressure = 4;
304const int velocity = 7;
307const int velocity_prev = 8;
314typedef vector_dist<3,double,aggregate<int, int,double, double, double, double, double[3], double[3], double[3]> >
particles;
325 template<
typename Decomposition,
typename vector>
inline void addComputation(
Decomposition & dec, vector & vd,
size_t v,
size_t p)
327 if (vd.template getProp<type>(p) == FLUID )
328 {dec.addComputationCost(v,4);}
330 {dec.addComputationCost(v,3);}
333 template<
typename Decomposition>
inline void applyModel(
Decomposition & dec,
size_t v)
335 dec.setSubSubDomainComputationCost(v, dec.getSubSubDomainComputationCost(v) * dec.getSubSubDomainComputationCost(v));
338 float distributionTol()
347 template<
typename Decomposition,
typename vector>
inline void addComputation(
Decomposition & dec, vector & vd,
size_t v,
size_t p)
349 dec.addComputationCost(v,vd.template getProp<nn_num>(p) + 4);
352 template<
typename Decomposition>
inline void applyModel(
Decomposition & dec,
size_t v)
356 float distributionTol()
370 double rho_a = vd.template getProp<rho>(a);
371 double rho_frac = rho_a / rho_zero;
373 vd.template getProp<Pressure>(a) = B*( rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac - 1.0);
379const double a2 = 1.0/M_PI/H/H/H;
381inline double Wab(
double r)
386 {
return (1.0 - 3.0/2.0*r*r + 3.0/4.0*r*r*r)*a2;}
388 {
return (1.0/4.0*(2.0 - r*r)*(2.0 - r*r)*(2.0 - r*r))*a2;}
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;
404 double qq2 = qq * qq;
405 double fac1 = (c1*qq + d1*qq2)/r;
406 double b1 = (qq < 1.0)?1.0f:0.0f;
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;
412 double factor = (b1*fac1 + b2*fac2);
414 DW.
get(0) = factor * dx.
get(0);
415 DW.
get(1) = factor * dx.
get(1);
416 DW.
get(2) = factor * dx.
get(2);
419inline double Tensile(
double r,
double rhoa,
double rhob,
double prs1,
double prs2)
427 double wqq2=wqq1*wqq1;
429 wab=a2_4*(wqq2*wqq1);
436 wab=a2*(1.0f-1.5f*wqq2+0.75f*wqq3);
440 double fab=wab*W_dap;
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);
445 return (fab*(tensilp1+tensilp2));
452 const double dot_rr2 = dot/(rr2+Eta2);
453 visc=std::max(dot_rr2,visc);
457 const float amubar=H*dot_rr2;
458 const float robar=(rhoa+rhob)*0.5f;
459 const float pi_visc=(-visco*cbar*amubar/robar);
468template<
typename VerletList>
inline void calc_forces(
particles & vd,
VerletList & NN,
double & max_visc)
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;
494 while (itg2.isNext())
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;
516 while (part.isNext())
525 size_t typea = vd.
getProp<type>(a);
528 double massa = (vd.
getProp<type>(a) == FLUID)?MassFluid:MassBound;
531 double rhoa = vd.
getProp<rho>(a);
534 double Pa = vd.
getProp<Pressure>(a);
540 auto Np = NN.template getNNIterator<NO_CHECK>(a);
545 while (Np.isNext() ==
true)
556 float r2 = norm2(dr);
559 if (r2 < FourH2 && r2 > 1e-18)
563 unsigned int typeb = vd.
getProp<type>(b);
565 double massb = (typeb == FLUID)?MassFluid:MassBound;
567 double Pb = vd.
getProp<Pressure>(b);
568 double rhob = vd.
getProp<rho>(b);
577 double factor = - ((Pa + Pb) / (rhoa * rhob) + Tensile(r,rhoa,rhob,Pa,Pb) + Pi(dr,r2,v_rel,rhoa,rhob,massb,visc));
580 factor = (typea == BOUNDARY && typeb == BOUNDARY)?0.0f:factor;
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);
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);
590 double scal = (v_rel.get(0)*DW.
get(0)+v_rel.get(1)*DW.
get(1)+v_rel.get(2)*DW.
get(2));
593 scal = (typea == BOUNDARY && typeb == BOUNDARY)?0.0f:scal;
595 vd.
getProp<drho>(a) += massb*scal;
596 vd.
getProp<drho>(b) += massa*scal;
613 vd.template ghost_put<add_,drho,force>();
618void max_acceleration_and_velocity(
particles & vd,
double & max_acc,
double & max_vel)
623 while (part.isNext())
628 double acc2 = norm2(acc);
631 double vel2 = norm2(vel);
641 max_acc = sqrt(max_acc);
642 max_vel = sqrt(max_vel);
650double calc_deltaT(
particles & vd,
double ViscDtMax)
654 max_acceleration_and_velocity(vd,Maxacc,Maxvel);
657 const double dt_f = (Maxacc)?sqrt(H/Maxacc):std::numeric_limits<int>::max();
660 const double dt_cv = H/(std::max(cbar,Maxvel*10.) + H*ViscDtMax);
663 double dt=double(CFLnumber)*std::min(dt_f,dt_cv);
676void verlet_int(
particles & vd,
double dt,
double & max_disp)
685 double dt205 = dt*dt*0.5;
693 while (part.isNext())
699 if (vd.template getProp<type>(a) == BOUNDARY)
702 double rhop = vd.template getProp<rho>(a);
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;
711 vd.template getProp<rho_prev>(a) = rhop;
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;
727 double d2 = dx*dx + dy*dy + dz*dz;
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);
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);
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)
747 to_remove.add(a.getKey());
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;
764 max_disp = sqrt(max_disp);
773void euler_int(
particles & vd,
double dt,
double & max_disp)
782 double dt205 = dt*dt*0.5;
788 while (part.isNext())
794 if (vd.template getProp<type>(a) == BOUNDARY)
797 double rhop = vd.template getProp<rho>(a);
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;
806 vd.template getProp<rho_prev>(a) = rhop;
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;
821 double d2 = dx*dx + dy*dy + dz*dz;
823 max_disp = (max_disp > d2)?max_disp:d2;
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);
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);
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)
840 to_remove.add(a.getKey());
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;
855 max_disp = sqrt(max_disp);
861int main(
int argc,
char* argv[])
864 openfpm_init(&argc,&argv);
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};
871 W_dap = 1.0/Wab(H/1.5);
874 size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
878 double skin = 0.25 * 2*H;
879 double r_gskin = 2*H + skin;
895 particles vd(0,domain,bc,g,BIND_DEC_TO_GHOST);
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});
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);
913 while (fluid_it.isNext())
924 vd.template getLastProp<type>() = FLUID;
933 vd.template getLastProp<Pressure>() = rho_zero * gravity * (max_fluid_height - fluid_it.get().get(2));
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;
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;
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});
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});
958 holes.add(recipient2);
959 holes.add(obstacle1);
962 while (bound_box.isNext())
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;
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;
986 while (obstacle_box.isNext())
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);
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;
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;
1017 auto & v_cl = create_vcluster();
1020 std::cout <<
"SUM: " << tot_part << std::endl;
1029 vd.
ghost_get<type,rho,Pressure,velocity>();
1039 double tot_disp = 0.0;
1049 if (2*tot_disp >= skin)
1066 std::cout <<
"REBALANCED " << std::endl;
1073 vd.
ghost_get<type,rho,Pressure,velocity>();
1082 std::cout <<
"RECONSTRUCT Verlet " << std::endl;
1089 vd.
ghost_get<type,rho,Pressure,velocity>(SKIP_LABELLING);
1094 double max_visc = 0.0;
1097 calc_forces(vd,NN,max_visc);
1104 double dt = calc_deltaT(vd,max_visc);
1111 verlet_int(vd,dt,max_disp);
1114 euler_int(vd,dt,max_disp);
1118 tot_disp += max_disp;
1127 vd.
write_frame(
"Geometry",write,VTK_WRITER | FORMAT_BINARY);
1129 vd.
ghost_get<type,rho,Pressure,velocity>(SKIP_LABELLING);
1133 std::cout <<
"TIME: " << t <<
" write " << it_time.
getwct() <<
" " << v_cl.
getProcessUnitID() <<
" TOT disp: " << tot_disp <<
" " << cnt << std::endl;
1138 std::cout <<
"TIME: " << t <<
" " << it_time.
getwct() <<
" " << v_cl.
getProcessUnitID() <<
" TOT disp: " << tot_disp <<
" " << cnt << std::endl;
This class represent an N-dimensional box.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
__device__ __host__ T getHigh(int i) const
get the high interval of the box
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.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
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.
Class for Verlet list implementation.
Implementation of 1-D std::vector like structure.
Class for cpu time benchmarking.
double getwct()
Return the elapsed real time.
vect_dist_key_dx get()
Get the actual key.
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.
Model for Dynamic load balancing.