//Basic first order semi-Lagrangian advection of velocities void FluidSim::advect(float dt) { temp_u.assign(0); temp_v.assign(0); temp_w.assign(0); //semi-Lagrangian advection on u-component of velocity for(int k = 0; k < nk; ++k) for(int j = 0; j < nj; ++j) for(int i = 0; i < ni+1; ++i) { Vec3f pos(i*dx, (j+0.5f)*dx, (k+0.5f)*dx); pos = trace_rk2(pos, -dt); temp_u(i,j,k) = get_velocity(pos)[0]; } //semi-Lagrangian advection on v-component of velocity for(int k = 0; k < nk; ++k) for(int j = 0; j < nj+1; ++j) for(int i = 0; i < ni; ++i) { Vec3f pos((i+0.5f)*dx, j*dx, (k+0.5f)*dx); pos = trace_rk2(pos, -dt); temp_v(i,j,k) = get_velocity(pos)[1]; } //semi-Lagrangian advection on w-component of velocity for(int k = 0; k < nk+1; ++k) for(int j = 0; j < nj; ++j) for(int i = 0; i < ni; ++i) { Vec3f pos((i+0.5f)*dx, (j+0.5f)*dx, k*dx); pos = trace_rk2(pos, -dt); temp_w(i,j,k) = get_velocity(pos)[2]; } //move update velocities into u/v vectors u = temp_u; v = temp_v; w = temp_w; }
//For extrapolated points, replace the normal component //of velocity with the object velocity (in this case zero). void FluidSim::constrain_velocity() { temp_u = u; temp_v = v; //(At lower grid resolutions, the normal estimate from the signed //distance function is poor, so it doesn't work quite as well. //An exact normal would do better.) //constrain u for(int j = 0; j < u.nj; ++j) for(int i = 0; i < u.ni; ++i) { if(u_weights(i,j) == 0) { //apply constraint Vec2f pos(i*dx, (j+0.5f)*dx); Vec2f vel = get_velocity(pos); Vec2f normal(0,0); interpolate_gradient(normal, pos/dx, nodal_solid_phi); normalize(normal); float perp_component = dot(vel, normal); vel -= perp_component*normal; temp_u(i,j) = vel[0]; } } //constrain v for(int j = 0; j < v.nj; ++j) for(int i = 0; i < v.ni; ++i) { if(v_weights(i,j) == 0) { //apply constraint Vec2f pos((i+0.5f)*dx, j*dx); Vec2f vel = get_velocity(pos); Vec2f normal(0,0); interpolate_gradient(normal, pos/dx, nodal_solid_phi); normalize(normal); float perp_component = dot(vel, normal); vel -= perp_component*normal; temp_v(i,j) = vel[1]; } } //update u = temp_u; v = temp_v; }
//Basic first order semi-Lagrangian advection of velocities void FluidSim::advect(float dt) { //semi-Lagrangian advection on u-component of velocity for(int j = 0; j < nj; ++j) for(int i = 0; i < ni+1; ++i) { Vec2f pos(i*dx, (j+0.5f)*dx); pos = trace_rk2(pos, -dt); temp_u(i,j) = get_velocity(pos)[0]; } //semi-Lagrangian advection on v-component of velocity for(int j = 0; j < nj+1; ++j) for(int i = 0; i < ni; ++i) { Vec2f pos((i+0.5f)*dx, j*dx); pos = trace_rk2(pos, -dt); temp_v(i,j) = get_velocity(pos)[1]; } //move update velocities into u/v vectors u = temp_u; v = temp_v; }
//--------------------------------------------------------------------------- //读取位移解及等效应变能数据 void Postprocessor::read_u_solution_equivalent_energy(const string &output_file_name, double equivalent_energy[]) { //------------------------------------------------------------------------------------------------- //二进制读取数据 int us, uis; fstream idata(output_file_name.c_str(), ios::in|ios::binary); //读取位移解数据 idata.read((char *)&us, sizeof(int)); idata.read((char *)&uis, sizeof(int)); vector<double> temp_u(uis); u.assign(us, temp_u); for(int i=0; i<us; i++) for(int j=0; j<uis; j++) idata.read((char *)&u[i][j], sizeof(double)); //读取等效应变能数据 idata.read((char *)equivalent_energy, sizeof(double)*9); idata.close(); }
//For extrapolated points, replace the normal component //of velocity with the object velocity (in this case zero). void FluidSim::constrain_velocity() { temp_u = u; temp_v = v; temp_w = w; //(At lower grid resolutions, the normal estimate from the signed //distance function can be poor, so it doesn't work quite as well. //An exact normal would do better if we had it for the geometry.) //constrain u for(int k = 0; k < u.nk;++k) for(int j = 0; j < u.nj; ++j) for(int i = 0; i < u.ni; ++i) { if(u_weights(i,j,k) == 0) { //apply constraint temp_u(i,j,k) = 0;//vel[0]; } } //constrain v for(int k = 0; k < v.nk;++k) for(int j = 0; j < v.nj; ++j) for(int i = 0; i < v.ni; ++i) { if(v_weights(i,j,k) == 0) { //apply constraint temp_v(i,j,k) = 0; //vel[1]; } } //constrain w for(int k = 0; k < w.nk;++k) for(int j = 0; j < w.nj; ++j) for(int i = 0; i < w.ni; ++i) { if(w_weights(i,j,k) == 0) { //apply constraint temp_w(i,j,k) = 0; //vel[2]; } } //update u = temp_u; v = temp_v; w = temp_w; }