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 [email protected] 00026 00027 ***************************************************************** */ 00028 /** 00029 *\file MeshImplTest.hpp 00030 *\brief Test MeshImpl class 00031 * 00032 * Test MeshImpl functionality. 00033 * 00034 * Note: there are additional tests for MeshImpl in the mis-named 00035 * MeshInterfaceTest.cpp, VtkTest.cpp, and presumably ExodusTest.cpp. 00036 * 00037 *\author Jason Kraftcheck 00038 *\date 2007-10-18 00039 */ 00040 00041 #include "Mesquite.hpp" 00042 #include "MeshImpl.hpp" 00043 #include "MsqError.hpp" 00044 #include "MsqVertex.hpp" 00045 00046 #include "UnitUtil.hpp" 00047 00048 #include <iostream> 00049 #include <cstdio> 00050 00051 using namespace MBMesquite; 00052 00053 const bool DUMP_MESH = false; 00054 00055 class MeshImplTest : public CppUnit::TestFixture 00056 { 00057 public: 00058 CPPUNIT_TEST_SUITE( MeshImplTest ); 00059 CPPUNIT_TEST( test_zero_length_data ); 00060 CPPUNIT_TEST( skin_mesh_2D ); 00061 CPPUNIT_TEST( skin_mesh_3D ); 00062 CPPUNIT_TEST( skin_mesh_mixed ); 00063 CPPUNIT_TEST( skin_mesh_higher_order ); 00064 CPPUNIT_TEST_SUITE_END(); 00065 00066 void test_zero_length_data(); 00067 void skin_mesh_2D(); 00068 void skin_mesh_3D(); 00069 void skin_mesh_mixed(); 00070 void skin_mesh_higher_order(); 00071 00072 static void load_vtk( const char* file_data, MeshImpl& mesh, MsqError& err ); 00073 static void dump_mesh( const char* filename, MeshImpl& data, MsqError& err ); 00074 }; 00075 00076 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MeshImplTest, "MeshImplTest" ); 00077 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MeshImplTest, "Unit" ); 00078 00079 void MeshImplTest::load_vtk( const char* file_data, MeshImpl& mesh, MsqError& err ) 00080 { 00081 const char* fname = "MeshImplTest.vtk"; 00082 FILE* f = fopen( fname, "w" ); 00083 if( !f ) 00084 { 00085 MSQ_SETERR( err )( MsqError::FILE_ACCESS, "Cannot create temp file: %s\n", fname ); 00086 return; 00087 } 00088 00089 if( !fwrite( file_data, strlen( file_data ), 1, f ) ) 00090 { 00091 MSQ_SETERR( err )( "I/O error while writing temporary file\n", MsqError::IO_ERROR ); 00092 fclose( f ); 00093 remove( fname ); 00094 return; 00095 } 00096 00097 fclose( f ); 00098 mesh.read_vtk( fname, err );MSQ_CHKERR( err ); 00099 remove( fname ); 00100 00101 mesh.mark_skin_fixed( err );MSQ_CHKERR( err ); 00102 } 00103 00104 void MeshImplTest::dump_mesh( const char* filename, MeshImpl& mesh, MsqError& err ) 00105 { 00106 if( DUMP_MESH ) 00107 { 00108 mesh.write_vtk( filename, err ); 00109 if( MSQ_CHKERR( err ) ) std::cerr << err << std::endl; 00110 } 00111 } 00112 00113 void MeshImplTest::test_zero_length_data() 00114 { 00115 const size_t num_vtx = 2, zero = 0; 00116 const double coords[3 * num_vtx] = { 0, 0, 0, 1, 1, 1 }; 00117 const bool fixed[num_vtx] = { false, false }; 00118 std::vector< Mesh::ElementHandle > elems; 00119 std::vector< Mesh::VertexHandle > verts; 00120 MsqError err; 00121 const int conn[6] = { 0, 1, 0, 1, 0, 1 }; 00122 EntityTopology type = TRIANGLE; 00123 00124 MeshImpl no_elem1( 2, 0, TRIANGLE, fixed, coords, 0 ); 00125 verts.clear(); 00126 no_elem1.get_all_vertices( verts, err ); 00127 ASSERT_NO_ERROR( err ); 00128 CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() ); 00129 elems.clear(); 00130 no_elem1.get_all_elements( elems, err ); 00131 ASSERT_NO_ERROR( err ); 00132 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00133 00134 MeshImpl no_elem2( 2, 0, 0, fixed, coords, 0 ); 00135 verts.clear(); 00136 no_elem2.get_all_vertices( verts, err ); 00137 ASSERT_NO_ERROR( err ); 00138 CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() ); 00139 elems.clear(); 00140 no_elem2.get_all_elements( elems, err ); 00141 ASSERT_NO_ERROR( err ); 00142 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00143 00144 MeshImpl no_elem3( 2, 0, TRIANGLE, fixed, coords, conn ); 00145 verts.clear(); 00146 no_elem3.get_all_vertices( verts, err ); 00147 ASSERT_NO_ERROR( err ); 00148 CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() ); 00149 elems.clear(); 00150 no_elem3.get_all_elements( elems, err ); 00151 ASSERT_NO_ERROR( err ); 00152 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00153 00154 MeshImpl no_elem4( 2, 0, &type, fixed, coords, conn ); 00155 verts.clear(); 00156 no_elem4.get_all_vertices( verts, err ); 00157 ASSERT_NO_ERROR( err ); 00158 CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() ); 00159 elems.clear(); 00160 no_elem4.get_all_elements( elems, err ); 00161 ASSERT_NO_ERROR( err ); 00162 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00163 00164 MeshImpl no_vert1( 0, 0, TRIANGLE, 0, 0, 0 ); 00165 verts.clear(); 00166 no_vert1.get_all_vertices( verts, err ); 00167 ASSERT_NO_ERROR( err ); 00168 CPPUNIT_ASSERT_EQUAL( zero, verts.size() ); 00169 elems.clear(); 00170 no_vert1.get_all_elements( elems, err ); 00171 ASSERT_NO_ERROR( err ); 00172 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00173 00174 MeshImpl no_vert2( 0, 0, 0, 0, 0, 0 ); 00175 verts.clear(); 00176 no_vert2.get_all_vertices( verts, err ); 00177 ASSERT_NO_ERROR( err ); 00178 CPPUNIT_ASSERT_EQUAL( zero, verts.size() ); 00179 elems.clear(); 00180 no_vert2.get_all_elements( elems, err ); 00181 ASSERT_NO_ERROR( err ); 00182 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00183 00184 MeshImpl no_vert3( 0, 0, TRIANGLE, fixed, coords, 0 ); 00185 verts.clear(); 00186 no_vert3.get_all_vertices( verts, err ); 00187 ASSERT_NO_ERROR( err ); 00188 CPPUNIT_ASSERT_EQUAL( zero, verts.size() ); 00189 elems.clear(); 00190 no_vert3.get_all_elements( elems, err ); 00191 ASSERT_NO_ERROR( err ); 00192 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00193 00194 MeshImpl no_vert4( 0, 0, 0, fixed, coords, 0 ); 00195 verts.clear(); 00196 no_vert4.get_all_vertices( verts, err ); 00197 ASSERT_NO_ERROR( err ); 00198 CPPUNIT_ASSERT_EQUAL( zero, verts.size() ); 00199 elems.clear(); 00200 no_vert4.get_all_elements( elems, err ); 00201 ASSERT_NO_ERROR( err ); 00202 CPPUNIT_ASSERT_EQUAL( zero, elems.size() ); 00203 } 00204 00205 void MeshImplTest::skin_mesh_2D() 00206 { 00207 MsqPrintError err( std::cerr ); 00208 const char vtk_file[] = "#vtk DataFile Version 2.0\n" 00209 "test data for MeshImplTest::skin_mesh_2D\n" 00210 "ASCII\n" 00211 "DATASET STRUCTURED_POINTS\n" 00212 "DIMENSIONS 10 10 1\n" 00213 "ORIGIN 0 0 0\n" 00214 "SPACING 1 1 1\n"; 00215 00216 MeshImpl mesh; 00217 load_vtk( vtk_file, mesh, err ); 00218 CPPUNIT_ASSERT( !err ); 00219 dump_mesh( "MeshSkin2D.vtk", mesh, err ); 00220 00221 std::vector< Mesh::VertexHandle > verts; 00222 mesh.get_all_vertices( verts, err ); 00223 CPPUNIT_ASSERT( !err ); 00224 00225 std::vector< Mesh::VertexHandle > elems; 00226 std::vector< size_t > offsets; 00227 std::vector< bool > fixed; 00228 00229 for( unsigned i = 0; i < verts.size(); ++i ) 00230 { 00231 elems.clear(); 00232 offsets.clear(); 00233 mesh.vertices_get_attached_elements( &verts[i], 1, elems, offsets, err ); 00234 CPPUNIT_ASSERT( !err ); 00235 00236 mesh.vertices_get_fixed_flag( &verts[i], fixed, 1, err ); 00237 CPPUNIT_ASSERT( !err ); 00238 00239 if( elems.size() == 4 ) 00240 CPPUNIT_ASSERT( !fixed[0] ); 00241 else 00242 CPPUNIT_ASSERT( fixed[0] ); 00243 } 00244 } 00245 00246 void MeshImplTest::skin_mesh_3D() 00247 { 00248 MsqPrintError err( std::cerr ); 00249 const char vtk_file[] = "#vtk DataFile Version 2.0\n" 00250 "test data for MeshImplTest::skin_mesh_3D\n" 00251 "ASCII\n" 00252 "DATASET STRUCTURED_POINTS\n" 00253 "DIMENSIONS 10 10 10\n" 00254 "ORIGIN 0 0 0\n" 00255 "SPACING 1 1 1\n"; 00256 00257 MeshImpl mesh; 00258 load_vtk( vtk_file, mesh, err ); 00259 CPPUNIT_ASSERT( !err ); 00260 dump_mesh( "MeshSkin3D.vtk", mesh, err ); 00261 00262 std::vector< Mesh::VertexHandle > verts; 00263 mesh.get_all_vertices( verts, err ); 00264 CPPUNIT_ASSERT( !err ); 00265 00266 std::vector< Mesh::VertexHandle > elems; 00267 std::vector< size_t > offsets; 00268 std::vector< bool > fixed; 00269 00270 for( unsigned i = 0; i < verts.size(); ++i ) 00271 { 00272 elems.clear(); 00273 offsets.clear(); 00274 mesh.vertices_get_attached_elements( &verts[i], 1, elems, offsets, err ); 00275 CPPUNIT_ASSERT( !err ); 00276 00277 mesh.vertices_get_fixed_flag( &verts[i], fixed, 1, err ); 00278 CPPUNIT_ASSERT( !err ); 00279 00280 if( elems.size() == 8 ) 00281 CPPUNIT_ASSERT( !fixed[0] ); 00282 else 00283 CPPUNIT_ASSERT( fixed[0] ); 00284 } 00285 } 00286 00287 // Make sure that if we have a volume mesh with one interior 00288 // face that the vertices on that face are not marked as fixed 00289 // due soley to the fact that there are no adjacent faces. 00290 // That is, the iterior face doesn't 'count' because it is the 00291 // side of a volume element. 00292 void MeshImplTest::skin_mesh_mixed() 00293 { 00294 MsqPrintError err( std::cerr ); 00295 // define the mesh of a tetrahedron centered 00296 // at the origin as four tetrahedral elements 00297 // sharing a vertex at the origin. 00298 const char vtk_file[] = "#vtk DataFile Version 2.0\n" 00299 "test data for MeshImplTest::skin_mesh_mixed\n" 00300 "ASCII\n" 00301 "DATASET UNSTRUCTURED_GRID\n" 00302 "POINTS 5 float\n" 00303 " 0 0 0\n" // center vertex 00304 " 2 -1 -1\n" 00305 " 0 2 -1\n" 00306 "-2 -1 -1\n" 00307 " 0 0 2\n" 00308 "CELLS 5 24\n" 00309 "4 1 2 3 0\n" 00310 "4 1 3 4 0\n" 00311 "4 4 2 1 0\n" 00312 "4 4 3 2 0\n" 00313 "3 0 1 2\n" // iterior triangle 00314 "CELL_TYPES 5\n" 00315 "10 10 10 10 5\n"; 00316 00317 MeshImpl mesh; 00318 load_vtk( vtk_file, mesh, err ); 00319 CPPUNIT_ASSERT( !err ); 00320 dump_mesh( "MeshSkinMixed.vtk", mesh, err ); 00321 00322 std::vector< Mesh::VertexHandle > verts; 00323 mesh.get_all_vertices( verts, err ); 00324 CPPUNIT_ASSERT( !err ); 00325 CPPUNIT_ASSERT_EQUAL( 5u, (unsigned)verts.size() ); 00326 MsqVertex coords[5]; 00327 mesh.vertices_get_coordinates( arrptr( verts ), coords, 5, err ); 00328 CPPUNIT_ASSERT( !err ); 00329 std::vector< bool > fixed; 00330 mesh.vertices_get_fixed_flag( arrptr( verts ), fixed, 5, err ); 00331 CPPUNIT_ASSERT( !err ); 00332 CPPUNIT_ASSERT_EQUAL( (size_t)5, fixed.size() ); 00333 00334 int free_idx = -1; 00335 for( int i = 0; i < 5; ++i ) 00336 { 00337 if( !fixed[i] ) 00338 { 00339 CPPUNIT_ASSERT_EQUAL( -1, free_idx ); // at most 1 free vertex 00340 free_idx = i; 00341 } 00342 } 00343 CPPUNIT_ASSERT( -1 != free_idx ); // at least one free vertex 00344 00345 // free vertex must be at origin 00346 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 0, 0, 0 ), coords[free_idx], DBL_EPSILON ); 00347 } 00348 00349 void MeshImplTest::skin_mesh_higher_order() 00350 { 00351 MsqPrintError err( std::cerr ); 00352 // define a simple 2-quad mesh: 00353 // 00354 // 0 1 2 3 4 00355 // o----o----o----o----o 00356 // | | | 00357 // | | | 00358 // o5 o6 o7 00359 // | | | 00360 // | | | 00361 // o----o----o----o----o 00362 // 8 9 10 11 12 00363 // 00364 // Expect all vertices but 6 to be fixed. 00365 // Position mesh such that vertex 6 is at the origin. 00366 00367 const char vtk_file[] = "#vtk DataFile Version 2.0\n" 00368 "test data for MeshImplTest::skin_mesh_mixed\n" 00369 "ASCII\n" 00370 "DATASET UNSTRUCTURED_GRID\n" 00371 "POINTS 13 float\n" 00372 "-2 1 0\n" 00373 "-1 1 0\n" 00374 " 0 1 0\n" 00375 " 1 1 0\n" 00376 " 2 1 0\n" 00377 "-2 0 0\n" 00378 " 0 0 0\n" 00379 " 2 0 0\n" 00380 "-2 -1 0\n" 00381 "-1 -1 0\n" 00382 " 0 -1 0\n" 00383 " 1 -1 0\n" 00384 " 2 -1 0\n" 00385 "CELLS 2 18\n" 00386 "8 0 8 10 2 5 9 6 1\n" 00387 "8 2 10 12 4 6 11 7 3\n" 00388 "CELL_TYPES 2\n" 00389 "23 23\n"; 00390 00391 MeshImpl mesh; 00392 load_vtk( vtk_file, mesh, err ); 00393 CPPUNIT_ASSERT( !err ); 00394 dump_mesh( "MeshSkinHO.vtk", mesh, err ); 00395 00396 std::vector< Mesh::VertexHandle > verts; 00397 mesh.get_all_vertices( verts, err ); 00398 CPPUNIT_ASSERT( !err ); 00399 CPPUNIT_ASSERT_EQUAL( 13u, (unsigned)verts.size() ); 00400 MsqVertex coords[13]; 00401 mesh.vertices_get_coordinates( arrptr( verts ), coords, 13, err ); 00402 CPPUNIT_ASSERT( !err ); 00403 std::vector< bool > fixed; 00404 mesh.vertices_get_fixed_flag( arrptr( verts ), fixed, 13, err ); 00405 CPPUNIT_ASSERT( !err ); 00406 CPPUNIT_ASSERT_EQUAL( (size_t)13, fixed.size() ); 00407 00408 int free_idx = -1; 00409 for( int i = 0; i < 13; ++i ) 00410 { 00411 if( !fixed[i] ) 00412 { 00413 CPPUNIT_ASSERT_EQUAL( -1, free_idx ); // at most 1 free vertex 00414 free_idx = i; 00415 } 00416 } 00417 CPPUNIT_ASSERT( -1 != free_idx ); // at least one free vertex 00418 00419 // free vertex must be at origin 00420 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 0, 0, 0 ), coords[free_idx], DBL_EPSILON ); 00421 }