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 ); }
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; }
// 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 ) ); }
// 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) ); }
/* 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() ); }
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); }
// 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] ); } }
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); }
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]); } }
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()); }
// 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() ); }
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 ); }
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; }
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; } } }