Point operator()(MESH& m, NODE n, double t) { (void) t; Point pressure_force = Point(0.0, 0.0, 0.0); for(auto it=m.adj_triangle_begin(n.uid()); it != m.adj_triangle_end(n.uid()); ++ it) { auto tri = (*it); Point normal = get_normal_surface(tri); double area = tri.area(); pressure_force += normal * area * pressure; } return pressure_force; }
Point operator() (MESH& m, NODE n, double t){ Point node_velocity = n.value().velocity; Point node_normal(0.0, 0.0, 0.0); for (auto it = m.adj_triangle_begin(n.uid()); it != m.adj_triangle_end(n.uid()); ++it){ auto tri = (*it); // approximate node normal vector by the sum of normal vectors of its neighboring faces node_normal += get_normal_surface(tri); } // calculte wind force Point force = wind_const * dot(wind_velocity_ - node_velocity, node_normal) * node_normal; (void) t; return force; }
Point post_process(MESH& m, FORCE force, CONSTRAINT& c, double t, double dt, uint water_nodes) { static double ball_bottom = std::numeric_limits<double>::max(); double water_dis = std::numeric_limits<double>::max(); double dh = 0; static double submerged_height = 0; Point bottom_loc; Point water_loc; for (auto n_it = m.node_begin(); n_it != m.node_end(); ++n_it) { // handles the shallow water if ((*n_it).index() < water_nodes) { double sum_area = 0; QVar value = QVar(0,0,0); for (auto tri_it = m.adj_triangle_begin((*n_it).uid()); tri_it != m.adj_triangle_end((*n_it).uid()); ++tri_it) { value += (*tri_it).value().q_bar * (*tri_it).area(); sum_area += (*tri_it).area(); } (*n_it).value().q = value * 1.0/(sum_area); } // handles the ball else { (*n_it).set_position((*n_it).position() + (*n_it).value().velocity*dt); dh = (*n_it).value().q.h - (*n_it).position().z; (*n_it).value().q.h = (*n_it).position().z; (*n_it).value().velocity += force(m,(*n_it),t)*dt/(*n_it).value().mass; if ((*n_it).value().q.h < ball_bottom) { ball_bottom = (*n_it).position().z; bottom_loc = (*n_it).position(); } } } // find the water node closest to the bottom of the ball for (auto n_it = m.node_begin(); (*n_it).index() != water_nodes; ++n_it) { if (norm(Point((*n_it).position().x,(*n_it).position().y,0)-Point(bottom_loc.x,bottom_loc.y,0)) < water_dis){ water_dis = norm(Point((*n_it).position().x,(*n_it).position().y,0)-Point(bottom_loc.x,bottom_loc.y,0)); water_loc = Point((*n_it).position().x,(*n_it).position().y,(*n_it).value().q.h); } } // apply contraints of neccessary c(m,ball_bottom); // determines if the ball fell below shallow water and updates height submerged if (bottom_loc.z < water_loc.z) submerged_height += dh; return Point(bottom_loc.x, bottom_loc.y, submerged_height); }