![]() |
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
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 }