Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
MOAB_iMesh_unit_tests.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines