Пример #1
0
double hyperbolic_step(MESH& m, FLUX& f, double t, double dt, Point ball_loc, int water_tris) {
  for (auto tri_it = m.triangle_begin(); (*tri_it).index() != water_tris; ++tri_it) {
    QVar sum = QVar(0,0,0);

    /* Defines the force of the floating objects by checking its submerged 
    *  cross section of the ball intersects with the centers of adjacent triangles 
    */
    floatObj obj = floatObj();
    if (norm((*tri_it).center()-Point(ball_loc.x, ball_loc.y, 0)) < ball_loc.z)
      obj = floatObj(total_mass*grav, M_PI*ball_loc.z*ball_loc.z, density);

    Point norm_vec = (*tri_it).normal((*tri_it).node1(), (*tri_it).node2());
    // Calcuate flux using adjacent triangle's Q
    if ((*tri_it).adj_triangle((*tri_it).node1(), (*tri_it).node2()).is_valid())
      sum += f(norm_vec.x, norm_vec.y, dt, (*tri_it).value().q_bar, 
      		(*tri_it).adj_triangle((*tri_it).node1(), (*tri_it).node2()).value().q_bar, obj);
    // Boundary conditions
    else
      sum += f(norm_vec.x, norm_vec.y, dt, (*tri_it).value().q_bar, 
      		QVar((*tri_it).value().q_bar.h, 0, 0), obj);

    norm_vec = (*tri_it).normal((*tri_it).node2(), (*tri_it).node3());
    // Calcuate flux using adjacent triangle's Q
    if ((*tri_it).adj_triangle((*tri_it).node2(), (*tri_it).node3()).is_valid()) 
      sum += f(norm_vec.x, norm_vec.y, dt, (*tri_it).value().q_bar, 
      		(*tri_it).adj_triangle((*tri_it).node2(), (*tri_it).node3()).value().q_bar, obj); 
    // Boundary conditions
    else 
      sum += f(norm_vec.x, norm_vec.y, dt, (*tri_it).value().q_bar, 
      		QVar((*tri_it).value().q_bar.h, 0, 0), obj);

    norm_vec = (*tri_it).normal((*tri_it).node3(), (*tri_it).node1());
    // Calcuate flux using adjacent triangle's Q
    if ((*tri_it).adj_triangle((*tri_it).node3(), (*tri_it).node1()).is_valid())
      sum += f(norm_vec.x, norm_vec.y, dt, (*tri_it).value().q_bar, 
      		(*tri_it).adj_triangle((*tri_it).node3(), (*tri_it).node1()).value().q_bar, obj); 
    // Boundary conditions
    else
      sum += f(norm_vec.x, norm_vec.y, dt, (*tri_it).value().q_bar, 
      		QVar((*tri_it).value().q_bar.h, 0, 0), obj);

    (*tri_it).value().q_bar2 = ((*tri_it).value().S * dt/(*tri_it).area()) + (*tri_it).value().q_bar - 
                               (sum * dt/(*tri_it).area());
	}

  /* In order to use original (as opposed to update) q_bar values in the equation above, we have to update
   * q_bar values for all triangles after the q_bar values have been calculated.
   * Updates the Source term
   */
  for (auto tri_it = m.triangle_begin(); (*tri_it).index() != water_tris; ++tri_it){
    (*tri_it).value().S = (*tri_it).value().S/(*tri_it).value().q_bar.h*(*tri_it).value().q_bar2.h;
    (*tri_it).value().q_bar = (*tri_it).value().q_bar2;
  }

  return t + dt;
}
Пример #2
0
double hyperbolic_step(MESH& m, FLUX& f, double t, double dt) {
  // HW4B: YOUR CODE HERE
  // Step the finite volume model in time by dt.

  // Pseudocode:
  // Compute all fluxes. (before updating any triangle Q_bars)
  // For each triangle, update Q_bar using the fluxes as in Equation 8.
  //  NOTE: Much like symp_euler_step, this may require TWO for-loops

  /* 1. Initialize a vector temp_Q of size @a m.num_triangles() for storing all temp Q_bar values
   * 2. Use a TriangleIterator to iterate through all the triangles, for each tri_it:
   *      a. Compute the sum of fluxes sum_fluxes
   *      b. temp_Q[(*it).index()] = sum_fluxes
   * 3. Use indices of triangles to do another for loop, for each triangle(i):
   *      a. triangle_i.value().Q_bar = temp_Q[i]
   */
  std::vector<QVar> temp_fluxes(m.num_triangles(), QVar());
  for (auto tri_it = m.triangle_begin(); tri_it != m.triangle_end(); ++tri_it) {
    auto qk = (*tri_it).value();
    
    QVar F_k(0, 0, 0);
    for (size_type i = 0; i < 3; ++i) {
      auto edge = (*tri_it).edge(i);
      QVar qm(0, 0, 0);
      if (m.adj_triangle1_index(edge) == -1 || m.adj_triangle2_index(edge) == -1) {
          //set_boundary_conditions
        qm = QVar(qk.h, 0, 0);
      } else {
        size_type adj_tri_idx = m.adj_triangle1_index(edge) == (*tri_it).index() ?
            m.adj_triangle2_index(edge) : m.adj_triangle1_index(edge);

        auto adj_triangle = m.triangle(adj_tri_idx);
        qm = adj_triangle.value(); 
      }
      auto norm_ke = m.out_norm((*tri_it), edge); 
      F_k = F_k + f(norm_ke.x, norm_ke.y, dt, qk, qm);
    } 
    // print_triangle(m, (*tri_it), f, t, dt);
    temp_fluxes[(*tri_it).index()] = qk - F_k * (dt / (*tri_it).area());
  }
  
  for (auto tri_it = m.triangle_begin(); tri_it != m.triangle_end(); ++tri_it) {
    (*tri_it).value() = temp_fluxes[(*tri_it).index()];
  }
  
  return t + dt;
}
Пример #3
0
double get_volume(MESH& m) {
  double volume = 0.0;
  for(auto it = m.triangle_begin(); it != m.triangle_end(); ++it){
    auto tri = (*it);
    Point normal = get_normal_surface(tri);
    double area = tri.area();
    volume += normal.z * area * (tri.node(0).position().z + tri.node(1).position().z + tri.node(2).position().z) / 3.0;
  }
  return volume;
}
Пример #4
0
double hyperbolic_step(MESH& m, FLUX& f, double t, double dt) {
  // HW4B: YOUR CODE HERE
  // Step the finite volume model in time by dt.

  // Pseudocode:
  // Compute all fluxes. (before updating any triangle Q_bars)
  // For each triangle, update Q_bar using the fluxes as in Equation 8.
  //  NOTE: Much like symp_euler_step, this may require TWO for-loops
  
  // Implement Equation 7 from your pseudocode here.

  for(auto i = m.edge_begin(); i != m.edge_end(); ++i){
    if ((*i).triangle1().index() != (unsigned) -1 && (*i).triangle2().index() != (unsigned) -1 ){
      MeshType::Triangle trik = (*i).triangle1();
      MeshType::Triangle trim = (*i).triangle2();
      unsigned int edge_k = 0;
      unsigned int edge_m = 0;
      //which edge (*i) is in trik and trim
      while(trik.node(edge_k).index()== (*i).node1().index() 
        || trik.node(edge_k).index()== (*i).node2().index() )
        ++edge_k;
      while(trim.node(edge_m).index()== (*i).node1().index() 
        || trim.node(edge_m).index()== (*i).node2().index() )
        ++edge_m;
      QVar flux = f(trik.normal(edge_k).x, trik.normal(edge_k).y, dt, trik.value().Q, trim.value().Q);
      trik.value().F[edge_k] = flux;
      trim.value().F[edge_m] = -flux;
    }
    else{
      MeshType::Triangle trik;
      if ((*i).triangle1().index() != (unsigned) -1)
        trik = (*i).triangle1();
      else
        trik = (*i).triangle2();
      unsigned int edge_k = 0;
      while(trik.node(edge_k).index()== (*i).node1().index() 
        || trik.node(edge_k).index()== (*i).node2().index() )
        ++edge_k;
      QVar flux = f(trik.normal(edge_k).x, trik.normal(edge_k).y, dt, trik.value().Q, QVar(trik.value().Q.h, 0, 0));
      trik.value().F[edge_k] = flux;
    }
  }

  for(auto i = m.triangle_begin(); i != m.triangle_end(); ++i){
    QVar sum = QVar(0, 0, 0);
    for (int j = 0; j < 3; ++j){
      sum += (*i).value().F[j];
    }
    (*i).value().Q = (*i).value().Q-dt/(*i).area()*sum;
  }
  
  return t + dt;
};
Пример #5
0
void post_process(MESH& m) {
  // HW4B: Post-processing step
  // Translate the triangle-averaged values to node-averaged values
  // Implement Equation 9 from your pseudocode here
  for (auto it = m.node_begin(); it != m.node_end(); ++it){
    double sumarea=0;
    QVar sumQ = QVar(0, 0, 0);
    for(auto j = m.triangle_begin(*it); j != m.triangle_end(*it); ++j){
      sumarea += (*j).area();
      sumQ += (*j).value().Q * (*j).area();
    }
    (*it).value().Q = sumQ/sumarea;
  }
}