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