63 #include "Vector/vector_dist.hpp"
64 #include "Operators/Vector/vector_dist_operators.hpp"
65 #include "Vector/vector_dist_subset.hpp"
66 #include "OdeIntegrators/OdeIntegrators.hpp"
67 #include "Draw/DrawParticles.hpp"
123 const double dp = 0.0085;
129 const double coeff_sound = 20.0;
132 const double gamma_ = 7.0;
135 const double H = 0.0147224318643;
138 const double Eta2 = 0.01 * H*H;
141 const double visco = 0.1;
147 const double MassFluid = 0.000614125;
150 const double MassBound = 0.000614125;
154 const double t_end = 0.001;
156 const double t_end = 1.5;
160 const double gravity = 9.81;
163 const double RhoZero = 1000.0;
169 const double CFLnumber = 0.2;
172 const double DtMin = 0.00001;
175 const double RhoMin = 700.0;
178 const double RhoMax = 1300.0;
181 double max_fluid_height = 0.0;
186 const size_t TYPE = 0;
192 const int RHO_PREV = 2;
196 const int RHO_TMP = 8;
199 const int PRESSURE = 3;
208 const int VELOCITY = 6;
211 const int VELOCITY_PREV = 7;
215 const int VELOCITY_TMP = 9;
243 template<
typename Decomposition,
typename vector>
inline void addComputation(
Decomposition & dec,
248 if (vectorDist.template getProp<TYPE>(p) == FLUID)
249 dec.addComputationCost(v,4);
251 dec.addComputationCost(v,3);
254 template<
typename Decomposition>
inline void applyModel(
Decomposition & dec,
size_t v)
256 dec.setSubSubDomainComputationCost(v, dec.getSubSubDomainComputationCost(v) * dec.getSubSubDomainComputationCost(v));
259 double distributionTol()
290 double rho_a = vectorDist.template getProp<RHO>(a);
291 double rho_frac = rho_a / RhoZero;
293 vectorDist.template getProp<PRESSURE>(a) = B*( rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac*rho_frac - 1.0);
317 const double a2 = 1.0/M_PI/H/H/H;
319 inline double Wab(
double r)
324 return (1.0 - 3.0/2.0*r*r + 3.0/4.0*r*r*r)*a2;
326 return (1.0/4.0*(2.0 - r)*(2.0 - r)*(2.0 - r))*a2;
348 const double c1 = -3.0/M_PI/H/H/H/H;
349 const double d1 = 9.0/4.0/M_PI/H/H/H/H;
350 const double c2 = -3.0/4.0/M_PI/H/H/H/H;
351 const double a2_4 = 0.25*a2;
359 double qq2 = qq * qq;
360 double fac1 = (c1*qq + d1*qq2)/r;
361 double b1 = (qq < 1.0)?1.0f:0.0f;
363 double wqq = (2.0 - qq);
364 double fac2 = c2 * wqq * wqq / r;
365 double b2 = (qq >= 1.0 && qq < 2.0)?1.0f:0.0f;
367 double factor = (b1*fac1 + b2*fac2);
369 DW.
get(0) = factor * dx.
get(0);
370 DW.
get(1) = factor * dx.
get(1);
371 DW.
get(2) = factor * dx.
get(2);
395 inline double Tensile(
double r,
double rhoa,
double rhob,
double prs1,
double prs2)
403 double wqq2=wqq1*wqq1;
405 wab=a2_4*(wqq2*wqq1);
412 wab=a2*(1.0f-1.5f*wqq2+0.75f*wqq3);
416 double fab=wab*W_dap;
418 const double tensilp1=(prs1/(rhoa*rhoa))*(prs1>0? 0.01: -0.2);
419 const double tensilp2=(prs2/(rhob*rhob))*(prs2>0? 0.01: -0.2);
421 return (fab*(tensilp1+tensilp2));
445 const double dot_rr2 = dot/(rr2+Eta2);
446 visc=std::max(dot_rr2,visc);
450 const float amubar=H*dot_rr2;
451 const float robar=(rhoa+rhob)*0.5f;
452 const float pi_visc=(-visco*cbar*amubar/robar);
477 template<
typename CellList>
inline void calc_forces(
vector_dist_type & vectorDist,
CellList & cellList,
double & max_visc)
485 while (part.isNext())
494 double massa = (vectorDist.
getProp<TYPE>(a) == FLUID)?MassFluid:MassBound;
497 double rhoa = vectorDist.
getProp<RHO>(a);
500 double Pa = vectorDist.
getProp<PRESSURE>(a);
506 vectorDist.template getProp<FORCE>(a)[0] = 0.0;
507 vectorDist.template getProp<FORCE>(a)[1] = 0.0;
508 vectorDist.template getProp<FORCE>(a)[2] = -gravity;
509 vectorDist.template getProp<DRHO>(a) = 0.0;
512 if (vectorDist.
getProp<TYPE>(a) != FLUID)
516 auto Np = cellList.getNNIteratorBox(cellList.getCell(vectorDist.
getPos(a)));
519 while (Np.isNext() ==
true)
528 if (a.getKey() == b) {++Np;
continue;};
531 double massb = (vectorDist.
getProp<TYPE>(b) == FLUID)?MassFluid:MassBound;
537 double Pb = vectorDist.
getProp<PRESSURE>(b);
538 double rhob = vectorDist.
getProp<RHO>(b);
543 double r2 = norm2(dr);
556 const double dot = dr.get(0)*dv.
get(0) + dr.get(1)*dv.
get(1) + dr.get(2)*dv.
get(2);
557 const double dot_rr2 = dot/(r2+Eta2);
558 max_visc=std::max(dot_rr2,max_visc);
571 auto Np = cellList.getNNIteratorBox(cellList.getCell(vectorDist.
getPos(a)));
574 while (Np.isNext() ==
true)
583 if (a.getKey() == b) {++Np;
continue;};
585 double massb = (vectorDist.
getProp<TYPE>(b) == FLUID)?MassFluid:MassBound;
587 double Pb = vectorDist.
getProp<PRESSURE>(b);
588 double rhob = vectorDist.
getProp<RHO>(b);
593 double r2 = norm2(dr);
605 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));
607 vectorDist.
getProp<FORCE>(a)[0] += factor * DW.
get(0);
608 vectorDist.
getProp<FORCE>(a)[1] += factor * DW.
get(1);
609 vectorDist.
getProp<FORCE>(a)[2] += factor * DW.
get(2);
640 void max_acceleration_and_velocity(
vector_dist_type & vectorDist,
double & max_acc,
double & max_vel)
645 while (part.isNext())
650 double acc2 = norm2(acc);
653 double vel2 = norm2(vel);
663 max_acc = sqrt(max_acc);
664 max_vel = sqrt(max_vel);
701 max_acceleration_and_velocity(vectorDist,Maxacc,Maxvel);
704 const double dt_f = (Maxacc)?sqrt(H/Maxacc):std::numeric_limits<int>::max();
707 const double dt_cv = H/(std::max(cbar,Maxvel*10.) + H*ViscDtMax);
710 double dt=double(CFLnumber)*std::min(dt_f,dt_cv);
740 template<
typename vector_dist_type,
typename CellList_type>
743 CellList_type &cellList;
749 vectorDist(vectorDist)
754 double dt05 = dt*0.5;
757 auto posExpression = getV<POS_PROP>(vectorDist);
758 auto forceExpression = getV<FORCE>(vectorDist);
759 auto drhoExpression = getV<DRHO>(vectorDist);
760 auto typeExpression = getV<TYPE>(vectorDist);
762 auto rhoExpression = getV<RHO>(vectorDist);
763 auto rho_prevExpression = getV<RHO_PREV>(vectorDist);
765 auto velocityExpression = getV<VELOCITY>(vectorDist);
766 auto velocity_prevExpression = getV<VELOCITY_PREV>(vectorDist);
768 if (iteration < 40) {
769 X.data.get<0>() = rho_prevExpression;
771 X.data.get<4>() = velocity_prevExpression[0];
772 X.data.get<5>() = velocity_prevExpression[1];
773 X.data.get<6>() = velocity_prevExpression[2];
775 dxdt.data.get<0>() = 2*drhoExpression;
777 dxdt.data.get<1>() = velocityExpression[0] + forceExpression[0]*dt05 * typeExpression;
778 dxdt.data.get<2>() = velocityExpression[1] + forceExpression[1]*dt05 * typeExpression;
779 dxdt.data.get<3>() = velocityExpression[2] + forceExpression[2]*dt05 * typeExpression;
781 dxdt.data.get<4>() = forceExpression[0]*2 * typeExpression;
782 dxdt.data.get<5>() = forceExpression[1]*2 * typeExpression;
783 dxdt.data.get<6>() = forceExpression[2]*2 * typeExpression;
788 dxdt.data.get<0>() = drhoExpression;
790 dxdt.data.get<1>() = velocityExpression[0] + forceExpression[0]*dt05 * typeExpression;
791 dxdt.data.get<2>() = velocityExpression[1] + forceExpression[1]*dt05 * typeExpression;
792 dxdt.data.get<3>() = velocityExpression[2] + forceExpression[2]*dt05 * typeExpression;
794 dxdt.data.get<4>() = forceExpression[0] * typeExpression;
795 dxdt.data.get<5>() = forceExpression[1] * typeExpression;
796 dxdt.data.get<6>() = forceExpression[2] * typeExpression;
846 while (part.isNext())
852 if (vectorDist.template getProp<TYPE>(a) == BOUNDARY)
854 double rho = vectorDist.template getProp<RHO>(a);
857 vectorDist.template getProp<RHO>(a) = RhoZero;
864 if (vectorDist.
getPos(a)[0] < 0.000263878 || vectorDist.
getPos(a)[1] < 0.000263878 || vectorDist.
getPos(a)[2] < 0.000263878 ||
865 vectorDist.
getPos(a)[0] > 0.000263878+1.59947 || vectorDist.
getPos(a)[1] > 0.000263878+0.672972 || vectorDist.
getPos(a)[2] > 0.000263878+0.903944 ||
866 vectorDist.template getProp<RHO>(a) < RhoMin || vectorDist.template getProp<RHO>(a) > RhoMax)
868 to_remove.add(a.getKey());
875 vectorDist.
remove(to_remove,0);
905 template<
typename Vector,
typename CellList>
906 inline void sensor_pressure(
Vector & vectorDist,
915 for (
size_t i = 0 ; i < probes.size() ; i++)
917 float press_tmp = 0.0f;
921 if (vectorDist.getDecomposition().isLocal(probes.get(i)) ==
true)
927 auto itg = cellList.getNNIteratorBox(cellList.getCell(probes.get(i)));
933 if (vectorDist.template getProp<TYPE>(q) != FLUID)
944 double r = sqrt(norm2(xp - xq));
946 double ker = Wab(r) * (MassFluid / RhoZero);
953 press_tmp += vectorDist.template getProp<PRESSURE>(q) * ker;
964 press_tmp = 1.0 / tot_ker * press_tmp;
975 press_t.last().add(press_tmp);
981 int main(
int argc,
char* argv[])
1001 openfpm_init(&argc,&argv);
1007 probes.add({0.8779,0.3,0.02});
1008 probes.add({0.754,0.31,0.02});
1011 Box<3,double> domain({-0.05,-0.05,-0.05},{1.7010,0.7065,0.5025});
1012 size_t sz[3] = {207,90,66};
1015 W_dap = 1.0/Wab(H/1.5);
1018 size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
1104 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});
1110 max_fluid_height = fluid_it.getBoxMargins().
getHigh(2);
1111 h_swl = fluid_it.getBoxMargins().
getHigh(2) - fluid_it.getBoxMargins().
getLow(2);
1112 B = (coeff_sound)*(coeff_sound)*gravity*h_swl*RhoZero / gamma_;
1113 cbar = coeff_sound * sqrt(gravity * h_swl);
1116 while (fluid_it.isNext())
1122 vectorDist.getLastPos()[0] = fluid_it.get().get(0);
1123 vectorDist.getLastPos()[1] = fluid_it.get().get(1);
1124 vectorDist.getLastPos()[2] = fluid_it.get().get(2);
1127 vectorDist.template getLastProp<TYPE>() = FLUID;
1136 vectorDist.template getLastProp<PRESSURE>() = RhoZero * gravity * (max_fluid_height - fluid_it.get().get(2));
1138 vectorDist.template getLastProp<RHO>() = pow(vectorDist.template getLastProp<PRESSURE>() / B + 1, 1.0/gamma_) * RhoZero;
1139 vectorDist.template getLastProp<RHO_PREV>() = vectorDist.template getLastProp<RHO>();
1140 vectorDist.template getLastProp<VELOCITY>()[0] = 0.0;
1141 vectorDist.template getLastProp<VELOCITY>()[1] = 0.0;
1142 vectorDist.template getLastProp<VELOCITY>()[2] = 0.0;
1144 vectorDist.template getLastProp<VELOCITY_PREV>()[0] = 0.0;
1145 vectorDist.template getLastProp<VELOCITY_PREV>()[1] = 0.0;
1146 vectorDist.template getLastProp<VELOCITY_PREV>()[2] = 0.0;
1180 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});
1181 Box<3,double> recipient2({dp,dp,dp},{1.6-dp/2.0,0.67-dp/2.0,0.4+dp/2.0});
1183 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});
1184 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});
1185 Box<3,double> obstacle3({0.9+dp,0.24,0.0},{1.02,0.36,0.45});
1188 holes.add(recipient2);
1189 holes.add(obstacle1);
1192 while (bound_box.isNext())
1196 vectorDist.getLastPos()[0] = bound_box.get().get(0);
1197 vectorDist.getLastPos()[1] = bound_box.get().get(1);
1198 vectorDist.getLastPos()[2] = bound_box.get().get(2);
1200 vectorDist.template getLastProp<TYPE>() = BOUNDARY;
1201 vectorDist.template getLastProp<RHO>() = RhoZero;
1202 vectorDist.template getLastProp<RHO_PREV>() = RhoZero;
1203 vectorDist.template getLastProp<VELOCITY>()[0] = 0.0;
1204 vectorDist.template getLastProp<VELOCITY>()[1] = 0.0;
1205 vectorDist.template getLastProp<VELOCITY>()[2] = 0.0;
1207 vectorDist.template getLastProp<VELOCITY_PREV>()[0] = 0.0;
1208 vectorDist.template getLastProp<VELOCITY_PREV>()[1] = 0.0;
1209 vectorDist.template getLastProp<VELOCITY_PREV>()[2] = 0.0;
1236 while (obstacle_box.isNext())
1240 vectorDist.getLastPos()[0] = obstacle_box.get().get(0);
1241 vectorDist.getLastPos()[1] = obstacle_box.get().get(1);
1242 vectorDist.getLastPos()[2] = obstacle_box.get().get(2);
1244 vectorDist.template getLastProp<TYPE>() = BOUNDARY;
1245 vectorDist.template getLastProp<RHO>() = RhoZero;
1246 vectorDist.template getLastProp<RHO_PREV>() = RhoZero;
1247 vectorDist.template getLastProp<VELOCITY>()[0] = 0.0;
1248 vectorDist.template getLastProp<VELOCITY>()[1] = 0.0;
1249 vectorDist.template getLastProp<VELOCITY>()[2] = 0.0;
1251 vectorDist.template getLastProp<VELOCITY_PREV>()[0] = 0.0;
1252 vectorDist.template getLastProp<VELOCITY_PREV>()[1] = 0.0;
1253 vectorDist.template getLastProp<VELOCITY_PREV>()[2] = 0.0;
1348 vectorDist.addComputationCosts(md);
1349 vectorDist.getDecomposition().decompose();
1354 vectorDist.ghost_get<TYPE,RHO,PRESSURE,VELOCITY>();
1356 auto cellList = vectorDist.getCellList(2*H);
1378 boost::numeric::odeint::euler<state_type_7d_ofp, double, state_type_7d_ofp, double, boost::numeric::odeint::vector_space_algebra_ofp> eulerOdeint;
1381 RHSFunctor<decltype(vectorDist), decltype(cellList)> rhsFunctor(vectorDist, cellList);
1386 auto posExpression = getV<POS_PROP>(vectorDist);
1387 auto forceExpression = getV<FORCE>(vectorDist);
1388 auto drhoExpression = getV<DRHO>(vectorDist);
1389 auto typeExpression = getV<TYPE>(vectorDist);
1391 auto rhoExpression = getV<RHO>(vectorDist);
1392 auto rho_tmpExpression = getV<RHO_TMP>(vectorDist);
1393 auto rho_prevExpression = getV<RHO_PREV>(vectorDist);
1395 auto velocityExpression = getV<VELOCITY>(vectorDist);
1396 auto velocity_tmpExpression = getV<VELOCITY_TMP>(vectorDist);
1397 auto velocity_prevExpression = getV<VELOCITY_PREV>(vectorDist);
1400 X.data.get<0>() = rhoExpression;
1401 X.data.get<1>() = posExpression[0];
1402 X.data.get<2>() = posExpression[1];
1403 X.data.get<3>() = posExpression[2];
1404 X.data.get<4>() = velocityExpression[0];
1405 X.data.get<5>() = velocityExpression[1];
1406 X.data.get<6>() = velocityExpression[2];
1427 vectorDist.addComputationCosts(md);
1428 vectorDist.getDecomposition().decompose();
1431 std::cout <<
"REBALANCED " << std::endl;
1437 EqState(vectorDist);
1439 double max_visc = 0.0;
1441 vectorDist.ghost_get<TYPE,RHO,PRESSURE,VELOCITY>();
1448 calc_forces(vectorDist,cellList,max_visc);
1456 dt = calc_deltaT(vectorDist,max_visc);
1461 rho_tmpExpression = rhoExpression;
1462 velocity_tmpExpression[0] = velocityExpression[0];
1463 velocity_tmpExpression[1] = velocityExpression[1];
1464 velocity_tmpExpression[2] = velocityExpression[2];
1468 if (iteration < 40) {
1469 X.data.get<0>() = rho_prevExpression;
1471 X.data.get<4>() = velocity_prevExpression[0];
1472 X.data.get<5>() = velocity_prevExpression[1];
1473 X.data.get<6>() = velocity_prevExpression[2];
1475 X.data.get<0>() = rhoExpression;
1476 X.data.get<4>() = velocityExpression[0];
1477 X.data.get<5>() = velocityExpression[1];
1478 X.data.get<6>() = velocityExpression[2];
1481 X.data.get<1>() = posExpression[0];
1482 X.data.get<2>() = posExpression[1];
1483 X.data.get<3>() = posExpression[2];
1485 eulerOdeint.do_step(rhsFunctor, X, t, dt);
1487 rhoExpression=X.data.get<0>();
1488 posExpression[0] = X.data.get<1>();
1489 posExpression[1] = X.data.get<2>();
1490 posExpression[2] = X.data.get<3>();
1491 velocityExpression[0] = X.data.get<4>();
1492 velocityExpression[1] = X.data.get<5>();
1493 velocityExpression[2] = X.data.get<6>();
1495 rho_prevExpression = rho_tmpExpression;
1496 velocity_prevExpression[0] = velocity_tmpExpression[0];
1497 velocity_prevExpression[1] = velocity_tmpExpression[1];
1498 velocity_prevExpression[2] = velocity_tmpExpression[2];
1500 if (iteration == 40)
1505 checkPosPrpLimits(vectorDist);
1513 vectorDist.ghost_get<TYPE,RHO,PRESSURE,VELOCITY>();
1514 vectorDist.updateCellList(cellList);
1518 if (iteration < 40) {
1519 X.data.get<0>() = rho_prevExpression;
1521 X.data.get<4>() = velocity_prevExpression[0];
1522 X.data.get<5>() = velocity_prevExpression[1];
1523 X.data.get<6>() = velocity_prevExpression[2];
1525 X.data.get<0>() = rhoExpression;
1526 X.data.get<4>() = velocityExpression[0];
1527 X.data.get<5>() = velocityExpression[1];
1528 X.data.get<6>() = velocityExpression[2];
1531 X.data.get<1>() = posExpression[0];
1532 X.data.get<2>() = posExpression[1];
1533 X.data.get<3>() = posExpression[2];
1536 sensor_pressure(vectorDist,cellList,press_t,probes);
1538 vectorDist.write_frame(
"Geometry",write);
1542 {std::cout <<
"TIME: " << t <<
" write " << it_time.
getwct() <<
" " << v_cl.
getProcessUnitID() <<
" " << iteration <<
" Max visc: " << max_visc << std::endl;}
1547 {std::cout <<
"TIME: " << t <<
" " << it_time.
getwct() <<
" " << v_cl.
getProcessUnitID() <<
" " << iteration <<
" Max visc: " << max_visc << 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
Class for FAST cell list implementation.
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.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Class for cpu time benchmarking.
double getwct()
Return the elapsed real time.
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.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
A 7d Odeint and Openfpm compatible structure.