예제 #1
0
  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; 
  }  
예제 #2
0
 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;
 }
예제 #3
0
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);
}