Ejemplo n.º 1
0
  void VtkTest::check_field_attrib( const char* temp_file_name )
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
   
    std::string name;
    Mesh::TagType type;
    unsigned tagsize;


    void* th = mesh.tag_get( "test_field elem_vects", err );
    CPPUNIT_ASSERT( !err );

    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::DOUBLE && tagsize == 3 );
    
    double elem_data[24];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_data, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( Vector3D( elem_data+3*i ) == Vector3D( i+1, i+1, i+1 ) );
   
    
    th = mesh.tag_get( "test_field elem_ids", err );
    CPPUNIT_ASSERT( !err );

    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 );
    
    int elem_ids[8];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_ids, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( elem_ids[i] == i+1 );
   
    
    th = mesh.tag_get( "field1", err );
    CPPUNIT_ASSERT( !err );

    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 );
    
    int values[8];
    mesh.tag_get_element_data( th, 8, arrptr(elems), values, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( values[i] == 8-i );
  }
Ejemplo n.º 2
0
  void test_vertex_byte()
  {
    size_t nbVert = mVertices.size();
    size_t i;
	unsigned char* bytes = new unsigned char[nbVert];
    mMesh->vertices_get_byte(arrptr(mVertices), bytes, nbVert, mErr); 
    CPPUNIT_ASSERT(!mErr);

    // Asserts all vertex bytes are initialised to 0. 
    for (i=0; i<nbVert; ++i)
      CPPUNIT_ASSERT(bytes[i] == 0);

    // Test various vertex byte read / write routines.
    bytes[3] |= 4;
    mMesh->vertices_set_byte(arrptr(mVertices), bytes, nbVert, mErr); 
    CPPUNIT_ASSERT(!mErr);
    mMesh->vertex_set_byte(mVertices[5], 8, mErr); 
    CPPUNIT_ASSERT(!mErr);
    unsigned char byte;
    mMesh->vertex_get_byte(mVertices[3], &byte, mErr);
    CPPUNIT_ASSERT(!mErr);
    CPPUNIT_ASSERT(byte == 4);
    mMesh->vertices_get_byte(arrptr(mVertices), bytes, nbVert, mErr);
    CPPUNIT_ASSERT(!mErr);
    for (i=0; i<nbVert; ++i) {
      if (i==3)
        CPPUNIT_ASSERT(bytes[i] == 4);
      else if (i==5)
        CPPUNIT_ASSERT(bytes[i] == 8);
      else
        CPPUNIT_ASSERT(bytes[i] == 0);
    }

    delete [] bytes;
  }
Ejemplo n.º 3
0
    // Test reading Vtk vector attribute
  void VtkTest::test_read_vector_attrib()
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    FILE* file = fopen( temp_file_name, "w+" );
    fputs( structured_3d_points_data, file );
    fputs( simple_vector_attrib, file );
    fclose( file );
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
   
    void* th = mesh.tag_get( "hexvect", err );
    CPPUNIT_ASSERT( !err );

    std::string name;
    Mesh::TagType type;
    unsigned tagsize;
    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::DOUBLE && tagsize == 3 );
    
    double elem_data[24];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_data, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( Vector3D( elem_data+3*i ) == Vector3D( i+1, i+1, i+1 ) );
  }
Ejemplo n.º 4
0
    // Test reading Vtk simple (one-component) scalar attribute
  void VtkTest::test_read_simple_scalar_attrib()
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
   
    FILE* file = fopen( temp_file_name, "w+" );
    fputs( structured_3d_points_data, file );
    fputs( simple_scalar_attrib, file );
    fclose( file );
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
   
    void* th = mesh.tag_get( "global_id", err );
    CPPUNIT_ASSERT( !err );

    std::string name;
    Mesh::TagType type;
    unsigned tagsize;
    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 );
    
    int elem_data[8];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_data, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( elem_data[i] == (1+i) );
  }
Ejemplo n.º 5
0
   /* Automatically called by CppUnit before each test function. */
  void setUp()
  {
      // Read a VTK file -- 1 triangle flanked by 1 quad on each side (1 tri + 3 quads)
    mMesh = new Mesquite::MeshImpl;
    mMesh->read_vtk(MESH_FILES_DIR "2D/vtk/mixed/untangled/hybrid_3quad_1tri.vtk", mErr);
    CPPUNIT_ASSERT(!mErr);

      // Get mesh data
    mMesh->get_all_elements( mElements, mErr );
    CPPUNIT_ASSERT(!mErr);
    mMesh->elements_get_attached_vertices( arrptr(mElements),
                                           mElements.size(),
                                           mConnectivity,
                                           mOffsets,
                                           mErr );
    CPPUNIT_ASSERT(!mErr);
    
      // Construct list of vertices w/out duplicates from
      // connectivity list.
    std::vector<Mesquite::Mesh::VertexHandle>::iterator new_end;
    mVertices = mConnectivity;
    std::sort( mVertices.begin(), mVertices.end() );
    new_end = std::unique( mVertices.begin(), mVertices.end() );
    mVertices.resize( new_end - mVertices.begin() );
  }
Ejemplo n.º 6
0
  void test_vertices()
  {
    size_t nbVert = mVertices.size();
    CPPUNIT_ASSERT_EQUAL(9,(int)nbVert);

    Mesquite::MsqVertex correct_coords[9], coords[9];
    correct_coords[0].set(1,0,0);
    correct_coords[1].set(0,1.732,0);
    correct_coords[2].set(-1,0,0);
    correct_coords[3].set(-1,-2,0);
    correct_coords[4].set(1,-2,0);
    correct_coords[5].set(2.732,1,0);
    correct_coords[6].set(1.732,2.732,0);
    correct_coords[7].set(-1.732,2.732,0);
    correct_coords[8].set(-2.732,1,0);

    mMesh->vertices_get_coordinates(arrptr(mVertices), coords, nbVert, mErr);
    CPPUNIT_ASSERT(!mErr);
    for (size_t i=0; i<nbVert; ++i) {
      for (int j=0; j<3; ++j)
        CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[i][j], correct_coords[i][j], .01);
    }

    coords[3].set(2.,3.,4.);
    mMesh->vertex_set_coordinates(mVertices[3], coords[3], mErr);
    CPPUNIT_ASSERT(!mErr);
    Mesquite::MsqVertex coords_2;
    mMesh->vertices_get_coordinates(&mVertices[3], &coords_2, 1, mErr);
    CPPUNIT_ASSERT(!mErr);
    for (int j=0; j<3; ++j)
      CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[3][j], coords_2[j], 1e-6);
  }
Ejemplo n.º 7
0
    // Test reading MeshImpl boundary-vertex bit
    // from Vtk scalar attribute.
  void VtkTest::test_read_fixed_attrib()
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    FILE* file = fopen( temp_file_name, "w+" );
    fputs( structured_3d_points_data, file );
    fputs( fixed_vertex_attrib, file );
    fclose( file );
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);

    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
    
    std::vector<Mesh::VertexHandle> verts;
    std::vector<size_t> offsets;
    mesh.elements_get_attached_vertices( arrptr(elems), elems.size(), verts, offsets, err );
    ASSERT_NO_ERROR(err);
    
    // get unique list of vertices
    std::vector<Mesh::VertexHandle>::iterator new_end;
    std::sort( verts.begin(), verts.end() );
    new_end = std::unique( verts.begin(), verts.end() );
    verts.resize( new_end - verts.begin() );
    CPPUNIT_ASSERT_EQUAL( verts.size(), (size_t)27 );

    // get fixed flag
    std::vector<bool> fixed;
    mesh.vertices_get_fixed_flag( arrptr(verts), fixed, verts.size(), err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL( verts.size(), fixed.size() );
    
    for (int i = 0; i < 27; ++i)
    {
      bool should_be_fixed = (i != 13);
      CPPUNIT_ASSERT_EQUAL( should_be_fixed, (bool)fixed[i] );
    }
  }
Ejemplo n.º 8
0
  void test_vertex_get_attached_elements()
  {
	  size_t i;
    const size_t nbVert = mVertices.size();

    std::vector<Mesquite::Mesh::ElementHandle> elements;
    std::vector<size_t> offsets;
    mMesh->vertices_get_attached_elements( arrptr(mVertices),
                                           mVertices.size(),
                                           elements,
                                           offsets,
                                           mErr );
    CPPUNIT_ASSERT(!mErr);
    CPPUNIT_ASSERT_EQUAL(offsets.size(), mVertices.size() + 1);

    // checks we have 6 vertices contained in 1 element only
    // and 3 vertices contained in 3 elements. 
    int n1=0;
    int n3=0;
    for (i = 1; i <= mVertices.size(); ++i)
    {
      const size_t nev = offsets[i] - offsets[i-1];
      if (nev==1)
        ++n1;
      else if (nev==3)
        ++n3;
      else // failure. 
        CPPUNIT_ASSERT(false);
    }
    CPPUNIT_ASSERT(n1==6);
    CPPUNIT_ASSERT(n3==3);

    // gets the index of a vertex in a corner
    int one_corner_vertex_index=0;
    for (i = 0; i < nbVert; ++i)
    {
      const size_t nev = offsets[i+1] - offsets[i];
      if (1 == nev)
        break;
    }
    CPPUNIT_ASSERT( i < nbVert );
    one_corner_vertex_index = i;

    // retrieve the attached element.
    // This is a poor test.  We allow an element handle of zero,
    // and just testing that the function returned something isn't
    // that useful. - J.K.
    //Mesquite::Mesh::ElementHandle elem=0;
    //mMesh->vertex_get_attached_elements(mVertices[one_corner_vertex_index], &elem, 1, mErr);
    //CPPUNIT_ASSERT(!mErr);
    //CPPUNIT_ASSERT(elem!=0);

  }
Ejemplo n.º 9
0
 void test_vertex_is_fixed()
 {
   size_t nbVert = mVertices.size();
   bool correct_fixed[9] = {false, false, false, true, true, true, true, true, true};
   std::vector<bool> fixed;
   mMesh->vertices_get_fixed_flag( arrptr(mVertices), fixed, 9, mErr );
   CPPUNIT_ASSERT(!mErr);
   CPPUNIT_ASSERT_EQUAL( (size_t)8, fixed.size() );
   for (size_t i=0; i<nbVert; ++i) {
     CPPUNIT_ASSERT_EQUAL(correct_fixed[i], (bool)fixed[i]);
   }
 }
Ejemplo n.º 10
0
  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]],
                                    arrptr(tri_coords), 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());
  }
Ejemplo n.º 11
0
   // Check if the 2x2 brick of structured mesh
   // read from file is as expected.
 void VtkTest::check_4quad_structured( Mesh& mesh )
 {
   MsqPrintError err(cout);
   
   std::vector<Mesh::ElementHandle> elems(4);
   std::vector<Mesh::VertexHandle> verts(9);
   std::vector<size_t> offsets(5);
   
   mesh.get_all_elements( elems, err );
   ASSERT_NO_ERROR(err);
   CPPUNIT_ASSERT_EQUAL(elems.size(), (size_t)4);
   
   mesh.elements_get_attached_vertices( arrptr(elems), elems.size(),
                                        verts, offsets, err );
   ASSERT_NO_ERROR(err);
   CPPUNIT_ASSERT(verts.size() == 16);
   CPPUNIT_ASSERT(offsets.size() == 5);
   
   check_4quad_block( mesh, verts.begin() );
 }
Ejemplo n.º 12
0
  void VtkTest::test_read_unstructured( const char* filename )
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    mesh.read_vtk( filename, err );
    ASSERT_NO_ERROR(err);
    
      // Get mesh data
    std::vector<Mesh::VertexHandle> conn;
    std::vector<Mesh::ElementHandle> elems(38);
    std::vector<size_t> offsets(39);
    mesh.get_all_elements( elems, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)38 );
    mesh.elements_get_attached_vertices( arrptr(elems), elems.size(),
                                         conn, offsets, err );
    ASSERT_NO_ERROR(err);

    unsigned i;
    struct meshdata { EntityTopology type; size_t nodes; size_t count; };
    meshdata list[] = {
      { Mesquite::HEXAHEDRON,    8,  8 },
      { Mesquite::QUADRILATERAL, 4,  4 },
      { Mesquite::PYRAMID,       5,  4 },
      { Mesquite::TETRAHEDRON,   4,  6 },
      { Mesquite::TRIANGLE,      3, 14 },
      { Mesquite::PRISM,         6,  2 }, 
      { Mesquite::MIXED,         0,  0 } };
      
      // Count expected lenght of connectivity list
    size_t conn_len = 0;
    for (i = 0; list[i].nodes; ++i)
      conn_len += list[i].nodes * list[i].count;
    CPPUNIT_ASSERT_EQUAL( conn_len, conn.size() );
    
    check_8hex_block( mesh, conn.begin() );
    check_4quad_block( mesh, conn.begin() + 64 );
  }
Ejemplo n.º 13
0
 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(arrptr(mElements), 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;
 }
Ejemplo n.º 14
0
  void VtkTest::test_read_quadratic( const char* filename )
  {
    const size_t NUM_ELEM = 8;
  
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    mesh.read_vtk( filename, err );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems(NUM_ELEM);
    mesh.get_all_elements( elems, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL(elems.size(), NUM_ELEM );
    
    std::vector<Mesh::VertexHandle> conn;
    std::vector<size_t> offsets;
    mesh.elements_get_attached_vertices( arrptr(elems), elems.size(), conn, offsets, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL( conn.size(), (size_t)108 );
    
    EntityTopology types[NUM_ELEM];
    mesh.elements_get_topologies( arrptr(elems), types, NUM_ELEM, err );
    ASSERT_NO_ERROR(err);

    static const double hex_corners[] = 
     {  1.0, -1.0, -1.0, 
        1.0,  1.0, -1.0, 
       -1.0,  1.0, -1.0, 
       -1.0, -1.0, -1.0,
        1.0, -1.0,  1.0, 
        1.0,  1.0,  1.0, 
       -1.0,  1.0,  1.0, 
       -1.0, -1.0,  1.0 };
    static const double tet_corners[] = 
     {  1.0, -1.0, -1.0,
        1.0,  1.0, -1.0,
       -1.0,  0.0, -1.0,
        0.0,  0.0,  1.0 };
    static const double pyr_corners[] = 
     {  1.0, -1.0, -1.0, 
        1.0,  1.0, -1.0, 
       -1.0,  1.0, -1.0, 
       -1.0, -1.0, -1.0,
        0.0,  0.0,  1.0 };
    static const double pri_corners[] = 
      { -1.0, -1.0, -1.0,
         1.0,  1.0, -1.0,
        -1.0,  1.0, -1.0,
        -1.0, -1.0,  1.0,
         1.0,  1.0,  1.0,
        -1.0,  1.0,  1.0 };
    static const unsigned hex_edges[] =
     { 0, 1, 
       1, 2, 
       2, 3,
       3, 0,
       0, 4,
       1, 5,
       2, 6,
       3, 7,
       4, 5,
       5, 6,
       6, 7,
       7, 4 };
    static const unsigned tet_edges[] = 
     { 0, 1,
       1, 2, 
       2, 0,
       0, 3,
       1, 3, 
       2, 3 };
    static const unsigned pri_edges[] =
     { 0, 1, 
       1, 2, 
       2, 0,
       0, 3,
       1, 4,
       2, 5,
       3, 4,
       4, 5,
       5, 3 };
    static const unsigned pyr_edges[] =
     { 0, 1, 
       1, 2, 
       2, 3,
       3, 0,
       0, 4,
       1, 4,
       2, 4,
       3, 4 };
    static const unsigned hex_faces[] = 
    { 4, 0, 1, 5, 4,
      4, 1, 2, 6, 5,
      4, 2, 3, 7, 6,
      4, 3, 0, 4, 7,
      4, 3, 2, 1, 0,
      4, 4, 5, 6, 7
    };
    static const struct {
      EntityTopology topology;
      unsigned num_corners;
      unsigned num_edges;
      unsigned num_faces; // if non-zero expect mid-face nodes
      unsigned num_region; // if non-zero expect mid-region node
      const double* corners;
      const unsigned* edges;
      const unsigned* faces;
    } expected_elems[NUM_ELEM] = {
      { Mesquite::HEXAHEDRON,    8, 12, 0, 0, hex_corners, hex_edges, hex_faces },
      { Mesquite::HEXAHEDRON,    8, 12, 6, 1, hex_corners, hex_edges, hex_faces },
      { Mesquite::TETRAHEDRON,   4,  6, 0, 0, tet_corners, tet_edges, 0 },
      { Mesquite::QUADRILATERAL, 4,  4, 0, 0, hex_corners, hex_edges, 0 },
      { Mesquite::QUADRILATERAL, 4,  4, 0, 1, hex_corners, hex_edges, 0 },
      { Mesquite::TRIANGLE,      3,  3, 0, 0, tet_corners, tet_edges, 0 },
      { Mesquite::PRISM,         6,  9, 0, 0, pri_corners, pri_edges, 0 },
      { Mesquite::PYRAMID,       5,  8, 0, 0, pyr_corners, pyr_edges, 0 } };
    
    MsqVertex have;
    std::vector<Mesh::VertexHandle>::iterator v_it = conn.begin();
    for (unsigned i = 0; i < NUM_ELEM; ++i)
    {
      CPPUNIT_ASSERT_EQUAL( expected_elems[i].topology, types[i] );

      size_t vtx_start = offsets[i];
      size_t vtx_end = offsets[i+1];
      size_t conn_len = expected_elems[i].num_corners 
                      + expected_elems[i].num_edges
                      + expected_elems[i].num_faces
                      + expected_elems[i].num_region;
      CPPUNIT_ASSERT_EQUAL( conn_len, vtx_end - vtx_start );
      
      for (unsigned c = 0; c < expected_elems[i].num_corners; ++c, ++v_it)
      {
        Vector3D expected(expected_elems[i].corners + 3*c);
        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);
        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );
      }
      
      for (unsigned m = 0; m < expected_elems[i].num_edges; ++m, ++v_it)
      {
        unsigned start_idx = expected_elems[i].edges[2*m];
        unsigned end_idx = expected_elems[i].edges[2*m+1];
        Vector3D start( expected_elems[i].corners + 3*start_idx );
        Vector3D end( expected_elems[i].corners + 3*end_idx );
        Vector3D expected = 0.5 * (start + end);
        
        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);
        
        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );
      }

      const unsigned* f_it = expected_elems[i].faces;
      for (unsigned m = 0; m < expected_elems[i].num_faces; ++m, ++v_it)
      {
        Vector3D expected(0,0,0);
        const unsigned face_size = *f_it; ++f_it;
        CPPUNIT_ASSERT( face_size == 3u || face_size == 4u );
        for (unsigned f = 0; f < face_size; ++f, ++f_it) 
          expected += Vector3D( expected_elems[i].corners + 3 * *f_it );
        expected /= face_size;
        
        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);
        
        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );
      }
      
      if (expected_elems[i].num_region) {
        CPPUNIT_ASSERT_EQUAL( 1u, expected_elems[i].num_region );

        Vector3D expected(0,0,0);
        for (unsigned m = 0; m < expected_elems[i].num_corners; ++m)
          expected += Vector3D( expected_elems[i].corners + 3*m );
        expected /= expected_elems[i].num_corners;

        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);

        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );

        ++v_it;
      }
    }
  }