示例#1
0
文件: Grid.hpp 项目: k-ye/mcmc-viz
  /** Returns a grid of the interval separated by the number of points.
    * @param[in] x [low, high] domain of x
    * @param[in] y [low, high] domain of y
    * @param[in] n_x number of linearly spaced points in interval x
    * @param[in] n_y number of linearly space points in interval y
    * @return Mesh which connects all the points in the grid.
    *
    * Complexity: O(n_x*n_y).
    */
  MeshType operator()(interval x, interval y, size_type n_x, size_type n_y) {
    MeshType mesh;
    value_type x_step = (x.second - x.first) / (n_x - 1);
    value_type y_step = (y.second - y.first) / (n_y - 1);

    for (size_type j = n_y; j > 0; --j) {
      for (size_type i = 1; i <= n_x; ++i) {
        mesh.add_node(Point((i-1)*x_step, (j-1)*y_step, 0));
        MeshType::size_type idx = mesh.num_nodes() - 1;
        if (j != n_y) {
          if (i == 1) {
            mesh.add_triangle(mesh.node(idx), mesh.node(idx - n_x), mesh.node(idx - n_x + 1));
          } else if (i == n_x) {
            mesh.add_triangle(mesh.node(idx), mesh.node(idx - 1), mesh.node(idx - n_x));
          } else {
            mesh.add_triangle(mesh.node(idx), mesh.node(idx - 1), mesh.node(idx - n_x));
            mesh.add_triangle(mesh.node(idx), mesh.node(idx - n_x), mesh.node(idx - n_x + 1));
          }
        }
      }
    }
    return mesh;
  }
示例#2
0
int main(int argc, char* argv[])
{
  // Check arguments
  if (argc < 3) {
    std::cerr << "Usage: shallow_water NODES_FILE TRIS_FILE\n";
    exit(1);
  }

  MeshType mesh;
  // HW4B: Need node_type before this can be used!
#if 1
  std::vector<typename MeshType::node_type> mesh_node;
#endif

  // Read all Points and add them to the Mesh
  std::ifstream nodes_file(argv[1]);
  Point p;
  while (CS207::getline_parsed(nodes_file, p)) {
    // HW4B: Need to implement add_node before this can be used!
#if 1
    mesh_node.push_back(mesh.add_node(p));
#endif
  }

  // Read all mesh triangles and add them to the Mesh
  std::ifstream tris_file(argv[2]);
  std::array<int,3> t;
  while (CS207::getline_parsed(tris_file, t)) {
    // HW4B: Need to implement add_triangle before this can be used!
#if 1
    mesh.add_triangle(mesh_node[t[0]], mesh_node[t[1]], mesh_node[t[2]]);
#endif
  }

  // Print out the stats
  std::cout << mesh.num_nodes() << " "
            << mesh.num_edges() << " "
            << mesh.num_triangles() << std::endl;

  // HW4B Initialization
  // Set the initial conditions based off third argument
  // Perform any needed precomputation
  std::pair<double, double> value_pair;
  if ((*argv[3]) == '0') {
      std::cout << "Pebble Ripple" << std::endl;
      value_pair = PebbleRipple()(mesh);
  } else if ((*argv[3]) == '1') {
      std::cout << "Sharp Wave" << std::endl;
      value_pair = SharpWave()(mesh);
  } else {
      std::cout << "Dam Break" << std::endl;
      value_pair = DamBreak()(mesh);
  }
  
  double max_height = value_pair.first;
  double min_edge_length = value_pair.second;

  // Launch the SDLViewer
  CS207::SDLViewer viewer;
  viewer.launch();

  // HW4B: Need to define Mesh::node_type and node/edge iterator
  // before these can be used!
#if 1
  auto node_map = viewer.empty_node_map(mesh);
  viewer.add_nodes(mesh.node_begin(), mesh.node_end(),
                   CS207::DefaultColor(), NodePosition(), node_map);
  viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);
#endif
  viewer.center_view();
  // CFL stability condition requires dt <= dx / max|velocity|
  // For the shallow water equations with u = v = 0 initial conditions
  //   we can compute the minimum edge length and maximum original water height
  //   to set the time-step
  // Compute the minimum edge length and maximum water height for computing dt
#if 1
  double dt = 0.25 * min_edge_length / (sqrt(grav * max_height));
#else
  // Placeholder!! Delete me when min_edge_length and max_height can be computed!
  double dt = 0.1;
#endif
  double t_start = 0;
  double t_end = 5;

  // Preconstruct a Flux functor
  EdgeFluxCalculator f;

  // Begin the time stepping
  for (double t = t_start; t < t_end; t += dt) {
    // Step forward in time with forward Euler
    hyperbolic_step(mesh, f, t, dt);
    // Update node values with triangle-averaged values
    post_process(mesh);
    
    // Update the viewer with new node positions
#if 1
    // Update viewer with nodes' new positions
    viewer.add_nodes(mesh.node_begin(), mesh.node_end(),
                     CoolColor(), NodePosition(), node_map);
#endif
    viewer.set_label(t);

    // These lines slow down the animation for small meshes.
    // Feel free to remove them or tweak the constants.
    if (mesh.num_nodes() < 100)
      CS207::sleep(0.05);
  }

  return 0;
}
示例#3
0
int main(int argc, char** argv) {
  // Check arguments
  if (argc < 5) {
    std::cerr << "Usage: " << argv[0] << " NODES_FILE TETS_FILE\n";
    exit(1);
  }

  // Construct the first mesh
  MeshType mesh;
  //construct the second mesh
  MeshType mesh2;

  std::vector<typename MeshType::node_type> mesh_node;
  // Read all Points and add them to the Mesh
  std::ifstream nodes_file(argv[1]);
  Point p;
  while (CS207::getline_parsed(nodes_file, p)) {
    mesh_node.push_back(mesh.add_node(p));
  }

  // Read all mesh triangles and add them to the Mesh
  std::ifstream tris_file(argv[2]);
  std::array<int,3> t;
  while (CS207::getline_parsed(tris_file, t)) {
    mesh.add_triangle(mesh_node[t[0]], mesh_node[t[1]], mesh_node[t[2]]);
  }

  std::vector<typename MeshType::node_type> mesh_node2;
  // Read all Points and add them to the Mesh
  std::ifstream nodes_file2(argv[3]);
  while (CS207::getline_parsed(nodes_file2, p)) {
    mesh_node2.push_back(mesh2.add_node(p));
  }

  // Read all mesh triangles and add them to the Mesh
  std::ifstream tris_file2(argv[4]);
  while (CS207::getline_parsed(tris_file2, t)) {
    mesh2.add_triangle(mesh_node2[t[0]], mesh_node2[t[1]], mesh_node2[t[2]]);
  }
  
  //move the second mesh to the specified position
  for(auto it = mesh2.node_begin();it!=mesh2.node_end();++it){
    (*it).position().elem[1] +=4 ;
    (*it).position().elem[2] +=4 ;
  }

  // Print out the stats
  std::cout << mesh.num_nodes() << " "
            << mesh.num_edges() << " "
            << mesh.num_triangles() << std::endl;
  std::cout << mesh2.num_nodes() << " "
            << mesh2.num_edges() << " "
            << mesh2.num_triangles() << std::endl;



  //set the mass and velocity of each Node for the first mesh
  for (auto it = mesh.node_begin(); it != mesh.node_end(); ++it){
    (*it).value().mass = float(1)/mesh.num_nodes();
    (*it).value().velocity = Point(0, 10, 10);
  }
  //set the mass and velocity of each Node for the second mesh
  for (auto it = mesh2.node_begin(); it != mesh2.node_end(); ++it){
    (*it).value().mass = float(1)/mesh.num_nodes();
    (*it).value().velocity = Point(0, -10, -10);
  }

  //set K and L for each edge
  for (auto it = mesh.node_begin(); it != mesh.node_end(); ++it)
  {
    for (auto j = (*it).edge_begin(); j != (*it).edge_end(); ++j){
       (*j).value().L = (*j).length();
       (*j).value().K = 16000;
    }
  }

  for (auto it = mesh2.node_begin(); it != mesh2.node_end(); ++it)
  {
    for (auto j = (*it).edge_begin(); j != (*it).edge_end(); ++j){
       (*j).value().L = (*j).length();
       (*j).value().K = 16000;
    }
  }


  // Launch the SDLViewer
  CS207::SDLViewer viewer;
  auto node_map = viewer.empty_node_map(mesh);
  viewer.launch();

  viewer.add_nodes(mesh.node_begin(), mesh.node_end(), node_map);
  viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);
  viewer.add_nodes(mesh2.node_begin(), mesh2.node_end(), node_map);
  viewer.add_edges(mesh2.edge_begin(), mesh2.edge_end(), node_map);

  viewer.center_view();
  
  //Begin the mass-spring simulation
  double dt = 0.0002;
  double t_start = 0.0;
  double t_end   = 10.0;
   
  //three color parameter
  int color1 = 1; 
  int color2 = 1; 
  int color3 = 1; 
  
  //Create listener
  Pause_listener* pause = new Pause_listener(dt); 
  Speed_listener* speed = new Speed_listener(dt, dt); 
  XYZ_listener<MeshType>* xyz = new XYZ_listener<MeshType>(&mesh);
  Color_listener* col = new Color_listener(&color1, &color2, &color3);
  
  //add listener
  viewer.add_listener(pause);
  viewer.add_listener(speed);
  viewer.add_listener(xyz);
  viewer.add_listener(col);

  //Initialize forces
  WindForce wind_force(Point(0,100,200));
  PressureForce<typename MeshType::node_type, MeshType> pressure_force(1, 2500, &mesh);
  DampingForce damp_force(float(1)/mesh.num_nodes());
  //auto force = make_combined_force(MassSpringForce(), GravityForce(), make_combined_force(pressure_force, damp_force, wind_force));
  auto force = make_combined_force(MassSpringForce(), make_combined_force(pressure_force, damp_force, wind_force));
  
  //Initialize constriants
  auto constraint = PlaneConstraint<MeshType>(-4);

  //simulation processing   
  for (double t = t_start; t < t_end; t += dt) {
    constraint(mesh, 0);
    constraint(mesh2, 0);
    //define a collision constrain
    auto collision_constrain = CollisionConstraint<MeshType>();
    //add the forces to the meshs at each dt
    symp_euler_step(mesh, t, dt, force);
    symp_euler_step(mesh2, t, dt, force);
    
    //detec the collision betweent the two meshes
    CollisionDetector<MeshType> c;
    c.add_object(mesh);
    c.add_object(mesh2);
    c.check_collisions();
    std::vector<unsigned> collision;
    std::vector<unsigned> collision2;

    //find the corresponding mesh for each node
    for (auto it=c.begin(); it!= c.end(); ++it){
      auto boom = *it;
      Node n = boom.n1;
      if (boom.mesh1 == &mesh)
        collision.push_back(n.index());
      if (boom.mesh1 == &mesh2)
        collision2.push_back(n.index());
    }

    //add the collision constrain to the meshes
    collision_constrain(mesh,mesh2,collision,collision2);
    viewer.set_label(t);
    
    //update with removed nodes
    //clear teh viewer's node
    viewer.clear();
    node_map.clear();
    //update viewer with new positions and new edges
    viewer.add_nodes(mesh.node_begin(), mesh.node_end(), color(color1, color2, color3), node_map);
    viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);
    viewer.add_nodes(mesh2.node_begin(), mesh2.node_end(), color(color1, color2, color3), node_map);
    viewer.add_edges(mesh2.edge_begin(), mesh2.edge_end(), node_map);

    // These lines slow down the animation for small graphs
    if (mesh.num_nodes() < 100)
      CS207::sleep(0.001);
  }

  return 0;
}
示例#4
0
int main(int argc, char* argv[]) {
  // Check arguments
  if (argc < 2) {
    std::cerr << "Usage: " << argv[0] << " NODES_FILE TETS_FILE\n";
    exit(1);
  }

  MeshType mesh;
  std::vector<typename MeshType::node_type> nodes;

  // Create a nodes_file from the first input argument
  std::ifstream nodes_file(argv[1]);
  
  // Interpret each line of the nodes_file as a 3D Point and add to the Mesh
  Point p;
  while (CS207::getline_parsed(nodes_file, p))
    nodes.push_back(mesh.add_node(p));

  // Create a trianges_file from the second input argument
  std::ifstream triangles_file(argv[2]);

  // Interpret each line of the tets_file as three ints which refer to nodes
  std::array<int,3> t;


  // add in the triangles
  while (CS207::getline_parsed(triangles_file, t))
    for (unsigned i = 1; i < t.size(); ++i)
      for (unsigned j = 0; j < i; ++j)
        for (unsigned k = 0; k < j; ++k)
        {
          mesh.add_triangle(nodes[t[i]], nodes[t[j]], nodes[t[k]]);
      }   

  // Set masses of nodes equal to 1/N where N is the number of nodes
  // and the initial velocities to 0. Also, get the indexes of
  // the nodes at positions (1,0,0) and (0,0,0)
  for(auto it=mesh.node_begin(); it != mesh.node_end(); ++ it)
  {
      (*it).value().mass = total_mass/mesh.num_nodes();
      (*it).value().velocity = Point(0.0,0.0,0.0);
  }

  // Set spring constants for each node equal to spring_const variable
  // and set initial length values equal to lengths of edges prior to
  // running the symplectic Euler steps
  for(auto it=mesh.edge_begin(); it != mesh.edge_end(); ++ it)
  {
      (*it).value().spring_constant = spring_const;
      (*it).value().initial_length = (*it).length();
  }


  // Set the triangle direction values so that we can determine which 
  // way to point normal vectors. This part assumes a convex shape
  Point center = get_center(mesh);
  for(auto it=mesh.triangle_begin(); it != mesh.triangle_end(); ++ it)
  {  
  	//std::cout << (*it).index() << std::endl;
  	set_normal_direction((*it),center);
  }

  // Print out the stats
  std::cout << mesh.num_nodes() << " " << mesh.num_edges() << std::endl;

  std::cout << "Center: " << get_center(mesh) << std::endl;
  // Launch the SDLViewer
  CS207::SDLViewer viewer;
  auto node_map = viewer.empty_node_map(mesh);
  viewer.launch();

  viewer.add_nodes(mesh.node_begin(), mesh.node_end(), node_map);
  viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);

  viewer.center_view();

  // Begin the mass-spring simulation
  double dt = 0.0001;
  double t_start = 0;
  double t_end = 20.0;
  

  // Initialize constraints
  PlaneConstraint c1;
  //SelfCollisionConstraint c2;
  //auto combined_constraints = make_combined_constraints(c1,c2);
  


  for (double t = t_start; t < t_end; t += dt) {
    MassSpringForce ms_force;
    PressureForce p_force = PressureForce(0.0);
    DampingForce d_force = DampingForce(mesh.num_nodes());
    GravityForce g_force;
    WindForce w_force;

    (void) d_force; // prevents compiler from throwing error for unused variable
      
    
    if (t >= t_addgas - dt) {
      p_force.set_pressure(gas_const/get_volume(mesh));
      if (t < t_addgas)
        std::cout << "Adding gas to the ball now..." << std::endl;
    }

    auto combined_forces = make_combined_force(ms_force, p_force, w_force, g_force);

    symp_euler_step(mesh, t, dt, combined_forces, c1);

    // Update viewer with nodes' new positions
    viewer.add_nodes(mesh.node_begin(), mesh.node_end(), node_map);

    // update the viewer's label with the ball center's position on the z axis 
    viewer.set_label(get_center(mesh).z);

  }
  return 0;
}
示例#5
0
int main(int argc, char* argv[])
{
  // Check arguments
  if (argc < 3) {
    std::cerr << "Usage: shallow_water NODES_FILE TRIS_FILE\n";
    exit(1);
  }

  MeshType mesh;
  // HW4B: Need node_type before this can be used!
#if 1
  std::vector<typename MeshType::node_type> mesh_node;
#endif

  // Read all Points and add them to the Mesh
  std::ifstream nodes_file(argv[1]);
  Point p;
  while (CS207::getline_parsed(nodes_file, p)) {
    // HW4B: Need to implement add_node before this can be used!
#if 1
    mesh_node.push_back(mesh.add_node(p));
#endif
  }

  // Read all mesh triangles and add them to the Mesh
  std::ifstream tris_file(argv[2]);
  std::array<int,3> t;
  while (CS207::getline_parsed(tris_file, t)) {
    // HW4B: Need to implement add_triangle before this can be used!
#if 1
    mesh.add_triangle(mesh_node[t[0]], mesh_node[t[1]], mesh_node[t[2]]);
#endif
  }

  // Print out the stats
  std::cout << mesh.num_nodes() << " "
            << mesh.num_edges() << " "
            << mesh.num_triangles() << std::endl;

  // HW4B Initialization
  // Set the initial conditions according the type of input pattern
  if(argv[2][5]=='d'){
    Dam<MeshType> init;
    for(auto it= mesh.node_begin(); it != mesh.node_end(); ++it)
      init(*it);
    }
  else if((argv[2][5]=='p')){
    Pebble<MeshType> init;
    for(auto it= mesh.node_begin(); it != mesh.node_end(); ++it)
      init(*it);
    }
  else{
    Wave<MeshType> init;
    for(auto it= mesh.node_begin(); it != mesh.node_end(); ++it)
      init(*it);
    }

  // Set triangle values
  for (auto it=mesh.triangle_begin(); it!=mesh.triangle_end(); ++it) {
    (*it).value().Q = QVar(0.0,0.0,0.0);
    (*it).value().Q += (*it).node(0).value().Q;
    (*it).value().Q += (*it).node(1).value().Q;
    (*it).value().Q += (*it).node(2).value().Q;
    (*it).value().Q /= 3.0;
  }
 

  // Launch the SDLViewer
  CS207::SDLViewer viewer;
  viewer.launch();


  // HW4B: Need to define Mesh::node_type and node/edge iterator
  // before these can be used!
#if 1
  auto node_map = viewer.empty_node_map(mesh);
  viewer.add_nodes(mesh.node_begin(), mesh.node_end(),
                   CS207::DefaultColor(), NodePosition(), node_map);
  viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);
#endif
  viewer.center_view();


  // HW4B: Timestep
  // CFL stability condition requires dt <= dx / max|velocity|
  // For the shallow water equations with u = v = 0 initial conditions
  //   we can compute the minimum edge length and maximum original water height
  //   to set the time-step
  // Compute the minimum edge length and maximum water height for computing dt
  double min_edge_length =( *mesh.edge_begin()).length();
  for (auto it=mesh.edge_begin(); it!=mesh.edge_end(); ++it) {
    if ((*it).length() < min_edge_length) {
      min_edge_length = (*it).length();
    }
  }
  double max_height = 0.0;
  for (auto it=mesh.node_begin(); it!=mesh.node_end(); ++it) {
    if ((*it).value().Q.h > max_height) {
      max_height = (*it).value().Q.h;
    }
  }
  
#if 1

  double dt = 0.25 * min_edge_length / (sqrt(grav * max_height));
#else
  // Placeholder!! Delete me when min_edge_length and max_height can be computed!
  double dt = 0.1;
#endif
  double t_start = 0;
  double t_end = 10;

  // Preconstruct a Flux functor
  EdgeFluxCalculator f;

  // Begin the time stepping
  for (double t = t_start; t < t_end; t += dt) {
    //print(mesh, t);
    // Step forward in time with forward Euler
    hyperbolic_step(mesh, f, t, dt);

    // Update node values with triangle-averaged values
    post_process(mesh);

    // Update the viewer with new node positions
    // HW4B: Need to define node_iterators before these can be used!
#if 1
    viewer.add_nodes(mesh.node_begin(), mesh.node_end(),
                     CS207::DefaultColor(), NodePosition(), node_map);
#endif
    viewer.set_label(t);

    // These lines slow down the animation for small meshes.
    // Feel free to remove them or tweak the constants.
    if (mesh.num_nodes() < 100)
      CS207::sleep(0.05);
  }

  return 0;
}
示例#6
0
int main(int argc, char* argv[]) {
  // Check arguments
  if (argc < 5) {
    std::cerr << "Usage: final_project NODES_FILE TRIS_FILE ball.nodes ball.tris \n";
    exit(1);
  }

  MeshType mesh;
  std::vector<typename MeshType::node_type> mesh_node;

  // Read all water Points and add them to the Mesh
  std::ifstream nodes_file(argv[1]);
  Point p;
  uint water_nodes = 0;
  while (CS207::getline_parsed(nodes_file, p)) {
    mesh_node.push_back(mesh.add_node(p));
    water_nodes++;
  }

  // Read all water mesh triangles and add them to the Mesh
  std::ifstream tris_file(argv[2]);
  std::array<int,3> t;
  int water_tris = 0;
  while (CS207::getline_parsed(tris_file, t)) {
    mesh.add_triangle(mesh_node[t[0]], mesh_node[t[1]], mesh_node[t[2]]);
    water_tris++;
  }
  uint water_edges = mesh.num_edges();

  std::ifstream nodes_file2(argv[3]);
  double radius = 1 * scale;
  while (CS207::getline_parsed(nodes_file2, p)) {
    p *= scale;
    p.z += + start_height;
    mesh_node.push_back(mesh.add_node(p));
  }

  // Read all ball mesh triangles and add them to the mesh
  std::ifstream tris_file2(argv[4]);
  while (CS207::getline_parsed(tris_file2, t)) {
    mesh.add_triangle(mesh_node[t[0]+water_nodes], mesh_node[t[1]+water_nodes], mesh_node[t[2]+water_nodes]);
  }

  // Print out the stats
  std::cout << mesh.num_nodes() << " "
            << mesh.num_edges() << " "
            << mesh.num_triangles() << std::endl;

  /* Set the initial conditions */ 
  // Set the initial values of the nodes and get the maximum height double
  double max_h = 0;
  double dx = 0;
  double dy = 0;
  auto init_cond = Still();
  auto b_init_cond = Cone(); 

  // Find the maximum height and apply initial conditions to nodes
  for (auto it = mesh.node_begin(); it != mesh.node_end(); ++it) { 
    auto n = *it;
    if (n.index() < water_nodes){
	    n.value().q = init_cond(n.position());
	    n.value().b = b_init_cond(n.position());
	    max_h = std::max(max_h, n.value().q.h);
  	}
  	else {
  		n.value().q = QVar(n.position().z, 0, 0);
      n.value().mass = total_mass/(mesh.num_nodes() - water_nodes);
      n.value().velocity = Point(0.0,0.0,0.0);
  	}
  } 

  // Set the initial values of the triangles to the average of their nodes and finds S
  // Set the triangle direction values so that we can determine which 
  // way to point normal vectors. This part assumes a convex shape
  Point center = get_center(mesh); 
  for (auto it = mesh.triangle_begin(); it != mesh.triangle_end(); ++it) {
    auto t = *it; 
    if (t.index() < water_tris){
	    t.value().q_bar = (t.node1().value().q + 
	                       t.node2().value().q + 
	                       t.node3().value().q) / 3.0;
	    t.value().q_bar2 = t.value().q_bar;

	    double b_avg = (t.node1().value().b + 
	                    t.node2().value().b + 
	                    t.node3().value().b) / 3.0;
	    // finds the max dx and dy to calculate Source
	    dx = std::max(dx, fabs(t.node1().position().x - t.node2().position().x));
	    dx = std::max(dx, fabs(t.node2().position().x - t.node3().position().x));
	    dx = std::max(dx, fabs(t.node3().position().x - t.node1().position().x));
	    dy = std::max(dy, fabs(t.node1().position().y - t.node2().position().y));
	    dy = std::max(dy, fabs(t.node2().position().y - t.node3().position().y));
	    dy = std::max(dy, fabs(t.node3().position().y - t.node1().position().y));
	    t.value().S = QVar(0, -grav * t.value().q_bar.h * b_avg / dx, -grav * t.value().q_bar.h * b_avg / dy);
	  } 
    else
      set_normal_direction((*it),center);
  }

  // Calculate the minimum edge length and set edge inital condititons
  double min_edge_length = std::numeric_limits<double>::max();
  uint count = 0;
  for (auto it = mesh.edge_begin(); it != mesh.edge_end(); ++it, count++){
    if (count < water_edges)
      min_edge_length = std::min(min_edge_length, (*it).length());
    else {
      (*it).value().spring_constant = spring_const;
      (*it).value().initial_length = (*it).length();
    }
  }
	
  // Launch the SDLViewer
  CS207::SDLViewer viewer;
  viewer.launch();

  auto node_map = viewer.empty_node_map(mesh);
  viewer.add_nodes(mesh.node_begin(), mesh.node_end(),
                   Color(water_nodes), NodePosition(), node_map);
  viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);
  // adds solid color-slows down program significantly
  //viewer.add_triangles(mesh.triangle_begin(), mesh.triangle_end(), node_map);
  viewer.center_view();


  // CFL stability condition requires dt <= dx / max|velocity|
  // For the shallow water equations with u = v = 0 initial conditions
  //   we can compute the minimum edge length and maximum original water height
  //   to set the time-step
  // Compute the minimum edge length and maximum water height for computing dt
  double dt = 0.25 * min_edge_length / (sqrt(grav * max_h));
  double t_start = 0;
  double t_end = 10;
  Point ball_loc = Point(0,0,0);
  double dh = 0;
  // double pressure = gas_const/(4/3*M_PI*radius*radius*radius);

  // add listener
  my_listener* l = new my_listener(viewer,mesh,dt); 
  viewer.add_listener(l);

  // Preconstruct a Flux functor
  EdgeFluxCalculator f;
  // defines the constraint
  PlaneConstraint c = PlaneConstraint(plane_const);

  // Begin the time stepping
  for (double t = t_start; t < t_end; t += dt) {
    // define forces on ball
    GravityForce g_force;
    BuoyantForce b_force = BuoyantForce(dh, ball_loc.z);
    WindForce w_force;
    MassSpringForce ms_force;
    // PressureForce p_force = PressureForce(pressure);
    // DampingForce d_force = DampingForce(mesh.num_nodes());
    auto combined_forces = make_combined_force(g_force, b_force, w_force, ms_force);
    
    // Step forward in time with forward Euler
    hyperbolic_step(mesh, f, t, dt, ball_loc, water_tris);

    // Update node values with triangle-averaged values
    ball_loc = post_process(mesh, combined_forces, c, t, dt, water_nodes);

    // Update the viewer with new node positions
    viewer.add_nodes(mesh.node_begin(), mesh.node_end(), 
                     Color(water_nodes), NodePosition(), node_map);
    // viewer.add_triangles(mesh.triangle_begin(), mesh.triangle_end(), node_map);
    viewer.set_label(t);

    // find radius of cross sectional radius of ball submerged
    dh = ball_loc.z;
    if (dh > 2*radius)
      dh = 2 * radius;
    ball_loc.z = cross_radius(radius, dh);

    // These lines slow down the animation for small meshes.
    if (mesh.num_nodes() < 100)
      CS207::sleep(0.05);
  }
  return 0;
}
示例#7
0
int main(int argc, char* argv[])
{
  // Check arguments
  if (argc < 3) {
    std::cerr << "Usage: shallow_water NODES_FILE TRIS_FILE\n";
    exit(1);
  }

auto start = std::chrono::high_resolution_clock::now();

  MeshType mesh;
  // HW4B: Need node_type before this can be used!

  std::vector<typename MeshType::node_type> mesh_node;

  // Read all Points and add them to the Mesh
  std::ifstream nodes_file(argv[1]);
  Point p;
  while (CS207::getline_parsed(nodes_file, p)) {
    mesh_node.push_back(mesh.add_node(p));
  }

  // Read all mesh triangles and add them to the Mesh
  std::ifstream tris_file(argv[2]);
  std::array<int,3> t;
  while (CS207::getline_parsed(tris_file, t)) {
    // HW4B: Need to implement add_triangle before this can be used!
    mesh.add_triangle(mesh_node[t[0]], mesh_node[t[1]], mesh_node[t[2]]);
  }

  // Print out the stats
  std::cout << mesh.num_nodes() << " "
            << mesh.num_edges() << " "
            << mesh.num_triangles() << std::endl;

 
 //Start of nearest neighor.  Put all positions that you want inspected in a vector of type double
 std::vector<double> pos; 
 for (auto it = mesh.node_begin(); it != mesh.node_end(); ++it ) 	
	pos.push_back((*it).position().z);

  unsigned num_neighbors = 10; //num of neighors to return
  unsigned object_idx = 5; // do this if you want to examine the neighbors of a specific idx

  MeshType::NearestNeighbor a = mesh.calculateNearestNeighbors(num_neighbors ,pos);
  auto idx = mesh.getNeighbors(a,object_idx);
  auto dist = mesh.getNeighborDistances(a,object_idx);
  /*auto all_n = mesh.getAllNeighbors(a);
  auto all_d = mesh.getAllNeighborDistances(a);*/

  for (unsigned i = 0; i < idx.size(); ++i)
	std::cout << "Node " << object_idx << "'s " << i << " neighbor is: node " << idx[i] << " with distance of " << dist[i] << endl;

  /*//Uncomment to view results for all nodes
  for (unsigned j = 0; j < pos.size(); ++j){
     std::cout << endl;
     for (unsigned i = 0; i < num_neighbors; ++i)
	std::cout << "For node " << j << " neighbor " << i << " is index " << all_n[i+j*num_neighbors] << " and distance is " << all_d[i+j*num_neighbors] << endl;
  }*/


  // HW4B Initialization
  // Set the initial conditions
  int wave = 0, peddle=0, dam=1;
  if (wave){
	for ( auto it = mesh.node_begin(); it!= mesh.node_end(); ++it){
		auto x = (*it).position().x;
		auto y = (*it).position().y;
		double h = 1-0.75 * exp(-80 * ( (x-0.75)*(x-0.75) + y*y ));
		mesh.value((*it),QVar( h,0,0));
	}
  }
  else if (peddle){
	for ( auto it = mesh.node_begin(); it!= mesh.node_end(); ++it){
		auto x = (*it).position().x;
		auto y = (*it).position().y;
		double h = (x-0.75)*(x-0.75) + y*y -0.15*0.15 ;
		int H =0;
		if (h < 0)
			H = 1;
		mesh.value((*it), QVar(1+0.75*H,0,0));
	}
  }
  else if (dam){
	for ( auto it = mesh.node_begin(); it!= mesh.node_end(); ++it){
		auto x = (*it).position().x;
		int H =0;
		if (x < 0)
			H = 1;
		mesh.value((*it), QVar(1+0.75*H,0,0));
	}
  }
  
  
  // Perform any needed precomputation
// initialize triangle
  for (auto it = mesh.tri_begin(); it != mesh.tri_end(); ++it ) {
	(*it).value() = ((*it).node1().value() + (*it).node2().value() + (*it).node3().value())/3.0;
  }


  // Launch the SDLViewer
  CS207::SDLViewer viewer;
  viewer.launch();

  // HW4B: Need to define Mesh::node_type and node/edge iterator
  // before these can be used!
  
  auto node_map = viewer.empty_node_map(mesh);
  viewer.add_nodes(mesh.node_begin(), mesh.node_end(),
                   CS207::DefaultColor(), NodePosition(), node_map);
  viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);

  viewer.center_view();
  
  // HW4B: Timestep
  // CFL stability condition requires dt <= dx / max|velocity|
  // For the shallow water equations with u = v = 0 initial conditions
  //   we can compute the minimum edge length and maximum original water height
  //   to set the time-step
  // Compute the minimum edge length and maximum water height for computing dt
  auto min_length = *std::min_element(mesh.edge_begin(), mesh.edge_end(), EdgeComparator);
  
  auto max_h = *std::max_element(mesh.node_begin(), mesh.node_end(), HeightComparator);
  
  double dt = 0.25 * min_length.length() / (sqrt(grav * max_h.value().h));
  double t_start = 0;
  double t_end = 0.1;

  // Preconstruct a Flux functor
  EdgeFluxCalculator f;

  // Begin the time stepping
  for (double t = t_start; t < t_end; t += dt) {
    // Step forward in time with forward Euler
    hyperbolic_step(mesh, f, t, dt);

    // Update node values with triangle-averaged values
    post_process(mesh);

    // Update the viewer with new node positions
    // HW4B: Need to define node_iterators before these can be used!
    viewer.add_nodes(mesh.node_begin(), mesh.node_end(),
                     CS207::DefaultColor(), NodePosition(), node_map);
    viewer.set_label(t);
	
    // These lines slow down the animation for small meshes.
    // Feel free to remove them or tweak the constants.
    if (mesh.num_nodes() < 100)
      CS207::sleep(0.05);
  }
auto elapsed = std::chrono::high_resolution_clock::now() - start;
long long microseconds = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();

cout << microseconds << endl;
  
return 0;
}