Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #include "TestRunner.hpp" 00002 #include "iMesh.h" 00003 #include "MBiMesh.hpp" 00004 #include "moab/Core.hpp" 00005 #include <algorithm> 00006 00007 iMesh_Instance create_mesh(); 00008 00009 void test_getEntArrAdj_conn(); 00010 void test_getEntArrAdj_vertex(); 00011 void test_getEntArrAdj_up(); 00012 void test_getEntArrAdj_down(); 00013 void test_getEntArrAdj_invalid_size(); 00014 void test_getEntArrAdj_none(); 00015 void test_existinterface(); 00016 void test_tags_retrieval(); 00017 void test_invalid_parallel_option(); 00018 00019 int main( int argc, char* argv[] ) 00020 { 00021 REGISTER_TEST( test_getEntArrAdj_conn ); 00022 REGISTER_TEST( test_getEntArrAdj_vertex ); 00023 REGISTER_TEST( test_getEntArrAdj_up ); 00024 REGISTER_TEST( test_getEntArrAdj_down ); 00025 REGISTER_TEST( test_getEntArrAdj_invalid_size ); 00026 REGISTER_TEST( test_getEntArrAdj_none ); 00027 REGISTER_TEST( test_existinterface ); 00028 #ifdef MOAB_HAVE_HDF5 00029 REGISTER_TEST( test_tags_retrieval ); 00030 #endif 00031 #ifndef MOAB_HAVE_MPI 00032 REGISTER_TEST( test_invalid_parallel_option ); 00033 #endif 00034 int result = RUN_TESTS( argc, argv ); 00035 00036 // Delete the static iMesh instance defined in create_mesh() 00037 iMesh_Instance mesh = create_mesh(); 00038 int err; 00039 iMesh_dtor( mesh, &err ); 00040 CHECK_EQUAL( iBase_SUCCESS, err ); 00041 00042 return result; 00043 } 00044 00045 // INTERVAL x INTERVAL x INTERVAL regular hex mesh with skin faces. 00046 // Vertices are located at even coordinate 00047 // values and adjacent vertices are separated by one unit. The entire 00048 // grid is in the first octant with the first vertex at the origin. 00049 // Faces are grouped by the side of the grid that they occur in. 00050 // The faces are { -Y, X, Y, -X, -Z, Z }. 00051 const int INTERVALS = 2; 00052 iBase_EntityHandle VERTS[INTERVALS + 1][INTERVALS + 1][INTERVALS + 1]; 00053 iBase_EntityHandle HEXES[INTERVALS][INTERVALS][INTERVALS]; 00054 iBase_EntityHandle FACES[6][INTERVALS][INTERVALS]; 00055 00056 static void HEX_VERTS( int i, int j, int k, iBase_EntityHandle conn[8] ) 00057 { 00058 conn[0] = VERTS[i][j][k]; 00059 conn[1] = VERTS[i + 1][j][k]; 00060 conn[2] = VERTS[i + 1][j + 1][k]; 00061 conn[3] = VERTS[i][j + 1][k]; 00062 conn[4] = VERTS[i][j][k + 1]; 00063 conn[5] = VERTS[i + 1][j][k + 1]; 00064 conn[6] = VERTS[i + 1][j + 1][k + 1]; 00065 conn[7] = VERTS[i][j + 1][k + 1]; 00066 } 00067 00068 static void QUAD_VERTS( int f, int i, int j, iBase_EntityHandle conn[4] ) 00069 { 00070 switch( f ) 00071 { 00072 case 0: 00073 case 2: 00074 conn[0] = VERTS[i][INTERVALS * ( f / 2 )][j]; 00075 conn[1] = VERTS[i + 1][INTERVALS * ( f / 2 )][j]; 00076 conn[2] = VERTS[i + 1][INTERVALS * ( f / 2 )][j + 1]; 00077 conn[3] = VERTS[i][INTERVALS * ( f / 2 )][j + 1]; 00078 break; 00079 case 1: 00080 case 3: 00081 conn[0] = VERTS[INTERVALS * ( 1 / f )][i][j]; 00082 conn[1] = VERTS[INTERVALS * ( 1 / f )][i + 1][j]; 00083 conn[2] = VERTS[INTERVALS * ( 1 / f )][i + 1][j + 1]; 00084 conn[3] = VERTS[INTERVALS * ( 1 / f )][i][j + 1]; 00085 break; 00086 case 4: 00087 case 5: 00088 conn[0] = VERTS[i][j][INTERVALS * ( f - 4 )]; 00089 conn[1] = VERTS[i + 1][j][INTERVALS * ( f - 4 )]; 00090 conn[2] = VERTS[i + 1][j + 1][INTERVALS * ( f - 4 )]; 00091 conn[3] = VERTS[i][j + 1][INTERVALS * ( f - 4 )]; 00092 break; 00093 default: 00094 CHECK( false ); 00095 } 00096 } 00097 00098 iMesh_Instance create_mesh() 00099 { 00100 static iMesh_Instance instance = 0; 00101 if( instance ) return instance; 00102 00103 int err; 00104 iMesh_Instance tmp; 00105 iMesh_newMesh( 0, &tmp, &err, 0 ); 00106 CHECK_EQUAL( iBase_SUCCESS, err ); 00107 00108 for( int i = 0; i < INTERVALS + 1; ++i ) 00109 for( int j = 0; j < INTERVALS + 1; ++j ) 00110 for( int k = 0; k < INTERVALS + 1; ++k ) 00111 { 00112 iMesh_createVtx( tmp, i, j, k, &VERTS[i][j][k], &err ); 00113 CHECK_EQUAL( iBase_SUCCESS, err ); 00114 } 00115 00116 int status; 00117 iBase_EntityHandle conn[8]; 00118 for( int i = 0; i < INTERVALS; ++i ) 00119 for( int j = 0; j < INTERVALS; ++j ) 00120 for( int k = 0; k < INTERVALS; ++k ) 00121 { 00122 HEX_VERTS( i, j, k, conn ); 00123 iMesh_createEnt( tmp, iMesh_HEXAHEDRON, conn, 8, &HEXES[i][j][k], &status, &err ); 00124 CHECK_EQUAL( iBase_SUCCESS, err ); 00125 CHECK_EQUAL( iBase_NEW, status ); 00126 } 00127 00128 for( int f = 0; f < 6; ++f ) 00129 for( int i = 0; i < INTERVALS; ++i ) 00130 for( int j = 0; j < INTERVALS; ++j ) 00131 { 00132 QUAD_VERTS( f, i, j, conn ); 00133 iMesh_createEnt( tmp, iMesh_QUADRILATERAL, conn, 4, &FACES[f][i][j], &status, &err ); 00134 CHECK_EQUAL( iBase_SUCCESS, err ); 00135 } 00136 00137 return ( instance = tmp ); 00138 } 00139 00140 void test_getEntArrAdj_conn() 00141 { 00142 iMesh_Instance mesh = create_mesh(); 00143 int err; 00144 00145 // test hex vertices 00146 for( int i = 0; i < INTERVALS; ++i ) 00147 { 00148 for( int j = 0; j < INTERVALS; ++j ) 00149 { 00150 iBase_EntityHandle adj[8 * INTERVALS]; 00151 int off[INTERVALS + 1]; 00152 int adj_alloc = sizeof( adj ) / sizeof( adj[0] ); 00153 int off_alloc = sizeof( off ) / sizeof( off[0] ); 00154 int adj_size = -1, off_size = -1; 00155 iBase_EntityHandle* adj_ptr = adj; 00156 int* off_ptr = off; 00157 iMesh_getEntArrAdj( mesh, HEXES[i][j], INTERVALS, iBase_VERTEX, &adj_ptr, &adj_alloc, &adj_size, &off_ptr, 00158 &off_alloc, &off_size, &err ); 00159 CHECK_EQUAL( &adj[0], adj_ptr ); 00160 CHECK_EQUAL( &off[0], off_ptr ); 00161 CHECK_EQUAL( iBase_SUCCESS, err ); 00162 CHECK_EQUAL( 8 * INTERVALS, adj_size ); 00163 CHECK_EQUAL( 8 * INTERVALS, adj_alloc ); 00164 CHECK_EQUAL( INTERVALS + 1, off_size ); 00165 CHECK_EQUAL( INTERVALS + 1, off_alloc ); 00166 for( int k = 0; k < INTERVALS; ++k ) 00167 { 00168 CHECK_EQUAL( 8 * k, off[k] ); 00169 iBase_EntityHandle conn[8]; 00170 HEX_VERTS( i, j, k, conn ); 00171 CHECK_ARRAYS_EQUAL( conn, 8, adj + off[k], off[k + 1] - off[k] ); 00172 } 00173 } 00174 } 00175 00176 // test quad vertices for one side of mesh 00177 const int f = 0; 00178 for( int i = 0; i < INTERVALS; ++i ) 00179 { 00180 iBase_EntityHandle adj[4 * INTERVALS]; 00181 int off[INTERVALS + 1]; 00182 int adj_alloc = sizeof( adj ) / sizeof( adj[0] ); 00183 int off_alloc = sizeof( off ) / sizeof( off[0] ); 00184 int adj_size = -1, off_size = -1; 00185 iBase_EntityHandle* adj_ptr = adj; 00186 int* off_ptr = off; 00187 iMesh_getEntArrAdj( mesh, FACES[f][i], INTERVALS, iBase_VERTEX, &adj_ptr, &adj_alloc, &adj_size, &off_ptr, 00188 &off_alloc, &off_size, &err ); 00189 CHECK_EQUAL( &adj[0], adj_ptr ); 00190 CHECK_EQUAL( &off[0], off_ptr ); 00191 CHECK_EQUAL( iBase_SUCCESS, err ); 00192 CHECK_EQUAL( 4 * INTERVALS, adj_size ); 00193 CHECK_EQUAL( 4 * INTERVALS, adj_alloc ); 00194 CHECK_EQUAL( INTERVALS + 1, off_size ); 00195 CHECK_EQUAL( INTERVALS + 1, off_alloc ); 00196 for( int k = 0; k < INTERVALS; ++k ) 00197 { 00198 CHECK_EQUAL( 4 * k, off[k] ); 00199 iBase_EntityHandle conn[4]; 00200 QUAD_VERTS( f, i, k, conn ); 00201 CHECK_ARRAYS_EQUAL( conn, 4, adj + off[k], off[k + 1] - off[k] ); 00202 } 00203 } 00204 } 00205 00206 void test_getEntArrAdj_vertex() 00207 { 00208 iMesh_Instance mesh = create_mesh(); 00209 int err; 00210 00211 // get hexes adjacent to row of vertices at x=0,y=0; 00212 iBase_EntityHandle* adj = 0; 00213 int* off = 0; 00214 int adj_alloc = 0, off_alloc = 0; 00215 int adj_size = -1, off_size = -1; 00216 iMesh_getEntArrAdj( mesh, VERTS[0][0], INTERVALS + 1, iBase_REGION, &adj, &adj_alloc, &adj_size, &off, &off_alloc, 00217 &off_size, &err ); 00218 CHECK_EQUAL( iBase_SUCCESS, err ); 00219 CHECK( 0 != adj ); 00220 CHECK( 0 != off ); 00221 CHECK_EQUAL( 2 * INTERVALS, 00222 adj_size ); // INTERVALS+1 verts, end ones with one hex, others with two 00223 CHECK_EQUAL( INTERVALS + 2, off_size ); // one more than number of input handles 00224 CHECK( adj_alloc >= adj_size ); 00225 CHECK( off_alloc >= off_size ); 00226 00227 // first and last vertices should have one adjacent hex 00228 CHECK_EQUAL( 1, off[1] - off[0] ); 00229 CHECK_EQUAL( HEXES[0][0][0], adj[off[0]] ); 00230 CHECK_EQUAL( 1, off[INTERVALS + 1] - off[INTERVALS] ); 00231 CHECK_EQUAL( HEXES[0][0][INTERVALS - 1], adj[off[INTERVALS]] ); 00232 // middle ones should have two adjacent hexes 00233 for( int i = 1; i < INTERVALS; ++i ) 00234 { 00235 CHECK_EQUAL( 2, off[i + 1] - off[i] ); 00236 CHECK_EQUAL( HEXES[0][0][i - 1], adj[off[i]] ); 00237 CHECK_EQUAL( HEXES[0][0][i], adj[off[i] + 1] ); 00238 } 00239 00240 free( adj ); 00241 free( off ); 00242 } 00243 00244 void test_getEntArrAdj_up() 00245 { 00246 iMesh_Instance mesh = create_mesh(); 00247 int err; 00248 00249 // get hexes adjacent to a row of faces in the z=0 plane 00250 iBase_EntityHandle* adj = 0; 00251 int* off = 0; 00252 int adj_alloc = 0, off_alloc = 0; 00253 int adj_size = -1, off_size = -1; 00254 iMesh_getEntArrAdj( mesh, FACES[4][0], INTERVALS, iBase_REGION, &adj, &adj_alloc, &adj_size, &off, &off_alloc, 00255 &off_size, &err ); 00256 CHECK_EQUAL( iBase_SUCCESS, err ); 00257 CHECK( 0 != adj ); 00258 CHECK( 0 != off ); 00259 CHECK_EQUAL( INTERVALS, adj_size ); // one hex adjacent to each skin face 00260 CHECK_EQUAL( INTERVALS + 1, off_size ); // one more than number of input handles 00261 CHECK( adj_alloc >= adj_size ); 00262 CHECK( off_alloc >= off_size ); 00263 00264 for( int i = 0; i < INTERVALS; ++i ) 00265 { 00266 CHECK_EQUAL( 1, off[i + 1] - off[i] ); 00267 CHECK_EQUAL( HEXES[0][i][0], adj[off[i]] ); 00268 } 00269 00270 free( adj ); 00271 free( off ); 00272 } 00273 00274 void test_getEntArrAdj_down() 00275 { 00276 iMesh_Instance mesh = create_mesh(); 00277 int err; 00278 00279 // get quads adjacent to a edge-row of hexes 00280 iBase_EntityHandle* adj = 0; 00281 int* off = 0; 00282 int adj_alloc = 0, off_alloc = 0; 00283 int adj_size = -1, off_size = -1; 00284 iMesh_getEntArrAdj( mesh, HEXES[0][0], INTERVALS, iBase_FACE, &adj, &adj_alloc, &adj_size, &off, &off_alloc, 00285 &off_size, &err ); 00286 CHECK_EQUAL( iBase_SUCCESS, err ); 00287 CHECK( 0 != adj ); 00288 CHECK( 0 != off ); 00289 CHECK_EQUAL( 2 * INTERVALS + 2, adj_size ); // corner hexes adj to 3 faces, others adj to 2 00290 CHECK_EQUAL( INTERVALS + 1, off_size ); // one more than number of input handles 00291 CHECK( adj_alloc >= adj_size ); 00292 CHECK( off_alloc >= off_size ); 00293 00294 // first (corner) hex should have three adjacent faces 00295 CHECK_EQUAL( 3, off[1] - off[0] ); 00296 iBase_EntityHandle exp[3] = { FACES[0][0][0], FACES[3][0][0], FACES[4][0][0] }; 00297 iBase_EntityHandle act[3]; 00298 std::copy( adj + off[0], adj + off[1], act ); 00299 std::sort( exp, exp + 3 ); 00300 std::sort( act, act + 3 ); 00301 CHECK_ARRAYS_EQUAL( exp, 3, act, 3 ); 00302 00303 // last (corner) hex should have three adjacent faces 00304 CHECK_EQUAL( 3, off[INTERVALS] - off[INTERVALS - 1] ); 00305 iBase_EntityHandle exp2[3] = { FACES[0][0][INTERVALS - 1], FACES[3][0][INTERVALS - 1], FACES[5][0][0] }; 00306 std::copy( adj + off[INTERVALS - 1], adj + off[INTERVALS], act ); 00307 std::sort( exp2, exp2 + 3 ); 00308 std::sort( act, act + 3 ); 00309 CHECK_ARRAYS_EQUAL( exp2, 3, act, 3 ); 00310 00311 // all middle hexes should have two adjacent faces 00312 // FixME: This loop is never executed (INTERVALS is 2) 00313 /* 00314 for (int i = 1; i < INTERVALS-1; ++i) { 00315 iBase_EntityHandle e1, e2, a1, a2; 00316 e1 = FACES[0][0][i]; 00317 e2 = FACES[3][0][i]; 00318 if (e1 > e2) std::swap(e1,e2); 00319 00320 CHECK_EQUAL( 2, off[i+1] - off[i] ); 00321 a1 = adj[off[i] ]; 00322 a2 = adj[off[i]+1]; 00323 if (a1 > a2) std::swap(a1,a2); 00324 00325 CHECK_EQUAL( e1, a1 ); 00326 CHECK_EQUAL( e2, a2 ); 00327 } 00328 */ 00329 00330 free( adj ); 00331 free( off ); 00332 } 00333 00334 void test_getEntArrAdj_invalid_size() 00335 { 00336 iMesh_Instance mesh = create_mesh(); 00337 int err = -1; 00338 00339 const int SPECIAL1 = 0xDeadBeef; 00340 const int SPECIAL2 = 0xCafe5; 00341 const int SPECIAL3 = 0xbabb1e; 00342 00343 // test a downward query 00344 volatile int marker1 = SPECIAL1; 00345 iBase_EntityHandle adj1[8 * INTERVALS - 1]; // one too small 00346 volatile int marker2 = SPECIAL2; 00347 int off1[INTERVALS + 1]; 00348 int adj1_alloc = sizeof( adj1 ) / sizeof( adj1[0] ); 00349 int off1_alloc = sizeof( off1 ) / sizeof( off1[0] ); 00350 int adj_size, off_size; 00351 iBase_EntityHandle* adj_ptr = adj1; 00352 int* off_ptr = off1; 00353 iMesh_getEntArrAdj( mesh, HEXES[0][0], INTERVALS, iBase_VERTEX, &adj_ptr, &adj1_alloc, &adj_size, &off_ptr, 00354 &off1_alloc, &off_size, &err ); 00355 CHECK_EQUAL( &adj1[0], adj_ptr ); 00356 CHECK_EQUAL( &off1[0], off_ptr ); 00357 // first ensure no stack corruption from writing off end of array 00358 CHECK_EQUAL( SPECIAL1, marker1 ); 00359 CHECK_EQUAL( SPECIAL2, marker2 ); 00360 // now verify that it correctly failed 00361 CHECK_EQUAL( iBase_BAD_ARRAY_SIZE, err ); 00362 00363 // now test an upwards query 00364 volatile int marker3 = SPECIAL3; 00365 int off2[INTERVALS]; 00366 volatile int marker4 = SPECIAL1; 00367 int off2_alloc = sizeof( off2 ) / sizeof( off2[0] ); 00368 err = iBase_SUCCESS; 00369 adj_ptr = adj1; 00370 off_ptr = off2; 00371 iMesh_getEntArrAdj( mesh, VERTS[0][0], INTERVALS + 1, iBase_REGION, &adj_ptr, &adj1_alloc, &adj_size, &off_ptr, 00372 &off2_alloc, &off_size, &err ); 00373 // first ensure no stack corruption from writing off end of array 00374 CHECK_EQUAL( &adj1[0], adj_ptr ); 00375 CHECK_EQUAL( &off2[0], off_ptr ); 00376 CHECK_EQUAL( SPECIAL3, marker3 ); 00377 CHECK_EQUAL( SPECIAL1, marker4 ); 00378 // now verify that it correctly failed 00379 CHECK_EQUAL( iBase_BAD_ARRAY_SIZE, err ); 00380 } 00381 00382 void test_getEntArrAdj_none() 00383 { 00384 iMesh_Instance mesh = create_mesh(); 00385 int err = -1; 00386 00387 iBase_EntityHandle* adj = 0; 00388 int* off = 0; 00389 int adj_alloc = 0, off_alloc = 0; 00390 int adj_size = -1, off_size = -1; 00391 iMesh_getEntArrAdj( mesh, NULL, 0, iBase_REGION, &adj, &adj_alloc, &adj_size, &off, &off_alloc, &off_size, &err ); 00392 CHECK_EQUAL( iBase_SUCCESS, err ); 00393 CHECK_EQUAL( 0, adj_alloc ); 00394 CHECK_EQUAL( 0, adj_size ); 00395 CHECK_EQUAL( 1, off_size ); 00396 CHECK( off_alloc >= 1 ); 00397 CHECK_EQUAL( 0, off[0] ); 00398 00399 free( off ); 00400 } 00401 00402 void test_existinterface() 00403 { 00404 // test construction of an imesh instance from a core instance 00405 moab::Core* core = new moab::Core(); 00406 MBiMesh* mesh = new MBiMesh( core ); 00407 iMesh_Instance imesh = reinterpret_cast< iMesh_Instance >( mesh ); 00408 00409 // make sure we can call imesh functions 00410 int dim, err; 00411 iMesh_getGeometricDimension( imesh, &dim, &err ); 00412 CHECK_EQUAL( iBase_SUCCESS, err ); 00413 00414 // now make sure we can delete the instance without it deleting the MOAB instance 00415 iMesh_dtor( imesh, &err ); 00416 CHECK_EQUAL( err, iBase_SUCCESS ); 00417 00418 ErrorCode rval = core->get_number_entities_by_dimension( 0, 0, dim ); 00419 CHECK_EQUAL( moab::MB_SUCCESS, rval ); 00420 00421 // finally, delete the MOAB instance 00422 delete core; 00423 } 00424 00425 void test_tags_retrieval() 00426 { 00427 iMesh_Instance mesh; 00428 int err; 00429 iMesh_newMesh( "", &mesh, &err, 0 ); 00430 CHECK_EQUAL( iBase_SUCCESS, err ); 00431 00432 iBase_EntitySetHandle root_set; 00433 iMesh_getRootSet( mesh, &root_set, &err ); 00434 CHECK_EQUAL( iBase_SUCCESS, err ); 00435 00436 // open a file with var len tags (sense tags) 00437 // they should be filtered out 00438 std::string filename = STRINGIFY( MESHDIR ) "/PB.h5m"; 00439 00440 iMesh_load( mesh, root_set, filename.c_str(), NULL, &err, filename.length(), 0 ); 00441 CHECK_EQUAL( iBase_SUCCESS, err ); 00442 00443 iBase_EntitySetHandle* contained_set_handles = NULL; 00444 int contained_set_handles_allocated = 0; 00445 int contained_set_handles_size; 00446 // get all entity sets 00447 iMesh_getEntSets( mesh, root_set, 1, &contained_set_handles, &contained_set_handles_allocated, 00448 &contained_set_handles_size, &err ); 00449 CHECK_EQUAL( iBase_SUCCESS, err ); 00450 // get tags for all sets 00451 for( int i = 0; i < contained_set_handles_size; i++ ) 00452 { 00453 iBase_TagHandle* tag_handles = NULL; 00454 int tag_handles_allocated = 0; 00455 int tag_handles_size; 00456 iMesh_getAllEntSetTags( mesh, contained_set_handles[i], &tag_handles, &tag_handles_allocated, &tag_handles_size, 00457 &err ); 00458 CHECK_EQUAL( iBase_SUCCESS, err ); 00459 00460 for( int j = 0; j < tag_handles_size; j++ ) 00461 { 00462 int tagSize; 00463 iMesh_getTagSizeValues( mesh, tag_handles[j], &tagSize, &err ); 00464 CHECK_EQUAL( iBase_SUCCESS, err ); 00465 } 00466 free( tag_handles ); 00467 } 00468 free( contained_set_handles ); 00469 00470 // Delete the iMesh instance 00471 iMesh_dtor( mesh, &err ); 00472 CHECK_EQUAL( iBase_SUCCESS, err ); 00473 00474 return; 00475 } 00476 00477 void test_invalid_parallel_option() 00478 { 00479 iMesh_Instance mesh; 00480 int err; 00481 iMesh_newMesh( "moab:PARALLEL", &mesh, &err, 13 ); 00482 CHECK_EQUAL( iBase_NOT_SUPPORTED, err ); 00483 00484 iMesh_dtor( mesh, &err ); 00485 CHECK_EQUAL( iBase_SUCCESS, err ); 00486 }