static vec3 expected_acceleration(double time, const struct rocket_state *rocket_state) { /* TODO: add coefficient of normal force at the center of pressure */ vec3 force = vec_add(thrust_force(rocket_state, (microseconds) time), drag_force(rocket_state)); vec3 accel = vec_add(gravity_acceleration(rocket_state), vec_scale(force, 1/mass)); geodetic pos = ECEF_to_geodetic(rocket_state->pos); if(pos.altitude <= initial_geodetic.altitude){ mat3 rot = make_LTP_rotation(pos); ground_clip(&accel, rot); } return accel; }
void Cconfig::sum_force() { Cmatrix stress; Cvector g;//vector gravity if(cell.boundary=="WALL_INCLINED"){ g.x[0]= cell.gravity*sin(PI/180 * cell.slope ); g.x[1]= -cell.gravity*cos(PI/180 * cell.slope ); g.x[2]=0; }// else g is null #pragma omp parallel for num_threads(NTHREADS) // YG, MPI for(int ip=0; ip< P.size();ip++) { P[ip].Fsum = (g*P[ip].m); P[ip].Gsum*=0; } if(LIQUID_TRANSFER) drag_force(); // YG, no MPI for(int ic=0;ic<C.size();ic++) { Cvector dx; P[C[ic].A].Fsum += C[ic].F; P[C[ic].B].Fsum -= C[ic].F; P[C[ic].A].Gsum += (C[ic].RA^C[ic].F) +C[ic].G; P[C[ic].B].Gsum -= (C[ic].RB^C[ic].F) +C[ic].G; // Additional force due to positive water pressure, CHECK !! Cvector FWATER_A = C[ic].nA * (P[C[ic].B].positive_pressure)*C[ic].voronoi_area; Cvector FWATER_B = C[ic].nA * (P[C[ic].A].positive_pressure)*C[ic].voronoi_area; P[C[ic].A].Fsum -= FWATER_A; P[C[ic].B].Fsum += FWATER_B; dx = C[ic].dX; stress+= (C[ic].F| dx); } double positive_pressure =0.0; for(int ip=0; ip<P.size();ip++){ // positive pressure, contribute to the full domain, using voronoi_volume ! positive_pressure += P[ip].positive_pressure * P[ip].voronoi_volume; // if(P[ip].saturation <= 1.0) positive_pressure += P[ip].positive_pressure * P[ip].water_volume; // else positive_pressure += P[ip].positive_pressure * P[ip].void_volume; } for(int ii=0;ii<3;ii++) stress.x[ii][ii] -= positive_pressure; if(PSEUDO_2D) stress/=(cell.L.x[0]*cell.L.x[1]); else stress/=(cell.L.x[0]*cell.L.x[1]*cell.L.x[2]); //cell.stress = stress.symetric(); cell.stress =stress; if(cell.boundary!="WALL_INCLINED") return; cell.normal_stress_in=0; cell.shear_stress_in=0; for(int ic=0;ic<C.size();ic++) { if(P[C[ic].A].AM_I_BOUNDARY==-1||P[C[ic].A].AM_I_BOUNDARY==-2){ cell.normal_stress_in+=C[ic].F.x[1]; cell.shear_stress_in+=C[ic].F.x[0];} if(P[C[ic].B].AM_I_BOUNDARY==-1||P[C[ic].B].AM_I_BOUNDARY==-2){ cell.normal_stress_in-=C[ic].F.x[1]; cell.shear_stress_in-=C[ic].F.x[0];} } cell.normal_stress_in/=(cell.L.x[0]* cell.L.x[2]);cell.shear_stress_in/=(cell.L.x[0]* cell.L.x[2]); cell.normal_stress_in*=-1;//get it positive in compression }
void Cconfig::sum_force() { Cmatrix stress, stressEff; // stress *= 0; stressEff *= 0; Cvector g = cell.g; #pragma omp parallel for num_threads(NTHREADS) // YG, MPI for(int ip=0; ip< P.size();ip++) { P[ip].Fsum = (g*P[ip].m); P[ip].Gsum*=0; } if(LIQUID_TRANSFER) drag_force(); // YG, no MPI for(int ic=0;ic<C.size();ic++) { Cvector dx; P[C[ic].A].Fsum += C[ic].F; if(C[ic].B >=0) P[C[ic].B].Fsum -= C[ic].F; P[C[ic].A].Gsum += (C[ic].RA^C[ic].F) +C[ic].G; if(C[ic].B >=0) P[C[ic].B].Gsum -= (C[ic].RB^C[ic].F) +C[ic].G; if(LIQUID_TRANSFER && C[ic].B >=0){ // Additional force due to positive water pressure, CHECK !! Cvector FWATER_A = C[ic].nA * (P[C[ic].B].positive_pressure)*C[ic].voronoi_area; Cvector FWATER_B = C[ic].nA * (P[C[ic].A].positive_pressure)*C[ic].voronoi_area; // C[ic].fwater = (P[C[ic].A].positive_pressure + P[C[ic].B].positive_pressure)*C[ic].voronoi_area/2.0; P[C[ic].A].Fsum += FWATER_A; P[C[ic].B].Fsum -= FWATER_B; } dx = C[ic].dX; stress+= (C[ic].F| dx); stressEff += (C[ic].FEff| dx); // Effective stress } if(LIQUID_TRANSFER){ double positive_pressure =0.0; for(int ip=0; ip<P.size();ip++){ // positive pressure, contribute to the full domain, using voronoi_volume ! positive_pressure += P[ip].positive_pressure * P[ip].voronoi_volume; // if(P[ip].saturation <= 1.0) positive_pressure += P[ip].positive_pressure * P[ip].water_volume; // else positive_pressure += P[ip].positive_pressure * P[ip].void_volume; } for(int ii=0;ii<3;ii++) stress.x[ii][ii] -= positive_pressure; } if(PSEUDO_2D) stress/=(cell.L.x[0]*cell.L.x[1]); else stress/=(cell.L.x[0]*cell.L.x[1]*cell.L.x[2]); if(PSEUDO_2D) stressEff /=(cell.L.x[0]*cell.L.x[1]); else stressEff /=(cell.L.x[0]*cell.L.x[1]*cell.L.x[2]); //cell.stress = stress.symetric(); cell.stress =stress; cell.stressEff =stressEff; cell.normal_stress_in = stress.x[1][1]; cell.shear_stress_in = stress.x[0][1]; if(cell.boundary!="WALL_INCLINED" && cell.boundary != "BALL_BOX_Y") return; cell.normal_stress_bottom = 0.0; cell.shear_stress_bottom = 0.0; cell.normal_stress_top = 0.0; cell.shear_stress_top = 0.0; for(int ic=0;ic<C.size();ic++) { if(C[ic].B >= 0){ // grain-grain contact at the bottom if(P[C[ic].A].AM_I_BOUNDARY==-1||P[C[ic].A].AM_I_BOUNDARY==-2){ cell.normal_stress_bottom+=C[ic].F.x[1]; cell.shear_stress_bottom+=C[ic].F.x[0];} if(P[C[ic].B].AM_I_BOUNDARY==-1||P[C[ic].B].AM_I_BOUNDARY==-2){ cell.normal_stress_bottom-=C[ic].F.x[1]; cell.shear_stress_bottom-=C[ic].F.x[0];} // grain-grain contact at the top if(P[C[ic].A].AM_I_BOUNDARY==1||P[C[ic].A].AM_I_BOUNDARY==2){ cell.normal_stress_top+=C[ic].F.x[1]; cell.shear_stress_top+=C[ic].F.x[0];} if(P[C[ic].B].AM_I_BOUNDARY==1||P[C[ic].B].AM_I_BOUNDARY==2){ cell.normal_stress_top-=C[ic].F.x[1]; cell.shear_stress_top-=C[ic].F.x[0];} } if(C[ic].B == -3) // grain-wall contact at the bottom {cell.normal_stress_bottom-=C[ic].F.x[1]; cell.shear_stress_bottom-=C[ic].F.x[0];} if(C[ic].B == -4) // grain-wall contact at the top {cell.normal_stress_top-=C[ic].F.x[1]; cell.shear_stress_top-=C[ic].F.x[0];} } cell.normal_stress_bottom/=(cell.L.x[0]* cell.L.x[2]); cell.shear_stress_bottom/=(cell.L.x[0]* cell.L.x[2]); cell.normal_stress_bottom*=-1; //bottom: normal stress direction, get it positive in compression cell.normal_stress_top/=(cell.L.x[0]* cell.L.x[2]); cell.shear_stress_top/=(cell.L.x[0]* cell.L.x[2]); cell.shear_stress_top*=-1; // top: shear stress direction }