예제 #1
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_EDGES>,
      typename MeshTraits<MeshType>::location_edge_const_iterator,
      typename MeshTraits<MeshType>::location_edge_const_iterator>
      internaledges( MeshType const& mesh, mpl::bool_<false> )
{
    return boost::make_tuple( mpl::size_t<MESH_EDGES>(),
                              mesh.beginInternalEdge(),
                              mesh.endInternalEdge() );
}
예제 #2
0
 MeshType* load(const xml::Node& desc, gcm::Body* body)
 {
     MeshType* mesh = new MeshType();
     mesh->setId(desc["id"]);
     mesh->setCalc(desc.getAttributeByName("calc", "false") == "true");
     mesh->setBody(body);
     loadMesh(desc, mesh);
     return mesh;
 }
예제 #3
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_FACES>,
      typename MeshTraits<MeshType>::face_const_iterator,
      typename MeshTraits<MeshType>::face_const_iterator>
      idedfaces( MeshType const& mesh, size_type id, mpl::bool_<false> )
{
    return boost::make_tuple( mpl::size_t<MESH_FACES>(),
                              mesh.beginFaceWithId( id ),
                              mesh.endFaceWithId( id ) );
}
예제 #4
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_POINTS>,
      typename MeshTraits<MeshType>::location_point_const_iterator,
      typename MeshTraits<MeshType>::location_point_const_iterator>
      internalpoints( MeshType const& mesh, mpl::bool_<false> )
{
    return boost::make_tuple( mpl::size_t<MESH_POINTS>(),
                              mesh.beginInternalPoint( ),
                              mesh.endInternalPoint() );
}
예제 #5
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_EDGES>,
      typename MeshTraits<MeshType>::location_edge_const_iterator,
      typename MeshTraits<MeshType>::location_edge_const_iterator>
      boundaryedges( MeshType const& mesh, mpl::bool_<false> )
{
    return boost::make_tuple( mpl::size_t<MESH_EDGES>(),
                              mesh.beginEdgeOnBoundary(),
                              mesh.endEdgeOnBoundary() );
}
예제 #6
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_ELEMENTS>,
      typename MeshTraits<MeshType>::element_const_iterator,
      typename MeshTraits<MeshType>::element_const_iterator>
      allelements( MeshType const& mesh, mpl::bool_<false> )
{
    return boost::make_tuple( mpl::size_t<MESH_ELEMENTS>(),
                              mesh.beginElement(),
                              mesh.endElement() );
}
예제 #7
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_POINTS>,
      typename MeshTraits<MeshType>::marker_point_const_iterator,
      typename MeshTraits<MeshType>::marker_point_const_iterator>
      markedpoints( MeshType const& mesh, size_type flag, mpl::bool_<false> )
{
    return boost::make_tuple( mpl::size_t<MESH_POINTS>(),
                              mesh.beginPointWithMarker( flag ),
                              mesh.endPointWithMarker( flag ) );
}
예제 #8
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_ELEMENTS>,
      typename MeshTraits<MeshType>::element_const_iterator,
      typename MeshTraits<MeshType>::element_const_iterator>
      elements( MeshType const& mesh, rank_type pid, mpl::bool_<false> )
{

    return boost::make_tuple( mpl::size_t<MESH_ELEMENTS>(),
                              mesh.beginElementWithProcessId( pid ),
                              mesh.endElementWithProcessId( pid ) );
}
예제 #9
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_FACES>,
      typename MeshTraits<MeshType>::marker3_face_const_iterator,
      typename MeshTraits<MeshType>::marker3_face_const_iterator>
      marked3faces( MeshType const& mesh, rank_type __pid, mpl::bool_<false> )
{
    typedef typename MeshTraits<MeshType>::marker3_face_const_iterator iterator;
    auto beg = mesh.beginFaceWithMarker3();
    auto end = mesh.endFaceWithMarker3();
    return boost::make_tuple( mpl::size_t<MESH_FACES>(),
                              beg, end );
}
예제 #10
0
 double initialize_node_values(MeshType& mesh) const {
     double max_height = 0;
     for (auto nit = mesh.node_begin(); nit != mesh.node_end(); ++nit) {
         unsigned H = 0;
         if ((*nit).position().x < 0) H = 1;
         (*nit).value() = QVar(1 + 0.75 * H * (pow(((*nit).position().x - 0.75), 2) + 
                   pow((*nit).position().y, 2) - 0.15 * 0.15), 0, 0);
         max_height = std::max(max_height, (*nit).value().h);
     }
     
     return max_height;
 }
예제 #11
0
    double initialize_node_values(MeshType& mesh) const {
        double max_height = 0;
        for (auto nit = mesh.node_begin(); nit != mesh.node_end(); ++nit) {
            (*nit).value() = QVar(1 - 0.75 * exp(
              -80*(pow((*nit).position().x - 0.75, 2) + pow((*nit).position().y, 2))
              ), 0, 0);

            max_height = std::max(max_height, (*nit).value().h);
        }

        return max_height;
    }
예제 #12
0
 std::pair<double, double> operator()(MeshType& mesh) const {
     double max_height = derived().initialize_node_values(mesh);
     
     double min_edge_length = (*mesh.edge_begin()).length();
     for (auto eit = mesh.edge_begin(); eit != mesh.edge_end(); ++eit) {
         min_edge_length = std::min(min_edge_length, (*eit).length());
     }
 
     for (auto tri_it = mesh.triangle_begin(); tri_it != mesh.triangle_end(); ++tri_it) {
         (*tri_it).value() = ((*tri_it).node(0).value() + (*tri_it).node(1).value() + (*tri_it).node(2).value()) / 3.0;
     }
     return std::make_pair(max_height, min_edge_length);
 }
예제 #13
0
 double initialize_node_values(MeshType& mesh) const {
     double max_height = 0;
     for (auto nit = mesh.node_begin(); nit != mesh.node_end(); ++nit) {
         if ((*nit).position().x < 0) {
             (*nit).value() = QVar(1.75, 0, 0);
         }
         else {
             (*nit).value() = QVar(1, 0, 0);
         }
         max_height = std::max(max_height, (*nit).value().h);
     }
     
     return max_height;
 }
예제 #14
0
void createPointNeighbors ( MeshType const& mesh, neighborList_Type& neighborList )
{
    neighborList.resize ( mesh.numGlobalPoints() );
    // generate point neighbors by watching edges
    // note: this can be based also on faces or volumes
    for ( UInt ie = 0; ie < mesh.numEdges(); ie++ )
    {
        ID id0 = mesh.edge ( ie ).point ( 0 ).id();
        ID id1 = mesh.edge ( ie ).point ( 1 ).id();

        ASSERT ( mesh.point ( id0 ).id() == id0 && mesh.point ( id1 ).id() == id1,
                 "the mesh has been reordered, the point must be found" );

        neighborList[ id0 ].insert ( id1 );
        neighborList[ id1 ].insert ( id0 );
    }
}
예제 #15
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_ELEMENTS>,
      typename MeshTraits<MeshType>::location_element_const_iterator,
      typename MeshTraits<MeshType>::location_element_const_iterator>
boundaryelements( MeshType const& mesh, uint16_type entity_min_dim, uint16_type entity_max_dim, rank_type pid, mpl::bool_<false> )
{
    typedef typename MeshTraits<MeshType>::location_element_const_iterator iterator;
    std::pair<iterator, iterator> p = mesh.boundaryElements( entity_min_dim, entity_max_dim, pid );
    return boost::make_tuple( mpl::size_t<MESH_ELEMENTS>(), p.first, p.second );
}
예제 #16
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_ELEMENTS>,
      typename MeshTraits<MeshType>::location_element_const_iterator,
      typename MeshTraits<MeshType>::location_element_const_iterator>
      internalelements( MeshType const& mesh, rank_type pid, mpl::bool_<false> )
{
    typedef typename MeshTraits<MeshType>::location_element_const_iterator iterator;
    std::pair<iterator, iterator> p = mesh.internalElements( pid );
    return boost::make_tuple( mpl::size_t<MESH_ELEMENTS>(), p.first, p.second );
}
예제 #17
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_FACES>,
      typename MeshTraits<MeshType>::pid_face_const_iterator,
      typename MeshTraits<MeshType>::pid_face_const_iterator>
      faces( MeshType const& mesh, rank_type __pid, mpl::bool_<false> )
{
    typedef typename MeshTraits<MeshType>::pid_face_const_iterator pid_face_const_iterator;
    pid_face_const_iterator it,en;
    boost::tie( it, en ) = mesh.facesWithProcessId( __pid );
    return boost::make_tuple( mpl::size_t<MESH_FACES>(), it, en );
}
예제 #18
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_FACES>,
      typename MeshTraits<MeshType>::location_face_const_iterator,
      typename MeshTraits<MeshType>::location_face_const_iterator>
      boundaryfaces( MeshType const& mesh, rank_type __pid, mpl::bool_<false>  )
{
    typedef typename MeshTraits<MeshType>::location_face_const_iterator iterator;
    std::pair<iterator, iterator> p = mesh.facesOnBoundary( __pid );
    return boost::make_tuple( mpl::size_t<MESH_FACES>(),
                              p.first, p.second );
}
예제 #19
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_ELEMENTS>,
      typename MeshTraits<MeshType>::marker3_element_const_iterator,
      typename MeshTraits<MeshType>::marker3_element_const_iterator>
      marked3elements( MeshType const& mesh, flag_type flag, rank_type pid, mpl::bool_<false> )
{
    typedef typename MeshTraits<MeshType>::marker3_element_const_iterator iterator;
    std::pair<iterator, iterator> p = mesh.elementsWithMarker3( flag, pid );
    return boost::make_tuple( mpl::size_t<MESH_ELEMENTS>(),
                              p.first, p.second );
}
예제 #20
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_EDGES>,
      typename MeshTraits<MeshType>::marker_edge_const_iterator,
      typename MeshTraits<MeshType>::marker_edge_const_iterator>
      markededges( MeshType const& mesh, flag_type __marker, rank_type __pid, mpl::bool_<false> )
{
    typedef typename MeshTraits<MeshType>::marker_edge_const_iterator iterator;
    std::pair<iterator, iterator> p = mesh.edgesWithMarker( __marker, __pid );
    return boost::make_tuple( mpl::size_t<MESH_EDGES>(),
                              p.first, p.second );
}
예제 #21
0
void createPointNeighbors ( MeshType& mesh )
{
    // TODO: ASSERT_COMPILE_TIME that MeshType::pointMarker == NeighborMarker
    // this guarantees that the pointNeighbors structure is available.

    // generate point neighbors by watching edges
    // note: this can be based also on faces or volumes
    for ( UInt ie = 0; ie < mesh.numEdges(); ie++ )
    {
        ID id0 = mesh.edge ( ie ).point ( 0 ).id();
        ID id1 = mesh.edge ( ie ).point ( 1 ).id();

        ASSERT ( mesh.point ( id0 ).id() == id0 , "the mesh has been reordered, the point must be found" );
        ASSERT ( mesh.point ( id1 ).id() == id1 , "the mesh has been reordered, the point must be found" );

        mesh.point ( id0 ).pointNeighbors().insert ( id1 );
        mesh.point ( id1 ).pointNeighbors().insert ( id0 );
    }
}
예제 #22
0
void test(const shared_ptr< DistanceOctree< MeshType > > & distanceOctree, const MeshType & mesh, const AABB & domainAABB, Vector3<uint_t> numBlocks)
{
   Vector3<real_t> blockSize(domainAABB.xSize() / real_c(numBlocks[0]),
      domainAABB.ySize() / real_c(numBlocks[1]),
      domainAABB.zSize() / real_c(numBlocks[2]));

   real_t maxError = blockSize.min() / real_t(10);

   SetupBlockForest setupBlockforest;
   setupBlockforest.addRootBlockExclusionFunction(F(distanceOctree, maxError));
   setupBlockforest.addWorkloadMemorySUIDAssignmentFunction(blockforest::uniformWorkloadAndMemoryAssignment);


   setupBlockforest.init(domainAABB, numBlocks[0], numBlocks[1], numBlocks[2], false, false, false);
   WALBERLA_LOG_DEVEL(setupBlockforest.toString());


   std::vector< Vector3<real_t> > vertexPositions;
   vertexPositions.reserve(mesh.n_vertices());
   for (auto vIt = mesh.vertices_begin(); vIt != mesh.vertices_end(); ++vIt)
   {
      vertexPositions.push_back(toWalberla(mesh.point(*vIt)));
   }

   std::vector< const blockforest::SetupBlock* > setupBlocks;
   setupBlockforest.getBlocks(setupBlocks);

   // Check wether all vertices are located in allocated blocks
   std::vector< Vector3<real_t> > uncoveredVertices(vertexPositions);

   for (auto bIt = setupBlocks.begin(); bIt != setupBlocks.end(); ++bIt)
   {
      const AABB & aabb = (*bIt)->getAABB();

      uncoveredVertices.erase(std::remove_if(uncoveredVertices.begin(), uncoveredVertices.end(), PointInAABB(aabb)), uncoveredVertices.end());
   }

   WALBERLA_CHECK(uncoveredVertices.empty(), "Not all vertices of the mesh are located in allocated blocks!");

   //setupBlockforest.assignAllBlocksToRootProcess();
   //setupBlockforest.writeVTKOutput( "setupblockforest" );
}
예제 #23
0
파일: filters.hpp 프로젝트: LANTZT/feelpp
boost::tuple<mpl::size_t<MESH_FACES>,
      typename MeshTraits<MeshType>::interprocess_face_const_iterator,
      typename MeshTraits<MeshType>::interprocess_face_const_iterator>
      interprocessfaces( MeshType const& mesh, rank_type neighbor_pid, mpl::bool_<false> )
{

    typedef typename MeshTraits<MeshType>::interprocess_face_const_iterator iterator;
    std::pair<iterator, iterator> p = mesh.interProcessFaces( neighbor_pid );
    return boost::make_tuple( mpl::size_t<MESH_FACES>(),
                              p.first, p.second );
}
예제 #24
0
coupledInfo<MeshType>::coupledInfo
(
    const MeshType& mesh,
    const bool isTwoDMesh,
    const bool isLocal,
    const bool isSend,
    const label patchIndex,
    const label mPatch,
    const label sPatch,
    const label mfzIndex,
    const label sfzIndex
)
:
    mesh_(mesh),
    builtMaps_(false),
    map_
    (
        IOobject
        (
            "coupleMap_"
          + Foam::name(mPatch)
          + "_To_"
          + Foam::name(sPatch)
          + word(isLocal ? "_Local" : "_Proc")
          + word(isSend ? "_Send" : "_Recv"),
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            true
        ),
        isTwoDMesh,
        isLocal,
        isSend,
        patchIndex,
        mPatch,
        sPatch
    ),
    masterFaceZone_(mfzIndex),
    slaveFaceZone_(sfzIndex)
{}
예제 #25
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;
}
예제 #26
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;
  }
예제 #27
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;
}
예제 #28
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;
}
Array<Mesh> SerialPartitionerBase::makeMeshParts(const Mesh& mesh, int np,
  Array<Sundance::Map<int, int> >& oldElemLIDToNewLIDMaps,
  Array<Sundance::Map<int, int> >& oldVertLIDToNewLIDMaps) const 
{
  int dim = mesh.spatialDim();

  Array<int> elemAssignments;
  Array<int> nodeAssignments;
  Array<int> nodeOwnerElems;
  Array<int> nodesPerProc;
  
  getAssignments(mesh, np, elemAssignments);

  getNodeAssignments(np, elemAssignments, nodeAssignments, nodeOwnerElems,
    nodesPerProc);

  Array<Array<int> > offProcNodes(np);
  Array<Array<int> > offProcElems(np);

  Array<Set<int> > offProcNodeSet(np);
  Array<Set<int> > offProcElemSet(np);

  Array<Array<int> > procNodes(np);
  Array<Array<int> > procElems(np);

  for (int p=0; p<np; p++)
  {
    getOffProcData(p, elemAssignments, nodeAssignments, 
      offProcNodeSet[p], offProcElemSet[p]);
    offProcNodes[p] = offProcNodeSet[p].elements();
    offProcElems[p] = offProcElemSet[p].elements();
    procElems[p].reserve(elemAssignments.size()/np);
    procNodes[p].reserve(nodeAssignments.size()/np);
  }

  Array<int> remappedElems;
  Array<int> remappedNodes;

  remapEntities(elemAssignments, np, remappedElems);
  remapEntities(nodeAssignments, np, remappedNodes);

  for (int e=0; e<elemAssignments.size(); e++)
  {
    procElems[elemAssignments[e]].append(e);
  }

  for (int n=0; n<nodeAssignments.size(); n++)
  {
    procNodes[nodeAssignments[n]].append(n);
  }

  /* Now we make NP submeshes */
  Array<Mesh> rtn(np);
  oldVertLIDToNewLIDMaps.resize(np);
  oldElemLIDToNewLIDMaps.resize(np);
  for (int p=0; p<np; p++)
  {
    Sundance::Map<int, int>& oldVertLIDToNewLIDMap 
      = oldVertLIDToNewLIDMaps[p];
    Sundance::Map<int, int>& oldElemLIDToNewLIDMap 
      = oldElemLIDToNewLIDMaps[p];
    MeshType type = new BasicSimplicialMeshType();
    rtn[p] = type.createEmptyMesh(mesh.spatialDim(), MPIComm::world());

    Set<int> unusedVertGID;

    /* add the on-processor nodes */
    for (int n=0; n<procNodes[p].size(); n++)
    {
      int oldLID = procNodes[p][n];
      int newGID = remappedNodes[oldLID];
      unusedVertGID.put(newGID);
      int newLID = rtn[p].addVertex(newGID, mesh.nodePosition(oldLID), p, 0);
      oldVertLIDToNewLIDMap.put(oldLID, newLID);
    }

    /* add the off-processor nodes */
    for (int n=0; n<offProcNodes[p].size(); n++)
    {
      int oldLID = offProcNodes[p][n];
      int nodeOwnerProc = nodeAssignments[oldLID];
      int newGID = remappedNodes[oldLID];
      unusedVertGID.put(newGID);
      int newLID = rtn[p].addVertex(newGID, mesh.nodePosition(oldLID), nodeOwnerProc, 0);
      oldVertLIDToNewLIDMap.put(oldLID, newLID);
    }
    
    /* add the on-processor elements */
    for (int e=0; e<procElems[p].size(); e++)
    {
      int oldLID = procElems[p][e];
      int newGID = remappedElems[oldLID];
      Array<int> vertGIDs;
      Array<int> orientations;
      mesh.getFacetArray(dim, oldLID, 0, vertGIDs, orientations);
      for (int v=0; v<vertGIDs.size(); v++)
      {
        vertGIDs[v] = remappedNodes[vertGIDs[v]];
        if (unusedVertGID.contains(vertGIDs[v])) unusedVertGID.erase(newGID);
      }
      int newLID = rtn[p].addElement(newGID, vertGIDs, p, 1);
      oldElemLIDToNewLIDMap.put(oldLID, newLID);
    }
    
    /* add the off-processor elements */
    for (int e=0; e<offProcElems[p].size(); e++)
    {
      int oldLID = offProcElems[p][e];
      int newGID = remappedElems[oldLID];
      int elemOwnerProc = elemAssignments[oldLID];
      Array<int> vertGIDs;
      Array<int> orientations;
      mesh.getFacetArray(dim, oldLID, 0, vertGIDs, orientations);
      for (int v=0; v<vertGIDs.size(); v++)
      {
        vertGIDs[v] = remappedNodes[vertGIDs[v]];
        if (unusedVertGID.contains(vertGIDs[v])) unusedVertGID.erase(newGID);
      }
      int newLID = rtn[p].addElement(newGID, vertGIDs, elemOwnerProc, 1);
      oldElemLIDToNewLIDMap.put(oldLID, newLID);

//      TEST_FOR_EXCEPTION(unusedVertGID.size() != 0, InternalError,
//        "unused vertices=" << unusedVertGID);
    }

    /* Now, propagate the labels of any intermediate-dimension cells
     * to the submesh */
    for (int d=1; d<dim; d++)
    {
      Set<int> labels = mesh.getAllLabelsForDimension(d);
      for (Set<int>::const_iterator i=labels.begin(); i!=labels.end(); i++)
      {
        Array<int> labeledCells;
        int label = *i;
        if (label == 0) continue;
        mesh.getLIDsForLabel(d, label, labeledCells);
        for (int c=0; c<labeledCells.size(); c++)
        {
          int lid = labeledCells[c];
          Array<int> cofacets;
          mesh.getCofacets(d, lid, dim, cofacets);
          for (int n=0; n<cofacets.size(); n++)
          {
            int cofLID = cofacets[n];
            if (elemAssignments[cofLID]==p 
              || offProcElemSet[p].contains(cofLID))
            {
              /* at this point we need to find the facet index of the side
               * relative to the new element. */
              
              /* find vertices of old cell */
              Array<int> oldVerts;
              Array<int> newVerts;
              Array<int> orientation;
              mesh.getFacetArray(d, lid, 0, oldVerts, orientation);
              for (int v=0; v<oldVerts.size(); v++)
              {
                newVerts.append(remappedNodes[oldVerts[v]]);
              }
              /* Put the vertices in a set. This will let us compare to the
               * vertex sets in the new submesh. */
              Set<int> newVertSet = arrayToSet(newVerts);
              
              /* Find the cofacet in the new submesh */
              int newElemLID = oldElemLIDToNewLIDMap.get(cofLID);

              /* Get the d-facets of the element in the new submesh */
              Array<int> submeshFacets;
              rtn[p].getFacetArray(dim, newElemLID, d, 
                submeshFacets, orientation);
              int facetIndex = -1;
              for (int df=0; df<submeshFacets.size(); df++)
              {
                /* Get the vertices of this d-facet */
                int facetLID = submeshFacets[df];
                Array<int> verts;
                rtn[p].getFacetArray(d, facetLID, 0, verts, orientation);
                Array<int> vertGID(verts.size());
                for (int v=0; v<verts.size(); v++)
                {
                  vertGID[v] = rtn[p].mapLIDToGID(0, verts[v]);
                }
                Set<int> subVertSet = arrayToSet(vertGID);
                if (subVertSet==newVertSet)
                {
                  facetIndex = df;
                  break;
                }
              }
              TEST_FOR_EXCEPTION(facetIndex==-1, InternalError,
                "couldn't match new " << d << "-cell in submesh to old " << d
                << "cell. This should never happen");

              /* OK, now we have the d-cell's facet index relative to one
               * of its cofacets existing on the new submesh. We now
               * find the LID of the d-cell so we can set its label */
              int o;  // dummy orientation variable; not needed here
              int newFacetLID = rtn[p].facetLID(dim, newElemLID, d, 
                facetIndex, o);
              /* Set the label, finally! */
              rtn[p].setLabel(d, newFacetLID, label);
              break; /* no need to continue the loop over cofacets once 
                      * we've set the label */
            }
            else
            {
            }
          }
        }
      }
    }
  }

  return rtn;
}
예제 #30
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;
}