MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2004 Sandia Corporation and Argonne National 00005 Laboratory. Under the terms of Contract DE-AC04-94AL85000 00006 with Sandia Corporation, the U.S. Government retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 [email protected], [email protected], [email protected], 00024 [email protected], [email protected], [email protected] 00025 00026 ***************************************************************** */ 00027 // -*- Mode : c++; tab-width: 2; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 2 00028 // -*- 00029 // 00030 00031 #include "meshfiles.h" 00032 00033 #include <iostream> 00034 using std::cout; 00035 00036 #ifndef DEBUG 00037 #include "Mesquite.hpp" 00038 #include "PatchData.hpp" 00039 #include "MeshImpl.hpp" 00040 #include "MeshInterface.hpp" 00041 #include "VertexPatches.hpp" 00042 #include "PatchIterator.hpp" 00043 #include "UnitUtil.hpp" 00044 #include "Instruction.hpp" 00045 using MBMesquite::arrptr; 00046 using MBMesquite::EntityTopology; 00047 using MBMesquite::Mesh; 00048 using MBMesquite::MeshImpl; 00049 using MBMesquite::MsqPrintError; 00050 using MBMesquite::MsqVertex; 00051 using MBMesquite::PatchIterator; 00052 using MBMesquite::Vector3D; 00053 using MBMesquite::VertexPatches; 00054 #else 00055 #include <stdio.h> 00056 #endif 00057 00058 #include <algorithm> 00059 00060 extern const char temp_file_name[] = "VtkTest.vtk"; 00061 00062 // VTK file for 2x2x2 block of hexes as structured-point 00063 extern const char structured_3d_points_data[] = "# vtk DataFile Version 2.0\n" 00064 "Mesquite Mesh\n" 00065 "ASCII\n" 00066 "DATASET STRUCTURED_POINTS\n" 00067 "DIMENSIONS 3 3 3\n" 00068 "ORIGIN 0 0 0\n" 00069 "SPACING 1.5 1.5 1.5\n"; 00070 00071 // VTK file for 2x2 block of quads as structured-point 00072 extern const char structured_2d_points_data[] = "# vtk DataFile Version 2.0\n" 00073 "Mesquite Mesh\n" 00074 "ASCII\n" 00075 "DATASET STRUCTURED_POINTS\n" 00076 "DIMENSIONS 3 3 1\n" 00077 "ORIGIN 0 0 0\n" 00078 "SPACING 1.5 1.5 0.0\n"; 00079 00080 // VTK file for 2x2x2 block of hexes as structured-grid 00081 extern const char structured_grid_data[] = "# vtk DataFile Version 2.0\n" 00082 "Mesquite Mesh\n" 00083 "ASCII\n" 00084 "DATASET STRUCTURED_GRID\n" 00085 "DIMENSIONS 3 3 3\n" 00086 "POINTS 27 float\n" 00087 "0.0 0.0 0.0\n1.5 0.0 0.0\n3.0 0.0 0.0\n" 00088 "0.0 1.5 0.0\n1.5 1.5 0.0\n3.0 1.5 0.0\n" 00089 "0.0 3.0 0.0\n1.5 3.0 0.0\n3.0 3.0 0.0\n" 00090 "0.0 0.0 1.5\n1.5 0.0 1.5\n3.0 0.0 1.5\n" 00091 "0.0 1.5 1.5\n1.5 1.5 1.5\n3.0 1.5 1.5\n" 00092 "0.0 3.0 1.5\n1.5 3.0 1.5\n3.0 3.0 1.5\n" 00093 "0.0 0.0 3.0\n1.5 0.0 3.0\n3.0 0.0 3.0\n" 00094 "0.0 1.5 3.0\n1.5 1.5 3.0\n3.0 1.5 3.0\n" 00095 "0.0 3.0 3.0\n1.5 3.0 3.0\n3.0 3.0 3.0\n"; 00096 00097 // VTK file for 2x2x2 block of hexes as rectilinear-grid 00098 extern const char rectilinear_grid_data[] = "# vtk DataFile Version 2.0\n" 00099 "Mesquite Mesh\n" 00100 "ASCII\n" 00101 "DATASET RECTILINEAR_GRID\n" 00102 "DIMENSIONS 3 3 3\n" 00103 "X_COORDINATES 3 float\n" 00104 "0.0 1.5 3.0\n" 00105 "Y_COORDINATES 3 float\n" 00106 "0.0 1.5 3.0\n" 00107 "Z_COORDINATES 3 float\n" 00108 "0.0 1.5 3.0\n"; 00109 00110 // VTK file containing mixed-element unstructured mesh 00111 // First 8 elems result in same 2x2x2 block of hexes as 00112 // structured cases above. The next 4 elems are the same 00113 // as the quads from the 2D structured-point file above. 00114 extern const char mixed_unstructured_data[] = 00115 "# vtk DataFile Version 2.0\n" 00116 "Mesquite Mesh\n" 00117 "ASCII\n" 00118 "DATASET UNSTRUCTURED_GRID\n" 00119 "POINTS 35 float\n" 00120 "\n" // points for an 2x2x2 brick of hexes (same geom/topo as above structured meshes) 00121 "0.0 0.0 0.0\n1.5 0.0 0.0\n3.0 0.0 0.0\n" 00122 "0.0 1.5 0.0\n1.5 1.5 0.0\n3.0 1.5 0.0\n" 00123 "0.0 3.0 0.0\n1.5 3.0 0.0\n3.0 3.0 0.0\n" 00124 "0.0 0.0 1.5\n1.5 0.0 1.5\n3.0 0.0 1.5\n" 00125 "0.0 1.5 1.5\n1.5 1.5 1.5\n3.0 1.5 1.5\n" 00126 "0.0 3.0 1.5\n1.5 3.0 1.5\n3.0 3.0 1.5\n" 00127 "0.0 0.0 3.0\n1.5 0.0 3.0\n3.0 0.0 3.0\n" 00128 "0.0 1.5 3.0\n1.5 1.5 3.0\n3.0 1.5 3.0\n" 00129 "0.0 3.0 3.0\n1.5 3.0 3.0\n3.0 3.0 3.0\n" 00130 "\n" // more points on +x side of brick for pyramids and tets 00131 "4 0.75 0.75\n4 2.25 0.75\n4 0.75 2.25\n4 2.25 2.25\n" 00132 "\n" // more points for two prisms/wedges 00133 "6 0.75 0.75\n6 2.25 0.75\n6 0.75 2.25\n6 2.25 2.25\n" 00134 "\n" 00135 "CELLS 38 216\n" 00136 "\n" // 8 hexes in 2x2x2 block 00137 "8 0 1 4 3 9 10 13 12\n" 00138 "8 1 2 5 4 10 11 14 13\n" 00139 "8 3 4 7 6 12 13 16 15\n" 00140 "8 4 5 8 7 13 14 17 16\n" 00141 "8 9 10 13 12 18 19 22 21\n" 00142 "8 10 11 14 13 19 20 23 22\n" 00143 "8 12 13 16 15 21 22 25 24\n" 00144 "8 13 14 17 16 22 23 26 25\n" 00145 "\n" // Quads on -z face of hex (inverted to match structured data) 00146 "4 0 1 4 3\n" 00147 "4 1 2 5 4\n" 00148 "4 3 4 7 6\n" 00149 "4 4 5 8 7\n" 00150 "\n" // some pyramids on the +x side of the block 00151 "5 2 5 14 11 27\n" 00152 "5 5 8 17 14 28\n" 00153 "5 11 14 23 20 29\n" 00154 "5 14 17 26 23 30\n" 00155 "\n" // Some tetrahedrons around the pyramids 00156 "4 5 14 27 28\n" 00157 "4 14 28 17 30\n" 00158 "4 29 14 23 30\n" 00159 "4 11 27 14 29\n" 00160 "4 27 29 30 14\n" 00161 "4 28 27 30 14\n" 00162 "\n" // Triangles bounding the pyramid/tet region 00163 "3 2 5 27\n" 00164 "3 5 28 27\n" 00165 "3 5 8 28\n" 00166 "3 8 17 28\n" 00167 "3 17 30 28\n" 00168 "3 17 26 30\n" 00169 "3 26 23 30\n" 00170 "3 23 29 30\n" 00171 "3 23 20 29\n" 00172 "3 20 11 29\n" 00173 "3 11 27 29\n" 00174 "3 2 27 11\n" 00175 "3 27 28 30\n" 00176 "3 27 30 29\n" 00177 "\n" // A couple wedges/prisms 00178 "6 27 30 28 31 34 32\n" 00179 "6 30 27 29 34 31 33\n" 00180 "\n" 00181 "CELL_TYPES 38\n" 00182 "12 12 12 12 12 12 12 12\n" // 8 hexes 00183 " 9 9 9 9\n" // 4 quads 00184 "14 14 14 14\n" // 4 pyramids 00185 "10 10 10 10 10 10\n" // 6 tets 00186 " 5 5 5 5 5 5 5 " 00187 " 5 5 5 5 5 5 5\n" // 14 tri 00188 "13 13\n"; // 2 wedges 00189 00190 extern const char quadratic_unstructured_data[] = 00191 "# vtk DataFile Version 2.0\n" 00192 "Mesquite Mesh\n" 00193 "ASCII\n" 00194 "DATASET UNSTRUCTURED_GRID\n" 00195 "POINTS 41 float\n" 00196 "\n" // points for a single quadtratic hex, in ExodusII order 00197 " 1.0 -1.0 -1.0 \n" // 0 bottom corners 00198 " 1.0 1.0 -1.0 \n" // 1 00199 "-1.0 1.0 -1.0 \n" // 2 00200 "-1.0 -1.0 -1.0 \n" // 3 00201 " 1.0 -1.0 1.0 \n" // 4 top corners 00202 " 1.0 1.0 1.0 \n" // 5 00203 "-1.0 1.0 1.0 \n" // 6 00204 "-1.0 -1.0 1.0 \n" // 7 00205 " 1.0 0.0 -1.0 \n" // 8 bottom mid-nodes 00206 " 0.0 1.0 -1.0 \n" // 9 00207 "-1.0 0.0 -1.0 \n" // 10 00208 " 0.0 -1.0 -1.0 \n" // 11 00209 " 1.0 -1.0 0.0 \n" // 12 side mid-nodes 00210 " 1.0 1.0 0.0 \n" // 13 00211 "-1.0 1.0 0.0 \n" // 14 00212 "-1.0 -1.0 0.0 \n" // 15 00213 " 1.0 0.0 1.0 \n" // 16 top mid-nodes 00214 " 0.0 1.0 1.0 \n" // 17 00215 "-1.0 0.0 1.0 \n" // 18 00216 " 0.0 -1.0 1.0 \n" // 19 00217 " 1.0 0.0 0.0 \n" // 20 mid-nodes for side faces 00218 " 0.0 1.0 0.0 \n" // 21 00219 "-1.0 0.0 0.0 \n" // 22 00220 " 0.0 -1.0 0.0 \n" // 23 00221 " 0.0 0.0 -1.0 \n" // 24 mid-nodes for top/bottom faces 00222 " 0.0 0.0 1.0 \n" // 25 00223 " 0.0 0.0 0.0 \n" // 26 mid-region 00224 "\n" // points for a single quadtatic tet, in ExodusII order 00225 " 1.0 -1.0 -1.0 \n" // 27 base triangle 00226 " 1.0 1.0 -1.0 \n" // 28 00227 "-1.0 0.0 -1.0 \n" // 29 00228 " 0.0 0.0 1.0 \n" // 30 apex 00229 " 1.0 0.0 -1.0 \n" // 31 base mid-nodes 00230 " 0.0 0.5 -1.0 \n" // 32 00231 " 0.0 -0.5 -1.0 \n" // 33 00232 " 0.5 -0.5 0.0 \n" // 34 side mid-nodes 00233 " 0.5 0.5 0.0 \n" // 35 00234 "-0.5 0.0 0.0 \n" // 36 00235 "\n" // mid-edge nodes for apex edges of quadratic pyramid 00236 " 0.5 -0.5 0 \n" // 37 00237 " 0.5 0.5 0 \n" // 38 00238 "-0.5 0.5 0 \n" // 39 00239 "-0.5 -0.5 0 \n" // 40 00240 "\n" 00241 "CELLS 8 116\n" 00242 "20 0 1 2 3 4 5 6 7 8 9 10 11 16 17 18 19 12 13 14 15\n" // Hex20 00243 "27 0 1 2 3 4 5 6 7 8 9 10 11 16 17 18 19 12 13 14 15 23 21 20 22 24 25 26\n" // Hex27 00244 "10 27 28 29 30 31 32 33 34 35 36\n" // Tet10 00245 "8 0 1 2 3 8 9 10 11\n" // Quad8 (base of hex) 00246 "9 0 1 2 3 8 9 10 11 24\n" // Quad9 (base of hex) 00247 "6 27 28 29 31 32 33\n" // Tri6 (base of tet) 00248 "15 3 2 1 7 6 5 10 9 24 18 17 25 15 14 13\n" // quadratic prism as half of hex 00249 "13 0 1 2 3 25 8 9 10 11 37 38 39 40\n" // quadratic pyramid with same base as hex 00250 "\n" 00251 "CELL_TYPES 8\n" 00252 "25 29 24 23 28 22 26 27\n"; 00253 00254 // A simple scalar attribute specifying point and hex 00255 // IDs. May be appended to any of the above 3D structured 00256 // mesh files. 00257 extern const char simple_scalar_attrib[] = "CELL_DATA 8\n" 00258 "SCALARS global_id int 1\n" 00259 "LOOKUP_TABLE default\n" 00260 "1 2 3 4 5 6 7 8\n" 00261 "\n" 00262 "POINT_DATA 27\n" 00263 "SCALARS global_id int\n" 00264 "LOOKUP_TABLE default\n" 00265 " 1 2 3 4 5 6 7 8 9\n" 00266 "10 11 12 13 14 15 16 17 18\n" 00267 "19 20 21 22 23 24 25 26 27\n"; 00268 00269 // A VTK vector attribute. May be appended to any of the 00270 // above 3D structured mesh files. 00271 extern const char simple_vector_attrib[] = "CELL_DATA 8\n" 00272 "VECTORS hexvect float\n" 00273 "1 1 1\n" 00274 "2 2 2\n" 00275 "3 3 3\n" 00276 "4 4 4\n" 00277 "5 5 5\n" 00278 "6 6 6\n" 00279 "7 7 7\n" 00280 "8 8 8\n"; 00281 00282 extern const char simple_field_attrib[] = "CELL_DATA 8\n" 00283 "FIELD test_field 2\n" 00284 "elem_ids 1 8 int\n" 00285 "1 2 3 4 5 6 7 8\n" 00286 "elem_vects 3 8 float\n" 00287 "1 1 1\n" 00288 "2 2 2\n" 00289 "3 3 3\n" 00290 "4 4 4\n" 00291 "5 5 5\n" 00292 "6 6 6\n" 00293 "7 7 7\n" 00294 "8 8 8\n" 00295 "FIELD field1 1\n" 00296 "values 1 8 int\n" 00297 "8 7 6 5 4 3 2 1\n"; 00298 00299 // A scalar VTK attribute with the name and datatype 00300 // expected by MeshImpl for specifying boundary vertices. 00301 // May be appended to any of the above 3D structured 00302 // mesh files 00303 extern const char fixed_vertex_attrib[] = "POINT_DATA 27\n" 00304 "SCALARS fixed float\n" 00305 "LOOKUP_TABLE default\n" 00306 "1 1 1 1 1 1 1 1 1\n" 00307 "1 1 1 1 0 1 1 1 1\n" 00308 "1 1 1 1 1 1 1 1 1\n"; 00309 00310 #ifndef DEBUG 00311 00312 class VtkTest : public CppUnit::TestFixture 00313 { 00314 private: 00315 CPPUNIT_TEST_SUITE( VtkTest ); 00316 00317 // Original test for old Vtk parser 00318 CPPUNIT_TEST( test_elements ); 00319 00320 // Additional tests for new Vtk parser - J.Kraftcheck, 2004-10-12 00321 CPPUNIT_TEST( test_read_unstructured ); 00322 CPPUNIT_TEST( test_read_structured_2d_points ); 00323 CPPUNIT_TEST( test_read_structured_3d_points ); 00324 CPPUNIT_TEST( test_read_structured_grid ); 00325 CPPUNIT_TEST( test_read_rectilinear_grid ); 00326 CPPUNIT_TEST( test_read_simple_scalar_attrib ); 00327 CPPUNIT_TEST( test_read_vector_attrib ); 00328 CPPUNIT_TEST( test_read_field_attrib ); 00329 CPPUNIT_TEST( test_write_field_attrib ); 00330 CPPUNIT_TEST( test_read_fixed_attrib ); 00331 CPPUNIT_TEST( test_read_quadratic ); 00332 CPPUNIT_TEST( test_write_quadratic ); 00333 00334 // Test writer - J.Kraftcheck, 2004-10-12 00335 CPPUNIT_TEST( test_write ); 00336 00337 CPPUNIT_TEST_SUITE_END(); 00338 00339 public: 00340 /* Automatically called by CppUnit before each test function. */ 00341 void setUp() {} 00342 00343 // Automatically called by CppUnit after each test function. 00344 void tearDown() {} 00345 00346 public: 00347 VtkTest() {} 00348 00349 // Check if the 2x2x2 brick of structured mesh 00350 // read from file is as expected. 00351 void check_8hex_structured( Mesh& mesh ); 00352 00353 // Check if the 2x2x2 brick of hexes 00354 // read from file is as expected. 00355 void check_8hex_block( Mesh& mesh, std::vector< Mesh::VertexHandle >::iterator connectivity ); 00356 00357 // Check if the 2x2 brick of structured mesh 00358 // read from file is as expected. 00359 void check_4quad_structured( Mesh& mesh ); 00360 00361 // Check if the 2x2 brick of quads 00362 // read from file is as expected. 00363 void check_4quad_block( Mesh& mesh, std::vector< Mesh::VertexHandle >::iterator connectivity ); 00364 00365 // Test reading VTK unstructured mesh 00366 void test_read_unstructured(); 00367 00368 void test_read_unstructured( const char* filename ); 00369 00370 // Test reading 2D Vtk structured-points mesh 00371 void test_read_structured_2d_points(); 00372 00373 // Test reading 3D Vtk structured-points mesh 00374 void test_read_structured_3d_points(); 00375 00376 // Test reading 3D Vtk structured-grid mesh 00377 void test_read_structured_grid(); 00378 00379 // Test reading 3D Vtk rectilinear-grid mesh 00380 void test_read_rectilinear_grid(); 00381 00382 // Test reading Vtk simple (one-component) scalar attribute 00383 void test_read_simple_scalar_attrib(); 00384 00385 // Test reading Vtk vector attribute 00386 void test_read_vector_attrib(); 00387 00388 // Test reading VTK FIELD attribute data 00389 void test_read_field_attrib(); 00390 void test_write_field_attrib(); 00391 void check_field_attrib( const char* file ); 00392 00393 // Test reading MeshImpl boundary-vertex bit 00394 // from Vtk scalar attribute. 00395 void test_read_fixed_attrib(); 00396 00397 // Test writing VTK unstructured mesh 00398 void test_write(); 00399 00400 void test_read_quadratic(); 00401 void test_read_quadratic( const char* filename ); 00402 void test_write_quadratic(); 00403 00404 void test_elements(); 00405 00406 int tri_check_validity( const MBMesquite::MsqMeshEntity* element_array, 00407 size_t num_elements, 00408 const MBMesquite::MsqVertex* vtx_array, 00409 size_t num_vertices ); 00410 00411 int tet_validity_check( const MBMesquite::MsqMeshEntity* element_array, 00412 size_t num_elements, 00413 const MBMesquite::MsqVertex* vtx_array ); 00414 }; 00415 // Check if the 2x2x2 brick of structured mesh 00416 // read from file is as expected. 00417 void VtkTest::check_8hex_structured( Mesh& mesh ) 00418 { 00419 MsqPrintError err( cout ); 00420 00421 std::vector< Mesh::ElementHandle > elems( 8 ); 00422 std::vector< Mesh::VertexHandle > verts( 64 ); 00423 std::vector< size_t > offsets( 9 ); 00424 00425 mesh.get_all_elements( elems, err ); 00426 ASSERT_NO_ERROR( err ); 00427 CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 ); 00428 00429 mesh.elements_get_attached_vertices( arrptr( elems ), elems.size(), verts, offsets, err ); 00430 ASSERT_NO_ERROR( err ); 00431 CPPUNIT_ASSERT( verts.size() == 64 ); 00432 CPPUNIT_ASSERT( offsets.size() == 9 ); 00433 00434 check_8hex_block( mesh, verts.begin() ); 00435 } 00436 00437 // Check if the 2x2x2 brick of hexes 00438 // read from file is as expected. 00439 void VtkTest::check_8hex_block( Mesh& mesh, std::vector< Mesh::VertexHandle >::iterator connectivity ) 00440 { 00441 MsqPrintError err( cout ); 00442 const int base_corners[] = { 0, 1, 3, 4, 9, 10, 12, 13 }; 00443 const int corner_offsets[] = { 0, 1, 4, 3, 9, 10, 13, 12 }; 00444 00445 for( int hex = 0; hex < 8; ++hex ) 00446 { 00447 for( int node = 0; node < 8; ++node ) 00448 { 00449 const int index = base_corners[hex] + corner_offsets[node]; 00450 const int x = index % 3; 00451 const int y = ( index / 3 ) % 3; 00452 const int z = index / 9; 00453 const Vector3D expected_coords( 1.5 * x, 1.5 * y, 1.5 * z ); 00454 MsqVertex actual_coords; 00455 Mesh::VertexHandle* conn_ptr = &*connectivity; 00456 ++connectivity; 00457 mesh.vertices_get_coordinates( conn_ptr, &actual_coords, 1, err ); 00458 CPPUNIT_ASSERT( !err ); 00459 CPPUNIT_ASSERT( expected_coords.within_tolerance_box( actual_coords, DBL_EPSILON ) ); 00460 } 00461 } 00462 } 00463 00464 // Check if the 2x2 brick of structured mesh 00465 // read from file is as expected. 00466 void VtkTest::check_4quad_structured( Mesh& mesh ) 00467 { 00468 MsqPrintError err( cout ); 00469 00470 std::vector< Mesh::ElementHandle > elems( 4 ); 00471 std::vector< Mesh::VertexHandle > verts( 9 ); 00472 std::vector< size_t > offsets( 5 ); 00473 00474 mesh.get_all_elements( elems, err ); 00475 ASSERT_NO_ERROR( err ); 00476 CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)4 ); 00477 00478 mesh.elements_get_attached_vertices( arrptr( elems ), elems.size(), verts, offsets, err ); 00479 ASSERT_NO_ERROR( err ); 00480 CPPUNIT_ASSERT( verts.size() == 16 ); 00481 CPPUNIT_ASSERT( offsets.size() == 5 ); 00482 00483 check_4quad_block( mesh, verts.begin() ); 00484 } 00485 00486 // Check if the 2x2 brick of quads 00487 // read from file is as expected. 00488 void VtkTest::check_4quad_block( Mesh& mesh, std::vector< Mesh::VertexHandle >::iterator connectivity ) 00489 { 00490 MsqPrintError err( cout ); 00491 const int base_corners[] = { 0, 1, 3, 4 }; 00492 const int corner_offsets[] = { 0, 1, 4, 3 }; 00493 for( int quad = 0; quad < 4; ++quad ) 00494 { 00495 for( int node = 0; node < 4; ++node ) 00496 { 00497 const int index = base_corners[quad] + corner_offsets[node]; 00498 const int x = index % 3; 00499 const int y = index / 3; 00500 const Vector3D expected_coords( 1.5 * x, 1.5 * y, 0.0 ); 00501 MsqVertex actual_coords; 00502 Mesh::VertexHandle* conn_ptr = &*connectivity; 00503 ++connectivity; 00504 mesh.vertices_get_coordinates( conn_ptr, &actual_coords, 1, err ); 00505 CPPUNIT_ASSERT( !err ); 00506 CPPUNIT_ASSERT( expected_coords.within_tolerance_box( actual_coords, DBL_EPSILON ) ); 00507 } 00508 } 00509 } 00510 00511 // Test reading VTK unstructured mesh 00512 void VtkTest::test_read_unstructured() 00513 { 00514 FILE* file = fopen( temp_file_name, "w+" ); 00515 CPPUNIT_ASSERT( file ); 00516 int rval = fputs( mixed_unstructured_data, file ); 00517 fclose( file ); 00518 if( rval == EOF ) remove( temp_file_name ); 00519 CPPUNIT_ASSERT( rval != EOF ); 00520 00521 test_read_unstructured( temp_file_name ); 00522 } 00523 00524 void VtkTest::test_read_unstructured( const char* filename ) 00525 { 00526 MeshImpl mesh; 00527 MsqPrintError err( cout ); 00528 00529 mesh.read_vtk( filename, err ); 00530 ASSERT_NO_ERROR( err ); 00531 00532 // Get mesh data 00533 std::vector< Mesh::VertexHandle > conn; 00534 std::vector< Mesh::ElementHandle > elems( 38 ); 00535 std::vector< size_t > offsets( 39 ); 00536 mesh.get_all_elements( elems, err ); 00537 ASSERT_NO_ERROR( err ); 00538 CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)38 ); 00539 mesh.elements_get_attached_vertices( arrptr( elems ), elems.size(), conn, offsets, err ); 00540 ASSERT_NO_ERROR( err ); 00541 00542 unsigned i; 00543 struct meshdata 00544 { 00545 EntityTopology type; 00546 size_t nodes; 00547 size_t count; 00548 }; 00549 meshdata list[] = { { MBMesquite::HEXAHEDRON, 8, 8 }, { MBMesquite::QUADRILATERAL, 4, 4 }, 00550 { MBMesquite::PYRAMID, 5, 4 }, { MBMesquite::TETRAHEDRON, 4, 6 }, 00551 { MBMesquite::TRIANGLE, 3, 14 }, { MBMesquite::PRISM, 6, 2 }, 00552 { MBMesquite::MIXED, 0, 0 } }; 00553 00554 // Count expected lenght of connectivity list 00555 size_t conn_len = 0; 00556 for( i = 0; list[i].nodes; ++i ) 00557 conn_len += list[i].nodes * list[i].count; 00558 CPPUNIT_ASSERT_EQUAL( conn_len, conn.size() ); 00559 00560 check_8hex_block( mesh, conn.begin() ); 00561 check_4quad_block( mesh, conn.begin() + 64 ); 00562 } 00563 00564 // Test reading 2D Vtk structured-points mesh 00565 void VtkTest::test_read_structured_2d_points() 00566 { 00567 MeshImpl mesh; 00568 MsqPrintError err( cout ); 00569 00570 FILE* file = fopen( temp_file_name, "w+" ); 00571 fputs( structured_2d_points_data, file ); 00572 fclose( file ); 00573 00574 mesh.read_vtk( temp_file_name, err ); 00575 remove( temp_file_name ); 00576 ASSERT_NO_ERROR( err ); 00577 00578 check_4quad_structured( mesh ); 00579 } 00580 00581 // Test reading 3D Vtk structured-points mesh 00582 void VtkTest::test_read_structured_3d_points() 00583 { 00584 MeshImpl mesh; 00585 MsqPrintError err( cout ); 00586 00587 FILE* file = fopen( temp_file_name, "w+" ); 00588 fputs( structured_3d_points_data, file ); 00589 fclose( file ); 00590 00591 mesh.read_vtk( temp_file_name, err ); 00592 remove( temp_file_name ); 00593 ASSERT_NO_ERROR( err ); 00594 00595 check_8hex_structured( mesh ); 00596 } 00597 00598 // Test reading 3D Vtk structured-grid mesh 00599 void VtkTest::test_read_structured_grid() 00600 { 00601 MeshImpl mesh; 00602 MsqPrintError err( cout ); 00603 00604 FILE* file = fopen( temp_file_name, "w+" ); 00605 fputs( structured_grid_data, file ); 00606 fclose( file ); 00607 00608 mesh.read_vtk( temp_file_name, err ); 00609 remove( temp_file_name ); 00610 ASSERT_NO_ERROR( err ); 00611 00612 check_8hex_structured( mesh ); 00613 } 00614 00615 // Test reading 3D Vtk rectilinear-grid mesh 00616 void VtkTest::test_read_rectilinear_grid() 00617 { 00618 MeshImpl mesh; 00619 MsqPrintError err( cout ); 00620 00621 FILE* file = fopen( temp_file_name, "w+" ); 00622 fputs( rectilinear_grid_data, file ); 00623 fclose( file ); 00624 00625 mesh.read_vtk( temp_file_name, err ); 00626 remove( temp_file_name ); 00627 ASSERT_NO_ERROR( err ); 00628 00629 check_8hex_structured( mesh ); 00630 } 00631 00632 // Test reading Vtk simple (one-component) scalar attribute 00633 void VtkTest::test_read_simple_scalar_attrib() 00634 { 00635 MeshImpl mesh; 00636 MsqPrintError err( cout ); 00637 00638 FILE* file = fopen( temp_file_name, "w+" ); 00639 fputs( structured_3d_points_data, file ); 00640 fputs( simple_scalar_attrib, file ); 00641 fclose( file ); 00642 00643 mesh.read_vtk( temp_file_name, err ); 00644 remove( temp_file_name ); 00645 ASSERT_NO_ERROR( err ); 00646 00647 std::vector< Mesh::ElementHandle > elems; 00648 mesh.get_all_elements( elems, err ); 00649 CPPUNIT_ASSERT( !err ); 00650 CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 ); 00651 00652 void* th = mesh.tag_get( "global_id", err ); 00653 CPPUNIT_ASSERT( !err ); 00654 00655 std::string name; 00656 Mesh::TagType type; 00657 unsigned tagsize; 00658 mesh.tag_properties( th, name, type, tagsize, err ); 00659 CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 ); 00660 00661 int elem_data[8]; 00662 mesh.tag_get_element_data( th, 8, arrptr( elems ), elem_data, err ); 00663 CPPUNIT_ASSERT( !err ); 00664 00665 for( int i = 0; i < 8; ++i ) 00666 CPPUNIT_ASSERT( elem_data[i] == ( 1 + i ) ); 00667 } 00668 00669 // Test reading Vtk vector attribute 00670 void VtkTest::test_read_vector_attrib() 00671 { 00672 MeshImpl mesh; 00673 MsqPrintError err( cout ); 00674 00675 FILE* file = fopen( temp_file_name, "w+" ); 00676 fputs( structured_3d_points_data, file ); 00677 fputs( simple_vector_attrib, file ); 00678 fclose( file ); 00679 00680 mesh.read_vtk( temp_file_name, err ); 00681 remove( temp_file_name ); 00682 ASSERT_NO_ERROR( err ); 00683 00684 std::vector< Mesh::ElementHandle > elems; 00685 mesh.get_all_elements( elems, err ); 00686 CPPUNIT_ASSERT( !err ); 00687 CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 ); 00688 00689 void* th = mesh.tag_get( "hexvect", err ); 00690 CPPUNIT_ASSERT( !err ); 00691 00692 std::string name; 00693 Mesh::TagType type; 00694 unsigned tagsize; 00695 mesh.tag_properties( th, name, type, tagsize, err ); 00696 CPPUNIT_ASSERT( !err && type == Mesh::DOUBLE && tagsize == 3 ); 00697 00698 double elem_data[24]; 00699 mesh.tag_get_element_data( th, 8, arrptr( elems ), elem_data, err ); 00700 CPPUNIT_ASSERT( !err ); 00701 00702 for( int i = 0; i < 8; ++i ) 00703 CPPUNIT_ASSERT( Vector3D( elem_data + 3 * i ) == Vector3D( i + 1, i + 1, i + 1 ) ); 00704 } 00705 00706 // Test reading Vtk field attribute 00707 void VtkTest::test_read_field_attrib() 00708 { 00709 FILE* file = fopen( temp_file_name, "w+" ); 00710 fputs( structured_3d_points_data, file ); 00711 fputs( simple_field_attrib, file ); 00712 fclose( file ); 00713 check_field_attrib( temp_file_name ); 00714 } 00715 00716 void VtkTest::check_field_attrib( const char* temp_file_name ) 00717 { 00718 MeshImpl mesh; 00719 MsqPrintError err( cout ); 00720 00721 mesh.read_vtk( temp_file_name, err ); 00722 remove( temp_file_name ); 00723 ASSERT_NO_ERROR( err ); 00724 00725 std::vector< Mesh::ElementHandle > elems; 00726 mesh.get_all_elements( elems, err ); 00727 CPPUNIT_ASSERT( !err ); 00728 CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 ); 00729 00730 std::string name; 00731 Mesh::TagType type; 00732 unsigned tagsize; 00733 00734 void* th = mesh.tag_get( "test_field elem_vects", err ); 00735 CPPUNIT_ASSERT( !err ); 00736 00737 mesh.tag_properties( th, name, type, tagsize, err ); 00738 CPPUNIT_ASSERT( !err && type == Mesh::DOUBLE && tagsize == 3 ); 00739 00740 double elem_data[24]; 00741 mesh.tag_get_element_data( th, 8, arrptr( elems ), elem_data, err ); 00742 CPPUNIT_ASSERT( !err ); 00743 00744 for( int i = 0; i < 8; ++i ) 00745 CPPUNIT_ASSERT( Vector3D( elem_data + 3 * i ) == Vector3D( i + 1, i + 1, i + 1 ) ); 00746 00747 th = mesh.tag_get( "test_field elem_ids", err ); 00748 CPPUNIT_ASSERT( !err ); 00749 00750 mesh.tag_properties( th, name, type, tagsize, err ); 00751 CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 ); 00752 00753 int elem_ids[8]; 00754 mesh.tag_get_element_data( th, 8, arrptr( elems ), elem_ids, err ); 00755 CPPUNIT_ASSERT( !err ); 00756 00757 for( int i = 0; i < 8; ++i ) 00758 CPPUNIT_ASSERT( elem_ids[i] == i + 1 ); 00759 00760 th = mesh.tag_get( "field1", err ); 00761 CPPUNIT_ASSERT( !err ); 00762 00763 mesh.tag_properties( th, name, type, tagsize, err ); 00764 CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 ); 00765 00766 int values[8]; 00767 mesh.tag_get_element_data( th, 8, arrptr( elems ), values, err ); 00768 CPPUNIT_ASSERT( !err ); 00769 00770 for( int i = 0; i < 8; ++i ) 00771 CPPUNIT_ASSERT( values[i] == 8 - i ); 00772 } 00773 00774 // Test writing quadtratic elements 00775 void VtkTest::test_write_field_attrib() 00776 { 00777 MeshImpl mesh; 00778 MsqPrintError err( cout ); 00779 00780 // Create file containing unstructured mesh test case 00781 FILE* file = fopen( temp_file_name, "w+" ); 00782 fputs( structured_3d_points_data, file ); 00783 fputs( simple_field_attrib, file ); 00784 fclose( file ); 00785 00786 // Read unstructured mesh file 00787 mesh.read_vtk( temp_file_name, err ); 00788 remove( temp_file_name ); 00789 ASSERT_NO_ERROR( err ); 00790 00791 // Write unstructured mesh file back out 00792 mesh.write_vtk( temp_file_name, err ); 00793 if( err ) remove( temp_file_name ); 00794 ASSERT_NO_ERROR( err ); 00795 00796 // Check if file contained expected mesh 00797 check_field_attrib( temp_file_name ); 00798 } 00799 00800 // Test reading MeshImpl boundary-vertex bit 00801 // from Vtk scalar attribute. 00802 void VtkTest::test_read_fixed_attrib() 00803 { 00804 MeshImpl mesh; 00805 MsqPrintError err( cout ); 00806 00807 FILE* file = fopen( temp_file_name, "w+" ); 00808 fputs( structured_3d_points_data, file ); 00809 fputs( fixed_vertex_attrib, file ); 00810 fclose( file ); 00811 00812 mesh.read_vtk( temp_file_name, err ); 00813 remove( temp_file_name ); 00814 ASSERT_NO_ERROR( err ); 00815 00816 std::vector< Mesh::ElementHandle > elems; 00817 mesh.get_all_elements( elems, err ); 00818 CPPUNIT_ASSERT( !err ); 00819 CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 ); 00820 00821 std::vector< Mesh::VertexHandle > verts; 00822 std::vector< size_t > offsets; 00823 mesh.elements_get_attached_vertices( arrptr( elems ), elems.size(), verts, offsets, err ); 00824 ASSERT_NO_ERROR( err ); 00825 00826 // get unique list of vertices 00827 std::vector< Mesh::VertexHandle >::iterator new_end; 00828 std::sort( verts.begin(), verts.end() ); 00829 new_end = std::unique( verts.begin(), verts.end() ); 00830 verts.resize( new_end - verts.begin() ); 00831 CPPUNIT_ASSERT_EQUAL( verts.size(), (size_t)27 ); 00832 00833 // get fixed flag 00834 std::vector< bool > fixed; 00835 mesh.vertices_get_fixed_flag( arrptr( verts ), fixed, verts.size(), err ); 00836 ASSERT_NO_ERROR( err ); 00837 CPPUNIT_ASSERT_EQUAL( verts.size(), fixed.size() ); 00838 00839 for( int i = 0; i < 27; ++i ) 00840 { 00841 bool should_be_fixed = ( i != 13 ); 00842 CPPUNIT_ASSERT_EQUAL( should_be_fixed, (bool)fixed[i] ); 00843 } 00844 } 00845 00846 // Test writing VTK unstructured mesh 00847 void VtkTest::test_write() 00848 { 00849 MeshImpl mesh; 00850 MsqPrintError err( cout ); 00851 00852 // Create file containing unstructured mesh test case 00853 FILE* file = fopen( temp_file_name, "w+" ); 00854 CPPUNIT_ASSERT( file ); 00855 int rval = fputs( mixed_unstructured_data, file ); 00856 fclose( file ); 00857 if( rval == EOF ) remove( temp_file_name ); 00858 CPPUNIT_ASSERT( rval != EOF ); 00859 00860 // Read unstructured mesh file 00861 mesh.read_vtk( temp_file_name, err ); 00862 remove( temp_file_name ); 00863 ASSERT_NO_ERROR( err ); 00864 00865 // Write unstructured mesh file back out 00866 mesh.write_vtk( temp_file_name, err ); 00867 if( err ) remove( temp_file_name ); 00868 ASSERT_NO_ERROR( err ); 00869 00870 // Check if file contained expected mesh 00871 test_read_unstructured( temp_file_name ); 00872 remove( temp_file_name ); 00873 } 00874 00875 // Test reading VTK unstructured mesh quadratic elements 00876 void VtkTest::test_read_quadratic() 00877 { 00878 FILE* file = fopen( temp_file_name, "w+" ); 00879 CPPUNIT_ASSERT( file ); 00880 int rval = fputs( quadratic_unstructured_data, file ); 00881 fclose( file ); 00882 if( rval == EOF ) remove( temp_file_name ); 00883 CPPUNIT_ASSERT( rval != EOF ); 00884 00885 test_read_quadratic( temp_file_name ); 00886 remove( temp_file_name ); 00887 } 00888 00889 void VtkTest::test_read_quadratic( const char* filename ) 00890 { 00891 const size_t NUM_ELEM = 8; 00892 00893 MeshImpl mesh; 00894 MsqPrintError err( cout ); 00895 00896 mesh.read_vtk( filename, err ); 00897 ASSERT_NO_ERROR( err ); 00898 00899 std::vector< Mesh::ElementHandle > elems( NUM_ELEM ); 00900 mesh.get_all_elements( elems, err ); 00901 ASSERT_NO_ERROR( err ); 00902 CPPUNIT_ASSERT_EQUAL( elems.size(), NUM_ELEM ); 00903 00904 std::vector< Mesh::VertexHandle > conn; 00905 std::vector< size_t > offsets; 00906 mesh.elements_get_attached_vertices( arrptr( elems ), elems.size(), conn, offsets, err ); 00907 ASSERT_NO_ERROR( err ); 00908 CPPUNIT_ASSERT_EQUAL( conn.size(), (size_t)108 ); 00909 00910 EntityTopology types[NUM_ELEM]; 00911 mesh.elements_get_topologies( arrptr( elems ), types, NUM_ELEM, err ); 00912 ASSERT_NO_ERROR( err ); 00913 00914 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, 00915 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0 }; 00916 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 }; 00917 static const double pyr_corners[] = { 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 00918 -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0 }; 00919 static const double pri_corners[] = { -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 00920 -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0 }; 00921 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 }; 00922 static const unsigned tet_edges[] = { 0, 1, 1, 2, 2, 0, 0, 3, 1, 3, 2, 3 }; 00923 static const unsigned pri_edges[] = { 0, 1, 1, 2, 2, 0, 0, 3, 1, 4, 2, 5, 3, 4, 4, 5, 5, 3 }; 00924 static const unsigned pyr_edges[] = { 0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 4, 2, 4, 3, 4 }; 00925 static const unsigned hex_faces[] = { 4, 0, 1, 5, 4, 4, 1, 2, 6, 5, 4, 2, 3, 7, 6, 00926 4, 3, 0, 4, 7, 4, 3, 2, 1, 0, 4, 4, 5, 6, 7 }; 00927 static const struct 00928 { 00929 EntityTopology topology; 00930 unsigned num_corners; 00931 unsigned num_edges; 00932 unsigned num_faces; // if non-zero expect mid-face nodes 00933 unsigned num_region; // if non-zero expect mid-region node 00934 const double* corners; 00935 const unsigned* edges; 00936 const unsigned* faces; 00937 } expected_elems[NUM_ELEM] = { { MBMesquite::HEXAHEDRON, 8, 12, 0, 0, hex_corners, hex_edges, hex_faces }, 00938 { MBMesquite::HEXAHEDRON, 8, 12, 6, 1, hex_corners, hex_edges, hex_faces }, 00939 { MBMesquite::TETRAHEDRON, 4, 6, 0, 0, tet_corners, tet_edges, 0 }, 00940 { MBMesquite::QUADRILATERAL, 4, 4, 0, 0, hex_corners, hex_edges, 0 }, 00941 { MBMesquite::QUADRILATERAL, 4, 4, 0, 1, hex_corners, hex_edges, 0 }, 00942 { MBMesquite::TRIANGLE, 3, 3, 0, 0, tet_corners, tet_edges, 0 }, 00943 { MBMesquite::PRISM, 6, 9, 0, 0, pri_corners, pri_edges, 0 }, 00944 { MBMesquite::PYRAMID, 5, 8, 0, 0, pyr_corners, pyr_edges, 0 } }; 00945 00946 MsqVertex have; 00947 std::vector< Mesh::VertexHandle >::iterator v_it = conn.begin(); 00948 for( unsigned i = 0; i < NUM_ELEM; ++i ) 00949 { 00950 CPPUNIT_ASSERT_EQUAL( expected_elems[i].topology, types[i] ); 00951 00952 size_t vtx_start = offsets[i]; 00953 size_t vtx_end = offsets[i + 1]; 00954 size_t conn_len = expected_elems[i].num_corners + expected_elems[i].num_edges + expected_elems[i].num_faces + 00955 expected_elems[i].num_region; 00956 CPPUNIT_ASSERT_EQUAL( conn_len, vtx_end - vtx_start ); 00957 00958 for( unsigned c = 0; c < expected_elems[i].num_corners; ++c, ++v_it ) 00959 { 00960 Vector3D expected( expected_elems[i].corners + 3 * c ); 00961 mesh.vertices_get_coordinates( &*v_it, &have, 1, err ); 00962 ASSERT_NO_ERROR( err ); 00963 expected -= have; 00964 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON ); 00965 } 00966 00967 for( unsigned m = 0; m < expected_elems[i].num_edges; ++m, ++v_it ) 00968 { 00969 unsigned start_idx = expected_elems[i].edges[2 * m]; 00970 unsigned end_idx = expected_elems[i].edges[2 * m + 1]; 00971 Vector3D start( expected_elems[i].corners + 3 * start_idx ); 00972 Vector3D end( expected_elems[i].corners + 3 * end_idx ); 00973 Vector3D expected = 0.5 * ( start + end ); 00974 00975 mesh.vertices_get_coordinates( &*v_it, &have, 1, err ); 00976 ASSERT_NO_ERROR( err ); 00977 00978 expected -= have; 00979 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON ); 00980 } 00981 00982 const unsigned* f_it = expected_elems[i].faces; 00983 for( unsigned m = 0; m < expected_elems[i].num_faces; ++m, ++v_it ) 00984 { 00985 Vector3D expected( 0, 0, 0 ); 00986 const unsigned face_size = *f_it; 00987 ++f_it; 00988 CPPUNIT_ASSERT( face_size == 3u || face_size == 4u ); 00989 for( unsigned f = 0; f < face_size; ++f, ++f_it ) 00990 expected += Vector3D( expected_elems[i].corners + 3 * *f_it ); 00991 expected /= face_size; 00992 00993 mesh.vertices_get_coordinates( &*v_it, &have, 1, err ); 00994 ASSERT_NO_ERROR( err ); 00995 00996 expected -= have; 00997 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON ); 00998 } 00999 01000 if( expected_elems[i].num_region ) 01001 { 01002 CPPUNIT_ASSERT_EQUAL( 1u, expected_elems[i].num_region ); 01003 01004 Vector3D expected( 0, 0, 0 ); 01005 for( unsigned m = 0; m < expected_elems[i].num_corners; ++m ) 01006 expected += Vector3D( expected_elems[i].corners + 3 * m ); 01007 expected /= expected_elems[i].num_corners; 01008 01009 mesh.vertices_get_coordinates( &*v_it, &have, 1, err ); 01010 ASSERT_NO_ERROR( err ); 01011 01012 expected -= have; 01013 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON ); 01014 01015 ++v_it; 01016 } 01017 } 01018 } 01019 01020 // Test writing quadtratic elements 01021 void VtkTest::test_write_quadratic() 01022 { 01023 MeshImpl mesh; 01024 MsqPrintError err( cout ); 01025 01026 // Create file containing unstructured mesh test case 01027 FILE* file = fopen( temp_file_name, "w+" ); 01028 CPPUNIT_ASSERT( file ); 01029 int rval = fputs( quadratic_unstructured_data, file ); 01030 fclose( file ); 01031 if( rval == EOF ) remove( temp_file_name ); 01032 CPPUNIT_ASSERT( rval != EOF ); 01033 01034 // Read unstructured mesh file 01035 mesh.read_vtk( temp_file_name, err ); 01036 remove( temp_file_name ); 01037 ASSERT_NO_ERROR( err ); 01038 01039 // Write unstructured mesh file back out 01040 mesh.write_vtk( temp_file_name, err ); 01041 if( err ) remove( temp_file_name ); 01042 ASSERT_NO_ERROR( err ); 01043 01044 // Check if file contained expected mesh 01045 test_read_quadratic( temp_file_name ); 01046 remove( temp_file_name ); 01047 } 01048 01049 void VtkTest::test_elements() 01050 { 01051 MBMesquite::MsqPrintError err( cout ); 01052 MeshImpl mMesh; 01053 mMesh.read_vtk( MESH_FILES_DIR "2D/vtk/tris/untangled/equil_tri2.vtk", err ); 01054 ASSERT_NO_ERROR( err ); 01055 MBMesquite::MeshDomainAssoc mesh_and_domain = MBMesquite::MeshDomainAssoc( &mMesh, 0 ); 01056 MBMesquite::Instruction::initialize_vertex_byte( &mesh_and_domain, 0, err ); 01057 ASSERT_NO_ERROR( err ); 01058 01059 // Retrieve a patch 01060 MBMesquite::PatchData pd; 01061 pd.set_mesh( &mMesh ); 01062 VertexPatches patch_set; 01063 patch_set.set_mesh( &mMesh ); 01064 PatchIterator patches( &patch_set ); 01065 patches.get_next_patch( pd, err ); 01066 ASSERT_NO_ERROR( err ); 01067 01068 int free_vtx = pd.num_free_vertices(); 01069 // std::cout << "nb of free vertices: " << free_vtx << std::endl; 01070 CPPUNIT_ASSERT( free_vtx == 1 ); 01071 01072 MBMesquite::MsqMeshEntity* element_array = pd.get_element_array( err ); 01073 ASSERT_NO_ERROR( err ); 01074 size_t num_elements = pd.num_elements(); 01075 CPPUNIT_ASSERT( num_elements == 6 ); 01076 01077 const MBMesquite::MsqVertex* vtx_array = pd.get_vertex_array( err ); 01078 ASSERT_NO_ERROR( err ); 01079 size_t num_vertices = pd.num_nodes(); 01080 CPPUNIT_ASSERT( num_vertices == 7 ); 01081 01082 CPPUNIT_ASSERT( tri_check_validity( element_array, num_elements, vtx_array, num_vertices ) == 1 ); 01083 01084 patches.get_next_patch( pd, err ); 01085 ASSERT_NO_ERROR( err ); 01086 01087 element_array = pd.get_element_array( err ); 01088 ASSERT_NO_ERROR( err ); 01089 num_elements = pd.num_elements(); 01090 CPPUNIT_ASSERT( num_elements == 6 ); 01091 01092 vtx_array = pd.get_vertex_array( err ); 01093 ASSERT_NO_ERROR( err ); 01094 num_vertices = pd.num_nodes(); 01095 CPPUNIT_ASSERT( num_vertices == 7 ); 01096 01097 CPPUNIT_ASSERT( tri_check_validity( element_array, num_elements, vtx_array, num_vertices ) == 1 ); 01098 } 01099 01100 int VtkTest::tri_check_validity( const MBMesquite::MsqMeshEntity* element_array, 01101 size_t num_elements, 01102 const MBMesquite::MsqVertex* vtx_array, 01103 size_t num_vertices ) 01104 { 01105 01106 /* check that the simplicial mesh is still valid, 01107 based on right handedness. Returns a 1 or a 0 */ 01108 int valid = 1; 01109 double dEps = 1.e-13; 01110 01111 double x1, x2, x3, y1, y2, y3; // z1, z2, z3; 01112 std::vector< size_t > vertex_indices; 01113 01114 for( size_t i = 0; i < num_elements; i++ ) 01115 { 01116 element_array[i].get_vertex_indices( vertex_indices ); 01117 01118 x1 = vtx_array[vertex_indices[0]][0]; 01119 y1 = vtx_array[vertex_indices[0]][1]; 01120 x2 = vtx_array[vertex_indices[1]][0]; 01121 y2 = vtx_array[vertex_indices[1]][1]; 01122 x3 = vtx_array[vertex_indices[2]][0]; 01123 y3 = vtx_array[vertex_indices[2]][1]; 01124 01125 double a = x2 * y3 - x3 * y2; 01126 double b = y2 - y3; 01127 double c = x3 - x2; 01128 01129 double area = .5 * ( a + b * x1 + c * y1 ); 01130 if( area < dEps ) 01131 { 01132 // printf("x1 y1 = %f %f\n",x1,y1); 01133 // printf("x2 y3 = %f %f\n",x2,y2); 01134 // printf("x3 y3 = %f %f\n",x3,y3); 01135 // printf("area = %f\n",area); 01136 valid = 0; 01137 } 01138 } 01139 01140 return ( valid ); 01141 } 01142 01143 int VtkTest::tet_validity_check( const MBMesquite::MsqMeshEntity* element_array, 01144 size_t num_elements, 01145 const MBMesquite::MsqVertex* vtx_array ) 01146 { 01147 int valid = 1; 01148 double dEps = 1.e-13; 01149 double x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4; 01150 std::vector< size_t > vertex_indices; 01151 01152 for( size_t i = 0; i < num_elements; i++ ) 01153 { 01154 element_array[i].get_vertex_indices( vertex_indices ); 01155 01156 x1 = vtx_array[vertex_indices[0]][0]; 01157 y1 = vtx_array[vertex_indices[0]][1]; 01158 z1 = vtx_array[vertex_indices[0]][2]; 01159 01160 x2 = vtx_array[vertex_indices[1]][0]; 01161 y2 = vtx_array[vertex_indices[1]][1]; 01162 z2 = vtx_array[vertex_indices[1]][2]; 01163 01164 x3 = vtx_array[vertex_indices[2]][0]; 01165 y3 = vtx_array[vertex_indices[2]][1]; 01166 z3 = vtx_array[vertex_indices[2]][2]; 01167 01168 x4 = vtx_array[vertex_indices[3]][0]; 01169 y4 = vtx_array[vertex_indices[3]][1]; 01170 z4 = vtx_array[vertex_indices[3]][2]; 01171 01172 double dDX2 = x2 - x1; 01173 double dDX3 = x3 - x1; 01174 double dDX4 = x4 - x1; 01175 01176 double dDY2 = y2 - y1; 01177 double dDY3 = y3 - y1; 01178 double dDY4 = y4 - y1; 01179 01180 double dDZ2 = z2 - z1; 01181 double dDZ3 = z3 - z1; 01182 double dDZ4 = z4 - z1; 01183 01184 /* dDet is proportional to the cell volume */ 01185 double dDet = dDX2 * dDY3 * dDZ4 + dDX3 * dDY4 * dDZ2 + dDX4 * dDY2 * dDZ3 - dDZ2 * dDY3 * dDX4 - 01186 dDZ3 * dDY4 * dDX2 - dDZ4 * dDY2 * dDX3; 01187 01188 /* Compute a length scale based on edge lengths. */ 01189 double dScale = ( sqrt( ( x1 - x2 ) * ( x1 - x2 ) + ( y1 - y2 ) * ( y1 - y2 ) + ( z1 - z2 ) * ( z1 - z2 ) ) + 01190 sqrt( ( x1 - x3 ) * ( x1 - x3 ) + ( y1 - y3 ) * ( y1 - y3 ) + ( z1 - z3 ) * ( z1 - z3 ) ) + 01191 sqrt( ( x1 - x4 ) * ( x1 - x4 ) + ( y1 - y4 ) * ( y1 - y4 ) + ( z1 - z4 ) * ( z1 - z4 ) ) + 01192 sqrt( ( x2 - x3 ) * ( x2 - x3 ) + ( y2 - y3 ) * ( y2 - y3 ) + ( z2 - z3 ) * ( z2 - z3 ) ) + 01193 sqrt( ( x2 - x4 ) * ( x2 - x4 ) + ( y2 - y4 ) * ( y2 - y4 ) + ( z2 - z4 ) * ( z2 - z4 ) ) + 01194 sqrt( ( x3 - x4 ) * ( x3 - x4 ) + ( y3 - y4 ) * ( y3 - y4 ) + ( z3 - z4 ) * ( z3 - z4 ) ) ) / 01195 6.; 01196 01197 /* Use the length scale to get a better idea if the tet is flat or 01198 just really small. */ 01199 if( fabs( dScale ) < dEps ) 01200 { 01201 return ( valid = 0 ); 01202 } 01203 else 01204 { 01205 dDet /= ( dScale * dScale * dScale ); 01206 } 01207 01208 if( dDet > dEps ) 01209 { 01210 valid = 1; 01211 } 01212 else if( dDet < -dEps ) 01213 { 01214 valid = -1; 01215 } 01216 else 01217 { 01218 valid = 0; 01219 } 01220 } // end for i=1,numElements 01221 01222 return ( valid ); 01223 } 01224 01225 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VtkTest, "VtkTest" ); 01226 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VtkTest, "Unit" ); 01227 01228 #else /* ifndef DEBUG */ 01229 01230 int main() 01231 { 01232 FILE* file; 01233 01234 file = fopen( "2d_structured_points.vtk", "w" ); 01235 fputs( structured_2d_points_data, file ); 01236 fclose( file ); 01237 01238 file = fopen( "3d_structured_points.vtk", "w" ); 01239 fputs( structured_3d_points_data, file ); 01240 fputs( fixed_vertex_attrib, file ); 01241 fclose( file ); 01242 01243 file = fopen( "structured_grid.vtk", "w" ); 01244 fputs( structured_grid_data, file ); 01245 fputs( fixed_vertex_attrib, file ); 01246 fclose( file ); 01247 01248 file = fopen( "rectilinear_grid.vtk", "w" ); 01249 fputs( rectilinear_grid_data, file ); 01250 fputs( fixed_vertex_attrib, file ); 01251 fclose( file ); 01252 01253 file = fopen( "mixed_unstructured.vtk", "w" ); 01254 fputs( mixed_unstructured_data, file ); 01255 fclose( file ); 01256 01257 file = fopen( "quadratic.vtk", "w" ); 01258 fputs( quadratic_unstructured_data, file ); 01259 fclose( file ); 01260 01261 return 0; 01262 } 01263 #endif