void test_element_get_attached_vertex_indices()
  {
    // Find the index of the triangle
    Mesquite::EntityTopology topo=Mesquite::MIXED;
    int tri_index = -1;
    while (topo != Mesquite::TRIANGLE) {
      ++tri_index;
      CPPUNIT_ASSERT((unsigned)tri_index < mElements.size());
      Mesquite::Mesh::ElementHandle handle = mElements[tri_index];
      mMesh->elements_get_topologies(&handle, &topo, 1, mErr);
      CPPUNIT_ASSERT(!mErr);
    }

    // creates list with correct vertices coordinates for the triangle
    std::vector<Mesquite::Vector3D> correct_coords;
    correct_coords.push_back(Mesquite::Vector3D(1.,0.,0.));
    correct_coords.push_back(Mesquite::Vector3D(0.,1.732050807,0.));
    correct_coords.push_back(Mesquite::Vector3D(-1.,0.,0.));

    // Creates same list from the mesh implementation
    std::vector<Mesquite::MsqVertex> tri_coords(3);
    mMesh->vertices_get_coordinates(&mConnectivity[mOffsets[tri_index]],
                                    &tri_coords[0], 3, mErr );
    CPPUNIT_ASSERT(!mErr);

    // Makes sure both list contain the same elements (not necessarily in the same order).
    std::vector<Mesquite::Vector3D>::iterator correct_iter;
    std::vector<Mesquite::MsqVertex>::iterator tri_iter;
    for (tri_iter = tri_coords.begin(); tri_iter != tri_coords.end(); ++tri_iter)
    {
      for (correct_iter = correct_coords.begin(); 
           correct_iter != correct_coords.end(); 
           ++correct_iter)
      {
        if (Mesquite::Vector3D::distance_between(*tri_iter, *correct_iter) < 10e-4)   
          break;
      }
      
      // check if a match was found
      CPPUNIT_ASSERT( correct_iter != correct_coords.end() );
      
      // remove match from list
      correct_coords.erase( correct_iter );
    }
    CPPUNIT_ASSERT(correct_coords.empty());
  }
 void test_elements_get_topology()
 {
   const size_t nbElem = mElements.size();
   int nb_quads=0;
   int nb_tri=0;
   Mesquite::EntityTopology* topos = new Mesquite::EntityTopology[nbElem];
   mMesh->elements_get_topologies(&mElements[0], topos, nbElem, mErr);
   CPPUNIT_ASSERT(!mErr);
   for (size_t i=0; i<nbElem; ++i) {
     switch (topos[i]) {
     case Mesquite::TRIANGLE:
       ++nb_tri;
       break;
     case Mesquite::QUADRILATERAL:
       ++nb_quads;
       break;
     default:
       CPPUNIT_FAIL("Topology should be quad or Hex only.");
     }
   }
   CPPUNIT_ASSERT_EQUAL(1,nb_tri);
   CPPUNIT_ASSERT_EQUAL(3,nb_quads);
   delete []topos;
 }
Beispiel #3
0
int main( int argc, char* argv[] )
{
  unsigned i;
  const char* input_file = MESH_FILES_DIR "3D/VTK/mixed-hex-pyr-tet.vtk";
  if (argc == 2)
    input_file = argv[1];
  else if (argc != 1)
  {
    std::cerr << "Invalid arguments.\n";
    return 2;
  }
  
  
  Mesquite::MsqPrintError err(cout);
  IdealWeightMeanRatio m1;
  IdealWeightInverseMeanRatio m2(err);
  ConditionNumberQualityMetric m3;
  QualityMetric* metrics[] = { &m1, &m2, &m3, 0 };

    // Read Mesh
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(MESH_FILES_DIR "3D/VTK/12-pyramid-unit-sphere.vtk", err);
  CPPUNIT_ASSERT(!err);
  Mesquite::MeshImpl ideal_mesh;
  ideal_mesh.read_vtk(MESH_FILES_DIR "3D/VTK/12-pyramid-unit-sphere.vtk", err);
  CPPUNIT_ASSERT(!err);

    // Check that the mesh read correctly, and contains what is
    // expected later.

    // Get mesh data
    // Expecting file to contain 12 pyramid elements constructed
    // from 15 vertices.
  std::vector<Mesh::VertexHandle> vert_array;
  std::vector<Mesh::ElementHandle> elem_array;
  std::vector<size_t> conn_offsets;
  mesh.get_all_elements( elem_array, err ); 
  CPPUNIT_ASSERT(!err);
  CPPUNIT_ASSERT( elem_array.size() == 12 );
  mesh.elements_get_attached_vertices( &elem_array[0],
                                        elem_array.size(),
                                        vert_array,
                                        conn_offsets,
                                        err );
  CPPUNIT_ASSERT(!err);
  CPPUNIT_ASSERT(vert_array.size() == 60);
  CPPUNIT_ASSERT(conn_offsets.size() == 13);
  EntityTopology type_array[12];
  mesh.elements_get_topologies( &elem_array[0], type_array, 12, err );
  CPPUNIT_ASSERT(!err);
  
    // Verify element types and number of vertices
  for (i = 0; i < 12; ++i)
  {
    CPPUNIT_ASSERT( type_array[i] == PYRAMID );
    CPPUNIT_ASSERT( conn_offsets[i] == 5*i );
  }
  
    // All pyramids should share a common apex, at the
    // center of the sphere
  Mesh::VertexHandle apex_handle = vert_array[4];
  for (i = 1; i < 12; ++i)
  {
    CPPUNIT_ASSERT( vert_array[5*i+4] == apex_handle );
  }
  
    // Verify that apex is at origin and all other vertices are
    // on unit sphere
  MsqVertex vertices[60];
  mesh.vertices_get_coordinates( &vert_array[0], vertices, 60, err );
  CPPUNIT_ASSERT(!err);
  for (i = 0; i < 60; ++i)
  {
    if (vert_array[i] == apex_handle)
      CPPUNIT_ASSERT( vertices[i].within_tolerance_box( Vector3D(0,0,0), 1e-6 ) );
    else
      CPPUNIT_ASSERT( fabs(1.0 - vertices[i].length()) < 1e-6 );
  }
  
    // Try smoothing w/out moving the free vertex and verify that
    // the smoother didn't move the vertex
  Vector3D position(0,0,0);
  for (i = 0; metrics[i] != NULL; ++i)
    CPPUNIT_ASSERT( !smooth_mesh( &mesh, &ideal_mesh, apex_handle, position, metrics[i] ) );
  
    // Now try moving the vertex and see if the smoother moves it back
    // to the origin
  position.set( 0.1, 0.1, 0.1 );
  for (i = 0; metrics[i] != NULL; ++i)
    CPPUNIT_ASSERT( !smooth_mesh( &mesh, &ideal_mesh, apex_handle, position, metrics[i] ) );
  
    // Now try moving the vertex further and see if the smoother moves it back
    // to the origin
  position.set( 0.3, 0.3, 0.3 );
  for (i = 0; metrics[i] != NULL; ++i)
    CPPUNIT_ASSERT( !smooth_mesh( &mesh, &ideal_mesh, apex_handle, position, metrics[i] ) );

    // Now try smoothing a real mixed mesh
  CPPUNIT_ASSERT( !smooth_mixed_mesh( input_file ) );

  return 0;
}